[PATCH 01/20] f2fs: use block-based index and size calculations in remaining paths

From: Daeho Jeong

Date: Mon Nov 02 2026 - 14:41:06 EST


From: Daeho Jeong <daehojeong@xxxxxxxxxx>

Several paths still convert between file offsets and block indices with
PAGE_SHIFT or PAGE_SIZE, assuming that a page holds exactly one
filesystem block. Use the F2FS_BLK_* helpers there so that they stay
correct when the block size is smaller than PAGE_SIZE.

No functional change when the block size equals PAGE_SIZE, except that
__complete_revoke_list() now computes the truncation offset in 64 bits
and no longer overflows beyond 4GB on 32-bit architectures.

Signed-off-by: Daeho Jeong <daehojeong@xxxxxxxxxx>
---
fs/f2fs/data.c | 5 +++--
fs/f2fs/dir.c | 4 ++--
fs/f2fs/file.c | 48 +++++++++++++++++++++++------------------------
fs/f2fs/segment.c | 5 +++--
4 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 4ae61138a003..aacc92839f61 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1897,8 +1897,9 @@ struct folio *f2fs_get_new_data_folio(struct inode *inode,
}
got_it:
if (new_i_size && i_size_read(inode) <
- ((loff_t)(index + 1) << PAGE_SHIFT))
- f2fs_i_size_write(inode, ((loff_t)(index + 1) << PAGE_SHIFT));
+ F2FS_BLK_TO_BYTES(F2FS_I_SB(inode), index + 1))
+ f2fs_i_size_write(inode,
+ F2FS_BLK_TO_BYTES(F2FS_I_SB(inode), index + 1));
return folio;
}

diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 70847313ca6a..3eb0b7255951 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -39,8 +39,8 @@ extern struct kmem_cache *f2fs_cf_name_slab;

static unsigned long dir_blocks(struct inode *inode)
{
- return ((unsigned long long) (i_size_read(inode) + PAGE_SIZE - 1))
- >> PAGE_SHIFT;
+ return F2FS_BYTES_TO_BLK(F2FS_I_SB(inode),
+ i_size_read(inode) + F2FS_BLKSIZE_MASK(F2FS_I_SB(inode)));
}

static unsigned int dir_buckets(unsigned int level, int dir_level)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 05061254c3b2..93d3088c96f0 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1576,7 +1576,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
}
dn.ofs_in_node++;
i++;
- new_size = (loff_t)(dst + i) << PAGE_SHIFT;
+ new_size = F2FS_BLK_TO_BYTES(sbi, dst + i);
if (dst_inode->i_size < new_size)
f2fs_i_size_write(dst_inode, new_size);
} while (--ilen && (do_replace[i] || blkaddr[i] == NULL_ADDR));
@@ -1593,7 +1593,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
return PTR_ERR(fsrc);

src_off = offset_in_folio(fsrc,
- (loff_t)(src + i) << PAGE_SHIFT);
+ F2FS_BLK_TO_BYTES(sbi, src + i));

/*
* For same-inode operations (collapse/insert), src and
@@ -1623,10 +1623,10 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
}

dst_off = offset_in_folio(fdst,
- (loff_t)(dst + i) << PAGE_SHIFT);
+ F2FS_BLK_TO_BYTES(sbi, dst + i));
f2fs_folio_wait_writeback(fdst, true, true);
memcpy_folio(fdst, dst_off, fsrc, src_off,
- PAGE_SIZE);
+ F2FS_BLKSIZE(sbi));
if (folio_test_large(fdst)) {
if (!f2fs_ffs_find_or_alloc(fdst)) {
f2fs_folio_put(fdst, true);
@@ -1635,15 +1635,15 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
return -ENOMEM;
}
f2fs_ffs_mark_subrange_uptodate(fdst,
- dst_off, PAGE_SIZE);
+ dst_off, F2FS_BLKSIZE(sbi));
f2fs_ffs_mark_subrange_dirty(fdst, dst_off,
- PAGE_SIZE);
+ F2FS_BLKSIZE(sbi));
}
folio_mark_dirty(fdst);
if (same_folio && i_size_read(dst_inode) <
- ((loff_t)(dst + i + 1) << PAGE_SHIFT))
+ F2FS_BLK_TO_BYTES(sbi, dst + i + 1))
f2fs_i_size_write(dst_inode,
- ((loff_t)(dst + i + 1) << PAGE_SHIFT));
+ F2FS_BLK_TO_BYTES(sbi, dst + i + 1));
folio_set_f2fs_gcing(fdst);
f2fs_folio_put(fdst, true);
if (!same_folio)
@@ -1715,9 +1715,9 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_lock_context lc;
- pgoff_t nrpages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
- pgoff_t start = offset >> PAGE_SHIFT;
- pgoff_t end = (offset + len) >> PAGE_SHIFT;
+ pgoff_t nrpages = F2FS_BLK_ALIGN(sbi, i_size_read(inode));
+ pgoff_t start = F2FS_BYTES_TO_BLK(sbi, offset);
+ pgoff_t end = F2FS_BYTES_TO_BLK(sbi, offset + len);
int ret;

f2fs_balance_fs(sbi, true);
@@ -1988,10 +1988,10 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
if (ret)
return ret;

- pg_start = offset >> PAGE_SHIFT;
- pg_end = (offset + len) >> PAGE_SHIFT;
+ pg_start = F2FS_BYTES_TO_BLK(sbi, offset);
+ pg_end = F2FS_BYTES_TO_BLK(sbi, offset + len);
delta = pg_end - pg_start;
- idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ idx = F2FS_BLK_ALIGN(sbi, i_size_read(inode));

/* avoid gc operation during block exchange */
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
@@ -3104,10 +3104,10 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
f2fs_balance_fs(sbi, true);

