Blame SOURCES/xfsprogs-4.8.0-xfs_copy-UUID.patch

59d3c6
commit cbca895541facb3a1a00fd0fe6614301a64c0e3a
59d3c6
Author: Eric Sandeen <sandeen@redhat.com>
59d3c6
Date:   Fri Sep 23 09:16:52 2016 +1000
59d3c6
59d3c6
    xfs_copy: Fix meta UUID handling on multiple copies
59d3c6
    
59d3c6
    Zorro reported that when making multiple copies of a V5
59d3c6
    filesystem with xfs_copy while generating new UUIDs, all
59d3c6
    but the first copy were corrupt.
59d3c6
    
59d3c6
    Upon inspection, the corruption was related to incorrect UUIDs;
59d3c6
    the original UUID, as stamped into every metadata structure,
59d3c6
    was not preserved in the sb_meta_uuid field of the superblock
59d3c6
    on any but the first copy.
59d3c6
    
59d3c6
    This happened because sb_update_uuid was using the UUID present in
59d3c6
    the ag_hdr structure as the unchanging meta-uuid which is to match
59d3c6
    existing structures, but it also /updates/ that UUID with the
59d3c6
    new identifying UUID present in tcarg.  So the newly-generated
59d3c6
    UUIDs moved transitively from tcarg->uuid to ag_hdr->xfs_sb->sb_uuid
59d3c6
    to ag_hdr->xfs_sb->sb_meta_uuid each time the function got called.
59d3c6
    
59d3c6
    Fix this by looking instead to the unchanging, original UUID
59d3c6
    present in the xfs_sb_t we are given, which reflects the original
59d3c6
    filesystem's metadata UUID, and copy /that/ UUID into each target
59d3c6
    filesystem's meta_uuid field.
59d3c6
    
59d3c6
    Most of this patch is changing comments and re-ordering tests
59d3c6
    to match; the functional change is to simply use the *sb rather
59d3c6
    than the *ag_hdr to identify the proper metadata UUID.
59d3c6
    
59d3c6
    Reported-and-tested-by: Zorro Lang <zlang@redhat.com>
59d3c6
    Signed-off-by: Eric Sandeen <sandeen@redhat.com>
59d3c6
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
59d3c6
    Signed-off-by: Dave Chinner <david@fromorbit.com>
59d3c6
59d3c6
diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c
59d3c6
index 3c8998c..22ded6b 100644
59d3c6
--- a/copy/xfs_copy.c
59d3c6
+++ b/copy/xfs_copy.c
59d3c6
@@ -494,27 +494,29 @@ write_wbuf(void)
59d3c6
 
59d3c6
 void
59d3c6
 sb_update_uuid(
59d3c6
-	xfs_sb_t	*sb,
59d3c6
-	ag_header_t	*ag_hdr,
59d3c6
-	thread_args	*tcarg)
59d3c6
+	xfs_sb_t	*sb,		/* Original fs superblock */
59d3c6
+	ag_header_t	*ag_hdr,	/* AG hdr to update for this copy */
59d3c6
+	thread_args	*tcarg)		/* Args for this thread, with UUID */
59d3c6
 {
59d3c6
 	/*
59d3c6
 	 * If this filesystem has CRCs, the original UUID is stamped into
59d3c6
-	 * all metadata.  If we are changing the UUID in the copy, we need
59d3c6
-	 * to copy the original UUID into the meta_uuid slot and set the
59d3c6
-	 * set the incompat flag if that hasn't already been done.
59d3c6
+	 * all metadata.  If we don't have an existing meta_uuid field in the
59d3c6
+	 * the original filesystem and we are changing the UUID in this copy,
59d3c6
+	 * we must copy the original sb_uuid to the sb_meta_uuid slot and set
59d3c6
+	 * the incompat flag for the feature on this copy.
59d3c6
 	 */
59d3c6
-	if (!uuid_equal(&tcarg->uuid, &ag_hdr->xfs_sb->sb_uuid) &&
59d3c6
-	    xfs_sb_version_hascrc(sb) && !xfs_sb_version_hasmetauuid(sb)) {
59d3c6
+	if (xfs_sb_version_hascrc(sb) && !xfs_sb_version_hasmetauuid(sb) &&
59d3c6
+	    !uuid_equal(&tcarg->uuid, &sb->sb_uuid)) {
59d3c6
 		__be32 feat;
59d3c6
 
59d3c6
 		feat = be32_to_cpu(ag_hdr->xfs_sb->sb_features_incompat);
59d3c6
 		feat |= XFS_SB_FEAT_INCOMPAT_META_UUID;
59d3c6
 		ag_hdr->xfs_sb->sb_features_incompat = cpu_to_be32(feat);
59d3c6
 		platform_uuid_copy(&ag_hdr->xfs_sb->sb_meta_uuid,
59d3c6
-				   &ag_hdr->xfs_sb->sb_uuid);
59d3c6
+				   &sb->sb_uuid);
59d3c6
 	}
59d3c6
 
59d3c6
+	/* Copy the (possibly new) fs-identifier UUID into sb_uuid */
59d3c6
 	platform_uuid_copy(&ag_hdr->xfs_sb->sb_uuid, &tcarg->uuid);
59d3c6
 
59d3c6
 	/* We may have changed the UUID, so update the superblock CRC */