From: NeilBrown Date: Fri, 9 Jul 2010 06:18:56 +0000 (+1000) Subject: Retard cleaner more when space is tight. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=bec033d7eada714ce221095265b20b70de3d8e9a;p=LaFS.git Retard cleaner more when space is tight. If there is no space in any 'cleaner segment' to clean to, then only clean if there are no 'clean' (but not 'free') segments. As soon as we make a clean segment, we should stop cleaning and allow a checkpoint to make the clean segment free so maybe more progress can be made. Signed-off-by: NeilBrown --- diff --git a/clean.c b/clean.c index d59dc42..54405d4 100644 --- a/clean.c +++ b/clean.c @@ -597,11 +597,20 @@ static unsigned long do_clean(struct fs *fs) T -= 4 * fs->max_segment; max_segs = lafs_alloc_cleaner_segs(fs, 4); - if (max_segs < 1) - /* if we can only clean to main segment, do it - * but only do one segment at a time + if (max_segs < 1) { + /* If we can only clean to main segment, we may + * have to. However: + * - only do one segment at a time + * - if there is any clean_reserved, then use it + * - if there are no 'clean' segments, then clean. + * - if CleanerBlocks, then clean. + * otherwise don't. */ - max_segs = 1; + if (fs->clean_reserved + || fs->segtrack->clean.cnt == 0 + || test_bit(CleanerBlocks, &fs->fsstate)) + max_segs = 1; + } for (i = 0; i < max_segs; i++) { struct toclean *tc = &fs->cleaner.seg[i]; u64 C = fs->free_blocks + fs->clean_reserved diff --git a/cluster.c b/cluster.c index 526fb9d..96b9afa 100644 --- a/cluster.c +++ b/cluster.c @@ -432,11 +432,19 @@ static int new_segment(struct fs *fs, int cnum) close_segment(fs, cnum); - /* FIXME if clean_reserve is too small, maybe - * clear it completely. - */ - if ((cnum && fs->clean_reserved < fs->max_segment)) - return -ENOSPC; + if (cnum && fs->clean_reserved < fs->max_segment) { + /* we have reached the end of the last cleaner + * segment. The remainder of clean_reserved + * is of no value (if there even is any + */ + if (fs->clean_reserved) { + spin_lock(&fs->alloc_lock); + fs->free_blocks += fs->clean_reserved; + fs->clean_reserved = 0; + spin_unlock(&fs->alloc_lock); + } + return -ENOSPC; + } /* This gets a reference on the 'segsum' */ lafs_free_get(fs, &dev, &seg, 0); seg_setpos(fs, &wc->seg, segtovirt(fs, dev, seg));