summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-02-19 17:02:02 -0800
committerDarrick J. Wong <darrick.wong@oracle.com>2020-03-03 18:47:41 -0800
commit9eea11644ddca1e871fc64f32727c4f5321d4f18 (patch)
tree46c06bedefa28d4a52b48bde12e9c27247f694a5 /fs
parentc2aa215ea110429c58de6943212a12d8ee3a5dad (diff)
xfs: don't stall cowblocks scan if we can't take locks
Don't stall the cowblocks scan on a locked inode if we possibly can. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_icache.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 09647dfe5946..c55fc0dfd457 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1737,17 +1737,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)
+ ret = -EAGAIN;
+ return ret;
+ }
+ 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
@@ -1757,6 +1771,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;