summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/inode.c17
1 files changed, 10 insertions, 7 deletions
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;
}