]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ext4/extents.c
Merge branch 'clockevents/3.15-fixes' of git://git.linaro.org/people/daniel.lezcano...
[karo-tx-linux.git] / fs / ext4 / extents.c
index 2f49b12a4c40f66b6ec2700a5655d16bc30fc5cf..01b0c208f62507e12f50ddd4fd3669972797f823 100644 (file)
@@ -5395,7 +5395,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
        ext4_lblk_t punch_start, punch_stop;
        handle_t *handle;
        unsigned int credits;
-       loff_t new_size;
+       loff_t new_size, ioffset;
        int ret;
 
        /* Collapse range works only on fs block size aligned offsets. */
@@ -5404,6 +5404,9 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
                return -EINVAL;
 
        if (!S_ISREG(inode->i_mode))
+               return -EINVAL;
+
+       if (EXT4_SB(inode->i_sb)->s_cluster_ratio > 1)
                return -EOPNOTSUPP;
 
        trace_ext4_collapse_range(inode, offset, len);
@@ -5418,8 +5421,15 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
                        return ret;
        }
 
+       /*
+        * Need to round down offset to be aligned with page size boundary
+        * for page size > block size.
+        */
+       ioffset = round_down(offset, PAGE_SIZE);
+
        /* Write out all dirty pages */
-       ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
+       ret = filemap_write_and_wait_range(inode->i_mapping, ioffset,
+                                          LLONG_MAX);
        if (ret)
                return ret;
 
@@ -5441,7 +5451,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
                goto out_mutex;
        }
 
-       truncate_pagecache(inode, offset);
+       truncate_pagecache(inode, ioffset);
 
        /* Wait for existing dio to complete */
        ext4_inode_block_unlocked_dio(inode);