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 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 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 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 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 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 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 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 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