[PATCH 12/20] f2fs: support subpage blocks in defragmentation

From: Daeho Jeong

Date: Mon Nov 02 2026 - 16:16:41 EST


From: Daeho Jeong <daehojeong@xxxxxxxxxx>

Mark only the target block, not its whole page, dirty when redirtying
data for defragmentation, and read a multi-block folio once instead of
each block synchronously. Remove the -EOPNOTSUPP check. Reading the
folio once also applies to large folios when the block size equals
PAGE_SIZE.

Signed-off-by: Daeho Jeong <daehojeong@xxxxxxxxxx>
---
fs/f2fs/file.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 0fad86267256..29cfc0e2719a 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -3312,6 +3312,20 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
cnt < BLKS_PER_SEG(sbi)) {
struct folio *folio;

+ /*
+ * Read the whole folio in one I/O; otherwise each block
+ * of a multi-block folio is read synchronously below.
+ */
+ if (f2fs_has_multiblock_folios(inode)) {
+ folio = read_mapping_folio(inode->i_mapping,
+ f2fs_lblk_to_folio_index(sbi, idx), filp);
+ if (IS_ERR(folio)) {
+ err = PTR_ERR(folio);
+ goto clear_out;
+ }
+ folio_put(folio);
+ }
+
folio = f2fs_get_lock_data_folio(inode, idx, true);
if (IS_ERR(folio)) {
err = PTR_ERR(folio);
@@ -3320,9 +3334,13 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,

f2fs_folio_wait_writeback(folio, true, true);

- f2fs_ffs_mark_subrange_dirty(folio,
- offset_in_folio(folio, (loff_t)idx << PAGE_SHIFT),
- PAGE_SIZE);
+ if (f2fs_is_multiblock_folio(sbi, folio)) {
+ size_t off = f2fs_folio_byte_offset(sbi, folio, idx);
+
+ f2fs_ffs_mark_subrange_dirty(folio, off,
+ F2FS_BLKSIZE(sbi));
+ }
+
folio_mark_dirty(folio);
folio_set_f2fs_gcing(folio);
f2fs_folio_put(folio, true);
@@ -3363,9 +3381,6 @@ static int f2fs_ioc_defragment(struct file *filp, unsigned long arg)
struct f2fs_defragment range;
int err;

- if (f2fs_has_subpage_blocks(sbi))
- return -EOPNOTSUPP;
-
if (!capable(CAP_SYS_ADMIN))
return -EPERM;

--
2.56.0.317.g454f8302e1-goog