ext4: make __ext4_block_zero_page_range() support large folio
authorZhang Yi <yi.zhang@huawei.com>
Mon, 12 May 2025 06:33:14 +0000 (14:33 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 20 May 2025 14:31:12 +0000 (10:31 -0400)
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>
Link: https://patch.msgid.link/20250512063319.3539411-4-yi.zhang@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/inode.c

index fb0de28cefc229c9df3895703a0dce26147adabc..3596090f728a7ce73d1af424f981acc4c5e99343 100644 (file)
@@ -3746,9 +3746,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;
@@ -3763,13 +3761,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;