[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