xfs: extent shifting doesn't fully invalidate page cache
[platform/kernel/linux-rpi.git] / fs / xfs / xfs_bmap_util.c
index 6de8d90..c045723 100644 (file)
@@ -1080,7 +1080,7 @@ xfs_adjust_extent_unmap_boundaries(
        return 0;
 }
 
-static int
+int
 xfs_flush_unmap_range(
        struct xfs_inode        *ip,
        xfs_off_t               offset,
@@ -1175,9 +1175,9 @@ xfs_free_file_space(
         * page could be mmap'd and iomap_zero_range doesn't do that for us.
         * Writeback of the eof page will do this, albeit clumsily.
         */
-       if (offset + len >= XFS_ISIZE(ip) && ((offset + len) & PAGE_MASK)) {
+       if (offset + len >= XFS_ISIZE(ip) && offset_in_page(offset + len) > 0) {
                error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
-                               (offset + len) & ~PAGE_MASK, LLONG_MAX);
+                               round_down(offset + len, PAGE_SIZE), LLONG_MAX);
        }
 
        return error;
@@ -1244,13 +1244,7 @@ xfs_prepare_shift(
         * Writeback and invalidate cache for the remainder of the file as we're
         * about to shift down every extent from offset to EOF.
         */
-       error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, offset, -1);
-       if (error)
-               return error;
-       error = invalidate_inode_pages2_range(VFS_I(ip)->i_mapping,
-                                       offset >> PAGE_SHIFT, -1);
-       if (error)
-               return error;
+       error = xfs_flush_unmap_range(ip, offset, XFS_ISIZE(ip));
 
        /*
         * Clean out anything hanging around in the cow fork now that
@@ -1824,6 +1818,12 @@ xfs_swap_extents(
        if (error)
                goto out_unlock;
 
+       if (xfs_inode_has_cow_data(tip)) {
+               error = xfs_reflink_cancel_cow_range(tip, 0, NULLFILEOFF, true);
+               if (error)
+                       return error;
+       }
+
        /*
         * Extent "swapping" with rmap requires a permanent reservation and
         * a block reservation because it's really just a remap operation