Commit d2c292d8 authored by Jan Kara's avatar Jan Kara

xfs: Convert double locking of MMAPLOCK to use VFS helpers

Convert places in XFS that take MMAPLOCK for two inodes to use helper
VFS provides for it (filemap_invalidate_down_write_two()). Note that
this changes lock ordering for MMAPLOCK from inode number based ordering
to pointer based ordering VFS generally uses.

CC: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 2433480a
...@@ -1626,7 +1626,6 @@ xfs_swap_extents( ...@@ -1626,7 +1626,6 @@ xfs_swap_extents(
struct xfs_bstat *sbp = &sxp->sx_stat; struct xfs_bstat *sbp = &sxp->sx_stat;
int src_log_flags, target_log_flags; int src_log_flags, target_log_flags;
int error = 0; int error = 0;
int lock_flags;
uint64_t f; uint64_t f;
int resblks = 0; int resblks = 0;
unsigned int flags = 0; unsigned int flags = 0;
...@@ -1638,8 +1637,8 @@ xfs_swap_extents( ...@@ -1638,8 +1637,8 @@ xfs_swap_extents(
* do the rest of the checks. * do the rest of the checks.
*/ */
lock_two_nondirectories(VFS_I(ip), VFS_I(tip)); lock_two_nondirectories(VFS_I(ip), VFS_I(tip));
lock_flags = XFS_MMAPLOCK_EXCL; filemap_invalidate_lock_two(VFS_I(ip)->i_mapping,
xfs_lock_two_inodes(ip, XFS_MMAPLOCK_EXCL, tip, XFS_MMAPLOCK_EXCL); VFS_I(tip)->i_mapping);
/* Verify that both files have the same format */ /* Verify that both files have the same format */
if ((VFS_I(ip)->i_mode & S_IFMT) != (VFS_I(tip)->i_mode & S_IFMT)) { if ((VFS_I(ip)->i_mode & S_IFMT) != (VFS_I(tip)->i_mode & S_IFMT)) {
...@@ -1711,7 +1710,6 @@ xfs_swap_extents( ...@@ -1711,7 +1710,6 @@ xfs_swap_extents(
* or cancel will unlock the inodes from this point onwards. * or cancel will unlock the inodes from this point onwards.
*/ */
xfs_lock_two_inodes(ip, XFS_ILOCK_EXCL, tip, XFS_ILOCK_EXCL); xfs_lock_two_inodes(ip, XFS_ILOCK_EXCL, tip, XFS_ILOCK_EXCL);
lock_flags |= XFS_ILOCK_EXCL;
xfs_trans_ijoin(tp, ip, 0); xfs_trans_ijoin(tp, ip, 0);
xfs_trans_ijoin(tp, tip, 0); xfs_trans_ijoin(tp, tip, 0);
...@@ -1830,13 +1828,16 @@ xfs_swap_extents( ...@@ -1830,13 +1828,16 @@ xfs_swap_extents(
trace_xfs_swap_extent_after(ip, 0); trace_xfs_swap_extent_after(ip, 0);
trace_xfs_swap_extent_after(tip, 1); trace_xfs_swap_extent_after(tip, 1);
out_unlock_ilock:
xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_iunlock(tip, XFS_ILOCK_EXCL);
out_unlock: out_unlock:
xfs_iunlock(ip, lock_flags); filemap_invalidate_unlock_two(VFS_I(ip)->i_mapping,
xfs_iunlock(tip, lock_flags); VFS_I(tip)->i_mapping);
unlock_two_nondirectories(VFS_I(ip), VFS_I(tip)); unlock_two_nondirectories(VFS_I(ip), VFS_I(tip));
return error; return error;
out_trans_cancel: out_trans_cancel:
xfs_trans_cancel(tp); xfs_trans_cancel(tp);
goto out_unlock; goto out_unlock_ilock;
} }
...@@ -552,12 +552,10 @@ xfs_lock_inodes( ...@@ -552,12 +552,10 @@ xfs_lock_inodes(
} }
/* /*
* xfs_lock_two_inodes() can only be used to lock one type of lock at a time - * xfs_lock_two_inodes() can only be used to lock ilock. The iolock and
* the mmaplock or the ilock, but not more than one type at a time. If we lock * mmaplock must be double-locked separately since we use i_rwsem and
* more than one at a time, lockdep will report false positives saying we have * invalidate_lock for that. We now support taking one lock EXCL and the
* violated locking orders. The iolock must be double-locked separately since * other SHARED.
* we use i_rwsem for that. We now support taking one lock EXCL and the other
* SHARED.
*/ */
void void
xfs_lock_two_inodes( xfs_lock_two_inodes(
...@@ -575,15 +573,8 @@ xfs_lock_two_inodes( ...@@ -575,15 +573,8 @@ xfs_lock_two_inodes(
ASSERT(hweight32(ip1_mode) == 1); ASSERT(hweight32(ip1_mode) == 1);
ASSERT(!(ip0_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))); ASSERT(!(ip0_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)));
ASSERT(!(ip1_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))); ASSERT(!(ip1_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)));
ASSERT(!(ip0_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)) || ASSERT(!(ip0_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)));
!(ip0_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL))); ASSERT(!(ip1_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)));
ASSERT(!(ip1_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)) ||
!(ip1_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)));
ASSERT(!(ip1_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)) ||
!(ip0_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)));
ASSERT(!(ip0_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)) ||
!(ip1_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)));
ASSERT(ip0->i_ino != ip1->i_ino); ASSERT(ip0->i_ino != ip1->i_ino);
if (ip0->i_ino > ip1->i_ino) { if (ip0->i_ino > ip1->i_ino) {
...@@ -3748,11 +3739,8 @@ xfs_ilock2_io_mmap( ...@@ -3748,11 +3739,8 @@ xfs_ilock2_io_mmap(
ret = xfs_iolock_two_inodes_and_break_layout(VFS_I(ip1), VFS_I(ip2)); ret = xfs_iolock_two_inodes_and_break_layout(VFS_I(ip1), VFS_I(ip2));
if (ret) if (ret)
return ret; return ret;
if (ip1 == ip2) filemap_invalidate_lock_two(VFS_I(ip1)->i_mapping,
xfs_ilock(ip1, XFS_MMAPLOCK_EXCL); VFS_I(ip2)->i_mapping);
else
xfs_lock_two_inodes(ip1, XFS_MMAPLOCK_EXCL,
ip2, XFS_MMAPLOCK_EXCL);
return 0; return 0;
} }
...@@ -3762,12 +3750,9 @@ xfs_iunlock2_io_mmap( ...@@ -3762,12 +3750,9 @@ xfs_iunlock2_io_mmap(
struct xfs_inode *ip1, struct xfs_inode *ip1,
struct xfs_inode *ip2) struct xfs_inode *ip2)
{ {
bool same_inode = (ip1 == ip2); filemap_invalidate_unlock_two(VFS_I(ip1)->i_mapping,
VFS_I(ip2)->i_mapping);
xfs_iunlock(ip2, XFS_MMAPLOCK_EXCL);
if (!same_inode)
xfs_iunlock(ip1, XFS_MMAPLOCK_EXCL);
inode_unlock(VFS_I(ip2)); inode_unlock(VFS_I(ip2));
if (!same_inode) if (ip1 != ip2)
inode_unlock(VFS_I(ip1)); inode_unlock(VFS_I(ip1));
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment