Re: [PATCH 6/6] ext4: skip ext4_update_disksize_before_punch() in WRITE_ZEROES

From: Zhang Yi

Date: Thu Jul 02 2026 - 11:04:47 EST


On 7/2/2026 6:19 PM, Jan Kara wrote:
On Wed 01-07-26 22:20:09, yizhang089@xxxxxxxxx wrote:
From: Zhang Yi <yi.zhang@xxxxxxxxxx>

FALLOC_FL_WRITE_ZEROES is mutually exclusive with FALLOC_FL_KEEP_SIZE.
In ext4_zero_range(), when end > i_disksize, new_size is always set to
end for WRITE_ZEROES, so the i_disksize update should not be lost.

The ext4_update_disksize_before_punch() call is only needed for the
ZERO_RANGE path in ext4_zero_range(), as it handles the case where
KEEP_SIZE may preserve the original disk size. Skip it for WRITE_ZEROES
to avoid unnecessary work and potential confusion.

Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx>

Hum, but suppose i_disksize is before the start of our zeroed range, i_size
is beyond the end of the zeroed range. Now
ext4_alloc_file_blocks(EXT4_GET_BLOCKS_CREATE_ZERO) will create some zeroed
written extents beyond i_disksize and if we crash before
ext4_update_inode_size() runs, we have inconsistent filesystem with
written extents beyond i_disksize... Hum, actually that could have been the
case even before, just now there are more cases where this can happen. So I
think FALLOC_FL_WRITE_ZEROES mode needs to add the inode to the orphan list
to truncate the inode properly in case of crash.

Honza

Yes, indeed. I overlooked this case previously. I will address it in the
next version.

Thanks,
Yi.


---
fs/ext4/extents.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index c083703bf704..38753c2ef910 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4748,9 +4748,11 @@ static long ext4_zero_range(struct file *file, loff_t offset,
return ret;
}
- ret = ext4_update_disksize_before_punch(inode, offset, len);
- if (ret)
- return ret;
+ if (mode & FALLOC_FL_ZERO_RANGE) {
+ ret = ext4_update_disksize_before_punch(inode, offset, len);
+ if (ret)
+ return ret;
+ }
/* Now release the pages and zero block aligned part of pages */
ret = ext4_truncate_page_cache_block_range(inode, offset, end);
--
2.53.0