From: Darrick J. Wong Date: Mon, 29 Jun 2020 21:47:19 +0000 (-0700) Subject: xfs: reflink can skip remap existing mappings X-Git-Tag: v5.9-rc1~98^2~108 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=168eae803cede459d67ed0ab3ddb19539700a78a;p=thirdparty%2Fkernel%2Flinux.git xfs: reflink can skip remap existing mappings If the source and destination map are identical, we can skip the remap step to save some time. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 35a17ca5b5089..0a3681646fc96 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -1035,6 +1035,22 @@ xfs_reflink_remap_extent( trace_xfs_reflink_remap_extent_dest(ip, &smap); + /* + * Two extents mapped to the same physical block must not have + * different states; that's filesystem corruption. Move on to the next + * extent if they're both holes or both the same physical extent. + */ + if (dmap->br_startblock == smap.br_startblock) { + if (dmap->br_state != smap.br_state) + error = -EFSCORRUPTED; + goto out_cancel; + } + + /* If both extents are unwritten, leave them alone. */ + if (dmap->br_state == XFS_EXT_UNWRITTEN && + smap.br_state == XFS_EXT_UNWRITTEN) + goto out_cancel; + /* No reflinking if the AG of the dest mapping is low on space. */ if (dmap_written) { error = xfs_reflink_ag_has_free_space(mp,