allow UUID changes on V5/CRC filesystems
v3 cover allow UUID changes on V5/CRC filesystems
Final version? This has been through some degree of testing, by changing the UUID after a CRC mkfs, and re-setting it in between two xfs_repair runs before and after each test in the testsuite.
I still probably owe some xfstests testcases.
This is rebased onto the new xfsprogs libxfs rebase, and I removed the noise if a user asks to "restore" the UUID on a filesystem which doesn't need it - it just does nothing, and succeeds silently.
Thanks,
-Eric
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v3 1/2 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.
---
fs/xfs/libxfs/xfs_alloc.c +2 -2
@@ -450,7 +450,7 @@ xfs_agfl_verify(struct xfs_agfl *agfl =XFS_BUF_TO_AGFL (bp);int i; -if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be32_to_cpu (agfl->agfl_magicnum) !=XFS_AGFL_MAGIC )return false;
@@ -2203,7 +2203,7 @@ xfs_agf_verify(struct xfs_agf *agf =XFS_BUF_TO_AGF (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))return false; if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
fs/xfs/libxfs/xfs_alloc_btree.c +2 -2
@@ -295,7 +295,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTB_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
@@ -313,7 +313,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTC_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
fs/xfs/libxfs/xfs_attr_leaf.c +2 -2
@@ -262,7 +262,7 @@ xfs_attr3_leaf_verify(if (ichdr.magic !=XFS_ATTR3_LEAF_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -1056,7 +1056,7 @@ xfs_attr3_leaf_create( hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); ichdr.freemap[0 ].base =sizeof (struct xfs_attr3_leaf_hdr ); }else {
fs/xfs/libxfs/xfs_attr_remote.c +2 -2
@@ -100,7 +100,7 @@ xfs_attr3_rmt_verify(return false;if (rmt->rm_magic !=cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ))return false; -if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (rmt->rm_blkno) != bno)return false;
@@ -217,7 +217,7 @@ xfs_attr3_rmt_hdr_set( rmt->rm_magic =cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ); rmt->rm_offset =cpu_to_be32 (offset); rmt->rm_bytes =cpu_to_be32 (size); -uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid); rmt->rm_owner =cpu_to_be64 (ino); rmt->rm_blkno =cpu_to_be64 (bno);
fs/xfs/libxfs/xfs_bmap_btree.c +3 -2
@@ -349,7 +349,8 @@ xfs_bmbt_to_bmdr(if (xfs_sb_version_hascrc (&mp->m_sb)) {ASSERT (rblock->bb_magic ==cpu_to_be32 (XFS_BMAP_CRC_MAGIC )); -ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid));ASSERT (rblock->bb_u.l.bb_blkno ==cpu_to_be64 (XFS_BUF_DADDR_NULL )); }else
@@ -647,7 +648,7 @@ xfs_bmbt_verify(case cpu_to_be32 (XFS_BMAP_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (block->bb_u.l.bb_blkno) != bp->b_bn)return false;
fs/xfs/libxfs/xfs_btree.c +6 -4
@@ -65,7 +65,8 @@ xfs_btree_check_lblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { lblock_ok = lblock_ok && -uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.l.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -115,7 +116,8 @@ xfs_btree_check_sblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { sblock_ok = sblock_ok && -uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.s.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.s.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -1000,7 +1002,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.l.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.l.bb_owner =cpu_to_be64 (owner); -uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.l.bb_pad =0 ; buf->bb_u.l.bb_lsn =0 ; }
@@ -1013,7 +1015,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.s.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.s.bb_owner =cpu_to_be32 (__owner); -uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.s.bb_lsn =0 ; } }
fs/xfs/libxfs/xfs_da_btree.c +2 -2
@@ -146,7 +146,7 @@ xfs_da3_node_verify(if (ichdr.magic !=XFS_DA3_NODE_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -324,7 +324,7 @@ xfs_da3_node_create( ichdr.magic =XFS_DA3_NODE_MAGIC ; hdr3->info.blkno =cpu_to_be64 (bp->b_bn); hdr3->info.owner =cpu_to_be64 (args->dp->i_ino); -uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid); }else { ichdr.magic =XFS_DA_NODE_MAGIC ; }
fs/xfs/libxfs/xfs_dir2_block.c +2 -2
@@ -67,7 +67,7 @@ xfs_dir3_block_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -157,7 +157,7 @@ xfs_dir3_block_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid);return ; }
fs/xfs/libxfs/xfs_dir2_data.c +2 -2
@@ -220,7 +220,7 @@ xfs_dir3_data_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_DATA_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -604,7 +604,7 @@ xfs_dir3_data_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_DATA_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); }else hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );
fs/xfs/libxfs/xfs_dir2_leaf.c +2 -2
@@ -160,7 +160,7 @@ xfs_dir3_leaf_verify(if (leaf3->info.hdr.magic !=cpu_to_be16 (magic3))return false; -if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (leaf3->info.blkno) != bp->b_bn)return false;
@@ -310,7 +310,7 @@ xfs_dir3_leaf_init( : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); leaf3->info.blkno =cpu_to_be64 (bp->b_bn); leaf3->info.owner =cpu_to_be64 (owner); -uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid); }else {memset (leaf,0 ,sizeof (*leaf)); leaf->hdr.info.magic =cpu_to_be16 (type);
fs/xfs/libxfs/xfs_dir2_node.c +2 -2
@@ -93,7 +93,7 @@ xfs_dir3_free_verify(if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_FREE_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -226,7 +226,7 @@ xfs_dir3_free_get_buf( hdr3->hdr.blkno =cpu_to_be64 (bp->b_bn); hdr3->hdr.owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); }else hdr.magic =XFS_DIR2_FREE_MAGIC ; dp->d_ops->free_hdr_to_disk (bp->b_addr, &hdr);
fs/xfs/libxfs/xfs_dquot_buf.c +2 -2
@@ -163,7 +163,7 @@ xfs_dqcheck( d->dd_diskdq.d_id =cpu_to_be32 (id);if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }
@@ -198,7 +198,7 @@ xfs_dquot_buf_verify_crc(if (!xfs_verify_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ))return false; -if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_meta_uuid))return false; }return true;
fs/xfs/libxfs/xfs_format.h +19 -3
@@ -100,7 +100,7 @@ typedef struct xfs_sb {xfs_rfsblock_t sb_dblocks;/* number of data blocks */ xfs_rfsblock_t sb_rblocks;/* number of realtime blocks */ xfs_rtblock_t sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ xfs_fsblock_t sb_logstart;/* starting block of log if internal */ xfs_ino_t sb_rootino;/* root inode number */ xfs_ino_t sb_rbmino;/* bitmap inode for realtime extents */
@@ -174,6 +174,7 @@ typedef struct xfs_sb {xfs_ino_t sb_pquotino;/* project quota inode */ xfs_lsn_t sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_sb_t;
@@ -190,7 +191,7 @@ typedef struct xfs_dsb {__be64 sb_dblocks;/* number of data blocks */ __be64 sb_rblocks;/* number of realtime blocks */ __be64 sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ __be64 sb_logstart;/* starting block of log if internal */ __be64 sb_rootino;/* root inode number */ __be64 sb_rbmino;/* bitmap inode for realtime extents */
@@ -260,6 +261,7 @@ typedef struct xfs_dsb {__be64 sb_pquotino;/* project quota inode */ __be64 sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_dsb_t;
@@ -457,8 +459,10 @@ xfs_sb_has_ro_compat_feature( }#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0)/* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 1)/* metadata UUID */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_META_UUID)#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool
@@ -507,6 +511,18 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) }/* +* XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID +* is stored separately from the user-visible UUID; this allows the +* user-visible UUID to be changed on V5 filesystems which have a +* filesystem UUID stamped into every piece of metadata. +*/ +static inline int xfs_sb_version_hasmetauuid (xfs_sb_t *sbp) +{ +return (XFS_SB_VERSION_NUM (sbp) ==XFS_SB_VERSION_5 ) && + (sbp->sb_features_incompat &XFS_SB_FEAT_INCOMPAT_META_UUID ); +} + +/* * end of superblock version macros */
fs/xfs/libxfs/xfs_ialloc.c +3 -2
@@ -307,7 +307,8 @@ xfs_ialloc_inode_init(if (version ==3 ) { free->di_ino =cpu_to_be64 (ino); ino++; -uuid_copy (&free->di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&free->di_uuid, + &mp->m_sb.sb_meta_uuid);xfs_dinode_calc_crc (mp, free); }else if (tp) {/* just log the inode core */
@@ -2049,7 +2050,7 @@ xfs_agi_verify(struct xfs_agi *agi =XFS_BUF_TO_AGI (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))return false;/* * Validate the magic number of the agi block.
fs/xfs/libxfs/xfs_ialloc_btree.c +1 -1
@@ -230,7 +230,7 @@ xfs_inobt_verify(case cpu_to_be32 (XFS_FIBT_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
fs/xfs/libxfs/xfs_inode_buf.c +2 -2
@@ -306,7 +306,7 @@ xfs_dinode_verify(return false;if (be64_to_cpu (dip->di_ino) != ip->i_ino)return false; -if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_meta_uuid))return false;return true; }
@@ -368,7 +368,7 @@ xfs_iread(if (xfs_sb_version_hascrc (&mp->m_sb)) { ip->i_d.di_version =3 ; ip->i_d.di_ino = ip->i_ino; -uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); }else ip->i_d.di_version =2 ;return 0 ;
fs/xfs/libxfs/xfs_sb.c +15 -0
@@ -377,6 +377,17 @@ __xfs_sb_from_disk( to->sb_pad =0 ; to->sb_pquotino =be64_to_cpu (from->sb_pquotino); to->sb_lsn =be64_to_cpu (from->sb_lsn); +/* +* sb_meta_uuid is only on disk if it differs from sb_uuid and the +* feature flag is set; if not set we keep it only in memory. +*/ +if (xfs_sb_version_hasmetauuid (to)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + }else { +memcpy (&to->sb_meta_uuid, &from->sb_uuid, +sizeof (to->sb_meta_uuid)); + }/* Convert on-disk flags to in-memory flags? */ if (convert_xquota)xfs_sb_quota_from_disk (to);
@@ -518,6 +529,10 @@ xfs_sb_to_disk(cpu_to_be32 (from->sb_features_log_incompat); to->sb_pad =0 ; to->sb_lsn =cpu_to_be64 (from->sb_lsn); +if (xfs_sb_version_hasmetauuid (from)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + } } }
fs/xfs/libxfs/xfs_symlink_remote.c +2 -2
@@ -63,7 +63,7 @@ xfs_symlink_hdr_set( dsl->sl_magic =cpu_to_be32 (XFS_SYMLINK_MAGIC ); dsl->sl_offset =cpu_to_be32 (offset); dsl->sl_bytes =cpu_to_be32 (size); -uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid); dsl->sl_owner =cpu_to_be64 (ino); dsl->sl_blkno =cpu_to_be64 (bp->b_bn); bp->b_ops = &xfs_symlink_buf_ops;
@@ -107,7 +107,7 @@ xfs_symlink_verify(return false;if (dsl->sl_magic !=cpu_to_be32 (XFS_SYMLINK_MAGIC ))return false; -if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (bp->b_bn !=be64_to_cpu (dsl->sl_blkno))return false;
fs/xfs/xfs_dquot.c +1 -1
@@ -251,7 +251,7 @@ xfs_qm_init_dquot_blk( d->dd_diskdq.d_id =cpu_to_be32 (curid); d->dd_diskdq.d_flags = type;if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }
fs/xfs/xfs_fsops.c +3 -3
@@ -248,7 +248,7 @@ xfs_growfs_data_private( agf->agf_freeblks =cpu_to_be32 (tmpsize); agf->agf_longest =cpu_to_be32 (tmpsize);if (xfs_sb_version_hascrc (&mp->m_sb)) -uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid); error =xfs_bwrite (bp);xfs_buf_relse (bp);
@@ -271,7 +271,7 @@ xfs_growfs_data_private(if (xfs_sb_version_hascrc (&mp->m_sb)) { agfl->agfl_magicnum =cpu_to_be32 (XFS_AGFL_MAGIC ); agfl->agfl_seqno =cpu_to_be32 (agno); -uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid); } agfl_bno =XFS_BUF_TO_AGFL_BNO (mp, bp);
@@ -307,7 +307,7 @@ xfs_growfs_data_private( agi->agi_newino =cpu_to_be32 (NULLAGINO ); agi->agi_dirino =cpu_to_be32 (NULLAGINO );if (xfs_sb_version_hascrc (&mp->m_sb)) -uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);if (xfs_sb_version_hasfinobt (&mp->m_sb)) { agi->agi_free_root =cpu_to_be32 (XFS_FIBT_BLOCK (mp)); agi->agi_free_level =cpu_to_be32 (1 );
fs/xfs/xfs_inode.c +1 -1
@@ -787,7 +787,7 @@ xfs_ialloc(if (ip->i_d.di_version ==3 ) {ASSERT (ip->i_d.di_ino == ino); -ASSERT (uuid_equal (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid)); ip->i_d.di_crc =0 ; ip->i_d.di_changecount =1 ; ip->i_d.di_lsn =0 ;
fs/xfs/xfs_log_recover.c +2 -2
@@ -325,7 +325,7 @@ xlog_header_check_recover(XFS_ERROR_REPORT ("xlog_header_check_recover(1)" ,XFS_ERRLEVEL_HIGH , mp);return -EFSCORRUPTED ; - }else if (unlikely (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { + }else if (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {xfs_warn (mp,"dirty log entry has mismatched uuid - can't recover" );xlog_header_check_dump (mp, head);
@@ -353,7 +353,7 @@ xlog_header_check_mount(* by IRIX and continue. */ xfs_warn (mp,"nil uuid in log - IRIX style log" ); - }else if (unlikely (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { + }else if (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {xfs_warn (mp,"log has mismatched uuid - can't recover" );xlog_header_check_dump (mp, head); XFS_ERROR_REPORT("xlog_header_check_mount",
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 1/2] xfs: create new metadata UUID field and incompat flag
Quoted 12 lines · Eric Sandeen
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_uuidslot in memory when the superblock is read from disk; themeta_uuidfield is not written back to disk in this case.
Quoted 5 lines
The remainder of this patch simply switches verifiers, initializers, etc to use the new
sb_meta_uuidfield.Signed-off-by Eric Sandeen <[email protected]>---
Looks good to me:
Quoted 549 lines
fs/xfs/libxfs/xfs_alloc.c +2
-2@@ -450,7 +450,7 @@ xfs_agfl_verify(struct xfs_agfl *agfl =XFS_BUF_TO_AGFL (bp);int i; -if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be32_to_cpu (agfl->agfl_magicnum) !=XFS_AGFL_MAGIC )return false;@@ -2203,7 +2203,7 @@ xfs_agf_verify(struct xfs_agf *agf =XFS_BUF_TO_AGF (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))return false; if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&fs/xfs/libxfs/xfs_alloc_btree.c +2
-2@@ -295,7 +295,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTB_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;@@ -313,7 +313,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTC_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;fs/xfs/libxfs/xfs_attr_leaf.c +2
-2@@ -262,7 +262,7 @@ xfs_attr3_leaf_verify(if (ichdr.magic !=XFS_ATTR3_LEAF_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;@@ -1056,7 +1056,7 @@ xfs_attr3_leaf_create( hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); ichdr.freemap[0 ].base =sizeof (struct xfs_attr3_leaf_hdr ); }else {fs/xfs/libxfs/xfs_attr_remote.c +2
-2@@ -100,7 +100,7 @@ xfs_attr3_rmt_verify(return false;if (rmt->rm_magic !=cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ))return false; -if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (rmt->rm_blkno) != bno)return false;@@ -217,7 +217,7 @@ xfs_attr3_rmt_hdr_set( rmt->rm_magic =cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ); rmt->rm_offset =cpu_to_be32 (offset); rmt->rm_bytes =cpu_to_be32 (size); -uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid); rmt->rm_owner =cpu_to_be64 (ino); rmt->rm_blkno =cpu_to_be64 (bno);fs/xfs/libxfs/xfs_bmap_btree.c +3
-2@@ -349,7 +349,8 @@ xfs_bmbt_to_bmdr(if (xfs_sb_version_hascrc (&mp->m_sb)) {ASSERT (rblock->bb_magic ==cpu_to_be32 (XFS_BMAP_CRC_MAGIC )); -ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid));ASSERT (rblock->bb_u.l.bb_blkno ==cpu_to_be64 (XFS_BUF_DADDR_NULL )); }else @@ -647,7 +648,7 @@ xfs_bmbt_verify(case cpu_to_be32 (XFS_BMAP_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (block->bb_u.l.bb_blkno) != bp->b_bn)return false;fs/xfs/libxfs/xfs_btree.c +6
-4@@ -65,7 +65,8 @@ xfs_btree_check_lblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { lblock_ok = lblock_ok && -uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.l.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }@@ -115,7 +116,8 @@ xfs_btree_check_sblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { sblock_ok = sblock_ok && -uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.s.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.s.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }@@ -1000,7 +1002,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.l.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.l.bb_owner =cpu_to_be64 (owner); -uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.l.bb_pad =0 ; buf->bb_u.l.bb_lsn =0 ; }@@ -1013,7 +1015,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.s.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.s.bb_owner =cpu_to_be32 (__owner); -uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.s.bb_lsn =0 ; } }fs/xfs/libxfs/xfs_da_btree.c +2
-2@@ -146,7 +146,7 @@ xfs_da3_node_verify(if (ichdr.magic !=XFS_DA3_NODE_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;@@ -324,7 +324,7 @@ xfs_da3_node_create( ichdr.magic =XFS_DA3_NODE_MAGIC ; hdr3->info.blkno =cpu_to_be64 (bp->b_bn); hdr3->info.owner =cpu_to_be64 (args->dp->i_ino); -uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid); }else { ichdr.magic =XFS_DA_NODE_MAGIC ; }fs/xfs/libxfs/xfs_dir2_block.c +2
-2@@ -67,7 +67,7 @@ xfs_dir3_block_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;@@ -157,7 +157,7 @@ xfs_dir3_block_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid);return ; }fs/xfs/libxfs/xfs_dir2_data.c +2
-2@@ -220,7 +220,7 @@ xfs_dir3_data_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_DATA_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;@@ -604,7 +604,7 @@ xfs_dir3_data_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_DATA_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); }else hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );fs/xfs/libxfs/xfs_dir2_leaf.c +2
-2@@ -160,7 +160,7 @@ xfs_dir3_leaf_verify(if (leaf3->info.hdr.magic !=cpu_to_be16 (magic3))return false; -if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (leaf3->info.blkno) != bp->b_bn)return false;@@ -310,7 +310,7 @@ xfs_dir3_leaf_init( : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); leaf3->info.blkno =cpu_to_be64 (bp->b_bn); leaf3->info.owner =cpu_to_be64 (owner); -uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid); }else {memset (leaf,0 ,sizeof (*leaf)); leaf->hdr.info.magic =cpu_to_be16 (type);fs/xfs/libxfs/xfs_dir2_node.c +2
-2@@ -93,7 +93,7 @@ xfs_dir3_free_verify(if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_FREE_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;@@ -226,7 +226,7 @@ xfs_dir3_free_get_buf( hdr3->hdr.blkno =cpu_to_be64 (bp->b_bn); hdr3->hdr.owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); }else hdr.magic =XFS_DIR2_FREE_MAGIC ; dp->d_ops->free_hdr_to_disk (bp->b_addr, &hdr);fs/xfs/libxfs/xfs_dquot_buf.c +2
-2@@ -163,7 +163,7 @@ xfs_dqcheck( d->dd_diskdq.d_id =cpu_to_be32 (id);if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }@@ -198,7 +198,7 @@ xfs_dquot_buf_verify_crc(if (!xfs_verify_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ))return false; -if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_meta_uuid))return false; }return true;fs/xfs/libxfs/xfs_format.h +19
-3@@ -100,7 +100,7 @@ typedef struct xfs_sb {xfs_rfsblock_t sb_dblocks;/* number of data blocks */ xfs_rfsblock_t sb_rblocks;/* number of realtime blocks */ xfs_rtblock_t sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ xfs_fsblock_t sb_logstart;/* starting block of log if internal */ xfs_ino_t sb_rootino;/* root inode number */ xfs_ino_t sb_rbmino;/* bitmap inode for realtime extents */ @@ -174,6 +174,7 @@ typedef struct xfs_sb {xfs_ino_t sb_pquotino;/* project quota inode */ xfs_lsn_t sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_sb_t;@@ -190,7 +191,7 @@ typedef struct xfs_dsb {__be64 sb_dblocks;/* number of data blocks */ __be64 sb_rblocks;/* number of realtime blocks */ __be64 sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ __be64 sb_logstart;/* starting block of log if internal */ __be64 sb_rootino;/* root inode number */ __be64 sb_rbmino;/* bitmap inode for realtime extents */ @@ -260,6 +261,7 @@ typedef struct xfs_dsb {__be64 sb_pquotino;/* project quota inode */ __be64 sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_dsb_t;@@ -457,8 +459,10 @@ xfs_sb_has_ro_compat_feature( }#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0)/* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 1)/* metadata UUID */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_META_UUID)#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool@@ -507,6 +511,18 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) }/* +* XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID +* is stored separately from the user-visible UUID; this allows the +* user-visible UUID to be changed on V5 filesystems which have a +* filesystem UUID stamped into every piece of metadata. +*/ +static inline int xfs_sb_version_hasmetauuid (xfs_sb_t *sbp) +{ +return (XFS_SB_VERSION_NUM (sbp) ==XFS_SB_VERSION_5 ) && + (sbp->sb_features_incompat &XFS_SB_FEAT_INCOMPAT_META_UUID ); +} + +/* * end of superblock version macros */ fs/xfs/libxfs/xfs_ialloc.c +3
-2@@ -307,7 +307,8 @@ xfs_ialloc_inode_init(if (version ==3 ) { free->di_ino =cpu_to_be64 (ino); ino++; -uuid_copy (&free->di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&free->di_uuid, + &mp->m_sb.sb_meta_uuid);xfs_dinode_calc_crc (mp, free); }else if (tp) {/* just log the inode core */ @@ -2049,7 +2050,7 @@ xfs_agi_verify(struct xfs_agi *agi =XFS_BUF_TO_AGI (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))return false;/* * Validate the magic number of the agi block. fs/xfs/libxfs/xfs_ialloc_btree.c +1
-1@@ -230,7 +230,7 @@ xfs_inobt_verify(case cpu_to_be32 (XFS_FIBT_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;fs/xfs/libxfs/xfs_inode_buf.c +2
-2@@ -306,7 +306,7 @@ xfs_dinode_verify(return false;if (be64_to_cpu (dip->di_ino) != ip->i_ino)return false; -if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_meta_uuid))return false;return true; }@@ -368,7 +368,7 @@ xfs_iread(if (xfs_sb_version_hascrc (&mp->m_sb)) { ip->i_d.di_version =3 ; ip->i_d.di_ino = ip->i_ino; -uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); }else ip->i_d.di_version =2 ;return 0 ;fs/xfs/libxfs/xfs_sb.c +15
-0@@ -377,6 +377,17 @@ __xfs_sb_from_disk( to->sb_pad =0 ; to->sb_pquotino =be64_to_cpu (from->sb_pquotino); to->sb_lsn =be64_to_cpu (from->sb_lsn); +/* +* sb_meta_uuid is only on disk if it differs from sb_uuid and the +* feature flag is set; if not set we keep it only in memory. +*/ +if (xfs_sb_version_hasmetauuid (to)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + }else { +memcpy (&to->sb_meta_uuid, &from->sb_uuid, +sizeof (to->sb_meta_uuid)); + }/* Convert on-disk flags to in-memory flags? */ if (convert_xquota)xfs_sb_quota_from_disk (to);@@ -518,6 +529,10 @@ xfs_sb_to_disk(cpu_to_be32 (from->sb_features_log_incompat); to->sb_pad =0 ; to->sb_lsn =cpu_to_be64 (from->sb_lsn); +if (xfs_sb_version_hasmetauuid (from)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + } } }fs/xfs/libxfs/xfs_symlink_remote.c +2
-2@@ -63,7 +63,7 @@ xfs_symlink_hdr_set( dsl->sl_magic =cpu_to_be32 (XFS_SYMLINK_MAGIC ); dsl->sl_offset =cpu_to_be32 (offset); dsl->sl_bytes =cpu_to_be32 (size); -uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid); dsl->sl_owner =cpu_to_be64 (ino); dsl->sl_blkno =cpu_to_be64 (bp->b_bn); bp->b_ops = &xfs_symlink_buf_ops;@@ -107,7 +107,7 @@ xfs_symlink_verify(return false;if (dsl->sl_magic !=cpu_to_be32 (XFS_SYMLINK_MAGIC ))return false; -if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (bp->b_bn !=be64_to_cpu (dsl->sl_blkno))return false;fs/xfs/xfs_dquot.c +1
-1@@ -251,7 +251,7 @@ xfs_qm_init_dquot_blk( d->dd_diskdq.d_id =cpu_to_be32 (curid); d->dd_diskdq.d_flags = type;if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }fs/xfs/xfs_fsops.c +3
-3@@ -248,7 +248,7 @@ xfs_growfs_data_private( agf->agf_freeblks =cpu_to_be32 (tmpsize); agf->agf_longest =cpu_to_be32 (tmpsize);if (xfs_sb_version_hascrc (&mp->m_sb)) -uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid); error =xfs_bwrite (bp);xfs_buf_relse (bp);@@ -271,7 +271,7 @@ xfs_growfs_data_private(if (xfs_sb_version_hascrc (&mp->m_sb)) { agfl->agfl_magicnum =cpu_to_be32 (XFS_AGFL_MAGIC ); agfl->agfl_seqno =cpu_to_be32 (agno); -uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid); } agfl_bno =XFS_BUF_TO_AGFL_BNO (mp, bp);@@ -307,7 +307,7 @@ xfs_growfs_data_private( agi->agi_newino =cpu_to_be32 (NULLAGINO ); agi->agi_dirino =cpu_to_be32 (NULLAGINO );if (xfs_sb_version_hascrc (&mp->m_sb)) -uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);if (xfs_sb_version_hasfinobt (&mp->m_sb)) { agi->agi_free_root =cpu_to_be32 (XFS_FIBT_BLOCK (mp)); agi->agi_free_level =cpu_to_be32 (1 );fs/xfs/xfs_inode.c +1
-1@@ -787,7 +787,7 @@ xfs_ialloc(if (ip->i_d.di_version ==3 ) {ASSERT (ip->i_d.di_ino == ino); -ASSERT (uuid_equal (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid)); ip->i_d.di_crc =0 ; ip->i_d.di_changecount =1 ; ip->i_d.di_lsn =0 ;fs/xfs/xfs_log_recover.c +2
-2@@ -325,7 +325,7 @@ xlog_header_check_recover(XFS_ERROR_REPORT ("xlog_header_check_recover(1)" ,XFS_ERRLEVEL_HIGH , mp);return -EFSCORRUPTED ; - }else if (unlikely (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { + }else if (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {xfs_warn (mp,"dirty log entry has mismatched uuid - can't recover" );xlog_header_check_dump (mp, head);@@ -353,7 +353,7 @@ xlog_header_check_mount(* by IRIX and continue. */ xfs_warn (mp,"nil uuid in log - IRIX style log" ); - }else if (unlikely (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { + }else if (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {xfs_warn (mp,"log has mismatched uuid - can't recover" );xlog_header_check_dump (mp, head); XFS_ERROR_REPORT("xlog_header_check_mount",
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 1/2] xfs: create new metadata UUID field and incompat flag
In reply to Eric SandeenQuoted 8 lines · Eric Sandeen
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.
Quoted 8 lines
If the incompat flag is not set, this copies the user-visible UUID into into the
meta_uuidslot in memory when the superblock is read from disk; themeta_uuidfield 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_uuidfield.Signed-off-by Eric Sandeen <[email protected]>
Couple of minor things:
Quoted 8 lines
/*
+ *XFS_SB_FEAT_INCOMPAT_META_UUIDindicates that the metadata UUID
+ * is stored separately from the user-visible UUID; this allows the
+ * user-visible UUID to be changed on V5 filesystems which have a
+ * filesystem UUID stamped into every piece of metadata.
+ */
+static inline intxfs_sb_version_hasmetauuid(xfs_sb_t *sbp)
bool, struct xfs_sb.
Quoted 6 lines
+++
b/fs/xfs/libxfs/xfs_sb.cfs/xfs/libxfs/xfs_sb.c +1
-0@@ -377,6 +377,17 @@ __xfs_sb_from_disk( to->sb_pad =0 ; to->sb_pquotino =be64_to_cpu (from->sb_pquotino); to->sb_lsn =be64_to_cpu (from->sb_lsn); +/*
fs/xfs/libxfs/xfs_sb.c __xfs_sb_from_disk( · line 390
Quoted 10 lines
fs/xfs/libxfs/xfs_sb.c +10
-0+* sb_meta_uuid is only on disk if it differs from sb_uuid and the +* feature flag is set; if not set we keep it only in memory. +*/ +if (xfs_sb_version_hasmetauuid (to)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + }else { +memcpy (&to->sb_meta_uuid, &from->sb_uuid, +sizeof (to->sb_meta_uuid)); + }
uuid_copy()
fs/xfs/libxfs/xfs_sb.c xfs_sb_to_disk( · line 535
Quoted 11 lines
fs/xfs/libxfs/xfs_sb.c +4
-0/* Convert on-disk flags to in-memory flags? */ if (convert_xquota)xfs_sb_quota_from_disk (to);@@ -518,6 +529,10 @@ xfs_sb_to_disk(cpu_to_be32 (from->sb_features_log_incompat); to->sb_pad =0 ; to->sb_lsn =cpu_to_be64 (from->sb_lsn); +if (xfs_sb_version_hasmetauuid (from)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + }
uuid_copy() here, too.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v4 1/2 xfs: create new metadata UUID field and incompat flag
In reply to Eric SandeenThis 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.
---
fs/xfs/libxfs/xfs_alloc.c +2 -2
@@ -450,7 +450,7 @@ xfs_agfl_verify(struct xfs_agfl *agfl =XFS_BUF_TO_AGFL (bp);int i; -if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be32_to_cpu (agfl->agfl_magicnum) !=XFS_AGFL_MAGIC )return false;
@@ -2203,7 +2203,7 @@ xfs_agf_verify(struct xfs_agf *agf =XFS_BUF_TO_AGF (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))return false; if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
fs/xfs/libxfs/xfs_alloc_btree.c +2 -2
@@ -295,7 +295,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTB_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
@@ -313,7 +313,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTC_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
fs/xfs/libxfs/xfs_attr_leaf.c +2 -2
@@ -262,7 +262,7 @@ xfs_attr3_leaf_verify(if (ichdr.magic !=XFS_ATTR3_LEAF_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -1056,7 +1056,7 @@ xfs_attr3_leaf_create( hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); ichdr.freemap[0 ].base =sizeof (struct xfs_attr3_leaf_hdr ); }else {
fs/xfs/libxfs/xfs_attr_remote.c +2 -2
@@ -100,7 +100,7 @@ xfs_attr3_rmt_verify(return false;if (rmt->rm_magic !=cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ))return false; -if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (rmt->rm_blkno) != bno)return false;
@@ -217,7 +217,7 @@ xfs_attr3_rmt_hdr_set( rmt->rm_magic =cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ); rmt->rm_offset =cpu_to_be32 (offset); rmt->rm_bytes =cpu_to_be32 (size); -uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid); rmt->rm_owner =cpu_to_be64 (ino); rmt->rm_blkno =cpu_to_be64 (bno);
fs/xfs/libxfs/xfs_bmap_btree.c +3 -2
@@ -349,7 +349,8 @@ xfs_bmbt_to_bmdr(if (xfs_sb_version_hascrc (&mp->m_sb)) {ASSERT (rblock->bb_magic ==cpu_to_be32 (XFS_BMAP_CRC_MAGIC )); -ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid));ASSERT (rblock->bb_u.l.bb_blkno ==cpu_to_be64 (XFS_BUF_DADDR_NULL )); }else
@@ -647,7 +648,7 @@ xfs_bmbt_verify(case cpu_to_be32 (XFS_BMAP_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (block->bb_u.l.bb_blkno) != bp->b_bn)return false;
fs/xfs/libxfs/xfs_btree.c +6 -4
@@ -65,7 +65,8 @@ xfs_btree_check_lblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { lblock_ok = lblock_ok && -uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.l.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -115,7 +116,8 @@ xfs_btree_check_sblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { sblock_ok = sblock_ok && -uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.s.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.s.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -1000,7 +1002,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.l.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.l.bb_owner =cpu_to_be64 (owner); -uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.l.bb_pad =0 ; buf->bb_u.l.bb_lsn =0 ; }
@@ -1013,7 +1015,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.s.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.s.bb_owner =cpu_to_be32 (__owner); -uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.s.bb_lsn =0 ; } }
fs/xfs/libxfs/xfs_da_btree.c +2 -2
@@ -146,7 +146,7 @@ xfs_da3_node_verify(if (ichdr.magic !=XFS_DA3_NODE_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -324,7 +324,7 @@ xfs_da3_node_create( ichdr.magic =XFS_DA3_NODE_MAGIC ; hdr3->info.blkno =cpu_to_be64 (bp->b_bn); hdr3->info.owner =cpu_to_be64 (args->dp->i_ino); -uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid); }else { ichdr.magic =XFS_DA_NODE_MAGIC ; }
fs/xfs/libxfs/xfs_dir2_block.c +2 -2
@@ -67,7 +67,7 @@ xfs_dir3_block_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -157,7 +157,7 @@ xfs_dir3_block_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid);return ; }
fs/xfs/libxfs/xfs_dir2_data.c +2 -2
@@ -220,7 +220,7 @@ xfs_dir3_data_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_DATA_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -604,7 +604,7 @@ xfs_dir3_data_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_DATA_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); }else hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );
fs/xfs/libxfs/xfs_dir2_leaf.c +2 -2
@@ -160,7 +160,7 @@ xfs_dir3_leaf_verify(if (leaf3->info.hdr.magic !=cpu_to_be16 (magic3))return false; -if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (leaf3->info.blkno) != bp->b_bn)return false;
@@ -310,7 +310,7 @@ xfs_dir3_leaf_init( : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); leaf3->info.blkno =cpu_to_be64 (bp->b_bn); leaf3->info.owner =cpu_to_be64 (owner); -uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid); }else {memset (leaf,0 ,sizeof (*leaf)); leaf->hdr.info.magic =cpu_to_be16 (type);
fs/xfs/libxfs/xfs_dir2_node.c +2 -2
@@ -93,7 +93,7 @@ xfs_dir3_free_verify(if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_FREE_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -226,7 +226,7 @@ xfs_dir3_free_get_buf( hdr3->hdr.blkno =cpu_to_be64 (bp->b_bn); hdr3->hdr.owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); }else hdr.magic =XFS_DIR2_FREE_MAGIC ; dp->d_ops->free_hdr_to_disk (bp->b_addr, &hdr);
fs/xfs/libxfs/xfs_dquot_buf.c +2 -2
@@ -163,7 +163,7 @@ xfs_dqcheck( d->dd_diskdq.d_id =cpu_to_be32 (id);if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }
@@ -198,7 +198,7 @@ xfs_dquot_buf_verify_crc(if (!xfs_verify_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ))return false; -if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_meta_uuid))return false; }return true;
fs/xfs/libxfs/xfs_format.h +19 -3
@@ -100,7 +100,7 @@ typedef struct xfs_sb {xfs_rfsblock_t sb_dblocks;/* number of data blocks */ xfs_rfsblock_t sb_rblocks;/* number of realtime blocks */ xfs_rtblock_t sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ xfs_fsblock_t sb_logstart;/* starting block of log if internal */ xfs_ino_t sb_rootino;/* root inode number */ xfs_ino_t sb_rbmino;/* bitmap inode for realtime extents */
@@ -174,6 +174,7 @@ typedef struct xfs_sb {xfs_ino_t sb_pquotino;/* project quota inode */ xfs_lsn_t sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_sb_t;
@@ -190,7 +191,7 @@ typedef struct xfs_dsb {__be64 sb_dblocks;/* number of data blocks */ __be64 sb_rblocks;/* number of realtime blocks */ __be64 sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ __be64 sb_logstart;/* starting block of log if internal */ __be64 sb_rootino;/* root inode number */ __be64 sb_rbmino;/* bitmap inode for realtime extents */
@@ -260,6 +261,7 @@ typedef struct xfs_dsb {__be64 sb_pquotino;/* project quota inode */ __be64 sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_dsb_t;
@@ -457,8 +459,10 @@ xfs_sb_has_ro_compat_feature( }#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0)/* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 1)/* metadata UUID */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_META_UUID)#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool
@@ -507,6 +511,18 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) }/* +* XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID +* is stored separately from the user-visible UUID; this allows the +* user-visible UUID to be changed on V5 filesystems which have a +* filesystem UUID stamped into every piece of metadata. +*/ +static inline bool xfs_sb_version_hasmetauuid (struct xfs_sb *sbp) +{ +return (XFS_SB_VERSION_NUM (sbp) ==XFS_SB_VERSION_5 ) && + (sbp->sb_features_incompat &XFS_SB_FEAT_INCOMPAT_META_UUID ); +} + +/* * end of superblock version macros */
fs/xfs/libxfs/xfs_ialloc.c +3 -2
@@ -307,7 +307,8 @@ xfs_ialloc_inode_init(if (version ==3 ) { free->di_ino =cpu_to_be64 (ino); ino++; -uuid_copy (&free->di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&free->di_uuid, + &mp->m_sb.sb_meta_uuid);xfs_dinode_calc_crc (mp, free); }else if (tp) {/* just log the inode core */
@@ -2049,7 +2050,7 @@ xfs_agi_verify(struct xfs_agi *agi =XFS_BUF_TO_AGI (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))return false;/* * Validate the magic number of the agi block.
fs/xfs/libxfs/xfs_ialloc_btree.c +1 -1
@@ -230,7 +230,7 @@ xfs_inobt_verify(case cpu_to_be32 (XFS_FIBT_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
fs/xfs/libxfs/xfs_inode_buf.c +2 -2
@@ -306,7 +306,7 @@ xfs_dinode_verify(return false;if (be64_to_cpu (dip->di_ino) != ip->i_ino)return false; -if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_meta_uuid))return false;return true; }
@@ -368,7 +368,7 @@ xfs_iread(if (xfs_sb_version_hascrc (&mp->m_sb)) { ip->i_d.di_version =3 ; ip->i_d.di_ino = ip->i_ino; -uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); }else ip->i_d.di_version =2 ;return 0 ;
fs/xfs/libxfs/xfs_sb.c +10 -0
@@ -377,6 +377,14 @@ __xfs_sb_from_disk( to->sb_pad =0 ; to->sb_pquotino =be64_to_cpu (from->sb_pquotino); to->sb_lsn =be64_to_cpu (from->sb_lsn); +/* +* sb_meta_uuid is only on disk if it differs from sb_uuid and the +* feature flag is set; if not set we keep it only in memory. +*/ +if (xfs_sb_version_hasmetauuid (to)) +uuid_copy (&to->sb_meta_uuid, &from->sb_meta_uuid); +else +uuid_copy (&to->sb_meta_uuid, &from->sb_uuid);/* Convert on-disk flags to in-memory flags? */ if (convert_xquota)xfs_sb_quota_from_disk (to);
@@ -518,6 +526,8 @@ xfs_sb_to_disk(cpu_to_be32 (from->sb_features_log_incompat); to->sb_pad =0 ; to->sb_lsn =cpu_to_be64 (from->sb_lsn); +if (xfs_sb_version_hasmetauuid (from)) +uuid_copy (&to->sb_meta_uuid, &from->sb_meta_uuid); } }
fs/xfs/libxfs/xfs_symlink_remote.c +2 -2
@@ -63,7 +63,7 @@ xfs_symlink_hdr_set( dsl->sl_magic =cpu_to_be32 (XFS_SYMLINK_MAGIC ); dsl->sl_offset =cpu_to_be32 (offset); dsl->sl_bytes =cpu_to_be32 (size); -uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid); dsl->sl_owner =cpu_to_be64 (ino); dsl->sl_blkno =cpu_to_be64 (bp->b_bn); bp->b_ops = &xfs_symlink_buf_ops;
@@ -107,7 +107,7 @@ xfs_symlink_verify(return false;if (dsl->sl_magic !=cpu_to_be32 (XFS_SYMLINK_MAGIC ))return false; -if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (bp->b_bn !=be64_to_cpu (dsl->sl_blkno))return false;
fs/xfs/xfs_dquot.c +1 -1
@@ -251,7 +251,7 @@ xfs_qm_init_dquot_blk( d->dd_diskdq.d_id =cpu_to_be32 (curid); d->dd_diskdq.d_flags = type;if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }
fs/xfs/xfs_fsops.c +3 -3
@@ -248,7 +248,7 @@ xfs_growfs_data_private( agf->agf_freeblks =cpu_to_be32 (tmpsize); agf->agf_longest =cpu_to_be32 (tmpsize);if (xfs_sb_version_hascrc (&mp->m_sb)) -uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid); error =xfs_bwrite (bp);xfs_buf_relse (bp);
@@ -271,7 +271,7 @@ xfs_growfs_data_private(if (xfs_sb_version_hascrc (&mp->m_sb)) { agfl->agfl_magicnum =cpu_to_be32 (XFS_AGFL_MAGIC ); agfl->agfl_seqno =cpu_to_be32 (agno); -uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid); } agfl_bno =XFS_BUF_TO_AGFL_BNO (mp, bp);
@@ -307,7 +307,7 @@ xfs_growfs_data_private( agi->agi_newino =cpu_to_be32 (NULLAGINO ); agi->agi_dirino =cpu_to_be32 (NULLAGINO );if (xfs_sb_version_hascrc (&mp->m_sb)) -uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);if (xfs_sb_version_hasfinobt (&mp->m_sb)) { agi->agi_free_root =cpu_to_be32 (XFS_FIBT_BLOCK (mp)); agi->agi_free_level =cpu_to_be32 (1 );
fs/xfs/xfs_inode.c +1 -1
@@ -787,7 +787,7 @@ xfs_ialloc(if (ip->i_d.di_version ==3 ) {ASSERT (ip->i_d.di_ino == ino); -ASSERT (uuid_equal (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid)); ip->i_d.di_crc =0 ; ip->i_d.di_changecount =1 ; ip->i_d.di_lsn =0 ;
fs/xfs/xfs_log_recover.c +2 -2
@@ -325,7 +325,7 @@ xlog_header_check_recover(XFS_ERROR_REPORT ("xlog_header_check_recover(1)" ,XFS_ERRLEVEL_HIGH , mp);return -EFSCORRUPTED ; - }else if (unlikely (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { + }else if (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {xfs_warn (mp,"dirty log entry has mismatched uuid - can't recover" );xlog_header_check_dump (mp, head);
@@ -353,7 +353,7 @@ xlog_header_check_mount(* by IRIX and continue. */ xfs_warn (mp,"nil uuid in log - IRIX style log" ); - }else if (unlikely (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { + }else if (!uuid_equal (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {xfs_warn (mp,"log has mismatched uuid - can't recover" );xlog_header_check_dump (mp, head); XFS_ERROR_REPORT("xlog_header_check_mount",
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v3 2/2 xfsprogs: Add new sb_meta_uuid field, update userspace tools to manipulate it
In reply to Eric SandeenThis adds a new superblock field, sb_meta_uuid. This allows us to change the use-visible UUID on crc-enabled filesytems from userspace if desired, by copying the existing UUID to the new location for metadata comparisons. If this is done, an incompat flag must be set to prevent older filesystems from mounting the filesystem, but the original UUID can be restored, and the incompat flag removed, with a new xfs_db / xfs_admin UUID command, "restore."
Much of this patch mirrors the kernel patch in simply renaming the field used for metadata uuid comparison; other bits:
* Teach xfs_db to print the new meta_uuid field
* Allow xfs_db to generate a new UUID for CRC-enabled filesystems
* Allow xfs_db to revert to the original UUID and clear the flag
* Fix up xfs_copy to work with CRC-enabled filesystems
* Update the xfs_admin manpage to show the UUID "restore" command
---
This version makes the UUID "restore" command silent if there is nothing to do.
Still open to bike-shedding on the "restore" name. Maybe "revert?"
copy/xfs_copy.c +29 -12
@@ -466,6 +466,34 @@ write_wbuf(void)sighold (SIGCHLD ); } +void +sb_update_uuid ( +xfs_sb_t *sb, +ag_header_t *ag_hdr, +thread_args *tcarg) +{ +/* +* If this filesystem has CRCs, the original UUID is stamped into +* all metadata. We need to copy the original UUID into the meta_uuid +* slot and set the incompat flag if that hasn't already been done. +*/ +if (xfs_sb_version_hascrc (sb) && !xfs_sb_version_hasmetauuid (sb)) { +__be32 feat; + + feat =be32_to_cpu (ag_hdr->xfs_sb->sb_features_incompat); + feat |=XFS_SB_FEAT_INCOMPAT_META_UUID ; + ag_hdr->xfs_sb->sb_features_incompat =cpu_to_be32 (feat); +platform_uuid_copy (&ag_hdr->xfs_sb->sb_meta_uuid, + &ag_hdr->xfs_sb->sb_uuid); + } + +platform_uuid_copy (&ag_hdr->xfs_sb->sb_uuid, &tcarg->uuid); + +/* We changed the UUID, so update the superblock CRC if needed */ +if (xfs_sb_version_hascrc (sb)) +xfs_update_cksum ((char *)&ag_hdr->xfs_sb, sb->sb_sectsize, +XFS_SB_CRC_OFF ); +}int main (int argc,char **argv)
@@ -659,16 +687,6 @@ main(int argc, char **argv) sb = &mbuf.m_sb;libxfs_sb_from_disk (sb,XFS_BUF_TO_SBP (sbp)); -/* -* For now, V5 superblock filesystems are not supported without -d; -* we do not have the infrastructure yet to fix CRCs when a new UUID -* is generated. -*/ -if (xfs_sb_version_hascrc (sb) && !duplicate) { -do_log (_ ("%s: Cannot yet copy V5 fs without '-d'\n" ), progname); -exit (1 ); - } - mp =libxfs_mount (&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev,0 );if (mp ==NULL ) { do_log(_("%s: %s filesystem failed to initialize\n"
@@ -1127,8 +1145,7 @@ main(int argc, char **argv)/* do each thread in turn, each has its own UUID */ for (j =0 , tcarg = targ; j < num_targets; j++) { -platform_uuid_copy (&ag_hdr.xfs_sb->sb_uuid, - &tcarg->uuid); +sb_update_uuid (sb, &ag_hdr, tcarg);do_write (tcarg); tcarg++; }
db/sb.c +42 -12
90 lines not on this page · raw message
libxfs/xfs_alloc.c +2 -2
@@ -446,7 +446,7 @@ xfs_agfl_verify(struct xfs_agfl *agfl =XFS_BUF_TO_AGFL (bp);int i; -if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be32_to_cpu (agfl->agfl_magicnum) !=XFS_AGFL_MAGIC )return false;
@@ -2199,7 +2199,7 @@ xfs_agf_verify(struct xfs_agf *agf =XFS_BUF_TO_AGF (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))return false; if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
libxfs/xfs_alloc_btree.c +2 -2
@@ -293,7 +293,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTB_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
@@ -311,7 +311,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTC_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
libxfs/xfs_attr_leaf.c +2 -2
@@ -258,7 +258,7 @@ xfs_attr3_leaf_verify(if (ichdr.magic !=XFS_ATTR3_LEAF_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -1052,7 +1052,7 @@ xfs_attr3_leaf_create( hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); ichdr.freemap[0 ].base =sizeof (struct xfs_attr3_leaf_hdr ); }else {
libxfs/xfs_attr_remote.c +2 -2
@@ -95,7 +95,7 @@ xfs_attr3_rmt_verify(return false;if (rmt->rm_magic !=cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ))return false; -if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (rmt->rm_blkno) != bno)return false;
@@ -212,7 +212,7 @@ xfs_attr3_rmt_hdr_set( rmt->rm_magic =cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ); rmt->rm_offset =cpu_to_be32 (offset); rmt->rm_bytes =cpu_to_be32 (size); -uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid); rmt->rm_owner =cpu_to_be64 (ino); rmt->rm_blkno =cpu_to_be64 (bno);
libxfs/xfs_bmap_btree.c +3 -2
@@ -346,7 +346,8 @@ xfs_bmbt_to_bmdr(if (xfs_sb_version_hascrc (&mp->m_sb)) {ASSERT (rblock->bb_magic ==cpu_to_be32 (XFS_BMAP_CRC_MAGIC )); -ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid));ASSERT (rblock->bb_u.l.bb_blkno ==cpu_to_be64 (XFS_BUF_DADDR_NULL )); }else
@@ -644,7 +645,7 @@ xfs_bmbt_verify(case cpu_to_be32 (XFS_BMAP_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (block->bb_u.l.bb_blkno) != bp->b_bn)return false;
libxfs/xfs_btree.c +6 -4
@@ -62,7 +62,8 @@ xfs_btree_check_lblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { lblock_ok = lblock_ok && -uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.l.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -112,7 +113,8 @@ xfs_btree_check_sblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { sblock_ok = sblock_ok && -uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.s.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.s.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -997,7 +999,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.l.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.l.bb_owner =cpu_to_be64 (owner); -uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.l.bb_pad =0 ; buf->bb_u.l.bb_lsn =0 ; }
@@ -1010,7 +1012,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.s.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.s.bb_owner =cpu_to_be32 (__owner); -uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.s.bb_lsn =0 ; } }
libxfs/xfs_da_btree.c +2 -2
@@ -142,7 +142,7 @@ xfs_da3_node_verify(if (ichdr.magic !=XFS_DA3_NODE_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -320,7 +320,7 @@ xfs_da3_node_create( ichdr.magic =XFS_DA3_NODE_MAGIC ; hdr3->info.blkno =cpu_to_be64 (bp->b_bn); hdr3->info.owner =cpu_to_be64 (args->dp->i_ino); -uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid); }else { ichdr.magic =XFS_DA_NODE_MAGIC ; }
libxfs/xfs_dir2_block.c +2 -2
@@ -64,7 +64,7 @@ xfs_dir3_block_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -154,7 +154,7 @@ xfs_dir3_block_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid);return ; }
libxfs/xfs_dir2_data.c +2 -2
@@ -218,7 +218,7 @@ xfs_dir3_data_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_DATA_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -602,7 +602,7 @@ xfs_dir3_data_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_DATA_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); }else hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );
libxfs/xfs_dir2_leaf.c +2 -2
@@ -158,7 +158,7 @@ xfs_dir3_leaf_verify(if (leaf3->info.hdr.magic !=cpu_to_be16 (magic3))return false; -if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (leaf3->info.blkno) != bp->b_bn)return false;
@@ -308,7 +308,7 @@ xfs_dir3_leaf_init( : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); leaf3->info.blkno =cpu_to_be64 (bp->b_bn); leaf3->info.owner =cpu_to_be64 (owner); -uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid); }else {memset (leaf,0 ,sizeof (*leaf)); leaf->hdr.info.magic =cpu_to_be16 (type);
libxfs/xfs_dir2_node.c +2 -2
@@ -91,7 +91,7 @@ xfs_dir3_free_verify(if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_FREE_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -224,7 +224,7 @@ xfs_dir3_free_get_buf( hdr3->hdr.blkno =cpu_to_be64 (bp->b_bn); hdr3->hdr.owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); }else hdr.magic =XFS_DIR2_FREE_MAGIC ; dp->d_ops->free_hdr_to_disk (bp->b_addr, &hdr);
libxfs/xfs_dquot_buf.c +2 -2
@@ -171,7 +171,7 @@ xfs_dqcheck( d->dd_diskdq.d_id =cpu_to_be32 (id);if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }
@@ -206,7 +206,7 @@ xfs_dquot_buf_verify_crc(if (!xfs_verify_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ))return false; -if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_meta_uuid))return false; }return true;
libxfs/xfs_format.h +19 -3
@@ -100,7 +100,7 @@ typedef struct xfs_sb {xfs_rfsblock_t sb_dblocks;/* number of data blocks */ xfs_rfsblock_t sb_rblocks;/* number of realtime blocks */ xfs_rtblock_t sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ xfs_fsblock_t sb_logstart;/* starting block of log if internal */ xfs_ino_t sb_rootino;/* root inode number */ xfs_ino_t sb_rbmino;/* bitmap inode for realtime extents */
@@ -174,6 +174,7 @@ typedef struct xfs_sb {xfs_ino_t sb_pquotino;/* project quota inode */ xfs_lsn_t sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_sb_t;
@@ -190,7 +191,7 @@ typedef struct xfs_dsb {__be64 sb_dblocks;/* number of data blocks */ __be64 sb_rblocks;/* number of realtime blocks */ __be64 sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ __be64 sb_logstart;/* starting block of log if internal */ __be64 sb_rootino;/* root inode number */ __be64 sb_rbmino;/* bitmap inode for realtime extents */
@@ -260,6 +261,7 @@ typedef struct xfs_dsb {__be64 sb_pquotino;/* project quota inode */ __be64 sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_dsb_t;
@@ -457,8 +459,10 @@ xfs_sb_has_ro_compat_feature( }#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0)/* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 1)/* metadata UUID */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_META_UUID)#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool
@@ -507,6 +511,18 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) }/* +* XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID +* is stored separately from the user-visible UUID; this allows the +* user-visible UUID to be changed on V5 filesystems which have a +* filesystem UUID stamped into every piece of metadata. +*/ +static inline int xfs_sb_version_hasmetauuid (xfs_sb_t *sbp) +{ +return (XFS_SB_VERSION_NUM (sbp) ==XFS_SB_VERSION_5 ) && + (sbp->sb_features_incompat &XFS_SB_FEAT_INCOMPAT_META_UUID ); +} + +/* * end of superblock version macros */
libxfs/xfs_ialloc.c +3 -2
@@ -302,7 +302,8 @@ xfs_ialloc_inode_init(if (version ==3 ) { free->di_ino =cpu_to_be64 (ino); ino++; -uuid_copy (&free->di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&free->di_uuid, + &mp->m_sb.sb_meta_uuid);xfs_dinode_calc_crc (mp, free); }else if (tp) {/* just log the inode core */
@@ -2044,7 +2045,7 @@ xfs_agi_verify(struct xfs_agi *agi =XFS_BUF_TO_AGI (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))return false;/* * Validate the magic number of the agi block.
libxfs/xfs_ialloc_btree.c +1 -1
@@ -229,7 +229,7 @@ xfs_inobt_verify(case cpu_to_be32 (XFS_FIBT_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
libxfs/xfs_inode_buf.c +2 -2
@@ -304,7 +304,7 @@ xfs_dinode_verify(return false;if (be64_to_cpu (dip->di_ino) != ino)return false; -if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_meta_uuid))return false;return true; }
@@ -366,7 +366,7 @@ xfs_iread(if (xfs_sb_version_hascrc (&mp->m_sb)) { ip->i_d.di_version =3 ; ip->i_d.di_ino = ip->i_ino; -uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); }else ip->i_d.di_version =2 ;return 0 ;
libxfs/xfs_sb.c +15 -0
@@ -360,6 +360,17 @@ __xfs_sb_from_disk( to->sb_pad =0 ; to->sb_pquotino =be64_to_cpu (from->sb_pquotino); to->sb_lsn =be64_to_cpu (from->sb_lsn); +/* +* sb_meta_uuid is only on disk if it differs from sb_uuid and the +* feature flag is set; if not set we keep it only in memory. +*/ +if (xfs_sb_version_hasmetauuid (to)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + }else { +memcpy (&to->sb_meta_uuid, &from->sb_uuid, +sizeof (to->sb_meta_uuid)); + }/* Convert on-disk flags to in-memory flags? */ if (convert_xquota)xfs_sb_quota_from_disk (to);
@@ -501,6 +512,10 @@ xfs_sb_to_disk(cpu_to_be32 (from->sb_features_log_incompat); to->sb_pad =0 ; to->sb_lsn =cpu_to_be64 (from->sb_lsn); +if (xfs_sb_version_hasmetauuid (from)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + } } }
libxfs/xfs_symlink_remote.c +2 -2
@@ -60,7 +60,7 @@ xfs_symlink_hdr_set( dsl->sl_magic =cpu_to_be32 (XFS_SYMLINK_MAGIC ); dsl->sl_offset =cpu_to_be32 (offset); dsl->sl_bytes =cpu_to_be32 (size); -uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid); dsl->sl_owner =cpu_to_be64 (ino); dsl->sl_blkno =cpu_to_be64 (bp->b_bn); bp->b_ops = &xfs_symlink_buf_ops;
@@ -104,7 +104,7 @@ xfs_symlink_verify(return false;if (dsl->sl_magic !=cpu_to_be32 (XFS_SYMLINK_MAGIC ))return false; -if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (bp->b_bn !=be64_to_cpu (dsl->sl_blkno))return false;
libxlog/util.c +4 -2
@@ -29,8 +29,10 @@ header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head) {char uu_log[64 ], uu_sb[64 ]; -if (print_skip_uuid)return 0 ; -if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid))return 0 ; +if (print_skip_uuid) +return 0 ; +if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) +return 0 ;platform_uuid_unparse (&mp->m_sb.sb_uuid, uu_sb);platform_uuid_unparse (&head->h_fs_uuid, uu_log);
man/man8/xfs_admin.8 +6 -1
@@ -98,7 +98,12 @@ The .I uuid may also be .BR generate , -which will generate a new UUID for the filesystem. +which will generate a new UUID for the filesystem. Note that on CRC-enabled +filesystems, this will set an incompatible flag such that older kernels will +not be able to mount the filesystem. To remove this incompatible flag, use +.BR restore , +which will restore the original UUID and remove the incompatible +feature flag as needed. .TP .B \-V Prints the version number and exits.
man/man8/xfs_db.8 +7 -2
@@ -664,7 +664,7 @@ The possible data types are: .BR sb ", " symlink " and " text . See the TYPES section below for more information on these data types. .TP -.BI "uuid [" uuid " | " generate " | " rewrite ] +.BI "uuid [" uuid " | " generate " | " rewrite " | " restore ] Set the filesystem universally unique identifier (UUID). The filesystem UUID can be used by .BR mount (8)
@@ -675,7 +675,12 @@ can be set directly to the desired UUID, or it can be automatically generated using the .B generate option. These options will both write the UUID into every copy of the -superblock in the filesystem. +superblock in the filesystem. On a CRC-enabled filesystem, this will +set an incompatible superblock flag, and the filesystem will not be +mountable with older kernels. This can be reverted with the +.B restore +option, which will copy the original UUID back into place and clear +the incompatible flag as needed. .B rewrite copies the current UUID from the primary superblock to all secondary copies of the superblock.
mkfs/xfs_mkfs.c +2 -0
@@ -2598,6 +2598,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), sbp->sb_rextents = rtextents;platform_uuid_generate (&uuid);platform_uuid_copy (&sbp->sb_uuid, &uuid); +/* Only in memory; libxfs expects this as if read from disk */ +platform_uuid_copy (&sbp->sb_meta_uuid, &uuid); sbp->sb_logstart = logstart; sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino =NULLFSINO ; sbp->sb_rextsize = rtextblocks;
repair/agheader.c +12 -7
@@ -112,7 +112,7 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGF ;
@@ -120,7 +120,8 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)do_warn (_ ("bad uuid %s for agf %d\n" ), uu, i);if (!no_modify) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, + &mp->m_sb.sb_meta_uuid); }return retval; }
@@ -190,7 +191,7 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGI ;
@@ -198,7 +199,8 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)do_warn (_ ("bad uuid %s for agi %d\n" ), uu, agno);if (!no_modify) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, + &mp->m_sb.sb_meta_uuid); }return retval;
@@ -245,7 +247,7 @@ compare_sb(xfs_mount_t *mp, xfs_sb_t *sb)* superblocks, not just the secondary superblocks. */ static int -secondary_sb_wack( +secondary_sb_whack( struct xfs_mount *mp, struct xfs_buf *sbuf, struct xfs_sb *sb,
@@ -267,7 +269,10 @@ secondary_sb_wack(* * size is the size of data which is valid for this sb. */ -if (xfs_sb_version_hascrc (sb)) +if (xfs_sb_version_hasmetauuid (sb)) + size = offsetof(xfs_sb_t , sb_meta_uuid) + +sizeof (sb->sb_meta_uuid); +else if (xfs_sb_version_hascrc (sb)) size = offsetof(xfs_sb_t , sb_lsn) +sizeof (sb->sb_lsn);else if (xfs_sb_version_hasmorebits (sb))
@@ -511,7 +516,7 @@ verify_set_agheader(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, rval |=XR_AG_SB ; } - rval |=secondary_sb_wack (mp, sbuf, sb, i); + rval |=secondary_sb_whack (mp, sbuf, sb, i); rval |=verify_set_agf (mp, agf, i); rval |=verify_set_agi (mp, agi, i);
repair/agheader.h +0 -1
@@ -24,7 +24,6 @@ typedef struct fs_geometry {xfs_rfsblock_t sb_dblocks;/* # data blocks */ xfs_rfsblock_t sb_rblocks;/* # realtime blocks */ xfs_rtblock_t sb_rextents;/* # realtime extents */ -uuid_t sb_uuid;/* fs uuid */ xfs_fsblock_t sb_logstart;/* starting log block # */ xfs_agblock_t sb_rextsize;/* realtime extent size (blocks )*/ xfs_agblock_t sb_agblocks;/* # of blocks per ag */
repair/dinode.c +4 -3
@@ -207,9 +207,9 @@ clear_dinode_core(struct xfs_mount *mp, xfs_dinode_t *dinoc, xfs_ino_t ino_num) dinoc->di_ino =cpu_to_be64 (ino_num); } -if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid)) {__dirty_no_modify_ret (dirty); -platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid); }for (i =0 ; i <sizeof (dinoc->di_pad2)/sizeof (dinoc->di_pad2[0 ]); i++) {
@@ -2287,7 +2287,8 @@ _("inode identifier %llu mismatch on inode %" PRIu64 "\n"),return 1 ; goto clear_bad_out; } -if (platform_uuid_compare (&dino->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dino->di_uuid, + &mp->m_sb.sb_meta_uuid)) {if (!uncertain)do_warn (_ ("UUID mismatch on inode %" PRIu64"\n" ), lino);
repair/phase5.c +3 -3
@@ -1119,7 +1119,7 @@ build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, agi->agi_unlinked[i] =cpu_to_be32 (NULLAGINO );if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);if (xfs_sb_version_hasfinobt (&mp->m_sb)) { agi->agi_free_root =cpu_to_be32 (finobt_curs->root);
@@ -1360,7 +1360,7 @@ build_agf_agfl(xfs_mount_t *mp,#endif if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);/* initialise the AGFL, then fill it if there are blocks left over. */ agfl_buf = libxfs_getbuf(mp->m_dev,
@@ -1374,7 +1374,7 @@ build_agf_agfl(xfs_mount_t *mp,if (xfs_sb_version_hascrc (&mp->m_sb)) { agfl->agfl_magicnum =cpu_to_be32 (XFS_AGFL_MAGIC ); agfl->agfl_seqno =cpu_to_be32 (agno); -platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);for (i =0 ; i <XFS_AGFL_SIZE (mp); i++) agfl->agfl_bno[i] =cpu_to_be32 (NULLAGBLOCK ); }
repair/phase6.c +3 -3
@@ -527,7 +527,7 @@ mk_rbmino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rbmino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
@@ -783,7 +783,7 @@ mk_rsumino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rsumino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
@@ -897,7 +897,7 @@ mk_root_dir(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rootino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 2/2] xfsprogs: Add new sb_meta_uuid field, update userspace tools to manipulate it
Quoted 17 lines · Eric Sandeen
This adds a new superblock field,
sb_meta_uuid. This allows us to change the use-visible UUID on crc-enabled filesytems from userspace if desired, by copying the existing UUID to the new location for metadata comparisons. If this is done, an incompat flag must be set to prevent older filesystems from mounting the filesystem, but the original UUID can be restored, and the incompat flag removed, with a newxfs_db/xfs_adminUUID command, "restore."Much of this patch mirrors the kernel patch in simply renaming the field used for metadata uuid comparison; other bits:
* Teach
xfs_dbto print the newmeta_uuidfield
* Allowxfs_dbto generate a new UUID for CRC-enabled filesystems
* Allowxfs_dbto revert to the original UUID and clear the flag
* Fix upxfs_copyto work with CRC-enabled filesystems
* Update thexfs_adminmanpage to show the UUID "restore" command
Quoted 8 lines
Signed-off-by Eric Sandeen <[email protected]>---
This version makes the UUID "restore" command silent if there is nothing to do.
Still open to bike-shedding on the "restore" name. Maybe "revert?"
Restore seems fine to me...
Quoted 57 lines
copy/xfs_copy.c +28
-10@@ -466,6 +466,34 @@ write_wbuf(void)sighold (SIGCHLD ); } +void +sb_update_uuid ( +xfs_sb_t *sb, +ag_header_t *ag_hdr, +thread_args *tcarg) +{ +/* +* If this filesystem has CRCs, the original UUID is stamped into +* all metadata. We need to copy the original UUID into the meta_uuid +* slot and set the incompat flag if that hasn't already been done. +*/ +if (xfs_sb_version_hascrc (sb) && !xfs_sb_version_hasmetauuid (sb)) { +__be32 feat; + + feat =be32_to_cpu (ag_hdr->xfs_sb->sb_features_incompat); + feat |=XFS_SB_FEAT_INCOMPAT_META_UUID ; + ag_hdr->xfs_sb->sb_features_incompat =cpu_to_be32 (feat); +platform_uuid_copy (&ag_hdr->xfs_sb->sb_meta_uuid, + &ag_hdr->xfs_sb->sb_uuid); + } + +platform_uuid_copy (&ag_hdr->xfs_sb->sb_uuid, &tcarg->uuid); + +/* We changed the UUID, so update the superblock CRC if needed */ +if (xfs_sb_version_hascrc (sb)) +xfs_update_cksum ((char *)&ag_hdr->xfs_sb, sb->sb_sectsize, +XFS_SB_CRC_OFF ); +}int main (int argc,char **argv)@@ -659,16 +687,6 @@ main(int argc, char **argv) sb = &mbuf.m_sb;libxfs_sb_from_disk (sb,XFS_BUF_TO_SBP (sbp)); -/* -* For now, V5 superblock filesystems are not supported without -d; -* we do not have the infrastructure yet to fix CRCs when a new UUID -* is generated. -*/ -if (xfs_sb_version_hascrc (sb) && !duplicate) { -do_log (_ ("%s: Cannot yet copy V5 fs without '-d'\n" ), progname); -exit (1 ); - } - mp =libxfs_mount (&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev,0 );if (mp ==NULL ) { do_log(_("%s: %s filesystem failed to initialize\n"
copy/xfs_copy.c main(int argc, char **argv) · line 1148
Quoted 6 lines
copy/xfs_copy.c +1
-2@@ -1127,8 +1145,7 @@ main(int argc, char **argv)/* do each thread in turn, each has its own UUID */ for (j =0 , tcarg = targ; j < num_targets; j++) { -platform_uuid_copy (&ag_hdr.xfs_sb->sb_uuid, - &tcarg->uuid); +sb_update_uuid (sb, &ag_hdr, tcarg);
xfs_copy doesn't work for me (crc=1,finobt=1)...
# ./copy/xfs_copy /dev/vdb1 /dev/vdb2 0% ... 10% ... 20% ... 30% ... 40% ... 50% ... 60% ... 70% ... 80% ... 90% ... 100%
All copies completed.
# mount /dev/vdb2 /mnt/ mount: mount /dev/vdb2 on /mnt failed: Structure needs cleaning # dmesg | tail ... [ 4145.609403] XFS (vdb2): Metadata CRC error detected at xfs_sb_read_verify+0x112/0x170 [xfs], block 0xffffffffffffffff [ 4145.611224] XFS (vdb2): Unmount and run xfs_repair [ 4145.611945] XFS (vdb2): First 64 bytes of corrupted metadata buffer: [ 4145.612873] ffff8800d8def000: 58 46 53 42 00 00 10 00 00 00 00 00 00 25 40 00 XFSB.........%@. [ 4145.615047] ffff8800d8def010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 4145.616359] ffff8800d8def020: 73 68 6d 76 a1 6d 43 96 8f 35 cb 98 2c ff fd 8d shmv.mC..5..,... [ 4145.617926] ffff8800d8def030: 00 00 00 00 00 20 00 05 00 00 00 00 00 00 00 60 ..... .........` [ 4145.619267] XFS (vdb2): SB validate failed with error -74.
The same thing occurs with -d. It looks like the crc might not have updated..?
Quoted 11 lines
copy/xfs_copy.c +0
-0do_write (tcarg); tcarg++; }db/sb.c +0
-0@@ -29,6 +29,8 @@#include "output.h" #include "init.h"
...
Quoted 4 lines
db/sb.c +0
-0@@ -388,6 +405,17 @@ uuid_f(memcpy (&uu, uup,sizeof (uuid_t));platform_uuid_unparse (&uu, bp);dbprintf (_ ("old UUID = %s\n" ), bp);
db/sb.c uuid_f( · line 417
Quoted 10 lines
db/sb.c +10
-0+ }else if (!strcasecmp (argv[1 ],"restore" )) { +xfs_sb_t tsb; + +if (!get_sb (0 , &tsb)) +return 0 ; + +/* Not set; nothing to do. Success! */ +if (!xfs_sb_version_hasmetauuid (&tsb)) +return 0 ; +
Trailing whitespace on the line above.
Brian
Quoted 728 lines
db/sb.c +3
-0+memcpy (&uu, mp->m_sb.sb_meta_uuid,sizeof (uuid_t)); }else {if (platform_uuid_parse (argv[1 ], &uu)) {dbprintf (_ ("invalid UUID\n" ));@@ -660,6 +688,8 @@ version_string(strcat (s,",CRC" );if (xfs_sb_version_hasftype (sbp))strcat (s,",FTYPE" ); +if (xfs_sb_version_hasmetauuid (sbp)) +strcat (s,",META_UUID" );return s; }libxfs/xfs_alloc.c +2
-2@@ -446,7 +446,7 @@ xfs_agfl_verify(struct xfs_agfl *agfl =XFS_BUF_TO_AGFL (bp);int i; -if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be32_to_cpu (agfl->agfl_magicnum) !=XFS_AGFL_MAGIC )return false;@@ -2199,7 +2199,7 @@ xfs_agf_verify(struct xfs_agf *agf =XFS_BUF_TO_AGF (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))return false; if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&libxfs/xfs_alloc_btree.c +2
-2@@ -293,7 +293,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTB_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;@@ -311,7 +311,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTC_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;libxfs/xfs_attr_leaf.c +2
-2@@ -258,7 +258,7 @@ xfs_attr3_leaf_verify(if (ichdr.magic !=XFS_ATTR3_LEAF_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;@@ -1052,7 +1052,7 @@ xfs_attr3_leaf_create( hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); ichdr.freemap[0 ].base =sizeof (struct xfs_attr3_leaf_hdr ); }else {libxfs/xfs_attr_remote.c +2
-2@@ -95,7 +95,7 @@ xfs_attr3_rmt_verify(return false;if (rmt->rm_magic !=cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ))return false; -if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (rmt->rm_blkno) != bno)return false;@@ -212,7 +212,7 @@ xfs_attr3_rmt_hdr_set( rmt->rm_magic =cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ); rmt->rm_offset =cpu_to_be32 (offset); rmt->rm_bytes =cpu_to_be32 (size); -uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid); rmt->rm_owner =cpu_to_be64 (ino); rmt->rm_blkno =cpu_to_be64 (bno);libxfs/xfs_bmap_btree.c +3
-2@@ -346,7 +346,8 @@ xfs_bmbt_to_bmdr(if (xfs_sb_version_hascrc (&mp->m_sb)) {ASSERT (rblock->bb_magic ==cpu_to_be32 (XFS_BMAP_CRC_MAGIC )); -ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid));ASSERT (rblock->bb_u.l.bb_blkno ==cpu_to_be64 (XFS_BUF_DADDR_NULL )); }else @@ -644,7 +645,7 @@ xfs_bmbt_verify(case cpu_to_be32 (XFS_BMAP_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (block->bb_u.l.bb_blkno) != bp->b_bn)return false;libxfs/xfs_btree.c +6
-4@@ -62,7 +62,8 @@ xfs_btree_check_lblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { lblock_ok = lblock_ok && -uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.l.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }@@ -112,7 +113,8 @@ xfs_btree_check_sblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { sblock_ok = sblock_ok && -uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.s.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.s.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }@@ -997,7 +999,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.l.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.l.bb_owner =cpu_to_be64 (owner); -uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.l.bb_pad =0 ; buf->bb_u.l.bb_lsn =0 ; }@@ -1010,7 +1012,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.s.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.s.bb_owner =cpu_to_be32 (__owner); -uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.s.bb_lsn =0 ; } }libxfs/xfs_da_btree.c +2
-2@@ -142,7 +142,7 @@ xfs_da3_node_verify(if (ichdr.magic !=XFS_DA3_NODE_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;@@ -320,7 +320,7 @@ xfs_da3_node_create( ichdr.magic =XFS_DA3_NODE_MAGIC ; hdr3->info.blkno =cpu_to_be64 (bp->b_bn); hdr3->info.owner =cpu_to_be64 (args->dp->i_ino); -uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid); }else { ichdr.magic =XFS_DA_NODE_MAGIC ; }libxfs/xfs_dir2_block.c +2
-2@@ -64,7 +64,7 @@ xfs_dir3_block_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;@@ -154,7 +154,7 @@ xfs_dir3_block_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid);return ; }libxfs/xfs_dir2_data.c +2
-2@@ -218,7 +218,7 @@ xfs_dir3_data_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_DATA_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;@@ -602,7 +602,7 @@ xfs_dir3_data_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_DATA_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); }else hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );libxfs/xfs_dir2_leaf.c +2
-2@@ -158,7 +158,7 @@ xfs_dir3_leaf_verify(if (leaf3->info.hdr.magic !=cpu_to_be16 (magic3))return false; -if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (leaf3->info.blkno) != bp->b_bn)return false;@@ -308,7 +308,7 @@ xfs_dir3_leaf_init( : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); leaf3->info.blkno =cpu_to_be64 (bp->b_bn); leaf3->info.owner =cpu_to_be64 (owner); -uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid); }else {memset (leaf,0 ,sizeof (*leaf)); leaf->hdr.info.magic =cpu_to_be16 (type);libxfs/xfs_dir2_node.c +2
-2@@ -91,7 +91,7 @@ xfs_dir3_free_verify(if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_FREE_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;@@ -224,7 +224,7 @@ xfs_dir3_free_get_buf( hdr3->hdr.blkno =cpu_to_be64 (bp->b_bn); hdr3->hdr.owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); }else hdr.magic =XFS_DIR2_FREE_MAGIC ; dp->d_ops->free_hdr_to_disk (bp->b_addr, &hdr);libxfs/xfs_dquot_buf.c +2
-2@@ -171,7 +171,7 @@ xfs_dqcheck( d->dd_diskdq.d_id =cpu_to_be32 (id);if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }@@ -206,7 +206,7 @@ xfs_dquot_buf_verify_crc(if (!xfs_verify_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ))return false; -if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_meta_uuid))return false; }return true;libxfs/xfs_format.h +19
-3@@ -100,7 +100,7 @@ typedef struct xfs_sb {xfs_rfsblock_t sb_dblocks;/* number of data blocks */ xfs_rfsblock_t sb_rblocks;/* number of realtime blocks */ xfs_rtblock_t sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ xfs_fsblock_t sb_logstart;/* starting block of log if internal */ xfs_ino_t sb_rootino;/* root inode number */ xfs_ino_t sb_rbmino;/* bitmap inode for realtime extents */ @@ -174,6 +174,7 @@ typedef struct xfs_sb {xfs_ino_t sb_pquotino;/* project quota inode */ xfs_lsn_t sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_sb_t;@@ -190,7 +191,7 @@ typedef struct xfs_dsb {__be64 sb_dblocks;/* number of data blocks */ __be64 sb_rblocks;/* number of realtime blocks */ __be64 sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ __be64 sb_logstart;/* starting block of log if internal */ __be64 sb_rootino;/* root inode number */ __be64 sb_rbmino;/* bitmap inode for realtime extents */ @@ -260,6 +261,7 @@ typedef struct xfs_dsb {__be64 sb_pquotino;/* project quota inode */ __be64 sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_dsb_t;@@ -457,8 +459,10 @@ xfs_sb_has_ro_compat_feature( }#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0)/* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 1)/* metadata UUID */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_META_UUID)#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool@@ -507,6 +511,18 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) }/* +* XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID +* is stored separately from the user-visible UUID; this allows the +* user-visible UUID to be changed on V5 filesystems which have a +* filesystem UUID stamped into every piece of metadata. +*/ +static inline int xfs_sb_version_hasmetauuid (xfs_sb_t *sbp) +{ +return (XFS_SB_VERSION_NUM (sbp) ==XFS_SB_VERSION_5 ) && + (sbp->sb_features_incompat &XFS_SB_FEAT_INCOMPAT_META_UUID ); +} + +/* * end of superblock version macros */ libxfs/xfs_ialloc.c +3
-2@@ -302,7 +302,8 @@ xfs_ialloc_inode_init(if (version ==3 ) { free->di_ino =cpu_to_be64 (ino); ino++; -uuid_copy (&free->di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&free->di_uuid, + &mp->m_sb.sb_meta_uuid);xfs_dinode_calc_crc (mp, free); }else if (tp) {/* just log the inode core */ @@ -2044,7 +2045,7 @@ xfs_agi_verify(struct xfs_agi *agi =XFS_BUF_TO_AGI (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))return false;/* * Validate the magic number of the agi block. libxfs/xfs_ialloc_btree.c +1
-1@@ -229,7 +229,7 @@ xfs_inobt_verify(case cpu_to_be32 (XFS_FIBT_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;libxfs/xfs_inode_buf.c +2
-2@@ -304,7 +304,7 @@ xfs_dinode_verify(return false;if (be64_to_cpu (dip->di_ino) != ino)return false; -if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_meta_uuid))return false;return true; }@@ -366,7 +366,7 @@ xfs_iread(if (xfs_sb_version_hascrc (&mp->m_sb)) { ip->i_d.di_version =3 ; ip->i_d.di_ino = ip->i_ino; -uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); }else ip->i_d.di_version =2 ;return 0 ;libxfs/xfs_sb.c +15
-0@@ -360,6 +360,17 @@ __xfs_sb_from_disk( to->sb_pad =0 ; to->sb_pquotino =be64_to_cpu (from->sb_pquotino); to->sb_lsn =be64_to_cpu (from->sb_lsn); +/* +* sb_meta_uuid is only on disk if it differs from sb_uuid and the +* feature flag is set; if not set we keep it only in memory. +*/ +if (xfs_sb_version_hasmetauuid (to)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + }else { +memcpy (&to->sb_meta_uuid, &from->sb_uuid, +sizeof (to->sb_meta_uuid)); + }/* Convert on-disk flags to in-memory flags? */ if (convert_xquota)xfs_sb_quota_from_disk (to);@@ -501,6 +512,10 @@ xfs_sb_to_disk(cpu_to_be32 (from->sb_features_log_incompat); to->sb_pad =0 ; to->sb_lsn =cpu_to_be64 (from->sb_lsn); +if (xfs_sb_version_hasmetauuid (from)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + } } }libxfs/xfs_symlink_remote.c +2
-2@@ -60,7 +60,7 @@ xfs_symlink_hdr_set( dsl->sl_magic =cpu_to_be32 (XFS_SYMLINK_MAGIC ); dsl->sl_offset =cpu_to_be32 (offset); dsl->sl_bytes =cpu_to_be32 (size); -uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid); dsl->sl_owner =cpu_to_be64 (ino); dsl->sl_blkno =cpu_to_be64 (bp->b_bn); bp->b_ops = &xfs_symlink_buf_ops;@@ -104,7 +104,7 @@ xfs_symlink_verify(return false;if (dsl->sl_magic !=cpu_to_be32 (XFS_SYMLINK_MAGIC ))return false; -if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (bp->b_bn !=be64_to_cpu (dsl->sl_blkno))return false;libxlog/util.c +4
-2@@ -29,8 +29,10 @@ header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head) {char uu_log[64 ], uu_sb[64 ]; -if (print_skip_uuid)return 0 ; -if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid))return 0 ; +if (print_skip_uuid) +return 0 ; +if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) +return 0 ;platform_uuid_unparse (&mp->m_sb.sb_uuid, uu_sb);platform_uuid_unparse (&head->h_fs_uuid, uu_log);man/man8/xfs_admin.8 +6
-1@@ -98,7 +98,12 @@ The .I uuid may also be .BR generate , -which will generate a new UUID for the filesystem. +which will generate a new UUID for the filesystem. Note that on CRC-enabled +filesystems, this will set an incompatible flag such that older kernels will +not be able to mount the filesystem. To remove this incompatible flag, use +.BR restore , +which will restore the original UUID and remove the incompatible +feature flag as needed. .TP .B \-V Prints the version number and exits.man/man8/xfs_db.8 +7
-2@@ -664,7 +664,7 @@ The possible data types are: .BR sb ", " symlink " and " text . See the TYPES section below for more information on these data types. .TP -.BI "uuid [" uuid " | " generate " | " rewrite ] +.BI "uuid [" uuid " | " generate " | " rewrite " | " restore ] Set the filesystem universally unique identifier (UUID). The filesystem UUID can be used by .BR mount (8)@@ -675,7 +675,12 @@ can be set directly to the desired UUID, or it can be automatically generated using the .B generate option. These options will both write the UUID into every copy of the -superblock in the filesystem. +superblock in the filesystem. On a CRC-enabled filesystem, this will +set an incompatible superblock flag, and the filesystem will not be +mountable with older kernels. This can be reverted with the +.B restore +option, which will copy the original UUID back into place and clear +the incompatible flag as needed. .B rewrite copies the current UUID from the primary superblock to all secondary copies of the superblock.mkfs/xfs_mkfs.c +2
-0@@ -2598,6 +2598,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), sbp->sb_rextents = rtextents;platform_uuid_generate (&uuid);platform_uuid_copy (&sbp->sb_uuid, &uuid); +/* Only in memory; libxfs expects this as if read from disk */ +platform_uuid_copy (&sbp->sb_meta_uuid, &uuid); sbp->sb_logstart = logstart; sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino =NULLFSINO ; sbp->sb_rextsize = rtextblocks;repair/agheader.c +12
-7@@ -112,7 +112,7 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGF ;@@ -120,7 +120,8 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)do_warn (_ ("bad uuid %s for agf %d\n" ), uu, i);if (!no_modify) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, + &mp->m_sb.sb_meta_uuid); }return retval; }@@ -190,7 +191,7 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGI ;@@ -198,7 +199,8 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)do_warn (_ ("bad uuid %s for agi %d\n" ), uu, agno);if (!no_modify) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, + &mp->m_sb.sb_meta_uuid); }return retval;@@ -245,7 +247,7 @@ compare_sb(xfs_mount_t *mp, xfs_sb_t *sb)* superblocks, not just the secondary superblocks. */ static int -secondary_sb_wack( +secondary_sb_whack( struct xfs_mount *mp, struct xfs_buf *sbuf, struct xfs_sb *sb,@@ -267,7 +269,10 @@ secondary_sb_wack(* * size is the size of data which is valid for this sb. */ -if (xfs_sb_version_hascrc (sb)) +if (xfs_sb_version_hasmetauuid (sb)) + size = offsetof(xfs_sb_t , sb_meta_uuid) + +sizeof (sb->sb_meta_uuid); +else if (xfs_sb_version_hascrc (sb)) size = offsetof(xfs_sb_t , sb_lsn) +sizeof (sb->sb_lsn);else if (xfs_sb_version_hasmorebits (sb))@@ -511,7 +516,7 @@ verify_set_agheader(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, rval |=XR_AG_SB ; } - rval |=secondary_sb_wack (mp, sbuf, sb, i); + rval |=secondary_sb_whack (mp, sbuf, sb, i); rval |=verify_set_agf (mp, agf, i); rval |=verify_set_agi (mp, agi, i);repair/agheader.h +0
-1@@ -24,7 +24,6 @@ typedef struct fs_geometry {xfs_rfsblock_t sb_dblocks;/* # data blocks */ xfs_rfsblock_t sb_rblocks;/* # realtime blocks */ xfs_rtblock_t sb_rextents;/* # realtime extents */ -uuid_t sb_uuid;/* fs uuid */ xfs_fsblock_t sb_logstart;/* starting log block # */ xfs_agblock_t sb_rextsize;/* realtime extent size (blocks )*/ xfs_agblock_t sb_agblocks;/* # of blocks per ag */ repair/dinode.c +4
-3@@ -207,9 +207,9 @@ clear_dinode_core(struct xfs_mount *mp, xfs_dinode_t *dinoc, xfs_ino_t ino_num) dinoc->di_ino =cpu_to_be64 (ino_num); } -if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid)) {__dirty_no_modify_ret (dirty); -platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid); }for (i =0 ; i <sizeof (dinoc->di_pad2)/sizeof (dinoc->di_pad2[0 ]); i++) {@@ -2287,7 +2287,8 @@ _("inode identifier %llu mismatch on inode %" PRIu64 "\n"),return 1 ; goto clear_bad_out; } -if (platform_uuid_compare (&dino->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dino->di_uuid, + &mp->m_sb.sb_meta_uuid)) {if (!uncertain)do_warn (_ ("UUID mismatch on inode %" PRIu64"\n" ), lino);repair/phase5.c +3
-3@@ -1119,7 +1119,7 @@ build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, agi->agi_unlinked[i] =cpu_to_be32 (NULLAGINO );if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);if (xfs_sb_version_hasfinobt (&mp->m_sb)) { agi->agi_free_root =cpu_to_be32 (finobt_curs->root);@@ -1360,7 +1360,7 @@ build_agf_agfl(xfs_mount_t *mp,#endif if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);/* initialise the AGFL, then fill it if there are blocks left over. */ agfl_buf = libxfs_getbuf(mp->m_dev,@@ -1374,7 +1374,7 @@ build_agf_agfl(xfs_mount_t *mp,if (xfs_sb_version_hascrc (&mp->m_sb)) { agfl->agfl_magicnum =cpu_to_be32 (XFS_AGFL_MAGIC ); agfl->agfl_seqno =cpu_to_be32 (agno); -platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);for (i =0 ; i <XFS_AGFL_SIZE (mp); i++) agfl->agfl_bno[i] =cpu_to_be32 (NULLAGBLOCK ); }repair/phase6.c +3
-3@@ -527,7 +527,7 @@ mk_rbmino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rbmino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);@@ -783,7 +783,7 @@ mk_rsumino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rsumino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);@@ -897,7 +897,7 @@ mk_root_dir(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rootino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 2/2] xfsprogs: Add new sb_meta_uuid field, update userspace tools to manipulate it
Quoted 84 lines · Brian Foster
Quoted 17 lines · Eric Sandeen
This adds a new superblock field,
sb_meta_uuid. This allows us to change the use-visible UUID on crc-enabled filesytems from userspace if desired, by copying the existing UUID to the new location for metadata comparisons. If this is done, an incompat flag must be set to prevent older filesystems from mounting the filesystem, but the original UUID can be restored, and the incompat flag removed, with a newxfs_db/xfs_adminUUID command, "restore."Much of this patch mirrors the kernel patch in simply renaming the field used for metadata uuid comparison; other bits:
* Teach
xfs_dbto print the newmeta_uuidfield
* Allowxfs_dbto generate a new UUID for CRC-enabled filesystems
* Allowxfs_dbto revert to the original UUID and clear the flag
* Fix upxfs_copyto work with CRC-enabled filesystems
* Update thexfs_adminmanpage to show the UUID "restore" commandQuoted 8 lines
Signed-off-by Eric Sandeen <[email protected]>---
This version makes the UUID "restore" command silent if there is nothing to do.
Still open to bike-shedding on the "restore" name. Maybe "revert?"
Restore seems fine to me...
Quoted 25 lines
copy/xfs_copy.c +17
-0@@ -466,6 +466,34 @@ write_wbuf(void)sighold (SIGCHLD ); } +void +sb_update_uuid ( +xfs_sb_t *sb, +ag_header_t *ag_hdr, +thread_args *tcarg) +{ +/* +* If this filesystem has CRCs, the original UUID is stamped into +* all metadata. We need to copy the original UUID into the meta_uuid +* slot and set the incompat flag if that hasn't already been done. +*/ +if (xfs_sb_version_hascrc (sb) && !xfs_sb_version_hasmetauuid (sb)) { +__be32 feat; + + feat =be32_to_cpu (ag_hdr->xfs_sb->sb_features_incompat); + feat |=XFS_SB_FEAT_INCOMPAT_META_UUID ; + ag_hdr->xfs_sb->sb_features_incompat =cpu_to_be32 (feat);copy/xfs_copy.c write_wbuf(void) · line 495
Quoted 10 lines
copy/xfs_copy.c +10
-0+platform_uuid_copy (&ag_hdr->xfs_sb->sb_meta_uuid, + &ag_hdr->xfs_sb->sb_uuid); + } + +platform_uuid_copy (&ag_hdr->xfs_sb->sb_uuid, &tcarg->uuid); + +/* We changed the UUID, so update the superblock CRC if needed */ +if (xfs_sb_version_hascrc (sb)) +xfs_update_cksum ((char *)&ag_hdr->xfs_sb, sb->sb_sectsize, +XFS_SB_CRC_OFF );
xfs_copydoesn't work for me (crc=1,finobt=1)...# ./copy/xfs_copy /dev/vdb1 /dev/vdb2 0% ... 10% ... 20% ... 30% ... 40% ... 50% ... 60% ... 70% ... 80% ... 90% ... 100%All copies completed.
# mount /dev/vdb2 /mnt/ mount: mount /dev/vdb2 on /mnt failed: Structure needs cleaning # dmesg | tail ... [ 4145.609403] XFS (vdb2): Metadata CRC error detected at xfs_sb_read_verify+0x112/0x170 [xfs], block 0xffffffffffffffff [ 4145.611224] XFS (vdb2): Unmount and run xfs_repair [ 4145.611945] XFS (vdb2): First 64 bytes of corrupted metadata buffer: [ 4145.612873] ffff8800d8def000: 58 46 53 42 00 00 10 00 00 00 00 00 00 25 40 00 XFSB.........%@. [ 4145.615047] ffff8800d8def010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 4145.616359] ffff8800d8def020: 73 68 6d 76 a1 6d 43 96 8f 35 cb 98 2c ff fd 8d shmv.mC..5..,... [ 4145.617926] ffff8800d8def030: 00 00 00 00 00 20 00 05 00 00 00 00 00 00 00 60 ..... .........` [ 4145.619267] XFS (vdb2): SB validate failed with error -74.
Quoted 2 lines
The same thing occurs with -d. It looks like the crc might not have updated..?
yeargh,
- xfs_update_cksum((char *)&ag_hdr->xfs_sb, sb->sb_sectsize,
+ xfs_update_cksum((char *)ag_hdr->xfs_sb, sb->sb_sectsize,
will fix up, test harder, and resend :(
-Eric
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v4 2/2 xfsprogs: Add new sb_meta_uuid field, update userspace tools to manipulate it
In reply to Eric SandeenThis adds a new superblock field, sb_meta_uuid. This allows us to change the use-visible UUID on crc-enabled filesytems from userspace if desired, by copying the existing UUID to the new location for metadata comparisons. If this is done, an incompat flag must be set to prevent older filesystems from mounting the filesystem, but the original UUID can be restored, and the incompat flag removed, with a new xfs_db / xfs_admin UUID command, "restore."
Much of this patch mirrors the kernel patch in simply renaming the field used for metadata uuid comparison; other bits:
* Teach xfs_db to print the new meta_uuid field
* Allow xfs_db to generate a new UUID for CRC-enabled filesystems
* Allow xfs_db to revert to the original UUID and clear the flag
* Fix up xfs_copy to work with CRC-enabled filesystems
* Update the xfs_admin manpage to show the UUID "restore" command
---
This version makes the UUID "restore" command silent if there is nothing to do.
Also removed an errant "&" in xfs_copy, which was making the checksum update fail. :(
And don't set the META_UUID flag in xfs_copy if the UUID we are writing is the same as the original.
copy/xfs_copy.c +32 -12
@@ -466,6 +466,37 @@ write_wbuf(void)sighold (SIGCHLD ); } +void +sb_update_uuid ( +xfs_sb_t *sb, +ag_header_t *ag_hdr, +thread_args *tcarg) +{ +/* +* If this filesystem has CRCs, the original UUID is stamped into +* all metadata. If the new UUID is different, We need to copy the +* original UUID into the meta_uuid slot and set the incompat flag +* if that hasn't already been done. +*/ +if (xfs_sb_version_hascrc (sb) && +platform_uuid_compare (&tcarg->uuid, &ag_hdr->xfs_sb->sb_uuid) && + !xfs_sb_version_hasmetauuid (sb)) { +__be32 feat; + + feat =be32_to_cpu (ag_hdr->xfs_sb->sb_features_incompat); + feat |=XFS_SB_FEAT_INCOMPAT_META_UUID ; + ag_hdr->xfs_sb->sb_features_incompat =cpu_to_be32 (feat); +platform_uuid_copy (&ag_hdr->xfs_sb->sb_meta_uuid, + &ag_hdr->xfs_sb->sb_uuid); + } + +platform_uuid_copy (&ag_hdr->xfs_sb->sb_uuid, &tcarg->uuid); + +/* We might have changed the UUID, so update the superblock CRC */ +if (xfs_sb_version_hascrc (sb)) +xfs_update_cksum ((char *)ag_hdr->xfs_sb, sb->sb_sectsize, +XFS_SB_CRC_OFF ); +}int main (int argc,char **argv)
@@ -659,16 +690,6 @@ main(int argc, char **argv) sb = &mbuf.m_sb;libxfs_sb_from_disk (sb,XFS_BUF_TO_SBP (sbp)); -/* -* For now, V5 superblock filesystems are not supported without -d; -* we do not have the infrastructure yet to fix CRCs when a new UUID -* is generated. -*/ -if (xfs_sb_version_hascrc (sb) && !duplicate) { -do_log (_ ("%s: Cannot yet copy V5 fs without '-d'\n" ), progname); -exit (1 ); - } - mp =libxfs_mount (&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev,0 );if (mp ==NULL ) { do_log(_("%s: %s filesystem failed to initialize\n"
@@ -1127,8 +1148,7 @@ main(int argc, char **argv)/* do each thread in turn, each has its own UUID */ for (j =0 , tcarg = targ; j < num_targets; j++) { -platform_uuid_copy (&ag_hdr.xfs_sb->sb_uuid, - &tcarg->uuid); +sb_update_uuid (sb, &ag_hdr, tcarg);do_write (tcarg); tcarg++; }
db/sb.c +42 -12
90 lines not on this page · raw message
libxfs/xfs_alloc.c +2 -2
@@ -446,7 +446,7 @@ xfs_agfl_verify(struct xfs_agfl *agfl =XFS_BUF_TO_AGFL (bp);int i; -if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be32_to_cpu (agfl->agfl_magicnum) !=XFS_AGFL_MAGIC )return false;
@@ -2199,7 +2199,7 @@ xfs_agf_verify(struct xfs_agf *agf =XFS_BUF_TO_AGF (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))return false; if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
libxfs/xfs_alloc_btree.c +2 -2
@@ -293,7 +293,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTB_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
@@ -311,7 +311,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTC_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
libxfs/xfs_attr_leaf.c +2 -2
@@ -258,7 +258,7 @@ xfs_attr3_leaf_verify(if (ichdr.magic !=XFS_ATTR3_LEAF_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -1052,7 +1052,7 @@ xfs_attr3_leaf_create( hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); ichdr.freemap[0 ].base =sizeof (struct xfs_attr3_leaf_hdr ); }else {
libxfs/xfs_attr_remote.c +2 -2
@@ -95,7 +95,7 @@ xfs_attr3_rmt_verify(return false;if (rmt->rm_magic !=cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ))return false; -if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (rmt->rm_blkno) != bno)return false;
@@ -212,7 +212,7 @@ xfs_attr3_rmt_hdr_set( rmt->rm_magic =cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ); rmt->rm_offset =cpu_to_be32 (offset); rmt->rm_bytes =cpu_to_be32 (size); -uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid); rmt->rm_owner =cpu_to_be64 (ino); rmt->rm_blkno =cpu_to_be64 (bno);
libxfs/xfs_bmap_btree.c +3 -2
@@ -346,7 +346,8 @@ xfs_bmbt_to_bmdr(if (xfs_sb_version_hascrc (&mp->m_sb)) {ASSERT (rblock->bb_magic ==cpu_to_be32 (XFS_BMAP_CRC_MAGIC )); -ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid));ASSERT (rblock->bb_u.l.bb_blkno ==cpu_to_be64 (XFS_BUF_DADDR_NULL )); }else
@@ -644,7 +645,7 @@ xfs_bmbt_verify(case cpu_to_be32 (XFS_BMAP_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (block->bb_u.l.bb_blkno) != bp->b_bn)return false;
libxfs/xfs_btree.c +6 -4
@@ -62,7 +62,8 @@ xfs_btree_check_lblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { lblock_ok = lblock_ok && -uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.l.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -112,7 +113,8 @@ xfs_btree_check_sblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { sblock_ok = sblock_ok && -uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.s.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.s.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -997,7 +999,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.l.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.l.bb_owner =cpu_to_be64 (owner); -uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.l.bb_pad =0 ; buf->bb_u.l.bb_lsn =0 ; }
@@ -1010,7 +1012,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.s.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.s.bb_owner =cpu_to_be32 (__owner); -uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.s.bb_lsn =0 ; } }
libxfs/xfs_da_btree.c +2 -2
@@ -142,7 +142,7 @@ xfs_da3_node_verify(if (ichdr.magic !=XFS_DA3_NODE_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -320,7 +320,7 @@ xfs_da3_node_create( ichdr.magic =XFS_DA3_NODE_MAGIC ; hdr3->info.blkno =cpu_to_be64 (bp->b_bn); hdr3->info.owner =cpu_to_be64 (args->dp->i_ino); -uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid); }else { ichdr.magic =XFS_DA_NODE_MAGIC ; }
libxfs/xfs_dir2_block.c +2 -2
@@ -64,7 +64,7 @@ xfs_dir3_block_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -154,7 +154,7 @@ xfs_dir3_block_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid);return ; }
libxfs/xfs_dir2_data.c +2 -2
@@ -218,7 +218,7 @@ xfs_dir3_data_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_DATA_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -602,7 +602,7 @@ xfs_dir3_data_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_DATA_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); }else hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );
libxfs/xfs_dir2_leaf.c +2 -2
@@ -158,7 +158,7 @@ xfs_dir3_leaf_verify(if (leaf3->info.hdr.magic !=cpu_to_be16 (magic3))return false; -if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (leaf3->info.blkno) != bp->b_bn)return false;
@@ -308,7 +308,7 @@ xfs_dir3_leaf_init( : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); leaf3->info.blkno =cpu_to_be64 (bp->b_bn); leaf3->info.owner =cpu_to_be64 (owner); -uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid); }else {memset (leaf,0 ,sizeof (*leaf)); leaf->hdr.info.magic =cpu_to_be16 (type);
libxfs/xfs_dir2_node.c +2 -2
@@ -91,7 +91,7 @@ xfs_dir3_free_verify(if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_FREE_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -224,7 +224,7 @@ xfs_dir3_free_get_buf( hdr3->hdr.blkno =cpu_to_be64 (bp->b_bn); hdr3->hdr.owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); }else hdr.magic =XFS_DIR2_FREE_MAGIC ; dp->d_ops->free_hdr_to_disk (bp->b_addr, &hdr);
libxfs/xfs_dquot_buf.c +2 -2
@@ -171,7 +171,7 @@ xfs_dqcheck( d->dd_diskdq.d_id =cpu_to_be32 (id);if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }
@@ -206,7 +206,7 @@ xfs_dquot_buf_verify_crc(if (!xfs_verify_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ))return false; -if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_meta_uuid))return false; }return true;
libxfs/xfs_format.h +19 -3
@@ -100,7 +100,7 @@ typedef struct xfs_sb {xfs_rfsblock_t sb_dblocks;/* number of data blocks */ xfs_rfsblock_t sb_rblocks;/* number of realtime blocks */ xfs_rtblock_t sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ xfs_fsblock_t sb_logstart;/* starting block of log if internal */ xfs_ino_t sb_rootino;/* root inode number */ xfs_ino_t sb_rbmino;/* bitmap inode for realtime extents */
@@ -174,6 +174,7 @@ typedef struct xfs_sb {xfs_ino_t sb_pquotino;/* project quota inode */ xfs_lsn_t sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_sb_t;
@@ -190,7 +191,7 @@ typedef struct xfs_dsb {__be64 sb_dblocks;/* number of data blocks */ __be64 sb_rblocks;/* number of realtime blocks */ __be64 sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ __be64 sb_logstart;/* starting block of log if internal */ __be64 sb_rootino;/* root inode number */ __be64 sb_rbmino;/* bitmap inode for realtime extents */
@@ -260,6 +261,7 @@ typedef struct xfs_dsb {__be64 sb_pquotino;/* project quota inode */ __be64 sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_dsb_t;
@@ -457,8 +459,10 @@ xfs_sb_has_ro_compat_feature( }#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0)/* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 1)/* metadata UUID */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_META_UUID)#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool
@@ -507,6 +511,18 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) }/* +* XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID +* is stored separately from the user-visible UUID; this allows the +* user-visible UUID to be changed on V5 filesystems which have a +* filesystem UUID stamped into every piece of metadata. +*/ +static inline int xfs_sb_version_hasmetauuid (xfs_sb_t *sbp) +{ +return (XFS_SB_VERSION_NUM (sbp) ==XFS_SB_VERSION_5 ) && + (sbp->sb_features_incompat &XFS_SB_FEAT_INCOMPAT_META_UUID ); +} + +/* * end of superblock version macros */
libxfs/xfs_ialloc.c +3 -2
@@ -302,7 +302,8 @@ xfs_ialloc_inode_init(if (version ==3 ) { free->di_ino =cpu_to_be64 (ino); ino++; -uuid_copy (&free->di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&free->di_uuid, + &mp->m_sb.sb_meta_uuid);xfs_dinode_calc_crc (mp, free); }else if (tp) {/* just log the inode core */
@@ -2044,7 +2045,7 @@ xfs_agi_verify(struct xfs_agi *agi =XFS_BUF_TO_AGI (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))return false;/* * Validate the magic number of the agi block.
libxfs/xfs_ialloc_btree.c +1 -1
@@ -229,7 +229,7 @@ xfs_inobt_verify(case cpu_to_be32 (XFS_FIBT_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
libxfs/xfs_inode_buf.c +2 -2
@@ -304,7 +304,7 @@ xfs_dinode_verify(return false;if (be64_to_cpu (dip->di_ino) != ino)return false; -if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_meta_uuid))return false;return true; }
@@ -366,7 +366,7 @@ xfs_iread(if (xfs_sb_version_hascrc (&mp->m_sb)) { ip->i_d.di_version =3 ; ip->i_d.di_ino = ip->i_ino; -uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); }else ip->i_d.di_version =2 ;return 0 ;
libxfs/xfs_sb.c +15 -0
@@ -360,6 +360,17 @@ __xfs_sb_from_disk( to->sb_pad =0 ; to->sb_pquotino =be64_to_cpu (from->sb_pquotino); to->sb_lsn =be64_to_cpu (from->sb_lsn); +/* +* sb_meta_uuid is only on disk if it differs from sb_uuid and the +* feature flag is set; if not set we keep it only in memory. +*/ +if (xfs_sb_version_hasmetauuid (to)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + }else { +memcpy (&to->sb_meta_uuid, &from->sb_uuid, +sizeof (to->sb_meta_uuid)); + }/* Convert on-disk flags to in-memory flags? */ if (convert_xquota)xfs_sb_quota_from_disk (to);
@@ -501,6 +512,10 @@ xfs_sb_to_disk(cpu_to_be32 (from->sb_features_log_incompat); to->sb_pad =0 ; to->sb_lsn =cpu_to_be64 (from->sb_lsn); +if (xfs_sb_version_hasmetauuid (from)) { +memcpy (&to->sb_meta_uuid, &from->sb_meta_uuid, +sizeof (to->sb_meta_uuid)); + } } }
libxfs/xfs_symlink_remote.c +2 -2
@@ -60,7 +60,7 @@ xfs_symlink_hdr_set( dsl->sl_magic =cpu_to_be32 (XFS_SYMLINK_MAGIC ); dsl->sl_offset =cpu_to_be32 (offset); dsl->sl_bytes =cpu_to_be32 (size); -uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid); dsl->sl_owner =cpu_to_be64 (ino); dsl->sl_blkno =cpu_to_be64 (bp->b_bn); bp->b_ops = &xfs_symlink_buf_ops;
@@ -104,7 +104,7 @@ xfs_symlink_verify(return false;if (dsl->sl_magic !=cpu_to_be32 (XFS_SYMLINK_MAGIC ))return false; -if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (bp->b_bn !=be64_to_cpu (dsl->sl_blkno))return false;
libxlog/util.c +4 -2
@@ -29,8 +29,10 @@ header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head) {char uu_log[64 ], uu_sb[64 ]; -if (print_skip_uuid)return 0 ; -if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid))return 0 ; +if (print_skip_uuid) +return 0 ; +if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) +return 0 ;platform_uuid_unparse (&mp->m_sb.sb_uuid, uu_sb);platform_uuid_unparse (&head->h_fs_uuid, uu_log);
man/man8/xfs_admin.8 +6 -1
@@ -98,7 +98,12 @@ The .I uuid may also be .BR generate , -which will generate a new UUID for the filesystem. +which will generate a new UUID for the filesystem. Note that on CRC-enabled +filesystems, this will set an incompatible flag such that older kernels will +not be able to mount the filesystem. To remove this incompatible flag, use +.BR restore , +which will restore the original UUID and remove the incompatible +feature flag as needed. .TP .B \-V Prints the version number and exits.
man/man8/xfs_db.8 +7 -2
@@ -664,7 +664,7 @@ The possible data types are: .BR sb ", " symlink " and " text . See the TYPES section below for more information on these data types. .TP -.BI "uuid [" uuid " | " generate " | " rewrite ] +.BI "uuid [" uuid " | " generate " | " rewrite " | " restore ] Set the filesystem universally unique identifier (UUID). The filesystem UUID can be used by .BR mount (8)
@@ -675,7 +675,12 @@ can be set directly to the desired UUID, or it can be automatically generated using the .B generate option. These options will both write the UUID into every copy of the -superblock in the filesystem. +superblock in the filesystem. On a CRC-enabled filesystem, this will +set an incompatible superblock flag, and the filesystem will not be +mountable with older kernels. This can be reverted with the +.B restore +option, which will copy the original UUID back into place and clear +the incompatible flag as needed. .B rewrite copies the current UUID from the primary superblock to all secondary copies of the superblock.
mkfs/xfs_mkfs.c +2 -0
@@ -2598,6 +2598,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), sbp->sb_rextents = rtextents;platform_uuid_generate (&uuid);platform_uuid_copy (&sbp->sb_uuid, &uuid); +/* Only in memory; libxfs expects this as if read from disk */ +platform_uuid_copy (&sbp->sb_meta_uuid, &uuid); sbp->sb_logstart = logstart; sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino =NULLFSINO ; sbp->sb_rextsize = rtextblocks;
repair/agheader.c +12 -7
@@ -112,7 +112,7 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGF ;
@@ -120,7 +120,8 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)do_warn (_ ("bad uuid %s for agf %d\n" ), uu, i);if (!no_modify) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, + &mp->m_sb.sb_meta_uuid); }return retval; }
@@ -190,7 +191,7 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGI ;
@@ -198,7 +199,8 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)do_warn (_ ("bad uuid %s for agi %d\n" ), uu, agno);if (!no_modify) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, + &mp->m_sb.sb_meta_uuid); }return retval;
@@ -245,7 +247,7 @@ compare_sb(xfs_mount_t *mp, xfs_sb_t *sb)* superblocks, not just the secondary superblocks. */ static int -secondary_sb_wack( +secondary_sb_whack( struct xfs_mount *mp, struct xfs_buf *sbuf, struct xfs_sb *sb,
@@ -267,7 +269,10 @@ secondary_sb_wack(* * size is the size of data which is valid for this sb. */ -if (xfs_sb_version_hascrc (sb)) +if (xfs_sb_version_hasmetauuid (sb)) + size = offsetof(xfs_sb_t , sb_meta_uuid) + +sizeof (sb->sb_meta_uuid); +else if (xfs_sb_version_hascrc (sb)) size = offsetof(xfs_sb_t , sb_lsn) +sizeof (sb->sb_lsn);else if (xfs_sb_version_hasmorebits (sb))
@@ -511,7 +516,7 @@ verify_set_agheader(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, rval |=XR_AG_SB ; } - rval |=secondary_sb_wack (mp, sbuf, sb, i); + rval |=secondary_sb_whack (mp, sbuf, sb, i); rval |=verify_set_agf (mp, agf, i); rval |=verify_set_agi (mp, agi, i);
repair/agheader.h +0 -1
@@ -24,7 +24,6 @@ typedef struct fs_geometry {xfs_rfsblock_t sb_dblocks;/* # data blocks */ xfs_rfsblock_t sb_rblocks;/* # realtime blocks */ xfs_rtblock_t sb_rextents;/* # realtime extents */ -uuid_t sb_uuid;/* fs uuid */ xfs_fsblock_t sb_logstart;/* starting log block # */ xfs_agblock_t sb_rextsize;/* realtime extent size (blocks )*/ xfs_agblock_t sb_agblocks;/* # of blocks per ag */
repair/dinode.c +4 -3
@@ -207,9 +207,9 @@ clear_dinode_core(struct xfs_mount *mp, xfs_dinode_t *dinoc, xfs_ino_t ino_num) dinoc->di_ino =cpu_to_be64 (ino_num); } -if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid)) {__dirty_no_modify_ret (dirty); -platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid); }for (i =0 ; i <sizeof (dinoc->di_pad2)/sizeof (dinoc->di_pad2[0 ]); i++) {
@@ -2287,7 +2287,8 @@ _("inode identifier %llu mismatch on inode %" PRIu64 "\n"),return 1 ; goto clear_bad_out; } -if (platform_uuid_compare (&dino->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dino->di_uuid, + &mp->m_sb.sb_meta_uuid)) {if (!uncertain)do_warn (_ ("UUID mismatch on inode %" PRIu64"\n" ), lino);
repair/phase5.c +3 -3
@@ -1119,7 +1119,7 @@ build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, agi->agi_unlinked[i] =cpu_to_be32 (NULLAGINO );if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);if (xfs_sb_version_hasfinobt (&mp->m_sb)) { agi->agi_free_root =cpu_to_be32 (finobt_curs->root);
@@ -1360,7 +1360,7 @@ build_agf_agfl(xfs_mount_t *mp,#endif if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);/* initialise the AGFL, then fill it if there are blocks left over. */ agfl_buf = libxfs_getbuf(mp->m_dev,
@@ -1374,7 +1374,7 @@ build_agf_agfl(xfs_mount_t *mp,if (xfs_sb_version_hascrc (&mp->m_sb)) { agfl->agfl_magicnum =cpu_to_be32 (XFS_AGFL_MAGIC ); agfl->agfl_seqno =cpu_to_be32 (agno); -platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);for (i =0 ; i <XFS_AGFL_SIZE (mp); i++) agfl->agfl_bno[i] =cpu_to_be32 (NULLAGBLOCK ); }
repair/phase6.c +3 -3
@@ -527,7 +527,7 @@ mk_rbmino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rbmino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
@@ -783,7 +783,7 @@ mk_rsumino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rsumino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
@@ -897,7 +897,7 @@ mk_root_dir(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rootino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 2/2 xfsprogs: Add new sb_meta_uuid field, update userspace tools to manipulate it
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.
---
V5: bools and structs and xfs_copy()s to match kernelspace...
copy/xfs_copy.c +32 -12
@@ -466,6 +466,37 @@ write_wbuf(void)sighold (SIGCHLD ); } +void +sb_update_uuid ( +xfs_sb_t *sb, +ag_header_t *ag_hdr, +thread_args *tcarg) +{ +/* +* If this filesystem has CRCs, the original UUID is stamped into +* all metadata. If the new UUID is different, We need to copy the +* original UUID into the meta_uuid slot and set the incompat flag +* if that hasn't already been done. +*/ +if (xfs_sb_version_hascrc (sb) && +platform_uuid_compare (&tcarg->uuid, &ag_hdr->xfs_sb->sb_uuid) && + !xfs_sb_version_hasmetauuid (sb)) { +__be32 feat; + + feat =be32_to_cpu (ag_hdr->xfs_sb->sb_features_incompat); + feat |=XFS_SB_FEAT_INCOMPAT_META_UUID ; + ag_hdr->xfs_sb->sb_features_incompat =cpu_to_be32 (feat); +platform_uuid_copy (&ag_hdr->xfs_sb->sb_meta_uuid, + &ag_hdr->xfs_sb->sb_uuid); + } + +platform_uuid_copy (&ag_hdr->xfs_sb->sb_uuid, &tcarg->uuid); + +/* We might have changed the UUID, so update the superblock CRC */ +if (xfs_sb_version_hascrc (sb)) +xfs_update_cksum ((char *)ag_hdr->xfs_sb, sb->sb_sectsize, +XFS_SB_CRC_OFF ); +}int main (int argc,char **argv)
@@ -659,16 +690,6 @@ main(int argc, char **argv) sb = &mbuf.m_sb;libxfs_sb_from_disk (sb,XFS_BUF_TO_SBP (sbp)); -/* -* For now, V5 superblock filesystems are not supported without -d; -* we do not have the infrastructure yet to fix CRCs when a new UUID -* is generated. -*/ -if (xfs_sb_version_hascrc (sb) && !duplicate) { -do_log (_ ("%s: Cannot yet copy V5 fs without '-d'\n" ), progname); -exit (1 ); - } - mp =libxfs_mount (&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev,0 );if (mp ==NULL ) { do_log(_("%s: %s filesystem failed to initialize\n"
@@ -1127,8 +1148,7 @@ main(int argc, char **argv)/* do each thread in turn, each has its own UUID */ for (j =0 , tcarg = targ; j < num_targets; j++) { -platform_uuid_copy (&ag_hdr.xfs_sb->sb_uuid, - &tcarg->uuid); +sb_update_uuid (sb, &ag_hdr, tcarg);do_write (tcarg); tcarg++; }
db/sb.c +42 -12
90 lines not on this page · raw message
libxfs/xfs_alloc.c +2 -2
@@ -446,7 +446,7 @@ xfs_agfl_verify(struct xfs_agfl *agfl =XFS_BUF_TO_AGFL (bp);int i; -if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be32_to_cpu (agfl->agfl_magicnum) !=XFS_AGFL_MAGIC )return false;
@@ -2199,7 +2199,7 @@ xfs_agf_verify(struct xfs_agf *agf =XFS_BUF_TO_AGF (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))return false; if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
libxfs/xfs_alloc_btree.c +2 -2
@@ -293,7 +293,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTB_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
@@ -311,7 +311,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTC_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
libxfs/xfs_attr_leaf.c +2 -2
@@ -258,7 +258,7 @@ xfs_attr3_leaf_verify(if (ichdr.magic !=XFS_ATTR3_LEAF_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -1052,7 +1052,7 @@ xfs_attr3_leaf_create( hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); ichdr.freemap[0 ].base =sizeof (struct xfs_attr3_leaf_hdr ); }else {
libxfs/xfs_attr_remote.c +2 -2
@@ -95,7 +95,7 @@ xfs_attr3_rmt_verify(return false;if (rmt->rm_magic !=cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ))return false; -if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (rmt->rm_blkno) != bno)return false;
@@ -212,7 +212,7 @@ xfs_attr3_rmt_hdr_set( rmt->rm_magic =cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ); rmt->rm_offset =cpu_to_be32 (offset); rmt->rm_bytes =cpu_to_be32 (size); -uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid); rmt->rm_owner =cpu_to_be64 (ino); rmt->rm_blkno =cpu_to_be64 (bno);
libxfs/xfs_bmap_btree.c +3 -2
@@ -346,7 +346,8 @@ xfs_bmbt_to_bmdr(if (xfs_sb_version_hascrc (&mp->m_sb)) {ASSERT (rblock->bb_magic ==cpu_to_be32 (XFS_BMAP_CRC_MAGIC )); -ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid));ASSERT (rblock->bb_u.l.bb_blkno ==cpu_to_be64 (XFS_BUF_DADDR_NULL )); }else
@@ -644,7 +645,7 @@ xfs_bmbt_verify(case cpu_to_be32 (XFS_BMAP_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (block->bb_u.l.bb_blkno) != bp->b_bn)return false;
libxfs/xfs_btree.c +6 -4
@@ -62,7 +62,8 @@ xfs_btree_check_lblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { lblock_ok = lblock_ok && -uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.l.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -112,7 +113,8 @@ xfs_btree_check_sblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { sblock_ok = sblock_ok && -uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.s.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.s.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }
@@ -997,7 +999,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.l.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.l.bb_owner =cpu_to_be64 (owner); -uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.l.bb_pad =0 ; buf->bb_u.l.bb_lsn =0 ; }
@@ -1010,7 +1012,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.s.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.s.bb_owner =cpu_to_be32 (__owner); -uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.s.bb_lsn =0 ; } }
libxfs/xfs_da_btree.c +2 -2
@@ -142,7 +142,7 @@ xfs_da3_node_verify(if (ichdr.magic !=XFS_DA3_NODE_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;
@@ -320,7 +320,7 @@ xfs_da3_node_create( ichdr.magic =XFS_DA3_NODE_MAGIC ; hdr3->info.blkno =cpu_to_be64 (bp->b_bn); hdr3->info.owner =cpu_to_be64 (args->dp->i_ino); -uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid); }else { ichdr.magic =XFS_DA_NODE_MAGIC ; }
libxfs/xfs_dir2_block.c +2 -2
@@ -64,7 +64,7 @@ xfs_dir3_block_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -154,7 +154,7 @@ xfs_dir3_block_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid);return ; }
libxfs/xfs_dir2_data.c +2 -2
@@ -218,7 +218,7 @@ xfs_dir3_data_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_DATA_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -602,7 +602,7 @@ xfs_dir3_data_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_DATA_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); }else hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );
libxfs/xfs_dir2_leaf.c +2 -2
@@ -158,7 +158,7 @@ xfs_dir3_leaf_verify(if (leaf3->info.hdr.magic !=cpu_to_be16 (magic3))return false; -if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (leaf3->info.blkno) != bp->b_bn)return false;
@@ -308,7 +308,7 @@ xfs_dir3_leaf_init( : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); leaf3->info.blkno =cpu_to_be64 (bp->b_bn); leaf3->info.owner =cpu_to_be64 (owner); -uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid); }else {memset (leaf,0 ,sizeof (*leaf)); leaf->hdr.info.magic =cpu_to_be16 (type);
libxfs/xfs_dir2_node.c +2 -2
@@ -91,7 +91,7 @@ xfs_dir3_free_verify(if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_FREE_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;
@@ -224,7 +224,7 @@ xfs_dir3_free_get_buf( hdr3->hdr.blkno =cpu_to_be64 (bp->b_bn); hdr3->hdr.owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); }else hdr.magic =XFS_DIR2_FREE_MAGIC ; dp->d_ops->free_hdr_to_disk (bp->b_addr, &hdr);
libxfs/xfs_dquot_buf.c +2 -2
@@ -171,7 +171,7 @@ xfs_dqcheck( d->dd_diskdq.d_id =cpu_to_be32 (id);if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }
@@ -206,7 +206,7 @@ xfs_dquot_buf_verify_crc(if (!xfs_verify_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ))return false; -if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_meta_uuid))return false; }return true;
libxfs/xfs_format.h +19 -3
@@ -100,7 +100,7 @@ typedef struct xfs_sb {xfs_rfsblock_t sb_dblocks;/* number of data blocks */ xfs_rfsblock_t sb_rblocks;/* number of realtime blocks */ xfs_rtblock_t sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ xfs_fsblock_t sb_logstart;/* starting block of log if internal */ xfs_ino_t sb_rootino;/* root inode number */ xfs_ino_t sb_rbmino;/* bitmap inode for realtime extents */
@@ -174,6 +174,7 @@ typedef struct xfs_sb {xfs_ino_t sb_pquotino;/* project quota inode */ xfs_lsn_t sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_sb_t;
@@ -190,7 +191,7 @@ typedef struct xfs_dsb {__be64 sb_dblocks;/* number of data blocks */ __be64 sb_rblocks;/* number of realtime blocks */ __be64 sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ __be64 sb_logstart;/* starting block of log if internal */ __be64 sb_rootino;/* root inode number */ __be64 sb_rbmino;/* bitmap inode for realtime extents */
@@ -260,6 +261,7 @@ typedef struct xfs_dsb {__be64 sb_pquotino;/* project quota inode */ __be64 sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_dsb_t;
@@ -457,8 +459,10 @@ xfs_sb_has_ro_compat_feature( }#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0)/* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 1)/* metadata UUID */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_META_UUID)#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool
@@ -507,6 +511,18 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) }/* +* XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID +* is stored separately from the user-visible UUID; this allows the +* user-visible UUID to be changed on V5 filesystems which have a +* filesystem UUID stamped into every piece of metadata. +*/ +static inline bool xfs_sb_version_hasmetauuid (struct xfs_sb *sbp) +{ +return (XFS_SB_VERSION_NUM (sbp) ==XFS_SB_VERSION_5 ) && + (sbp->sb_features_incompat &XFS_SB_FEAT_INCOMPAT_META_UUID ); +} + +/* * end of superblock version macros */
libxfs/xfs_ialloc.c +3 -2
@@ -302,7 +302,8 @@ xfs_ialloc_inode_init(if (version ==3 ) { free->di_ino =cpu_to_be64 (ino); ino++; -uuid_copy (&free->di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&free->di_uuid, + &mp->m_sb.sb_meta_uuid);xfs_dinode_calc_crc (mp, free); }else if (tp) {/* just log the inode core */
@@ -2044,7 +2045,7 @@ xfs_agi_verify(struct xfs_agi *agi =XFS_BUF_TO_AGI (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))return false;/* * Validate the magic number of the agi block.
libxfs/xfs_ialloc_btree.c +1 -1
@@ -229,7 +229,7 @@ xfs_inobt_verify(case cpu_to_be32 (XFS_FIBT_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;
libxfs/xfs_inode_buf.c +2 -2
@@ -304,7 +304,7 @@ xfs_dinode_verify(return false;if (be64_to_cpu (dip->di_ino) != ino)return false; -if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_meta_uuid))return false;return true; }
@@ -366,7 +366,7 @@ xfs_iread(if (xfs_sb_version_hascrc (&mp->m_sb)) { ip->i_d.di_version =3 ; ip->i_d.di_ino = ip->i_ino; -uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); }else ip->i_d.di_version =2 ;return 0 ;
libxfs/xfs_sb.c +10 -0
@@ -360,6 +360,14 @@ __xfs_sb_from_disk( to->sb_pad =0 ; to->sb_pquotino =be64_to_cpu (from->sb_pquotino); to->sb_lsn =be64_to_cpu (from->sb_lsn); +/* +* sb_meta_uuid is only on disk if it differs from sb_uuid and the +* feature flag is set; if not set we keep it only in memory. +*/ +if (xfs_sb_version_hasmetauuid (to)) +uuid_copy (&to->sb_meta_uuid, &from->sb_meta_uuid); +else +uuid_copy (&to->sb_meta_uuid, &from->sb_uuid);/* Convert on-disk flags to in-memory flags? */ if (convert_xquota)xfs_sb_quota_from_disk (to);
@@ -501,6 +509,8 @@ xfs_sb_to_disk(cpu_to_be32 (from->sb_features_log_incompat); to->sb_pad =0 ; to->sb_lsn =cpu_to_be64 (from->sb_lsn); +if (xfs_sb_version_hasmetauuid (from)) +uuid_copy (&to->sb_meta_uuid, &from->sb_meta_uuid); } }
libxfs/xfs_symlink_remote.c +2 -2
@@ -60,7 +60,7 @@ xfs_symlink_hdr_set( dsl->sl_magic =cpu_to_be32 (XFS_SYMLINK_MAGIC ); dsl->sl_offset =cpu_to_be32 (offset); dsl->sl_bytes =cpu_to_be32 (size); -uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid); dsl->sl_owner =cpu_to_be64 (ino); dsl->sl_blkno =cpu_to_be64 (bp->b_bn); bp->b_ops = &xfs_symlink_buf_ops;
@@ -104,7 +104,7 @@ xfs_symlink_verify(return false;if (dsl->sl_magic !=cpu_to_be32 (XFS_SYMLINK_MAGIC ))return false; -if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (bp->b_bn !=be64_to_cpu (dsl->sl_blkno))return false;
libxlog/util.c +4 -2
@@ -29,8 +29,10 @@ header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head) {char uu_log[64 ], uu_sb[64 ]; -if (print_skip_uuid)return 0 ; -if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid))return 0 ; +if (print_skip_uuid) +return 0 ; +if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) +return 0 ;platform_uuid_unparse (&mp->m_sb.sb_uuid, uu_sb);platform_uuid_unparse (&head->h_fs_uuid, uu_log);
man/man8/xfs_admin.8 +6 -1
@@ -98,7 +98,12 @@ The .I uuid may also be .BR generate , -which will generate a new UUID for the filesystem. +which will generate a new UUID for the filesystem. Note that on CRC-enabled +filesystems, this will set an incompatible flag such that older kernels will +not be able to mount the filesystem. To remove this incompatible flag, use +.BR restore , +which will restore the original UUID and remove the incompatible +feature flag as needed. .TP .B \-V Prints the version number and exits.
man/man8/xfs_db.8 +7 -2
@@ -664,7 +664,7 @@ The possible data types are: .BR sb ", " symlink " and " text . See the TYPES section below for more information on these data types. .TP -.BI "uuid [" uuid " | " generate " | " rewrite ] +.BI "uuid [" uuid " | " generate " | " rewrite " | " restore ] Set the filesystem universally unique identifier (UUID). The filesystem UUID can be used by .BR mount (8)
@@ -675,7 +675,12 @@ can be set directly to the desired UUID, or it can be automatically generated using the .B generate option. These options will both write the UUID into every copy of the -superblock in the filesystem. +superblock in the filesystem. On a CRC-enabled filesystem, this will +set an incompatible superblock flag, and the filesystem will not be +mountable with older kernels. This can be reverted with the +.B restore +option, which will copy the original UUID back into place and clear +the incompatible flag as needed. .B rewrite copies the current UUID from the primary superblock to all secondary copies of the superblock.
mkfs/xfs_mkfs.c +2 -0
@@ -2598,6 +2598,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), sbp->sb_rextents = rtextents;platform_uuid_generate (&uuid);platform_uuid_copy (&sbp->sb_uuid, &uuid); +/* Only in memory; libxfs expects this as if read from disk */ +platform_uuid_copy (&sbp->sb_meta_uuid, &uuid); sbp->sb_logstart = logstart; sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino =NULLFSINO ; sbp->sb_rextsize = rtextblocks;
repair/agheader.c +12 -7
@@ -112,7 +112,7 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGF ;
@@ -120,7 +120,8 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)do_warn (_ ("bad uuid %s for agf %d\n" ), uu, i);if (!no_modify) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, + &mp->m_sb.sb_meta_uuid); }return retval; }
@@ -190,7 +191,7 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGI ;
@@ -198,7 +199,8 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)do_warn (_ ("bad uuid %s for agi %d\n" ), uu, agno);if (!no_modify) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, + &mp->m_sb.sb_meta_uuid); }return retval;
@@ -245,7 +247,7 @@ compare_sb(xfs_mount_t *mp, xfs_sb_t *sb)* superblocks, not just the secondary superblocks. */ static int -secondary_sb_wack( +secondary_sb_whack( struct xfs_mount *mp, struct xfs_buf *sbuf, struct xfs_sb *sb,
@@ -267,7 +269,10 @@ secondary_sb_wack(* * size is the size of data which is valid for this sb. */ -if (xfs_sb_version_hascrc (sb)) +if (xfs_sb_version_hasmetauuid (sb)) + size = offsetof(xfs_sb_t , sb_meta_uuid) + +sizeof (sb->sb_meta_uuid); +else if (xfs_sb_version_hascrc (sb)) size = offsetof(xfs_sb_t , sb_lsn) +sizeof (sb->sb_lsn);else if (xfs_sb_version_hasmorebits (sb))
@@ -511,7 +516,7 @@ verify_set_agheader(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, rval |=XR_AG_SB ; } - rval |=secondary_sb_wack (mp, sbuf, sb, i); + rval |=secondary_sb_whack (mp, sbuf, sb, i); rval |=verify_set_agf (mp, agf, i); rval |=verify_set_agi (mp, agi, i);
repair/agheader.h +0 -1
@@ -24,7 +24,6 @@ typedef struct fs_geometry {xfs_rfsblock_t sb_dblocks;/* # data blocks */ xfs_rfsblock_t sb_rblocks;/* # realtime blocks */ xfs_rtblock_t sb_rextents;/* # realtime extents */ -uuid_t sb_uuid;/* fs uuid */ xfs_fsblock_t sb_logstart;/* starting log block # */ xfs_agblock_t sb_rextsize;/* realtime extent size (blocks )*/ xfs_agblock_t sb_agblocks;/* # of blocks per ag */
repair/dinode.c +4 -3
@@ -207,9 +207,9 @@ clear_dinode_core(struct xfs_mount *mp, xfs_dinode_t *dinoc, xfs_ino_t ino_num) dinoc->di_ino =cpu_to_be64 (ino_num); } -if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid)) {__dirty_no_modify_ret (dirty); -platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid); }for (i =0 ; i <sizeof (dinoc->di_pad2)/sizeof (dinoc->di_pad2[0 ]); i++) {
@@ -2287,7 +2287,8 @@ _("inode identifier %llu mismatch on inode %" PRIu64 "\n"),return 1 ; goto clear_bad_out; } -if (platform_uuid_compare (&dino->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dino->di_uuid, + &mp->m_sb.sb_meta_uuid)) {if (!uncertain)do_warn (_ ("UUID mismatch on inode %" PRIu64"\n" ), lino);
repair/phase5.c +3 -3
@@ -1119,7 +1119,7 @@ build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, agi->agi_unlinked[i] =cpu_to_be32 (NULLAGINO );if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);if (xfs_sb_version_hasfinobt (&mp->m_sb)) { agi->agi_free_root =cpu_to_be32 (finobt_curs->root);
@@ -1360,7 +1360,7 @@ build_agf_agfl(xfs_mount_t *mp,#endif if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);/* initialise the AGFL, then fill it if there are blocks left over. */ agfl_buf = libxfs_getbuf(mp->m_dev,
@@ -1374,7 +1374,7 @@ build_agf_agfl(xfs_mount_t *mp,if (xfs_sb_version_hascrc (&mp->m_sb)) { agfl->agfl_magicnum =cpu_to_be32 (XFS_AGFL_MAGIC ); agfl->agfl_seqno =cpu_to_be32 (agno); -platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);for (i =0 ; i <XFS_AGFL_SIZE (mp); i++) agfl->agfl_bno[i] =cpu_to_be32 (NULLAGBLOCK ); }
repair/phase6.c +3 -3
@@ -527,7 +527,7 @@ mk_rbmino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rbmino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
@@ -783,7 +783,7 @@ mk_rsumino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rsumino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
@@ -897,7 +897,7 @@ mk_root_dir(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rootino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 2/2 V5] xfsprogs: Add new sb_meta_uuid field, update userspace tools to manipulate it
Quoted 12 lines · Eric Sandeen
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_uuidslot in memory when the superblock is read from disk; themeta_uuidfield is not written back to disk in this case.
Quoted 5 lines
The remainder of this patch simply switches verifiers, initializers, etc to use the new
sb_meta_uuidfield.Signed-off-by Eric Sandeen <[email protected]>---
Quoted 883 lines
V5: bools and structs and xfs_copy()s to match kernelspace...
copy/xfs_copy.c +32
-12@@ -466,6 +466,37 @@ write_wbuf(void)sighold (SIGCHLD ); } +void +sb_update_uuid ( +xfs_sb_t *sb, +ag_header_t *ag_hdr, +thread_args *tcarg) +{ +/* +* If this filesystem has CRCs, the original UUID is stamped into +* all metadata. If the new UUID is different, We need to copy the +* original UUID into the meta_uuid slot and set the incompat flag +* if that hasn't already been done. +*/ +if (xfs_sb_version_hascrc (sb) && +platform_uuid_compare (&tcarg->uuid, &ag_hdr->xfs_sb->sb_uuid) && + !xfs_sb_version_hasmetauuid (sb)) { +__be32 feat; + + feat =be32_to_cpu (ag_hdr->xfs_sb->sb_features_incompat); + feat |=XFS_SB_FEAT_INCOMPAT_META_UUID ; + ag_hdr->xfs_sb->sb_features_incompat =cpu_to_be32 (feat); +platform_uuid_copy (&ag_hdr->xfs_sb->sb_meta_uuid, + &ag_hdr->xfs_sb->sb_uuid); + } + +platform_uuid_copy (&ag_hdr->xfs_sb->sb_uuid, &tcarg->uuid); + +/* We might have changed the UUID, so update the superblock CRC */ +if (xfs_sb_version_hascrc (sb)) +xfs_update_cksum ((char *)ag_hdr->xfs_sb, sb->sb_sectsize, +XFS_SB_CRC_OFF ); +}int main (int argc,char **argv)@@ -659,16 +690,6 @@ main(int argc, char **argv) sb = &mbuf.m_sb;libxfs_sb_from_disk (sb,XFS_BUF_TO_SBP (sbp)); -/* -* For now, V5 superblock filesystems are not supported without -d; -* we do not have the infrastructure yet to fix CRCs when a new UUID -* is generated. -*/ -if (xfs_sb_version_hascrc (sb) && !duplicate) { -do_log (_ ("%s: Cannot yet copy V5 fs without '-d'\n" ), progname); -exit (1 ); - } - mp =libxfs_mount (&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev,0 );if (mp ==NULL ) { do_log(_("%s: %s filesystem failed to initialize\n"@@ -1127,8 +1148,7 @@ main(int argc, char **argv)/* do each thread in turn, each has its own UUID */ for (j =0 , tcarg = targ; j < num_targets; j++) { -platform_uuid_copy (&ag_hdr.xfs_sb->sb_uuid, - &tcarg->uuid); +sb_update_uuid (sb, &ag_hdr, tcarg);do_write (tcarg); tcarg++; }db/sb.c +42
-12@@ -29,6 +29,8 @@#include "output.h" #include "init.h" +#define uuid_equal (s,d) (platform_uuid_compare((s),(d)) == 0) +static int sb_f (int argc,char **argv);static void sb_help (void );static int uuid_f (int argc,char **argv);@@ -121,6 +123,7 @@ const field_t sb_flds[] = { { "crc", FLDT_CRC, OI(OFF(crc)), C1, 0, TYP_NONE }, { "pquotino", FLDT_INO, OI(OFF(pquotino)), C1, 0, TYP_INODE }, { "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE }, + { "meta_uuid", FLDT_UUID, OI(OFF(meta_uuid)), C1, 0, TYP_NONE }, { NULL } };@@ -334,6 +337,32 @@ do_uuid(xfs_agnumber_t agno, uuid_t *uuid)return &uu; }/* set uuid */ +if (!xfs_sb_version_hascrc (&tsb)) + goto write; +/* +* If we have CRCs, and this UUID differs from that stamped in the +* metadata, set the incompat flag and copy the old one to the +* metadata-specific location. +* +* If we are setting the user-visible UUID back to match the metadata +* UUID, clear the metadata-specific location and the incompat flag. +*/ +if (!xfs_sb_version_hasmetauuid (&tsb) && + !uuid_equal (uuid, &mp->m_sb.sb_meta_uuid)) { + mp->m_sb.sb_features_incompat |=XFS_SB_FEAT_INCOMPAT_META_UUID ; + tsb.sb_features_incompat |=XFS_SB_FEAT_INCOMPAT_META_UUID ; +memcpy (&tsb.sb_meta_uuid, &tsb.sb_uuid,sizeof (uuid_t)); + }else if (xfs_sb_version_hasmetauuid (&tsb) && +uuid_equal (uuid, &mp->m_sb.sb_meta_uuid)) { +memset (&tsb.sb_meta_uuid,0 ,sizeof (uuid_t)); +/* Write those zeros now; it's ignored once we clear the flag */ +libxfs_sb_to_disk (iocur_top->data, &tsb); + mp->m_sb.sb_features_incompat &= + ~XFS_SB_FEAT_INCOMPAT_META_UUID ; + tsb.sb_features_incompat &= ~XFS_SB_FEAT_INCOMPAT_META_UUID ; + } + +write:memcpy (&tsb.sb_uuid, uuid,sizeof (uuid_t));libxfs_sb_to_disk (iocur_top->data, &tsb);write_cur ();@@ -363,18 +392,6 @@ uuid_f(return 0 ; } -/* -* For now, changing the UUID of V5 superblock filesystems is -* not supported; we do not have the infrastructure to fix all -* other metadata when a new superblock UUID is generated. -*/ -if (xfs_sb_version_hascrc (&mp->m_sb) && -strcasecmp (argv[1 ],"rewrite" )) { -dbprintf (_ ("%s: only 'rewrite' supported on V5 fs\n" ), - progname); -return 0 ; - } -if (!strcasecmp (argv[1 ],"generate" )) {platform_uuid_generate (&uu); }else if (!strcasecmp (argv[1 ],"nil" )) {@@ -388,6 +405,17 @@ uuid_f(memcpy (&uu, uup,sizeof (uuid_t));platform_uuid_unparse (&uu, bp);dbprintf (_ ("old UUID = %s\n" ), bp); + }else if (!strcasecmp (argv[1 ],"restore" )) { +xfs_sb_t tsb; + +if (!get_sb (0 , &tsb)) +return 0 ; + +/* Not set; nothing to do. Success! */ +if (!xfs_sb_version_hasmetauuid (&tsb)) +return 0 ; + +memcpy (&uu, mp->m_sb.sb_meta_uuid,sizeof (uuid_t)); }else {if (platform_uuid_parse (argv[1 ], &uu)) {dbprintf (_ ("invalid UUID\n" ));@@ -660,6 +688,8 @@ version_string(strcat (s,",CRC" );if (xfs_sb_version_hasftype (sbp))strcat (s,",FTYPE" ); +if (xfs_sb_version_hasmetauuid (sbp)) +strcat (s,",META_UUID" );return s; }libxfs/xfs_alloc.c +2
-2@@ -446,7 +446,7 @@ xfs_agfl_verify(struct xfs_agfl *agfl =XFS_BUF_TO_AGFL (bp);int i; -if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be32_to_cpu (agfl->agfl_magicnum) !=XFS_AGFL_MAGIC )return false;@@ -2199,7 +2199,7 @@ xfs_agf_verify(struct xfs_agf *agf =XFS_BUF_TO_AGF (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))return false; if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&libxfs/xfs_alloc_btree.c +2
-2@@ -293,7 +293,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTB_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;@@ -311,7 +311,7 @@ xfs_allocbt_verify(case cpu_to_be32 (XFS_ABTC_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;libxfs/xfs_attr_leaf.c +2
-2@@ -258,7 +258,7 @@ xfs_attr3_leaf_verify(if (ichdr.magic !=XFS_ATTR3_LEAF_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;@@ -1052,7 +1052,7 @@ xfs_attr3_leaf_create( hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); ichdr.freemap[0 ].base =sizeof (struct xfs_attr3_leaf_hdr ); }else {libxfs/xfs_attr_remote.c +2
-2@@ -95,7 +95,7 @@ xfs_attr3_rmt_verify(return false;if (rmt->rm_magic !=cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ))return false; -if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (rmt->rm_blkno) != bno)return false;@@ -212,7 +212,7 @@ xfs_attr3_rmt_hdr_set( rmt->rm_magic =cpu_to_be32 (XFS_ATTR3_RMT_MAGIC ); rmt->rm_offset =cpu_to_be32 (offset); rmt->rm_bytes =cpu_to_be32 (size); -uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid); rmt->rm_owner =cpu_to_be64 (ino); rmt->rm_blkno =cpu_to_be64 (bno);libxfs/xfs_bmap_btree.c +3
-2@@ -346,7 +346,8 @@ xfs_bmbt_to_bmdr(if (xfs_sb_version_hascrc (&mp->m_sb)) {ASSERT (rblock->bb_magic ==cpu_to_be32 (XFS_BMAP_CRC_MAGIC )); -ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid));ASSERT (rblock->bb_u.l.bb_blkno ==cpu_to_be64 (XFS_BUF_DADDR_NULL )); }else @@ -644,7 +645,7 @@ xfs_bmbt_verify(case cpu_to_be32 (XFS_BMAP_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (block->bb_u.l.bb_blkno) != bp->b_bn)return false;libxfs/xfs_btree.c +6
-4@@ -62,7 +62,8 @@ xfs_btree_check_lblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { lblock_ok = lblock_ok && -uuid_equal (&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.l.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.l.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }@@ -112,7 +113,8 @@ xfs_btree_check_sblock(if (xfs_sb_version_hascrc (&mp->m_sb)) { sblock_ok = sblock_ok && -uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && +uuid_equal (&block->bb_u.s.bb_uuid, + &mp->m_sb.sb_meta_uuid) && block->bb_u.s.bb_blkno ==cpu_to_be64 ( bp ? bp->b_bn :XFS_BUF_DADDR_NULL ); }@@ -997,7 +999,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.l.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.l.bb_owner =cpu_to_be64 (owner); -uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.l.bb_pad =0 ; buf->bb_u.l.bb_lsn =0 ; }@@ -1010,7 +1012,7 @@ xfs_btree_init_block_int(if (flags &XFS_BTREE_CRC_BLOCKS ) { buf->bb_u.s.bb_blkno =cpu_to_be64 (blkno); buf->bb_u.s.bb_owner =cpu_to_be32 (__owner); -uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid); buf->bb_u.s.bb_lsn =0 ; } }libxfs/xfs_da_btree.c +2
-2@@ -142,7 +142,7 @@ xfs_da3_node_verify(if (ichdr.magic !=XFS_DA3_NODE_MAGIC )return false; -if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->info.blkno) != bp->b_bn)return false;@@ -320,7 +320,7 @@ xfs_da3_node_create( ichdr.magic =XFS_DA3_NODE_MAGIC ; hdr3->info.blkno =cpu_to_be64 (bp->b_bn); hdr3->info.owner =cpu_to_be64 (args->dp->i_ino); -uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid); }else { ichdr.magic =XFS_DA_NODE_MAGIC ; }libxfs/xfs_dir2_block.c +2
-2@@ -64,7 +64,7 @@ xfs_dir3_block_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;@@ -154,7 +154,7 @@ xfs_dir3_block_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_BLOCK_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid);return ; }libxfs/xfs_dir2_data.c +2
-2@@ -218,7 +218,7 @@ xfs_dir3_data_verify(if (xfs_sb_version_hascrc (&mp->m_sb)) {if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_DATA_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;@@ -602,7 +602,7 @@ xfs_dir3_data_init( hdr3->magic =cpu_to_be32 (XFS_DIR3_DATA_MAGIC ); hdr3->blkno =cpu_to_be64 (bp->b_bn); hdr3->owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->uuid, &mp->m_sb.sb_meta_uuid); }else hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );libxfs/xfs_dir2_leaf.c +2
-2@@ -158,7 +158,7 @@ xfs_dir3_leaf_verify(if (leaf3->info.hdr.magic !=cpu_to_be16 (magic3))return false; -if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (leaf3->info.blkno) != bp->b_bn)return false;@@ -308,7 +308,7 @@ xfs_dir3_leaf_init( : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); leaf3->info.blkno =cpu_to_be64 (bp->b_bn); leaf3->info.owner =cpu_to_be64 (owner); -uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid); }else {memset (leaf,0 ,sizeof (*leaf)); leaf->hdr.info.magic =cpu_to_be16 (type);libxfs/xfs_dir2_node.c +2
-2@@ -91,7 +91,7 @@ xfs_dir3_free_verify(if (hdr3->magic !=cpu_to_be32 (XFS_DIR3_FREE_MAGIC ))return false; -if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&hdr3->uuid, &mp->m_sb.sb_meta_uuid))return false;if (be64_to_cpu (hdr3->blkno) != bp->b_bn)return false;@@ -224,7 +224,7 @@ xfs_dir3_free_get_buf( hdr3->hdr.blkno =cpu_to_be64 (bp->b_bn); hdr3->hdr.owner =cpu_to_be64 (dp->i_ino); -uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); +uuid_copy (&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); }else hdr.magic =XFS_DIR2_FREE_MAGIC ; dp->d_ops->free_hdr_to_disk (bp->b_addr, &hdr);libxfs/xfs_dquot_buf.c +2
-2@@ -171,7 +171,7 @@ xfs_dqcheck( d->dd_diskdq.d_id =cpu_to_be32 (id);if (xfs_sb_version_hascrc (&mp->m_sb)) { -uuid_copy (&d->dd_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&d->dd_uuid, &mp->m_sb.sb_meta_uuid);xfs_update_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ); }@@ -206,7 +206,7 @@ xfs_dquot_buf_verify_crc(if (!xfs_verify_cksum ((char *)d,sizeof (struct xfs_dqblk ),XFS_DQUOT_CRC_OFF ))return false; -if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&d->dd_uuid, &mp->m_sb.sb_meta_uuid))return false; }return true;libxfs/xfs_format.h +19
-3@@ -100,7 +100,7 @@ typedef struct xfs_sb {xfs_rfsblock_t sb_dblocks;/* number of data blocks */ xfs_rfsblock_t sb_rblocks;/* number of realtime blocks */ xfs_rtblock_t sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ xfs_fsblock_t sb_logstart;/* starting block of log if internal */ xfs_ino_t sb_rootino;/* root inode number */ xfs_ino_t sb_rbmino;/* bitmap inode for realtime extents */ @@ -174,6 +174,7 @@ typedef struct xfs_sb {xfs_ino_t sb_pquotino;/* project quota inode */ xfs_lsn_t sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_sb_t;@@ -190,7 +191,7 @@ typedef struct xfs_dsb {__be64 sb_dblocks;/* number of data blocks */ __be64 sb_rblocks;/* number of realtime blocks */ __be64 sb_rextents;/* number of realtime extents */ -uuid_t sb_uuid;/* file system unique id */ +uuid_t sb_uuid;/* user-visible file system unique id */ __be64 sb_logstart;/* starting block of log if internal */ __be64 sb_rootino;/* root inode number */ __be64 sb_rbmino;/* bitmap inode for realtime extents */ @@ -260,6 +261,7 @@ typedef struct xfs_dsb {__be64 sb_pquotino;/* project quota inode */ __be64 sb_lsn;/* last write sequence */ +uuid_t sb_meta_uuid;/* metadata file system unique id */ /* must be padded to 64 bit alignment */ } xfs_dsb_t;@@ -457,8 +459,10 @@ xfs_sb_has_ro_compat_feature( }#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0)/* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 1)/* metadata UUID */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_META_UUID)#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool@@ -507,6 +511,18 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) }/* +* XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID +* is stored separately from the user-visible UUID; this allows the +* user-visible UUID to be changed on V5 filesystems which have a +* filesystem UUID stamped into every piece of metadata. +*/ +static inline bool xfs_sb_version_hasmetauuid (struct xfs_sb *sbp) +{ +return (XFS_SB_VERSION_NUM (sbp) ==XFS_SB_VERSION_5 ) && + (sbp->sb_features_incompat &XFS_SB_FEAT_INCOMPAT_META_UUID ); +} + +/* * end of superblock version macros */ libxfs/xfs_ialloc.c +3
-2@@ -302,7 +302,8 @@ xfs_ialloc_inode_init(if (version ==3 ) { free->di_ino =cpu_to_be64 (ino); ino++; -uuid_copy (&free->di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&free->di_uuid, + &mp->m_sb.sb_meta_uuid);xfs_dinode_calc_crc (mp, free); }else if (tp) {/* just log the inode core */ @@ -2044,7 +2045,7 @@ xfs_agi_verify(struct xfs_agi *agi =XFS_BUF_TO_AGI (bp);if (xfs_sb_version_hascrc (&mp->m_sb) && - !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_uuid)) + !uuid_equal (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))return false;/* * Validate the magic number of the agi block. libxfs/xfs_ialloc_btree.c +1
-1@@ -229,7 +229,7 @@ xfs_inobt_verify(case cpu_to_be32 (XFS_FIBT_CRC_MAGIC ):if (!xfs_sb_version_hascrc (&mp->m_sb))return false; -if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))return false;if (block->bb_u.s.bb_blkno !=cpu_to_be64 (bp->b_bn))return false;libxfs/xfs_inode_buf.c +2
-2@@ -304,7 +304,7 @@ xfs_dinode_verify(return false;if (be64_to_cpu (dip->di_ino) != ino)return false; -if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dip->di_uuid, &mp->m_sb.sb_meta_uuid))return false;return true; }@@ -366,7 +366,7 @@ xfs_iread(if (xfs_sb_version_hascrc (&mp->m_sb)) { ip->i_d.di_version =3 ; ip->i_d.di_ino = ip->i_ino; -uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); }else ip->i_d.di_version =2 ;return 0 ;libxfs/xfs_sb.c +10
-0@@ -360,6 +360,14 @@ __xfs_sb_from_disk( to->sb_pad =0 ; to->sb_pquotino =be64_to_cpu (from->sb_pquotino); to->sb_lsn =be64_to_cpu (from->sb_lsn); +/* +* sb_meta_uuid is only on disk if it differs from sb_uuid and the +* feature flag is set; if not set we keep it only in memory. +*/ +if (xfs_sb_version_hasmetauuid (to)) +uuid_copy (&to->sb_meta_uuid, &from->sb_meta_uuid); +else +uuid_copy (&to->sb_meta_uuid, &from->sb_uuid);/* Convert on-disk flags to in-memory flags? */ if (convert_xquota)xfs_sb_quota_from_disk (to);@@ -501,6 +509,8 @@ xfs_sb_to_disk(cpu_to_be32 (from->sb_features_log_incompat); to->sb_pad =0 ; to->sb_lsn =cpu_to_be64 (from->sb_lsn); +if (xfs_sb_version_hasmetauuid (from)) +uuid_copy (&to->sb_meta_uuid, &from->sb_meta_uuid); } }libxfs/xfs_symlink_remote.c +2
-2@@ -60,7 +60,7 @@ xfs_symlink_hdr_set( dsl->sl_magic =cpu_to_be32 (XFS_SYMLINK_MAGIC ); dsl->sl_offset =cpu_to_be32 (offset); dsl->sl_bytes =cpu_to_be32 (size); -uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_uuid); +uuid_copy (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid); dsl->sl_owner =cpu_to_be64 (ino); dsl->sl_blkno =cpu_to_be64 (bp->b_bn); bp->b_ops = &xfs_symlink_buf_ops;@@ -104,7 +104,7 @@ xfs_symlink_verify(return false;if (dsl->sl_magic !=cpu_to_be32 (XFS_SYMLINK_MAGIC ))return false; -if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_uuid)) +if (!uuid_equal (&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))return false;if (bp->b_bn !=be64_to_cpu (dsl->sl_blkno))return false;libxlog/util.c +4
-2@@ -29,8 +29,10 @@ header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head) {char uu_log[64 ], uu_sb[64 ]; -if (print_skip_uuid)return 0 ; -if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid))return 0 ; +if (print_skip_uuid) +return 0 ; +if (!platform_uuid_compare (&mp->m_sb.sb_uuid, &head->h_fs_uuid)) +return 0 ;platform_uuid_unparse (&mp->m_sb.sb_uuid, uu_sb);platform_uuid_unparse (&head->h_fs_uuid, uu_log);man/man8/xfs_admin.8 +6
-1@@ -98,7 +98,12 @@ The .I uuid may also be .BR generate , -which will generate a new UUID for the filesystem. +which will generate a new UUID for the filesystem. Note that on CRC-enabled +filesystems, this will set an incompatible flag such that older kernels will +not be able to mount the filesystem. To remove this incompatible flag, use +.BR restore , +which will restore the original UUID and remove the incompatible +feature flag as needed. .TP .B \-V Prints the version number and exits.man/man8/xfs_db.8 +7
-2@@ -664,7 +664,7 @@ The possible data types are: .BR sb ", " symlink " and " text . See the TYPES section below for more information on these data types. .TP -.BI "uuid [" uuid " | " generate " | " rewrite ] +.BI "uuid [" uuid " | " generate " | " rewrite " | " restore ] Set the filesystem universally unique identifier (UUID). The filesystem UUID can be used by .BR mount (8)@@ -675,7 +675,12 @@ can be set directly to the desired UUID, or it can be automatically generated using the .B generate option. These options will both write the UUID into every copy of the -superblock in the filesystem. +superblock in the filesystem. On a CRC-enabled filesystem, this will +set an incompatible superblock flag, and the filesystem will not be +mountable with older kernels. This can be reverted with the +.B restore +option, which will copy the original UUID back into place and clear +the incompatible flag as needed. .B rewrite copies the current UUID from the primary superblock to all secondary copies of the superblock.mkfs/xfs_mkfs.c +2
-0@@ -2598,6 +2598,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), sbp->sb_rextents = rtextents;platform_uuid_generate (&uuid);platform_uuid_copy (&sbp->sb_uuid, &uuid); +/* Only in memory; libxfs expects this as if read from disk */ +platform_uuid_copy (&sbp->sb_meta_uuid, &uuid); sbp->sb_logstart = logstart; sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino =NULLFSINO ; sbp->sb_rextsize = rtextblocks;repair/agheader.c +12
-7@@ -112,7 +112,7 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGF ;@@ -120,7 +120,8 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)do_warn (_ ("bad uuid %s for agf %d\n" ), uu, i);if (!no_modify) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, + &mp->m_sb.sb_meta_uuid); }return retval; }@@ -190,7 +191,7 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)if (!xfs_sb_version_hascrc (&mp->m_sb))return retval; -if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid)) {char uu[64 ]; retval =XR_AG_AGI ;@@ -198,7 +199,8 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)do_warn (_ ("bad uuid %s for agi %d\n" ), uu, agno);if (!no_modify) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, + &mp->m_sb.sb_meta_uuid); }return retval;@@ -245,7 +247,7 @@ compare_sb(xfs_mount_t *mp, xfs_sb_t *sb)* superblocks, not just the secondary superblocks. */ static int -secondary_sb_wack( +secondary_sb_whack( struct xfs_mount *mp, struct xfs_buf *sbuf, struct xfs_sb *sb,@@ -267,7 +269,10 @@ secondary_sb_wack(* * size is the size of data which is valid for this sb. */ -if (xfs_sb_version_hascrc (sb)) +if (xfs_sb_version_hasmetauuid (sb)) + size = offsetof(xfs_sb_t , sb_meta_uuid) + +sizeof (sb->sb_meta_uuid); +else if (xfs_sb_version_hascrc (sb)) size = offsetof(xfs_sb_t , sb_lsn) +sizeof (sb->sb_lsn);else if (xfs_sb_version_hasmorebits (sb))@@ -511,7 +516,7 @@ verify_set_agheader(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb, rval |=XR_AG_SB ; } - rval |=secondary_sb_wack (mp, sbuf, sb, i); + rval |=secondary_sb_whack (mp, sbuf, sb, i); rval |=verify_set_agf (mp, agf, i); rval |=verify_set_agi (mp, agi, i);repair/agheader.h +0
-1@@ -24,7 +24,6 @@ typedef struct fs_geometry {xfs_rfsblock_t sb_dblocks;/* # data blocks */ xfs_rfsblock_t sb_rblocks;/* # realtime blocks */ xfs_rtblock_t sb_rextents;/* # realtime extents */ -uuid_t sb_uuid;/* fs uuid */ xfs_fsblock_t sb_logstart;/* starting log block # */ xfs_agblock_t sb_rextsize;/* realtime extent size (blocks )*/ xfs_agblock_t sb_agblocks;/* # of blocks per ag */ repair/dinode.c +4
-3@@ -207,9 +207,9 @@ clear_dinode_core(struct xfs_mount *mp, xfs_dinode_t *dinoc, xfs_ino_t ino_num) dinoc->di_ino =cpu_to_be64 (ino_num); } -if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid)) {__dirty_no_modify_ret (dirty); -platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&dinoc->di_uuid, &mp->m_sb.sb_meta_uuid); }for (i =0 ; i <sizeof (dinoc->di_pad2)/sizeof (dinoc->di_pad2[0 ]); i++) {@@ -2287,7 +2287,8 @@ _("inode identifier %llu mismatch on inode %" PRIu64 "\n"),return 1 ; goto clear_bad_out; } -if (platform_uuid_compare (&dino->di_uuid, &mp->m_sb.sb_uuid)) { +if (platform_uuid_compare (&dino->di_uuid, + &mp->m_sb.sb_meta_uuid)) {if (!uncertain)do_warn (_ ("UUID mismatch on inode %" PRIu64"\n" ), lino);repair/phase5.c +3
-3@@ -1119,7 +1119,7 @@ build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, agi->agi_unlinked[i] =cpu_to_be32 (NULLAGINO );if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);if (xfs_sb_version_hasfinobt (&mp->m_sb)) { agi->agi_free_root =cpu_to_be32 (finobt_curs->root);@@ -1360,7 +1360,7 @@ build_agf_agfl(xfs_mount_t *mp,#endif if (xfs_sb_version_hascrc (&mp->m_sb)) -platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);/* initialise the AGFL, then fill it if there are blocks left over. */ agfl_buf = libxfs_getbuf(mp->m_dev,@@ -1374,7 +1374,7 @@ build_agf_agfl(xfs_mount_t *mp,if (xfs_sb_version_hascrc (&mp->m_sb)) { agfl->agfl_magicnum =cpu_to_be32 (XFS_AGFL_MAGIC ); agfl->agfl_seqno =cpu_to_be32 (agno); -platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);for (i =0 ; i <XFS_AGFL_SIZE (mp); i++) agfl->agfl_bno[i] =cpu_to_be32 (NULLAGBLOCK ); }repair/phase6.c +3
-3@@ -527,7 +527,7 @@ mk_rbmino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rbmino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);@@ -783,7 +783,7 @@ mk_rsumino(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rsumino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);@@ -897,7 +897,7 @@ mk_root_dir(xfs_mount_t *mp) ip->i_d.di_flags2 =0 ; ip->i_d.di_ino = mp->m_sb.sb_rootino;memset (&(ip->i_d.di_pad2[0 ]),0 ,sizeof (ip->i_d.di_pad2)); -platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +platform_uuid_copy (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); times |=XFS_ICHGTIME_CREATE ; }libxfs_trans_ichgtime (tp, ip, times);
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 3 lines · Eric Sandeen
Final version? This has been through some degree of testing, by changing the UUID after a CRC mkfs, and re-setting it in between two
xfs_repairruns before and after each test in the testsuite.
---
I think I see my problem.
Is there some strong technical reason why 'crc' has to
be on to get -finobt=1 && ftype=1. I'd like to try the latter two features, but the 'crc' stuff has me a bit bugged -- for unanticipated reasons like not being able to set the UUID (I so very often hit those corner cases...*lucky-me*).
Quoted 1 line
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 8 lines · Linda Walsh
Quoted 3 lines · Eric Sandeen
Final version? This has been through some degree of testing, by changing the UUID after a CRC mkfs, and re-setting it in between two
xfs_repairruns before and after each test in the testsuite.---
I think I see my problem.
Oh? what's that? ;)
Quoted 4 lines
Is there some strong technical reason why 'crc' has to be on to get -finobt=1 && ftype=1. I'd like to try the latter twofeatures, but the 'crc' stuff has me a bit bugged -- for unanticipated reasons like not being able to set the UUID (I so very often hit those corner cases...*lucky-me*).
mkfs.xfs -n ftype=1 will get you ftype w/ no crcs.
But some of the above requirements are just because we can't have an infinite test matrix.
Look at ext4 - would you like a flex_bg filesystem with bigalloc? what about a no-extents, meta-bg nodelalloc filesystem? Maybe a 64bit, no-resize-inode ... you get the picture. There are some very dark corners in a test matrix like that.
So the decision was made that for most new features, they were going to depend on the latest rev of the disk format, to keep the xfs code, developers, and users all relatively sane. Relatively...
-Eric
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs