aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-05-05 11:29:34 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2007-05-05 11:29:34 -0400
commit1123e2a85941c7f506bd42c91c7e9ab74fc42d79 (patch)
treedd8474b7d3a00442178b18baf62c09642d306845
parent3fddb6c985e3823c991399840d2d5ef5940e1b60 (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>
-rw-r--r--fs/jffs2/readinode.c15
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,
276 /* Who cares if the new one is good; keep it for now anyway. */ 276 /* Who cares if the new one is good; keep it for now anyway. */
277 rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); 277 rb_replace_node(&this->rb, &tn->rb, &rii->tn_root);
278 /* Same overlapping from in front and behind */ 278 /* Same overlapping from in front and behind */
279 tn->overlapped = this->overlapped;
280 jffs2_kill_tn(c, this); 279 jffs2_kill_tn(c, this);
281 dbg_readinode("Like new node. Throw away old\n"); 280 dbg_readinode("Like new node. Throw away old\n");
282 return 0; 281 goto calc_overlaps;
283 } 282 }
284 } 283 }
285 if (this->version < tn->version && 284 if (this->version < tn->version &&
@@ -293,7 +292,6 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
293 } 292 }
294 /* ... and is good. Kill 'this'... */ 293 /* ... and is good. Kill 'this'... */
295 rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); 294 rb_replace_node(&this->rb, &tn->rb, &rii->tn_root);
296 tn->overlapped = this->overlapped;
297 jffs2_kill_tn(c, this); 295 jffs2_kill_tn(c, this);
298 /* ... and any subsequent nodes which are also overlapped */ 296 /* ... and any subsequent nodes which are also overlapped */
299 this = tn_next(tn); 297 this = tn_next(tn);
@@ -309,7 +307,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
309 this = next; 307 this = next;
310 } 308 }
311 dbg_readinode("Done inserting new\n"); 309 dbg_readinode("Done inserting new\n");
312 return 0; 310 goto calc_overlaps;
313 } 311 }
314 if (this->version > tn->version && 312 if (this->version > tn->version &&
315 this->fn->ofs <= tn->fn->ofs && 313 this->fn->ofs <= tn->fn->ofs &&
@@ -321,6 +319,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
321 return 0; 319 return 0;
322 } 320 }
323 /* ... but 'this' was bad. Replace it... */ 321 /* ... but 'this' was bad. Replace it... */
322 tn->overlapped = this->overlapped;
324 rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); 323 rb_replace_node(&this->rb, &tn->rb, &rii->tn_root);
325 dbg_readinode("Bad CRC on old overlapping node. Kill it\n"); 324 dbg_readinode("Bad CRC on old overlapping node. Kill it\n");
326 jffs2_kill_tn(c, this); 325 jffs2_kill_tn(c, this);
@@ -359,6 +358,8 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
359 rb_link_node(&tn->rb, &insert_point->rb, link); 358 rb_link_node(&tn->rb, &insert_point->rb, link);
360 rb_insert_color(&tn->rb, &rii->tn_root); 359 rb_insert_color(&tn->rb, &rii->tn_root);
361 } 360 }
361
362 calc_overlaps:
362 /* If there's anything behind that overlaps us, note it */ 363 /* If there's anything behind that overlaps us, note it */
363 this = tn_prev(tn); 364 this = tn_prev(tn);
364 if (this) { 365 if (this) {
@@ -483,7 +484,7 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c,
483 vers_next = tn_prev(this); 484 vers_next = tn_prev(this);
484 eat_last(&ver_root, &this->rb); 485 eat_last(&ver_root, &this->rb);
485 if (check_tn_node(c, this)) { 486 if (check_tn_node(c, this)) {
486 dbg_readinode("node ver %x, 0x%x-0x%x failed CRC\n", 487 dbg_readinode("node ver %d, 0x%x-0x%x failed CRC\n",
487 this->version, this->fn->ofs, 488 this->version, this->fn->ofs,
488 this->fn->ofs+this->fn->size); 489 this->fn->ofs+this->fn->size);
489 jffs2_kill_tn(c, this); 490 jffs2_kill_tn(c, this);
@@ -496,7 +497,7 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c,
496 high_ver = this->version; 497 high_ver = this->version;
497 rii->latest_ref = this->fn->raw; 498 rii->latest_ref = this->fn->raw;
498 } 499 }
499 dbg_readinode("Add %p (v %x, 0x%x-0x%x, ov %d) to fragtree\n", 500 dbg_readinode("Add %p (v %d, 0x%x-0x%x, ov %d) to fragtree\n",
500 this, this->version, this->fn->ofs, 501 this, this->version, this->fn->ofs,
501 this->fn->ofs+this->fn->size, this->overlapped); 502 this->fn->ofs+this->fn->size, this->overlapped);
502 503
@@ -850,7 +851,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
850 return ret; 851 return ret;
851 } 852 }
852#ifdef JFFS2_DBG_READINODE_MESSAGES 853#ifdef JFFS2_DBG_READINODE_MESSAGES
853 dbg_readinode("After adding ver %d:\n", tn->version); 854 dbg_readinode("After adding ver %d:\n", je32_to_cpu(rd->version));
854 tn = tn_first(&rii->tn_root); 855 tn = tn_first(&rii->tn_root);
855 while (tn) { 856 while (tn) {
856 dbg_readinode("%p: v %d r 0x%x-0x%x ov %d\n", 857 dbg_readinode("%p: v %d r 0x%x-0x%x ov %d\n",