]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
f2fs: The GC triggered by ioctl also needs to mark the segno as victim
authorYongpeng Yang <yangyongpeng1@oppo.com>
Wed, 4 Dec 2024 03:31:13 +0000 (11:31 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 16 Dec 2024 16:12:29 +0000 (16:12 +0000)
In SSR mode, the segment selected for allocation might be the same as
the target segment of the GC triggered by ioctl, resulting in the GC
moving the CURSEG_I(sbi, type)->segno.
Thread A Thread B or Thread A
- f2fs_ioc_gc_range
 - __f2fs_ioc_gc_range(.victim_segno=segno#N)
  - f2fs_gc
   - __get_victim
    - f2fs_get_victim
    : segno#N is valid, return segno#N as source segment of GC
- f2fs_allocate_data_block
- need_new_seg
- get_ssr_segment
- f2fs_get_victim
: get segno #N as destination segment
- change_curseg

Fixes: e066b83c9b40 ("f2fs: add ioctl to flush data from faster device to cold area")
Signed-off-by: Yongpeng Yang <yangyongpeng1@oppo.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/gc.c

index 3e1b6d2ff3a7303ea8fb31fbbffe939eb437ac93..8029369bb71dfebde95c0222ee8399a3bef896eb 100644 (file)
@@ -806,11 +806,14 @@ retry:
                        goto out;
                }
 
-               if (sec_usage_check(sbi, GET_SEC_FROM_SEG(sbi, *result)))
+               if (sec_usage_check(sbi, GET_SEC_FROM_SEG(sbi, *result))) {
                        ret = -EBUSY;
-               else
-                       p.min_segno = *result;
-               goto out;
+                       goto out;
+               }
+               if (gc_type == FG_GC)
+                       clear_bit(GET_SEC_FROM_SEG(sbi, *result), dirty_i->victim_secmap);
+               p.min_segno = *result;
+               goto got_result;
        }
 
        ret = -ENODATA;