If you memory map a file using mmap(), but then the underlying file changes to a much smaller size. What happens if you access a memory offset that was shaved off from the file?
mmap works by manipulating your process's page table, a data structure your CPU uses to map address spaces. The CPU will translate "virtual" addresses to "physical" ones, and does so according to the page table set up by your kernel. When you access the mapped memory for the first time, your CPU generates a page fault.
On success, mmap() returns a pointer to the mapped area. On error, the value MAP_FAILED (that is, (void *) -1) is returned, and errno is set to indicate the error. On success, munmap() returns 0. On failure, it returns -1, and errno is set to indicate the error (probably to EINVAL).
In computing, mmap(2) is a POSIX-compliant Unix system call that maps files or devices into memory. It is a method of memory-mapped file I/O. It implements demand paging because file contents are not immediately read from disk and initially use no physical RAM at all.
The page fault happens after mmap has returned, and you start using your allocated segment.
IBM says it is undefined http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Fapis%2Fmmap.htm
If the size of the mapped file is decreased after mmap(), attempts to reference beyond the end of the file are undefined and may result in an MCH0601 exception.
If the size of the file increases after the mmap() function completes, then the whole pages beyond the original end of file will not be accessible via the mapping.
The same is said in SingleUnixSpecification: http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html
If the size of the mapped file changes after the call to mmap() as a result of some other operation on the mapped file, the effect of references to portions of the mapped region that correspond to added or removed portions of the file is unspecified.
'undefined' or 'unspecified' means - the OS is allowed to start formatting of disk or anything. Most probable is SIGSEGV-killing your application.
It depends on what flags you gave to mmap
, the man page:
MAP_SHARED Share this mapping. Updates to the mapping are visible to other processes that map this file, and are carried through to the underlying file. The file may not actually be updated until msync(2) or munmap() is called.
and
MAP_PRIVATE Create a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file. It is unspecified whether changes made to the file after the mmap() call are visible in the mapped region.
So for MAP_PRIVATE
, doesn't matter, each writer effectively has a "private" copy. (though it is only copies when a mutating operation occurs).
I would think that if you use MAP_SHARED
, then no other process would be allowed to open the file with write privileged. But that's a guess.
EDIT: ninjalj is right, the file can be modified even when you mmap
with MAP_SHARED
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With