UBIFS: clean up LEB recovery function
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Mon, 16 May 2011 10:41:55 +0000 (13:41 +0300)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Mon, 16 May 2011 12:48:48 +0000 (15:48 +0300)
This patch cleans up 'ubifs_recover_leb()' function and makes it more readable.
Move things which are done only once out of the loop and kill unneeded 'switch'
statement.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
fs/ubifs/recovery.c

index 42b4512c46b0a31dc231e5479d24da4281228d58..7d922033d666b5fb350ae36a669b53c4ada8432e 100644 (file)
@@ -609,8 +609,8 @@ static int drop_incomplete_group(struct ubifs_scan_leb *sleb, int *offs)
 struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
                                         int offs, void *sbuf, int grouped)
 {
-       int err, len = c->leb_size - offs, need_clean = 0, quiet = 1;
-       int empty_chkd = 0, start = offs;
+       int ret = 0, err, len = c->leb_size - offs, need_clean = 0;
+       int start = offs;
        struct ubifs_scan_leb *sleb;
        void *buf = sbuf + offs;
 
@@ -624,8 +624,6 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
                need_clean = 1;
 
        while (len >= 8) {
-               int ret;
-
                dbg_scan("look at LEB %d:%d (%d bytes left)",
                         lnum, offs, len);
 
@@ -635,8 +633,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
                 * Scan quietly until there is an error from which we cannot
                 * recover
                 */
-               ret = ubifs_scan_a_node(c, buf, len, lnum, offs, quiet);
-
+               ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0);
                if (ret == SCANNED_A_NODE) {
                        /* A valid node, and not a padding node */
                        struct ubifs_ch *ch = buf;
@@ -649,66 +646,37 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
                        offs += node_len;
                        buf += node_len;
                        len -= node_len;
-                       continue;
-               }
-
-               if (ret > 0) {
+               } else if (ret > 0) {
                        /* Padding bytes or a valid padding node */
                        offs += ret;
                        buf += ret;
                        len -= ret;
-                       continue;
-               }
-
-               if (ret == SCANNED_EMPTY_SPACE) {
-                       if (!is_empty(buf, len)) {
-                               if (!is_last_write(c, buf, offs))
-                                       break;
-                               clean_buf(c, &buf, lnum, &offs, &len);
-                               need_clean = 1;
-                       }
-                       empty_chkd = 1;
+               } else if (ret == SCANNED_EMPTY_SPACE ||
+                          ret == SCANNED_GARBAGE     ||
+                          ret == SCANNED_A_BAD_PAD_NODE ||
+                          ret == SCANNED_A_CORRUPT_NODE) {
+                       dbg_rcvry("found corruption - %d", ret);
                        break;
-               }
-
-               if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE)
-                       if (is_last_write(c, buf, offs)) {
-                               clean_buf(c, &buf, lnum, &offs, &len);
-                               need_clean = 1;
-                               empty_chkd = 1;
-                               break;
-                       }
-
-               if (ret == SCANNED_A_CORRUPT_NODE)
-                       if (no_more_nodes(c, buf, len, lnum, offs)) {
-                               clean_buf(c, &buf, lnum, &offs, &len);
-                               need_clean = 1;
-                               empty_chkd = 1;
-                               break;
-                       }
-
-               if (quiet) {
-                       /* Redo the last scan but noisily */
-                       quiet = 0;
-                       continue;
-               }
-
-               switch (ret) {
-               case SCANNED_GARBAGE:
-                       dbg_err("garbage");
-                       goto corrupted;
-               case SCANNED_A_CORRUPT_NODE:
-               case SCANNED_A_BAD_PAD_NODE:
-                       dbg_err("bad node");
-                       goto corrupted;
-               default:
-                       dbg_err("unknown");
+               } else {
+                       dbg_err("unexpected return value %d", ret);
                        err = -EINVAL;
                        goto error;
                }
        }
 
-       if (!empty_chkd && !is_empty(buf, len)) {
+       if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE) {
+               if (is_last_write(c, buf, offs)) {
+                       clean_buf(c, &buf, lnum, &offs, &len);
+                       need_clean = 1;
+               } else
+                       goto corrupted_rescan;
+       } else if (ret == SCANNED_A_CORRUPT_NODE) {
+               if (no_more_nodes(c, buf, len, lnum, offs)) {
+                       clean_buf(c, &buf, lnum, &offs, &len);
+                       need_clean = 1;
+               } else
+                       goto corrupted_rescan;
+       } else if (!is_empty(buf, len)) {
                if (is_last_write(c, buf, offs)) {
                        clean_buf(c, &buf, lnum, &offs, &len);
                        need_clean = 1;
@@ -751,6 +719,10 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
 
        return sleb;
 
+corrupted_rescan:
+       /* Re-scan the corrupted data with verbose messages */
+       dbg_err("corruptio %d", ret);
+       ubifs_scan_a_node(c, buf, len, lnum, offs, 1);
 corrupted:
        ubifs_scanned_corruption(c, lnum, offs, buf);
        err = -EUCLEAN;