diff options
-rw-r--r-- | fs/jffs2/readinode.c | 23 |
1 files changed, 9 insertions, 14 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index f461604cf01f..bd31d4956c6d 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -221,7 +221,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | |||
221 | uint32_t fn_end = tn->fn->ofs + tn->fn->size; | 221 | uint32_t fn_end = tn->fn->ofs + tn->fn->size; |
222 | struct jffs2_tmp_dnode_info *this; | 222 | struct jffs2_tmp_dnode_info *this; |
223 | 223 | ||
224 | dbg_readinode("insert fragment %#04x-%#04x, ver %u\n", tn->fn->ofs, fn_end, tn->version); | 224 | dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw)); |
225 | 225 | ||
226 | /* If a node has zero dsize, we only have to keep if it if it might be the | 226 | /* If a node has zero dsize, we only have to keep if it if it might be the |
227 | node with highest version -- i.e. the one which will end up as f->metadata. | 227 | node with highest version -- i.e. the one which will end up as f->metadata. |
@@ -271,11 +271,11 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | |||
271 | return 0; | 271 | return 0; |
272 | } else { | 272 | } else { |
273 | /* Who cares if the new one is good; keep it for now anyway. */ | 273 | /* Who cares if the new one is good; keep it for now anyway. */ |
274 | dbg_readinode("Like new node. Throw away old\n"); | ||
274 | rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); | 275 | rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); |
275 | /* Same overlapping from in front and behind */ | ||
276 | jffs2_kill_tn(c, this); | 276 | jffs2_kill_tn(c, this); |
277 | dbg_readinode("Like new node. Throw away old\n"); | 277 | /* Same overlapping from in front and behind */ |
278 | goto calc_overlaps; | 278 | return 0; |
279 | } | 279 | } |
280 | } | 280 | } |
281 | if (this->version < tn->version && | 281 | if (this->version < tn->version && |
@@ -287,11 +287,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | |||
287 | jffs2_kill_tn(c, tn); | 287 | jffs2_kill_tn(c, tn); |
288 | return 0; | 288 | return 0; |
289 | } | 289 | } |
290 | /* ... and is good. Kill 'this'... */ | 290 | /* ... and is good. Kill 'this' and any subsequent nodes which are also overlapped */ |
291 | rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); | ||
292 | jffs2_kill_tn(c, this); | ||
293 | /* ... and any subsequent nodes which are also overlapped */ | ||
294 | this = tn_next(tn); | ||
295 | while (this && this->fn->ofs + this->fn->size < fn_end) { | 291 | while (this && this->fn->ofs + this->fn->size < fn_end) { |
296 | struct jffs2_tmp_dnode_info *next = tn_next(this); | 292 | struct jffs2_tmp_dnode_info *next = tn_next(this); |
297 | if (this->version < tn->version) { | 293 | if (this->version < tn->version) { |
@@ -303,8 +299,8 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | |||
303 | } | 299 | } |
304 | this = next; | 300 | this = next; |
305 | } | 301 | } |
306 | dbg_readinode("Done inserting new\n"); | 302 | dbg_readinode("Done killing overlapped nodes\n"); |
307 | goto calc_overlaps; | 303 | break; |
308 | } | 304 | } |
309 | if (this->version > tn->version && | 305 | if (this->version > tn->version && |
310 | this->fn->ofs <= tn->fn->ofs && | 306 | this->fn->ofs <= tn->fn->ofs && |
@@ -316,11 +312,10 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | |||
316 | return 0; | 312 | return 0; |
317 | } | 313 | } |
318 | /* ... but 'this' was bad. Replace it... */ | 314 | /* ... but 'this' was bad. Replace it... */ |
319 | tn->overlapped = this->overlapped; | ||
320 | rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); | ||
321 | dbg_readinode("Bad CRC on old overlapping node. Kill it\n"); | 315 | dbg_readinode("Bad CRC on old overlapping node. Kill it\n"); |
316 | tn_erase(this, &rii->tn_root); | ||
322 | jffs2_kill_tn(c, this); | 317 | jffs2_kill_tn(c, this); |
323 | return 0; | 318 | break; |
324 | } | 319 | } |
325 | 320 | ||
326 | this = tn_next(this); | 321 | this = tn_next(this); |