ext4: only zero partial blocks in ext4_zero_partial_blocks()
authorLukas Czerner <lczerner@redhat.com>
Mon, 1 Jul 2013 12:12:39 +0000 (08:12 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 1 Jul 2013 12:12:39 +0000 (08:12 -0400)
Currently if we pass range into ext4_zero_partial_blocks() which covers
entire block we would attempt to zero it even though we should only zero
unaligned part of the block.

Fix this by checking whether the range covers the whole block skip
zeroing if so.

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext4/inode.c

index 09942341dfae6daca419b64ed1257e68a8c25979..502a9e1f5aa3817183056d81dea92498230cc8e6 100644 (file)
@@ -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;
 }