xfs: remove isize check from unshare operation
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 10 Oct 2016 05:49:01 +0000 (16:49 +1100)
committerDave Chinner <david@fromorbit.com>
Mon, 10 Oct 2016 05:49:01 +0000 (16:49 +1100)
Now that fallocate has an explicit unshare flag again, let's try
to remove the inode reflink flag whenever the user unshares any
part of a file since checking is cheap compared to the CoW.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reported-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_reflink.c

index c4e35dc..220d263 100644 (file)
@@ -1570,8 +1570,7 @@ next:
  */
 STATIC int
 xfs_reflink_try_clear_inode_flag(
-       struct xfs_inode        *ip,
-       xfs_off_t               old_isize)
+       struct xfs_inode        *ip)
 {
        struct xfs_mount        *mp = ip->i_mount;
        struct xfs_trans        *tp;
@@ -1585,9 +1584,6 @@ xfs_reflink_try_clear_inode_flag(
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        xfs_trans_ijoin(tp, ip, 0);
 
-       if (old_isize != i_size_read(VFS_I(ip)))
-               goto cancel;
-
        error = xfs_reflink_clear_inode_flag(ip, &tp);
        if (error)
                goto cancel;
@@ -1630,7 +1626,7 @@ xfs_reflink_unshare(
 
        /* Try to CoW the selected ranges */
        xfs_ilock(ip, XFS_ILOCK_EXCL);
-       fbno = XFS_B_TO_FSB(mp, offset);
+       fbno = XFS_B_TO_FSBT(mp, offset);
        isize = i_size_read(VFS_I(ip));
        end = XFS_B_TO_FSB(mp, offset + len);
        error = xfs_reflink_dirty_extents(ip, fbno, end, isize);
@@ -1643,12 +1639,10 @@ xfs_reflink_unshare(
        if (error)
                goto out;
 
-       /* Turn off the reflink flag if we unshared the whole file */
-       if (offset == 0 && len == isize) {
-               error = xfs_reflink_try_clear_inode_flag(ip, isize);
-               if (error)
-                       goto out;
-       }
+       /* Turn off the reflink flag if possible. */
+       error = xfs_reflink_try_clear_inode_flag(ip);
+       if (error)
+               goto out;
 
        return 0;