From: Darrick J. Wong <djwong@xxxxxxxxxx> Use xfs_repair to add the inode btree counter feature to a filesystem. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- man/man8/xfs_admin.8 | 11 ++++++++++- repair/globals.c | 1 + repair/globals.h | 1 + repair/phase1.c | 29 +++++++++++++++++++++++++++++ repair/xfs_repair.c | 11 +++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8 index 3f3aeea8..da05171d 100644 --- a/man/man8/xfs_admin.8 +++ b/man/man8/xfs_admin.8 @@ -126,7 +126,16 @@ without the .BR -n ) must be followed to clean the filesystem. .IP -There are currently no feature options. +Supported features are as follows: +.RS 0.7i +.TP 0.4i +.B inobtcount +Keep a count the number of blocks in each inode btree in the AGI. +This reduces mount time by speeding up metadata space reservation calculations. +The filesystem cannot be downgraded after this feature is enabled. +Once enabled, the filesystem will not be writable by older kernels. +This feature was added to Linux 5.10. +.RE .TP .BI \-U " uuid" Set the UUID of the filesystem to diff --git a/repair/globals.c b/repair/globals.c index b0e23864..89063b10 100644 --- a/repair/globals.c +++ b/repair/globals.c @@ -51,6 +51,7 @@ int convert_lazy_count; /* Convert lazy-count mode on/off */ int lazy_count; /* What to set if to if converting */ bool add_needsrepair; /* forcibly set needsrepair while repairing */ +bool add_inobtcount; /* add inode btree counts to AGI */ /* misc status variables */ diff --git a/repair/globals.h b/repair/globals.h index 9fa73b2c..a0051794 100644 --- a/repair/globals.h +++ b/repair/globals.h @@ -93,6 +93,7 @@ extern int convert_lazy_count; /* Convert lazy-count mode on/off */ extern int lazy_count; /* What to set if to if converting */ extern bool add_needsrepair; +extern bool add_inobtcount; /* misc status variables */ diff --git a/repair/phase1.c b/repair/phase1.c index 57f72cd0..96661c6b 100644 --- a/repair/phase1.c +++ b/repair/phase1.c @@ -50,6 +50,33 @@ set_needsrepair( sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR; } +static void +set_inobtcount( + struct xfs_sb *sb) +{ + if (!xfs_sb_version_hascrc(sb)) { + printf( + _("Inode btree count feature only supported on V5 filesystems.\n")); + exit(0); + } + + if (!xfs_sb_version_hasfinobt(sb)) { + printf( + _("Inode btree count feature requires free inode btree.\n")); + exit(0); + } + + if (xfs_sb_version_hasinobtcounts(sb)) { + printf(_("Filesystem already has inode btree counts.\n")); + return; + } + + printf(_("Adding inode btree counts to filesystem.\n")); + primary_sb_modified = 1; + sb->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT; + sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR; +} + /* * this has got to be big enough to hold 4 sectors */ @@ -148,6 +175,8 @@ _("Cannot disable lazy-counters on V5 fs\n")); if (add_needsrepair) set_needsrepair(sb); + if (add_inobtcount) + set_inobtcount(sb); /* shared_vn should be zero */ if (sb->sb_shared_vn) { diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index ae7106a6..0ff2e2bc 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -68,12 +68,14 @@ static char *o_opts[] = { enum c_opt_nums { CONVERT_LAZY_COUNT = 0, CONVERT_NEEDSREPAIR, + CONVERT_INOBTCOUNT, C_MAX_OPTS, }; static char *c_opts[] = { [CONVERT_LAZY_COUNT] = "lazycount", [CONVERT_NEEDSREPAIR] = "needsrepair", + [CONVERT_INOBTCOUNT] = "inobtcount", [C_MAX_OPTS] = NULL, }; @@ -316,6 +318,15 @@ process_args(int argc, char **argv) if (strtol(val, NULL, 0) == 1) add_needsrepair = true; break; + case CONVERT_INOBTCOUNT: + if (!val) + do_abort( + _("-c inobtcount requires a parameter\n")); + if (strtol(val, NULL, 0) != 1) + do_abort( + _("-c inobtcount only supports upgrades\n")); + add_inobtcount = true; + break; default: unknown('c', val); break;