]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfsprogs: Add new sb_meta_uuid field, update userspace tools to manipulate it
authorEric Sandeen <sandeen@sandeen.net>
Mon, 3 Aug 2015 00:45:00 +0000 (10:45 +1000)
committerDave Chinner <david@fromorbit.com>
Mon, 3 Aug 2015 00:45:00 +0000 (10:45 +1000)
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 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

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
29 files changed:
copy/xfs_copy.c
db/sb.c
libxfs/xfs_alloc.c
libxfs/xfs_alloc_btree.c
libxfs/xfs_attr_leaf.c
libxfs/xfs_attr_remote.c
libxfs/xfs_bmap_btree.c
libxfs/xfs_btree.c
libxfs/xfs_da_btree.c
libxfs/xfs_dir2_block.c
libxfs/xfs_dir2_data.c
libxfs/xfs_dir2_leaf.c
libxfs/xfs_dir2_node.c
libxfs/xfs_dquot_buf.c
libxfs/xfs_format.h
libxfs/xfs_ialloc.c
libxfs/xfs_ialloc_btree.c
libxfs/xfs_inode_buf.c
libxfs/xfs_sb.c
libxfs/xfs_symlink_remote.c
libxlog/util.c
man/man8/xfs_admin.8
man/man8/xfs_db.8
mkfs/xfs_mkfs.c
repair/agheader.c
repair/agheader.h
repair/dinode.c
repair/phase5.c
repair/phase6.c

index 279527cdad005a2332e36d3e3499a7b2be718aa9..2f9e4431f564f2f6a0b605f09316b859a04ea479 100644 (file)
@@ -25,6 +25,7 @@
 #include "xfs_copy.h"
 
 #define        rounddown(x, y) (((x)/(y))*(y))
+#define uuid_equal(s,d) (platform_uuid_compare((s),(d)) == 0)
 
 extern int     platform_check_ismounted(char *, char *, struct stat64 *, int);
 
@@ -466,6 +467,36 @@ 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 we are changing the UUID in the copy, we need
+        * to copy the original UUID into the meta_uuid slot and set the
+        * set the incompat flag if that hasn't already been done.
+        */
+       if (!uuid_equal(&tcarg->uuid, &ag_hdr->xfs_sb->sb_uuid) &&
+           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 may 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++;
                        }
diff --git a/db/sb.c b/db/sb.c
index b36680bef3abdfe6f942e7df7c7ce1c3cee3933c..5481fc327b55f42b4ea100b7d27a6a9bb2cc7064 100644 (file)
--- a/db/sb.c
+++ b/db/sb.c
@@ -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);
@@ -122,6 +124,7 @@ const field_t       sb_flds[] = {
        { "spino_align", FLDT_EXTLEN, OI(OFF(spino_align)), 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 }
 };
 
@@ -322,6 +325,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();
@@ -351,18 +380,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")) {
@@ -376,6 +393,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"));
@@ -652,6 +680,8 @@ version_string(
                strcat(s, ",FINOBT");
        if (xfs_sb_version_hassparseinodes(sbp))
                strcat(s, ",SPARSE_INODES");
+       if (xfs_sb_version_hasmetauuid(sbp))
+               strcat(s, ",META_UUID");
        return s;
 }
 
index 0d9b4c318cb46bc5ea0097c7fd96bc9a94f492e4..9d763296a66244ca9dbdc241edcd12396dc61702 100644 (file)
@@ -460,7 +460,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;
@@ -2256,7 +2256,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) &&
index 7fd72af95b0b214cff1e2f1772a1151c2647eb3a..e60538a97ac767dbb08b578d58d163b5c305d193 100644 (file)
@@ -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;
index 8f0772abd98345a3862d606c80e22cac93e37e9f..cc2506822da6d89fb06da92a1376696b5b82b041 100644 (file)
@@ -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 {
index 4f492c18cc8c9bfb13ffff5cf3a7d9a87ef03fd5..5feaf55d65e8e007318944b053b3d73daa0a5715 100644 (file)
@@ -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);
 
index 2fd04e0cd19a43d62a965865070357318a0ca619..f42bc2d7a5a34fa404d720c12d868fc60bc386e1 100644 (file)
@@ -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;
index 203e7d20f07b19d981184bf300325cc027381731..a16ae7d16bf331765411a069caf221f941978988 100644 (file)
@@ -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;
                }
        }
index 441bef4ec1d7949447ece2b2ef5ce1eb17f2e3d8..3de4cd3030c2a0b11ab29419a5253ed23e7b65ab 100644 (file)
@@ -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;
        }
index f061a99a3f11b31cd9fecfab044c015346b9aaca..489f301feda21e3e3789871b0bf0a4a15ea16b78 100644 (file)
@@ -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;
 
        }
