From: Darrick J. Wong <djwong@xxxxxxxxxx> Use suboption processing for -p so that we can add a few behavioral variants to protofiles in the next patch. As a side effect of this change, one can now provide the path to a protofile in the config file: [proto] file=/tmp/protofile Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- man/man8/mkfs.xfs.8.in | 26 ++++++++++++++++++---- mkfs/xfs_mkfs.c | 58 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in index 211e7b0c7b8..e1ca40e5da6 100644 --- a/man/man8/mkfs.xfs.8.in +++ b/man/man8/mkfs.xfs.8.in @@ -28,7 +28,7 @@ mkfs.xfs \- construct an XFS filesystem .I naming_options ] [ .B \-p -.I protofile +.I protofile_options ] [ .B \-q ] [ @@ -834,12 +834,29 @@ When CRCs are enabled (the default), the ftype functionality is always enabled, and cannot be turned off. .IP In other words, this option is only tunable on the deprecated V4 format. -.IP .RE +.PP +.PD 0 .TP -.BI \-p " protofile" +.BI \-p " protofile_options" +.TP +.BI "Section Name: " [proto] +.PD +These options specify the protofile parameters for populating the filesystem. +The valid +.I protofile_options +are: +.RS 1.2i +.TP +.BI [file=] protofile +The +.B file= +prefix is not required for this CLI argument for legacy reasons. +If specified as a config file directive, the prefix is required. + If the optional -.BI \-p " protofile" +.PD +.I protofile argument is given, .B mkfs.xfs uses @@ -979,6 +996,7 @@ in the directory. A scan of the protofile is always terminated with the dollar ( .B $ ) token. +.RE .TP .B \-q Quiet option. Normally diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index e219ec166da..4248e6ec344 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -113,6 +113,11 @@ enum { N_MAX_OPTS, }; +enum { + P_FILE = 0, + P_MAX_OPTS, +}; + enum { R_EXTSIZE = 0, R_SIZE, @@ -641,6 +646,21 @@ static struct opt_params nopts = { }, }; +static struct opt_params popts = { + .name = 'p', + .ini_section = "proto", + .subopts = { + [P_FILE] = "file", + [P_MAX_OPTS] = NULL, + }, + .subopt_params = { + { .index = P_FILE, + .conflicts = { { NULL, LAST_CONFLICT } }, + .defaultval = SUBOPT_NEEDS_VAL, + }, + }, +}; + static struct opt_params ropts = { .name = 'r', .ini_section = "realtime", @@ -841,6 +861,7 @@ struct cli_params { int blocksize; char *cfgfile; + char *protofile; /* parameters that depend on sector/block size being validated. */ char *dsize; @@ -1750,6 +1771,33 @@ naming_opts_parser( return 0; } +static int +proto_opts_parser( + struct opt_params *opts, + int subopt, + const char *value, + struct cli_params *cli) +{ + switch (subopt) { + case P_FILE: + fallthrough; + default: + if (cli->protofile) { + if (subopt < 0) + subopt = P_FILE; + respec(opts->name, opts->subopts, subopt); + } + cli->protofile = strdup(value); + if (!cli->protofile) { + fprintf(stderr, + _("Out of memory while saving protofile option.\n")); + exit(1); + } + break; + } + return 0; +} + static int rtdev_opts_parser( struct opt_params *opts, @@ -1813,6 +1861,7 @@ static struct subopts { { &lopts, log_opts_parser }, { &mopts, meta_opts_parser }, { &nopts, naming_opts_parser }, + { &popts, proto_opts_parser }, { &ropts, rtdev_opts_parser }, { &sopts, sector_opts_parser }, { NULL, NULL }, @@ -4013,7 +4062,6 @@ main( int discard = 1; int force_overwrite = 0; int quiet = 0; - char *protofile = NULL; char *protostring = NULL; int worst_freelist = 0; @@ -4119,6 +4167,7 @@ main( case 'l': case 'm': case 'n': + case 'p': case 'r': case 's': parse_subopts(c, optarg, &cli); @@ -4134,11 +4183,6 @@ main( case 'K': discard = 0; break; - case 'p': - if (protofile) - respec('p', NULL, 0); - protofile = optarg; - break; case 'q': quiet = 1; break; @@ -4165,7 +4209,7 @@ main( */ cfgfile_parse(&cli); - protostring = setup_proto(protofile); + protostring = setup_proto(cli.protofile); /* * Extract as much of the valid config as we can from the CLI input