]> www.infradead.org Git - mtd-utils.git/commitdiff
nanddump: add --skipbad option for bad blocks
authorBrian Norris <computersforpeace@gmail.com>
Fri, 3 Jun 2011 18:25:00 +0000 (11:25 -0700)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Mon, 6 Jun 2011 11:09:33 +0000 (14:09 +0300)
This patch adds a new option "--skipbad" to nanddump. It is subtly
different than "--omitbad". The following description was included in
the help message to attempt to clarify the differences.

 Notes on --omitbad and --skipbad:
   With either option, we stop dumping data when we encounter a bad block
   and resume dumping at the next good block. However, with --omitbad, we
   count the bad block as part of the total dump length, whereas with
   --skipbad, the bad block is 'skipped,' that is, not counted toward the
   total dump length.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
nanddump.c

index 214fb1236607d98c394c866cc10efe56a734495c..78ea22ec48f7aa85a1a9039a7ad52bf5ef0a9759 100644 (file)
@@ -50,6 +50,7 @@ static void display_help(void)
 "-a         --forcebinary        Force printing of binary data to tty\n"
 "-c         --canonicalprint     Print canonical Hex+ASCII dump\n"
 "-f file    --file=file          Dump to file\n"
+"-k         --skipbad            Skip over bad blocks (see below)\n"
 "-l length  --length=length      Length\n"
 "-n         --noecc              Read without error correction\n"
 "-N         --noskipbad          Read without bad block skipping\n"
@@ -57,7 +58,14 @@ static void display_help(void)
 "-b         --omitbad            Omit bad blocks from the dump\n"
 "-p         --prettyprint        Print nice (hexdump)\n"
 "-q         --quiet              Don't display progress and status messages\n"
-"-s addr    --startaddress=addr  Start address\n",
+"-s addr    --startaddress=addr  Start address\n"
+"\n"
+"Notes on --omitbad and --skipbad:\n"
+"  With either option, we stop dumping data when we encounter a bad block\n"
+"  and resume dumping at the next good block. However, with --omitbad, we\n"
+"  count the bad block as part of the total dump length, whereas with\n"
+"  --skipbad, the bad block is 'skipped,' that is, not counted toward the\n"
+"  total dump length.\n",
        PROGRAM_NAME);
        exit(EXIT_SUCCESS);
 }
@@ -90,6 +98,7 @@ static bool                   omitbad = false;
 static bool                    quiet = false;          // suppress diagnostic output
 static bool                    canonical = false;      // print nice + ascii
 static bool                    forcebinary = false;    // force printing binary to tty
+static bool                    skipbad = false;        // skip over bad blocks
 
 static void process_options(int argc, char * const argv[])
 {
@@ -97,7 +106,7 @@ static void process_options(int argc, char * const argv[])
 
        for (;;) {
                int option_index = 0;
-               static const char *short_options = "bs:f:l:opqnNca";
+               static const char *short_options = "bs:f:l:opqnNcak";
                static const struct option long_options[] = {
                        {"help", no_argument, 0, 0},
                        {"version", no_argument, 0, 0},
@@ -111,6 +120,7 @@ static void process_options(int argc, char * const argv[])
                        {"length", required_argument, 0, 'l'},
                        {"noecc", no_argument, 0, 'n'},
                        {"noskipbad", no_argument, 0, 'N'},
+                       {"skipbad", no_argument, 0, 'k'},
                        {"quiet", no_argument, 0, 'q'},
                        {0, 0, 0, 0},
                };
@@ -167,6 +177,9 @@ static void process_options(int argc, char * const argv[])
                        case 'N':
                                noskipbad = true;
                                break;
+                       case 'k':
+                               skipbad = true;
+                               break;
                        case '?':
                                error++;
                                break;
@@ -193,6 +206,19 @@ static void process_options(int argc, char * const argv[])
                exit(EXIT_FAILURE);
        }
 
+       if (noskipbad && skipbad) {
+               fprintf(stderr, "The noskipbad and skipbad options are "
+                               "mutually-exclusive.\n"
+                               "Choose one or the other.\n");
+               exit(EXIT_FAILURE);
+       }
+
+       if (omitbad && skipbad) {
+               fprintf(stderr, "The omitbad and skipbad options are mutually-"
+                               "exclusive.\nChoose one or the other.\n");
+               exit(EXIT_FAILURE);
+       }
+
        if ((argc - optind) != 1 || error)
                display_help();
 
@@ -403,6 +429,14 @@ int main(int argc, char * const argv[])
                }
 
                if (badblock) {
+                       /* skip bad block, increase end_addr */
+                       if (skipbad) {
+                               end_addr += mtd.eb_size;
+                               ofs += mtd.eb_size - bs;
+                               if (end_addr > mtd.size)
+                                       end_addr = mtd.size;
+                               continue;
+                       }
                        if (omitbad)
                                continue;
                        memset(readbuf, 0xff, bs);