From: Daeho Jeong daehojeong@google.com
stable inclusion from stable-v6.6.33 commit 61330214b227cf2b473009b7dd563ee15043dea6 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAD6H2
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 2f0209f579d12bd0ea43a01a8696e30a8eeec1da ]
Make f2fs_gc_range() an extenal function to use it for GC for a range.
Signed-off-by: Daeho Jeong daehojeong@google.com Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Stable-dep-of: aa4074e8fec4 ("f2fs: fix block migration when section is not aligned to pow2") Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Wang Hai wanghai38@huawei.com --- fs/f2fs/gc.c | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 9c150b2dd9ec..4cf37f51339c 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1980,10 +1980,34 @@ void f2fs_build_gc_manager(struct f2fs_sb_info *sbi) init_atgc_management(sbi); }
+static int f2fs_gc_range(struct f2fs_sb_info *sbi, + unsigned int start_seg, unsigned int end_seg, bool dry_run) +{ + unsigned int segno; + + for (segno = start_seg; segno <= end_seg; segno += SEGS_PER_SEC(sbi)) { + struct gc_inode_list gc_list = { + .ilist = LIST_HEAD_INIT(gc_list.ilist), + .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS), + }; + + do_garbage_collect(sbi, segno, &gc_list, FG_GC, true); + put_gc_inode(&gc_list); + + if (!dry_run && get_valid_blocks(sbi, segno, true)) + return -EAGAIN; + + if (fatal_signal_pending(current)) + return -ERESTARTSYS; + } + + return 0; +} + static int free_segment_range(struct f2fs_sb_info *sbi, - unsigned int secs, bool gc_only) + unsigned int secs, bool dry_run) { - unsigned int segno, next_inuse, start, end; + unsigned int next_inuse, start, end; struct cp_control cpc = { CP_RESIZE, 0, 0, 0 }; int gc_mode, gc_type; int err = 0; @@ -2009,25 +2033,8 @@ static int free_segment_range(struct f2fs_sb_info *sbi, f2fs_allocate_segment_for_resize(sbi, type, start, end);
/* do GC to move out valid blocks in the range */ - for (segno = start; segno <= end; segno += SEGS_PER_SEC(sbi)) { - struct gc_inode_list gc_list = { - .ilist = LIST_HEAD_INIT(gc_list.ilist), - .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS), - }; - - do_garbage_collect(sbi, segno, &gc_list, FG_GC, true); - put_gc_inode(&gc_list); - - if (!gc_only && get_valid_blocks(sbi, segno, true)) { - err = -EAGAIN; - goto out; - } - if (fatal_signal_pending(current)) { - err = -ERESTARTSYS; - goto out; - } - } - if (gc_only) + err = f2fs_gc_range(sbi, start, end, dry_run); + if (err || dry_run) goto out;
stat_inc_cp_call_count(sbi, TOTAL_CALL);