• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2002, Intel Corporation. All rights reserved.
3  * Copyright (c) 2012, Cyril Hrubis <chrubis@suse.cz>
4  *
5  * This file is licensed under the GPL license.  For the full content
6  * of this license, see the COPYING file at the top level of this
7  * source tree.
8  *
9  * The st_atime field of the mapped file may be marked for update
10  * at any time between the mmap() call and the corresponding munmap()
11  * call. The initial read or write reference to a mapped region
12  * shall cause the file st_atime field to be marked for update if
13  * it has not already been marked for update.
14  *
15  * Test Steps:
16  * 1. Do stat before mmap() and after munmap(),
17  *    also after writing the mapped region.
18  * 2. Compare whether st_atime has been updated.
19  */
20 
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/mman.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/wait.h>
29 #include <fcntl.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <time.h>
33 
34 #include "noatime.h"
35 #include "posixtest.h"
36 #include "tempfile.h"
37 
main(void)38 int main(void)
39 {
40 	char tmpfname[PATH_MAX];
41 	ssize_t size = 1024;
42 	char data[size];
43 	void *pa;
44 	int fd;
45 
46 	struct stat stat_buff, stat_buff2;
47 	time_t atime1, atime2, atime3;
48 
49 	char *ch;
50 
51 	PTS_GET_TMP_FILENAME(tmpfname, "pts_mmap_13_1");
52 	if (mounted_noatime(pts_get_tmpdir()) == 1) {
53 		printf("UNTESTED: The tmpdir is mounted noatime\n");
54 		return PTS_UNTESTED;
55 	}
56 
57 	unlink(tmpfname);
58 	fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
59 	if (fd == -1) {
60 		printf("Error at open(): %s\n", strerror(errno));
61 		return PTS_UNRESOLVED;
62 	}
63 
64 	memset(data, 'a', size);
65 	printf("Time before write(): %ld\n", time(NULL));
66 	if (write(fd, data, size) != size) {
67 		printf("Error at write(): %s\n", strerror(errno));
68 		unlink(tmpfname);
69 		return PTS_UNRESOLVED;
70 	}
71 
72 	if (stat(tmpfname, &stat_buff) == -1) {
73 		printf("Error at 1st stat(): %s\n", strerror(errno));
74 		unlink(tmpfname);
75 		return PTS_UNRESOLVED;
76 	}
77 	/* atime1: write */
78 	atime1 = stat_buff.st_atime;
79 
80 	sleep(1);
81 
82 	printf("Time before mmap(): %ld\n", time(NULL));
83 	pa = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
84 	if (pa == MAP_FAILED) {
85 		printf("Error at mmap: %s\n", strerror(errno));
86 		unlink(tmpfname);
87 		return PTS_FAIL;
88 	}
89 
90 	if (stat(tmpfname, &stat_buff2) == -1) {
91 		printf("Error at 2nd stat(): %s\n", strerror(errno));
92 		unlink(tmpfname);
93 		return PTS_UNRESOLVED;
94 	}
95 	/* for mmap */
96 	atime2 = stat_buff2.st_atime;
97 
98 	/* Wait a while in case the precision of the sa_time
99 	 * is not acurate enough to reflect the change
100 	 */
101 	sleep(1);
102 
103 	/* write reference to mapped memory */
104 	ch = pa;
105 	*ch = 'b';
106 
107 	printf("Time before munmap(): %ld\n", time(NULL));
108 	munmap(pa, size);
109 
110 	/* FIXME: Update the in-core meta data to the disk */
111 	fsync(fd);
112 	close(fd);
113 	if (stat(tmpfname, &stat_buff) == -1) {
114 		printf("Error at 3rd stat(): %s\n", strerror(errno));
115 		unlink(tmpfname);
116 		return PTS_UNRESOLVED;
117 	}
118 	/* atime3: write to memory */
119 	atime3 = stat_buff.st_atime;
120 
121 	printf("atime1: %d, atime2: %d, atime3: %d\n",
122 	       (int)atime1, (int)atime2, (int)atime3);
123 	if (atime1 != atime3 || atime1 != atime2) {
124 		printf("Test PASSED\n");
125 		unlink(tmpfname);
126 		return PTS_PASS;
127 	}
128 
129 	printf("Test FAILED: st_atime was not updated properly\n");
130 	unlink(tmpfname);
131 	return PTS_FAIL;
132 }
133