xfs: swap inode reflink flags when swapping inode extents
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 3 Oct 2016 16:11:42 +0000 (09:11 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 5 Oct 2016 23:26:26 +0000 (16:26 -0700)
When we're swapping the extents of two inodes, be sure to swap the
reflink inode flag too.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/xfs_bmap_util.c

index f7b3f02ff6501a342df28d1aed80a461eff7ef63..e2f46e645612d8d3a1d2e132b98d89b24d15ad6b 100644 (file)
@@ -1660,6 +1660,8 @@ xfs_swap_extents(
        int             taforkblks = 0;
        __uint64_t      tmp;
        int             lock_flags;
+       struct xfs_ifork        *cowfp;
+       __uint64_t      f;
 
        /* XXX: we can't do this with rmap, will fix later */
        if (xfs_sb_version_hasrmapbt(&mp->m_sb))
@@ -1873,6 +1875,19 @@ xfs_swap_extents(
                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)) {
+               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;
+               cowfp = ip->i_cowfp;
+               ip->i_cowfp = tip->i_cowfp;
+               tip->i_cowfp = cowfp;
+       }
+
        xfs_trans_log_inode(tp, ip,  src_log_flags);
        xfs_trans_log_inode(tp, tip, target_log_flags);