diff options
Diffstat (limited to 'fs/jffs2/nodemgmt.c')
-rw-r--r-- | fs/jffs2/nodemgmt.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index 2651135bdf42..c1d8b5ed9ab9 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: nodemgmt.c,v 1.115 2004/11/22 11:07:21 dwmw2 Exp $ | 10 | * $Id: nodemgmt.c,v 1.122 2005/05/06 09:30:27 dedekind Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -75,7 +75,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs | |||
75 | dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size; | 75 | dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size; |
76 | if (dirty < c->nospc_dirty_size) { | 76 | if (dirty < c->nospc_dirty_size) { |
77 | if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { | 77 | if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { |
78 | printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n"); | 78 | D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n")); |
79 | break; | 79 | break; |
80 | } | 80 | } |
81 | D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n", | 81 | D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n", |
@@ -98,7 +98,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs | |||
98 | avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size; | 98 | avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size; |
99 | if ( (avail / c->sector_size) <= blocksneeded) { | 99 | if ( (avail / c->sector_size) <= blocksneeded) { |
100 | if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { | 100 | if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { |
101 | printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n"); | 101 | D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n")); |
102 | break; | 102 | break; |
103 | } | 103 | } |
104 | 104 | ||
@@ -308,7 +308,10 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r | |||
308 | 308 | ||
309 | D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len)); | 309 | D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len)); |
310 | #if 1 | 310 | #if 1 |
311 | if (jeb != c->nextblock || (ref_offset(new)) != jeb->offset + (c->sector_size - jeb->free_size)) { | 311 | /* we could get some obsolete nodes after nextblock was refiled |
312 | in wbuf.c */ | ||
313 | if ((c->nextblock || !ref_obsolete(new)) | ||
314 | &&(jeb != c->nextblock || ref_offset(new) != jeb->offset + (c->sector_size - jeb->free_size))) { | ||
312 | printk(KERN_WARNING "argh. node added in wrong place\n"); | 315 | printk(KERN_WARNING "argh. node added in wrong place\n"); |
313 | jffs2_free_raw_node_ref(new); | 316 | jffs2_free_raw_node_ref(new); |
314 | return -EINVAL; | 317 | return -EINVAL; |
@@ -332,7 +335,7 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r | |||
332 | c->used_size += len; | 335 | c->used_size += len; |
333 | } | 336 | } |
334 | 337 | ||
335 | if (!jeb->free_size && !jeb->dirty_size) { | 338 | if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) { |
336 | /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ | 339 | /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ |
337 | D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", | 340 | D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", |
338 | jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); | 341 | jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); |
@@ -400,7 +403,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
400 | jeb = &c->blocks[blocknr]; | 403 | jeb = &c->blocks[blocknr]; |
401 | 404 | ||
402 | if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) && | 405 | if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) && |
403 | !(c->flags & JFFS2_SB_FLAG_MOUNTING)) { | 406 | !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) { |
404 | /* Hm. This may confuse static lock analysis. If any of the above | 407 | /* Hm. This may confuse static lock analysis. If any of the above |
405 | three conditions is false, we're going to return from this | 408 | three conditions is false, we're going to return from this |
406 | function without actually obliterating any nodes or freeing | 409 | function without actually obliterating any nodes or freeing |
@@ -434,7 +437,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
434 | 437 | ||
435 | // Take care, that wasted size is taken into concern | 438 | // Take care, that wasted size is taken into concern |
436 | if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) { | 439 | if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) { |
437 | D1(printk("Dirtying\n")); | 440 | D1(printk(KERN_DEBUG "Dirtying\n")); |
438 | addedsize = ref_totlen(c, jeb, ref); | 441 | addedsize = ref_totlen(c, jeb, ref); |
439 | jeb->dirty_size += ref_totlen(c, jeb, ref); | 442 | jeb->dirty_size += ref_totlen(c, jeb, ref); |
440 | c->dirty_size += ref_totlen(c, jeb, ref); | 443 | c->dirty_size += ref_totlen(c, jeb, ref); |
@@ -456,7 +459,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
456 | } | 459 | } |
457 | } | 460 | } |
458 | } else { | 461 | } else { |
459 | D1(printk("Wasting\n")); | 462 | D1(printk(KERN_DEBUG "Wasting\n")); |
460 | addedsize = 0; | 463 | addedsize = 0; |
461 | jeb->wasted_size += ref_totlen(c, jeb, ref); | 464 | jeb->wasted_size += ref_totlen(c, jeb, ref); |
462 | c->wasted_size += ref_totlen(c, jeb, ref); | 465 | c->wasted_size += ref_totlen(c, jeb, ref); |
@@ -467,8 +470,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
467 | 470 | ||
468 | D1(ACCT_PARANOIA_CHECK(jeb)); | 471 | D1(ACCT_PARANOIA_CHECK(jeb)); |
469 | 472 | ||
470 | if (c->flags & JFFS2_SB_FLAG_MOUNTING) { | 473 | if (c->flags & JFFS2_SB_FLAG_SCANNING) { |
471 | /* Mount in progress. Don't muck about with the block | 474 | /* Flash scanning is in progress. Don't muck about with the block |
472 | lists because they're not ready yet, and don't actually | 475 | lists because they're not ready yet, and don't actually |
473 | obliterate nodes that look obsolete. If they weren't | 476 | obliterate nodes that look obsolete. If they weren't |
474 | marked obsolete on the flash at the time they _became_ | 477 | marked obsolete on the flash at the time they _became_ |
@@ -527,7 +530,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
527 | 530 | ||
528 | spin_unlock(&c->erase_completion_lock); | 531 | spin_unlock(&c->erase_completion_lock); |
529 | 532 | ||
530 | if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c)) { | 533 | if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c) || |
534 | (c->flags & JFFS2_SB_FLAG_BUILDING)) { | ||
531 | /* We didn't lock the erase_free_sem */ | 535 | /* We didn't lock the erase_free_sem */ |
532 | return; | 536 | return; |
533 | } | 537 | } |
@@ -590,11 +594,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
590 | *p = ref->next_in_ino; | 594 | *p = ref->next_in_ino; |
591 | ref->next_in_ino = NULL; | 595 | ref->next_in_ino = NULL; |
592 | 596 | ||
593 | if (ic->nodes == (void *)ic) { | 597 | if (ic->nodes == (void *)ic && ic->nlink == 0) |
594 | D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino)); | ||
595 | jffs2_del_ino_cache(c, ic); | 598 | jffs2_del_ino_cache(c, ic); |
596 | jffs2_free_inode_cache(ic); | ||
597 | } | ||
598 | 599 | ||
599 | spin_unlock(&c->erase_completion_lock); | 600 | spin_unlock(&c->erase_completion_lock); |
600 | } | 601 | } |