1 #define _FILE_OFFSET_BITS 64
9 #include <asm/unistd.h>
10 #include <asm/fcntl.h>
11 #include <sys/mount.h>
15 static int block_size = 1024;
16 static unsigned read_prob = 50;
17 static unsigned num_reads, num_writes, num_fails;
18 static unsigned rep_time = 10;
20 void bit_set(unsigned char *bm, off_t i)
22 bm[i/8] |= (1<<(i%8));
25 unsigned bit_query(unsigned char *bm, off_t i)
27 return (bm[i/8] & (1<<(i%8))) ? 1 : 0;
30 static void do_seek(int fd, off_t ofs)
32 if (lseek(fd, ofs, SEEK_SET) != ofs) {
38 static void init_buf(unsigned *buf, unsigned bnum)
43 for (i=1;i<block_size/4;i++) buf[i] = random();
46 static void write_block(int fd, unsigned *buf, off_t i)
48 do_seek(fd, i*(off_t)block_size);
49 if (write(fd, buf, block_size) != block_size) {
50 fprintf(stderr,"write failed on block %u\n", (unsigned)i);
55 static void check_block(int fd, unsigned *buf, off_t i)
57 unsigned buf2[block_size/4];
59 do_seek(fd, i*(off_t)block_size);
60 if (read(fd, buf2, block_size) != block_size) {
61 fprintf(stderr,"read failed on block %u\n", (unsigned)i);
64 if (memcmp(buf, buf2, block_size) != 0) {
65 int j, count=0, first = -1;
66 for (j=0; j<block_size/4; j++) {
67 if (buf[j] != buf2[j]) {
69 if (first == -1) first = j;
72 printf("compare failed on block %u (%d words differ) 1st error at word %u\n",
73 (unsigned)i, count, first);
74 fd = open("buf1.dat", O_WRONLY|O_CREAT|O_TRUNC, 0644);
75 write(fd, buf, block_size);
77 fd = open("buf2.dat", O_WRONLY|O_CREAT|O_TRUNC, 0644);
78 write(fd, buf2, block_size);
80 printf("Wrote good data to buf1.dat\n");
81 printf("Wrote bad data to buf2.dat\n");
87 static void try_block(int fd, off_t i, unsigned char *bitmap)
90 buf = (unsigned *)memalign(block_size, block_size);
92 if (!bit_query(bitmap, i) || (random()%100 > read_prob)) {
95 write_block(fd, buf, i);
99 check_block(fd, buf, i);
107 static void disk_test(char *dev)
111 unsigned char *bitmap;
116 fd = open(dev, O_RDWR|O_SYNC|O_LARGEFILE);
123 if (ioctl(fd, BLKGETSIZE, &blocks) != 0) {
124 fprintf(stderr,"BLKGETSIZE failed\n");
128 blocks /= (block_size/512);
131 bitmap = calloc((blocks+7)/8, 1);
133 fprintf(stderr,"malloc of bitmap failed\n");
139 printf("starting disktest on %s with %u blocks of size %u\n",
140 dev, blocks, block_size);
141 printf("using read probability of %u%%\n", read_prob);
148 i = ((unsigned)random()) % blocks;
150 try_block(fd, blk % blocks, bitmap);
151 try_block(fd, i, bitmap);
159 if (t2 - t1 >= rep_time) {
160 printf("%s %d blocks (%d reads, %d writes, %d fails, %.2fMB/sec)\n",
161 dev, count, num_reads, num_writes, num_fails,
162 1.0e-6*(count2*block_size)/(t2-t1));
163 srandom(random() | time(NULL));
174 static void usage(void)
178 "usage: disktest [options] <device>\n" \
181 " -B <blocks> set block count\n" \
182 " -s <blk_size> set block size\n" \
183 " -R <value> set read probability (1-100)\n" \
184 " -t <value> set report time in seconds\n" \
190 int main(int argc, char *argv[])
196 while ((opt = getopt(argc, argv, "B:s:R:t:h")) != EOF) {
199 blocks = atoi(optarg);
202 block_size = atoi(optarg);
205 read_prob = atoi(optarg);
208 rep_time = atoi(optarg);
219 if (argc < 1) usage();