]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
UBIFS: check ubifs_scan error codes better
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Tue, 25 Aug 2009 13:22:53 +0000 (16:22 +0300)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Thu, 10 Sep 2009 09:06:47 +0000 (12:06 +0300)
The 'ubifs_scan()' function returns -EUCLEAN if something is corrupted
and recovery is needed, otherwise it returns other error codes. However,
in few places UBIFS does not check the error codes and runs recovery.
This patch changes this behavior and makes UBIFS start recovery only
on -EUCLEAN errors.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Reviewed-by: Adrian Hunter <Adrian.Hunter@nokia.com>
fs/ubifs/master.c
fs/ubifs/orphan.c

index 6f95a168a56fee347c5b074bfd09dad46954651e..28beaeedadc07d5ad7c3c312d27e30d7be01ee64 100644 (file)
@@ -29,7 +29,8 @@
  * @c: UBIFS file-system description object
  *
  * This function scans the master node LEBs and search for the latest master
- * node. Returns zero in case of success and a negative error code in case of
+ * node. Returns zero in case of success, %-EUCLEAN if there master area is
+ * corrupted and requires recovery, and a negative error code in case of
  * failure.
  */
 static int scan_for_master(struct ubifs_info *c)
@@ -48,7 +49,7 @@ static int scan_for_master(struct ubifs_info *c)
                snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node,
                                  list);
                if (snod->type != UBIFS_MST_NODE)
-                       goto out;
+                       goto out_dump;
                memcpy(c->mst_node, snod->node, snod->len);
                offs = snod->offs;
        }
@@ -65,7 +66,7 @@ static int scan_for_master(struct ubifs_info *c)
                goto out;
        snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list);
        if (snod->type != UBIFS_MST_NODE)
-               goto out;
+               goto out_dump;
        if (snod->offs != offs)
                goto out;
        if (memcmp((void *)c->mst_node + UBIFS_CH_SZ,
@@ -78,6 +79,12 @@ static int scan_for_master(struct ubifs_info *c)
 
 out:
        ubifs_scan_destroy(sleb);
+       return -EUCLEAN;
+
+out_dump:
+       ubifs_err("unexpected node type %d master LEB %d:%d",
+                 snod->type, lnum, snod->offs);
+       ubifs_scan_destroy(sleb);
        return -EINVAL;
 }
 
@@ -256,7 +263,8 @@ int ubifs_read_master(struct ubifs_info *c)
 
        err = scan_for_master(c);
        if (err) {
-               err = ubifs_recover_master_node(c);
+               if (err == -EUCLEAN)
+                       err = ubifs_recover_master_node(c);
                if (err)
                        /*
                         * Note, we do not free 'c->mst_node' here because the
index 3119af3cdc510e0c2550724da97c702a1fd2c97d..82009c74b6a32e7faad97dba0d0e67b98e5bdc5d 100644 (file)
@@ -672,7 +672,8 @@ static int kill_orphans(struct ubifs_info *c)
                dbg_rcvry("LEB %d", lnum);
                sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1);
                if (IS_ERR(sleb)) {
-                       sleb = ubifs_recover_leb(c, lnum, 0, c->sbuf, 0);
+                       if (PTR_ERR(sleb) == -EUCLEAN)
+                               sleb = ubifs_recover_leb(c, lnum, 0, c->sbuf, 0);
                        if (IS_ERR(sleb)) {
                                err = PTR_ERR(sleb);
                                break;