From fa316ead819fc0ed3bc46a9994295537b8510c17 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 3 Jul 2024 14:22:06 -0700 Subject: [PATCH] xfs_repair: support adding rtgroups to a filesystem 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 --- man/man8/xfs_admin.8 | 18 ++++++++++ repair/globals.c | 2 ++ repair/globals.h | 2 ++ repair/phase2.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ repair/xfs_repair.c | 22 ++++++++++++ 5 files changed, 123 insertions(+) diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8 index e55dee607..b92d429cf 100644 --- a/man/man8/xfs_admin.8 +++ b/man/man8/xfs_admin.8 @@ -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" diff --git a/repair/globals.c b/repair/globals.c index 2b8e5ff64..f2e614523 100644 --- a/repair/globals.c +++ b/repair/globals.c @@ -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 */ diff --git a/repair/globals.h b/repair/globals.h index d2222c1d0..88d391448 100644 --- a/repair/globals.h +++ b/repair/globals.h @@ -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 */ diff --git a/repair/phase2.c b/repair/phase2.c index 79e589e7f..75fbd7598 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -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; diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 214203155..53fa47dc9 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -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; -- 2.50.1