* [PATCH 6.6.y 1/3] f2fs: fix to reclaim space in f2fs_allocate_pinning_section()
@ 2026-10-09 10:58 Chao Yu
2026-10-09 10:58 ` [PATCH 6.6.y 2/3] f2fs: fix to shrink gc_lock coverage in f2fs_gc_range() Chao Yu
2026-10-09 10:58 ` [PATCH 6.6.y 3/3] f2fs: fix to reset all pinned status during fggc Chao Yu
0 siblings, 2 replies; 3+ messages in thread
From: Chao Yu @ 2026-10-09 10:58 UTC (permalink / raw)
To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu, stable, Daeho Jeong
From: Chao Yu <chao@kernel.org>
[ Upstream commit fa487f56efba6344aef67d871688f0908fe08af3 ]
It needs to trigger checkpoint to free space reclaimed by f2fs_gc_range(),
otherwise, fallocate() on pinfile will fail easily even there is slash
space in conventional zone.
[Testcase]
nullblk_create.sh 512 2 1024 1024
mkfs.f2fs /dev/nullb0 -f -m
mount /dev/nullb0 /mnt/f2fs/
touch /mnt/f2fs/pinfile
f2fs_io pinfile set /mnt/f2fs/pinfile
mkdir /mnt/f2fs/dir/
for((i=0;i<3934;i++)) do { dd if=/dev/zero of=/mnt/f2fs/dir/$i bs=1M count=1;} done
sync
for((i=0;i<3934;i+=2)) do { rm /mnt/f2fs/dir/$i;} done
for((i=0;i<1950;i++)) do { rm /mnt/f2fs/dir/$i;} done
sync
f2fs_io fallocate 0 0 $((1024*1024*1024)) /mnt/f2fs/pinfile
sync
stat /mnt/f2fs/pinfile
f2fs_io fiemap 0 $((1024*1024*1024)) /mnt/f2fs/pinfile
[Before]
fallocate failed: Resource temporarily unavailable
File: /mnt/f2fs/pinfile
Size: 109051904 Blocks: 213208 IO Block: 4096 regular file
Device: 250,0 Inode: 4 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2026-08-12 20:04:02.264000000 +0800
Modify: 2026-08-12 20:04:26.784000000 +0800
Change: 2026-08-12 20:04:26.784000000 +0800
Birth: -
root@localhost:~#
root@localhost:~#
root@localhost:~#
root@localhost:~# f2fs_io fiemap 0 $((1024*1024*1024)) /mnt/f2fs/pinfile
Fiemap: offset = 0 len = 1073741824
logical addr. physical addr. length flags
0 0000000000000000 0000000002e00000 0000000000200000 00001000
1 0000000000200000 000000002dc00000 0000000000400000 00001000
2 0000000000600000 000000002e400000 0000000000600000 00001000
3 0000000000c00000 000000007a400000 0000000005c00000 00001001
[After]
File: /mnt/f2fs/pinfile
Size: 1073741824 Blocks: 2099216 IO Block: 4096 regular file
Device: 250,0 Inode: 4 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2026-08-12 19:47:49.428000000 +0800
Modify: 2026-08-12 19:49:06.808000000 +0800
Change: 2026-08-12 19:49:06.808000000 +0800
Birth: -
Fiemap: offset = 0 len = 1073741824
logical addr. physical addr. length flags
0 0000000000000000 0000000002e00000 0000000000200000 00001000
1 0000000000200000 000000003aa00000 0000000000400000 00001000
2 0000000000600000 000000003b400000 0000000000200000 00001000
3 0000000000800000 000000007a200000 0000000005e00000 00001000
4 0000000006600000 0000000002800000 0000000000200000 00001000
5 0000000006800000 0000000003200000 0000000000400000 00001000
6 0000000006c00000 0000000003000000 0000000000200000 00001000
7 0000000006e00000 0000000003600000 0000000037200000 00001000
8 000000003e000000 000000003b200000 0000000000200000 00001000
9 000000003e200000 000000003a800000 0000000000200000 00001000
10 000000003e400000 000000003ae00000 0000000000400000 00001000
11 000000003e800000 000000003b600000 0000000001800000 00001001
Cc: stable@kernel.org
Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
Cc: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ Chao Yu: backport to 6.6.y:
- retain existing f2fs_up_write(&sbi->gc_lock) as 6.6 lacks lock tracing
- assign err = f2fs_gc_range(...) to check return value as in upstream ]
Signed-off-by: Chao Yu <chao@kernel.org>
---
fs/f2fs/segment.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 9c27353f384b..c5c94ac40860 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3148,11 +3148,15 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi)
if (f2fs_sb_has_blkzoned(sbi) && err && 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)
+ return err;
+ err = f2fs_sync_fs(sbi->sb, 1);
+ if (!err) {
+ gc_required = false;
+ goto retry;
+ }
}
return err;
--
2.49.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH 6.6.y 2/3] f2fs: fix to shrink gc_lock coverage in f2fs_gc_range() 2026-10-09 10:58 [PATCH 6.6.y 1/3] f2fs: fix to reclaim space in f2fs_allocate_pinning_section() Chao Yu @ 2026-10-09 10:58 ` Chao Yu 2026-10-09 10:58 ` [PATCH 6.6.y 3/3] f2fs: fix to reset all pinned status during fggc Chao Yu 1 sibling, 0 replies; 3+ messages in thread From: Chao Yu @ 2026-10-09 10:58 UTC (permalink / raw) To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu, stable, Daeho Jeong From: Chao Yu <chao@kernel.org> [ Upstream commit 5d49025a4e596c4c9ac0c519ef9f9a2c91396856 ] In f2fs_allocate_pinning_section(), we will hold gc_lock before calling f2fs_gc_range() to migrate section in conventional zone, we may suffer worse case because we may need to traverse and migrate multiple sections if we failed to move blocks in section due to lot of reasons: ENOMEM, fail to migrate block of pinfile, racing on i_gc_rwsem. To avoid hold gc_lock for long time to block checkpoint, let's hold the lock and only try to migrate one section. Cc: stable@kernel.org Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices") Cc: Daeho Jeong <daehojeong@google.com> Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> [ Chao Yu: backport to 6.6.y: - drop file.c changes as f2fs_ioc_reserve_dev_alias() is not present in 6.6 - use f2fs_{down,up}_write(&sbi->gc_lock) as 6.6 lacks lock tracing - use IS_CURSEC() in gc.c as cursec pinning is not present in 6.6 - pass dry_run_sections == 0 to do_garbage_collect() as in 6.6 ] Signed-off-by: Chao Yu <chao@kernel.org> --- fs/f2fs/f2fs.h | 2 +- fs/f2fs/gc.c | 33 ++++++++++++++++++++++++--------- fs/f2fs/segment.c | 4 +--- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 63d3450f895e..bf6f58c110f2 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3921,7 +3921,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control); void f2fs_build_gc_manager(struct f2fs_sb_info *sbi); int f2fs_gc_range(struct f2fs_sb_info *sbi, unsigned int start_seg, unsigned int end_seg, - bool dry_run, unsigned int dry_run_sections); + bool dry_run, unsigned int dry_run_sections, bool lock); int f2fs_resize_fs(struct file *filp, __u64 block_count); int __init f2fs_create_garbage_collection_cache(void); void f2fs_destroy_garbage_collection_cache(void); diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index ac21950f53cd..8a37461fc278 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -2034,7 +2034,7 @@ void f2fs_build_gc_manager(struct f2fs_sb_info *sbi) int f2fs_gc_range(struct f2fs_sb_info *sbi, unsigned int start_seg, unsigned int end_seg, - bool dry_run, unsigned int dry_run_sections) + bool dry_run, unsigned int dry_run_sections, bool lock) { unsigned int segno; unsigned int gc_secs = dry_run_sections; @@ -2045,29 +2045,44 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi, .ilist = LIST_HEAD_INIT(gc_list.ilist), .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS), }; + int err = 0; + + if (lock) + f2fs_down_write(&sbi->gc_lock); /* * avoid migrating empty section, as it can be allocated by * log in parallel. */ if (!get_valid_blocks(sbi, segno, true)) - continue; + goto next; if (IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, segno))) - continue; + goto next; do_garbage_collect(sbi, segno, &gc_list, FG_GC, dry_run_sections == 0); put_gc_inode(&gc_list); - if (!dry_run && get_valid_blocks(sbi, segno, true)) - return -EAGAIN; + if (!dry_run && get_valid_blocks(sbi, segno, true)) { + err = -EAGAIN; + goto next; + } if (dry_run && dry_run_sections && - !get_valid_blocks(sbi, segno, true) && --gc_secs == 0) - break; + !get_valid_blocks(sbi, segno, true)) { + --gc_secs; + goto next; + } if (fatal_signal_pending(current)) - return -ERESTARTSYS; + err = -ERESTARTSYS; +next: + if (lock) + f2fs_up_write(&sbi->gc_lock); + if (err) + return err; + if (dry_run && dry_run_sections && !gc_secs) + return 0; } return 0; @@ -2102,7 +2117,7 @@ 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 */ - err = f2fs_gc_range(sbi, start, end, dry_run, 0); + err = f2fs_gc_range(sbi, start, end, dry_run, 0, false); if (err || dry_run) goto out; diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index c5c94ac40860..6bc1b57a7835 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -3147,9 +3147,7 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi) f2fs_unlock_op(sbi); if (f2fs_sb_has_blkzoned(sbi) && err && gc_required) { - f2fs_down_write(&sbi->gc_lock); - err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk), true, 1); - f2fs_up_write(&sbi->gc_lock); + err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk), true, 1, true); if (err) return err; err = f2fs_sync_fs(sbi->sb, 1); -- 2.49.0 ^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 6.6.y 3/3] f2fs: fix to reset all pinned status during fggc 2026-10-09 10:58 [PATCH 6.6.y 1/3] f2fs: fix to reclaim space in f2fs_allocate_pinning_section() Chao Yu 2026-10-09 10:58 ` [PATCH 6.6.y 2/3] f2fs: fix to shrink gc_lock coverage in f2fs_gc_range() Chao Yu @ 2026-10-09 10:58 ` Chao Yu 1 sibling, 0 replies; 3+ messages in thread From: Chao Yu @ 2026-10-09 10:58 UTC (permalink / raw) To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu, stable, Daeho Jeong From: Chao Yu <chao@kernel.org> [ Upstream commit 2b8704b6a8b2896ccad1f5941d9a3e2c5031a470 ] Otherwise, the pinned status may affect latter flow of fggc. Cc: stable@kernel.org Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices") Cc: Daeho Jeong <daehojeong@google.com> Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> Signed-off-by: Chao Yu <chao@kernel.org> --- fs/f2fs/gc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 8a37461fc278..8a4395bfeff6 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -2064,6 +2064,9 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi, dry_run_sections == 0); put_gc_inode(&gc_list); + /* reset all pinned status during fggc */ + f2fs_unpin_all_sections(sbi, true); + if (!dry_run && get_valid_blocks(sbi, segno, true)) { err = -EAGAIN; goto next; -- 2.49.0 ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-09 10:58 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-10-09 10:58 [PATCH 6.6.y 1/3] f2fs: fix to reclaim space in f2fs_allocate_pinning_section() Chao Yu 2026-10-09 10:58 ` [PATCH 6.6.y 2/3] f2fs: fix to shrink gc_lock coverage in f2fs_gc_range() Chao Yu 2026-10-09 10:58 ` [PATCH 6.6.y 3/3] f2fs: fix to reset all pinned status during fggc Chao Yu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®