f2fs: fix to check return value of f2fs_gc_range
authorZhiguo Niu <zhiguo.niu@unisoc.com>
Fri, 1 Mar 2024 08:25:55 +0000 (16:25 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 4 Mar 2024 17:52:58 +0000 (09:52 -0800)
f2fs_gc_range may return error, so its caller
f2fs_allocate_pinning_section should determine whether
to do retry based on ist return value.

Also just do f2fs_gc_range when f2fs_allocate_new_section
return -EAGAIN, and check cp error case in f2fs_gc_range.

Signed-off-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/gc.c
fs/f2fs/segment.c

index e435e1f58cd5c3c7f33f2a099919dd6642fbb1e8..c60b7472475bfe0214c1b941b1d3202dcfcdfb47 100644 (file)
@@ -1986,6 +1986,9 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi,
        unsigned int segno;
        unsigned int gc_secs = dry_run_sections;
 
+       if (unlikely(f2fs_cp_error(sbi)))
+               return -EIO;
+
        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),
index e284a3dc97c4ac7ced5a65f8f21f015c6fcc505f..5abb044a9cdf499da02a9a48c4fd412c69831118 100644 (file)
@@ -3109,6 +3109,7 @@ static int __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
 {
        struct curseg_info *curseg = CURSEG_I(sbi, type);
        unsigned int old_segno;
+       int err = 0;
 
        if (type == CURSEG_COLD_DATA_PINNED && !curseg->inited)
                goto allocate;
@@ -3121,8 +3122,9 @@ static int __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
 
 allocate:
        old_segno = curseg->segno;
-       if (new_curseg(sbi, type, true))
-               return -EAGAIN;
+       err = new_curseg(sbi, type, true);
+       if (err)
+               return err;
        stat_inc_seg_type(sbi, curseg);
        locate_dirty_segment(sbi, old_segno);
        return 0;
@@ -3151,13 +3153,14 @@ retry:
        err = f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false);
        f2fs_unlock_op(sbi);
 
-       if (f2fs_sb_has_blkzoned(sbi) && err && gc_required) {
+       if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) {
                f2fs_down_write(&sbi->gc_lock);
-               f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk), true, 1);
+               err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk), true, 1);
                f2fs_up_write(&sbi->gc_lock);
 
                gc_required = false;
-               goto retry;
+               if (!err)
+                       goto retry;
        }
 
        return err;