[PATCH 02/11] xfs: don't stall cowblocks scan if we can't take locks

Darrick J. Wong
2021-01-23T18:53:10Z

From: Darrick J. Wong <djwong@kernel.org>

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>
---
fs/xfs/xfs_icache.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index c71eb15e3835..89f9e692fde7 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -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;