diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 09942341dfae..502a9e1f5aa3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3424,33 +3424,36 @@ int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, { struct super_block *sb = inode->i_sb; struct address_space *mapping = inode->i_mapping; - unsigned partial = lstart & (sb->s_blocksize - 1); + unsigned partial_start, partial_end; ext4_fsblk_t start, end; loff_t byte_end = (lstart + length - 1); int err = 0; + partial_start = lstart & (sb->s_blocksize - 1); + partial_end = byte_end & (sb->s_blocksize - 1); + start = lstart >> sb->s_blocksize_bits; end = byte_end >> sb->s_blocksize_bits; /* Handle partial zero within the single block */ - if (start == end) { + if (start == end && + (partial_start || (partial_end != sb->s_blocksize - 1))) { err = ext4_block_zero_page_range(handle, mapping, lstart, length); return err; } /* Handle partial zero out on the start of the range */ - if (partial) { + if (partial_start) { err = ext4_block_zero_page_range(handle, mapping, lstart, sb->s_blocksize); if (err) return err; } /* Handle partial zero out on the end of the range */ - partial = byte_end & (sb->s_blocksize - 1); - if (partial != sb->s_blocksize - 1) + if (partial_end != sb->s_blocksize - 1) err = ext4_block_zero_page_range(handle, mapping, - byte_end - partial, - partial + 1); + byte_end - partial_end, + partial_end + 1); return err; }