diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-05-05 16:29:34 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-05-05 16:29:34 +0100 |
commit | 1123e2a85941c7f506bd42c91c7e9ab74fc42d79 (patch) | |
tree | dd8474b7d3a00442178b18baf62c09642d306845 /fs/jffs2/readinode.c | |
parent | 3fddb6c985e3823c991399840d2d5ef5940e1b60 (diff) |
[JFFS2] Remember to calculate overlap on nodes which replace older nodes
This fixes a problem Artem found with the integck test tool -- we
weren't correctly keeping track of the 'overlap' flag in some cases,
which led to the nodes being played back in an incorrect order and file
corruption.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/readinode.c')
-rw-r--r-- | fs/jffs2/readinode.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 6aff38930b50..b0645ac7769a 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -276,10 +276,9 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, /* Who cares if the new one is good; keep it for now anyway. */ rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); /* Same overlapping from in front and behind */ - tn->overlapped = this->overlapped; jffs2_kill_tn(c, this); dbg_readinode("Like new node. Throw away old\n"); - return 0; + goto calc_overlaps; } } if (this->version < tn->version && @@ -293,7 +292,6 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, } /* ... and is good. Kill 'this'... */ rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); - tn->overlapped = this->overlapped; jffs2_kill_tn(c, this); /* ... and any subsequent nodes which are also overlapped */ this = tn_next(tn); @@ -309,7 +307,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, this = next; } dbg_readinode("Done inserting new\n"); - return 0; + goto calc_overlaps; } if (this->version > tn->version && this->fn->ofs <= tn->fn->ofs && @@ -321,6 +319,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, return 0; } /* ... but 'this' was bad. Replace it... */ + tn->overlapped = this->overlapped; rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); dbg_readinode("Bad CRC on old overlapping node. Kill it\n"); jffs2_kill_tn(c, this); @@ -359,6 +358,8 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, rb_link_node(&tn->rb, &insert_point->rb, link); rb_insert_color(&tn->rb, &rii->tn_root); } + + calc_overlaps: /* If there's anything behind that overlaps us, note it */ this = tn_prev(tn); if (this) { @@ -483,7 +484,7 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c, vers_next = tn_prev(this); eat_last(&ver_root, &this->rb); if (check_tn_node(c, this)) { - dbg_readinode("node ver %x, 0x%x-0x%x failed CRC\n", + dbg_readinode("node ver %d, 0x%x-0x%x failed CRC\n", this->version, this->fn->ofs, this->fn->ofs+this->fn->size); jffs2_kill_tn(c, this); @@ -496,7 +497,7 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c, high_ver = this->version; rii->latest_ref = this->fn->raw; } - dbg_readinode("Add %p (v %x, 0x%x-0x%x, ov %d) to fragtree\n", + dbg_readinode("Add %p (v %d, 0x%x-0x%x, ov %d) to fragtree\n", this, this->version, this->fn->ofs, this->fn->ofs+this->fn->size, this->overlapped); @@ -850,7 +851,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref return ret; } #ifdef JFFS2_DBG_READINODE_MESSAGES - dbg_readinode("After adding ver %d:\n", tn->version); + dbg_readinode("After adding ver %d:\n", je32_to_cpu(rd->version)); tn = tn_first(&rii->tn_root); while (tn) { dbg_readinode("%p: v %d r 0x%x-0x%x ov %d\n", |