aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap_util.c')
-rw-r--r--fs/xfs/xfs_bmap_util.c38
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(
1459 return error; 1459 return error;
1460 1460
1461 /* 1461 /*
1462 * The extent shiting code works on extent granularity. So, if 1462 * Clean out anything hanging around in the cow fork now that
1463 * we've flushed all the dirty data out to disk to avoid having
1464 * CoW extents at the wrong offsets.
1465 */
1466 if (xfs_is_reflink_inode(ip)) {
1467 error = xfs_reflink_cancel_cow_range(ip, offset, NULLFILEOFF,
1468 true);
1469 if (error)
1470 return error;
1471 }
1472
1473 /*
1474 * The extent shifting code works on extent granularity. So, if
1463 * stop_fsb is not the starting block of extent, we need to split 1475 * stop_fsb is not the starting block of extent, we need to split
1464 * the extent at stop_fsb. 1476 * the extent at stop_fsb.
1465 */ 1477 */
@@ -2110,11 +2122,31 @@ xfs_swap_extents(
2110 ip->i_d.di_flags2 |= tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK; 2122 ip->i_d.di_flags2 |= tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK;
2111 tip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; 2123 tip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
2112 tip->i_d.di_flags2 |= f & XFS_DIFLAG2_REFLINK; 2124 tip->i_d.di_flags2 |= f & XFS_DIFLAG2_REFLINK;
2125 }
2126
2127 /* Swap the cow forks. */
2128 if (xfs_sb_version_hasreflink(&mp->m_sb)) {
2129 xfs_extnum_t extnum;
2130
2131 ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS);
2132 ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS);
2133
2134 extnum = ip->i_cnextents;
2135 ip->i_cnextents = tip->i_cnextents;
2136 tip->i_cnextents = extnum;
2137
2113 cowfp = ip->i_cowfp; 2138 cowfp = ip->i_cowfp;
2114 ip->i_cowfp = tip->i_cowfp; 2139 ip->i_cowfp = tip->i_cowfp;
2115 tip->i_cowfp = cowfp; 2140 tip->i_cowfp = cowfp;
2116 xfs_inode_set_cowblocks_tag(ip); 2141
2117 xfs_inode_set_cowblocks_tag(tip); 2142 if (ip->i_cowfp && ip->i_cnextents)
2143 xfs_inode_set_cowblocks_tag(ip);
2144 else
2145 xfs_inode_clear_cowblocks_tag(ip);
2146 if (tip->i_cowfp && tip->i_cnextents)
2147 xfs_inode_set_cowblocks_tag(tip);
2148 else
2149 xfs_inode_clear_cowblocks_tag(tip);
2118 } 2150 }
2119 2151
2120 xfs_trans_log_inode(tp, ip, src_log_flags); 2152 xfs_trans_log_inode(tp, ip, src_log_flags);