|
@@ -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;
|
|
|
}
|
|
|
|