10 //#define pread(fd, buf, count, pos) read_pos(fd, pos, buf, count)
16 FILE *outputFile
= NULL
;
18 int scan_device(const char *dev
, off_t startBlock
, off_t endBlock
)
21 size_t len
= group
* blockSize
;
22 off_t block
= startBlock
;
23 off_t at
= block
* blockSize
;
27 buffer
= (char *)malloc(len
);
32 fd
= open(dev
, O_RDONLY
);
40 fprintf(stderr
, "Scanning '%s', %d * %d bytes at once\n",
41 dev
, group
, blockSize
);
44 fprintf(stderr
, "\n");
46 for (; block
<= endBlock
; block
+= group
, at
+= len
) {
49 fprintf(stderr
, "checking block %Ld\x1b[1A\n", block
);
50 got
= pread(fd
, buffer
, len
, at
);
55 fprintf(stderr
, "block %Ld (offset %Ld): got %d < %zd\n",
60 fprintf(stderr
, "block %Ld: error: %s\n", block
, strerror(errno
));
62 if (errno != EIO && errno != ENXIO) {
68 // try each block separately
69 for (i
= 0; i
< group
; i
++) {
70 got
= pread(fd
, buffer
, blockSize
, at
+ blockSize
* i
);
73 if (got
< blockSize
) {
75 fprintf(stderr
, "block %Ld: error: %s\n", block
+ i
, strerror(errno
));
77 fprintf(stderr
, "block %Ld: read %d bytes\n", block
+ i
, got
);
78 fprintf(outputFile
, "%Ld\n", block
+ i
);
95 fprintf(stderr
, "badblocks [-sv] [-b block-size] [-c block-at-once] "
96 "/dev/disk/... [end-block [start-block]]\n");
100 int main(int argc
, char **argv
)
103 off_t startBlock
= 0LL;
104 off_t endBlock
= INT64_MAX
;
109 while ((ch
= getopt(argc
, argv
, "b:c:hsv?")) != -1) {
112 blockSize
= atoi(optarg
);
113 //fprintf(stderr, "bs %d\n", blockSize);
116 group
= atoi(optarg
);
117 //fprintf(stderr, "g %d\n", group);
136 startBlock
= atoll(argv
[2]);
138 endBlock
= atoll(argv
[1]);
140 return scan_device(argv
[0], startBlock
, endBlock
);