Commit 7807ef7ba2a41c05f6197381f572dd38baa6c1ce

Authored by David Woodhouse
1 parent 3560160aa2

[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

... ... @@ -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));
... ... @@ -436,6 +436,7 @@
436 436  
437 437 /* erase.c */
438 438 void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count);
  439 +void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
439 440  
440 441 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
441 442 /* wbuf.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();