diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-10-06 15:12:58 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-10-06 15:12:58 -0400 |
commit | 8fb870df5a1f261294b833dd807bcba3bacface6 (patch) | |
tree | 2e6018f0256feca906797b248603202962302fa6 /fs/jffs2/nodemgmt.c | |
parent | 49defc015ff58fda46a3afa3462dfdfa69bc8401 (diff) |
[JFFS2] Trigger garbage collection when very_dirty_list size becomes excessive
With huge amounts of free space, we weren't bothering to GC for while a
while, and pathological numbers of obsolete nodes were accumulating,
seriously affecting performance on NAND flash (OLPC trac #3978)
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/nodemgmt.c')
-rw-r--r-- | fs/jffs2/nodemgmt.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index 5b49bff364b4..1b79534e9d48 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c | |||
@@ -722,6 +722,8 @@ int jffs2_thread_should_wake(struct jffs2_sb_info *c) | |||
722 | { | 722 | { |
723 | int ret = 0; | 723 | int ret = 0; |
724 | uint32_t dirty; | 724 | uint32_t dirty; |
725 | int nr_very_dirty = 0; | ||
726 | struct jffs2_eraseblock *jeb; | ||
725 | 727 | ||
726 | if (c->unchecked_size) { | 728 | if (c->unchecked_size) { |
727 | D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n", | 729 | D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n", |
@@ -743,8 +745,16 @@ int jffs2_thread_should_wake(struct jffs2_sb_info *c) | |||
743 | (dirty > c->nospc_dirty_size)) | 745 | (dirty > c->nospc_dirty_size)) |
744 | ret = 1; | 746 | ret = 1; |
745 | 747 | ||
746 | D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n", | 748 | list_for_each_entry(jeb, &c->very_dirty_list, list) { |
747 | c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret?"yes":"no")); | 749 | nr_very_dirty++; |
750 | if (nr_very_dirty == c->vdirty_blocks_gctrigger) { | ||
751 | ret = 1; | ||
752 | D1(break); | ||
753 | } | ||
754 | } | ||
755 | |||
756 | D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x, vdirty_blocks %d: %s\n", | ||
757 | c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, nr_very_dirty, ret?"yes":"no")); | ||
748 | 758 | ||
749 | return ret; | 759 | return ret; |
750 | } | 760 | } |