]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
mkfs.xfs: enable metadata directories
authorDarrick J. Wong <djwong@kernel.org>
Thu, 21 Nov 2024 00:24:22 +0000 (16:24 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 24 Dec 2024 02:01:28 +0000 (18:01 -0800)
Enable formatting filesystems with metadata directories.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/libxfs_api_defs.h
man/man8/mkfs.xfs.8.in
mkfs/lts_4.19.conf
mkfs/lts_5.10.conf
mkfs/lts_5.15.conf
mkfs/lts_5.4.conf
mkfs/lts_6.1.conf
mkfs/lts_6.12.conf
mkfs/lts_6.6.conf
mkfs/proto.c
mkfs/xfs_mkfs.c

index e79aa0e06e4f90682379760ab05e1dec57ce03e1..2f218296688477356f90f4a7a34ece6dd68ec63b 100644 (file)
 #define xfs_metafile_iget              libxfs_metafile_iget
 #define xfs_trans_metafile_iget                libxfs_trans_metafile_iget
 #define xfs_metafile_set_iflag         libxfs_metafile_set_iflag
+#define xfs_metadir_cancel             libxfs_metadir_cancel
+#define xfs_metadir_commit             libxfs_metadir_commit
 #define xfs_metadir_link               libxfs_metadir_link
 #define xfs_metadir_lookup             libxfs_metadir_lookup
 #define xfs_metadir_start_create       libxfs_metadir_start_create
index e56c8f31a52c78b2237b7ca21af8e4e3b8754c37..de5f6baf59df9564d936b0c97b9960c9bab63695 100644 (file)
@@ -271,6 +271,17 @@ option set.
 When the option
 .B \-m finobt=0
 is used, the inode btree counter feature is not supported and is disabled.
+.TP
+.BI metadir= value
+This option creates an internal directory tree to store filesystem metadata.
+.IP
+By default,
+.B mkfs.xfs
+will not enable this feature.
+If the option
+.B \-m crc=0
+is used, the metadata directory feature is not supported and is disabled.
+
 .TP
 .BI uuid= value
 Use the given value as the filesystem UUID for the newly created filesystem.
index 4f190bacf9780cad147f7ffc3124e2090cfcc7c1..4aa12f429ca2dda44d43142377dfae92ed20b6da 100644 (file)
@@ -6,6 +6,7 @@ bigtime=0
 crc=1
 finobt=1
 inobtcount=0
+metadir=0
 reflink=0
 rmapbt=0
 autofsck=0
index a55fc68e4e3f2f12f52aea8cd5743fd80aa53f9d..9625135c011f088860201bef014b6c06e035285c 100644 (file)
@@ -6,6 +6,7 @@ bigtime=0
 crc=1
 finobt=1
 inobtcount=0
+metadir=0
 reflink=1
 rmapbt=0
 autofsck=0
index daea0b40671936fc8e453c13b83c9c71bf020ba7..5306fad7e02f0feb725d1e608fc5cddd0f5263f8 100644 (file)
@@ -6,6 +6,7 @@ bigtime=1
 crc=1
 finobt=1
 inobtcount=1
+metadir=0
 reflink=1
 rmapbt=0
 autofsck=0
index 0f807fc35e34b4558a0e0951069a94f3c09d33e4..9114388b0248a5dbdf33aa66c4af48657a099ddb 100644 (file)
@@ -6,6 +6,7 @@ bigtime=0
 crc=1
 finobt=1
 inobtcount=0
+metadir=0
 reflink=1
 rmapbt=0
 autofsck=0
index 0ff5bbad5a1c2dfada4b8e141e0b5bb88d60bc60..1d5378042eed6c547a358d8a426a9841ceea3598 100644 (file)
@@ -6,6 +6,7 @@ bigtime=1
 crc=1
 finobt=1
 inobtcount=1
+metadir=0
 reflink=1
 rmapbt=0
 autofsck=0
index 35b79082495d24526bc017d87d011d9880fbffe2..b204b78511f666512f2f2c3edbb38d941a4d0aac 100644 (file)
@@ -6,6 +6,7 @@ bigtime=1
 crc=1
 finobt=1
 inobtcount=1
+metadir=0
 reflink=1
 rmapbt=1
 autofsck=0
index 2ef5957e0b3a3faf25948f5e0d9bd75ea9e18028..d2649c562fac12c33c2e170ca924677b3ddc37d5 100644 (file)
@@ -6,6 +6,7 @@ bigtime=1
 crc=1
 finobt=1
 inobtcount=1
+metadir=0
 reflink=1
 rmapbt=1
 autofsck=0
index d8eb6ca33672bd84f63ad33e73e129c9b7f369c6..05c2621f8a0b13d30f3954949f45bb4b8d708da7 100644 (file)
@@ -471,6 +471,65 @@ creatproto(
        return 0;
 }
 
+/* Create a new metadata root directory. */
+static int
+create_metadir(
+       struct xfs_mount        *mp)
+{
+       struct xfs_inode        *ip = NULL;
+       struct xfs_trans        *tp;
+       int                     error;
+       struct xfs_icreate_args args = {
+               .mode           = S_IFDIR,
+               .flags          = XFS_ICREATE_UNLINKABLE,
+       };
+       xfs_ino_t               ino;
+
+       if (!xfs_has_metadir(mp))
+               return 0;
+
+       error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_create,
+                       libxfs_create_space_res(mp, MAXNAMELEN), 0, 0, &tp);
+       if (error)
+               return error;
+
+       /*
+        * Create a new inode and set the sb pointer.  The primary super is
+        * still marked inprogress, so we do not need to log the metadirino
+        * change ourselves.
+        */
+       error = -libxfs_dialloc(&tp, &args, &ino);
+       if (error)
+               goto out_cancel;
+       error = -libxfs_icreate(tp, ino, &args, &ip);
+       if (error)
+               goto out_cancel;
+       mp->m_sb.sb_metadirino = ino;
+
+       /*
+        * Initialize the root directory.  There are no ILOCKs in userspace
+        * so we do not need to drop it here.
+        */
+       libxfs_metafile_set_iflag(tp, ip, XFS_METAFILE_DIR);
+       error = -libxfs_dir_init(tp, ip, ip);
+       if (error)
+               goto out_cancel;
+
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               goto out_rele;
+
+       mp->m_metadirip = ip;
+       return 0;
+
+out_cancel:
+       libxfs_trans_cancel(tp);
+out_rele:
+       if (ip)
+               libxfs_irele(ip);
+       return error;
+}
+
 static void
 parseproto(
        xfs_mount_t     *mp,
@@ -709,8 +768,15 @@ parseproto(
                 * RT initialization.  Do this here to ensure that
                 * the RT inodes get placed after the root inode.
                 */
-               if (isroot)
+               if (isroot) {
+                       error = create_metadir(mp);
+                       if (error)
+                               fail(
+       _("Creation of the metadata directory inode failed"),
+                                       error);
+
                        rtinit(mp);
+               }
                tp = NULL;
                for (;;) {
                        name = getdirentname(pp);
index bbd0dbb6c80ab63ebf9edbe0a9a304149770f89d..4e51caead9dac2aef147238224264cfade246b6e 100644 (file)
@@ -150,6 +150,7 @@ enum {
        M_INOBTCNT,
        M_BIGTIME,
        M_AUTOFSCK,
+       M_METADIR,
        M_MAX_OPTS,
 };
 
@@ -812,6 +813,7 @@ static struct opt_params mopts = {
                [M_INOBTCNT] = "inobtcount",
                [M_BIGTIME] = "bigtime",
                [M_AUTOFSCK] = "autofsck",
+               [M_METADIR] = "metadir",
                [M_MAX_OPTS] = NULL,
        },
        .subopt_params = {
@@ -861,6 +863,12 @@ static struct opt_params mopts = {
                  .maxval = 1,
                  .defaultval = 1,
                },
+               { .index = M_METADIR,
+                 .conflicts = { { NULL, LAST_CONFLICT } },
+                 .minval = 0,
+                 .maxval = 1,
+                 .defaultval = 1,
+               },
        },
 };
 
@@ -913,6 +921,7 @@ struct sb_feat_args {
        bool    reflink;                /* XFS_SB_FEAT_RO_COMPAT_REFLINK */
        bool    inobtcnt;               /* XFS_SB_FEAT_RO_COMPAT_INOBTCNT */
        bool    bigtime;                /* XFS_SB_FEAT_INCOMPAT_BIGTIME */
+       bool    metadir;                /* XFS_SB_FEAT_INCOMPAT_METADIR */
        bool    nodalign;
        bool    nortalign;
        bool    nrext64;
@@ -1048,7 +1057,8 @@ usage( void )
 /* blocksize */                [-b size=num]\n\
 /* config file */      [-c options=xxx]\n\
 /* metadata */         [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\
-                           inobtcount=0|1,bigtime=0|1,autofsck=xxx]\n\
+                           inobtcount=0|1,bigtime=0|1,autofsck=xxx,\n\
+                           metadir=0|1]\n\
 /* data subvol */      [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
                            (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
                            sectsize=num,concurrency=num]\n\
@@ -1883,6 +1893,9 @@ meta_opts_parser(
                                illegal(value, "m autofsck");
                }
                break;
+       case M_METADIR:
+               cli->sb_feat.metadir = getnum(value, opts, subopt);
+               break;
        default:
                return -EINVAL;
        }
@@ -2465,6 +2478,14 @@ _("autofsck not supported without CRC support\n"));
                        usage();
                }
                cli->autofsck = FSPROP_AUTOFSCK_UNSET;
