Commit 7807ef7ba2a41c05f6197381f572dd38baa6c1ce
1 parent
3560160aa2
Exists in
master
and in
7 other branches
[JFFS2] Fix summary handling of unknown but compatible nodes.
For RWCOMPAT and ROCOMPAT nodes, we should still allow the mount to succeed. Just abandon the summary and fall through to the full scan. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Showing 3 changed files with 22 additions and 6 deletions Side-by-side Diff
fs/jffs2/erase.c
... | ... | @@ -30,7 +30,6 @@ |
30 | 30 | #endif |
31 | 31 | static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset); |
32 | 32 | static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); |
33 | -static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); | |
34 | 33 | static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); |
35 | 34 | |
36 | 35 | static void jffs2_erase_block(struct jffs2_sb_info *c, |
... | ... | @@ -283,7 +282,7 @@ |
283 | 282 | jffs2_del_ino_cache(c, ic); |
284 | 283 | } |
285 | 284 | |
286 | -static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) | |
285 | +void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) | |
287 | 286 | { |
288 | 287 | struct jffs2_raw_node_ref *ref; |
289 | 288 | D1(printk(KERN_DEBUG "Freeing all node refs for eraseblock offset 0x%08x\n", jeb->offset)); |
fs/jffs2/nodelist.h
fs/jffs2/summary.c
... | ... | @@ -554,9 +554,21 @@ |
554 | 554 | } |
555 | 555 | #endif |
556 | 556 | default : { |
557 | -printk("nodetype = %#04x\n",je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)); | |
558 | - JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); | |
559 | - return -EIO; | |
557 | + uint16_t nodetype = je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype); | |
558 | + JFFS2_WARNING("Unsupported node type %x found in summary! Exiting...\n", nodetype); | |
559 | + if ((nodetype & JFFS2_COMPAT_MASK) == JFFS2_FEATURE_INCOMPAT) | |
560 | + return -EIO; | |
561 | + | |
562 | + /* For compatible node types, just fall back to the full scan */ | |
563 | + c->wasted_size -= jeb->wasted_size; | |
564 | + c->free_size += c->sector_size - jeb->free_size; | |
565 | + c->used_size -= jeb->used_size; | |
566 | + c->dirty_size -= jeb->dirty_size; | |
567 | + jeb->wasted_size = jeb->used_size = jeb->dirty_size = 0; | |
568 | + jeb->free_size = c->sector_size; | |
569 | + | |
570 | + jffs2_free_all_node_refs(c, jeb); | |
571 | + return -ENOTRECOVERABLE; | |
560 | 572 | } |
561 | 573 | } |
562 | 574 | } |
563 | 575 | |
... | ... | @@ -642,8 +654,12 @@ |
642 | 654 | } |
643 | 655 | |
644 | 656 | ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random); |
657 | + /* -ENOTRECOVERABLE isn't a fatal error -- it means we should do a full | |
658 | + scan of this eraseblock. So return zero */ | |
659 | + if (ret == -ENOTRECOVERABLE) | |
660 | + return 0; | |
645 | 661 | if (ret) |
646 | - return ret; | |
662 | + return ret; /* real error */ | |
647 | 663 | |
648 | 664 | /* for PARANOIA_CHECK */ |
649 | 665 | cache_ref = jffs2_alloc_raw_node_ref(); |