diff options
Diffstat (limited to 'misc/badblocks.c')
-rw-r--r-- | misc/badblocks.c | 139 |
1 files changed, 82 insertions, 57 deletions
diff --git a/misc/badblocks.c b/misc/badblocks.c index 890d5107..e5024f6c 100644 --- a/misc/badblocks.c +++ b/misc/badblocks.c @@ -33,10 +33,6 @@ #define _GNU_SOURCE /* for O_DIRECT */ #endif -#ifndef O_LARGEFILE -#define O_LARGEFILE 0 -#endif - #include "config.h" #include <errno.h> #include <fcntl.h> @@ -65,27 +61,30 @@ extern int optind; #include "ext2fs/ext2fs.h" #include "nls-enable.h" -const char * program_name = "badblocks"; -const char * done_string = N_("done \n"); +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif -static int v_flag = 0; /* verbose */ -static int w_flag = 0; /* do r/w test: 0=no, 1=yes, +static const char * program_name = "badblocks"; +static const char * done_string = N_("done \n"); + +static int v_flag; /* verbose */ +static int w_flag; /* do r/w test: 0=no, 1=yes, * 2=non-destructive */ -static int s_flag = 0; /* show progress of test */ -static int force = 0; /* force check of mounted device */ -static int t_flag = 0; /* number of test patterns */ -static int t_max = 0; /* allocated test patterns */ -static unsigned int *t_patts = NULL; /* test patterns */ -static int current_O_DIRECT = 0; /* Current status of O_DIRECT flag */ -static int use_buffered_io = 0; -static int exclusive_ok = 0; -static unsigned int max_bb = 0; /* Abort test if more than this number of bad blocks has been encountered */ -static unsigned int d_flag = 0; /* delay factor between reads */ +static int s_flag; /* show progress of test */ +static int force; /* force check of mounted device */ +static int t_flag; /* number of test patterns */ +static int t_max; /* allocated test patterns */ +static unsigned int *t_patts; /* test patterns */ +static int use_buffered_io; +static int exclusive_ok; +static unsigned int max_bb; /* Abort test if more than this number of bad blocks has been encountered */ +static unsigned int d_flag; /* delay factor between reads */ static struct timeval time_start; #define T_INC 32 -unsigned int sys_page_size = 4096; +static unsigned int sys_page_size = 4096; static void usage(void) { @@ -286,6 +285,7 @@ static void set_o_direct(int dev, unsigned char *buffer, size_t size, ext2_loff_t offset) { #ifdef O_DIRECT + static int current_O_DIRECT; /* Current status of O_DIRECT flag */ int new_flag = O_DIRECT; int flag; @@ -300,7 +300,8 @@ static void set_o_direct(int dev, unsigned char *buffer, size_t size, flag = fcntl(dev, F_GETFL); if (flag > 0) { flag = (flag & ~O_DIRECT) | new_flag; - fcntl(dev, F_SETFL, flag); + if (fcntl(dev, F_SETFL, flag) < 0) + perror("set_o_direct"); } current_O_DIRECT = new_flag; } @@ -369,7 +370,7 @@ static int do_read (int dev, unsigned char * buffer, int try, int block_size, /* Seek to the correct loc. */ if (ext2fs_llseek (dev, (ext2_loff_t) current_block * block_size, SEEK_SET) != (ext2_loff_t) current_block * block_size) - com_err (program_name, errno, _("during seek")); + com_err (program_name, errno, "%s", _("during seek")); /* Try the read */ if (d_flag) @@ -442,7 +443,7 @@ static int do_write(int dev, unsigned char * buffer, int try, int block_size, /* Seek to the correct loc. */ if (ext2fs_llseek (dev, (ext2_loff_t) current_block * block_size, SEEK_SET) != (ext2_loff_t) current_block * block_size) - com_err (program_name, errno, _("during seek")); + com_err (program_name, errno, "%s", _("during seek")); /* Try the write */ got = write (dev, buffer, try * block_size); @@ -466,7 +467,8 @@ static void flush_bufs(void) #endif retval = ext2fs_sync_device(host_dev, 1); if (retval) - com_err(program_name, retval, _("during ext2fs_sync_device")); + com_err(program_name, retval, "%s", + _("during ext2fs_sync_device")); } static unsigned int test_ro (int dev, blk_t last_block, @@ -485,8 +487,8 @@ static unsigned int test_ro (int dev, blk_t last_block, errcode = ext2fs_badblocks_list_iterate_begin(bb_list,&bb_iter); if (errcode) { - com_err (program_name, errcode, - _("while beginning bad block list iteration")); + com_err(program_name, errcode, "%s", + _("while beginning bad block list iteration")); exit (1); } do { @@ -500,13 +502,14 @@ static unsigned int test_ro (int dev, blk_t last_block, } if (!blkbuf) { - com_err (program_name, ENOMEM, _("while allocating buffers")); + com_err(program_name, ENOMEM, "%s", + _("while allocating buffers")); exit (1); } if (v_flag) { - fprintf (stderr, _("Checking blocks %lu to %lu\n"), - (unsigned long) first_block, - (unsigned long) last_block - 1); + fprintf(stderr, _("Checking blocks %lu to %lu\n"), + (unsigned long)first_block, + (unsigned long)last_block - 1); } if (t_flag) { fputs(_("Checking for bad blocks in read-only mode\n"), stderr); @@ -557,7 +560,7 @@ static unsigned int test_ro (int dev, blk_t last_block, currently_testing += got; if (got != try) { try = 1; - if (recover_block == ~0) + if (recover_block == ~0U) recover_block = currently_testing - got + blocks_at_once; continue; @@ -599,7 +602,8 @@ static unsigned int test_rw (int dev, blk_t last_block, read_buffer = buffer + blocks_at_once * block_size; if (!buffer) { - com_err (program_name, ENOMEM, _("while allocating buffers")); + com_err(program_name, ENOMEM, "%s", + _("while allocating buffers")); exit (1); } @@ -647,7 +651,7 @@ static unsigned int test_rw (int dev, blk_t last_block, currently_testing += got; if (got != try) { try = 1; - if (recover_block == ~0) + if (recover_block == ~0U) recover_block = currently_testing - got + blocks_at_once; continue; @@ -686,13 +690,13 @@ static unsigned int test_rw (int dev, blk_t last_block, currently_testing += got; if (got != try) { try = 1; - if (recover_block == ~0) + if (recover_block == ~0U) recover_block = currently_testing - got + blocks_at_once; continue; } else if (currently_testing == recover_block) { try = blocks_at_once; - recover_block = ~0; + recover_block = ~0U; } for (i=0; i < got; i++) { if (memcmp(read_buffer + i * block_size, @@ -739,14 +743,14 @@ static unsigned int test_nd (int dev, blk_t last_block, errcode_t errcode; unsigned long buf_used; static unsigned int bb_count; - int granularity = blocks_at_once; - blk_t recover_block = ~0; + unsigned int granularity = blocks_at_once; + blk_t recover_block = ~0U; bb_count = 0; errcode = ext2fs_badblocks_list_iterate_begin(bb_list,&bb_iter); if (errcode) { - com_err (program_name, errcode, - _("while beginning bad block list iteration")); + com_err(program_name, errcode, "%s", + _("while beginning bad block list iteration")); exit (1); } do { @@ -754,9 +758,10 @@ static unsigned int test_nd (int dev, blk_t last_block, } while (next_bad && next_bad < first_block); blkbuf = allocate_buffer(3 * blocks_at_once * block_size); - test_record = malloc (blocks_at_once*sizeof(struct saved_blk_record)); + test_record = malloc(blocks_at_once * sizeof(struct saved_blk_record)); if (!blkbuf || !test_record) { - com_err(program_name, ENOMEM, _("while allocating buffers")); + com_err(program_name, ENOMEM, "%s", + _("while allocating buffers")); exit (1); } @@ -839,7 +844,7 @@ static unsigned int test_nd (int dev, blk_t last_block, got = do_read (dev, save_ptr, try, block_size, currently_testing); if (got == 0) { - if (recover_block == ~0) + if (recover_block == ~0U) recover_block = currently_testing + blocks_at_once; if (granularity != 1) { @@ -874,7 +879,7 @@ static unsigned int test_nd (int dev, blk_t last_block, currently_testing += got; if (got != try) { try = 1; - if (recover_block == ~0) + if (recover_block == ~0U) recover_block = currently_testing - got + blocks_at_once; continue; @@ -1047,6 +1052,7 @@ int main (int argc, char ** argv) unsigned int); int open_flag; long sysval; + blk64_t inblk; setbuf(stdout, NULL); setbuf(stderr, NULL); @@ -1159,15 +1165,15 @@ int main (int argc, char ** argv) } if (!w_flag) { if (t_flag > 1) { - com_err(program_name, 0, - _("Maximum of one test_pattern may be specified " - "in read-only mode")); + com_err(program_name, 0, "%s", + _("Maximum of one test_pattern may be " + "specified in read-only mode")); exit(1); } if (t_patts && (t_patts[0] == (unsigned int) ~0)) { - com_err(program_name, 0, - _("Random test_pattern is not allowed " - "in read-only mode")); + com_err(program_name, 0, "%s", + _("Random test_pattern is not allowed " + "in read-only mode")); exit(1); } } @@ -1179,13 +1185,13 @@ int main (int argc, char ** argv) block_size, &last_block); if (errcode == EXT2_ET_UNIMPLEMENTED) { - com_err(program_name, 0, + com_err(program_name, 0, "%s", _("Couldn't determine device size; you " "must specify\nthe size manually\n")); exit(1); } if (errcode) { - com_err(program_name, errcode, + com_err(program_name, errcode, "%s", _("while trying to determine device size")); exit(1); } @@ -1200,10 +1206,17 @@ int main (int argc, char ** argv) first_block = parse_uint(argv[optind], _("first block")); } else first_block = 0; if (first_block >= last_block) { - com_err (program_name, 0, _("invalid starting block (%lu): must be less than %lu"), - (unsigned long) first_block, (unsigned long) last_block); + com_err (program_name, 0, _("invalid starting block (%llu): must be less than %llu"), + first_block, last_block); exit (1); } + /* ext2 badblocks file can't handle large values */ + if (last_block >> 32) { + com_err(program_name, EOVERFLOW, + _("invalid end block (%llu): must be 32-bit value"), + last_block); + exit(1); + } if (w_flag) check_mount(device_name); @@ -1255,23 +1268,35 @@ int main (int argc, char ** argv) errcode = ext2fs_badblocks_list_create(&bb_list,0); if (errcode) { - com_err (program_name, errcode, - _("while creating in-memory bad blocks list")); + com_err(program_name, errcode, "%s", + _("while creating in-memory bad blocks list")); exit (1); } if (in) { for(;;) { - switch(fscanf (in, "%u\n", &next_bad)) { + switch (fscanf(in, "%llu\n", &inblk)) { case 0: - com_err (program_name, 0, "input file - bad format"); + com_err(program_name, 0, "%s", + _("input file - bad format")); exit (1); case EOF: break; default: + if (inblk >> 32) { + com_err(program_name, + EOVERFLOW, "%s", + _("while adding to in-memory " + "bad block list")); + exit(1); + } + next_bad = inblk; errcode = ext2fs_badblocks_list_add(bb_list,next_bad); if (errcode) { - com_err (program_name, errcode, _("while adding to in-memory bad block list")); + com_err(program_name, errcode, + "%s", + _("while adding to in-memory " + "bad block list")); exit (1); } continue; |