xref: /openbsd/regress/sys/uvm/mmap_mod/mmap_mod.c (revision bc1257b2)
1*bc1257b2Sphessler /*	$OpenBSD: mmap_mod.c,v 1.2 2010/06/20 17:56:07 phessler Exp $	*/
297ceb7c9Sart 
397ceb7c9Sart /*
497ceb7c9Sart  * Public domain. 2007, Artur Grabowski <art@openbsd.org>
597ceb7c9Sart  */
697ceb7c9Sart 
797ceb7c9Sart #include <sys/types.h>
897ceb7c9Sart #include <sys/mman.h>
997ceb7c9Sart #include <err.h>
1097ceb7c9Sart #include <stdlib.h>
1197ceb7c9Sart #include <stdio.h>
12*bc1257b2Sphessler #include <string.h>
1397ceb7c9Sart #include <unistd.h>
1497ceb7c9Sart 
1597ceb7c9Sart /*
1697ceb7c9Sart  * Test a corner case where a pmap can lose mod/ref bits after unmapping
1797ceb7c9Sart  * and remapping a page.
1897ceb7c9Sart  */
1997ceb7c9Sart int
main()2097ceb7c9Sart main()
2197ceb7c9Sart {
2297ceb7c9Sart 	char name[20] = "/tmp/fluff.XXXXXX";
2397ceb7c9Sart 	char *buf, *pat;
2497ceb7c9Sart 	size_t ps;
2597ceb7c9Sart 	int fd;
2697ceb7c9Sart 
2797ceb7c9Sart 	ps = getpagesize();
2897ceb7c9Sart 
2997ceb7c9Sart 	if ((fd = mkstemp(name)) == -1)
3097ceb7c9Sart 		err(1, "mkstemp");
3197ceb7c9Sart 
3297ceb7c9Sart 	if (unlink(name) == -1)
3397ceb7c9Sart 		err(1, "unlink");
3497ceb7c9Sart 
3597ceb7c9Sart 	if (ftruncate(fd, ps))
3697ceb7c9Sart 		err(1, "ftruncate");
3797ceb7c9Sart 
3897ceb7c9Sart 	if ((pat = malloc(ps)) == NULL)
3997ceb7c9Sart 		err(1, "malloc");
4097ceb7c9Sart 
4197ceb7c9Sart 	memset(pat, 'a', ps);
4297ceb7c9Sart 
4397ceb7c9Sart 	if (pwrite(fd, pat, ps, 0) != ps)
4497ceb7c9Sart 		err(1, "write");
4597ceb7c9Sart 
4697ceb7c9Sart 	buf = mmap(NULL, ps, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);
4797ceb7c9Sart 	if (buf == MAP_FAILED)
4897ceb7c9Sart 		err(1, "mmap");
4997ceb7c9Sart 
5097ceb7c9Sart 	if (*buf != 'a')
5197ceb7c9Sart 		errx(1, "mapped area - no file data ('%c' != 'a')", *buf);
5297ceb7c9Sart 
5397ceb7c9Sart 	memset(buf, 'x', ps);
5497ceb7c9Sart 
5597ceb7c9Sart 	if (munmap(buf, ps) == -1)
5697ceb7c9Sart 		err(1, "munmap");
5797ceb7c9Sart 
5897ceb7c9Sart 	buf = mmap(NULL, ps, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);
5997ceb7c9Sart 	if (buf == MAP_FAILED)
6097ceb7c9Sart 		err(1, "mmap 2");
6197ceb7c9Sart 
6297ceb7c9Sart 	if (*buf != 'x')
6397ceb7c9Sart 		errx(1, "mapped area lost modifications ('%c' != 'x')", *buf);
6497ceb7c9Sart 
6597ceb7c9Sart 	if (msync(buf, ps, MS_SYNC) == -1)
6697ceb7c9Sart 		err(1, "msync");
6797ceb7c9Sart 
6897ceb7c9Sart 	if (pread(fd, pat, ps, 0) != ps)
6997ceb7c9Sart 		err(1, "pread");
7097ceb7c9Sart 
7197ceb7c9Sart 	if (*pat != 'x')
7297ceb7c9Sart 		errx(1, "synced area lost modifications ('%c' != 'x')", *pat);
7397ceb7c9Sart 
7497ceb7c9Sart 	return (0);
7597ceb7c9Sart }
76