diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2020-06-29 14:47:20 -0700 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2020-07-06 10:46:57 -0700 |
commit | e2aaee9cd34d8396a48abf0b1be81a464c1d51c5 (patch) | |
tree | c4fb88e06b3541ae2bcbf610c5abbc7bfab63f71 /fs/xfs/xfs_reflink.c | |
parent | 10b4bd6c9cbc1434c9aca523dac9c4313b56f1ae (diff) | |
download | linux-e2aaee9cd34d8396a48abf0b1be81a464c1d51c5.tar.bz2 |
xfs: move helpers that lock and unlock two inodes against userspace IO
Move the double-inode locking helpers to xfs_inode.c since they're not
specific to reflink.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_reflink.c')
-rw-r--r-- | fs/xfs/xfs_reflink.c | 97 |
1 files changed, 2 insertions, 95 deletions
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index c1f2222ffece..aac83f9d6107 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -1230,99 +1230,6 @@ xfs_reflink_remap_blocks( } /* - * Grab the exclusive iolock for a data copy from src to dest, making sure to - * abide vfs locking order (lowest pointer value goes first) and breaking the - * layout leases before proceeding. The loop is needed because we cannot call - * the blocking break_layout() with the iolocks held, and therefore have to - * back out both locks. - */ -static int -xfs_iolock_two_inodes_and_break_layout( - struct inode *src, - struct inode *dest) -{ - int error; - - if (src > dest) - swap(src, dest); - -retry: - /* Wait to break both inodes' layouts before we start locking. */ - error = break_layout(src, true); - if (error) - return error; - if (src != dest) { - error = break_layout(dest, true); - if (error) - return error; - } - - /* Lock one inode and make sure nobody got in and leased it. */ - inode_lock(src); - error = break_layout(src, false); - if (error) { - inode_unlock(src); - if (error == -EWOULDBLOCK) - goto retry; - return error; - } - - if (src == dest) - return 0; - - /* Lock the other inode and make sure nobody got in and leased it. */ - inode_lock_nested(dest, I_MUTEX_NONDIR2); - error = break_layout(dest, false); - if (error) { - inode_unlock(src); - inode_unlock(dest); - if (error == -EWOULDBLOCK) - goto retry; - return error; - } - - return 0; -} - -/* - * Lock two files so that userspace cannot initiate I/O via file syscalls or - * mmap activity. - */ -static int -xfs_reflink_remap_lock( - struct xfs_inode *ip1, - struct xfs_inode *ip2) -{ - int ret; - - ret = xfs_iolock_two_inodes_and_break_layout(VFS_I(ip1), VFS_I(ip2)); - if (ret) - return ret; - if (ip1 == ip2) - xfs_ilock(ip1, XFS_MMAPLOCK_EXCL); - else - xfs_lock_two_inodes(ip1, XFS_MMAPLOCK_EXCL, - ip2, XFS_MMAPLOCK_EXCL); - return 0; -} - -/* Unlock both files to allow IO and mmap activity. */ -void -xfs_reflink_remap_unlock( - struct xfs_inode *ip1, - struct xfs_inode *ip2) -{ - bool same_inode = (ip1 == ip2); - - xfs_iunlock(ip2, XFS_MMAPLOCK_EXCL); - if (!same_inode) - xfs_iunlock(ip1, XFS_MMAPLOCK_EXCL); - inode_unlock(VFS_I(ip2)); - if (!same_inode) - inode_unlock(VFS_I(ip1)); -} - -/* * If we're reflinking to a point past the destination file's EOF, we must * zero any speculative post-EOF preallocations that sit between the old EOF * and the destination file offset. @@ -1387,7 +1294,7 @@ xfs_reflink_remap_prep( int ret; /* Lock both files against IO */ - ret = xfs_reflink_remap_lock(src, dest); + ret = xfs_ilock2_io_mmap(src, dest); if (ret) return ret; @@ -1440,7 +1347,7 @@ xfs_reflink_remap_prep( return 0; out_unlock: - xfs_reflink_remap_unlock(src, dest); + xfs_iunlock2_io_mmap(src, dest); return ret; } |