diff options
Diffstat (limited to 'fs/xfs/xfs_bmap_util.c')
| -rw-r--r-- | fs/xfs/xfs_bmap_util.c | 40 | 
1 files changed, 37 insertions, 3 deletions
| diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index cd9a5400ba4f..6503cfa44262 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -84,6 +84,7 @@ xfs_zero_extent(  		GFP_NOFS, 0);  } +#ifdef CONFIG_XFS_RT  int  xfs_bmap_rtalloc(  	struct xfs_bmalloca	*ap)	/* bmap alloc argument struct */ @@ -190,6 +191,7 @@ xfs_bmap_rtalloc(  	}  	return 0;  } +#endif /* CONFIG_XFS_RT */  /*   * Check if the endoff is outside the last extent. If so the caller will grow @@ -1459,7 +1461,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 +2124,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); |