[PATCH v2 0/2] f2fs: pack same-inode blocks by inode during FG_GC

From: Daejun Park

Date: Fri Jun 05 2026 - 05:22:56 EST


Hi,

FG_GC migrates a victim section's valid blocks in source segment-offset
order, so blocks from several inodes stay interleaved in the destination
curseg and post-GC files stay fragmented. This series migrates them in
inode order instead, producing inode-contiguous runs across the section.

Patch 1 is a pure refactor (extract do_migrate_one_data_block()).
Patch 2 records each valid block on a per-inode list in phase 3 and
drains it in inode order via pack_gc_section() once the section has been
scanned. It is gated on a sysfs knob (gc_inode_local_packing, default
on for large sections) and FG_GC only; on slab alloc failure a block
falls back to immediate migration.

Changes since v1:
- patch 2: fix seg_freed accounting. Migration is deferred to
pack_gc_section(), so the in-loop 'freed:' check saw the source still
valid and seg_freed stayed 0; f2fs_gc() then under-counted sec_freed
and a sync F2FS_IOC_GC returned -EAGAIN despite freeing space.
seg_freed is now recomputed after the pack pass.
- patch 2: clear next_victim_seg on the freezing 'goto stop' path,
where queued blocks are dropped un-migrated.
- patch 2: bound the packing queue (MAX_GC_PACK_BLOCKS) and drain it in
batches instead of holding a whole section's records.
- patch 1: unchanged.
- rebased onto current f2fs/dev.

Results (QEMU guest):
- large section (-s 32, 64 x 4 MiB): post-GC extents 65536 -> 49170
(-24 %).
- natural FG_GC, 90 % full, 300 s hot/cold rewrite: cold-file extents
-63 %, move_blks -18 %, skipped_gc_rwsem -59 %.
- seg_freed regression test (new): packing now matches the legacy path
(seg_freed 152, sec_freed 38, 24/24 sync ioctls succeed); on v1 the
packing column was 0/0/0 with every ioctl returning -EAGAIN.

Data sha256 is preserved across GC; a FAULT_SLAB_ALLOC run exercises the
alloc-failure fallback with a clean dmesg.

Daejun Park (2):
f2fs: extract do_migrate_one_data_block() helper for GC migration
f2fs: pack same-inode blocks by inode during FG_GC

Documentation/ABI/testing/sysfs-fs-f2fs | 10 +
fs/f2fs/f2fs.h | 7 +-
fs/f2fs/gc.c | 271 +++++++++++++++++++-----
fs/f2fs/gc.h | 1 +
fs/f2fs/super.c | 1 +
fs/f2fs/sysfs.c | 7 +
6 files changed, 240 insertions(+), 57 deletions(-)


base-commit: c0b65f6129c7fbb526e921dd60261650f1b2bef9
--
2.43.0