diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2020-02-19 17:02:02 -0800 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2020-03-03 18:47:41 -0800 |
commit | 9eea11644ddca1e871fc64f32727c4f5321d4f18 (patch) | |
tree | 46c06bedefa28d4a52b48bde12e9c27247f694a5 /fs | |
parent | c2aa215ea110429c58de6943212a12d8ee3a5dad (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.c | 21 |
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; |