aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-20 22:45:27 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-20 22:45:27 -0400
commit7807ef7ba2a41c05f6197381f572dd38baa6c1ce (patch)
tree73d06f8b60b3e007b49fec33983365938135d2d1
parent3560160aa26ebced1944aaa2e7e436d2a1b1bf70 (diff)
[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>
-rw-r--r--fs/jffs2/erase.c3
-rw-r--r--fs/jffs2/nodelist.h1
-rw-r--r--fs/jffs2/summary.c24
3 files changed, 22 insertions, 6 deletions
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index fecf5584f830..f677d6950fd4 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -30,7 +30,6 @@ static void jffs2_erase_callback(struct erase_info *);
30#endif 30#endif
31static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset); 31static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset);
32static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 32static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
33static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
34static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 33static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
35 34
36static void jffs2_erase_block(struct jffs2_sb_info *c, 35static void jffs2_erase_block(struct jffs2_sb_info *c,
@@ -283,7 +282,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
283 jffs2_del_ino_cache(c, ic); 282 jffs2_del_ino_cache(c, ic);
284} 283}
285 284
286static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 285void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
287{ 286{
288 struct jffs2_raw_node_ref *ref; 287 struct jffs2_raw_node_ref *ref;
289 D1(printk(KERN_DEBUG "Freeing all node refs for eraseblock offset 0x%08x\n", jeb->offset)); 288 D1(printk(KERN_DEBUG "Freeing all node refs for eraseblock offset 0x%08x\n", jeb->offset));
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index 1f5d5b0100aa..194cff7c4853 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -436,6 +436,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c);
436 436
437/* erase.c */ 437/* erase.c */
438void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count); 438void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count);
439void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
439 440
440#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 441#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
441/* wbuf.c */ 442/* wbuf.c */
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 53a84b468cfe..9ced3aa95818 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -554,9 +554,21 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
554 } 554 }
555#endif 555#endif
556 default : { 556 default : {
557printk("nodetype = %#04x\n",je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)); 557 uint16_t nodetype = je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype);
558 JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); 558 JFFS2_WARNING("Unsupported node type %x found in summary! Exiting...\n", nodetype);
559 return -EIO; 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 }
@@ -642,8 +654,12 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
642 } 654 }
643 655
644 ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random); 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 if (ret) 661 if (ret)
646 return ret; 662 return ret; /* real error */
647 663
648 /* for PARANOIA_CHECK */ 664 /* for PARANOIA_CHECK */
649 cache_ref = jffs2_alloc_raw_node_ref(); 665 cache_ref = jffs2_alloc_raw_node_ref();