From 168eae803cede459d67ed0ab3ddb19539700a78a Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 29 Jun 2020 14:47:19 -0700 Subject: 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 --- fs/xfs/xfs_reflink.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'fs') diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 35a17ca5b508..0a3681646fc9 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, -- cgit v1.2.3