[PATCH] f2fs: do not discard valid segments with discard_unit=section

From: Keoseong Park

Date: Mon Oct 12 2026 - 03:02:44 EST


With discard_unit=section, f2fs_clear_prefree_segments() widens a run
of prefree segments to section boundaries, but only LFS mode checks the
sections for valid blocks afterwards. In adaptive mode with large
sections the widened range is discarded as it is, including segments
that are still valid, and their data is lost.

Check each section whenever the range was widened over large sections.

Testcase:
- mkfs.f2fs -f -s 2 /dev/vda
- mount -o discard,discard_unit=section /dev/vda /mnt/f2fs
- for i in 0 1 2 3 4 5; do
dd if=/dev/urandom of=/mnt/f2fs/k$i bs=2M count=1 conv=fsync; done
- rm /mnt/f2fs/k0 /mnt/f2fs/k2 /mnt/f2fs/k4; sync
- umount /mnt/f2fs
- mount -o discard,discard_unit=section /dev/vda /mnt/f2fs

Before, k1, k3 and k5 are lost after the remount, or the umount hits
the f2fs_bug_on() in __check_sit_bitmap() with CONFIG_F2FS_CHECK_FS.
After, they are intact.

Fixes: 4f993264fe29 ("f2fs: introduce discard_unit mount option")
Signed-off-by: Keoseong Park <keosung.park@xxxxxxxxxxx>
---
fs/f2fs/segment.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 794e0d99fc7..2e1502c5571 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2325,7 +2325,7 @@ void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,

/* Should cover 2MB zoned device for zone-based reset */
if (!f2fs_sb_has_blkzoned(sbi) &&
- (!f2fs_lfs_mode(sbi) || !__is_large_section(sbi))) {
+ (!section_alignment || !__is_large_section(sbi))) {
f2fs_issue_discard(sbi, START_BLOCK(sbi, start),
SEGS_TO_BLKS(sbi, end - start));
continue;
--
2.43.0