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: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
2433480a7e
commit
d2c292d84c
|
@ -1626,7 +1626,6 @@ xfs_swap_extents(
|
|||
struct xfs_bstat *sbp = &sxp->sx_stat;
|
||||
int src_log_flags, target_log_flags;
|
||||
int error = 0;
|
||||
int lock_flags;
|
||||
uint64_t f;
|
||||
int resblks = 0;
|
||||
unsigned int flags = 0;
|
||||
|
@ -1638,8 +1637,8 @@ xfs_swap_extents(
|
|||
* do the rest of the checks.
|
||||
*/
|
||||
lock_two_nondirectories(VFS_I(ip), VFS_I(tip));
|
||||
lock_flags = XFS_MMAPLOCK_EXCL;
|
||||
xfs_lock_two_inodes(ip, XFS_MMAPLOCK_EXCL, tip, XFS_MMAPLOCK_EXCL);
|
||||
filemap_invalidate_lock_two(VFS_I(ip)->i_mapping,
|
||||
VFS_I(tip)->i_mapping);
|
||||
|
||||
/* Verify that both files have the same format */
|
||||
if ((VFS_I(ip)->i_mode & S_IFMT) != (VFS_I(tip)->i_mode & S_IFMT)) {
|
||||
|
@ -1711,7 +1710,6 @@ xfs_swap_extents(
|
|||
* or cancel will unlock the inodes from this point onwards.
|
||||
*/
|
||||
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, tip, 0);
|
||||
|
||||
|
@ -1830,13 +1828,16 @@ xfs_swap_extents(
|
|||
trace_xfs_swap_extent_after(ip, 0);
|
||||
trace_xfs_swap_extent_after(tip, 1);
|
||||
|
||||
out_unlock_ilock:
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
xfs_iunlock(tip, XFS_ILOCK_EXCL);
|
||||
out_unlock:
|
||||
xfs_iunlock(ip, lock_flags);
|
||||
xfs_iunlock(tip, lock_flags);
|
||||
filemap_invalidate_unlock_two(VFS_I(ip)->i_mapping,
|
||||
VFS_I(tip)->i_mapping);
|
||||
unlock_two_nondirectories(VFS_I(ip), VFS_I(tip));
|
||||
return error;
|
||||
|
||||
out_trans_cancel:
|
||||
xfs_trans_cancel(tp);
|
||||
goto out_unlock;
|
||||
goto out_unlock_ilock;
|
||||
}
|
||||
|
|
|
@ -552,12 +552,10 @@ again:
|
|||
}
|
||||
|
||||
/*
|
||||
* xfs_lock_two_inodes() can only be used to lock one type of lock at a time -
|
||||
* the mmaplock or the ilock, but not more than one type at a time. If we lock
|
||||
* more than one at a time, lockdep will report false positives saying we have
|
||||
* violated locking orders. The iolock must be double-locked separately since
|
||||
* we use i_rwsem for that. We now support taking one lock EXCL and the other
|
||||
* SHARED.
|
||||
* xfs_lock_two_inodes() can only be used to lock ilock. The iolock and
|
||||
* mmaplock must be double-locked separately since we use i_rwsem and
|
||||
* invalidate_lock for that. We now support taking one lock EXCL and the
|
||||
* other SHARED.
|
||||
*/
|
||||
void
|
||||
xfs_lock_two_inodes(
|
||||
|
@ -575,15 +573,8 @@ xfs_lock_two_inodes(
|
|||
ASSERT(hweight32(ip1_mode) == 1);
|
||||
ASSERT(!(ip0_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)) ||
|
||||
!(ip0_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_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_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)));
|
||||
ASSERT(!(ip1_mode & (XFS_MMAPLOCK_SHARED|XFS_MMAPLOCK_EXCL)));
|
||||
ASSERT(ip0->i_ino != ip1->i_ino);
|
||||
|
||||
if (ip0->i_ino > ip1->i_ino) {
|
||||
|
@ -3748,11 +3739,8 @@ xfs_ilock2_io_mmap(
|
|||
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);
|
||||
filemap_invalidate_lock_two(VFS_I(ip1)->i_mapping,
|
||||
VFS_I(ip2)->i_mapping);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3762,12 +3750,9 @@ xfs_iunlock2_io_mmap(
|
|||
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);
|
||||
filemap_invalidate_unlock_two(VFS_I(ip1)->i_mapping,
|
||||
VFS_I(ip2)->i_mapping);
|
||||
inode_unlock(VFS_I(ip2));
|
||||
if (!same_inode)
|
||||
if (ip1 != ip2)
|
||||
inode_unlock(VFS_I(ip1));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue