xfs: don't stall cowblocks scan if we can't take locks
authorDarrick J. Wong <djwong@kernel.org>
Sat, 23 Jan 2021 00:48:35 +0000 (16:48 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 3 Feb 2021 17:18:49 +0000 (09:18 -0800)
Don't stall the cowblocks scan on a locked inode if we possibly can.
We'd much rather the background scanner keep moving.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
fs/xfs/xfs_icache.c

index c71eb15e383518db889dc5a3d042798e3f56690e..89f9e692fde759eb0b7b223d91918dcd0b17fd58 100644 (file)
@@ -1605,17 +1605,31 @@ xfs_inode_free_cowblocks(
        void                    *args)
 {
        struct xfs_eofblocks    *eofb = args;
+       bool                    wait;
        int                     ret = 0;
 
+       wait = eofb && (eofb->eof_flags & XFS_EOF_FLAGS_SYNC);
+
        if (!xfs_prep_free_cowblocks(ip))
                return 0;
 
        if (!xfs_inode_matches_eofb(ip, eofb))
                return 0;
 
-       /* Free the CoW blocks */
-       xfs_ilock(ip, XFS_IOLOCK_EXCL);
-       xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
+       /*
+        * If the caller is waiting, return -EAGAIN to keep the background
+        * scanner moving and revisit the inode in a subsequent pass.
+        */
+       if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
+               if (wait)
+                       return -EAGAIN;
+               return 0;
+       }
+       if (!xfs_ilock_nowait(ip, XFS_MMAPLOCK_EXCL)) {
+               if (wait)
+                       ret = -EAGAIN;
+               goto out_iolock;
+       }
 
        /*
         * Check again, nobody else should be able to dirty blocks or change
@@ -1625,6 +1639,7 @@ xfs_inode_free_cowblocks(
                ret = xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, false);
 
        xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
+out_iolock:
        xfs_iunlock(ip, XFS_IOLOCK_EXCL);
 
        return ret;