Using mmap() for Advanced File I/O - Synchronizing a File with a Mapping (
Page 4 of 5 )
POSIX provides a memory-mapped equivalent of the fsync() system call that we discussed in Chapter 2:
#include <sys/mman.h>
int msync (void *addr, size_t len, int flags);
A call to msync() flushes back to disk any changes made to a file mapped via mmap(), synchronizing the mapped file with the mapping. Specifically, the file or subset of a file associated with the mapping starting at memory address addr
and continuing for
len
bytes is synchronized to disk. The
addr
argument must be page-aligned; it is generally the return value from a previous
mmap()
invocation.
Without invocation of
msync()
, there is no guarantee that a dirty mapping will be written back to disk until the file is unmapped. This is different from the behavior of
write()
, where a buffer is dirtied as part of the writing process, and queued for writeback to disk. When writing into a memory mapping, the process directly modifies the file’s pages in the kernel’s page cache, without kernel involvement. The kernel may not synchronize the page cache and the disk anytime soon.
The
flags
parameter controls the behavior of the synchronizing operation. It is a bitwise OR of the following values:
MS_ASYNC
Specifies that synchronization should occur asynchronously. The update is scheduled, but the
msync()
call returns immediately without waiting for the writes to take place.
MS_INVALIDATE
Specifies that all other cached copies of the mapping be invalidated. Any future access to any mappings of this file will reflect the newly synchronized on-disk contents.
MS_SYNC
Specifies that synchronization should occur synchronously. The
msync()
call will not return until all pages are written back to disk.
Either
MS_ASYNC
or
MS_SYNC
must be specified, but not both.
Usage is simple:
if (msync (addr, len, MS_ASYNC) == -1
)
perror ("msync");
This example asynchronously synchronizes (say that 10 times fast) to disk the file mapped in the region
[addr,addr+len)
.
On success, msync() returns 0. On failure, the call returns -1
, and sets
errno
appro
priately. The following are valid
errno
values:
EINVAL
The
flags
parameter has both
MS_SYNC
and
MS_ASYNC
set, a bit other than one of the three valid flags is set, or
addr
is not page-aligned.
ENOMEM
The given memory region (or part of it) is not mapped. Note that Linux will return
ENOMEM
, as POSIX dictates, when asked to synchronize a region that is only partly unmapped, but it will still synchronize any valid mappings in the region.
Before version 2.4.19 of the Linux kernel,
msync()
returned
EFAULT
in place of
ENOMEM
.