aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-08-25 09:22:53 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-09-10 05:06:47 -0400
commit0dcd18e4073454daf591e7127247e32ec942b4f3 (patch)
tree2f9e0175bc1af2e841269c19f0a5f65cc22088d7 /fs/ubifs
parent348709bad348d2fd013e1529b4cf5f220717c328 (diff)
UBIFS: check ubifs_scan error codes better
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>
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/master.c16
-rw-r--r--fs/ubifs/orphan.c3
2 files changed, 14 insertions, 5 deletions
diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c
index 6f95a168a56f..28beaeedadc0 100644
--- a/fs/ubifs/master.c
+++ b/fs/ubifs/master.c
@@ -29,7 +29,8 @@
29 * @c: UBIFS file-system description object 29 * @c: UBIFS file-system description object
30 * 30 *
31 * This function scans the master node LEBs and search for the latest master 31 * This function scans the master node LEBs and search for the latest master
32 * node. Returns zero in case of success and a negative error code in case of 32 * node. Returns zero in case of success, %-EUCLEAN if there master area is
33 * corrupted and requires recovery, and a negative error code in case of
33 * failure. 34 * failure.
34 */ 35 */
35static int scan_for_master(struct ubifs_info *c) 36static int scan_for_master(struct ubifs_info *c)
@@ -48,7 +49,7 @@ static int scan_for_master(struct ubifs_info *c)
48 snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, 49 snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node,
49 list); 50 list);
50 if (snod->type != UBIFS_MST_NODE) 51 if (snod->type != UBIFS_MST_NODE)
51 goto out; 52 goto out_dump;
52 memcpy(c->mst_node, snod->node, snod->len); 53 memcpy(c->mst_node, snod->node, snod->len);
53 offs = snod->offs; 54 offs = snod->offs;
54 } 55 }
@@ -65,7 +66,7 @@ static int scan_for_master(struct ubifs_info *c)
65 goto out; 66 goto out;
66 snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list); 67 snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list);
67 if (snod->type != UBIFS_MST_NODE) 68 if (snod->type != UBIFS_MST_NODE)
68 goto out; 69 goto out_dump;
69 if (snod->offs != offs) 70 if (snod->offs != offs)
70 goto out; 71 goto out;
71 if (memcmp((void *)c->mst_node + UBIFS_CH_SZ, 72 if (memcmp((void *)c->mst_node + UBIFS_CH_SZ,
@@ -78,6 +79,12 @@ static int scan_for_master(struct ubifs_info *c)
78 79
79out: 80out:
80 ubifs_scan_destroy(sleb); 81 ubifs_scan_destroy(sleb);
82 return -EUCLEAN;
83
84out_dump:
85 ubifs_err("unexpected node type %d master LEB %d:%d",
86 snod->type, lnum, snod->offs);
87 ubifs_scan_destroy(sleb);
81 return -EINVAL; 88 return -EINVAL;
82} 89}
83 90
@@ -256,7 +263,8 @@ int ubifs_read_master(struct ubifs_info *c)
256 263
257 err = scan_for_master(c); 264 err = scan_for_master(c);
258 if (err) { 265 if (err) {
259 err = ubifs_recover_master_node(c); 266 if (err == -EUCLEAN)
267 err = ubifs_recover_master_node(c);
260 if (err) 268 if (err)
261 /* 269 /*
262 * Note, we do not free 'c->mst_node' here because the 270 * Note, we do not free 'c->mst_node' here because the
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c
index 3119af3cdc51..82009c74b6a3 100644
--- a/fs/ubifs/orphan.c
+++ b/fs/ubifs/orphan.c
@@ -672,7 +672,8 @@ static int kill_orphans(struct ubifs_info *c)
672 dbg_rcvry("LEB %d", lnum); 672 dbg_rcvry("LEB %d", lnum);
673 sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1); 673 sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1);
674 if (IS_ERR(sleb)) { 674 if (IS_ERR(sleb)) {
675 sleb = ubifs_recover_leb(c, lnum, 0, c->sbuf, 0); 675 if (PTR_ERR(sleb) == -EUCLEAN)
676 sleb = ubifs_recover_leb(c, lnum, 0, c->sbuf, 0);
676 if (IS_ERR(sleb)) { 677 if (IS_ERR(sleb)) {
677 err = PTR_ERR(sleb); 678 err = PTR_ERR(sleb);
678 break; 679 break;