[PATCH v2 3/8] ext4: make __ext4_block_zero_page_range() support large folio

Zhang Yi
2025-05-12T06:44:52Z

From: Zhang Yi <yi.zhang@huawei.com>

The partial block zero range helper __ext4_block_zero_page_range()
currently only supports folios of PAGE_SIZE in size. The calculations
for the start block and the offset within a folio for the given range
are incorrect. Modify the implementation to use offset_in_folio()
instead of directly masking PAGE_SIZE - 1, which will be able to support
for large folios.

Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
---
fs/ext4/inode.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 4d8187f3814e..573ae0b3be1d 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3701,9 +3701,7 @@ void ext4_set_aops(struct inode *inode)
static int __ext4_block_zero_page_range(handle_t *handle,
struct address_space *mapping, loff_t from, loff_t length)
{
- ext4_fsblk_t index = from >> PAGE_SHIFT;
- unsigned offset = from & (PAGE_SIZE-1);
- unsigned blocksize, pos;
+ unsigned int offset, blocksize, pos;
ext4_lblk_t iblock;
struct inode *inode = mapping->host;
struct buffer_head *bh;
@@ -3718,13 +3716,14 @@ static int __ext4_block_zero_page_range(handle_t *handle,

blocksize = inode->i_sb->s_blocksize;

- iblock = index << (PAGE_SHIFT - inode->i_sb->s_blocksize_bits);
+ iblock = folio->index << (PAGE_SHIFT - inode->i_sb->s_blocksize_bits);

bh = folio_buffers(folio);
if (!bh)
bh = create_empty_buffers(folio, blocksize, 0);

/* Find the buffer that contains "offset" */
+ offset = offset_in_folio(folio, from);
pos = blocksize;
while (offset >= pos) {
bh = bh->b_this_page;
--
2.46.1