/* Verification tool, designed to detect data corruption on a filesystem tridge@samba.org, March 2002 XFS space preallocation changes -- lord@sgi.com, April 2003 */ #include "global.h" #include /* variables settable on the command line */ static int loop_count = 100; static int num_files = 1; static int file_size = 1024*1024; static int block_size = 1024; static char *base_dir = "."; static int use_mmap; static int do_prealloc; static int use_sync; static int do_frags = 1; typedef unsigned char uchar; #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif static void *x_malloc(int size) { void *ret = malloc(size); if (!ret) { fprintf(stderr,"Out of memory for size %d!\n", size); exit(1); } return ret; } /* generate a buffer for a particular child, fnum etc. Just use a simple buffer to make debugging easy */ static void gen_buffer(char *buf, int loop, int child, int fnum, int ofs) { uchar v = (loop+child+fnum+(ofs/block_size)) % 256; memset(buf, v, block_size); } /* check if a buffer from disk is correct */ static void check_buffer(uchar *buf, int loop, int child, int fnum, int ofs) { char *buf2; buf2 = x_malloc(block_size); gen_buffer(buf2, loop, child, fnum, ofs); if (memcmp(buf, buf2, block_size) != 0) { int i, j; for (i=0;buf[i] == buf2[i] && id_name,".") == 0) continue; if (strcmp(de->d_name,"..") == 0) continue; sprintf(fname, "%s/%s", dir, de->d_name); if (lstat(fname, &st)) { perror(fname); continue; } if (S_ISDIR(st.st_mode)) { traverse(fname, fn); } fn(fname); } closedir(d); } /* the main child function - this creates/checks the file for one child */ static void run_child(int child) { int i, loop; char dir[1024]; sprintf(dir, "%s/child%d", base_dir, child); /* cleanup any old files */ if (remove(dir) != 0 && errno != ENOENT) { printf("Child %d cleaning %s\n", child, dir); traverse(dir, remove); remove(dir); } if (mkdir(dir, 0755) != 0) { perror(dir); exit(1); } for (loop = 0; loop < loop_count; loop++) { printf("Child %d loop %d\n", child, loop); for (i=0;i