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 <unistd.h> 17 #include <stdio.h> 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <fcntl.h> 21 22 #define MAXFDS 128 23 24 struct state { 25 char name[16]; 26 int state; 27 int isdir; 28 }; 29 30 #define STATE_CLEAR 0 31 #define STATE_CREATED 1 32 #define STATE_DELETED 2 33 34 struct state state_array[MAXFDS]; 35 36 #define DATA_SIZE 65536 37 38 char data_buffer[DATA_SIZE]; 39 40 void clear_state_array() 41 { 42 int i; 43 44 for (i = 0; i < MAXFDS; i++) 45 state_array[i].state = STATE_CLEAR; 46 } 47 48 int get_random_fd() 49 { 50 int fd; 51 52 while (1) { 53 fd = ((int) random()) % MAXFDS; 54 if (fd > 2) 55 return fd; 56 } 57 } 58 59 unsigned int get_inode_num(int fd) 60 { 61 struct stat st; 62 63 if (fstat(fd, &st) < 0) { 64 perror("fstat"); 65 return 0; 66 } 67 return st.st_ino; 68 } 69 70 71 void create_random_file() 72 { 73 char template[16] = "EX.XXXXXX"; 74 int fd; 75 int isdir = 0; 76 int size; 77 78 mktemp(template); 79 isdir = random() & 1; 80 if (isdir) { 81 if (mkdir(template, 0700) < 0) 82 return; 83 fd = open(template, O_RDONLY, 0600); 84 printf("Created temp directory %s, fd = %d\n", 85 template, fd); 86 } else { 87 size = random() & (DATA_SIZE-1); 88 fd = open(template, O_CREAT|O_RDWR, 0600); 89 write(fd, data_buffer, size); 90 printf("Created temp file %s, fd = %d, size=%d\n", 91 template, fd, size); 92 } 93 state_array[fd].isdir = isdir; 94 if (fd < 0) 95 return; 96 state_array[fd].isdir = isdir; 97 state_array[fd].state = STATE_CREATED; 98 strcpy(state_array[fd].name, template); 99 } 100 101 void truncate_file(int fd) 102 { 103 int size; 104 105 size = random() & (DATA_SIZE-1); 106 107 if (state_array[fd].isdir) 108 return; 109 110 ftruncate(fd, size); 111 printf("Truncating temp file %s, fd = %d, ino=%u, size=%d\n", 112 state_array[fd].name, fd, get_inode_num(fd), size); 113 } 114 115 116 void unlink_file(int fd) 117 { 118 char *filename = state_array[fd].name; 119 120 printf("Deleting %s, fd = %d, ino = %u\n", filename, fd, 121 get_inode_num(fd)); 122 123 if (state_array[fd].isdir) 124 rmdir(filename); 125 else 126 unlink(filename); 127 state_array[fd].state = STATE_DELETED; 128 } 129 130 void close_file(int fd) 131 { 132 char *filename = state_array[fd].name; 133 134 printf("Closing %s, fd = %d, ino = %u\n", filename, fd, 135 get_inode_num(fd)); 136 137 close(fd); 138 state_array[fd].state = STATE_CLEAR; 139 } 140 141 142 main(int argc, char **argv) 143 { 144 int i, fd; 145 146 memset(data_buffer, 0, sizeof(data_buffer)); 147 sprintf(data_buffer, "This is a test file created by the " 148 "random_exerciser program\n"); 149 150 for (i=0; i < 100000; i++) { 151 fd = get_random_fd(); 152 switch (state_array[fd].state) { 153 case STATE_CLEAR: 154 create_random_file(); 155 break; 156 case STATE_CREATED: 157 if ((state_array[fd].isdir == 0) && 158 (random() & 2)) 159 truncate_file(fd); 160 else 161 unlink_file(fd); 162 break; 163 case STATE_DELETED: 164 close_file(fd); 165 break; 166 } 167 } 168 } 169 170 171