]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
badblocks: add a max bad blocks count option
authorIustin Pop <iustin@google.com>
Wed, 11 Jun 2008 11:12:17 +0000 (13:12 +0200)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 17 Jun 2008 11:33:29 +0000 (07:33 -0400)
Currently, badblocks will continue scanning the device until it reaches
last_block, even though it might be that the drive is not responding
at all anymore.

This patch introduces a new parameter ('-e') that allows one to specify
the maximum bad block count; if badblocks sees more than this number, it
will abort the test.

While this is not useful for testing a device that will need to be used
as a filesystem (because we don't get an exhaustive list of bad blocks),
it is useful for testing if a device has bad blocks at all: for example,
with a count of 1, it will finish after the first error thus not needing
to test the whole device if the only purpose of the test is to check for
any bad blocks.

Signed-off-by: Iustin Pop <iustin@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
misc/badblocks.8.in
misc/badblocks.c

index 47488100a40a2342df63fa5ec294de50fd7b5925..b83b598a9445ddd87f1a52db65675339d86dda6d 100644 (file)
@@ -16,6 +16,10 @@ badblocks \- search a device for bad blocks
 .I blocks_at_once
 ]
 [
+.B \-e
+.I max_bad_blocks
+]
+[
 .B \-i
 .I input_file
 ]
@@ -81,6 +85,11 @@ Specify the size of blocks in bytes.  The default is 1024.
 .BI \-c " number of blocks"
 is the number of blocks which are tested at a time.  The default is 64.
 .TP
+.BI \-e " max bad block count"
+Specify a maximum number of bad blocks before aborting the test.  The
+default is 0, meaning the test will continue until the end of the test
+range is reached.
+.TP
 .B \-f
 Normally, badblocks will refuse to do a read/write or a non-destructive
 test on a device which is mounted, since either can cause the system to
@@ -183,6 +192,13 @@ This option erases data!  If you want to do write-mode testing on
 an existing file system, use the
 .B \-n
 option instead.  It is slower, but it will preserve your data.  
+.PP
+The
+.B \-e
+option will cause badblocks to output a possibly incomplete list of
+bad blocks. Therefore it is recommended to use it only when one wants
+to know if there are any bad blocks at all on the device, and not when
+the list of bad blocks is wanted.
 .SH AUTHOR
 .B badblocks
 was written by Remy Card <Remy.Card@linux.org>.  Current maintainer is
index 709effe9539470d2de0f2595b0bbe70224cb8a36..d2992e364f5b684611b999e6e050fd6b7d1bea75 100644 (file)
@@ -70,6 +70,7 @@ 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 exclusive_ok = 0;
+static unsigned int max_bb = 0;                /* Abort test if more than this number of bad blocks has been encountered */
 
 #define T_INC 32
 
@@ -77,7 +78,7 @@ unsigned int sys_page_size = 4096;
 
 static void usage(void)
 {
-       fprintf(stderr, _("Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwnf]\n [-c blocks_at_once] [-p num_passes] [-t test_pattern [-t test_pattern [...]]]\n device [last_block [start_block]]\n"),
+       fprintf(stderr, _("Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwnf]\n [-c blocks_at_once] [-p num_passes] [-e max_bad_blocks] [-t test_pattern [-t test_pattern [...]]]\n device [last_block [start_block]]\n"),
                 program_name);
        exit (1);
 }
@@ -379,6 +380,12 @@ static unsigned int test_ro (int dev, blk_t last_block,
        }
        while (currently_testing < last_block)
        {
+               if (max_bb && bb_count >= max_bb) {
+                       if (s_flag || v_flag) {
+                               fputs(_("Too many bad blocks, aborting test\n"), stderr);
+                       }
+                       break;
+               }
                if (next_bad) {
                        if (currently_testing == next_bad) {
                                /* fprintf (out, "%lu\n", nextbad); */
@@ -476,6 +483,12 @@ static unsigned int test_rw (int dev, blk_t last_block,
 
                try = blocks_at_once;
                while (currently_testing < last_block) {
+                       if (max_bb && bb_count >= max_bb) {
+                               if (s_flag || v_flag) {
+                                       fputs(_("Too many bad blocks, aborting test\n"), stderr);
+                               }
+                               break;
+                       }
                        if (currently_testing + try > last_block)
                                try = last_block - currently_testing;
                        got = do_write(dev, buffer, try, block_size,
@@ -515,6 +528,12 @@ static unsigned int test_rw (int dev, blk_t last_block,
 
                try = blocks_at_once;
                while (currently_testing < last_block) {
+                       if (max_bb && bb_count >= max_bb) {
+                               if (s_flag || v_flag) {
+                                       fputs(_("Too many bad blocks, aborting test\n"), stderr);
+                               }
+                               break;
+                       }
                        if (currently_testing + try > last_block)
                                try = last_block - currently_testing;
                        got = do_read (dev, read_buffer, try, block_size,
@@ -652,6 +671,12 @@ static unsigned int test_nd (int dev, blk_t last_block,
                        alarm_intr(SIGALRM);
 
                while (currently_testing < last_block) {
+                       if (max_bb && bb_count >= max_bb) {
+                               if (s_flag || v_flag) {
+                                       fputs(_("Too many bad blocks, aborting test\n"), stderr);
+                               }
+                               break;
+                       }
                        got = try = blocks_at_once - buf_used;
                        if (next_bad) {
                                if (currently_testing == next_bad) {
@@ -884,7 +909,7 @@ int main (int argc, char ** argv)
        
        if (argc && *argv)
                program_name = *argv;
-       while ((c = getopt (argc, argv, "b:fi:o:svwnc:p:h:t:X")) != EOF) {
+       while ((c = getopt (argc, argv, "b:e:fi:o:svwnc:p:h:t:X")) != EOF) {
                switch (c) {
                case 'b':
                        block_size = parse_uint(optarg, "block size");
@@ -924,6 +949,9 @@ int main (int argc, char ** argv)
                case 'c':
                        blocks_at_once = parse_uint(optarg, "blocks at once");
                        break;
+               case 'e':
+                       max_bb = parse_uint(optarg, "max bad block count");
+                       break;
                case 'p':
                        num_passes = parse_uint(optarg, 
                                                "number of clean passes");