summaryrefslogtreecommitdiffstats
path: root/fs/jffs2/build.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-10-06 21:12:58 +0200
committerDavid Woodhouse <dwmw2@infradead.org>2007-10-06 21:12:58 +0200
commit8fb870df5a1f261294b833dd807bcba3bacface6 (patch)
tree2e6018f0256feca906797b248603202962302fa6 /fs/jffs2/build.c
parent[MTD] [NAND] Avoid deadlock in erase callback; release chip lock first. (diff)
downloadlinux-8fb870df5a1f261294b833dd807bcba3bacface6.tar.xz
linux-8fb870df5a1f261294b833dd807bcba3bacface6.zip
[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/build.c')
-rw-r--r--fs/jffs2/build.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index 0ca2fff2617f..8c27c12816ba 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -285,6 +285,14 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
than actually making progress? */
c->resv_blocks_gcbad = 0;//c->resv_blocks_deletion + 2;
+ /* What number of 'very dirty' eraseblocks do we allow before we
+ trigger the GC thread even if we don't _need_ the space. When we
+ can't mark nodes obsolete on the medium, the old dirty nodes cause
+ performance problems because we have to inspect and discard them. */
+ c->vdirty_blocks_gctrigger = c->resv_blocks_gcmerge;
+ if (jffs2_can_mark_obsolete(c))
+ c->vdirty_blocks_gctrigger *= 10;
+
/* If there's less than this amount of dirty space, don't bother
trying to GC to make more space. It'll be a fruitless task */
c->nospc_dirty_size = c->sector_size + (c->flash_size / 100);
@@ -303,6 +311,8 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024);
dbg_fsbuild("Amount of dirty space required to GC: %d bytes\n",
c->nospc_dirty_size);
+ dbg_fsbuild("Very dirty blocks before GC triggered: %d\n",
+ c->vdirty_blocks_gctrigger);
}
int jffs2_do_mount_fs(struct jffs2_sb_info *c)