inode_lock(inode);
- pg_start = range->start >> PAGE_SHIFT;
+ pg_start = F2FS_BYTES_TO_BLK(sbi, range->start);
pg_end = min_t(pgoff_t,
- (range->start + range->len) >> PAGE_SHIFT,
- DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE));
+ F2FS_BYTES_TO_BLK(sbi, range->start + range->len),
+ F2FS_BLK_ALIGN(sbi, i_size_read(inode)));

if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED) ||
f2fs_is_atomic_file(inode)) {
@@ -3124,8 +3124,8 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,

/* writeback all dirty pages in the range */
err = filemap_write_and_wait_range(inode->i_mapping,
- (loff_t)pg_start << PAGE_SHIFT,
- ((loff_t)pg_end << PAGE_SHIFT) - 1);
+ F2FS_BLK_TO_BYTES(sbi, pg_start),
+ F2FS_BLK_TO_BYTES(sbi, pg_end) - 1);
if (err)
goto out;

@@ -3249,7 +3249,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
unlock_out:
inode_unlock(inode);
if (!err) {
- range->len = (u64)total << PAGE_SHIFT;
+ range->len = F2FS_BLK_TO_BYTES(sbi, total);
stat_inc_defrag_blk_count(sbi, total);
}
return err;
@@ -4354,7 +4354,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(inode->i_mapping);

- last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ last_idx = F2FS_BLK_ALIGN(sbi, i_size_read(inode));

while (page_idx < last_idx) {
struct dnode_of_data dn;
@@ -4532,7 +4532,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(inode->i_mapping);

- last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ last_idx = F2FS_BLK_ALIGN(sbi, i_size_read(inode));

while (page_idx < last_idx) {
struct dnode_of_data dn;
@@ -4997,7 +4997,7 @@ static int f2fs_ioc_decompress_file(struct file *filp)
if (!atomic_read(&fi->i_compr_blocks))
goto out;

- last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ last_idx = F2FS_BLK_ALIGN(sbi, i_size_read(inode));
last_idx >>= fi->i_log_cluster_size;

for (cluster_idx = 0; cluster_idx < last_idx; cluster_idx++) {
@@ -5084,7 +5084,7 @@ static int f2fs_ioc_compress_file(struct file *filp)

set_inode_flag(inode, FI_ENABLE_COMPRESS);

- last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ last_idx = F2FS_BLK_ALIGN(sbi, i_size_read(inode));
last_idx >>= fi->i_log_cluster_size;

for (cluster_idx = 0; cluster_idx < last_idx; cluster_idx++) {
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 31ac93a93021..2b0821c2c18b 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -285,6 +285,7 @@ static int __replace_atomic_write_block(struct inode *inode, pgoff_t index,
static void __complete_revoke_list(struct inode *inode, struct list_head *head,
bool revoke)
{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct revoke_entry *cur, *tmp;
pgoff_t start_index = 0;
bool truncate = is_inode_flag_set(inode, FI_ATOMIC_REPLACE);
@@ -303,7 +304,7 @@ static void __complete_revoke_list(struct inode *inode, struct list_head *head,
}

if (!revoke && truncate)
- f2fs_do_truncate_blocks(inode, start_index * PAGE_SIZE, false);
+ f2fs_do_truncate_blocks(inode, F2FS_BLK_TO_BYTES(sbi, start_index), false);
}

static int __f2fs_commit_atomic_write(struct inode *inode)
@@ -315,7 +316,7 @@ static int __f2fs_commit_atomic_write(struct inode *inode)
struct list_head revoke_list;
block_t blkaddr;
struct dnode_of_data dn;
- pgoff_t len = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ pgoff_t len = F2FS_BLK_ALIGN(sbi, i_size_read(inode));
pgoff_t off = 0, blen, index;
int ret = 0, i;

--
2.56.0.317.g454f8302e1-goog