+
+               if (cli->sb_feat.metadir &&
+                   cli_opt_set(&mopts, M_METADIR)) {
+                       fprintf(stderr,
+_("metadata directory not supported without CRC support\n"));
+                       usage();
+               }
+               cli->sb_feat.metadir = false;
        }
 
        if (!cli->sb_feat.finobt) {
@@ -3568,7 +3589,8 @@ sb_set_features(
         * the sb_bad_features2 field. To avoid older kernels mounting
         * filesystems they shouldn't, set both field to the same value.
         */
-       sbp->sb_bad_features2 = sbp->sb_features2;
+       if (!fp->metadir)
+               sbp->sb_bad_features2 = sbp->sb_features2;
 
        if (!fp->crcs_enabled)
                return;
@@ -3618,6 +3640,8 @@ sb_set_features(
                 */
                sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
        }
+       if (fp->metadir)
+               sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_METADIR;
 }
 
 /*
@@ -4053,6 +4077,7 @@ finish_superblock_setup(
        platform_uuid_copy(&sbp->sb_meta_uuid, &cfg->uuid);
        sbp->sb_logstart = cfg->logstart;
        sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO;
+       sbp->sb_metadirino = NULLFSINO;
        sbp->sb_agcount = (xfs_agnumber_t)cfg->agcount;
        sbp->sb_rbmblocks = cfg->rtbmblocks;
        sbp->sb_logblocks = (xfs_extlen_t)cfg->logblocks;
@@ -4279,6 +4304,8 @@ rewrite_secondary_superblocks(
        }
        dsb = buf->b_addr;
        dsb->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
+       if (xfs_has_metadir(mp))
+               dsb->sb_metadirino = cpu_to_be64(mp->m_sb.sb_metadirino);
        libxfs_buf_mark_dirty(buf);
        libxfs_buf_relse(buf);
 
@@ -4297,6 +4324,8 @@ rewrite_secondary_superblocks(
        }
        dsb = buf->b_addr;
        dsb->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
+       if (xfs_has_metadir(mp))
+               dsb->sb_metadirino = cpu_to_be64(mp->m_sb.sb_metadirino);
        libxfs_buf_mark_dirty(buf);
        libxfs_buf_relse(buf);
 }