diff options
author | Dan Williams <dan.j.williams@intel.com> | 2017-11-15 16:56:11 -0800 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2017-11-15 16:56:11 -0800 |
commit | 4247f24c23589bcc3bc3490515ef8c9497e9ae55 (patch) | |
tree | 89726a0e171c443a3e8def2992b56dbd8a21df21 /fs/xfs/xfs_bmap_util.c | |
parent | 79ab67ede21f536851a99ea68ee6fc1f5435e055 (diff) | |
parent | 9f586fff6574f6ecbf323f92d44ffaf0d96225fe (diff) | |
download | kernel_replicant_linux-4247f24c23589bcc3bc3490515ef8c9497e9ae55.tar.gz kernel_replicant_linux-4247f24c23589bcc3bc3490515ef8c9497e9ae55.tar.bz2 kernel_replicant_linux-4247f24c23589bcc3bc3490515ef8c9497e9ae55.zip |
Merge branch 'for-4.15/dax' into libnvdimm-for-next
Diffstat (limited to 'fs/xfs/xfs_bmap_util.c')
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index cd9a5400ba4f..e9db7fc95b70 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1459,7 +1459,19 @@ xfs_shift_file_space( return error; /* - * The extent shiting code works on extent granularity. So, if + * Clean out anything hanging around in the cow fork now that + * we've flushed all the dirty data out to disk to avoid having + * CoW extents at the wrong offsets. + */ + if (xfs_is_reflink_inode(ip)) { + error = xfs_reflink_cancel_cow_range(ip, offset, NULLFILEOFF, + true); + if (error) + return error; + } + + /* + * The extent shifting code works on extent granularity. So, if * stop_fsb is not the starting block of extent, we need to split * the extent at stop_fsb. */ @@ -2110,11 +2122,31 @@ xfs_swap_extents( 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(&mp->m_sb)) { + xfs_extnum_t extnum; + + ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); + ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); + + extnum = ip->i_cnextents; + ip->i_cnextents = tip->i_cnextents; + tip->i_cnextents = extnum; + cowfp = ip->i_cowfp; ip->i_cowfp = tip->i_cowfp; tip->i_cowfp = cowfp; - xfs_inode_set_cowblocks_tag(ip); - xfs_inode_set_cowblocks_tag(tip); + + if (ip->i_cowfp && ip->i_cnextents) + xfs_inode_set_cowblocks_tag(ip); + else + xfs_inode_clear_cowblocks_tag(ip); + if (tip->i_cowfp && tip->i_cnextents) + xfs_inode_set_cowblocks_tag(tip); + else + xfs_inode_clear_cowblocks_tag(tip); } xfs_trans_log_inode(tp, ip, src_log_flags); |