Commit f41a0716 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

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.
We'd much rather the background scanner keep moving.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
parent a636b1d1
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -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;