xref: /aosp_15_r20/external/e2fsprogs/tests/progs/random_exercise.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker  * random_exercise.c --- Test program which exercises an ext2
3*6a54128fSAndroid Build Coastguard Worker  * 	filesystem.  It creates a lot of random files in the current
4*6a54128fSAndroid Build Coastguard Worker  * 	directory, while holding some files open while they are being
5*6a54128fSAndroid Build Coastguard Worker  * 	deleted.  This exercises the orphan list code, as well as
6*6a54128fSAndroid Build Coastguard Worker  * 	creating lots of fodder for the ext3 journal.
7*6a54128fSAndroid Build Coastguard Worker  *
8*6a54128fSAndroid Build Coastguard Worker  * Copyright (C) 2000 Theodore Ts'o.
9*6a54128fSAndroid Build Coastguard Worker  *
10*6a54128fSAndroid Build Coastguard Worker  * %Begin-Header%
11*6a54128fSAndroid Build Coastguard Worker  * This file may be redistributed under the terms of the GNU Public
12*6a54128fSAndroid Build Coastguard Worker  * License.
13*6a54128fSAndroid Build Coastguard Worker  * %End-Header%
14*6a54128fSAndroid Build Coastguard Worker  */
15*6a54128fSAndroid Build Coastguard Worker 
16*6a54128fSAndroid Build Coastguard Worker #include "config.h"
17*6a54128fSAndroid Build Coastguard Worker #include <unistd.h>
18*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
19*6a54128fSAndroid Build Coastguard Worker #include <sys/types.h>
20*6a54128fSAndroid Build Coastguard Worker #include <sys/stat.h>
21*6a54128fSAndroid Build Coastguard Worker #include <fcntl.h>
22*6a54128fSAndroid Build Coastguard Worker 
23*6a54128fSAndroid Build Coastguard Worker #define MAXFDS	128
24*6a54128fSAndroid Build Coastguard Worker 
25*6a54128fSAndroid Build Coastguard Worker struct state {
26*6a54128fSAndroid Build Coastguard Worker 	char	name[16];
27*6a54128fSAndroid Build Coastguard Worker 	int	state;
28*6a54128fSAndroid Build Coastguard Worker 	int	isdir;
29*6a54128fSAndroid Build Coastguard Worker };
30*6a54128fSAndroid Build Coastguard Worker 
31*6a54128fSAndroid Build Coastguard Worker #define STATE_CLEAR	0
32*6a54128fSAndroid Build Coastguard Worker #define STATE_CREATED	1
33*6a54128fSAndroid Build Coastguard Worker #define STATE_DELETED	2
34*6a54128fSAndroid Build Coastguard Worker 
35*6a54128fSAndroid Build Coastguard Worker struct state state_array[MAXFDS];
36*6a54128fSAndroid Build Coastguard Worker 
37*6a54128fSAndroid Build Coastguard Worker #define DATA_SIZE 65536
38*6a54128fSAndroid Build Coastguard Worker 
39*6a54128fSAndroid Build Coastguard Worker char data_buffer[DATA_SIZE];
40*6a54128fSAndroid Build Coastguard Worker 
clear_state_array()41*6a54128fSAndroid Build Coastguard Worker void clear_state_array()
42*6a54128fSAndroid Build Coastguard Worker {
43*6a54128fSAndroid Build Coastguard Worker 	int	i;
44*6a54128fSAndroid Build Coastguard Worker 
45*6a54128fSAndroid Build Coastguard Worker 	for (i = 0; i < MAXFDS; i++)
46*6a54128fSAndroid Build Coastguard Worker 		state_array[i].state = STATE_CLEAR;
47*6a54128fSAndroid Build Coastguard Worker }
48*6a54128fSAndroid Build Coastguard Worker 
get_random_fd()49*6a54128fSAndroid Build Coastguard Worker int get_random_fd()
50*6a54128fSAndroid Build Coastguard Worker {
51*6a54128fSAndroid Build Coastguard Worker 	int	fd;
52*6a54128fSAndroid Build Coastguard Worker 
53*6a54128fSAndroid Build Coastguard Worker 	while (1) {
54*6a54128fSAndroid Build Coastguard Worker 		fd = ((int) random()) % MAXFDS;
55*6a54128fSAndroid Build Coastguard Worker 		if (fd > 2)
56*6a54128fSAndroid Build Coastguard Worker 			return fd;
57*6a54128fSAndroid Build Coastguard Worker 	}
58*6a54128fSAndroid Build Coastguard Worker }
59*6a54128fSAndroid Build Coastguard Worker 
get_inode_num(int fd)60*6a54128fSAndroid Build Coastguard Worker unsigned int get_inode_num(int fd)
61*6a54128fSAndroid Build Coastguard Worker {
62*6a54128fSAndroid Build Coastguard Worker 	struct stat st;
63*6a54128fSAndroid Build Coastguard Worker 
64*6a54128fSAndroid Build Coastguard Worker 	if (fstat(fd, &st) < 0) {
65*6a54128fSAndroid Build Coastguard Worker 		perror("fstat");
66*6a54128fSAndroid Build Coastguard Worker 		return 0;
67*6a54128fSAndroid Build Coastguard Worker 	}
68*6a54128fSAndroid Build Coastguard Worker 	return st.st_ino;
69*6a54128fSAndroid Build Coastguard Worker }
70*6a54128fSAndroid Build Coastguard Worker 
71*6a54128fSAndroid Build Coastguard Worker 
create_random_file()72*6a54128fSAndroid Build Coastguard Worker void create_random_file()
73*6a54128fSAndroid Build Coastguard Worker {
74*6a54128fSAndroid Build Coastguard Worker 	char template[16] = "EX.XXXXXX";
75*6a54128fSAndroid Build Coastguard Worker 	int	fd;
76*6a54128fSAndroid Build Coastguard Worker 	int	isdir = 0;
77*6a54128fSAndroid Build Coastguard Worker 	int	size;
78*6a54128fSAndroid Build Coastguard Worker 
79*6a54128fSAndroid Build Coastguard Worker 	mktemp(template);
80*6a54128fSAndroid Build Coastguard Worker 	isdir = random() & 1;
81*6a54128fSAndroid Build Coastguard Worker 	if (isdir) {
82*6a54128fSAndroid Build Coastguard Worker 		if (mkdir(template, 0700) < 0)
83*6a54128fSAndroid Build Coastguard Worker 			return;
84*6a54128fSAndroid Build Coastguard Worker 		fd = open(template, O_RDONLY, 0600);
85*6a54128fSAndroid Build Coastguard Worker 		printf("Created temp directory %s, fd = %d\n",
86*6a54128fSAndroid Build Coastguard Worker 		       template, fd);
87*6a54128fSAndroid Build Coastguard Worker 	} else {
88*6a54128fSAndroid Build Coastguard Worker 		size = random() & (DATA_SIZE-1);
89*6a54128fSAndroid Build Coastguard Worker 		fd = open(template, O_CREAT|O_RDWR, 0600);
90*6a54128fSAndroid Build Coastguard Worker 		write(fd, data_buffer, size);
91*6a54128fSAndroid Build Coastguard Worker 		printf("Created temp file %s, fd = %d, size=%d\n",
92*6a54128fSAndroid Build Coastguard Worker 		       template, fd, size);
93*6a54128fSAndroid Build Coastguard Worker 	}
94*6a54128fSAndroid Build Coastguard Worker 	state_array[fd].isdir = isdir;
95*6a54128fSAndroid Build Coastguard Worker 	if (fd < 0)
96*6a54128fSAndroid Build Coastguard Worker 		return;
97*6a54128fSAndroid Build Coastguard Worker 	state_array[fd].isdir = isdir;
98*6a54128fSAndroid Build Coastguard Worker 	state_array[fd].state = STATE_CREATED;
99*6a54128fSAndroid Build Coastguard Worker 	strcpy(state_array[fd].name, template);
100*6a54128fSAndroid Build Coastguard Worker }
101*6a54128fSAndroid Build Coastguard Worker 
truncate_file(int fd)102*6a54128fSAndroid Build Coastguard Worker void truncate_file(int fd)
103*6a54128fSAndroid Build Coastguard Worker {
104*6a54128fSAndroid Build Coastguard Worker 	int	size;
105*6a54128fSAndroid Build Coastguard Worker 
106*6a54128fSAndroid Build Coastguard Worker 	size = random() & (DATA_SIZE-1);
107*6a54128fSAndroid Build Coastguard Worker 
108*6a54128fSAndroid Build Coastguard Worker 	if (state_array[fd].isdir)
109*6a54128fSAndroid Build Coastguard Worker 		return;
110*6a54128fSAndroid Build Coastguard Worker 
111*6a54128fSAndroid Build Coastguard Worker 	ftruncate(fd, size);
112*6a54128fSAndroid Build Coastguard Worker 	printf("Truncating temp file %s, fd = %d, ino=%u, size=%d\n",
113*6a54128fSAndroid Build Coastguard Worker 	       state_array[fd].name, fd, get_inode_num(fd), size);
114*6a54128fSAndroid Build Coastguard Worker }
115*6a54128fSAndroid Build Coastguard Worker 
116*6a54128fSAndroid Build Coastguard Worker 
unlink_file(int fd)117*6a54128fSAndroid Build Coastguard Worker void unlink_file(int fd)
118*6a54128fSAndroid Build Coastguard Worker {
119*6a54128fSAndroid Build Coastguard Worker 	char *filename = state_array[fd].name;
120*6a54128fSAndroid Build Coastguard Worker 
121*6a54128fSAndroid Build Coastguard Worker 	printf("Deleting %s, fd = %d, ino = %u\n", filename, fd,
122*6a54128fSAndroid Build Coastguard Worker 	       get_inode_num(fd));
123*6a54128fSAndroid Build Coastguard Worker 
124*6a54128fSAndroid Build Coastguard Worker 	if (state_array[fd].isdir)
125*6a54128fSAndroid Build Coastguard Worker 		rmdir(filename);
126*6a54128fSAndroid Build Coastguard Worker 	else
127*6a54128fSAndroid Build Coastguard Worker 		unlink(filename);
128*6a54128fSAndroid Build Coastguard Worker 	state_array[fd].state = STATE_DELETED;
129*6a54128fSAndroid Build Coastguard Worker }
130*6a54128fSAndroid Build Coastguard Worker 
close_file(int fd)131*6a54128fSAndroid Build Coastguard Worker void close_file(int fd)
132*6a54128fSAndroid Build Coastguard Worker {
133*6a54128fSAndroid Build Coastguard Worker 	char *filename = state_array[fd].name;
134*6a54128fSAndroid Build Coastguard Worker 
135*6a54128fSAndroid Build Coastguard Worker 	printf("Closing %s, fd = %d, ino = %u\n", filename, fd,
136*6a54128fSAndroid Build Coastguard Worker 	       get_inode_num(fd));
137*6a54128fSAndroid Build Coastguard Worker 
138*6a54128fSAndroid Build Coastguard Worker 	close(fd);
139*6a54128fSAndroid Build Coastguard Worker 	state_array[fd].state = STATE_CLEAR;
140*6a54128fSAndroid Build Coastguard Worker }
141*6a54128fSAndroid Build Coastguard Worker 
142*6a54128fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)143*6a54128fSAndroid Build Coastguard Worker main(int argc, char **argv)
144*6a54128fSAndroid Build Coastguard Worker {
145*6a54128fSAndroid Build Coastguard Worker 	int	i, fd;
146*6a54128fSAndroid Build Coastguard Worker 
147*6a54128fSAndroid Build Coastguard Worker 	memset(data_buffer, 0, sizeof(data_buffer));
148*6a54128fSAndroid Build Coastguard Worker 	sprintf(data_buffer, "This is a test file created by the "
149*6a54128fSAndroid Build Coastguard Worker 		"random_exerciser program\n");
150*6a54128fSAndroid Build Coastguard Worker 
151*6a54128fSAndroid Build Coastguard Worker 	for (i=0; i < 100000; i++) {
152*6a54128fSAndroid Build Coastguard Worker 		fd = get_random_fd();
153*6a54128fSAndroid Build Coastguard Worker 		switch (state_array[fd].state) {
154*6a54128fSAndroid Build Coastguard Worker 		case STATE_CLEAR:
155*6a54128fSAndroid Build Coastguard Worker 			create_random_file();
156*6a54128fSAndroid Build Coastguard Worker 			break;
157*6a54128fSAndroid Build Coastguard Worker 		case STATE_CREATED:
158*6a54128fSAndroid Build Coastguard Worker 			if ((state_array[fd].isdir == 0) &&
159*6a54128fSAndroid Build Coastguard Worker 			    (random() & 2))
160*6a54128fSAndroid Build Coastguard Worker 				truncate_file(fd);
161*6a54128fSAndroid Build Coastguard Worker 			else
162*6a54128fSAndroid Build Coastguard Worker 				unlink_file(fd);
163*6a54128fSAndroid Build Coastguard Worker 			break;
164*6a54128fSAndroid Build Coastguard Worker 		case STATE_DELETED:
165*6a54128fSAndroid Build Coastguard Worker 			close_file(fd);
166*6a54128fSAndroid Build Coastguard Worker 			break;
167*6a54128fSAndroid Build Coastguard Worker 		}
168*6a54128fSAndroid Build Coastguard Worker 	}
169*6a54128fSAndroid Build Coastguard Worker }
170*6a54128fSAndroid Build Coastguard Worker 
171*6a54128fSAndroid Build Coastguard Worker 
172