From: Paolo Bonzini Date: Sun, 14 Feb 2010 01:36:04 GMT Subject: mmap with MAP_PRIVATE is useless (was Re: Bug#569505: git-core: 'git add' corrupts repository if the working directory is modified as it runs) Message-ID: <4B775384.50009@gnu.org> In-Reply-To: <20100212002741.GB9883@progeny.tock> > I tested this with a number of kernel versions from 2.6.27 to 2.6.31. > All of them reproduced this problem. I checked this because strace > shows 'git add' doing a mmap(..., MAP_PRIVATE, ...) of its input file, > so I was wondering if there might have been a recent change in mmap() > behavior in either git or the kernel. From mmap(2): "it is unspecified whether changes made to the file after the mmap() call are visible in the mapped region". You may think that doing a dummy "*p = *p" every 4096 bytes `fixes' it (because it causes copy-on-write for every page) but even that does not work because you can get a SIGBUS if the file is truncated while you have it mapped privately (e.g. by fopen ("file", "w") or open with O_TRUNC). Testcase: #include #include #include int main () { system ("echo foo > file.test"); int f = open ("file.test", O_RDONLY); char *p = mmap (NULL, 4096, PROT_READ, MAP_PRIVATE, f, 0); close (f); printf ("%s", p); // prints "foo\n" f = open ("file.test", O_RDWR | O_CREAT | O_TRUNC, 0666); write (f, "bar\n", 4); // comment out and next printf SIGSEGVs printf ("%s", p); // prints "bar\n" } This means that MAP_PRIVATE is utterly useless. Paolo