You seem to be confusing memory-mapping with files in memory-residing
filesystems, along with other concepts like how processes maintain access to
files even as they're moved around.
I'll go question by question to see if I can clear things up.
- Let's say I browse to a directory in my file system and there is a file in
this directory. Is it possible that this file points to a region in the main
memory, instead of pointing to a region in the disk?
It does point to main memory if it's on a memory-residing file-system, like procfs
which is typically mounted on /proc, or sysfs which is on /sys, or tmpfs which
is sometimes on /tmp.
- If this is possible, is this what we call 'memory-mapped file'?
No. Like stephen-kitt said, "memory-mapping" refers to a way to access a file by
"mapping" it on main memory and working with it there rather than reading and
writing chunks at a time via functions like read() and write().
- What would be the meaning of moving such file around the file system (that
is, mving such file from a directory into another)? What I understand is,
since the file is memory mapped, the process(es) interacting with the file
always writes to a predefined region of the main memory, and when we open
that file (for example using vim), we read that region of main memory (so,
no disk is involved). Hence, no matter where we move the file, it will
always work correctly right? If yes, does moving the file around the file
system has any significance?
If you move it around within the same filesystem, you're really just moving
around a reference, an inode from one directory to another. If there are
programs that already had this file opened, they'll still be accessing the same
file because they already have the inode on hand via a file-descriptor. This is
what happened with the table_name.idb file you mentioned in a comment.
- Is there a command which would tell if a file is memory-mapped?
Wossname already answered this for memory-mapped files. lsof
will tell you
which processes have the file memory-mapped.
To know if a file is in a memory-residing filesystem, you can use df
or
mount
to list the filesystems and their mountpoints. You just need to know
which types of filesystems reside in memory by looking them up (e.g. in
wikipedia).
- Finally, if I open a memory-mapped file with vim, make some changes on it
and save and close vim, what will happen? Will my changes simply be written
to main memory? If that's the case, will other processes which use this file
will see the changes I have just made? In my experience, the other processes
did not see the changes I have made to the file when I made some changes on
the file with vim. What is the reason for this?
Personally, I haven't used the mmap
function in a C program, but as I
understand it from skimming man mmap
and info mmap
, there is no magic
involved in maintaining the in-memory representation in sync. In its basic form,
calling mmap copies the file contents to memory and msync
is used to write it
back from memory to the disk. If the on-disk file changes, there is nothing in
place to detect that and automatically modify the in-memory representation in
all processes that mapped it.
EDIT: Turns out that mmap() actually does try to keep the in-memory representation in sync under some conditions. If the map is only read from, it will be kept in sync even when other processes write to the file. If it's written to (by assigning to the memory region), what happens depends on which of the apparently mandatory MAP_SHARED or MAP_PRIVATE flags is provided to mmap(). If MAP_PRIVATE is provided, the map forks from the on-disk representation and stops being in sync until you use msync(). If MAP_SHARED is provided, then the updates are made visible to other processes that have the file mapped, as well as (though this isn't necesarily immediate) the on-disk representation.
I just opened vim on an existing file e
, and ran the command :w
, while
having inotifywait -m .
running in another terminal. Among some weird bits,
this is the important part I got from inotifywait
.
./ MOVED_FROM e
./ MOVED_TO e~
./ CREATE e
./ OPEN e
./ MODIFY e
./ CLOSE_WRITE,CLOSE e
./ ATTRIB e
./ ATTRIB e
./ DELETE e~
Vim creates a new file, and removes the old one. Why it does this instead of
modifying the file is beyond the scope of this question, but the point is that
this is a new file and therefore has a new inode.
Now, what do you mean by other processes using this file? If you mean processes
which had the file opened while you were doing this, no they won't see the
changes. This is because, although they opened a file with the same path, they
aren't the same file. If you mean processes which may open the file after you
did this, then yes they will see the changes. They'll be opening the new file
you created.
It's important to note that though programs may seem to have a file open on the
user interface, that doesn't necesarily mean that that they keep the file open
in the process. Vim is an example of this, as shown above.