diff options
| -rw-r--r-- | fs/ubifs/master.c | 16 | ||||
| -rw-r--r-- | fs/ubifs/orphan.c | 3 |
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 | */ |
| 35 | static int scan_for_master(struct ubifs_info *c) | 36 | static 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 | ||
| 79 | out: | 80 | out: |
| 80 | ubifs_scan_destroy(sleb); | 81 | ubifs_scan_destroy(sleb); |
| 82 | return -EUCLEAN; | ||
| 83 | |||
| 84 | out_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; |
