mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 03:50:53 +07:00
xfs: refactor locking and unlocking two inodes against userspace IO
Refactor the two functions that we use to lock and unlock two inodes to block userspace from initiating IO against a file, whether via system calls or mmap activity. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
This commit is contained in:
parent
451d34ee07
commit
10b4bd6c9c
@ -1065,7 +1065,7 @@ xfs_file_remap_range(
|
||||
if (mp->m_flags & XFS_MOUNT_WSYNC)
|
||||
xfs_log_force_inode(dest);
|
||||
out_unlock:
|
||||
xfs_reflink_remap_unlock(file_in, file_out);
|
||||
xfs_reflink_remap_unlock(src, dest);
|
||||
if (ret)
|
||||
trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_);
|
||||
return remapped > 0 ? remapped : ret;
|
||||
|
@ -1284,24 +1284,42 @@ xfs_iolock_two_inodes_and_break_layout(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unlock both inodes after they've been prepped for a range clone. */
|
||||
/*
|
||||
* 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 file *file_in,
|
||||
struct file *file_out)
|
||||
struct xfs_inode *ip1,
|
||||
struct xfs_inode *ip2)
|
||||
{
|
||||
struct inode *inode_in = file_inode(file_in);
|
||||
struct xfs_inode *src = XFS_I(inode_in);
|
||||
struct inode *inode_out = file_inode(file_out);
|
||||
struct xfs_inode *dest = XFS_I(inode_out);
|
||||
bool same_inode = (inode_in == inode_out);
|
||||
bool same_inode = (ip1 == ip2);
|
||||
|
||||
xfs_iunlock(dest, XFS_MMAPLOCK_EXCL);
|
||||
xfs_iunlock(ip2, XFS_MMAPLOCK_EXCL);
|
||||
if (!same_inode)
|
||||
xfs_iunlock(src, XFS_MMAPLOCK_EXCL);
|
||||
inode_unlock(inode_out);
|
||||
xfs_iunlock(ip1, XFS_MMAPLOCK_EXCL);
|
||||
inode_unlock(VFS_I(ip2));
|
||||
if (!same_inode)
|
||||
inode_unlock(inode_in);
|
||||
inode_unlock(VFS_I(ip1));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1366,18 +1384,12 @@ xfs_reflink_remap_prep(
|
||||
struct xfs_inode *src = XFS_I(inode_in);
|
||||
struct inode *inode_out = file_inode(file_out);
|
||||
struct xfs_inode *dest = XFS_I(inode_out);
|
||||
bool same_inode = (inode_in == inode_out);
|
||||
int ret;
|
||||
|
||||
/* Lock both files against IO */
|
||||
ret = xfs_iolock_two_inodes_and_break_layout(inode_in, inode_out);
|
||||
ret = xfs_reflink_remap_lock(src, dest);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (same_inode)
|
||||
xfs_ilock(src, XFS_MMAPLOCK_EXCL);
|
||||
else
|
||||
xfs_lock_two_inodes(src, XFS_MMAPLOCK_EXCL, dest,
|
||||
XFS_MMAPLOCK_EXCL);
|
||||
|
||||
/* Check file eligibility and prepare for block sharing. */
|
||||
ret = -EINVAL;
|
||||
@ -1428,7 +1440,7 @@ xfs_reflink_remap_prep(
|
||||
|
||||
return 0;
|
||||
out_unlock:
|
||||
xfs_reflink_remap_unlock(file_in, file_out);
|
||||
xfs_reflink_remap_unlock(src, dest);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,6 @@ extern int xfs_reflink_remap_blocks(struct xfs_inode *src, loff_t pos_in,
|
||||
loff_t *remapped);
|
||||
extern int xfs_reflink_update_dest(struct xfs_inode *dest, xfs_off_t newlen,
|
||||
xfs_extlen_t cowextsize, unsigned int remap_flags);
|
||||
extern void xfs_reflink_remap_unlock(struct file *file_in,
|
||||
struct file *file_out);
|
||||
extern void xfs_reflink_remap_unlock(struct xfs_inode *ip1, struct xfs_inode *ip2);
|
||||
|
||||
#endif /* __XFS_REFLINK_H */
|
||||
|
Loading…
Reference in New Issue
Block a user