aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@sandeen.net>2015-07-28 21:53:31 -0400
committerDave Chinner <david@fromorbit.com>2015-07-28 21:53:31 -0400
commitce748eaa65f2e9392ba82726503c8d994ffd6393 (patch)
treeff3ec811268e84efbcebbf4b24ec23ff3438c1c7
parentbc0195aad0daa2ad5b0d76cce22b167bc3435590 (diff)
xfs: create new metadata UUID field and incompat flag
This adds a new superblock field, sb_meta_uuid. If set, along with a new incompat flag, the code will use that field on a V5 filesystem to compare to metadata UUIDs, which allows us to change the user- visible UUID at will. Userspace handles the setting and clearing of the incompat flag as appropriate, as the UUID gets changed; i.e. setting the user-visible UUID back to the original UUID (as stored in the new field) will remove the incompatible feature flag. If the incompat flag is not set, this copies the user-visible UUID into into the meta_uuid slot in memory when the superblock is read from disk; the meta_uuid field is not written back to disk in this case. The remainder of this patch simply switches verifiers, initializers, etc to use the new sb_meta_uuid field. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c4
-rw-r--r--fs/xfs/libxfs/xfs_alloc_btree.c4
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.c4
-rw-r--r--fs/xfs/libxfs/xfs_attr_remote.c4
-rw-r--r--fs/xfs/libxfs/xfs_bmap_btree.c5
-rw-r--r--fs/xfs/libxfs/xfs_btree.c10
-rw-r--r--fs/xfs/libxfs/xfs_da_btree.c4
-rw-r--r--fs/xfs/libxfs/xfs_dir2_block.c4
-rw-r--r--fs/xfs/libxfs/xfs_dir2_data.c4
-rw-r--r--fs/xfs/libxfs/xfs_dir2_leaf.c4
-rw-r--r--fs/xfs/libxfs/xfs_dir2_node.c4
-rw-r--r--fs/xfs/libxfs/xfs_dquot_buf.c4
-rw-r--r--fs/xfs/libxfs/xfs_format.h22
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.c5
-rw-r--r--fs/xfs/libxfs/xfs_ialloc_btree.c2
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.c4
-rw-r--r--fs/xfs/libxfs/xfs_sb.c10
-rw-r--r--fs/xfs/libxfs/xfs_symlink_remote.c4
18 files changed, 66 insertions, 36 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index f9e9ffe6fb46..b7fc17ce8233 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -464,7 +464,7 @@ xfs_agfl_verify(
464 struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp); 464 struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp);
465 int i; 465 int i;
466 466
467 if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) 467 if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))
468 return false; 468 return false;
469 if (be32_to_cpu(agfl->agfl_magicnum) != XFS_AGFL_MAGIC) 469 if (be32_to_cpu(agfl->agfl_magicnum) != XFS_AGFL_MAGIC)
470 return false; 470 return false;
@@ -2260,7 +2260,7 @@ xfs_agf_verify(
2260 struct xfs_agf *agf = XFS_BUF_TO_AGF(bp); 2260 struct xfs_agf *agf = XFS_BUF_TO_AGF(bp);
2261 2261
2262 if (xfs_sb_version_hascrc(&mp->m_sb) && 2262 if (xfs_sb_version_hascrc(&mp->m_sb) &&
2263 !uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_uuid)) 2263 !uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))
2264 return false; 2264 return false;
2265 2265
2266 if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) && 2266 if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c
index 59d521c09a17..90de071dd4c2 100644
--- a/fs/xfs/libxfs/xfs_alloc_btree.c
+++ b/fs/xfs/libxfs/xfs_alloc_btree.c
@@ -295,7 +295,7 @@ xfs_allocbt_verify(
295 case cpu_to_be32(XFS_ABTB_CRC_MAGIC): 295 case cpu_to_be32(XFS_ABTB_CRC_MAGIC):
296 if (!xfs_sb_version_hascrc(&mp->m_sb)) 296 if (!xfs_sb_version_hascrc(&mp->m_sb))
297 return false; 297 return false;
298 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) 298 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
299 return false; 299 return false;
300 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) 300 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))
301 return false; 301 return false;
@@ -313,7 +313,7 @@ xfs_allocbt_verify(
313 case cpu_to_be32(XFS_ABTC_CRC_MAGIC): 313 case cpu_to_be32(XFS_ABTC_CRC_MAGIC):
314 if (!xfs_sb_version_hascrc(&mp->m_sb)) 314 if (!xfs_sb_version_hascrc(&mp->m_sb))
315 return false; 315 return false;
316 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) 316 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
317 return false; 317 return false;
318 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) 318 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))
319 return false; 319 return false;
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index e9d401ce93bb..33df52d97ec7 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -262,7 +262,7 @@ xfs_attr3_leaf_verify(
262 if (ichdr.magic != XFS_ATTR3_LEAF_MAGIC) 262 if (ichdr.magic != XFS_ATTR3_LEAF_MAGIC)
263 return false; 263 return false;
264 264
265 if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_uuid)) 265 if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))
266 return false; 266 return false;
267 if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn) 267 if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)
268 return false; 268 return false;
@@ -1056,7 +1056,7 @@ xfs_attr3_leaf_create(
1056 1056
1057 hdr3->blkno = cpu_to_be64(bp->b_bn); 1057 hdr3->blkno = cpu_to_be64(bp->b_bn);
1058 hdr3->owner = cpu_to_be64(dp->i_ino); 1058 hdr3->owner = cpu_to_be64(dp->i_ino);
1059 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); 1059 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
1060 1060
1061 ichdr.freemap[0].base = sizeof(struct xfs_attr3_leaf_hdr); 1061 ichdr.freemap[0].base = sizeof(struct xfs_attr3_leaf_hdr);
1062 } else { 1062 } else {
diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
index 20de88d1bf86..eba0d1e91a93 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.c
+++ b/fs/xfs/libxfs/xfs_attr_remote.c
@@ -100,7 +100,7 @@ xfs_attr3_rmt_verify(
100 return false; 100 return false;
101 if (rmt->rm_magic != cpu_to_be32(XFS_ATTR3_RMT_MAGIC)) 101 if (rmt->rm_magic != cpu_to_be32(XFS_ATTR3_RMT_MAGIC))
102 return false; 102 return false;
103 if (!uuid_equal(&rmt->rm_uuid, &mp->m_sb.sb_uuid)) 103 if (!uuid_equal(&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))
104 return false; 104 return false;
105 if (be64_to_cpu(rmt->rm_blkno) != bno) 105 if (be64_to_cpu(rmt->rm_blkno) != bno)
106 return false; 106 return false;
@@ -217,7 +217,7 @@ xfs_attr3_rmt_hdr_set(
217 rmt->rm_magic = cpu_to_be32(XFS_ATTR3_RMT_MAGIC); 217 rmt->rm_magic = cpu_to_be32(XFS_ATTR3_RMT_MAGIC);
218 rmt->rm_offset = cpu_to_be32(offset); 218 rmt->rm_offset = cpu_to_be32(offset);
219 rmt->rm_bytes = cpu_to_be32(size); 219 rmt->rm_bytes = cpu_to_be32(size);
220 uuid_copy(&rmt->rm_uuid, &mp->m_sb.sb_uuid); 220 uuid_copy(&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid);
221 rmt->rm_owner = cpu_to_be64(ino); 221 rmt->rm_owner = cpu_to_be64(ino);
222 rmt->rm_blkno = cpu_to_be64(bno); 222 rmt->rm_blkno = cpu_to_be64(bno);
223 223
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
index 2c44c8e50782..6b0cf6546a82 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.c
+++ b/fs/xfs/libxfs/xfs_bmap_btree.c
@@ -349,7 +349,8 @@ xfs_bmbt_to_bmdr(
349 349
350 if (xfs_sb_version_hascrc(&mp->m_sb)) { 350 if (xfs_sb_version_hascrc(&mp->m_sb)) {
351 ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_CRC_MAGIC)); 351 ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_CRC_MAGIC));
352 ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); 352 ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid,
353 &mp->m_sb.sb_meta_uuid));
353 ASSERT(rblock->bb_u.l.bb_blkno == 354 ASSERT(rblock->bb_u.l.bb_blkno ==
354 cpu_to_be64(XFS_BUF_DADDR_NULL)); 355 cpu_to_be64(XFS_BUF_DADDR_NULL));
355 } else 356 } else
@@ -647,7 +648,7 @@ xfs_bmbt_verify(
647 case cpu_to_be32(XFS_BMAP_CRC_MAGIC): 648 case cpu_to_be32(XFS_BMAP_CRC_MAGIC):
648 if (!xfs_sb_version_hascrc(&mp->m_sb)) 649 if (!xfs_sb_version_hascrc(&mp->m_sb))
649 return false; 650 return false;
650 if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) 651 if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
651 return false; 652 return false;
652 if (be64_to_cpu(block->bb_u.l.bb_blkno) != bp->b_bn) 653 if (be64_to_cpu(block->bb_u.l.bb_blkno) != bp->b_bn)
653 return false; 654 return false;
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index c72283dd8d44..f7d7ee7a2607 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -65,7 +65,8 @@ xfs_btree_check_lblock(
65 65
66 if (xfs_sb_version_hascrc(&mp->m_sb)) { 66 if (xfs_sb_version_hascrc(&mp->m_sb)) {
67 lblock_ok = lblock_ok && 67 lblock_ok = lblock_ok &&
68 uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && 68 uuid_equal(&block->bb_u.l.bb_uuid,
69 &mp->m_sb.sb_meta_uuid) &&
69 block->bb_u.l.bb_blkno == cpu_to_be64( 70 block->bb_u.l.bb_blkno == cpu_to_be64(
70 bp ? bp->b_bn : XFS_BUF_DADDR_NULL); 71 bp ? bp->b_bn : XFS_BUF_DADDR_NULL);
71 } 72 }
@@ -115,7 +116,8 @@ xfs_btree_check_sblock(
115 116
116 if (xfs_sb_version_hascrc(&mp->m_sb)) { 117 if (xfs_sb_version_hascrc(&mp->m_sb)) {
117 sblock_ok = sblock_ok && 118 sblock_ok = sblock_ok &&
118 uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && 119 uuid_equal(&block->bb_u.s.bb_uuid,
120 &mp->m_sb.sb_meta_uuid) &&
119 block->bb_u.s.bb_blkno == cpu_to_be64( 121 block->bb_u.s.bb_blkno == cpu_to_be64(
120 bp ? bp->b_bn : XFS_BUF_DADDR_NULL); 122 bp ? bp->b_bn : XFS_BUF_DADDR_NULL);
121 } 123 }
@@ -1000,7 +1002,7 @@ xfs_btree_init_block_int(
1000 if (flags & XFS_BTREE_CRC_BLOCKS) { 1002 if (flags & XFS_BTREE_CRC_BLOCKS) {
1001 buf->bb_u.l.bb_blkno = cpu_to_be64(blkno); 1003 buf->bb_u.l.bb_blkno = cpu_to_be64(blkno);
1002 buf->bb_u.l.bb_owner = cpu_to_be64(owner); 1004 buf->bb_u.l.bb_owner = cpu_to_be64(owner);
1003 uuid_copy(&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); 1005 uuid_copy(&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid);
1004 buf->bb_u.l.bb_pad = 0; 1006 buf->bb_u.l.bb_pad = 0;
1005 buf->bb_u.l.bb_lsn = 0; 1007 buf->bb_u.l.bb_lsn = 0;
1006 } 1008 }
@@ -1013,7 +1015,7 @@ xfs_btree_init_block_int(
1013 if (flags & XFS_BTREE_CRC_BLOCKS) { 1015 if (flags & XFS_BTREE_CRC_BLOCKS) {
1014 buf->bb_u.s.bb_blkno = cpu_to_be64(blkno); 1016 buf->bb_u.s.bb_blkno = cpu_to_be64(blkno);
1015 buf->bb_u.s.bb_owner = cpu_to_be32(__owner); 1017 buf->bb_u.s.bb_owner = cpu_to_be32(__owner);
1016 uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); 1018 uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid);
1017 buf->bb_u.s.bb_lsn = 0; 1019 buf->bb_u.s.bb_lsn = 0;
1018 } 1020 }
1019 } 1021 }
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index 2385f8cd08ab..e9f6709a3846 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -146,7 +146,7 @@ xfs_da3_node_verify(
146 if (ichdr.magic != XFS_DA3_NODE_MAGIC) 146 if (ichdr.magic != XFS_DA3_NODE_MAGIC)
147 return false; 147 return false;
148 148
149 if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_uuid)) 149 if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))
150 return false; 150 return false;
151 if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn) 151 if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)
152 return false; 152 return false;
@@ -324,7 +324,7 @@ xfs_da3_node_create(
324 ichdr.magic = XFS_DA3_NODE_MAGIC; 324 ichdr.magic = XFS_DA3_NODE_MAGIC;
325 hdr3->info.blkno = cpu_to_be64(bp->b_bn); 325 hdr3->info.blkno = cpu_to_be64(bp->b_bn);
326 hdr3->info.owner = cpu_to_be64(args->dp->i_ino); 326 hdr3->info.owner = cpu_to_be64(args->dp->i_ino);
327 uuid_copy(&hdr3->info.uuid, &mp->m_sb.sb_uuid); 327 uuid_copy(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid);
328 } else { 328 } else {
329 ichdr.magic = XFS_DA_NODE_MAGIC; 329 ichdr.magic = XFS_DA_NODE_MAGIC;
330 } 330 }
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 9354e190b82e..4778d1dd511a 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -67,7 +67,7 @@ xfs_dir3_block_verify(
67 if (xfs_sb_version_hascrc(&mp->m_sb)) { 67 if (xfs_sb_version_hascrc(&mp->m_sb)) {
68 if (hdr3->magic != cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) 68 if (hdr3->magic != cpu_to_be32(XFS_DIR3_BLOCK_MAGIC))
69 return false; 69 return false;
70 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) 70 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
71 return false; 71 return false;
72 if (be64_to_cpu(hdr3->blkno) != bp->b_bn) 72 if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
73 return false; 73 return false;
@@ -157,7 +157,7 @@ xfs_dir3_block_init(
157 hdr3->magic = cpu_to_be32(XFS_DIR3_BLOCK_MAGIC); 157 hdr3->magic = cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);
158 hdr3->blkno = cpu_to_be64(bp->b_bn); 158 hdr3->blkno = cpu_to_be64(bp->b_bn);
159 hdr3->owner = cpu_to_be64(dp->i_ino); 159 hdr3->owner = cpu_to_be64(dp->i_ino);
160 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); 160 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
161 return; 161 return;
162 162
163 } 163 }
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index de1ea16f5748..6a57fdbc63ef 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -220,7 +220,7 @@ xfs_dir3_data_verify(
220 if (xfs_sb_version_hascrc(&mp->m_sb)) { 220 if (xfs_sb_version_hascrc(&mp->m_sb)) {
221 if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC)) 221 if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC))
222 return false; 222 return false;
223 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) 223 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
224 return false; 224 return false;
225 if (be64_to_cpu(hdr3->blkno) != bp->b_bn) 225 if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
226 return false; 226 return false;
@@ -604,7 +604,7 @@ xfs_dir3_data_init(
604 hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); 604 hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
605 hdr3->blkno = cpu_to_be64(bp->b_bn); 605 hdr3->blkno = cpu_to_be64(bp->b_bn);
606 hdr3->owner = cpu_to_be64(dp->i_ino); 606 hdr3->owner = cpu_to_be64(dp->i_ino);
607 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); 607 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
608 608
609 } else 609 } else
610 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 610 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 106119955400..f300240ebb8d 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -160,7 +160,7 @@ xfs_dir3_leaf_verify(
160 160
161 if (leaf3->info.hdr.magic != cpu_to_be16(magic3)) 161 if (leaf3->info.hdr.magic != cpu_to_be16(magic3))
162 return false; 162 return false;
163 if (!uuid_equal(&leaf3->info.uuid, &mp->m_sb.sb_uuid)) 163 if (!uuid_equal(&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))
164 return false; 164 return false;
165 if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn) 165 if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
166 return false; 166 return false;
@@ -310,7 +310,7 @@ xfs_dir3_leaf_init(
310 : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); 310 : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
311 leaf3->info.blkno = cpu_to_be64(bp->b_bn); 311 leaf3->info.blkno = cpu_to_be64(bp->b_bn);
312 leaf3->info.owner = cpu_to_be64(owner); 312 leaf3->info.owner = cpu_to_be64(owner);
313 uuid_copy(&leaf3->info.uuid, &mp->m_sb.sb_uuid); 313 uuid_copy(&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid);
314 } else { 314 } else {
315 memset(leaf, 0, sizeof(*leaf)); 315 memset(leaf, 0, sizeof(*leaf));
316 leaf->hdr.info.magic = cpu_to_be16(type); 316 leaf->hdr.info.magic = cpu_to_be16(type);
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 41b80d3d3877..527b7337a43b 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -93,7 +93,7 @@ xfs_dir3_free_verify(
93 93
94 if (hdr3->magic != cpu_to_be32(XFS_DIR3_FREE_MAGIC)) 94 if (hdr3->magic != cpu_to_be32(XFS_DIR3_FREE_MAGIC))
95 return false; 95 return false;
96 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) 96 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
97 return false; 97 return false;
98 if (be64_to_cpu(hdr3->blkno) != bp->b_bn) 98 if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
99 return false; 99 return false;
@@ -226,7 +226,7 @@ xfs_dir3_free_get_buf(
226 226
227 hdr3->hdr.blkno = cpu_to_be64(bp->b_bn); 227 hdr3->hdr.blkno = cpu_to_be64(bp->b_bn);
228 hdr3->hdr.owner = cpu_to_be64(dp->i_ino); 228 hdr3->hdr.owner = cpu_to_be64(dp->i_ino);
229 uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); 229 uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid);
230 } else 230 } else
231 hdr.magic = XFS_DIR2_FREE_MAGIC; 231 hdr.magic = XFS_DIR2_FREE_MAGIC;
232 dp->d_ops->free_hdr_to_disk(bp->b_addr, &hdr); 232 dp->d_ops->free_hdr_to_disk(bp->b_addr, &hdr);
diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c
index 6fbf2d853a54..5331b7f0460c 100644
--- a/fs/xfs/libxfs/xfs_dquot_buf.c
+++ b/fs/xfs/libxfs/xfs_dquot_buf.c
@@ -163,7 +163,7 @@ xfs_dqcheck(
163 d->dd_diskdq.d_id = cpu_to_be32(id); 163 d->dd_diskdq.d_id = cpu_to_be32(id);
164 164
165 if (xfs_sb_version_hascrc(&mp->m_sb)) { 165 if (xfs_sb_version_hascrc(&mp->m_sb)) {
166 uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid); 166 uuid_copy(&d->dd_uuid, &mp->m_sb.sb_meta_uuid);
167 xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk), 167 xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
168 XFS_DQUOT_CRC_OFF); 168 XFS_DQUOT_CRC_OFF);
169 } 169 }
@@ -198,7 +198,7 @@ xfs_dquot_buf_verify_crc(
198 if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk), 198 if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
199 XFS_DQUOT_CRC_OFF)) 199 XFS_DQUOT_CRC_OFF))
200 return false; 200 return false;
201 if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid)) 201 if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_meta_uuid))
202 return false; 202 return false;
203 } 203 }
204 return true; 204 return true;
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index a0ae572051de..9590a069e556 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -100,7 +100,7 @@ typedef struct xfs_sb {
100 xfs_rfsblock_t sb_dblocks; /* number of data blocks */ 100 xfs_rfsblock_t sb_dblocks; /* number of data blocks */
101 xfs_rfsblock_t sb_rblocks; /* number of realtime blocks */ 101 xfs_rfsblock_t sb_rblocks; /* number of realtime blocks */
102 xfs_rtblock_t sb_rextents; /* number of realtime extents */ 102 xfs_rtblock_t sb_rextents; /* number of realtime extents */
103 uuid_t sb_uuid; /* file system unique id */ 103 uuid_t sb_uuid; /* user-visible file system unique id */
104 xfs_fsblock_t sb_logstart; /* starting block of log if internal */ 104 xfs_fsblock_t sb_logstart; /* starting block of log if internal */
105 xfs_ino_t sb_rootino; /* root inode number */ 105 xfs_ino_t sb_rootino; /* root inode number */
106 xfs_ino_t sb_rbmino; /* bitmap inode for realtime extents */ 106 xfs_ino_t sb_rbmino; /* bitmap inode for realtime extents */
@@ -174,6 +174,7 @@ typedef struct xfs_sb {
174 174
175 xfs_ino_t sb_pquotino; /* project quota inode */ 175 xfs_ino_t sb_pquotino; /* project quota inode */
176 xfs_lsn_t sb_lsn; /* last write sequence */ 176 xfs_lsn_t sb_lsn; /* last write sequence */
177 uuid_t sb_meta_uuid; /* metadata file system unique id */
177 178
178 /* must be padded to 64 bit alignment */ 179 /* must be padded to 64 bit alignment */
179} xfs_sb_t; 180} xfs_sb_t;
@@ -190,7 +191,7 @@ typedef struct xfs_dsb {
190 __be64 sb_dblocks; /* number of data blocks */ 191 __be64 sb_dblocks; /* number of data blocks */
191 __be64 sb_rblocks; /* number of realtime blocks */ 192 __be64 sb_rblocks; /* number of realtime blocks */
192 __be64 sb_rextents; /* number of realtime extents */ 193 __be64 sb_rextents; /* number of realtime extents */
193 uuid_t sb_uuid; /* file system unique id */ 194 uuid_t sb_uuid; /* user-visible file system unique id */
194 __be64 sb_logstart; /* starting block of log if internal */ 195 __be64 sb_logstart; /* starting block of log if internal */
195 __be64 sb_rootino; /* root inode number */ 196 __be64 sb_rootino; /* root inode number */
196 __be64 sb_rbmino; /* bitmap inode for realtime extents */ 197 __be64 sb_rbmino; /* bitmap inode for realtime extents */
@@ -260,6 +261,7 @@ typedef struct xfs_dsb {
260 261
261 __be64 sb_pquotino; /* project quota inode */ 262 __be64 sb_pquotino; /* project quota inode */
262 __be64 sb_lsn; /* last write sequence */ 263 __be64 sb_lsn; /* last write sequence */
264 uuid_t sb_meta_uuid; /* metadata file system unique id */
263 265
264 /* must be padded to 64 bit alignment */ 266 /* must be padded to 64 bit alignment */
265} xfs_dsb_t; 267} xfs_dsb_t;
@@ -458,9 +460,11 @@ xfs_sb_has_ro_compat_feature(
458 460
459#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ 461#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
460#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ 462#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
463#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
461#define XFS_SB_FEAT_INCOMPAT_ALL \ 464#define XFS_SB_FEAT_INCOMPAT_ALL \
462 (XFS_SB_FEAT_INCOMPAT_FTYPE| \ 465 (XFS_SB_FEAT_INCOMPAT_FTYPE| \
463 XFS_SB_FEAT_INCOMPAT_SPINODES) 466 XFS_SB_FEAT_INCOMPAT_SPINODES| \
467 XFS_SB_FEAT_INCOMPAT_META_UUID)
464 468
465#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL 469#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
466static inline bool 470static inline bool
@@ -515,6 +519,18 @@ static inline bool xfs_sb_version_hassparseinodes(struct xfs_sb *sbp)
515} 519}
516 520
517/* 521/*
522 * XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID
523 * is stored separately from the user-visible UUID; this allows the
524 * user-visible UUID to be changed on V5 filesystems which have a
525 * filesystem UUID stamped into every piece of metadata.
526 */
527static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp)
528{
529 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
530 (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID);
531}
532
533/*
518 * end of superblock version macros 534 * end of superblock version macros
519 */ 535 */
520 536
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 66efc702452a..ce63e0431f3e 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -338,7 +338,8 @@ xfs_ialloc_inode_init(
338 if (version == 3) { 338 if (version == 3) {
339 free->di_ino = cpu_to_be64(ino); 339 free->di_ino = cpu_to_be64(ino);
340 ino++; 340 ino++;
341 uuid_copy(&free->di_uuid, &mp->m_sb.sb_uuid); 341 uuid_copy(&free->di_uuid,
342 &mp->m_sb.sb_meta_uuid);
342 xfs_dinode_calc_crc(mp, free); 343 xfs_dinode_calc_crc(mp, free);
343 } else if (tp) { 344 } else if (tp) {
344 /* just log the inode core */ 345 /* just log the inode core */
@@ -2500,7 +2501,7 @@ xfs_agi_verify(
2500 struct xfs_agi *agi = XFS_BUF_TO_AGI(bp); 2501 struct xfs_agi *agi = XFS_BUF_TO_AGI(bp);
2501 2502
2502 if (xfs_sb_version_hascrc(&mp->m_sb) && 2503 if (xfs_sb_version_hascrc(&mp->m_sb) &&
2503 !uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_uuid)) 2504 !uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))
2504 return false; 2505 return false;
2505 /* 2506 /*
2506 * Validate the magic number of the agi block. 2507 * Validate the magic number of the agi block.
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c
index 674ad8f760be..f39b285beb19 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.c
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.c
@@ -239,7 +239,7 @@ xfs_inobt_verify(
239 case cpu_to_be32(XFS_FIBT_CRC_MAGIC): 239 case cpu_to_be32(XFS_FIBT_CRC_MAGIC):
240 if (!xfs_sb_version_hascrc(&mp->m_sb)) 240 if (!xfs_sb_version_hascrc(&mp->m_sb))
241 return false; 241 return false;
242 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) 242 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
243 return false; 243 return false;
244 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) 244 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))
245 return false; 245 return false;
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 6526e7696184..268c00f4f83a 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -304,7 +304,7 @@ xfs_dinode_verify(
304 return false; 304 return false;
305 if (be64_to_cpu(dip->di_ino) != ip->i_ino) 305 if (be64_to_cpu(dip->di_ino) != ip->i_ino)
306 return false; 306 return false;
307 if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_uuid)) 307 if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_meta_uuid))
308 return false; 308 return false;
309 return true; 309 return true;
310} 310}
@@ -366,7 +366,7 @@ xfs_iread(
366 if (xfs_sb_version_hascrc(&mp->m_sb)) { 366 if (xfs_sb_version_hascrc(&mp->m_sb)) {
367 ip->i_d.di_version = 3; 367 ip->i_d.di_version = 3;
368 ip->i_d.di_ino = ip->i_ino; 368 ip->i_d.di_ino = ip->i_ino;
369 uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); 369 uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid);
370 } else 370 } else
371 ip->i_d.di_version = 2; 371 ip->i_d.di_version = 2;
372 return 0; 372 return 0;
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index df9851c46b5c..0f5e08fe64a2 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -398,6 +398,14 @@ __xfs_sb_from_disk(
398 to->sb_spino_align = be32_to_cpu(from->sb_spino_align); 398 to->sb_spino_align = be32_to_cpu(from->sb_spino_align);
399 to->sb_pquotino = be64_to_cpu(from->sb_pquotino); 399 to->sb_pquotino = be64_to_cpu(from->sb_pquotino);
400 to->sb_lsn = be64_to_cpu(from->sb_lsn); 400 to->sb_lsn = be64_to_cpu(from->sb_lsn);
401 /*
402 * sb_meta_uuid is only on disk if it differs from sb_uuid and the
403 * feature flag is set; if not set we keep it only in memory.
404 */
405 if (xfs_sb_version_hasmetauuid(to))
406 uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
407 else
408 uuid_copy(&to->sb_meta_uuid, &from->sb_uuid);
401 /* Convert on-disk flags to in-memory flags? */ 409 /* Convert on-disk flags to in-memory flags? */
402 if (convert_xquota) 410 if (convert_xquota)
403 xfs_sb_quota_from_disk(to); 411 xfs_sb_quota_from_disk(to);
@@ -539,6 +547,8 @@ xfs_sb_to_disk(
539 cpu_to_be32(from->sb_features_log_incompat); 547 cpu_to_be32(from->sb_features_log_incompat);
540 to->sb_spino_align = cpu_to_be32(from->sb_spino_align); 548 to->sb_spino_align = cpu_to_be32(from->sb_spino_align);
541 to->sb_lsn = cpu_to_be64(from->sb_lsn); 549 to->sb_lsn = cpu_to_be64(from->sb_lsn);
550 if (xfs_sb_version_hasmetauuid(from))
551 uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
542 } 552 }
543} 553}
544 554
diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c
index e7e26bd6468f..8f8af05b3f13 100644
--- a/fs/xfs/libxfs/xfs_symlink_remote.c
+++ b/fs/xfs/libxfs/xfs_symlink_remote.c
@@ -63,7 +63,7 @@ xfs_symlink_hdr_set(
63 dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC); 63 dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC);
64 dsl->sl_offset = cpu_to_be32(offset); 64 dsl->sl_offset = cpu_to_be32(offset);
65 dsl->sl_bytes = cpu_to_be32(size); 65 dsl->sl_bytes = cpu_to_be32(size);
66 uuid_copy(&dsl->sl_uuid, &mp->m_sb.sb_uuid); 66 uuid_copy(&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid);
67 dsl->sl_owner = cpu_to_be64(ino); 67 dsl->sl_owner = cpu_to_be64(ino);
68 dsl->sl_blkno = cpu_to_be64(bp->b_bn); 68 dsl->sl_blkno = cpu_to_be64(bp->b_bn);
69 bp->b_ops = &xfs_symlink_buf_ops; 69 bp->b_ops = &xfs_symlink_buf_ops;
@@ -107,7 +107,7 @@ xfs_symlink_verify(
107 return false; 107 return false;
108 if (dsl->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC)) 108 if (dsl->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC))
109 return false; 109 return false;
110 if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_uuid)) 110 if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))
111 return false; 111 return false;
112 if (bp->b_bn != be64_to_cpu(dsl->sl_blkno)) 112 if (bp->b_bn != be64_to_cpu(dsl->sl_blkno))
113 return false; 113 return false;