From: Zhang Yi In ext4_zero_range(), move the ext4_zero_partial_blocks() call, which handles unaligned edges, into the same branch where the unaligned range is preallocated, immediately after ext4_alloc_file_blocks(). This is safe because there is no dependency between partial block handling and the subsequent full block handling. This change will be used by later patches that handle unaligned FALLOC_FL_WRITE_ZEROES operations, which will need to check the partial zeroed result. Signed-off-by: Zhang Yi Reviewed-by: Jan Kara --- fs/ext4/extents.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 125f628e738a..27ca641e701b 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4734,10 +4734,16 @@ static long ext4_zero_range(struct file *file, loff_t offset, } flags = EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT; - /* Preallocate the range including the unaligned edges */ + /* + * Preallocate the range including the unaligned edges, and zero + * out partial blocks if they already contain data. + */ if (!IS_ALIGNED(offset | end, blocksize)) { ret = ext4_alloc_file_blocks(file, offset, len, new_size, flags); + if (!ret) + ret = ext4_zero_partial_blocks(inode, offset, len, + &partial_zeroed); if (ret) return ret; } @@ -4770,10 +4776,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, if (IS_ALIGNED(offset | end, blocksize)) return ret; - /* Zero out partial block at the edges of the range */ - ret = ext4_zero_partial_blocks(inode, offset, len, &partial_zeroed); - if (ret) - return ret; if (((file->f_flags & O_SYNC) || IS_SYNC(inode)) && partial_zeroed) { ret = filemap_write_and_wait_range(inode->i_mapping, offset, end - 1); -- 2.52.0