diff options
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( | |||
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); |