aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/gc.c
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2015-10-05 22:22:44 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2015-10-09 16:20:56 -0700
commitd530d4d8e237f4d12c93bb76df40b69b8b8a1dcd (patch)
treea4496eb0dd00eef9caa6b190790502d91f847ff0 /fs/f2fs/gc.c
parentf2fs: skip searching dirty map if dirty segment is not exist (diff)
downloadlinux-dev-d530d4d8e237f4d12c93bb76df40b69b8b8a1dcd.tar.xz
linux-dev-d530d4d8e237f4d12c93bb76df40b69b8b8a1dcd.zip
f2fs: support synchronous gc in ioctl
This patch drops in batches gc triggered through ioctl, since user can easily control the gc by designing the loop around the ->ioctl. We support synchronous gc by forcing using FG_GC in f2fs_gc, so with it, user can make sure that in this round all blocks gced were persistent in the device until ioctl returned. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/gc.c')
-rw-r--r--fs/f2fs/gc.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index d844a8028527..830d27770a32 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -78,7 +78,7 @@ static int gc_thread_func(void *data)
stat_inc_bggc_count(sbi);
/* if return value is not zero, no victim was selected */
- if (f2fs_gc(sbi))
+ if (f2fs_gc(sbi, false))
wait_ms = gc_th->no_gc_sleep_time;
/* balancing f2fs's metadata periodically */
@@ -803,12 +803,12 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno,
return nfree;
}
-int f2fs_gc(struct f2fs_sb_info *sbi)
+int f2fs_gc(struct f2fs_sb_info *sbi, bool sync)
{
unsigned int segno, i;
- int gc_type = BG_GC;
+ int gc_type = sync ? FG_GC : BG_GC;
int sec_freed = 0;
- int ret = -1;
+ int ret = -EINVAL;
struct cp_control cpc;
struct gc_inode_list gc_list = {
.ilist = LIST_HEAD_INIT(gc_list.ilist),
@@ -855,15 +855,20 @@ gc_more:
if (gc_type == FG_GC)
sbi->cur_victim_sec = NULL_SEGNO;
- if (has_not_enough_free_secs(sbi, sec_freed))
- goto gc_more;
+ if (!sync) {
+ if (has_not_enough_free_secs(sbi, sec_freed))
+ goto gc_more;
- if (gc_type == FG_GC)
- write_checkpoint(sbi, &cpc);
+ if (gc_type == FG_GC)
+ write_checkpoint(sbi, &cpc);
+ }
stop:
mutex_unlock(&sbi->gc_mutex);
put_gc_inode(&gc_list);
+
+ if (sync)
+ ret = sec_freed ? 0 : -EAGAIN;
return ret;
}