index 609c097bb1e922745b3ddffab93e9dbe0768436a..c475ba888b886acde48c016dcc6044f460875aaa 100644 (file)
@@ -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);
index c2dba8a4e78b545acb3741c7d50fb9ffb5e7158c..80d03b3bd328e5dab4d12be2956d1263eb7d0177 100644 (file)
@@ -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);
index 3b71e9e514205ee3b25e4e1535d7430d9e813fe0..581d648a1d1601bb46e97b978e44c79117bd216e 100644 (file)
@@ -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);
index 2e0484a6fe48c57c2fdfaccbb34a92e634ff5e4c..1a2546b40910c9f72c101b7812ccfdc857ab1509 100644 (file)
@@ -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;
index 68d41753f35c54520a7778a53c04d5e6732e78af..282926da33c8fa1770f2bb536032c0cb9d4415f5 100644 (file)
@@ -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;
@@ -458,9 +460,12 @@ xfs_sb_has_ro_compat_feature(
 
 #define XFS_SB_FEAT_INCOMPAT_FTYPE     (1 << 0)        /* filetype in dirent */
 #define XFS_SB_FEAT_INCOMPAT_SPINODES  (1 << 1)        /* sparse inode chunks */
+#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2)        /* metadata UUID */
+
 #define XFS_SB_FEAT_INCOMPAT_ALL \
                (XFS_SB_FEAT_INCOMPAT_FTYPE|    \
-                XFS_SB_FEAT_INCOMPAT_SPINODES)
+                XFS_SB_FEAT_INCOMPAT_SPINODES| \
+                XFS_SB_FEAT_INCOMPAT_META_UUID)
 
 #define XFS_SB_FEAT_INCOMPAT_UNKNOWN   ~XFS_SB_FEAT_INCOMPAT_ALL
 static inline bool
@@ -514,6 +519,18 @@ static inline bool xfs_sb_version_hassparseinodes(struct xfs_sb *sbp)
                xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_SPINODES);
 }
 
+/*
+ * 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
  */
index 05ecd061768c7085e93e095ca1474f00ba2f2954..d26027cd8ff42fff6b1470f8d6ca8a10bbbc921b 100644 (file)
@@ -333,7 +333,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 */
@@ -2495,7 +2496,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.
index 7055149d0ecbebcf7697c8137066f50e29f115b3..09ffdb42e36873eb24b8fa513d882a3d393d69b2 100644 (file)
@@ -238,7 +238,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;
index b8e65a9b1173bd47834cd72ff962a74771ac46ef..be9d1662af5bdb2ccc113c9b1dc4efb735fe4bc9 100644 (file)
@@ -302,7 +302,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;
 }
@@ -364,7 +364,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;
index 81cd1811c391bc247b8ae23d53f4edc537656e07..54cad5630a5956a7ac9cc9ff26833c52d5f907bf 100644 (file)
@@ -381,6 +381,14 @@ __xfs_sb_from_disk(
        to->sb_spino_align = be32_to_cpu(from->sb_spino_align);
        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);
@@ -522,6 +530,8 @@ xfs_sb_to_disk(
                                cpu_to_be32(from->sb_features_log_incompat);
                to->sb_spino_align = cpu_to_be32(from->sb_spino_align);
                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);
        }
 }
 
index 6bc5af530373f3c924ea5fa4b56bc4e952a1d3d6..7d46d9ee08c87e4ae3e1044781245f21a7d34c71 100644 (file)
@@ -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;
index 498c06ce61229e3b5ec3f6cba38f87610d91bd4b..4a7fc36eb1306f912c31ee002819cb9d1ac65546 100644 (file)
@@ -85,8 +85,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);
index b393d7446ead1b1d80bd4af121bd99e860b4d5d8..c17b35ee94e514535a883efcaaf660eed318e5ea 100644 (file)
@@ -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.
index d52723060028de01572561e85a90605002a9f08c..df54bb7bd3a64cd9be1a90223e130978adccbdf7 100644 (file)
@@ -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.
index f3901beac36684413a929ce6ad8235b03b03216d..a9afa999e0d81ac19f338d5f1becb63d5b8e380f 100644 (file)
@@ -2628,6 +2628,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;
index 9ae2deb36d68ccfbe712d73e4cbe5d4991370f16..cfca529f817740142beec6adc5717e2081a94a99 100644 (file)
@@ -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);
index 5541fb96df68086232b76db4cd6c00183b25ad9c..6b2974ca765ad04e3e5ff940043c81330a5cf70b 100644 (file)
@@ -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 */
index 179203ee1a3062a90842688b03b1d32eb4a30e0e..0ea5a9ea6676ce61e411b712676fbe82dd774b2e 100644 (file)
@@ -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);
index b5a53b192b3c0991a4623f4c42152210699ec630..079b8b406488c81c8a6e0e0d586ddb675e8d4f85 100644 (file)
@@ -1128,7 +1128,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);
@@ -1406,7 +1406,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,
@@ -1420,7 +1420,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);
        }
index 130ed4f1ba68ddf0f21029848e12a3bb6f6521fd..09da2e22a12358b731476533bc207c8db313b887 100644 (file)
@@ -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);