Linux XFS filesystem development
 help / color / mirror / Atom feed
* [PATCHSET 2/2] xfsprogs: generate mkfs.xfs config files
@ 2026-08-31 23:26 Darrick J. Wong
  2026-08-31 23:26 ` [PATCH 1/5] mkfs: automatically upgrade autofsck earlier Darrick J. Wong
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Darrick J. Wong @ 2026-08-31 23:26 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: linux-xfs

Hi all,

Every year, we generate a new mkfs.xfs configuration file to match the
stable feature set of that year's LTS kernel.  Right now I just do this
by copying the old configuration file and tweaking the values by hand.

Instead, let's create some library code that can emit the same
configuration variables that we've been shipping for some years now,
and hook that up to mkfs/xfs_db/xfs_spaceman so that we can generate
them either from the mkfs defaults or pre-existing filesystems.

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

With a bit of luck, this should all go splendidly.
Comments and questions are, as always, welcome.

--D

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=generate-cfgfiles
---
Commits in this patchset:
 * mkfs: automatically upgrade autofsck earlier
 * mkfs: print config file for a given mkfs configuration
 * xfs_db: print configuration file for mounted filesystems
 * xfs_spaceman: print configuration file for mounted filesystems
 * xfs_admin: print configuration file for mounted filesystems
---
 libfrog/fsgeom.h        |    3 
 db/info.c               |  193 ++++++++++++++++++++++++
 db/xfs_admin.sh         |   15 ++
 libfrog/fsgeom.c        |  376 +++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/mkfs.xfs.8.in  |    6 +
 man/man8/xfs_admin.8    |    7 +
 man/man8/xfs_db.8       |    6 +
 man/man8/xfs_spaceman.8 |    6 +
 mkfs/xfs_mkfs.c         |   62 +++++++-
 spaceman/info.c         |  136 +++++++++++++++++
 10 files changed, 798 insertions(+), 12 deletions(-)


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/5] mkfs: automatically upgrade autofsck earlier
  2026-08-31 23:26 [PATCHSET 2/2] xfsprogs: generate mkfs.xfs config files Darrick J. Wong
@ 2026-08-31 23:26 ` Darrick J. Wong
  2026-09-03 11:17   ` Andrey Albershteyn
  2026-08-31 23:27 ` [PATCH 2/5] mkfs: print config file for a given mkfs configuration Darrick J. Wong
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2026-08-31 23:26 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Move this chunk of code earlier in mkfs.xfs because a subsequent patch
will need the final value of cli.autofsck at the point where we do the
dry run reporting stuff.  Nobody changes cli.autofsck after
validate_sb_features().

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 mkfs/xfs_mkfs.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)


diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index a4864c37a8821b..74bbb677eee2b6 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -6106,6 +6106,15 @@ main(
 	validate_zoned(&cfg, &cli, &dft, &zt);
 	validate_sb_features(&cfg, &cli);
 
+	/*
+	 * If the filesystem has full backreferences and the user didn't
+	 * express an autofsck preference, enable online repair because they
+	 * might as well get some useful functionality from the extra metadata.
+	 */
+	if (cli.autofsck == FSPROP_AUTOFSCK_UNSET &&
+	    cli.sb_feat.rmapbt && cli.sb_feat.parent_pointers)
+		cli.autofsck = FSPROP_AUTOFSCK_REPAIR;
+
 	/*
 	 * we've now completed basic validation of the features, sector and
 	 * block sizes, so from this point onwards we use the values found in
@@ -6297,15 +6306,6 @@ main(
 	if (mp->m_sb.sb_agcount > 1)
 		rewrite_secondary_superblocks(mp);
 
-	/*
-	 * If the filesystem has full backreferences and the user didn't
-	 * express an autofsck preference, enable online repair because they
-	 * might as well get some useful functionality from the extra metadata.
-	 */
-	if (cli.autofsck == FSPROP_AUTOFSCK_UNSET &&
-	    cli.sb_feat.rmapbt && cli.sb_feat.parent_pointers)
-		cli.autofsck = FSPROP_AUTOFSCK_REPAIR;
-
 	if (cli.autofsck != FSPROP_AUTOFSCK_UNSET)
 		set_autofsck(mp, &cli);
 


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/5] mkfs: print config file for a given mkfs configuration
  2026-08-31 23:26 [PATCHSET 2/2] xfsprogs: generate mkfs.xfs config files Darrick J. Wong
  2026-08-31 23:26 ` [PATCH 1/5] mkfs: automatically upgrade autofsck earlier Darrick J. Wong
@ 2026-08-31 23:27 ` Darrick J. Wong
  2026-09-03 11:14   ` Andrey Albershteyn
  2026-08-31 23:27 ` [PATCH 3/5] xfs_db: print configuration file for mounted filesystems Darrick J. Wong
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2026-08-31 23:27 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Add a -c makecfg= switch to mkfs to emit a mkfs.xfs configuration file
documenting the user-visible filesystem featuresets of the configured
filesystem.  This can be used to emit default configuration files as we
do once a year for each LTS.

Note that geometry information is not written to the configuration file.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 libfrog/fsgeom.h       |    3 
 libfrog/fsgeom.c       |  376 ++++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/mkfs.xfs.8.in |    6 +
 mkfs/xfs_mkfs.c        |   44 +++++-
 4 files changed, 428 insertions(+), 1 deletion(-)


diff --git a/libfrog/fsgeom.h b/libfrog/fsgeom.h
index b851b9bbf36a58..1109dd2bcdb4cc 100644
--- a/libfrog/fsgeom.h
+++ b/libfrog/fsgeom.h
@@ -217,4 +217,7 @@ bytes_per_rtgroup(
 		fsgeo->blocksize;
 }
 
+int xfrog_write_mkfs_config(const struct xfs_fsop_geom *fsgeo,
+		const struct fsxattr *fsx, int autofsck, FILE *fp);
+
 #endif /* __LIBFROG_FSGEOM_H__ */
diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
index 571d376c6b3c28..fdb7b96e06b246 100644
--- a/libfrog/fsgeom.c
+++ b/libfrog/fsgeom.c
@@ -7,6 +7,8 @@
 #include "bitops.h"
 #include "fsgeom.h"
 #include "util.h"
