]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_repair: support adding rtgroups to a filesystem
authorDarrick J. Wong <djwong@kernel.org>
Wed, 3 Jul 2024 21:22:06 +0000 (14:22 -0700)
committerChristoph Hellwig <hch@lst.de>
Tue, 6 Aug 2024 12:53:50 +0000 (05:53 -0700)
Allow users to add the rtgroups feature to a filesystem if the
filesystem does not already have a realtime volume attached.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
man/man8/xfs_admin.8
repair/globals.c
repair/globals.h
repair/phase2.c
repair/xfs_repair.c

index e55dee6070e460d33e7bb75417710f3589bb60ca..b92d429cf115982b7cfb08865759945c6f1ef992 100644 (file)
@@ -200,6 +200,24 @@ device.
 The filesystem cannot be downgraded after this feature is enabled.
 This upgrade can fail if any AG has less than 5% free space remaining.
 This feature is not upstream yet.
+.TP 0.4i
+.B rtsb
+Write a superblock to the realtime volume to aid in identifying realtime
+volumes.
+The filesystem cannot be downgraded after this feature is enabled.
+This upgrade is only possible if the filesystem already supports rtgroups.
+This upgrade is not possible if a realtime volume has already been added to the
+filesystem.
+This feature is not upstream yet.
+.TP 0.4i
+.B rtgroups
+Create allocation groups for the realtime volume, to increase parallelism.
+This is required for reverse mapping btrees and reflink support on the realtime
+device.
+The filesystem cannot be downgraded after this feature is enabled.
+This upgrade is not possible if a realtime volume has already been added to the
+filesystem.
+This feature is not upstream yet.
 .RE
 .TP
 .BI \-U " uuid"
index 2b8e5ff649a73b42c0f2e413500792d410750bf2..f2e6145239d8c02999660a5f88438d0544eb5712 100644 (file)
@@ -58,6 +58,8 @@ bool  add_reflink;            /* add reference count btrees */
 bool   add_rmapbt;             /* add reverse mapping btrees */
 bool   add_parent;             /* add parent pointers */
 bool   add_metadir;            /* add metadata directory tree */
+bool   add_rtsb;               /* add realtime superblock */
+bool   add_rtgroups;           /* add realtime allocation groups */
 
 /* misc status variables */
 
index d2222c1d07776fa9ea85c1c1c517fbe09350862b..88d391448244fed6e99125cf8a63c439faaf233f 100644 (file)
@@ -99,6 +99,8 @@ extern bool   add_reflink;            /* add reference count btrees */
 extern bool    add_rmapbt;             /* add reverse mapping btrees */
 extern bool    add_parent;             /* add parent pointers */
 extern bool    add_metadir;            /* add metadata directory tree */
+extern bool    add_rtsb;               /* add realtime superblock */
+extern bool    add_rtgroups;           /* add realtime allocation groups */
 
 /* misc status variables */
 
index 79e589e7ff0432eac3bd38a6e51eb479f0482be3..75fbd7598d29dfbb17d96642461a0b757d03ee53 100644 (file)
@@ -380,6 +380,81 @@ set_metadir(
        return true;
 }
 
+static bool
+set_rtsb(
+       struct xfs_mount        *mp,
+       struct xfs_sb           *new_sb)
+{
+       if (xfs_has_rtsb(mp)) {
+               printf(_("Filesystem already supports realtime superblock.\n"));
+               exit(0);
+       }
+
+       if (!xfs_has_rtgroups(mp) && !add_rtgroups) {
+               printf(
+       _("Realtime superblock feature only supported if realtime groups are enabled.\n"));
+               exit(0);
+       }
+
+       if (!xfs_has_crc(mp)) {
+               printf(
+       _("Realtime superblock only supported on V5 filesystems.\n"));
+               exit(0);
+       }
+
+       if (xfs_has_realtime(mp)) {
+               printf(
+       _("Realtime superblock feature cannot be added to existing realtime volumes.\n"));
+               exit(0);
+       }
+
+       printf(_("Adding realtime superblock to filesystem.\n"));
+       new_sb->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RTSB;
+       new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
+       return true;
+}
+
+static bool
+set_rtgroups(
+       struct xfs_mount        *mp,
+       struct xfs_sb           *new_sb)
+{
+       if (xfs_has_rtgroups(mp)) {
+               printf(_("Filesystem already supports realtime groups.\n"));
+               exit(0);
+       }
+
+       if (!xfs_has_metadir(mp) && !add_metadir) {
+               printf(
+       _("Realtime allocation group feature only supported if metadir is enabled.\n"));
+               exit(0);
+       }
+
+       if (!xfs_has_crc(mp)) {
+               printf(
+       _("Realtime allocation groups only supported on V5 filesystems.\n"));
+               exit(0);
+       }
+
+       if (xfs_has_realtime(mp)) {
+               printf(
+       _("Realtime allocation group feature cannot be added to existing realtime volumes.\n"));
+               exit(0);
+       }
+
+       printf(_("Adding realtime groups to filesystem.\n"));
+       new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_RTGROUPS;
+       new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
+       new_sb->sb_rgcount = 0;
+       /*
+        * The allocation group size is 1TB, rounded down to the nearest rt
+        * extent.
+        */
+       new_sb->sb_rgextents =
+               (1ULL << (40 - mp->m_sb.sb_blocklog)) >> mp->m_sb.sb_rextslog;
+       return true;
+}
+
 struct check_state {
        struct xfs_sb           sb;
        uint64_t                features;
@@ -657,6 +732,10 @@ upgrade_filesystem(
                dirty |= set_parent(mp, &new_sb);
        if (add_metadir)
                dirty |= set_metadir(mp, &new_sb);
+       if (add_rtsb)
+               dirty |= set_rtsb(mp, &new_sb);
+       if (add_rtgroups)
+               dirty |= set_rtgroups(mp, &new_sb);
        if (!dirty)
                return;
 
index 2142031554732f115cd8be595428c43cf421604f..53fa47dc9673caa0ed5825c66a5ef80866b76151 100644 (file)
@@ -76,6 +76,8 @@ enum c_opt_nums {
        CONVERT_RMAPBT,
        CONVERT_PARENT,
        CONVERT_METADIR,
+       CONVERT_RTSB,
+       CONVERT_RTGROUPS,
        C_MAX_OPTS,
 };
 
@@ -90,6 +92,8 @@ static char *c_opts[] = {
        [CONVERT_RMAPBT]        = "rmapbt",
        [CONVERT_PARENT]        = "parent",
        [CONVERT_METADIR]       = "metadir",
+       [CONVERT_RTSB]          = "rtsb",
+       [CONVERT_RTGROUPS]      = "rtgroups",
        [C_MAX_OPTS]            = NULL,
 };
 
@@ -427,6 +431,24 @@ process_args(int argc, char **argv)
                _("-c metadir only supports upgrades\n"));
                                        add_metadir = true;
                                        break;
+                               case CONVERT_RTSB:
+                                       if (!val)
+                                               do_abort(
+               _("-c rtsb requires a parameter\n"));
+                                       if (strtol(val, NULL, 0) != 1)
+                                               do_abort(
+               _("-c rtsb only supports upgrades\n"));
+                                       add_rtsb = true;
+                                       break;
+                               case CONVERT_RTGROUPS:
+                                       if (!val)
+                                               do_abort(
+               _("-c rtgroups requires a parameter\n"));
+                                       if (strtol(val, NULL, 0) != 1)
+                                               do_abort(
+               _("-c rtgroups only supports upgrades\n"));
+                                       add_rtgroups = true;
+                                       break;
                                default:
                                        unknown('c', val);
                                        break;