blob: 99a65143f79707d83e22e17b60619fcb832e849a [file] [log] [blame]
robbiew84457092003-01-10 17:48:12 +00001/* IBM Corporation */
2/* 01/03/2003 Port to LTP avenkat@us.ibm.com */
3/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */
4
5/*
6 * Copyright (c) International Business Machines Corp., 2003
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
robbiew84457092003-01-10 17:48:12 +000021 */
22
23/*
24 * Mmap a sparse file and then fiddle with the hole in the middle.
25 * Then check the file contents.
26 *
27 * Usage: mmapstress07 filename holesize e_pageskip sparseoff
28 * EXAMPLE: mmapstress07 myfile 4096 1 4096
29 */
30#include <stdio.h>
31#include <sys/types.h>
32#include <sys/mman.h>
33#include <stdlib.h>
34#include <unistd.h>
35#include <fcntl.h>
36#include <signal.h>
37#include <errno.h>
38#include <sys/wait.h>
39#include "test.h"
robbiew84457092003-01-10 17:48:12 +000040#define FAILED 0
41#define PASSED 1
42
43static char *tmpname;
44
45#define ERROR(M) (void)fprintf(stderr, "%s: errno = %d: " M "\n", \
46 argv[0], errno)
47
48#define CLEANERROR(M) (void)close(rofd); \
49 (void)close(rwfd); \
50 (void)unlink(tmpname); \
51 ERROR(M)
52
53#define CATCH_SIG(SIG) \
54 if (sigaction(SIG, &sa, 0) == -1) { \
55 ERROR("couldn't catch signal " #SIG); \
56 exit(1); \
57 }
58
Wanlong Gao354ebb42012-12-07 10:10:04 +080059extern time_t time(time_t *);
60extern char *ctime(const time_t *);
61extern void exit(int);
62static int checkchars(int fd, char val, int n);
robbiew84457092003-01-10 17:48:12 +000063
64char *TCID = "mmapstress07";
65
robbiew84457092003-01-10 17:48:12 +000066int local_flag = PASSED;
67int block_number;
68FILE *temp;
69int TST_TOTAL = 1;
robbiew84457092003-01-10 17:48:12 +000070
71int anyfail();
72void ok_exit();
73
Wanlong Gao354ebb42012-12-07 10:10:04 +080074 /*ARGSUSED*/ static
75void cleanup(int sig)
robbiew84457092003-01-10 17:48:12 +000076{
Wanlong Gao354ebb42012-12-07 10:10:04 +080077 /*
78 * Don't check error codes - we could be signaled before the file is
79 * created.
80 */
81 (void)unlink(tmpname);
82 exit(1);
robbiew84457092003-01-10 17:48:12 +000083}
84
Wanlong Gao354ebb42012-12-07 10:10:04 +080085int main(int argc, char **argv)
robbiew84457092003-01-10 17:48:12 +000086{
Wanlong Gao354ebb42012-12-07 10:10:04 +080087 size_t pagesize = (size_t) sysconf(_SC_PAGE_SIZE);
88 caddr_t mapaddr;
89 time_t t;
90 int rofd, rwfd, i;
91 struct sigaction sa;
92 int e_pageskip;
robbiew84457092003-01-10 17:48:12 +000093#ifdef LARGE_FILE
Wanlong Gao354ebb42012-12-07 10:10:04 +080094 off64_t holesize;
95 off64_t sparseoff;
robbiew84457092003-01-10 17:48:12 +000096#else /* LARGE_FILE */
Wanlong Gao354ebb42012-12-07 10:10:04 +080097 off_t holesize;
98 off_t sparseoff;
robbiew84457092003-01-10 17:48:12 +000099#endif /* LARGE_FILE */
100
101 (void)time(&t);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800102// (void)printf("%s: Started %s", argv[0], ctime(&t));
robbiew84457092003-01-10 17:48:12 +0000103 /* Test fsync & mmap over a hole in a sparse file & extend fragment */
subrata_modakab5bcc32008-12-12 10:40:15 +0000104 if (argc < 2 || argc > 5) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800105 fprintf(stderr,
106 "Usage: mmapstress07 filename holesize e_pageskip sparseoff\n");
robbiew84457092003-01-10 17:48:12 +0000107 /***** ** LTP Port 02/01/03 ** **** */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800108 fprintf(stderr,
109 "\t*holesize should be a multiple of pagesize\n");
robbiew84457092003-01-10 17:48:12 +0000110 fprintf(stderr, "\t*e_pageskip should be 1 always \n");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800111 fprintf(stderr,
112 "\t*sparseoff should be a multiple of pagesize\n");
robbiew84457092003-01-10 17:48:12 +0000113 fprintf(stderr, "Example: mmapstress07 myfile 4096 1 8192\n");
114 /***** ** ****** ***** ***** ** 02/01/03 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800115 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000116 }
117 tst_tmpdir();
118 tmpname = argv[1];
subrata_modakab5bcc32008-12-12 10:40:15 +0000119
120 if (argc >= 3) {
robbiew84457092003-01-10 17:48:12 +0000121#ifdef LARGE_FILE
subrata_modakab5bcc32008-12-12 10:40:15 +0000122 holesize = atoll(argv[2]);
robbiew84457092003-01-10 17:48:12 +0000123#else /* LARGE_FILE */
subrata_modakab5bcc32008-12-12 10:40:15 +0000124 holesize = atoi(argv[2]);
robbiew84457092003-01-10 17:48:12 +0000125#endif /* LARGE_FILE */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800126 } else
subrata_modakab5bcc32008-12-12 10:40:15 +0000127 holesize = pagesize;
128
129 if (argc >= 4)
130 e_pageskip = atoi(argv[3]);
131 else
132 e_pageskip = 1;
133
134 if (argc >= 5) {
robbiew84457092003-01-10 17:48:12 +0000135#ifdef LARGE_FILE
subrata_modakab5bcc32008-12-12 10:40:15 +0000136 sparseoff = atoll(argv[4]);
robbiew84457092003-01-10 17:48:12 +0000137#else /* LARGE_FILE */
subrata_modakab5bcc32008-12-12 10:40:15 +0000138 sparseoff = atoi(argv[4]);
robbiew84457092003-01-10 17:48:12 +0000139#endif /* LARGE_FILE */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800140 } else
141 sparseoff = pagesize * 2;
subrata_modakab5bcc32008-12-12 10:40:15 +0000142
Wanlong Gao354ebb42012-12-07 10:10:04 +0800143 sa.sa_handler = cleanup;
144 sa.sa_flags = 0;
145 if (sigemptyset(&sa.sa_mask)) {
146 ERROR("sigemptyset failed");
147 return 1;
148 }
149 CATCH_SIG(SIGINT);
150 CATCH_SIG(SIGQUIT);
151 CATCH_SIG(SIGTERM);
robbiew84457092003-01-10 17:48:12 +0000152#ifdef LARGE_FILE
Wanlong Gao354ebb42012-12-07 10:10:04 +0800153 if ((rofd = open64(tmpname, O_RDONLY | O_CREAT, 0777)) == -1) {
robbiew84457092003-01-10 17:48:12 +0000154#else /* LARGE_FILE */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800155 if ((rofd = open(tmpname, O_RDONLY | O_CREAT, 0777)) == -1) {
robbiew84457092003-01-10 17:48:12 +0000156#endif /* LARGE_FILE */
157 ERROR("couldn't reopen rofd for reading");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800158 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000159 }
160#ifdef LARGE_FILE
161 if ((rwfd = open64(tmpname, O_RDWR)) == -1) {
162#else /* LARGE_FILE */
163 if ((rwfd = open(tmpname, O_RDWR)) == -1) {
164#endif /* LARGE_FILE */
165 CLEANERROR("couldn't reopen rwfd for read/write");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800166 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000167 }
168#ifdef LARGE_FILE
169 if (lseek64(rwfd, sparseoff, SEEK_SET) < 0) {
170#else /* LARGE_FILE */
171 if (lseek(rwfd, sparseoff, SEEK_SET) < 0) {
172#endif /* LARGE_FILE */
173 perror("lseek");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800174 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000175 }
176 /* fill file with junk. */
177 i = 0;
178 while (i < pagesize && write(rwfd, "a", 1) == 1)
179 i++;
180 if (i != pagesize) {
181 CLEANERROR("couldn't fill first part of file with junk");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800182 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000183 }
184#ifdef LARGE_FILE
185 if (lseek64(rwfd, holesize, SEEK_CUR) == -1) {
186#else /* LARGE_FILE */
187 if (lseek(rwfd, holesize, SEEK_CUR) == -1) {
188#endif /* LARGE_FILE */
189 CLEANERROR("couldn't create hole in file");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800190 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000191 }
192 /* create fragment */
193 i = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800194 while (i < (pagesize >> 1) && write(rwfd, "b", 1) == 1)
robbiew84457092003-01-10 17:48:12 +0000195 i++;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800196 if (i != (pagesize >> 1)) {
robbiew84457092003-01-10 17:48:12 +0000197 CLEANERROR("couldn't fill second part of file with junk");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800198 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000199 }
200 /* At this point fd contains 1 page of a's, holesize bytes skipped,
201 * 1/2 page of b's.
202 */
subrata_modakbdbaec52009-02-26 12:14:51 +0000203
robbiew84457092003-01-10 17:48:12 +0000204#ifdef LARGE_FILE
Wanlong Gao354ebb42012-12-07 10:10:04 +0800205 if ((mapaddr = mmap64((caddr_t) 0, pagesize * 2 + holesize, PROT_READ,
206 MAP_SHARED | MAP_FILE, rofd,
207 sparseoff)) == (caddr_t) - 1) {
robbiew84457092003-01-10 17:48:12 +0000208#else /* LARGE_FILE */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800209 if ((mapaddr = mmap((caddr_t) 0, pagesize * 2 + holesize, PROT_READ,
210 MAP_SHARED | MAP_FILE, rofd,
211 sparseoff)) == (caddr_t) - 1) {
robbiew84457092003-01-10 17:48:12 +0000212#endif /* LARGE_FILE */
213 CLEANERROR("mmap tmp file failed");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800214 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000215 }
subrata_modakab5bcc32008-12-12 10:40:15 +0000216 /* fill out remainder of page + one more page to extend mmapped flag */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800217 while (i < 2 * pagesize && write(rwfd, "c", 1) == 1)
robbiew84457092003-01-10 17:48:12 +0000218 i++;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800219 if (i != 2 * pagesize) {
robbiew84457092003-01-10 17:48:12 +0000220 CLEANERROR("couldn't fill second part of file with junk");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800221 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000222 }
223 /* fiddle with mmapped hole */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800224 if (*(mapaddr + pagesize + (holesize >> 1)) != 0) {
robbiew84457092003-01-10 17:48:12 +0000225 CLEANERROR("hole not filled with 0's");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800226 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000227 }
228#ifdef LARGE_FILE
229 if (lseek64(rwfd, sparseoff + e_pageskip * pagesize, SEEK_SET) == -1) {
230#else /* LARGE_FILE */
231 if (lseek(rwfd, sparseoff + e_pageskip * pagesize, SEEK_SET) == -1) {
232#endif /* LARGE_FILE */
233 CLEANERROR("couldn't lseek back to put e's in hole");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800234 anyfail(); /*LTP Port */
robbiew84457092003-01-10 17:48:12 +0000235 }
236 i = 0;
237 while (i < pagesize && write(rwfd, "e", 1) == 1)
238 i++;
239 if (i != pagesize) {
240 CLEANERROR("couldn't part of hole with e's");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800241 anyfail(); /*LTP Port */
robbiew84457092003-01-10 17:48:12 +0000242 }
243 if (fsync(rwfd) == -1) {
244 CLEANERROR("fsync failed");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800245 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000246 }
247#ifdef LARGE_FILE
248 if (lseek64(rofd, sparseoff, SEEK_SET) == -1) {
249#else /* LARGE_FILE */
250 if (lseek(rofd, sparseoff, SEEK_SET) == -1) {
251#endif /* LARGE_FILE */
252 CLEANERROR("couldn't lseek to begining to verify contents");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800253 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000254 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800255 if (munmap(mapaddr, holesize + 2 * pagesize) == -1) {
robbiew84457092003-01-10 17:48:12 +0000256 CLEANERROR("munmap of tmp file failed");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800257 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000258 }
259 /* check file's contents */
260 if (checkchars(rofd, 'a', pagesize)) {
261 CLEANERROR("first page not filled with a's");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800262 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000263 }
264 if (checkchars(rofd, '\0', (e_pageskip - 1) * pagesize)) {
265 CLEANERROR("e_skip not filled with 0's");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800266 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000267 }
268 if (checkchars(rofd, 'e', pagesize)) {
269 CLEANERROR("part after first 0's not filled with e's");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800270 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000271 }
272 if (checkchars(rofd, '\0', holesize - e_pageskip * pagesize)) {
273 CLEANERROR("second hole section not filled with 0's");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800274 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000275 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800276 if (checkchars(rofd, 'b', (pagesize >> 1))) {
robbiew84457092003-01-10 17:48:12 +0000277 CLEANERROR("next to last half page not filled with b's");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800278 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000279 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800280 if (checkchars(rofd, 'c', pagesize + (pagesize >> 1))) {
robbiew84457092003-01-10 17:48:12 +0000281 CLEANERROR("extended fragment not filled with c's");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800282 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000283 }
284 if (close(rofd) == -1) {
285 CLEANERROR("second close of rofd failed");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800286 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000287 }
288 if (unlink(tmpname) == -1) {
289 CLEANERROR("unlink failed");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800290 anyfail(); /* LTP Port */
robbiew84457092003-01-10 17:48:12 +0000291 }
292 (void)time(&t);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800293// (void)printf("%s: Finished %s", argv[0], ctime(&t));
robbiew84457092003-01-10 17:48:12 +0000294 ok_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800295 tst_exit();
robbiew84457092003-01-10 17:48:12 +0000296}
297
298/* checkchars
299 * verrify that the next n characters of file fd are of value val.
300 * 0 = success; -1 = failure
301 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800302static int checkchars(int fd, char val, int n)
robbiew84457092003-01-10 17:48:12 +0000303{
304 int i;
305 char buf;
306
307 for (i = 0; i < n && read(fd, &buf, 1) == 1; i++)
308 if (buf != val)
309 return -1;
310 return 0;
311}
312
313/***** ** LTP Port ** *****/
314int anyfail()
315{
Cyril Hrubis9fa8ad02014-12-16 13:20:49 +0100316 tst_brkm(TFAIL, tst_rmdir, "Test failed\n");
robbiew84457092003-01-10 17:48:12 +0000317}
318
robbiew84457092003-01-10 17:48:12 +0000319void ok_exit()
320{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800321 tst_resm(TPASS, "Test passed\n");
robbiew84457092003-01-10 17:48:12 +0000322 tst_rmdir();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800323 tst_exit();
robbiew84457092003-01-10 17:48:12 +0000324}
325
Chris Dearmanec6edca2012-10-17 19:54:01 -0700326/***** ** ****** ** *****/