xref: /aosp_15_r20/external/ltp/testcases/kernel/fs/ftest/ftest08.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  *
3*49cdfc7eSAndroid Build Coastguard Worker  *   Copyright (c) International Business Machines  Corp., 2002
4*49cdfc7eSAndroid Build Coastguard Worker  *   Copyright (c) Cyril Hrubis [email protected] 2009
5*49cdfc7eSAndroid Build Coastguard Worker  *
6*49cdfc7eSAndroid Build Coastguard Worker  *   This program is free software;  you can redistribute it and/or modify
7*49cdfc7eSAndroid Build Coastguard Worker  *   it under the terms of the GNU General Public License as published by
8*49cdfc7eSAndroid Build Coastguard Worker  *   the Free Software Foundation; either version 2 of the License, or
9*49cdfc7eSAndroid Build Coastguard Worker  *   (at your option) any later version.
10*49cdfc7eSAndroid Build Coastguard Worker  *
11*49cdfc7eSAndroid Build Coastguard Worker  *   This program is distributed in the hope that it will be useful,
12*49cdfc7eSAndroid Build Coastguard Worker  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
13*49cdfc7eSAndroid Build Coastguard Worker  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14*49cdfc7eSAndroid Build Coastguard Worker  *   the GNU General Public License for more details.
15*49cdfc7eSAndroid Build Coastguard Worker  *
16*49cdfc7eSAndroid Build Coastguard Worker  *   You should have received a copy of the GNU General Public License
17*49cdfc7eSAndroid Build Coastguard Worker  *   along with this program;  if not, write to the Free Software
18*49cdfc7eSAndroid Build Coastguard Worker  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*49cdfc7eSAndroid Build Coastguard Worker  */
20*49cdfc7eSAndroid Build Coastguard Worker 
21*49cdfc7eSAndroid Build Coastguard Worker /*
22*49cdfc7eSAndroid Build Coastguard Worker  * NAME
23*49cdfc7eSAndroid Build Coastguard Worker  *	ftest08.c -- test single file io (tsfio.c by rbk) (ported from SPIE,
24*49cdfc7eSAndroid Build Coastguard Worker  *		     section2/filesuite/ftest10.c, by Airong Zhang)
25*49cdfc7eSAndroid Build Coastguard Worker  *
26*49cdfc7eSAndroid Build Coastguard Worker  * 	this is the same as ftest4, except that it uses lseek64
27*49cdfc7eSAndroid Build Coastguard Worker  *
28*49cdfc7eSAndroid Build Coastguard Worker  * CALLS
29*49cdfc7eSAndroid Build Coastguard Worker  *	fsync, sync, lseek64, read, write
30*49cdfc7eSAndroid Build Coastguard Worker  *
31*49cdfc7eSAndroid Build Coastguard Worker  *
32*49cdfc7eSAndroid Build Coastguard Worker  * ALGORITHM
33*49cdfc7eSAndroid Build Coastguard Worker  *	Several child processes doing random seeks, read/write
34*49cdfc7eSAndroid Build Coastguard Worker  *	operations on the same file.
35*49cdfc7eSAndroid Build Coastguard Worker  *
36*49cdfc7eSAndroid Build Coastguard Worker  *
37*49cdfc7eSAndroid Build Coastguard Worker  * RESTRICTIONS
38*49cdfc7eSAndroid Build Coastguard Worker  *	Runs a long time with default args - can take others on input
39*49cdfc7eSAndroid Build Coastguard Worker  *	line.  Use with "term mode".
40*49cdfc7eSAndroid Build Coastguard Worker  *
41*49cdfc7eSAndroid Build Coastguard Worker  */
42*49cdfc7eSAndroid Build Coastguard Worker 
43*49cdfc7eSAndroid Build Coastguard Worker #define _XOPEN_SOURCE 500
44*49cdfc7eSAndroid Build Coastguard Worker #define _LARGEFILE64_SOURCE 1
45*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
46*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
47*49cdfc7eSAndroid Build Coastguard Worker #include <sys/param.h>
48*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
49*49cdfc7eSAndroid Build Coastguard Worker #include <sys/file.h>
50*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
51*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
52*49cdfc7eSAndroid Build Coastguard Worker #include <sys/uio.h>
53*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
54*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
55*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
56*49cdfc7eSAndroid Build Coastguard Worker #include <inttypes.h>
57*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
58*49cdfc7eSAndroid Build Coastguard Worker #include "safe_macros.h"
59*49cdfc7eSAndroid Build Coastguard Worker #include "libftest.h"
60*49cdfc7eSAndroid Build Coastguard Worker 
61*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "ftest08";
62*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 1;
63*49cdfc7eSAndroid Build Coastguard Worker 
64*49cdfc7eSAndroid Build Coastguard Worker #define PASSED 1
65*49cdfc7eSAndroid Build Coastguard Worker #define FAILED 0
66*49cdfc7eSAndroid Build Coastguard Worker 
67*49cdfc7eSAndroid Build Coastguard Worker #define MAXCHILD	25
68*49cdfc7eSAndroid Build Coastguard Worker #define K_1		1024
69*49cdfc7eSAndroid Build Coastguard Worker #define K_2		2048
70*49cdfc7eSAndroid Build Coastguard Worker #define K_4		4096
71*49cdfc7eSAndroid Build Coastguard Worker #define	MAXIOVCNT	16
72*49cdfc7eSAndroid Build Coastguard Worker 
73*49cdfc7eSAndroid Build Coastguard Worker static void init(void);
74*49cdfc7eSAndroid Build Coastguard Worker static void runtest(void);
75*49cdfc7eSAndroid Build Coastguard Worker static void dotest(int, int, int);
76*49cdfc7eSAndroid Build Coastguard Worker static void domisc(int, int);
77*49cdfc7eSAndroid Build Coastguard Worker static void term(int sig);
78*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void);
79*49cdfc7eSAndroid Build Coastguard Worker 
80*49cdfc7eSAndroid Build Coastguard Worker static int csize;		/* chunk size */
81*49cdfc7eSAndroid Build Coastguard Worker static int iterations;		/* # total iterations */
82*49cdfc7eSAndroid Build Coastguard Worker static off64_t max_size;	/* max file size */
83*49cdfc7eSAndroid Build Coastguard Worker static int misc_intvl;		/* for doing misc things; 0 ==> no */
84*49cdfc7eSAndroid Build Coastguard Worker static int nchild;		/* number of child processes */
85*49cdfc7eSAndroid Build Coastguard Worker static int parent_pid;
86*49cdfc7eSAndroid Build Coastguard Worker static int pidlist[MAXCHILD];
87*49cdfc7eSAndroid Build Coastguard Worker 
88*49cdfc7eSAndroid Build Coastguard Worker static char filename[MAXPATHLEN];
89*49cdfc7eSAndroid Build Coastguard Worker static int local_flag;
90*49cdfc7eSAndroid Build Coastguard Worker 
main(int ac,char * av[])91*49cdfc7eSAndroid Build Coastguard Worker int main(int ac, char *av[])
92*49cdfc7eSAndroid Build Coastguard Worker {
93*49cdfc7eSAndroid Build Coastguard Worker 	int lc;
94*49cdfc7eSAndroid Build Coastguard Worker 
95*49cdfc7eSAndroid Build Coastguard Worker 	tst_parse_opts(ac, av, NULL, NULL);
96*49cdfc7eSAndroid Build Coastguard Worker 
97*49cdfc7eSAndroid Build Coastguard Worker 	for (lc = 0; TEST_LOOPING(lc); lc++) {
98*49cdfc7eSAndroid Build Coastguard Worker 
99*49cdfc7eSAndroid Build Coastguard Worker 		local_flag = PASSED;
100*49cdfc7eSAndroid Build Coastguard Worker 		init();
101*49cdfc7eSAndroid Build Coastguard Worker 		runtest();
102*49cdfc7eSAndroid Build Coastguard Worker 
103*49cdfc7eSAndroid Build Coastguard Worker 		if (local_flag == PASSED)
104*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TPASS, "Test passed.");
105*49cdfc7eSAndroid Build Coastguard Worker 		else
106*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Test failed.");
107*49cdfc7eSAndroid Build Coastguard Worker 	}
108*49cdfc7eSAndroid Build Coastguard Worker 
109*49cdfc7eSAndroid Build Coastguard Worker 	cleanup();
110*49cdfc7eSAndroid Build Coastguard Worker 	tst_exit();
111*49cdfc7eSAndroid Build Coastguard Worker }
112*49cdfc7eSAndroid Build Coastguard Worker 
init(void)113*49cdfc7eSAndroid Build Coastguard Worker static void init(void)
114*49cdfc7eSAndroid Build Coastguard Worker {
115*49cdfc7eSAndroid Build Coastguard Worker 	int fd;
116*49cdfc7eSAndroid Build Coastguard Worker 	char wdbuf[MAXPATHLEN];
117*49cdfc7eSAndroid Build Coastguard Worker 
118*49cdfc7eSAndroid Build Coastguard Worker 	parent_pid = getpid();
119*49cdfc7eSAndroid Build Coastguard Worker 	tst_tmpdir();
120*49cdfc7eSAndroid Build Coastguard Worker 
121*49cdfc7eSAndroid Build Coastguard Worker 	/*
122*49cdfc7eSAndroid Build Coastguard Worker 	 * Make a filename for the test.
123*49cdfc7eSAndroid Build Coastguard Worker 	 */
124*49cdfc7eSAndroid Build Coastguard Worker 	if (!filename[0])
125*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(filename, "%s/ftest08.%d", getcwd(wdbuf, MAXPATHLEN),
126*49cdfc7eSAndroid Build Coastguard Worker 			getpid());
127*49cdfc7eSAndroid Build Coastguard Worker 
128*49cdfc7eSAndroid Build Coastguard Worker 	fd = SAFE_OPEN(NULL, filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
129*49cdfc7eSAndroid Build Coastguard Worker 
130*49cdfc7eSAndroid Build Coastguard Worker 	close(fd);
131*49cdfc7eSAndroid Build Coastguard Worker 
132*49cdfc7eSAndroid Build Coastguard Worker 	/*
133*49cdfc7eSAndroid Build Coastguard Worker 	 * Default values for run conditions.
134*49cdfc7eSAndroid Build Coastguard Worker 	 */
135*49cdfc7eSAndroid Build Coastguard Worker 	iterations = 10;
136*49cdfc7eSAndroid Build Coastguard Worker 	nchild = 5;
137*49cdfc7eSAndroid Build Coastguard Worker 	csize = K_2;		/* should run with 1, 2, and 4 K sizes */
138*49cdfc7eSAndroid Build Coastguard Worker 	max_size = K_1 * K_1;
139*49cdfc7eSAndroid Build Coastguard Worker 	misc_intvl = 10;
140*49cdfc7eSAndroid Build Coastguard Worker 
141*49cdfc7eSAndroid Build Coastguard Worker 	if (sigset(SIGTERM, term) == SIG_ERR) {
142*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "first sigset failed");
143*49cdfc7eSAndroid Build Coastguard Worker 	}
144*49cdfc7eSAndroid Build Coastguard Worker 
145*49cdfc7eSAndroid Build Coastguard Worker }
146*49cdfc7eSAndroid Build Coastguard Worker 
runtest(void)147*49cdfc7eSAndroid Build Coastguard Worker static void runtest(void)
148*49cdfc7eSAndroid Build Coastguard Worker {
149*49cdfc7eSAndroid Build Coastguard Worker 	int child, count, fd, i, nwait, status;
150*49cdfc7eSAndroid Build Coastguard Worker 
151*49cdfc7eSAndroid Build Coastguard Worker 	nwait = 0;
152*49cdfc7eSAndroid Build Coastguard Worker 
153*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < nchild; i++) {
154*49cdfc7eSAndroid Build Coastguard Worker 
155*49cdfc7eSAndroid Build Coastguard Worker 		if ((child = fork()) == 0) {
156*49cdfc7eSAndroid Build Coastguard Worker 			fd = open(filename, O_RDWR);
157*49cdfc7eSAndroid Build Coastguard Worker 			if (fd < 0) {
158*49cdfc7eSAndroid Build Coastguard Worker 				tst_brkm(TFAIL,
159*49cdfc7eSAndroid Build Coastguard Worker 					 NULL,
160*49cdfc7eSAndroid Build Coastguard Worker 					 "\tTest[%d]: error %d openning %s.",
161*49cdfc7eSAndroid Build Coastguard Worker 					 i,
162*49cdfc7eSAndroid Build Coastguard Worker 					 errno, filename);
163*49cdfc7eSAndroid Build Coastguard Worker 			}
164*49cdfc7eSAndroid Build Coastguard Worker 			dotest(nchild, i, fd);
165*49cdfc7eSAndroid Build Coastguard Worker 			close(fd);
166*49cdfc7eSAndroid Build Coastguard Worker 			tst_exit();
167*49cdfc7eSAndroid Build Coastguard Worker 		}
168*49cdfc7eSAndroid Build Coastguard Worker 
169*49cdfc7eSAndroid Build Coastguard Worker 		if (child < 0) {
170*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK | TERRNO, NULL, "fork failed");
171*49cdfc7eSAndroid Build Coastguard Worker 		} else {
172*49cdfc7eSAndroid Build Coastguard Worker 			pidlist[i] = child;
173*49cdfc7eSAndroid Build Coastguard Worker 			nwait++;
174*49cdfc7eSAndroid Build Coastguard Worker 		}
175*49cdfc7eSAndroid Build Coastguard Worker 	}
176*49cdfc7eSAndroid Build Coastguard Worker 
177*49cdfc7eSAndroid Build Coastguard Worker 	/*
178*49cdfc7eSAndroid Build Coastguard Worker 	 * Wait for children to finish.
179*49cdfc7eSAndroid Build Coastguard Worker 	 */
180*49cdfc7eSAndroid Build Coastguard Worker 	count = 0;
181*49cdfc7eSAndroid Build Coastguard Worker 	while ((child = wait(&status)) != -1 || errno == EINTR) {
182*49cdfc7eSAndroid Build Coastguard Worker 		if (child > 0) {
183*49cdfc7eSAndroid Build Coastguard Worker 			//tst_resm(TINFO, "\tTest{%d} exited status = 0x%x", child, status);
184*49cdfc7eSAndroid Build Coastguard Worker 			if (status) {
185*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TFAIL,
186*49cdfc7eSAndroid Build Coastguard Worker 					 "\tExpected 0 exit status - failed.");
187*49cdfc7eSAndroid Build Coastguard Worker 				local_flag = FAILED;
188*49cdfc7eSAndroid Build Coastguard Worker 			}
189*49cdfc7eSAndroid Build Coastguard Worker 			++count;
190*49cdfc7eSAndroid Build Coastguard Worker 		}
191*49cdfc7eSAndroid Build Coastguard Worker 	}
192*49cdfc7eSAndroid Build Coastguard Worker 
193*49cdfc7eSAndroid Build Coastguard Worker 	/*
194*49cdfc7eSAndroid Build Coastguard Worker 	 * Should have collected all children.
195*49cdfc7eSAndroid Build Coastguard Worker 	 */
196*49cdfc7eSAndroid Build Coastguard Worker 	if (count != nwait) {
197*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TFAIL, "\tWrong # children waited on, count = %d",
198*49cdfc7eSAndroid Build Coastguard Worker 			 count);
199*49cdfc7eSAndroid Build Coastguard Worker 		local_flag = FAILED;
200*49cdfc7eSAndroid Build Coastguard Worker 	}
201*49cdfc7eSAndroid Build Coastguard Worker 
202*49cdfc7eSAndroid Build Coastguard Worker 	unlink(filename);
203*49cdfc7eSAndroid Build Coastguard Worker 	sync();
204*49cdfc7eSAndroid Build Coastguard Worker }
205*49cdfc7eSAndroid Build Coastguard Worker 
206*49cdfc7eSAndroid Build Coastguard Worker /*
207*49cdfc7eSAndroid Build Coastguard Worker  * dotest()
208*49cdfc7eSAndroid Build Coastguard Worker  *	Children execute this.
209*49cdfc7eSAndroid Build Coastguard Worker  *
210*49cdfc7eSAndroid Build Coastguard Worker  * Randomly read/mod/write chunks with known pattern and check.
211*49cdfc7eSAndroid Build Coastguard Worker  * When fill sectors, iterate.
212*49cdfc7eSAndroid Build Coastguard Worker  */
213*49cdfc7eSAndroid Build Coastguard Worker #define	NMISC	2
214*49cdfc7eSAndroid Build Coastguard Worker enum m_type { m_fsync, m_sync };
215*49cdfc7eSAndroid Build Coastguard Worker char *m_str[] = { "fsync", "sync" };
216*49cdfc7eSAndroid Build Coastguard Worker 
217*49cdfc7eSAndroid Build Coastguard Worker int misc_cnt[NMISC];		/* counts # of each kind of misc */
218*49cdfc7eSAndroid Build Coastguard Worker int misc_flag;
219*49cdfc7eSAndroid Build Coastguard Worker int nchunks;
220*49cdfc7eSAndroid Build Coastguard Worker 
221*49cdfc7eSAndroid Build Coastguard Worker #define	CHUNK(i)	((((off64_t)i) * testers + me) * csize)
222*49cdfc7eSAndroid Build Coastguard Worker #define	NEXTMISC	((rand() % misc_intvl) + 5)
223*49cdfc7eSAndroid Build Coastguard Worker 
dotest(int testers,int me,int fd)224*49cdfc7eSAndroid Build Coastguard Worker static void dotest(int testers, int me, int fd)
225*49cdfc7eSAndroid Build Coastguard Worker {
226*49cdfc7eSAndroid Build Coastguard Worker 	char *bits;
227*49cdfc7eSAndroid Build Coastguard Worker 	char val, val0;
228*49cdfc7eSAndroid Build Coastguard Worker 	int count, collide, chunk, whenmisc, xfr, i;
229*49cdfc7eSAndroid Build Coastguard Worker 
230*49cdfc7eSAndroid Build Coastguard Worker 	/* Stuff for the readv call */
231*49cdfc7eSAndroid Build Coastguard Worker 	struct iovec r_iovec[MAXIOVCNT];
232*49cdfc7eSAndroid Build Coastguard Worker 	int r_ioveclen;
233*49cdfc7eSAndroid Build Coastguard Worker 
234*49cdfc7eSAndroid Build Coastguard Worker 	/* Stuff for the writev call */
235*49cdfc7eSAndroid Build Coastguard Worker 	struct iovec val0_iovec[MAXIOVCNT];
236*49cdfc7eSAndroid Build Coastguard Worker 	struct iovec val_iovec[MAXIOVCNT];
237*49cdfc7eSAndroid Build Coastguard Worker 	int w_ioveclen;
238*49cdfc7eSAndroid Build Coastguard Worker 	struct stat stat;
239*49cdfc7eSAndroid Build Coastguard Worker 
240*49cdfc7eSAndroid Build Coastguard Worker 	nchunks = max_size / (testers * csize);
241*49cdfc7eSAndroid Build Coastguard Worker 	whenmisc = 0;
242*49cdfc7eSAndroid Build Coastguard Worker 
243*49cdfc7eSAndroid Build Coastguard Worker 	if ((bits = malloc((nchunks + 7) / 8)) == NULL) {
244*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "\tmalloc failed(bits)");
245*49cdfc7eSAndroid Build Coastguard Worker 	}
246*49cdfc7eSAndroid Build Coastguard Worker 
247*49cdfc7eSAndroid Build Coastguard Worker 	/* Allocate memory for the iovec buffers and init the iovec arrays */
248*49cdfc7eSAndroid Build Coastguard Worker 	r_ioveclen = w_ioveclen = csize / MAXIOVCNT;
249*49cdfc7eSAndroid Build Coastguard Worker 
250*49cdfc7eSAndroid Build Coastguard Worker 	/* Please note that the above statement implies that csize
251*49cdfc7eSAndroid Build Coastguard Worker 	 * be evenly divisible by MAXIOVCNT.
252*49cdfc7eSAndroid Build Coastguard Worker 	 */
253*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < MAXIOVCNT; i++) {
254*49cdfc7eSAndroid Build Coastguard Worker 		if ((r_iovec[i].iov_base = malloc(r_ioveclen)) == NULL) {
255*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK, NULL, "\tmalloc failed(iov_base)");
256*49cdfc7eSAndroid Build Coastguard Worker 		}
257*49cdfc7eSAndroid Build Coastguard Worker 		r_iovec[i].iov_len = r_ioveclen;
258*49cdfc7eSAndroid Build Coastguard Worker 
259*49cdfc7eSAndroid Build Coastguard Worker 		/* Allocate unused memory areas between all the buffers to
260*49cdfc7eSAndroid Build Coastguard Worker 		 * make things more diffult for the OS.
261*49cdfc7eSAndroid Build Coastguard Worker 		 */
262*49cdfc7eSAndroid Build Coastguard Worker 		if (malloc((i + 1) * 8) == NULL) {
263*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK, NULL, "\tmalloc failed((i+1)*8)");
264*49cdfc7eSAndroid Build Coastguard Worker 		}
265*49cdfc7eSAndroid Build Coastguard Worker 
266*49cdfc7eSAndroid Build Coastguard Worker 		if ((val0_iovec[i].iov_base = malloc(w_ioveclen)) == NULL) {
267*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK, NULL, "\tmalloc failed(val0_iovec)");
268*49cdfc7eSAndroid Build Coastguard Worker 		}
269*49cdfc7eSAndroid Build Coastguard Worker 
270*49cdfc7eSAndroid Build Coastguard Worker 		val0_iovec[i].iov_len = w_ioveclen;
271*49cdfc7eSAndroid Build Coastguard Worker 
272*49cdfc7eSAndroid Build Coastguard Worker 		if (malloc((i + 1) * 8) == NULL) {
273*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK, NULL, "\tmalloc failed((i+1)*8)");
274*49cdfc7eSAndroid Build Coastguard Worker 		}
275*49cdfc7eSAndroid Build Coastguard Worker 
276*49cdfc7eSAndroid Build Coastguard Worker 		if ((val_iovec[i].iov_base = malloc(w_ioveclen)) == NULL) {
277*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK, NULL, "\tmalloc failed(iov_base)");
278*49cdfc7eSAndroid Build Coastguard Worker 		}
279*49cdfc7eSAndroid Build Coastguard Worker 		val_iovec[i].iov_len = w_ioveclen;
280*49cdfc7eSAndroid Build Coastguard Worker 
281*49cdfc7eSAndroid Build Coastguard Worker 		if (malloc((i + 1) * 8) == NULL) {
282*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK, NULL, "\tmalloc failed(((i+1)*8)");
283*49cdfc7eSAndroid Build Coastguard Worker 		}
284*49cdfc7eSAndroid Build Coastguard Worker 	}
285*49cdfc7eSAndroid Build Coastguard Worker 
286*49cdfc7eSAndroid Build Coastguard Worker 	/*
287*49cdfc7eSAndroid Build Coastguard Worker 	 * No init sectors; file-sys makes 0 to start.
288*49cdfc7eSAndroid Build Coastguard Worker 	 */
289*49cdfc7eSAndroid Build Coastguard Worker 	val = (64 / testers) * me + 1;
290*49cdfc7eSAndroid Build Coastguard Worker 	val0 = 0;
291*49cdfc7eSAndroid Build Coastguard Worker 
292*49cdfc7eSAndroid Build Coastguard Worker 	/*
293*49cdfc7eSAndroid Build Coastguard Worker 	 * For each iteration:
294*49cdfc7eSAndroid Build Coastguard Worker 	 *      zap bits array
295*49cdfc7eSAndroid Build Coastguard Worker 	 *      loop:
296*49cdfc7eSAndroid Build Coastguard Worker 	 *              pick random chunk, read it.
297*49cdfc7eSAndroid Build Coastguard Worker 	 *              if corresponding bit off {
298*49cdfc7eSAndroid Build Coastguard Worker 	 *                      verify == 0. (sparse file)
299*49cdfc7eSAndroid Build Coastguard Worker 	 *                      ++count;
300*49cdfc7eSAndroid Build Coastguard Worker 	 *              } else
301*49cdfc7eSAndroid Build Coastguard Worker 	 *                      verify == val.
302*49cdfc7eSAndroid Build Coastguard Worker 	 *              write "val" on it.
303*49cdfc7eSAndroid Build Coastguard Worker 	 *              repeat until count = nchunks.
304*49cdfc7eSAndroid Build Coastguard Worker 	 *      ++val.
305*49cdfc7eSAndroid Build Coastguard Worker 	 */
306*49cdfc7eSAndroid Build Coastguard Worker 	srand(getpid());
307*49cdfc7eSAndroid Build Coastguard Worker 
308*49cdfc7eSAndroid Build Coastguard Worker 	if (misc_intvl)
309*49cdfc7eSAndroid Build Coastguard Worker 		whenmisc = NEXTMISC;
310*49cdfc7eSAndroid Build Coastguard Worker 
311*49cdfc7eSAndroid Build Coastguard Worker 	while (iterations-- > 0) {
312*49cdfc7eSAndroid Build Coastguard Worker 		for (i = 0; i < NMISC; i++)
313*49cdfc7eSAndroid Build Coastguard Worker 			misc_cnt[i] = 0;
314*49cdfc7eSAndroid Build Coastguard Worker 		memset(bits, 0, (nchunks + 7) / 8);
315*49cdfc7eSAndroid Build Coastguard Worker 		/* Have to fill the val0 and val iov buffers in a different manner
316*49cdfc7eSAndroid Build Coastguard Worker 		 */
317*49cdfc7eSAndroid Build Coastguard Worker 		for (i = 0; i < MAXIOVCNT; i++) {
318*49cdfc7eSAndroid Build Coastguard Worker 			memset(val0_iovec[i].iov_base, val0,
319*49cdfc7eSAndroid Build Coastguard Worker 			       val0_iovec[i].iov_len);
320*49cdfc7eSAndroid Build Coastguard Worker 			memset(val_iovec[i].iov_base, val,
321*49cdfc7eSAndroid Build Coastguard Worker 			       val_iovec[i].iov_len);
322*49cdfc7eSAndroid Build Coastguard Worker 
323*49cdfc7eSAndroid Build Coastguard Worker 		}
324*49cdfc7eSAndroid Build Coastguard Worker 
325*49cdfc7eSAndroid Build Coastguard Worker 		count = 0;
326*49cdfc7eSAndroid Build Coastguard Worker 		collide = 0;
327*49cdfc7eSAndroid Build Coastguard Worker 
328*49cdfc7eSAndroid Build Coastguard Worker 		while (count < nchunks) {
329*49cdfc7eSAndroid Build Coastguard Worker 			chunk = rand() % nchunks;
330*49cdfc7eSAndroid Build Coastguard Worker 			/*
331*49cdfc7eSAndroid Build Coastguard Worker 			 * Read it.
332*49cdfc7eSAndroid Build Coastguard Worker 			 */
333*49cdfc7eSAndroid Build Coastguard Worker 			if (lseek64(fd, CHUNK(chunk), 0) < 0) {
334*49cdfc7eSAndroid Build Coastguard Worker 				tst_brkm(TFAIL,
335*49cdfc7eSAndroid Build Coastguard Worker 					 NULL, "\tTest[%d]: lseek64(0) fail at %"
336*49cdfc7eSAndroid Build Coastguard Worker 					 PRIx64 "x, errno = %d.", me,
337*49cdfc7eSAndroid Build Coastguard Worker 					 CHUNK(chunk), errno);
338*49cdfc7eSAndroid Build Coastguard Worker 			}
339*49cdfc7eSAndroid Build Coastguard Worker 			if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) {
340*49cdfc7eSAndroid Build Coastguard Worker 				tst_brkm(TFAIL,
341*49cdfc7eSAndroid Build Coastguard Worker 					 NULL, "\tTest[%d]: readv fail at %" PRIx64
342*49cdfc7eSAndroid Build Coastguard Worker 					 "x, errno = %d.", me, CHUNK(chunk),
343*49cdfc7eSAndroid Build Coastguard Worker 					 errno);
344*49cdfc7eSAndroid Build Coastguard Worker 			}
345*49cdfc7eSAndroid Build Coastguard Worker 			/*
346*49cdfc7eSAndroid Build Coastguard Worker 			 * If chunk beyond EOF just write on it.
347*49cdfc7eSAndroid Build Coastguard Worker 			 * Else if bit off, haven't seen it yet.
348*49cdfc7eSAndroid Build Coastguard Worker 			 * Else, have.  Verify values.
349*49cdfc7eSAndroid Build Coastguard Worker 			 */
350*49cdfc7eSAndroid Build Coastguard Worker 			if (xfr == 0) {
351*49cdfc7eSAndroid Build Coastguard Worker 				bits[chunk / 8] |= (1 << (chunk % 8));
352*49cdfc7eSAndroid Build Coastguard Worker 			} else if ((bits[chunk / 8] & (1 << (chunk % 8))) == 0) {
353*49cdfc7eSAndroid Build Coastguard Worker 				if (xfr != csize) {
354*49cdfc7eSAndroid Build Coastguard Worker 					tst_brkm(TFAIL,
355*49cdfc7eSAndroid Build Coastguard Worker 						 NULL,
356*49cdfc7eSAndroid Build Coastguard Worker 						 "\tTest[%d]: xfr=%d != %d, zero read.",
357*49cdfc7eSAndroid Build Coastguard Worker 						 me, xfr, csize);
358*49cdfc7eSAndroid Build Coastguard Worker 				}
359*49cdfc7eSAndroid Build Coastguard Worker 				for (i = 0; i < MAXIOVCNT; i++) {
360*49cdfc7eSAndroid Build Coastguard Worker 					if (memcmp
361*49cdfc7eSAndroid Build Coastguard Worker 					    (r_iovec[i].iov_base,
362*49cdfc7eSAndroid Build Coastguard Worker 					     val0_iovec[i].iov_base,
363*49cdfc7eSAndroid Build Coastguard Worker 					     r_iovec[i].iov_len)) {
364*49cdfc7eSAndroid Build Coastguard Worker 						tst_resm(TFAIL,
365*49cdfc7eSAndroid Build Coastguard Worker 							 "\tTest[%d] bad verify @ 0x%"
366*49cdfc7eSAndroid Build Coastguard Worker 							 PRIx64
367*49cdfc7eSAndroid Build Coastguard Worker 							 " for val %d count %d xfr %d.",
368*49cdfc7eSAndroid Build Coastguard Worker 							 me, CHUNK(chunk), val0,
369*49cdfc7eSAndroid Build Coastguard Worker 							 count, xfr);
370*49cdfc7eSAndroid Build Coastguard Worker 						fstat(fd, &stat);
371*49cdfc7eSAndroid Build Coastguard Worker 						tst_resm(TINFO,
372*49cdfc7eSAndroid Build Coastguard Worker 							 "\tStat: size=%llx, ino=%x",
373*49cdfc7eSAndroid Build Coastguard Worker 							 stat.st_size, (unsigned)stat.st_ino);
374*49cdfc7eSAndroid Build Coastguard Worker 						ft_dumpiov(&r_iovec[i]);
375*49cdfc7eSAndroid Build Coastguard Worker 						ft_dumpbits(bits,
376*49cdfc7eSAndroid Build Coastguard Worker 							    (nchunks + 7) / 8);
377*49cdfc7eSAndroid Build Coastguard Worker 						tst_exit();
378*49cdfc7eSAndroid Build Coastguard Worker 					}
379*49cdfc7eSAndroid Build Coastguard Worker 				}
380*49cdfc7eSAndroid Build Coastguard Worker 				bits[chunk / 8] |= (1 << (chunk % 8));
381*49cdfc7eSAndroid Build Coastguard Worker 				++count;
382*49cdfc7eSAndroid Build Coastguard Worker 			} else {
383*49cdfc7eSAndroid Build Coastguard Worker 				if (xfr != csize) {
384*49cdfc7eSAndroid Build Coastguard Worker 					tst_brkm(TFAIL,
385*49cdfc7eSAndroid Build Coastguard Worker 						 NULL,
386*49cdfc7eSAndroid Build Coastguard Worker 						 "\tTest[%d]: xfr=%d != %d, val read.",
387*49cdfc7eSAndroid Build Coastguard Worker 						 me, xfr, csize);
388*49cdfc7eSAndroid Build Coastguard Worker 				}
389*49cdfc7eSAndroid Build Coastguard Worker 				++collide;
390*49cdfc7eSAndroid Build Coastguard Worker 				for (i = 0; i < MAXIOVCNT; i++) {
391*49cdfc7eSAndroid Build Coastguard Worker 					if (memcmp
392*49cdfc7eSAndroid Build Coastguard Worker 					    (r_iovec[i].iov_base,
393*49cdfc7eSAndroid Build Coastguard Worker 					     val_iovec[i].iov_base,
394*49cdfc7eSAndroid Build Coastguard Worker 					     r_iovec[i].iov_len)) {
395*49cdfc7eSAndroid Build Coastguard Worker 						tst_resm(TFAIL,
396*49cdfc7eSAndroid Build Coastguard Worker 							 "\tTest[%d] bad verify @ 0x%"
397*49cdfc7eSAndroid Build Coastguard Worker 							 PRIx64
398*49cdfc7eSAndroid Build Coastguard Worker 							 " for val %d count %d xfr %d.",
399*49cdfc7eSAndroid Build Coastguard Worker 							 me, CHUNK(chunk), val,
400*49cdfc7eSAndroid Build Coastguard Worker 							 count, xfr);
401*49cdfc7eSAndroid Build Coastguard Worker 						fstat(fd, &stat);
402*49cdfc7eSAndroid Build Coastguard Worker 						tst_resm(TINFO,
403*49cdfc7eSAndroid Build Coastguard Worker 							 "\tStat: size=%llx, ino=%x",
404*49cdfc7eSAndroid Build Coastguard Worker 							 stat.st_size, (unsigned)stat.st_ino);
405*49cdfc7eSAndroid Build Coastguard Worker 						ft_dumpiov(&r_iovec[i]);
406*49cdfc7eSAndroid Build Coastguard Worker 						ft_dumpbits(bits,
407*49cdfc7eSAndroid Build Coastguard Worker 							    (nchunks + 7) / 8);
408*49cdfc7eSAndroid Build Coastguard Worker 						tst_exit();
409*49cdfc7eSAndroid Build Coastguard Worker 					}
410*49cdfc7eSAndroid Build Coastguard Worker 				}
411*49cdfc7eSAndroid Build Coastguard Worker 			}
412*49cdfc7eSAndroid Build Coastguard Worker 			/*
413*49cdfc7eSAndroid Build Coastguard Worker 			 * Write it.
414*49cdfc7eSAndroid Build Coastguard Worker 			 */
415*49cdfc7eSAndroid Build Coastguard Worker 			if (lseek64(fd, -xfr, 1) < 0) {
416*49cdfc7eSAndroid Build Coastguard Worker 				tst_brkm(TFAIL,
417*49cdfc7eSAndroid Build Coastguard Worker 					 NULL, "\tTest[%d]: lseek64(1) fail at %"
418*49cdfc7eSAndroid Build Coastguard Worker 					 PRIx64 ", errno = %d.", me,
419*49cdfc7eSAndroid Build Coastguard Worker 					 CHUNK(chunk), errno);
420*49cdfc7eSAndroid Build Coastguard Worker 			}
421*49cdfc7eSAndroid Build Coastguard Worker 			if ((xfr =
422*49cdfc7eSAndroid Build Coastguard Worker 			     writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) {
423*49cdfc7eSAndroid Build Coastguard Worker 				if (errno == ENOSPC) {
424*49cdfc7eSAndroid Build Coastguard Worker 					tst_resm(TFAIL,
425*49cdfc7eSAndroid Build Coastguard Worker 						 "\tTest[%d]: no space, exiting.",
426*49cdfc7eSAndroid Build Coastguard Worker 						 me);
427*49cdfc7eSAndroid Build Coastguard Worker 					fsync(fd);
428*49cdfc7eSAndroid Build Coastguard Worker 					tst_exit();
429*49cdfc7eSAndroid Build Coastguard Worker 				}
430*49cdfc7eSAndroid Build Coastguard Worker 				tst_brkm(TFAIL,
431*49cdfc7eSAndroid Build Coastguard Worker 					 NULL, "\tTest[%d]: writev fail at %" PRIx64
432*49cdfc7eSAndroid Build Coastguard Worker 					 "x xfr %d, errno = %d.", me,
433*49cdfc7eSAndroid Build Coastguard Worker 					 CHUNK(chunk), xfr, errno);
434*49cdfc7eSAndroid Build Coastguard Worker 			}
435*49cdfc7eSAndroid Build Coastguard Worker 			/*
436*49cdfc7eSAndroid Build Coastguard Worker 			 * If hit "misc" interval, do it.
437*49cdfc7eSAndroid Build Coastguard Worker 			 */
438*49cdfc7eSAndroid Build Coastguard Worker 			if (misc_intvl && --whenmisc <= 0) {
439*49cdfc7eSAndroid Build Coastguard Worker 				domisc(me, fd);
440*49cdfc7eSAndroid Build Coastguard Worker 				whenmisc = NEXTMISC;
441*49cdfc7eSAndroid Build Coastguard Worker 			}
442*49cdfc7eSAndroid Build Coastguard Worker 			if (count + collide > 2 * nchunks)
443*49cdfc7eSAndroid Build Coastguard Worker 				break;
444*49cdfc7eSAndroid Build Coastguard Worker 		}
445*49cdfc7eSAndroid Build Coastguard Worker 
446*49cdfc7eSAndroid Build Coastguard Worker 		/*
447*49cdfc7eSAndroid Build Coastguard Worker 		 * End of iteration, maybe before doing all chunks.
448*49cdfc7eSAndroid Build Coastguard Worker 		 */
449*49cdfc7eSAndroid Build Coastguard Worker 
450*49cdfc7eSAndroid Build Coastguard Worker 		if (count < nchunks) {
451*49cdfc7eSAndroid Build Coastguard Worker 			//tst_resm(TINFO, "\tTest{%d} val %d stopping @ %d, collide = {%d}.",
452*49cdfc7eSAndroid Build Coastguard Worker 			//              me, val, count, collide);
453*49cdfc7eSAndroid Build Coastguard Worker 			for (i = 0; i < nchunks; i++) {
454*49cdfc7eSAndroid Build Coastguard Worker 				if ((bits[i / 8] & (1 << (i % 8))) == 0) {
455*49cdfc7eSAndroid Build Coastguard Worker 					if (lseek64(fd, CHUNK(i), 0) <
456*49cdfc7eSAndroid Build Coastguard Worker 					    (off64_t) 0) {
457*49cdfc7eSAndroid Build Coastguard Worker 						tst_brkm(TFAIL,
458*49cdfc7eSAndroid Build Coastguard Worker 							 NULL, "\tTest[%d]: lseek64 fail at %"
459*49cdfc7eSAndroid Build Coastguard Worker 							 PRIx64
460*49cdfc7eSAndroid Build Coastguard Worker 							 "x, errno = %d.", me,
461*49cdfc7eSAndroid Build Coastguard Worker 							 CHUNK(i), errno);
462*49cdfc7eSAndroid Build Coastguard Worker 					}
463*49cdfc7eSAndroid Build Coastguard Worker 					if (writev(fd, &val_iovec[0], MAXIOVCNT)
464*49cdfc7eSAndroid Build Coastguard Worker 					    != csize) {
465*49cdfc7eSAndroid Build Coastguard Worker 						tst_brkm(TFAIL,
466*49cdfc7eSAndroid Build Coastguard Worker 							 NULL, "\tTest[%d]: writev fail at %"
467*49cdfc7eSAndroid Build Coastguard Worker 							 PRIx64
468*49cdfc7eSAndroid Build Coastguard Worker 							 "x, errno = %d.", me,
469*49cdfc7eSAndroid Build Coastguard Worker 							 CHUNK(i), errno);
470*49cdfc7eSAndroid Build Coastguard Worker 					}
471*49cdfc7eSAndroid Build Coastguard Worker 				}
472*49cdfc7eSAndroid Build Coastguard Worker 			}
473*49cdfc7eSAndroid Build Coastguard Worker 		}
474*49cdfc7eSAndroid Build Coastguard Worker 
475*49cdfc7eSAndroid Build Coastguard Worker 		fsync(fd);
476*49cdfc7eSAndroid Build Coastguard Worker 		++misc_cnt[m_fsync];
477*49cdfc7eSAndroid Build Coastguard Worker 		//tst_resm(TINFO, "\tTest[%d] val %d done, count = %d, collide = %d.",
478*49cdfc7eSAndroid Build Coastguard Worker 		//              me, val, count, collide);
479*49cdfc7eSAndroid Build Coastguard Worker 		//for (i = 0; i < NMISC; i++)
480*49cdfc7eSAndroid Build Coastguard Worker 		//      tst_resm(TINFO, "\t\tTest[%d]: %d %s's.", me, misc_cnt[i], m_str[i]);
481*49cdfc7eSAndroid Build Coastguard Worker 		val0 = val++;
482*49cdfc7eSAndroid Build Coastguard Worker 	}
483*49cdfc7eSAndroid Build Coastguard Worker }
484*49cdfc7eSAndroid Build Coastguard Worker 
485*49cdfc7eSAndroid Build Coastguard Worker /*
486*49cdfc7eSAndroid Build Coastguard Worker  * domisc()
487*49cdfc7eSAndroid Build Coastguard Worker  *	Inject misc syscalls into the thing.
488*49cdfc7eSAndroid Build Coastguard Worker  */
domisc(int me,int fd)489*49cdfc7eSAndroid Build Coastguard Worker static void domisc(int me, int fd)
490*49cdfc7eSAndroid Build Coastguard Worker {
491*49cdfc7eSAndroid Build Coastguard Worker 	enum m_type type;
492*49cdfc7eSAndroid Build Coastguard Worker 
493*49cdfc7eSAndroid Build Coastguard Worker 	if (misc_flag) {
494*49cdfc7eSAndroid Build Coastguard Worker 		type = m_fsync;
495*49cdfc7eSAndroid Build Coastguard Worker 		misc_flag = 0;
496*49cdfc7eSAndroid Build Coastguard Worker 	} else {
497*49cdfc7eSAndroid Build Coastguard Worker 		type = m_sync;;
498*49cdfc7eSAndroid Build Coastguard Worker 		misc_flag = 1;
499*49cdfc7eSAndroid Build Coastguard Worker 	}
500*49cdfc7eSAndroid Build Coastguard Worker 
501*49cdfc7eSAndroid Build Coastguard Worker 	switch (type) {
502*49cdfc7eSAndroid Build Coastguard Worker 	case m_fsync:
503*49cdfc7eSAndroid Build Coastguard Worker 		if (fsync(fd) < 0) {
504*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TFAIL, NULL, "\tTest[%d]: fsync error %d.",
505*49cdfc7eSAndroid Build Coastguard Worker 				 me,
506*49cdfc7eSAndroid Build Coastguard Worker 				 errno);
507*49cdfc7eSAndroid Build Coastguard Worker 		}
508*49cdfc7eSAndroid Build Coastguard Worker 		break;
509*49cdfc7eSAndroid Build Coastguard Worker 	case m_sync:
510*49cdfc7eSAndroid Build Coastguard Worker 		sync();
511*49cdfc7eSAndroid Build Coastguard Worker 		break;
512*49cdfc7eSAndroid Build Coastguard Worker 	}
513*49cdfc7eSAndroid Build Coastguard Worker 
514*49cdfc7eSAndroid Build Coastguard Worker 	++misc_cnt[type];
515*49cdfc7eSAndroid Build Coastguard Worker }
516*49cdfc7eSAndroid Build Coastguard Worker 
term(int sig LTP_ATTRIBUTE_UNUSED)517*49cdfc7eSAndroid Build Coastguard Worker static void term(int sig LTP_ATTRIBUTE_UNUSED)
518*49cdfc7eSAndroid Build Coastguard Worker {
519*49cdfc7eSAndroid Build Coastguard Worker 	int i;
520*49cdfc7eSAndroid Build Coastguard Worker 
521*49cdfc7eSAndroid Build Coastguard Worker 	tst_resm(TINFO, "\tterm -[%d]- got sig term.", getpid());
522*49cdfc7eSAndroid Build Coastguard Worker 
523*49cdfc7eSAndroid Build Coastguard Worker 	if (parent_pid == getpid()) {
524*49cdfc7eSAndroid Build Coastguard Worker 		for (i = 0; i < nchild; i++)
525*49cdfc7eSAndroid Build Coastguard Worker 			if (pidlist[i])
526*49cdfc7eSAndroid Build Coastguard Worker 				kill(pidlist[i], SIGTERM);
527*49cdfc7eSAndroid Build Coastguard Worker 		return;
528*49cdfc7eSAndroid Build Coastguard Worker 	}
529*49cdfc7eSAndroid Build Coastguard Worker 
530*49cdfc7eSAndroid Build Coastguard Worker 	tst_exit();
531*49cdfc7eSAndroid Build Coastguard Worker }
532*49cdfc7eSAndroid Build Coastguard Worker 
cleanup(void)533*49cdfc7eSAndroid Build Coastguard Worker void cleanup(void)
534*49cdfc7eSAndroid Build Coastguard Worker {
535*49cdfc7eSAndroid Build Coastguard Worker 
536*49cdfc7eSAndroid Build Coastguard Worker 	tst_rmdir();
537*49cdfc7eSAndroid Build Coastguard Worker }
538