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

From: Jan Kara

Date: Thu Jul 02 2026 - 06:39:59 EST


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

> ---
> 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
>
--
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR