summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-04-02 12:11:01 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2020-06-01 21:16:49 -0700
commit0d456752a3e273b755bd993537b2e6246bdb88a5 (patch)
tree1857b0b41c024fba9813d901752b9c85e0052545 /fs
parent2464e7898125145633deae435e6e73556ba487cb (diff)
xfs: refactor reflink flag handling in xfs_swap_extent_forks
Refactor the old data fork swap function to use the new reflink flag helpers to propagate reflink flags between the two files. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_bmap_util.c57
1 files changed, 16 insertions, 41 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index b6825cb3148b..71165ae1aa7c 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1396,18 +1396,22 @@ xfs_swap_change_owner(
STATIC int
xfs_swap_extent_forks(
struct xfs_trans **tpp,
- struct xfs_inode *ip,
- struct xfs_inode *tip)
+ struct xfs_swapext_req *req)
{
+ struct xfs_inode *ip = req->ip1;
+ struct xfs_inode *tip = req->ip2;
xfs_filblks_t aforkblks = 0;
xfs_filblks_t taforkblks = 0;
int64_t temp_blks;
xfs_extnum_t junk;
uint64_t tmp;
+ unsigned int reflink_state;
int src_log_flags = XFS_ILOG_CORE;
int target_log_flags = XFS_ILOG_CORE;
int error;
+ reflink_state = xfs_swapext_reflink_prep(req);
+
/*
* Count the number of extended attribute blocks
*/
@@ -1499,35 +1503,7 @@ xfs_swap_extent_forks(
break;
}
- /* Do we have to swap reflink flags? */
- if ((ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK) ^
- (tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK)) {
- uint64_t f;
-
- f = ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK;
- ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
- ip->i_d.di_flags2 |= tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK;
- tip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
- tip->i_d.di_flags2 |= f & XFS_DIFLAG2_REFLINK;
- }
-
- /* Swap the cow forks. */
- if (xfs_sb_version_hasreflink(&ip->i_mount->m_sb)) {
- ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS);
- ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS);
-
- swap(ip->i_cnextents, tip->i_cnextents);
- swap(ip->i_cowfp, tip->i_cowfp);
-
- if (ip->i_cowfp && ip->i_cowfp->if_bytes)
- xfs_inode_set_cowblocks_tag(ip);
- else
- xfs_inode_clear_cowblocks_tag(ip);
- if (tip->i_cowfp && tip->i_cowfp->if_bytes)
- xfs_inode_set_cowblocks_tag(tip);
- else
- xfs_inode_clear_cowblocks_tag(tip);
- }
+ xfs_swapext_reflink_finish(*tpp, req, reflink_state);
xfs_trans_log_inode(*tpp, ip, src_log_flags);
xfs_trans_log_inode(*tpp, tip, target_log_flags);
@@ -1645,6 +1621,11 @@ xfs_swap_extents(
struct xfs_inode *tip, /* tmp inode */
struct xfs_swapext *sxp)
{
+ struct xfs_swapext_req req = {
+ .ip1 = ip,
+ .ip2 = tip,
+ .whichfork = XFS_DATA_FORK,
+ };
struct xfs_mount *mp = ip->i_mount;
struct xfs_trans *tp;
struct xfs_bstat *sbp = &sxp->sx_stat;
@@ -1789,17 +1770,11 @@ xfs_swap_extents(
* recovery is going to see the fork as owned by the swapped inode,
* not the pre-swapped inodes.
*/
- if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
- struct xfs_swapext_req req = {
- .ip1 = ip,
- .ip2 = tip,
- .whichfork = XFS_DATA_FORK,
- .blockcount = XFS_B_TO_FSB(ip->i_mount,
- i_size_read(VFS_I(ip))),
- };
+ req.blockcount = XFS_B_TO_FSB(ip->i_mount, i_size_read(VFS_I(ip)));
+ if (xfs_sb_version_hasrmapbt(&mp->m_sb))
error = xfs_swapext_deferred_bmap(&tp, &req);
- } else
- error = xfs_swap_extent_forks(&tp, ip, tip);
+ else
+ error = xfs_swap_extent_forks(&tp, &req);
if (error) {
trace_xfs_swap_extent_error(ip, error, _THIS_IP_);
goto out_trans_cancel;