|
 |
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 */
|