Commit 7807ef7b authored by David Woodhouse's avatar David Woodhouse

[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: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 3560160a
...@@ -30,7 +30,6 @@ static void jffs2_erase_callback(struct erase_info *); ...@@ -30,7 +30,6 @@ static void jffs2_erase_callback(struct erase_info *);
#endif #endif
static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset); static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset);
static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
static void jffs2_erase_block(struct jffs2_sb_info *c, static 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,7 +282,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
jffs2_del_ino_cache(c, ic); jffs2_del_ino_cache(c, ic);
} }
static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
{ {
struct jffs2_raw_node_ref *ref; struct jffs2_raw_node_ref *ref;
D1(printk(KERN_DEBUG "Freeing all node refs for eraseblock offset 0x%08x\n", jeb->offset)); D1(printk(KERN_DEBUG "Freeing all node refs for eraseblock offset 0x%08x\n", jeb->offset));
......
...@@ -436,6 +436,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c); ...@@ -436,6 +436,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c);
/* erase.c */ /* erase.c */
void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count); void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count);
void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
/* wbuf.c */ /* wbuf.c */
......
...@@ -554,9 +554,21 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras ...@@ -554,9 +554,21 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
} }
#endif #endif
default : { default : {
printk("nodetype = %#04x\n",je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)); uint16_t nodetype = je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype);
JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); JFFS2_WARNING("Unsupported node type %x found in summary! Exiting...\n", nodetype);
return -EIO; if ((nodetype & JFFS2_COMPAT_MASK) == JFFS2_FEATURE_INCOMPAT)
return -EIO;
/* For compatible node types, just fall back to the full scan */
c->wasted_size -= jeb->wasted_size;
c->free_size += c->sector_size - jeb->free_size;
c->used_size -= jeb->used_size;
c->dirty_size -= jeb->dirty_size;
jeb->wasted_size = jeb->used_size = jeb->dirty_size = 0;
jeb->free_size = c->sector_size;
jffs2_free_all_node_refs(c, jeb);
return -ENOTRECOVERABLE;
} }
} }
} }
...@@ -642,8 +654,12 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb ...@@ -642,8 +654,12 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
} }
ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random); ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random);
/* -ENOTRECOVERABLE isn't a fatal error -- it means we should do a full
scan of this eraseblock. So return zero */
if (ret == -ENOTRECOVERABLE)
return 0;
if (ret) if (ret)
return ret; return ret; /* real error */
/* for PARANOIA_CHECK */ /* for PARANOIA_CHECK */
cache_ref = jffs2_alloc_raw_node_ref(); cache_ref = jffs2_alloc_raw_node_ref();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment