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