+#include "list.h"
+#include "libfrog/fsproperties.h"
 
 static inline const char *
 rtdev_name(
@@ -250,3 +252,377 @@ xfrog_rtgroup_geometry(
 		return -errno;
 	return 0;
 }
+
+enum {
+	M_CRC = 0,
+	M_FINOBT,
+	M_RMAPBT,
+	M_REFLINK,
+	M_INOBTCNT,
+	M_BIGTIME,
+	M_METADIR,
+	M_AUTOFSCK,
+	M_MAX_OPTS,
+};
+
+enum {
+	D_RTINHERIT = 0,
+	D_PROJINHERIT,
+	D_EXTSZINHERIT,
+	D_COWEXTSIZE,
+	D_DAXINHERIT,
+	D_MAX_OPTS,
+};
+
+enum {
+	I_SPINODES = 0,
+	I_NREXT64,
+	I_EXCHANGE,
+	I_MAX_OPTS,
+};
+
+enum {
+	N_PARENT = 0,
+	N_FTYPE,
+	N_VERSION,
+	N_MAX_OPTS,
+};
+
+enum {
+	R_EXTSIZE = 0,
+	R_MAX_OPTS,
+};
+
+struct mkfs_config_opt;
+
+struct mkfs_config_data {
+	const struct xfs_fsop_geom	*fsgeo;
+	const struct fsxattr		*fsx;
+	enum fsprop_autofsck		autofsck;
+};
+
+typedef int (*opt_print_fn)(const struct mkfs_config_opt *opt,
+			    const struct mkfs_config_data *data,
+			    FILE *fp);
+
+struct mkfs_config_opt {
+	const char		*name;
+	uint64_t		fsgeom_flag;
+	uint64_t		xflags_flag;
+	opt_print_fn		print_fn;
+};
+
+struct mkfs_config_section {
+	const char		*ini_section;
+	struct mkfs_config_opt	subopts[16];
+};
+
+static int
+print_fsgeom(
+	const struct mkfs_config_opt	*opt,
+	const struct mkfs_config_data	*data,
+	FILE				*fp)
+{
+	const struct xfs_fsop_geom	*fsgeo = data->fsgeo;
+	int				ret;
+
+	ret = fprintf(fp, "%s=%d\n", opt->name,
+			!!(fsgeo->flags & opt->fsgeom_flag));
+	if (ret <= 0)
+		return ret;
+	return 0;
+}
+
+static int
+print_xflag(
+	const struct mkfs_config_opt	*opt,
+	const struct mkfs_config_data	*data,
+	FILE				*fp)
+{
+	const struct fsxattr		*fsx = data->fsx;
+	int				ret;
+
+	if (!(fsx->fsx_xflags & opt->xflags_flag))
+		return 0;
+
+	ret = fprintf(fp, "%s=%d\n", opt->name, 1);
+	if (ret <= 0)
+		return ret;
+	return 0;
+}
+
+static int
+print_projinherit(
+	const struct mkfs_config_opt	*opt,
+	const struct mkfs_config_data	*data,
+	FILE				*fp)
+{
+	const struct fsxattr		*fsx = data->fsx;
+	int				ret;
+
+	if (fsx->fsx_xflags & FS_XFLAG_PROJINHERIT) {
+		ret = fprintf(fp, "%s=%u\n", opt->name, fsx->fsx_projid);
+		if (ret <= 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+print_extszinherit(
+	const struct mkfs_config_opt	*opt,
+	const struct mkfs_config_data	*data,
+	FILE				*fp)
+{
+	const struct fsxattr		*fsx = data->fsx;
+	int				ret;
+
+	if (fsx->fsx_xflags & FS_XFLAG_EXTSZINHERIT) {
+		ret = fprintf(fp, "%s=%u\n", opt->name, fsx->fsx_extsize);
+		if (ret <= 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+print_cowextszinherit(
+	const struct mkfs_config_opt	*opt,
+	const struct mkfs_config_data	*data,
+	FILE				*fp)
+{
+	const struct fsxattr		*fsx = data->fsx;
+	int				ret;
+
+	if (fsx->fsx_xflags & FS_XFLAG_COWEXTSIZE) {
+		ret = fprintf(fp, "%s=%u\n", opt->name, fsx->fsx_cowextsize);
+		if (ret <= 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+print_rtextsize(
+	const struct mkfs_config_opt	*opt,
+	const struct mkfs_config_data	*data,
+	FILE				*fp)
+{
+	const struct xfs_fsop_geom	*fsgeo = data->fsgeo;
+	int				ret;
+
+	if (fsgeo->rtextsize > 1) {
+		ret = fprintf(fp, "%s=%u\n", opt->name,
+				fsgeo->rtextsize * fsgeo->blocksize);
+		if (ret <= 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+print_dirversion(
+	const struct mkfs_config_opt	*opt,
+	const struct mkfs_config_data	*data,
+	FILE				*fp)
+{
+	const struct xfs_fsop_geom	*fsgeo = data->fsgeo;
+	int				ret;
+
+	if (fsgeo->flags & XFS_FSOP_GEOM_FLAGS_DIRV2CI)
+		ret = fprintf(fp, "%s=ci\n", opt->name);
+	else
+		ret = fprintf(fp, "%s=2\n", opt->name);
+	if (ret <= 0)
+		return ret;
+	return 0;
+}
+
+static int
+print_autofsck(
+	const struct mkfs_config_opt	*opt,
+	const struct mkfs_config_data	*data,
+	FILE				*fp)
+{
+	int				ret;
+	const char			*value =
+		fsprop_autofsck_write(data->autofsck);
+
+	if (value) {
+		ret = fprintf(fp, "%s=%s\n", opt->name, value);
+		if (ret <= 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static const struct mkfs_config_section config_sections[] = {
+	{
+		.ini_section = "metadata",
+		.subopts = {
+			[M_CRC] = {
+				.name		= "crc",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_V5SB,
+			},
+			[M_FINOBT] = {
+				.name		= "finobt",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_FINOBT,
+			},
+			[M_RMAPBT] = {
+				.name		= "rmapbt",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_RMAPBT,
+			},
+			[M_REFLINK] = {
+				.name		= "reflink",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_REFLINK,
+			},
+			[M_INOBTCNT] = {
+				.name		= "inobtcount",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_INOBTCNT,
+			},
+			[M_BIGTIME] = {
+				.name		= "bigtime",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_BIGTIME,
+			},
+			[M_METADIR] = {
+				.name		= "metadir",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_METADIR,
+			},
+			[M_AUTOFSCK] = {
+				.name		= "autofsck",
+				.print_fn	= print_autofsck,
+			},
+			[M_MAX_OPTS] = { },
+		},
+	},
+	{
+		.ini_section			= "data",
+		.subopts = {
+			[D_RTINHERIT] = {
+				.name		= "rtinherit",
+				.xflags_flag	= FS_XFLAG_RTINHERIT,
+			},
+			[D_PROJINHERIT] = {
+				.name		= "projinherit",
+				.print_fn	= print_projinherit,
+			},
+			[D_EXTSZINHERIT] = {
+				.name		= "extszinherit",
+				.print_fn	= print_extszinherit,
+			},
+			[D_COWEXTSIZE] = {
+				.name		= "cowextsize",
+				.print_fn	= print_cowextszinherit,
+			},
+			[D_DAXINHERIT] = {
+				.name		= "daxinherit",
+				.xflags_flag	= FS_XFLAG_DAX,
+			},
+			[D_MAX_OPTS] = { },
+		},
+	},
+	{
+		.ini_section			= "inode",
+		.subopts = {
+			[I_SPINODES] = {
+				.name		= "sparse",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_SPINODES,
+			},
+			[I_NREXT64] = {
+				.name		= "nrext64",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_NREXT64,
+			},
+			[I_EXCHANGE] = {
+				.name		= "exchange",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_EXCHANGE_RANGE,
+			},
+			[I_MAX_OPTS] = { },
+		},
+	},
+	{
+		.ini_section = "naming",
+		.subopts = {
+			[N_PARENT] = {
+				.name		= "parent",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_PARENT,
+			},
+			[N_FTYPE] = {
+				.name		= "ftype",
+				.fsgeom_flag	= XFS_FSOP_GEOM_FLAGS_FTYPE,
+			},
+			[N_VERSION] = {
+				.name		= "version",
+				.print_fn	= print_dirversion,
+			},
+		},
+	},
+	{
+		.ini_section = "realtime",
+		.subopts = {
+			[R_EXTSIZE] = {
+				.name		= "extsize",
+				.print_fn	= print_rtextsize,
+			},
+			[R_MAX_OPTS] = { },
+		},
+	},
+};
+
+/*
+ * Write a mkfs.xfs configuration file for the user-visible filesystem features
+ * enabled in the corresponding fs geometry and root directory file attribute
+ * structures.
+ *
+ * Note: The regular and COW extent size hints must be in units of fsblocks,
+ * not bytes.
+ */
+int
+xfrog_write_mkfs_config(
+	const struct xfs_fsop_geom		*fsgeo,
+	const struct fsxattr			*fsx,
+	int					autofsck,
+	FILE					*fp)
+{
+	struct mkfs_config_data			d = {
+		.fsgeo				= fsgeo,
+		.fsx				= fsx,
+		.autofsck			= autofsck,
+	};
+	const struct mkfs_config_section	*section = config_sections;
+	const struct mkfs_config_opt		*opt;
+	int					i, j;
+	int					error;
+
+	for (i = 0; i < ARRAY_SIZE(config_sections); i++, section++) {
+		if (i > 0) {
+			error = fprintf(fp, "\n");
+			if (error <= 0)
+				return error;
+		}
+
+		error = fprintf(fp, "[%s]\n", section->ini_section);
+		if (error <= 0)
+			return error;
+
+		opt = section->subopts;
+		for (j = 0;
+		     j < ARRAY_SIZE(section->subopts) && opt->name;
+		     j++, opt++) {
+			if (opt->print_fn)
+				error = opt->print_fn(opt, &d, fp);
+			else if (opt->xflags_flag)
+				error = print_xflag(opt, &d, fp);
+			else if (opt->fsgeom_flag)
+				error = print_fsgeom(opt, &d, fp);
+			if (error)
+				return error;
+		}
+	}
+
+	return fflush(fp);
+}
diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in
index c4dee4fe07ae83..264457c3c283f1 100644
--- a/man/man8/mkfs.xfs.8.in
+++ b/man/man8/mkfs.xfs.8.in
@@ -163,6 +163,12 @@ .SH OPTIONS
 This option can be use either an absolute or relative path to the configuration
 file to be read.
 Sample configuration files can be found in @mkfs_cfg_dir@.
+.TP
+.BI makecfg= value
+Write a configuration file to the given path that can be re-read by mkfs.xfs
+for a future filesystem format attempt.
+This file will contain only user-visible features.
+If no path is given, the configuration will be printed on standard output.
 .RE
 .PP
 .PD 0
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 74bbb677eee2b6..212e17a354d8be 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -61,6 +61,7 @@ enum {
 
 enum {
 	C_OPTFILE = 0,
+	C_MAKECFG,
 	C_MAX_OPTS,
 };
 
@@ -312,6 +313,7 @@ static struct opt_params copts = {
 	.name = 'c',
 	.subopts = {
 		[C_OPTFILE] = "options",
+		[C_MAKECFG] = "makecfg",
 		[C_MAX_OPTS] = NULL,
 	},
 	.subopt_params = {
@@ -319,6 +321,10 @@ static struct opt_params copts = {
 		  .conflicts = { { NULL, LAST_CONFLICT } },
 		  .defaultval = SUBOPT_NEEDS_VAL,
 		},
+		{ .index = C_MAKECFG,
+		  .conflicts = { { NULL, LAST_CONFLICT } },
+		  .defaultval = 1,
+		},
 	},
 };
 
@@ -1072,6 +1078,7 @@ struct cli_params {
 
 	char	*cfgfile;
 	char	*protofile;
+	char	*makecfg;
 
 	enum fsprop_autofsck autofsck;
 
@@ -1207,7 +1214,7 @@ usage( void )
 {
 	fprintf(stderr, _("Usage: %s\n\
 /* blocksize */		[-b size=num]\n\
-/* config file */	[-c options=xxx]\n\
+/* config file */	[-c options=xxx,makecfg=0|1]\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\
 			    metadir=0|1]\n\
@@ -1787,6 +1794,12 @@ cfgfile_opts_parser(
 	case C_OPTFILE:
 		cli->cfgfile = getstr(value, opts, subopt);
 		break;
+	case C_MAKECFG:
+		if (!value)
+			cli->makecfg = "-";
+		else
+			cli->makecfg = getstr(value, opts, subopt);
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -6088,6 +6101,10 @@ main(
 	 */
 	cfgfile_parse(&cli);
 
+	/* Don't create anything if we're merely generating a config file */
+	if (cli.makecfg)
+		dry_run = 1;
+
 	/*
 	 * Extract as much of the valid config as we can from the CLI input
 	 * before opening the libxfs devices.
@@ -6197,6 +6214,31 @@ main(
 
 	validate_supported(mp, &cli);
 
+	if (cli.makecfg) {
+		struct xfs_fsop_geom	geo;
+		FILE			*fp;
+
+		if (!strcmp(cli.makecfg, "-")) {
+			fp = stdout;
+		} else {
+			fp = fopen(cli.makecfg, "w+");
+			if (!fp) {
+				perror(cli.makecfg);
+				exit(1);
+			}
+		}
+
+		libxfs_fs_geometry(mp, &geo, XFS_FS_GEOM_MAX_STRUCT_VER);
+		error = xfrog_write_mkfs_config(&geo, &cli.fsx, cli.autofsck,
+				fp);
+		if (error) {
+			perror(cli.makecfg);
+			exit(1);
+		}
+
+		exit(0);
+	}
+
 	/* Print the intended geometry of the fs. */
 	if (!quiet || dry_run) {
 		struct xfs_fsop_geom	geo;


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/5] xfs_db: print configuration file for mounted filesystems
  2026-08-31 23:26 [PATCHSET 2/2] xfsprogs: generate mkfs.xfs config files Darrick J. Wong
  2026-08-31 23:26 ` [PATCH 1/5] mkfs: automatically upgrade autofsck earlier Darrick J. Wong
  2026-08-31 23:27 ` [PATCH 2/5] mkfs: print config file for a given mkfs configuration Darrick J. Wong
@ 2026-08-31 23:27 ` Darrick J. Wong
  2026-09-03 11:20   ` Andrey Albershteyn
  2026-08-31 23:27 ` [PATCH 4/5] xfs_spaceman: " Darrick J. Wong
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2026-08-31 23:27 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Teach xfs_db to emit a mkfs.xfs config file for an unmounted filesystem.
This can be used to create a new filesystem based on an existing image.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 db/info.c         |  193 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/xfs_db.8 |    6 ++
 2 files changed, 199 insertions(+)


diff --git a/db/info.c b/db/info.c
index 9c233c9c0e6602..e4c026a2c4f429 100644
--- a/db/info.c
+++ b/db/info.c
@@ -9,6 +9,7 @@
 #include "output.h"
 #include "libfrog/fsgeom.h"
 #include "libfrog/logging.h"
+#include "libfrog/fsproperties.h"
 
 static void
 info_help(void)
@@ -276,10 +277,202 @@ static const struct cmdinfo rgresv_cmd = {
 	.help =		rgresv_help,
 };
 
+static void
+makecfg_help(void)
+{
+	dbprintf(_(
+"\n"
+" Print a mkfs.xfs configuration file for user-visible filesystem features\n"
+" of the current filesystem.  Geometry information are not printed.\n"
+"\n"
+));
+
+}
+static void
+fill_fsxattr(
+	struct xfs_inode	*ip,
+	struct fsxattr		*fa)
+{
+	struct xfs_mount	*mp = ip->i_mount;
+	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
+
+	fa->fsx_xflags = xfs_ip2xflags(ip);
+
+	if (ip->i_diflags & XFS_DIFLAG_EXTSIZE) {
+		fa->fsx_extsize = ip->i_extsize;
+	} else if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
+		/*
+		 * Don't let a misaligned extent size hint on a directory
+		 * escape to userspace if it won't pass the setattr checks
+		 * later.
+		 */
+		if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
+		    xfs_extlen_to_rtxmod(mp, ip->i_extsize) > 0) {
+			fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE |
+					    FS_XFLAG_EXTSZINHERIT);
+			fa->fsx_extsize = 0;
+		} else {
+			fa->fsx_extsize = ip->i_extsize;
+		}
+	}
+
+	if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) {
+		/*
+		 * Don't let a misaligned CoW extent size hint on a directory
+		 * escape to userspace if it won't pass the setattr checks
+		 * later.
+		 */
+		if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
+		    ip->i_cowextsize % mp->m_sb.sb_rextsize > 0) {
+			fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
+			fa->fsx_cowextsize = 0;
+		} else {
+			fa->fsx_cowextsize = ip->i_cowextsize;
+		}
+	}
+
+	fa->fsx_projid = ip->i_projid;
+	if (ifp && !xfs_need_iread_extents(ifp))
+		fa->fsx_nextents = xfs_iext_count(ifp);
+	else
+		fa->fsx_nextents = xfs_ifork_nextents(ifp);
+}
+
+static int
+get_autofsck(
+	struct xfs_inode	*ip,
+	enum fsprop_autofsck	*autofsck)
+{
+	char			value[FSPROP_MAX_VALUELEN + 1];
+	struct xfs_da_args	args = {
+		.dp		= ip,
+		.geo		= mp->m_attr_geo,
+		.whichfork	= XFS_ATTR_FORK,
+		.op_flags	= XFS_DA_OP_OKNOENT,
+		.attr_filter	= LIBXFS_ATTR_ROOT,
+		.owner		= mp->m_sb.sb_rootino,
+		.value		= value,
+		.valuelen	= sizeof(value),
+	};
+	char			*p;
+	int			error;
+
+	*autofsck = FSPROP_AUTOFSCK_UNSET;
+
+	error = fsprop_name_to_attr_name(FSPROP_AUTOFSCK_NAME, &p);
+	if (error < 0)
+		return ENOMEM;
+
+	args.namelen = error;
+	args.name = (const uint8_t *)p;
+
+	libxfs_attr_sethash(&args);
+
+	error = -libxfs_attr_get(&args);
+	if (error == ENODATA) {
+		error = 0;
+		goto out_p;
+	}
+	if (error)
+		goto out_p;
+	if (!args.valuelen)
+		return 0;
+
+	/* raw xattr value is not terminated */
+	value[args.valuelen] = 0;
+	*autofsck = fsprop_autofsck_read(value);
+
+out_p:
+	free(p);
+	return error;
+}
+
+static int
+makecfg_f(
+	int			argc,
+	char			**argv)
+{
+	struct xfs_fsop_geom	geo;
+	struct fsxattr		fsx = { };
+	struct xfs_inode	*ip;
+	FILE			*fp;
+	bool			close_fp = false;
+	enum fsprop_autofsck	autofsck;
+	int			c;
+	int			error;
+
+	while ((c = getopt(argc, argv, "")) != EOF) {
+		switch (c) {
+		default:
+			dbprintf(_("bad option for makecfg command\n"));
+			return 0;
+		}
+	}
+
+	if (optind != argc && optind != argc - 1) {
+		dbprintf(_("bad option for makecfg command\n"));
+		return 0;
+	}
+
+	error = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &ip);
+	if (error) {
+		fprintf(stderr, "root: %s\n", strerror(error));
+		return 1;
+	}
+
+	error = get_autofsck(ip, &autofsck);
+	if (error) {
+		fprintf(stderr, "autofsck: %s\n", strerror(error));
+		error = 1;
+		goto out_ip;
+	}
+
+	fill_fsxattr(ip, &fsx);
+	libxfs_fs_geometry(mp, &geo, XFS_FS_GEOM_MAX_STRUCT_VER);
+
+	if (optind == argc) {
+		fp = stdout;
+	} else {
+		fp = fopen(argv[optind], "w");
+		if (!fp) {
+			perror(argv[optind]);
+			error = 1;
+			goto out_ip;
+		}
+		close_fp = true;
+	}
+
+	error = xfrog_write_mkfs_config(&geo, &fsx, autofsck, fp);
+	if (error) {
+		if (close_fp)
+			perror(argv[optind]);
+		else
+			perror("makecfg");
+	}
+
+	if (close_fp)
+		fclose(fp);
+out_ip:
+	libxfs_irele(ip);
+	return error;
+}
+
+static const struct cmdinfo makecfg_cmd = {
+	.name =		"makecfg",
+	.cfunc =	makecfg_f,
+	.argmin =	0,
+	.argmax =	1,
+	.canpush =	0,
+	.args =		NULL,
+	.oneline =	N_("print mkfs.xfs configuration file"),
+	.help =		makecfg_help,
+};
+
 void
 info_init(void)
 {
 	add_command(&info_cmd);
 	add_command(&agresv_cmd);
 	add_command(&rgresv_cmd);
+	add_command(&makecfg_cmd);
 }
diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8
index ba2a68211ef21f..b602c9d399ece7 100644
--- a/man/man8/xfs_db.8
+++ b/man/man8/xfs_db.8
@@ -959,6 +959,12 @@ .SH COMMANDS
 .BI "help [" command ]
 Print help for one or all commands.
 .TP
+.BI "makecfg [" path ]
+Write a configuration file to the given path that can be re-read by mkfs.xfs
+for a future filesystem format attempt.
+This file will contain only user-visible features.
+If no path is given, the configuration will be printed on standard output.
+.TP
 .B info
 Displays selected geometry information about the filesystem.
 The output will have the same format that


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/5] xfs_spaceman: print configuration file for mounted filesystems
  2026-08-31 23:26 [PATCHSET 2/2] xfsprogs: generate mkfs.xfs config files Darrick J. Wong
                   ` (2 preceding siblings ...)
  2026-08-31 23:27 ` [PATCH 3/5] xfs_db: print configuration file for mounted filesystems Darrick J. Wong
@ 2026-08-31 23:27 ` Darrick J. Wong
  2026-09-03 11:20   ` Andrey Albershteyn
  2026-08-31 23:27 ` [PATCH 5/5] xfs_admin: " Darrick J. Wong
  2026-08-31 23:34 ` [PATCH RFC] xfs: test mkfs.xfs config file generation Darrick J. Wong
  5 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2026-08-31 23:27 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Teach xfs_spaceman to emit a mkfs.xfs config file for a mounted
filesystem.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 man/man8/xfs_spaceman.8 |    6 ++
 spaceman/info.c         |  136 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 142 insertions(+)


diff --git a/man/man8/xfs_spaceman.8 b/man/man8/xfs_spaceman.8
index 7d2d1ff94eeb55..26ff35ab59f2ec 100644
--- a/man/man8/xfs_spaceman.8
+++ b/man/man8/xfs_spaceman.8
@@ -84,6 +84,12 @@ .SH COMMANDS
 .PD
 .RE
 .TP
+.BI "makecfg [" path ]
+Write a configuration file to the given path that can be re-read by mkfs.xfs
+for a future filesystem format attempt.
+This file will contain only user-visible features.
+If no path is given, the configuration will be printed on standard output.
+.TP
 .B info
 Displays selected geometry information about the filesystem.
 The opened file must be a mount point of a XFS filesystem.
diff --git a/spaceman/info.c b/spaceman/info.c
index f6234c4c67aa19..653b8ff98f5c3f 100644
--- a/spaceman/info.c
+++ b/spaceman/info.c
@@ -8,6 +8,8 @@
 #include "init.h"
 #include "libfrog/paths.h"
 #include "libfrog/fsgeom.h"
+#include "libfrog/fsproperties.h"
+#include "libfrog/fsprops.h"
 #include "space.h"
 
 static void
@@ -51,8 +53,142 @@ static const struct cmdinfo info_cmd = {
 	.help =		info_help,
 };
 
+static void
+makecfg_help(void)
+{
+	printf(_(
+"\n"
+" Print a mkfs.xfs configuration file for user-visible filesystem features\n"
+" of the current filesystem.  Geometry information are not printed.\n"
+"\n"
+));
+
+}
+
+static int
+get_autofsck(
+	struct fileio		*f,
+	enum fsprop_autofsck	*autofsck)
+{
+	struct fsprops_handle	fph = { };
+	char			valuebuf[FSPROP_MAX_VALUELEN + 1] = { 0 };
+	size_t			valuelen = FSPROP_MAX_VALUELEN;
+	int			ret;
+
+	*autofsck = FSPROP_AUTOFSCK_UNSET;
+
+	ret = fsprops_open_handle(&f->xfd, &f->fs_path, &fph);
+	if (ret == -1 && errno == EOPNOTSUPP)
+		return 0;
+	if (ret)
+		return ret;
+
+	ret = fsprops_get(&fph, FSPROP_AUTOFSCK_NAME, valuebuf, &valuelen);
+	if (ret == -1 && errno == ENODATA) {
+		ret = 0;
+		goto out_fph;
+	}
+	if (ret)
+		goto out_fph;
+
+	*autofsck = fsprop_autofsck_read(valuebuf);
+
+out_fph:
+	fsprops_free_handle(&fph);
+	return ret;
+}
+
+static int makecfg_usage(void);
+
+static int
+makecfg_f(
+	int			argc,
+	char			**argv)
+{
+	struct fsxattr		fsx = { };
+	FILE			*fp;
+	bool			close_fp = false;
+	enum fsprop_autofsck	autofsck;
+	int			c;
+	int			ret;
+
+	while ((c = getopt(argc, argv, "")) != EOF) {
+		switch (c) {
+		default:
+			fprintf(stderr, _("bad option for makecfg command\n"));
+			return makecfg_usage();
+		}
+	}
+
+	if (optind != argc && optind != argc - 1) {
+		fprintf(stderr, _("bad option for makecfg command\n"));
+		return makecfg_usage();
+	}
+
+	if (fs_table_lookup_mount(file->name) == NULL) {
+		fprintf(stderr, _("%s: Not a XFS mount point.\n"), file->name);
+		return 1;
+	}
+
+	/* ioctl reports bytes, not fsblocks */
+	ret = ioctl(file->xfd.fd, FS_IOC_FSGETXATTR, &fsx);
+	if (ret) {
+		perror(file->name);
+		return 1;
+	}
+	fsx.fsx_extsize /= file->xfd.fsgeom.blocksize;
+	fsx.fsx_cowextsize /= file->xfd.fsgeom.blocksize;
+
+	ret = get_autofsck(file, &autofsck);
+	if (ret) {
+		perror("autofsck");
+		return 1;
+	}
+
+	if (optind == argc) {
+		fp = stdout;
+	} else {
+		fp = fopen(argv[optind], "w");
+		if (!fp) {
+			perror(argv[optind]);
+			return 1;
+		}
+		close_fp = true;
+	}
+
+	ret = xfrog_write_mkfs_config(&file->xfd.fsgeom, &fsx, autofsck, fp);
+	if (ret) {
+		if (close_fp)
+			perror(argv[optind]);
+		else
+			perror("makecfg");
+	}
+
+	if (close_fp)
+		fclose(fp);
+	return ret;
+}
+
+static const struct cmdinfo makecfg_cmd = {
+	.name =		"makecfg",
+	.cfunc =	makecfg_f,
+	.argmin =	0,
+	.argmax =	1,
+	.canpush =	0,
+	.args =		NULL,
+	.flags =	CMD_FLAG_ONESHOT,
+	.oneline =	N_("print mkfs.xfs configuration file"),
+	.help =		makecfg_help,
+};
+
+static int makecfg_usage(void)
+{
+	return command_usage(&makecfg_cmd);
+}
+
 void
 info_init(void)
 {
 	add_command(&info_cmd);
+	add_command(&makecfg_cmd);
 }


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/5] xfs_admin: print configuration file for mounted filesystems
  2026-08-31 23:26 [PATCHSET 2/2] xfsprogs: generate mkfs.xfs config files Darrick J. Wong
                   ` (3 preceding siblings ...)
  2026-08-31 23:27 ` [PATCH 4/5] xfs_spaceman: " Darrick J. Wong
@ 2026-08-31 23:27 ` Darrick J. Wong
  2026-09-03 11:21   ` Andrey Albershteyn
  2026-08-31 23:34 ` [PATCH RFC] xfs: test mkfs.xfs config file generation Darrick J. Wong
  5 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2026-08-31 23:27 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Teach xfs_admin to emit a mkfs.xfs config file for a mounted or
unmounted filesystem.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
-
---
 db/xfs_admin.sh      |   15 +++++++++++++--
 man/man8/xfs_admin.8 |    7 +++++++
 2 files changed, 20 insertions(+), 2 deletions(-)


diff --git a/db/xfs_admin.sh b/db/xfs_admin.sh
index 52a658ba4a540f..13a876ad8d1377 100755
--- a/db/xfs_admin.sh
+++ b/db/xfs_admin.sh
@@ -11,16 +11,20 @@ DB_OPTS=""
 DB_DEV_OPTS=""
 REPAIR_OPTS=""
 IO_OPTS=""
+SPACEMAN_OPTS=""
 REPAIR_DEV_OPTS=""
 LOG_OPTS=""
-USAGE="Usage: xfs_admin [-efjlpuV] [-c 0|1] [-L label] [-O v5_feature] [-r rtdev] [-U uuid] device [logdev]"
+USAGE="Usage: xfs_admin [-efjlpuV] [-C cfgfile] [-c 0|1] [-L label] [-O v5_feature] [-r rtdev] [-U uuid] device [logdev]"
 
-while getopts "c:efjlL:O:pr:uU:V" c
+while getopts "C:c:efjlL:O:pr:uU:V" c
 do
 	case $c in
 	c)	REPAIR_OPTS=$REPAIR_OPTS" -c lazycount="$OPTARG
 		require_offline=1
 		;;
+	C)	DB_OPTS=$DB_OPTS" -c 'makecfg "$OPTARG"'"
+		SPACEMAN_OPTS=$SPACEMAN_OPTS" -c 'makecfg "$OPTARG"'"
+		;;
 	e)	DB_OPTS=$DB_OPTS" -c 'version extflg'"
 		require_offline=1
 		;;
@@ -72,6 +76,13 @@ case $# in
 				exit 2
 			fi
 
+			if [ -n "$SPACEMAN_OPTS" ]; then
+				eval xfs_spaceman -p xfs_admin $SPACEMAN_OPTS "$mntpt"
+				res=$?
+				test $res -ne 0 && exit $res
+				test -n "$IO_OPTS" || exit $res
+			fi
+
 			if [ -n "$IO_OPTS" ]; then
 				eval xfs_io -p xfs_admin $IO_OPTS "$mntpt"
 				exit $?
diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8
index 63f8ee90307b30..d2652c0598f551 100644
--- a/man/man8/xfs_admin.8
+++ b/man/man8/xfs_admin.8
@@ -8,6 +8,8 @@ .SH SYNOPSIS
 ] [
 .BI \-O " featurelist"
 ] [
+.BR "\-C " cfgfile
+] [
 .BR "\-c 0" | 1
 ] [
 .B \-L
@@ -85,6 +87,11 @@ .SH OPTIONS
 .B \-u
 Print the current filesystem UUID (Universally Unique IDentifier).
 .TP
+.BI "\-C " path
+Write a configuration file to the given path that can be re-read by mkfs.xfs
+for a future filesystem format attempt.
+This file will contain only user-visible features.
+.TP
 .BR "\-c 0" | 1
 Enable (1) or disable (0) lazy-counters in the filesystem.
 .IP


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH RFC] xfs: test mkfs.xfs config file generation
  2026-08-31 23:26 [PATCHSET 2/2] xfsprogs: generate mkfs.xfs config files Darrick J. Wong
                   ` (4 preceding siblings ...)
  2026-08-31 23:27 ` [PATCH 5/5] xfs_admin: " Darrick J. Wong
@ 2026-08-31 23:34 ` Darrick J. Wong
  2026-09-03 11:21   ` Andrey Albershteyn
  5 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2026-08-31 23:34 UTC (permalink / raw)
  To: aalbersh, fstests; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Test configuration file generation via mkfs, xfs_db, and xfs_spaceman.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 tests/xfs/1909     |  123 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/1909.out |    2 +
 2 files changed, 125 insertions(+)
 create mode 100755 tests/xfs/1909
 create mode 100644 tests/xfs/1909.out

diff --git a/tests/xfs/1909 b/tests/xfs/1909
new file mode 100755
index 00000000000000..d405064c3e3d1d
--- /dev/null
+++ b/tests/xfs/1909
@@ -0,0 +1,123 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1909
+#
+# Functional testing for mkfs.xfs config file generation.
+#
+. ./common/preamble
+_begin_fstest auto mkfs
+
+# . ./common/filter
+
+_require_scratch
+_require_xfs_mkfs_cfgfile
+_require_xfs_spaceman_command "makecfg"
+_require_xfs_db_command "makecfg"
+_require_command "$XFS_ADMIN_PROG" "xfs_admin"
+
+# t1: Make sure all three tools generate the same config file
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+$XFS_SPACEMAN_PROG -c "makecfg $tmp.spaceman1" $SCRATCH_MNT
+$XFS_ADMIN_PROG -C $tmp.onadmin1 $SCRATCH_MNT
+_scratch_unmount
+# strip out deprecation warnings (e.g. v4 filesystems)
+_scratch_mkfs -c makecfg=$tmp.mkfs1
+_scratch_xfs_db -c "makecfg $tmp.db1"
+_scratch_xfs_admin -C $tmp.offadmin1
+
+cmp -s $tmp.mkfs1 $tmp.spaceman1 || echo "mkfs config1 does not match spaceman?"
+cmp -s $tmp.db1 $tmp.spaceman1 || echo "db config1 does not match spaceman?"
+cmp -s $tmp.db1 $tmp.mkfs1 || echo "db config1 does not match mkfs?"
+cmp -s $tmp.onadmin1 $tmp.mkfs1 || echo "online admin config1 does not match mkfs?"
+cmp -s $tmp.offadmin1 $tmp.mkfs1 || echo "offline admin config1 does not match mkfs?"
+
+echo "*** spaceman config1" >> $seqres.full
+cat $tmp.spaceman1 >> $seqres.full
+echo "*** mkfs config1" >> $seqres.full
+cat $tmp.mkfs1 >> $seqres.full
+echo "*** db config1" >> $seqres.full
+cat $tmp.db1 >> $seqres.full
+echo "*** online admin config1" >> $seqres.full
+cat $tmp.onadmin1 >> $seqres.full
+echo "*** offline admin config1" >> $seqres.full
+cat $tmp.offadmin1 >> $seqres.full
+
+# t2: Make sure the output changes if we set a new rootdir inherit option
+_scratch_mount
+$XFS_IO_PROG -c 'chattr +P' -c 'chproj 33' $SCRATCH_MNT
+$XFS_SPACEMAN_PROG -c "makecfg $tmp.spaceman2" $SCRATCH_MNT
+_scratch_unmount
+_scratch_xfs_db -c "makecfg $tmp.db2"
+
+cmp -s $tmp.db2 $tmp.spaceman2 || echo "db config2 does not match spaceman?"
+cmp -s $tmp.db1 $tmp.db2 && echo "db config1 should be different from db config2"
+
+echo "*** spaceman config2" >> $seqres.full
+cat $tmp.spaceman2 >> $seqres.full
+echo "*** db config2" >> $seqres.full
+cat $tmp.db2 >> $seqres.full
+
+# t3: Format with t2 config file, make sure the results match t2 and not t1
+_scratch_mkfs -c options=$tmp.db2 >> $seqres.full
+_scratch_mount
+$XFS_SPACEMAN_PROG -c "makecfg $tmp.spaceman3" $SCRATCH_MNT
+_scratch_unmount
+_scratch_xfs_db -c "makecfg $tmp.db3"
+
+cmp -s $tmp.db3 $tmp.spaceman3 || echo "db config3 does not match spaceman?"
+cmp -s $tmp.db3 $tmp.db1 && echo "db config3 should be different from db config1"
+cmp -s $tmp.db3 $tmp.db2 || echo "db config3 does not match db config2?"
+
+echo "*** spaceman config3" >> $seqres.full
+cat $tmp.spaceman3 >> $seqres.full
+echo "*** db config3" >> $seqres.full
+cat $tmp.db3 >> $seqres.full
+
+# t4: Set autofsck filesystem property, make sure that gets reflected
+autofsck="$(grep 'autofsck=' $tmp.spaceman3 | sed -e 's/^.*autofsck=//g')"
+case "$autofsck" in
+"")
+	if grep -q 'crc=1' $tmp.spaceman3; then
+		new_autofsck=check
+	fi
+	;;
+repair) new_autofsck=check;;
+*)	new_autofsck=repair;;
+esac
+if [ -n "$new_autofsck" ]; then
+	$XFS_PROPERTY_PROG $SCRATCH_DEV set "autofsck=$new_autofsck" >> $seqres.full
+	_scratch_mount
+	$XFS_SPACEMAN_PROG -c "makecfg $tmp.spaceman4" $SCRATCH_MNT
+	_scratch_unmount
+	_scratch_xfs_db -c "makecfg $tmp.db4"
+
+	cmp -s $tmp.db4 $tmp.spaceman4 || echo "db config4 does not match spaceman?"
+	cmp -s $tmp.db4 $tmp.db3 && echo "db config4 should be different from db config3"
+
+	echo "*** spaceman config4" >> $seqres.full
+	cat $tmp.spaceman4 >> $seqres.full
+	echo "*** db config4" >> $seqres.full
+	cat $tmp.db4 >> $seqres.full
+
+	_scratch_mkfs -c options=$tmp.db4 >> $seqres.full
+	_scratch_mount
+	$XFS_SPACEMAN_PROG -c "makecfg $tmp.spaceman4a" $SCRATCH_MNT
+	_scratch_unmount
+	_scratch_xfs_db -c "makecfg $tmp.db4a"
+
+	cmp -s $tmp.db4a $tmp.spaceman4a || echo "db config4a does not match spaceman?"
+	cmp -s $tmp.db4a $tmp.db3 && echo "db config4a should be different from db config3"
+	cmp -s $tmp.db4a $tmp.db4 || echo "db config4a does not match db config4?"
+
+	echo "*** spaceman config4a" >> $seqres.full
+	cat $tmp.spaceman4a >> $seqres.full
+	echo "*** db config4a" >> $seqres.full
+	cat $tmp.db4a >> $seqres.full
+
+fi
+
+echo Silence is golden
+_exit 0
diff --git a/tests/xfs/1909.out b/tests/xfs/1909.out
new file mode 100644
index 00000000000000..c17c5522d48db4
--- /dev/null
+++ b/tests/xfs/1909.out
@@ -0,0 +1,2 @@
+QA output created by 1909
+Silence is golden

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/5] mkfs: print config file for a given mkfs configuration
  2026-08-31 23:27 ` [PATCH 2/5] mkfs: print config file for a given mkfs configuration Darrick J. Wong
@ 2026-09-03 11:14   ` Andrey Albershteyn
  2026-09-03 21:49     ` Darrick J. Wong
  0 siblings, 1 reply; 14+ messages in thread
From: Andrey Albershteyn @ 2026-09-03 11:14 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 2026-08-31 16:27:05, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Add a -c makecfg= switch to mkfs to emit a mkfs.xfs configuration file
> documenting the user-visible filesystem featuresets of the configured
> filesystem.  This can be used to emit default configuration files as we
> do once a year for each LTS.
> 
> Note that geometry information is not written to the configuration file.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> ---
>  libfrog/fsgeom.h       |    3 
>  libfrog/fsgeom.c       |  376 ++++++++++++++++++++++++++++++++++++++++++++++++
>  man/man8/mkfs.xfs.8.in |    6 +
>  mkfs/xfs_mkfs.c        |   44 +++++-
>  4 files changed, 428 insertions(+), 1 deletion(-)
> 
> ...
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 74bbb677eee2b6..212e17a354d8be 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -61,6 +61,7 @@ enum {
>  
>  enum {
>  	C_OPTFILE = 0,
> +	C_MAKECFG,
>  	C_MAX_OPTS,
>  };
>  
> @@ -312,6 +313,7 @@ static struct opt_params copts = {
>  	.name = 'c',
>  	.subopts = {
>  		[C_OPTFILE] = "options",
> +		[C_MAKECFG] = "makecfg",
>  		[C_MAX_OPTS] = NULL,
>  	},
>  	.subopt_params = {
> @@ -319,6 +321,10 @@ static struct opt_params copts = {
>  		  .conflicts = { { NULL, LAST_CONFLICT } },
>  		  .defaultval = SUBOPT_NEEDS_VAL,
>  		},
> +		{ .index = C_MAKECFG,
> +		  .conflicts = { { NULL, LAST_CONFLICT } },
> +		  .defaultval = 1,
> +		},
>  	},
>  };
>  
> @@ -1072,6 +1078,7 @@ struct cli_params {
>  
>  	char	*cfgfile;
>  	char	*protofile;
> +	char	*makecfg;
>  
>  	enum fsprop_autofsck autofsck;
>  
> @@ -1207,7 +1214,7 @@ usage( void )
>  {
>  	fprintf(stderr, _("Usage: %s\n\
>  /* blocksize */		[-b size=num]\n\
> -/* config file */	[-c options=xxx]\n\
> +/* config file */	[-c options=xxx,makecfg=0|1]\n\

Shouldn't this be makecfg=xxx?

Otherwise, looks good to me
Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org>

-- 
- Andrey

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/5] mkfs: automatically upgrade autofsck earlier
  2026-08-31 23:26 ` [PATCH 1/5] mkfs: automatically upgrade autofsck earlier Darrick J. Wong
@ 2026-09-03 11:17   ` Andrey Albershteyn
  0 siblings, 0 replies; 14+ messages in thread
From: Andrey Albershteyn @ 2026-09-03 11:17 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 2026-08-31 16:26:49, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Move this chunk of code earlier in mkfs.xfs because a subsequent patch
> will need the final value of cli.autofsck at the point where we do the
> dry run reporting stuff.  Nobody changes cli.autofsck after
> validate_sb_features().
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> ---
>  mkfs/xfs_mkfs.c |   18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)

Looks good to me
Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org>

-- 
- Andrey

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/5] xfs_db: print configuration file for mounted filesystems
  2026-08-31 23:27 ` [PATCH 3/5] xfs_db: print configuration file for mounted filesystems Darrick J. Wong
@ 2026-09-03 11:20   ` Andrey Albershteyn
  0 siblings, 0 replies; 14+ messages in thread
From: Andrey Albershteyn @ 2026-09-03 11:20 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 2026-08-31 16:27:20, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Teach xfs_db to emit a mkfs.xfs config file for an unmounted filesystem.
> This can be used to create a new filesystem based on an existing image.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

Looks good to me
Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org>

-- 
- Andrey

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/5] xfs_spaceman: print configuration file for mounted filesystems
  2026-08-31 23:27 ` [PATCH 4/5] xfs_spaceman: " Darrick J. Wong
@ 2026-09-03 11:20   ` Andrey Albershteyn
  0 siblings, 0 replies; 14+ messages in thread
From: Andrey Albershteyn @ 2026-09-03 11:20 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 2026-08-31 16:27:36, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Teach xfs_spaceman to emit a mkfs.xfs config file for a mounted
> filesystem.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> ---
>  man/man8/xfs_spaceman.8 |    6 ++
>  spaceman/info.c         |  136 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 142 insertions(+)

Looks good to me
Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org>

-- 
- Andrey

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] xfs_admin: print configuration file for mounted filesystems
  2026-08-31 23:27 ` [PATCH 5/5] xfs_admin: " Darrick J. Wong
@ 2026-09-03 11:21   ` Andrey Albershteyn
  0 siblings, 0 replies; 14+ messages in thread
From: Andrey Albershteyn @ 2026-09-03 11:21 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 2026-08-31 16:27:51, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Teach xfs_admin to emit a mkfs.xfs config file for a mounted or
> unmounted filesystem.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> -
> ---
>  db/xfs_admin.sh      |   15 +++++++++++++--
>  man/man8/xfs_admin.8 |    7 +++++++
>  2 files changed, 20 insertions(+), 2 deletions(-)

Looks good to me
Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org>

-- 
- Andrey

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH RFC] xfs: test mkfs.xfs config file generation
  2026-08-31 23:34 ` [PATCH RFC] xfs: test mkfs.xfs config file generation Darrick J. Wong
@ 2026-09-03 11:21   ` Andrey Albershteyn
  0 siblings, 0 replies; 14+ messages in thread
From: Andrey Albershteyn @ 2026-09-03 11:21 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: fstests, linux-xfs

On 2026-08-31 16:34:30, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Test configuration file generation via mkfs, xfs_db, and xfs_spaceman.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> ---
>  tests/xfs/1909     |  123 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/xfs/1909.out |    2 +
>  2 files changed, 125 insertions(+)
>  create mode 100755 tests/xfs/1909
>  create mode 100644 tests/xfs/1909.out

Looks good to me
Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org>

-- 
- Andrey

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/5] mkfs: print config file for a given mkfs configuration
  2026-09-03 11:14   ` Andrey Albershteyn
@ 2026-09-03 21:49     ` Darrick J. Wong
  0 siblings, 0 replies; 14+ messages in thread
From: Darrick J. Wong @ 2026-09-03 21:49 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: linux-xfs

On Thu, Sep 03, 2026 at 01:14:01PM +0200, Andrey Albershteyn wrote:
> On 2026-08-31 16:27:05, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> > 
> > Add a -c makecfg= switch to mkfs to emit a mkfs.xfs configuration file
> > documenting the user-visible filesystem featuresets of the configured
> > filesystem.  This can be used to emit default configuration files as we
> > do once a year for each LTS.
> > 
> > Note that geometry information is not written to the configuration file.
> > 
> > Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> > ---
> >  libfrog/fsgeom.h       |    3 
> >  libfrog/fsgeom.c       |  376 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  man/man8/mkfs.xfs.8.in |    6 +
> >  mkfs/xfs_mkfs.c        |   44 +++++-
> >  4 files changed, 428 insertions(+), 1 deletion(-)
> > 
> > ...
> > 
> > diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> > index 74bbb677eee2b6..212e17a354d8be 100644
> > --- a/mkfs/xfs_mkfs.c
> > +++ b/mkfs/xfs_mkfs.c
> > @@ -61,6 +61,7 @@ enum {
> >  
> >  enum {
> >  	C_OPTFILE = 0,
> > +	C_MAKECFG,
> >  	C_MAX_OPTS,
> >  };
> >  
> > @@ -312,6 +313,7 @@ static struct opt_params copts = {
> >  	.name = 'c',
> >  	.subopts = {
> >  		[C_OPTFILE] = "options",
> > +		[C_MAKECFG] = "makecfg",
> >  		[C_MAX_OPTS] = NULL,
> >  	},
> >  	.subopt_params = {
> > @@ -319,6 +321,10 @@ static struct opt_params copts = {
> >  		  .conflicts = { { NULL, LAST_CONFLICT } },
> >  		  .defaultval = SUBOPT_NEEDS_VAL,
> >  		},
> > +		{ .index = C_MAKECFG,
> > +		  .conflicts = { { NULL, LAST_CONFLICT } },
> > +		  .defaultval = 1,
> > +		},
> >  	},
> >  };
> >  
> > @@ -1072,6 +1078,7 @@ struct cli_params {
> >  
> >  	char	*cfgfile;
> >  	char	*protofile;
> > +	char	*makecfg;
> >  
> >  	enum fsprop_autofsck autofsck;
> >  
> > @@ -1207,7 +1214,7 @@ usage( void )
> >  {
> >  	fprintf(stderr, _("Usage: %s\n\
> >  /* blocksize */		[-b size=num]\n\
> > -/* config file */	[-c options=xxx]\n\
> > +/* config file */	[-c options=xxx,makecfg=0|1]\n\
> 
> Shouldn't this be makecfg=xxx?

I think they all should be "=path" because they take file paths
specifically.  I'll amend this patch to change this to

/* config file */  [-c options=path,makecfg=path]\n\

> Otherwise, looks good to me
> Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org>

Thanks for reviewing!  A Sashiko review (I can run that internally now)
generated some complaints about xfrog_write_mkfs_config not handling the
quota mkfs options on metadir filesystems, and that there are a couple
of V4 options that it should emit.  I'll resend the series with those
two pieces of new functionality.

--D

> -- 
> - Andrey
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-09-03 21:49 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31 23:26 [PATCHSET 2/2] xfsprogs: generate mkfs.xfs config files Darrick J. Wong
2026-08-31 23:26 ` [PATCH 1/5] mkfs: automatically upgrade autofsck earlier Darrick J. Wong
2026-09-03 11:17   ` Andrey Albershteyn
2026-08-31 23:27 ` [PATCH 2/5] mkfs: print config file for a given mkfs configuration Darrick J. Wong
2026-09-03 11:14   ` Andrey Albershteyn
2026-09-03 21:49     ` Darrick J. Wong
2026-08-31 23:27 ` [PATCH 3/5] xfs_db: print configuration file for mounted filesystems Darrick J. Wong
2026-09-03 11:20   ` Andrey Albershteyn
2026-08-31 23:27 ` [PATCH 4/5] xfs_spaceman: " Darrick J. Wong
2026-09-03 11:20   ` Andrey Albershteyn
2026-08-31 23:27 ` [PATCH 5/5] xfs_admin: " Darrick J. Wong
2026-09-03 11:21   ` Andrey Albershteyn
2026-08-31 23:34 ` [PATCH RFC] xfs: test mkfs.xfs config file generation Darrick J. Wong
2026-09-03 11:21   ` Andrey Albershteyn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox