All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] mkfs: save user input into opts table
@ 2017-04-23 18:54 Jan Tulak
  2017-04-23 18:54 ` [PATCH 01/12] mkfs: Save raw user input field to the opts struct Jan Tulak
                   ` (14 more replies)
  0 siblings, 15 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:54 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Hi guys,

I decided to split my big patchset into more smaller ones. So, this is the
first set. It adds set/get functions similar to Dave's suggestion, to save and
retrieve user values to and from the big opts table and prepares the ground for
future patches.


It is a mix of patches I already submitted and new ones:
Patches 2, 3, 4, 5 are just slightly modified to fix their issues.
Other patches are new.

The last few patches could be merged into one, because it should only
substitute variables for get/set calls, but because there are so many
places where the changes occurs, I split them into smaller chunks,
making it (hopefully) easier for you to review.

This patchset requires my two previous uint patches.
Git tree: https://github.com/jtulak/xfsprogs-dev/tree/setters

Cheers,
Jan

P.S.:
As a side note, I thought about adding a verification mechanism to
the set_conf_val() function, which would guarantee that we never have
an invalid number even later in the code -- an attempt to catch for
bugs. However, it seems that in some cases, we convert the number
e.g. from number of 512 byte blocks to fs blocks in situ (L_SUNIT),
which means that in some occasions, we are getting out of the range
of allowed values on the input side. So, I'm not adding these checks now,
but it is an option that could give us a cheap way how to catch some bugs.
Another question though is, how useful it would be...


Jan Tulak (12):
  mkfs: Save raw user input field to the opts struct
  mkfs: rename defaultval to flagval in opts
  mkfs: remove intermediate getstr followed by getnum
  mkfs: merge tables for opts parsing into one table
  mkfs: extend opt_params with a value field
  mkfs: create get/set functions for opts table
  mkfs: save user input values into opts
  mkfs: replace variables with opts table: -b,d,s options
  mkfs: replace variables with opts table: -i options
  mkfs: replace variables with opts table: -l options
  mkfs: replace variables with opts table: -n options
  mkfs: replace variables with opts table: -r options

 mkfs/xfs_mkfs.c | 2457 ++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 1420 insertions(+), 1037 deletions(-)

-- 
2.1.4


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

* [PATCH 01/12] mkfs: Save raw user input field to the opts struct
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
@ 2017-04-23 18:54 ` Jan Tulak
  2017-04-25 17:38   ` Eric Sandeen
  2017-04-23 18:54 ` [PATCH 02/12] mkfs: rename defaultval to flagval in opts Jan Tulak
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:54 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Save exactly what the user gave us for every option.  This way, we will
never lose the information if we need it to print back an issue.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 83a04fc..84674d5 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -119,6 +119,10 @@ uint64_t		sectorsize;
  *     A special SUBOPT_NEEDS_VAL can be used to require a user-given
  *     value in any case.
  *
+ *   raw_input INTERNAL
+ *     Filled raw string from the user, so we never lose that information e.g.
+ *     to print it back in case of an issue.
+ *
  * !!! NOTE ==================================================================
  *
  * If you are adding a new option, or changing an existing one,
@@ -141,6 +145,7 @@ struct opt_params {
 		uint64_t	minval;
 		uint64_t	maxval;
 		uint64_t	defaultval;
+		const char	*raw_input;
 	}		subopt_params[MAX_SUBOPTS];
 };
 
@@ -748,6 +753,18 @@ struct opt_params mopts = {
  */
 #define WHACK_SIZE (128 * 1024)
 
+static inline void
+set_conf_raw(struct opt_params *opt, int subopt, const char *value)
+{
+	opt->subopt_params[subopt].raw_input = value;
+}
+
+static inline const char *
+get_conf_raw(const struct opt_params *opt, int subopt)
+{
+	return opt->subopt_params[subopt].raw_input;
+}
+
 /*
  * Convert lsu to lsunit for 512 bytes blocks and check validity of the values.
  */
-- 
2.1.4


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

* [PATCH 02/12] mkfs: rename defaultval to flagval in opts
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
  2017-04-23 18:54 ` [PATCH 01/12] mkfs: Save raw user input field to the opts struct Jan Tulak
@ 2017-04-23 18:54 ` Jan Tulak
  2017-04-25 16:52   ` Eric Sandeen
  2017-04-23 18:54 ` [PATCH 03/12] mkfs: remove intermediate getstr followed by getnum Jan Tulak
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:54 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

The old name 'defaultval' was misleading - it is not the default value,
but the value the option has when used as a flag by an user.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 120 ++++++++++++++++++++++++++++----------------------------
 1 file changed, 60 insertions(+), 60 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 84674d5..0a795a6 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -112,7 +112,7 @@ uint64_t		sectorsize;
  *     to zero. But if one value is different: minval=0 and maxval=1,
  *     then it is OK.)
  *
- *   defaultval MANDATORY
+ *   flagval MANDATORY
  *     The value used if user specifies the subopt, but no value.
  *     If the subopt accepts some values (-d file=[1|0]), then this
  *     sets what is used with simple specifying the subopt (-d file).
@@ -144,7 +144,7 @@ struct opt_params {
 		int		conflicts[MAX_CONFLICTS];
 		uint64_t	minval;
 		uint64_t	maxval;
-		uint64_t	defaultval;
+		uint64_t	flagval;
 		const char	*raw_input;
 	}		subopt_params[MAX_SUBOPTS];
 };
@@ -164,7 +164,7 @@ struct opt_params bopts = {
 				 LAST_CONFLICT },
 		  .minval = XFS_MIN_BLOCKSIZE_LOG,
 		  .maxval = XFS_MAX_BLOCKSIZE_LOG,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = B_SIZE,
 		  .convert = true,
@@ -173,7 +173,7 @@ struct opt_params bopts = {
 				 LAST_CONFLICT },
 		  .minval = XFS_MIN_BLOCKSIZE,
 		  .maxval = XFS_MAX_BLOCKSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 	},
 };
@@ -219,24 +219,24 @@ struct opt_params dopts = {
 				 LAST_CONFLICT },
 		  .minval = 1,
 		  .maxval = XFS_MAX_AGNUMBER,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_FILE,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 		{ .index = D_NAME,
 		  .conflicts = { LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_SIZE,
 		  .conflicts = { LAST_CONFLICT },
 		  .convert = true,
 		  .minval = XFS_AG_MIN_BYTES,
 		  .maxval = LLONG_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_SUNIT,
 		  .conflicts = { D_NOALIGN,
@@ -245,7 +245,7 @@ struct opt_params dopts = {
 				 LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_SWIDTH,
 		  .conflicts = { D_NOALIGN,
@@ -254,7 +254,7 @@ struct opt_params dopts = {
 				 LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_AGSIZE,
 		  .conflicts = { D_AGCOUNT,
@@ -262,7 +262,7 @@ struct opt_params dopts = {
 		  .convert = true,
 		  .minval = XFS_AG_MIN_BYTES,
 		  .maxval = XFS_AG_MAX_BYTES,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_SU,
 		  .conflicts = { D_NOALIGN,
@@ -272,7 +272,7 @@ struct opt_params dopts = {
 		  .convert = true,
 		  .minval = 0,
 		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_SW,
 		  .conflicts = { D_NOALIGN,
@@ -281,14 +281,14 @@ struct opt_params dopts = {
 				 LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_SECTLOG,
 		  .conflicts = { D_SECTSIZE,
 				 LAST_CONFLICT },
 		  .minval = XFS_MIN_SECTORSIZE_LOG,
 		  .maxval = XFS_MAX_SECTORSIZE_LOG,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_SECTSIZE,
 		  .conflicts = { D_SECTLOG,
@@ -297,7 +297,7 @@ struct opt_params dopts = {
 		  .is_power_2 = true,
 		  .minval = XFS_MIN_SECTORSIZE,
 		  .maxval = XFS_MAX_SECTORSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_NOALIGN,
 		  .conflicts = { D_SU,
@@ -307,25 +307,25 @@ struct opt_params dopts = {
 				 LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 		{ .index = D_RTINHERIT,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 		{ .index = D_PROJINHERIT,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = D_EXTSZINHERIT,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 	},
 };
@@ -357,7 +357,7 @@ struct opt_params iopts = {
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 		{ .index = I_LOG,
 		  .conflicts = { I_PERBLOCK,
@@ -365,13 +365,13 @@ struct opt_params iopts = {
 				 LAST_CONFLICT },
 		  .minval = XFS_DINODE_MIN_LOG,
 		  .maxval = XFS_DINODE_MAX_LOG,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = I_MAXPCT,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 100,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = I_PERBLOCK,
 		  .conflicts = { I_LOG,
@@ -380,7 +380,7 @@ struct opt_params iopts = {
 		  .is_power_2 = true,
 		  .minval = XFS_MIN_INODE_PERBLOCK,
 		  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = I_SIZE,
 		  .conflicts = { I_PERBLOCK,
@@ -389,25 +389,25 @@ struct opt_params iopts = {
 		  .is_power_2 = true,
 		  .minval = XFS_DINODE_MIN_SIZE,
 		  .maxval = XFS_DINODE_MAX_SIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = I_ATTR,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 2,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = I_PROJID32BIT,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 		{ .index = I_SPINODES,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 	},
 };
@@ -447,7 +447,7 @@ struct opt_params lopts = {
 				 LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = L_INTERNAL,
 		  .conflicts = { L_FILE,
@@ -455,27 +455,27 @@ struct opt_params lopts = {
 				 LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 		{ .index = L_SIZE,
 		  .conflicts = { LAST_CONFLICT },
 		  .convert = true,
 		  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
 		  .maxval = XFS_MAX_LOG_BYTES,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = L_VERSION,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 1,
 		  .maxval = 2,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = L_SUNIT,
 		  .conflicts = { L_SU,
 				 LAST_CONFLICT },
 		  .minval = 1,
 		  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = L_SU,
 		  .conflicts = { L_SUNIT,
@@ -483,20 +483,20 @@ struct opt_params lopts = {
 		  .convert = true,
 		  .minval = BBTOB(1),
 		  .maxval = XLOG_MAX_RECORD_BSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = L_DEV,
 		  .conflicts = { L_AGNUM,
 				 L_INTERNAL,
 				 LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = L_SECTLOG,
 		  .conflicts = { L_SECTSIZE,
 				 LAST_CONFLICT },
 		  .minval = XFS_MIN_SECTORSIZE_LOG,
 		  .maxval = XFS_MAX_SECTORSIZE_LOG,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = L_SECTSIZE,
 		  .conflicts = { L_SECTLOG,
@@ -505,26 +505,26 @@ struct opt_params lopts = {
 		  .is_power_2 = true,
 		  .minval = XFS_MIN_SECTORSIZE,
 		  .maxval = XFS_MAX_SECTORSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = L_FILE,
 		  .conflicts = { L_INTERNAL,
 				 LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 		{ .index = L_NAME,
 		  .conflicts = { L_AGNUM,
 				 L_INTERNAL,
 				 LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = L_LAZYSBCNTR,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 	},
 };
@@ -548,7 +548,7 @@ struct opt_params nopts = {
 				 LAST_CONFLICT },
 		  .minval = XFS_MIN_REC_DIRSIZE,
 		  .maxval = XFS_MAX_BLOCKSIZE_LOG,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = N_SIZE,
 		  .conflicts = { N_LOG,
@@ -557,19 +557,19 @@ struct opt_params nopts = {
 		  .is_power_2 = true,
 		  .minval = 1 << XFS_MIN_REC_DIRSIZE,
 		  .maxval = XFS_MAX_BLOCKSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = N_VERSION,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 2,
 		  .maxval = 2,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = N_FTYPE,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 	},
 };
@@ -597,33 +597,33 @@ struct opt_params ropts = {
 		  .convert = true,
 		  .minval = XFS_MIN_RTEXTSIZE,
 		  .maxval = XFS_MAX_RTEXTSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = R_SIZE,
 		  .conflicts = { LAST_CONFLICT },
 		  .convert = true,
 		  .minval = 0,
 		  .maxval = LLONG_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = R_DEV,
 		  .conflicts = { LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = R_FILE,
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		  .conflicts = { LAST_CONFLICT },
 		},
 		{ .index = R_NAME,
 		  .conflicts = { LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = R_NOALIGN,
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		  .conflicts = { LAST_CONFLICT },
 		},
 	},
@@ -649,7 +649,7 @@ struct opt_params sopts = {
 				 LAST_CONFLICT },
 		  .minval = XFS_MIN_SECTORSIZE_LOG,
 		  .maxval = XFS_MAX_SECTORSIZE_LOG,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = S_SECTLOG,
 		  .conflicts = { S_SIZE,
@@ -657,7 +657,7 @@ struct opt_params sopts = {
 				 LAST_CONFLICT },
 		  .minval = XFS_MIN_SECTORSIZE_LOG,
 		  .maxval = XFS_MAX_SECTORSIZE_LOG,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = S_SIZE,
 		  .conflicts = { S_LOG,
@@ -667,7 +667,7 @@ struct opt_params sopts = {
 		  .is_power_2 = true,
 		  .minval = XFS_MIN_SECTORSIZE,
 		  .maxval = XFS_MAX_SECTORSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = S_SECTSIZE,
 		  .conflicts = { S_LOG,
@@ -677,7 +677,7 @@ struct opt_params sopts = {
 		  .is_power_2 = true,
 		  .minval = XFS_MIN_SECTORSIZE,
 		  .maxval = XFS_MAX_SECTORSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 	},
 };
@@ -702,29 +702,29 @@ struct opt_params mopts = {
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 		{ .index = M_FINOBT,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 1,
+		  .flagval = 1,
 		},
 		{ .index = M_UUID,
 		  .conflicts = { LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		  .flagval = SUBOPT_NEEDS_VAL,
 		},
 		{ .index = M_RMAPBT,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 0,
+		  .flagval = 0,
 		},
 		{ .index = M_REFLINK,
 		  .conflicts = { LAST_CONFLICT },
 		  .minval = 0,
 		  .maxval = 1,
-		  .defaultval = 0,
+		  .flagval = 0,
 		},
 	},
 };
@@ -1365,9 +1365,9 @@ getnum(
 	check_opt(opts, index, false);
 	/* empty strings might just return a default value */
 	if (!str || *str == '\0') {
-		if (sp->defaultval == SUBOPT_NEEDS_VAL)
+		if (sp->flagval == SUBOPT_NEEDS_VAL)
 			reqval(opts->name, (char **)opts->subopts, index);
-		return sp->defaultval;
+		return sp->flagval;
 	}
 
 	if (sp->minval == 0 && sp->maxval == 0) {
-- 
2.1.4


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

* [PATCH 03/12] mkfs: remove intermediate getstr followed by getnum
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
  2017-04-23 18:54 ` [PATCH 01/12] mkfs: Save raw user input field to the opts struct Jan Tulak
  2017-04-23 18:54 ` [PATCH 02/12] mkfs: rename defaultval to flagval in opts Jan Tulak
@ 2017-04-23 18:54 ` Jan Tulak
  2017-04-25 17:37   ` Eric Sandeen
  2017-04-23 18:54 ` [PATCH 04/12] mkfs: merge tables for opts parsing into one table Jan Tulak
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:54 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Some options loaded a number as a string with getstr and converted it to
number with getnum later in the code, without any reason for this
approach.  (They were probably forgotten in some past cleaning.)

This patch changes them to skip the string and use getnum directly in
the main option-parsing loop, as do all the other numerical options.

And as we now have two variables of the same type for the same value,
merge them together. (e.g. former string dsize and number dbytes).

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
CHANGES:
* The first patch now ensures that we still have the raw input and
  we are not changing the form of user input (i.e. size stays in given
  units...)

 mkfs/xfs_mkfs.c | 88 ++++++++++++++++++++++++++-------------------------------
 1 file changed, 40 insertions(+), 48 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 0a795a6..7a72b11 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1363,6 +1363,7 @@ getnum(
 	uint64_t		c;
 
 	check_opt(opts, index, false);
+	set_conf_raw(opts, index, str);
 	/* empty strings might just return a default value */
 	if (!str || *str == '\0') {
 		if (sp->flagval == SUBOPT_NEEDS_VAL)
@@ -1450,7 +1451,7 @@ main(
 	char			*dfile;
 	uint64_t		dirblocklog;
 	uint64_t		dirblocksize;
-	char			*dsize;
+	uint64_t		dbytes;
 	uint64_t		dsu;
 	uint64_t		dsw;
 	uint64_t		dsunit;
@@ -1474,7 +1475,7 @@ main(
 	xfs_rfsblock_t		logblocks;
 	char			*logfile;
 	uint64_t		loginternal;
-	char			*logsize;
+	uint64_t		logbytes;
 	xfs_fsblock_t		logstart;
 	bool			lvflag;
 	bool			lsflag;
@@ -1503,11 +1504,11 @@ main(
 	char			*protostring;
 	bool			qflag;
 	xfs_rfsblock_t		rtblocks;
+	uint64_t		rtbytes;
 	xfs_extlen_t		rtextblocks;
 	xfs_rtblock_t		rtextents;
-	char			*rtextsize;
+	uint64_t		rtextbytes;
 	char			*rtfile;
-	char			*rtsize;
 	xfs_sb_t		*sbp;
 	uint64_t		sectorlog;
 	uint64_t		sector_mask;
@@ -1555,7 +1556,8 @@ main(
 	qflag = false;
 	imaxpct = inodelog = inopblock = isize = 0;
 	dfile = logfile = rtfile = NULL;
-	dsize = logsize = rtsize = rtextsize = protofile = NULL;
+	protofile = NULL;
+	rtbytes = rtextbytes = logbytes = dbytes = 0;
 	dsu = dsw = dsunit = dswidth = lalign = lsu = lsunit = 0;
 	nodsflag = norsflag = false;
 	force_overwrite = false;
@@ -1619,7 +1621,7 @@ main(
 					xi.dname = getstr(value, &dopts, D_NAME);
 					break;
 				case D_SIZE:
-					dsize = getstr(value, &dopts, D_SIZE);
+					dbytes = getnum(value, &dopts, D_SIZE);
 					break;
 				case D_SUNIT:
 					dsunit = getnum(value, &dopts, D_SUNIT);
@@ -1764,7 +1766,7 @@ main(
 					lvflag = 1;
 					break;
 				case L_SIZE:
-					logsize = getstr(value, &lopts, L_SIZE);
+					logbytes = getnum(value, &lopts, L_SIZE);
 					break;
 				case L_SECTLOG:
 					lsectorlog = getnum(value, &lopts,
@@ -1893,8 +1895,7 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case R_EXTSIZE:
-					rtextsize = getstr(value, &ropts,
-							   R_EXTSIZE);
+					rtextbytes = getnum(value, &ropts, R_EXTSIZE);
 					break;
 				case R_FILE:
 					xi.risfile = getnum(value, &ropts,
@@ -1906,7 +1907,7 @@ main(
 							   R_NAME);
 					break;
 				case R_SIZE:
-					rtsize = getstr(value, &ropts, R_SIZE);
+					rtbytes = getnum(value, &ropts, R_SIZE);
 					break;
 				case R_NOALIGN:
 					norsflag = getnum(value, &ropts,
@@ -2009,14 +2010,14 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 	 * sector size mismatches between the new filesystem and the underlying
 	 * host filesystem.
 	 */
-	check_device_type(dfile, &xi.disfile, !dsize, !dfile,
+	check_device_type(dfile, &xi.disfile, !dbytes, !dfile,
 			  Nflag ? NULL : &xi.dcreat, force_overwrite, "d");
 	if (!loginternal)
-		check_device_type(xi.logname, &xi.lisfile, !logsize, !xi.logname,
-				  Nflag ? NULL : &xi.lcreat,
+		check_device_type(xi.logname, &xi.lisfile, !logbytes,
+				  !xi.logname, Nflag ? NULL : &xi.lcreat,
 				  force_overwrite, "l");
 	if (xi.rtname)
-		check_device_type(xi.rtname, &xi.risfile, !rtsize, !xi.rtname,
+		check_device_type(xi.rtname, &xi.risfile, !rtbytes, !xi.rtname,
 				  Nflag ? NULL : &xi.rcreat,
 				  force_overwrite, "r");
 	if (xi.disfile || xi.lisfile || xi.risfile)
@@ -2197,10 +2198,7 @@ _("rmapbt not supported with realtime devices\n"));
 	}
 
 
-	if (dsize) {
-		uint64_t dbytes;
-
-		dbytes = getnum(dsize, &dopts, D_SIZE);
+	if (dbytes) {
 		if (dbytes % XFS_MIN_BLOCKSIZE) {
 			fprintf(stderr,
 			_("illegal data length %"PRIu64", not a multiple of %d\n"),
@@ -2229,10 +2227,7 @@ _("rmapbt not supported with realtime devices\n"));
 		usage();
 	}
 
-	if (logsize) {
-		uint64_t logbytes;
-
-		logbytes = getnum(logsize, &lopts, L_SIZE);
+	if (logbytes) {
 		if (logbytes % XFS_MIN_BLOCKSIZE) {
 			fprintf(stderr,
 			_("illegal log length %"PRIu64", not a multiple of %d\n"),
@@ -2246,10 +2241,7 @@ _("rmapbt not supported with realtime devices\n"));
 				logbytes, blocksize,
 				(uint64_t)(logblocks << blocklog));
 	}
-	if (rtsize) {
-		uint64_t rtbytes;
-
-		rtbytes = getnum(rtsize, &ropts, R_SIZE);
+	if (rtbytes) {
 		if (rtbytes % XFS_MIN_BLOCKSIZE) {
 			fprintf(stderr,
 			_("illegal rt length %"PRIu64", not a multiple of %d\n"),
@@ -2266,10 +2258,7 @@ _("rmapbt not supported with realtime devices\n"));
 	/*
 	 * If specified, check rt extent size against its constraints.
 	 */
-	if (rtextsize) {
-		uint64_t rtextbytes;
-
-		rtextbytes = getnum(rtextsize, &ropts, R_EXTSIZE);
+	if (rtextbytes) {
 		if (rtextbytes % blocksize) {
 			fprintf(stderr,
 		_("illegal rt extent size %"PRIu64", not a multiple of %"PRIu64"\n"),
@@ -2286,7 +2275,7 @@ _("rmapbt not supported with realtime devices\n"));
 		uint64_t	rswidth;
 		uint64_t	rtextbytes;
 
-		if (!norsflag && !xi.risfile && !(!rtsize && xi.disfile))
+		if (!norsflag && !xi.risfile && !(!rtbytes && xi.disfile))
 			rswidth = ft.rtswidth;
 		else
 			rswidth = 0;
@@ -2397,15 +2386,16 @@ _("rmapbt not supported with realtime devices\n"));
 		rtfile = _("volume rt");
 	else if (!xi.rtdev)
 		rtfile = _("none");
-	if (dsize && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
+	if (dbytes && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
 		fprintf(stderr,
 			_("size %s specified for data subvolume is too large, "
 			"maximum is %"PRIu64" blocks\n"),
-			dsize, (uint64_t)DTOBT(xi.dsize));
+			get_conf_raw(&dopts, D_SIZE),
+			(uint64_t)DTOBT(xi.dsize));
 		usage();
-	} else if (!dsize && xi.dsize > 0)
+	} else if (!dbytes && xi.dsize > 0)
 		dblocks = DTOBT(xi.dsize);
-	else if (!dsize) {
+	else if (!dbytes) {
 		fprintf(stderr, _("can't get size of data subvolume\n"));
 		usage();
 	}
@@ -2438,22 +2428,23 @@ reported by the device (%u).\n"),
 reported by the device (%u).\n"),
 			lsectorsize, xi.lbsize);
 	}
-	if (rtsize && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
+	if (rtbytes && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
 		fprintf(stderr, _(
 "Warning: the realtime subvolume sector size %"PRIu64" is less than the sector size\n\
 reported by the device (%u).\n"),
 			sectorsize, xi.rtbsize);
 	}
 
-	if (rtsize && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
+	if (rtbytes && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
 		fprintf(stderr,
 			_("size %s specified for rt subvolume is too large, "
 			"maximum is %"PRIu64" blocks\n"),
-			rtsize, (uint64_t)DTOBT(xi.rtsize));
+			get_conf_raw(&ropts, R_SIZE),
+			(uint64_t)DTOBT(xi.rtsize));
 		usage();
-	} else if (!rtsize && xi.rtsize > 0)
+	} else if (!rtbytes && xi.rtsize > 0)
 		rtblocks = DTOBT(xi.rtsize);
-	else if (rtsize && !xi.rtdev) {
+	else if (rtbytes && !xi.rtdev) {
 		fprintf(stderr,
 			_("size specified for non-existent rt subvolume\n"));
 		usage();
@@ -2658,26 +2649,27 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
 				   sb_feat.rmapbt, sb_feat.reflink);
 	ASSERT(min_logblocks);
 	min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
-	if (!logsize && dblocks >= (1024*1024*1024) >> blocklog)
+	if (!logbytes && dblocks >= (1024*1024*1024) >> blocklog)
 		min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
-	if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
+	if (logbytes && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
 		fprintf(stderr,
 _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks\n"),
-			logsize, (uint64_t)DTOBT(xi.logBBsize));
+			get_conf_raw(&lopts, L_SIZE),
+			(uint64_t)DTOBT(xi.logBBsize));
 		usage();
-	} else if (!logsize && xi.logBBsize > 0) {
+	} else if (!logbytes && xi.logBBsize > 0) {
 		logblocks = DTOBT(xi.logBBsize);
-	} else if (logsize && !xi.logdev && !loginternal) {
+	} else if (logbytes && !xi.logdev && !loginternal) {
 		fprintf(stderr,
 			_("size specified for non-existent log subvolume\n"));
 		usage();
-	} else if (loginternal && logsize && logblocks >= dblocks) {
+	} else if (loginternal && logbytes && logblocks >= dblocks) {
 		fprintf(stderr, _("size %"PRIu64" too large for internal log\n"),
 			logblocks);
 		usage();
 	} else if (!loginternal && !xi.logdev) {
 		logblocks = 0;
-	} else if (loginternal && !logsize) {
+	} else if (loginternal && !logbytes) {
 
 		if (dblocks < GIGABYTES(1, blocklog)) {
 			/* tiny filesystems get minimum sized logs. */
@@ -2741,7 +2733,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		 * Readjust the log size to fit within an AG if it was sized
 		 * automatically.
 		 */
-		if (!logsize) {
+		if (!logbytes) {
 			logblocks = MIN(logblocks,
 					libxfs_alloc_ag_max_usable(mp));
 
-- 
2.1.4


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

* [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (2 preceding siblings ...)
  2017-04-23 18:54 ` [PATCH 03/12] mkfs: remove intermediate getstr followed by getnum Jan Tulak
@ 2017-04-23 18:54 ` Jan Tulak
  2017-04-25  3:04   ` Luis R. Rodriguez
  2017-04-25 21:45   ` Eric Sandeen
  2017-04-23 18:54 ` [PATCH 05/12] mkfs: extend opt_params with a value field Jan Tulak
                   ` (10 subsequent siblings)
  14 siblings, 2 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:54 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Merge separate instances of opt_params into one indexable table. Git
makes this patch looks a bit more complicated, but it does not change
values or structure of anything else. It only moves all the "struct
opt_params dopts = {...}", changes indentation for these substructures
and replaces their usage (dopts -> opts[OPT_D]).

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 1316 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 683 insertions(+), 633 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 7a72b11..513e106 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -42,6 +42,7 @@ static int  ispow2(unsigned int i);
 uint64_t		blocksize;
 uint64_t		sectorsize;
 
+#define MAX_OPTS	16
 #define MAX_SUBOPTS	16
 #define SUBOPT_NEEDS_VAL	(-1LL)
 #define MAX_CONFLICTS	8
@@ -60,6 +61,10 @@ uint64_t		sectorsize;
  *
  * Description of the structure members follows:
  *
+ * index MANDATORY
+ *   An integer denoting the position of the specific option in opts array,
+ *   counting from 0 up to MAX_OPTS.
+ *
  * name MANDATORY
  *   Name is a single char, e.g., for '-d file', name is 'd'.
  *
@@ -132,6 +137,7 @@ uint64_t		sectorsize;
  * !!! END OF NOTE ===========================================================
  */
 struct opt_params {
+	int		index;
 	const char	name;
 	const char	*subopts[MAX_SUBOPTS];
 
@@ -147,584 +153,592 @@ struct opt_params {
 		uint64_t	flagval;
 		const char	*raw_input;
 	}		subopt_params[MAX_SUBOPTS];
-};
-
-struct opt_params bopts = {
-	.name = 'b',
-	.subopts = {
+} opts[MAX_OPTS] = {
+#define OPT_B	0
+	{
+		.index = OPT_B,
+		.name = 'b',
+		.subopts = {
 #define	B_LOG		0
-		"log",
+			"log",
 #define	B_SIZE		1
-		"size",
-		NULL
-	},
-	.subopt_params = {
-		{ .index = B_LOG,
-		  .conflicts = { B_SIZE,
-				 LAST_CONFLICT },
-		  .minval = XFS_MIN_BLOCKSIZE_LOG,
-		  .maxval = XFS_MAX_BLOCKSIZE_LOG,
-		  .flagval = SUBOPT_NEEDS_VAL,
+			"size",
+			NULL
 		},
-		{ .index = B_SIZE,
-		  .convert = true,
-		  .is_power_2 = true,
-		  .conflicts = { B_LOG,
-				 LAST_CONFLICT },
-		  .minval = XFS_MIN_BLOCKSIZE,
-		  .maxval = XFS_MAX_BLOCKSIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
+		.subopt_params = {
+			{ .index = B_LOG,
+			  .conflicts = { B_SIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_BLOCKSIZE_LOG,
+			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = B_SIZE,
+			  .convert = true,
+			  .is_power_2 = true,
+			  .conflicts = { B_LOG,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_BLOCKSIZE,
+			  .maxval = XFS_MAX_BLOCKSIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
 		},
 	},
-};
-
-struct opt_params dopts = {
-	.name = 'd',
-	.subopts = {
-#define	D_AGCOUNT	0
-		"agcount",
-#define	D_FILE		1
-		"file",
-#define	D_NAME		2
-		"name",
-#define	D_SIZE		3
-		"size",
-#define D_SUNIT		4
-		"sunit",
-#define D_SWIDTH	5
-		"swidth",
-#define D_AGSIZE	6
-		"agsize",
-#define D_SU		7
-		"su",
-#define D_SW		8
-		"sw",
-#define D_SECTLOG	9
-		"sectlog",
-#define D_SECTSIZE	10
-		"sectsize",
-#define D_NOALIGN	11
-		"noalign",
-#define D_RTINHERIT	12
-		"rtinherit",
-#define D_PROJINHERIT	13
-		"projinherit",
-#define D_EXTSZINHERIT	14
-		"extszinherit",
-		NULL
-	},
-	.subopt_params = {
-		{ .index = D_AGCOUNT,
-		  .conflicts = { D_AGSIZE,
-				 LAST_CONFLICT },
-		  .minval = 1,
-		  .maxval = XFS_MAX_AGNUMBER,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_FILE,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		},
-		{ .index = D_NAME,
-		  .conflicts = { LAST_CONFLICT },
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SIZE,
-		  .conflicts = { LAST_CONFLICT },
-		  .convert = true,
-		  .minval = XFS_AG_MIN_BYTES,
-		  .maxval = LLONG_MAX,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SUNIT,
-		  .conflicts = { D_NOALIGN,
-				 D_SU,
-				 D_SW,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SWIDTH,
-		  .conflicts = { D_NOALIGN,
-				 D_SU,
-				 D_SW,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_AGSIZE,
-		  .conflicts = { D_AGCOUNT,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .minval = XFS_AG_MIN_BYTES,
-		  .maxval = XFS_AG_MAX_BYTES,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SU,
-		  .conflicts = { D_NOALIGN,
-				 D_SUNIT,
-				 D_SWIDTH,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SW,
-		  .conflicts = { D_NOALIGN,
-				 D_SUNIT,
-				 D_SWIDTH,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SECTLOG,
-		  .conflicts = { D_SECTSIZE,
-				 LAST_CONFLICT },
-		  .minval = XFS_MIN_SECTORSIZE_LOG,
-		  .maxval = XFS_MAX_SECTORSIZE_LOG,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SECTSIZE,
-		  .conflicts = { D_SECTLOG,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .is_power_2 = true,
-		  .minval = XFS_MIN_SECTORSIZE,
-		  .maxval = XFS_MAX_SECTORSIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
+#define OPT_D	1
+	{
+		.index = OPT_D,
+		.name = 'd',
+		.subopts = {
+	#define	D_AGCOUNT	0
+			"agcount",
+	#define	D_FILE		1
+			"file",
+	#define	D_NAME		2
+			"name",
+	#define	D_SIZE		3
+			"size",
+	#define D_SUNIT		4
+			"sunit",
+	#define D_SWIDTH	5
+			"swidth",
+	#define D_AGSIZE	6
+			"agsize",
+	#define D_SU		7
+			"su",
+	#define D_SW		8
+			"sw",
+	#define D_SECTLOG	9
+			"sectlog",
+	#define D_SECTSIZE	10
+			"sectsize",
+	#define D_NOALIGN	11
+			"noalign",
+	#define D_RTINHERIT	12
+			"rtinherit",
+	#define D_PROJINHERIT	13
+			"projinherit",
+	#define D_EXTSZINHERIT	14
+			"extszinherit",
+			NULL
 		},
-		{ .index = D_NOALIGN,
-		  .conflicts = { D_SU,
-				 D_SW,
-				 D_SUNIT,
-				 D_SWIDTH,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		},
-		{ .index = D_RTINHERIT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		},
-		{ .index = D_PROJINHERIT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_EXTSZINHERIT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .flagval = SUBOPT_NEEDS_VAL,
+		.subopt_params = {
+			{ .index = D_AGCOUNT,
+			  .conflicts = { D_AGSIZE,
+					 LAST_CONFLICT },
+			  .minval = 1,
+			  .maxval = XFS_MAX_AGNUMBER,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_FILE,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
+			{ .index = D_NAME,
+			  .conflicts = { LAST_CONFLICT },
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SIZE,
+			  .conflicts = { LAST_CONFLICT },
+			  .convert = true,
+			  .minval = XFS_AG_MIN_BYTES,
+			  .maxval = LLONG_MAX,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SUNIT,
+			  .conflicts = { D_NOALIGN,
+					 D_SU,
+					 D_SW,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SWIDTH,
+			  .conflicts = { D_NOALIGN,
+					 D_SU,
+					 D_SW,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_AGSIZE,
+			  .conflicts = { D_AGCOUNT,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .minval = XFS_AG_MIN_BYTES,
+			  .maxval = XFS_AG_MAX_BYTES,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SU,
+			  .conflicts = { D_NOALIGN,
+					 D_SUNIT,
+					 D_SWIDTH,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SW,
+			  .conflicts = { D_NOALIGN,
+					 D_SUNIT,
+					 D_SWIDTH,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SECTLOG,
+			  .conflicts = { D_SECTSIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_SECTORSIZE_LOG,
+			  .maxval = XFS_MAX_SECTORSIZE_LOG,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SECTSIZE,
+			  .conflicts = { D_SECTLOG,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .is_power_2 = true,
+			  .minval = XFS_MIN_SECTORSIZE,
+			  .maxval = XFS_MAX_SECTORSIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_NOALIGN,
+			  .conflicts = { D_SU,
+					 D_SW,
+					 D_SUNIT,
+					 D_SWIDTH,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
+			{ .index = D_RTINHERIT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
+			{ .index = D_PROJINHERIT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_EXTSZINHERIT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
 		},
 	},
-};
-
-
-struct opt_params iopts = {
-	.name = 'i',
-	.subopts = {
+#define OPT_I	2
+	{
+		.index = OPT_I,
+		.name = 'i',
+		.subopts = {
 #define	I_ALIGN		0
-		"align",
+			"align",
 #define	I_LOG		1
-		"log",
+			"log",
 #define	I_MAXPCT	2
-		"maxpct",
+			"maxpct",
 #define	I_PERBLOCK	3
-		"perblock",
+			"perblock",
 #define	I_SIZE		4
-		"size",
+			"size",
 #define	I_ATTR		5
-		"attr",
+			"attr",
 #define	I_PROJID32BIT	6
-		"projid32bit",
+			"projid32bit",
 #define I_SPINODES	7
-		"sparse",
-		NULL
-	},
-	.subopt_params = {
-		{ .index = I_ALIGN,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		},
-		{ .index = I_LOG,
-		  .conflicts = { I_PERBLOCK,
-				 I_SIZE,
-				 LAST_CONFLICT },
-		  .minval = XFS_DINODE_MIN_LOG,
-		  .maxval = XFS_DINODE_MAX_LOG,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = I_MAXPCT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 100,
-		  .flagval = SUBOPT_NEEDS_VAL,
+			"sparse",
+			NULL
 		},
-		{ .index = I_PERBLOCK,
-		  .conflicts = { I_LOG,
-				 I_SIZE,
-				 LAST_CONFLICT },
-		  .is_power_2 = true,
-		  .minval = XFS_MIN_INODE_PERBLOCK,
-		  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = I_SIZE,
-		  .conflicts = { I_PERBLOCK,
-				 I_LOG,
-				 LAST_CONFLICT },
-		  .is_power_2 = true,
-		  .minval = XFS_DINODE_MIN_SIZE,
-		  .maxval = XFS_DINODE_MAX_SIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = I_ATTR,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 2,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = I_PROJID32BIT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		},
-		{ .index = I_SPINODES,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
+		.subopt_params = {
+			{ .index = I_ALIGN,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
+			{ .index = I_LOG,
+			  .conflicts = { I_PERBLOCK,
+					 I_SIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_DINODE_MIN_LOG,
+			  .maxval = XFS_DINODE_MAX_LOG,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = I_MAXPCT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 100,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = I_PERBLOCK,
+			  .conflicts = { I_LOG,
+					 I_SIZE,
+					 LAST_CONFLICT },
+			  .is_power_2 = true,
+			  .minval = XFS_MIN_INODE_PERBLOCK,
+			  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = I_SIZE,
+			  .conflicts = { I_PERBLOCK,
+					 I_LOG,
+					 LAST_CONFLICT },
+			  .is_power_2 = true,
+			  .minval = XFS_DINODE_MIN_SIZE,
+			  .maxval = XFS_DINODE_MAX_SIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = I_ATTR,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 2,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = I_PROJID32BIT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
+			{ .index = I_SPINODES,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
 		},
 	},
-};
-
-struct opt_params lopts = {
-	.name = 'l',
-	.subopts = {
-#define	L_AGNUM		0
-		"agnum",
-#define	L_INTERNAL	1
-		"internal",
-#define	L_SIZE		2
-		"size",
-#define L_VERSION	3
-		"version",
-#define L_SUNIT		4
-		"sunit",
-#define L_SU		5
-		"su",
-#define L_DEV		6
-		"logdev",
-#define	L_SECTLOG	7
-		"sectlog",
-#define	L_SECTSIZE	8
-		"sectsize",
-#define	L_FILE		9
-		"file",
-#define	L_NAME		10
-		"name",
-#define	L_LAZYSBCNTR	11
-		"lazy-count",
-		NULL
-	},
-	.subopt_params = {
-		{ .index = L_AGNUM,
-		  .conflicts = { L_DEV,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_INTERNAL,
-		  .conflicts = { L_FILE,
-				 L_DEV,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
+#define OPT_L	3
+	{
+		.index = OPT_L,
+		.name = 'l',
+		.subopts = {
+	#define	L_AGNUM		0
+			"agnum",
+	#define	L_INTERNAL	1
+			"internal",
+	#define	L_SIZE		2
+			"size",
+	#define L_VERSION	3
+			"version",
+	#define L_SUNIT		4
+			"sunit",
+	#define L_SU		5
+			"su",
+	#define L_DEV		6
+			"logdev",
+	#define	L_SECTLOG	7
+			"sectlog",
+	#define	L_SECTSIZE	8
+			"sectsize",
+	#define	L_FILE		9
+			"file",
+	#define	L_NAME		10
+			"name",
+	#define	L_LAZYSBCNTR	11
+			"lazy-count",
+			NULL
 		},
-		{ .index = L_SIZE,
-		  .conflicts = { LAST_CONFLICT },
-		  .convert = true,
-		  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
-		  .maxval = XFS_MAX_LOG_BYTES,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_VERSION,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 1,
-		  .maxval = 2,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_SUNIT,
-		  .conflicts = { L_SU,
-				 LAST_CONFLICT },
-		  .minval = 1,
-		  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_SU,
-		  .conflicts = { L_SUNIT,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .minval = BBTOB(1),
-		  .maxval = XLOG_MAX_RECORD_BSIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_DEV,
-		  .conflicts = { L_AGNUM,
-				 L_INTERNAL,
-				 LAST_CONFLICT },
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_SECTLOG,
-		  .conflicts = { L_SECTSIZE,
-				 LAST_CONFLICT },
-		  .minval = XFS_MIN_SECTORSIZE_LOG,
-		  .maxval = XFS_MAX_SECTORSIZE_LOG,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_SECTSIZE,
-		  .conflicts = { L_SECTLOG,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .is_power_2 = true,
-		  .minval = XFS_MIN_SECTORSIZE,
-		  .maxval = XFS_MAX_SECTORSIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_FILE,
-		  .conflicts = { L_INTERNAL,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		},
-		{ .index = L_NAME,
-		  .conflicts = { L_AGNUM,
-				 L_INTERNAL,
-				 LAST_CONFLICT },
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_LAZYSBCNTR,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
+		.subopt_params = {
+			{ .index = L_AGNUM,
+			  .conflicts = { L_DEV,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_INTERNAL,
+			  .conflicts = { L_FILE,
+					 L_DEV,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
+			{ .index = L_SIZE,
+			  .conflicts = { LAST_CONFLICT },
+			  .convert = true,
+			  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
+			  .maxval = XFS_MAX_LOG_BYTES,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_VERSION,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 1,
+			  .maxval = 2,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_SUNIT,
+			  .conflicts = { L_SU,
+					 LAST_CONFLICT },
+			  .minval = 1,
+			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_SU,
+			  .conflicts = { L_SUNIT,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .minval = BBTOB(1),
+			  .maxval = XLOG_MAX_RECORD_BSIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_DEV,
+			  .conflicts = { L_AGNUM,
+					 L_INTERNAL,
+					 LAST_CONFLICT },
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_SECTLOG,
+			  .conflicts = { L_SECTSIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_SECTORSIZE_LOG,
+			  .maxval = XFS_MAX_SECTORSIZE_LOG,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_SECTSIZE,
+			  .conflicts = { L_SECTLOG,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .is_power_2 = true,
+			  .minval = XFS_MIN_SECTORSIZE,
+			  .maxval = XFS_MAX_SECTORSIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_FILE,
+			  .conflicts = { L_INTERNAL,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
+			{ .index = L_NAME,
+			  .conflicts = { L_AGNUM,
+					 L_INTERNAL,
+					 LAST_CONFLICT },
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_LAZYSBCNTR,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
 		},
 	},
-};
-
-struct opt_params nopts = {
-	.name = 'n',
-	.subopts = {
-#define	N_LOG		0
-		"log",
-#define	N_SIZE		1
-		"size",
-#define	N_VERSION	2
-		"version",
-#define	N_FTYPE		3
-		"ftype",
-	NULL,
-	},
-	.subopt_params = {
-		{ .index = N_LOG,
-		  .conflicts = { N_SIZE,
-				 LAST_CONFLICT },
-		  .minval = XFS_MIN_REC_DIRSIZE,
-		  .maxval = XFS_MAX_BLOCKSIZE_LOG,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = N_SIZE,
-		  .conflicts = { N_LOG,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .is_power_2 = true,
-		  .minval = 1 << XFS_MIN_REC_DIRSIZE,
-		  .maxval = XFS_MAX_BLOCKSIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
+#define OPT_N	4
+	{
+		.index = OPT_N,
+		.name = 'n',
+		.subopts = {
+	#define	N_LOG		0
+			"log",
+	#define	N_SIZE		1
+			"size",
+	#define	N_VERSION	2
+			"version",
+	#define	N_FTYPE		3
+			"ftype",
+		NULL,
 		},
-		{ .index = N_VERSION,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 2,
-		  .maxval = 2,
-		  .flagval = SUBOPT_NEEDS_VAL,
+		.subopt_params = {
+			{ .index = N_LOG,
+			  .conflicts = { N_SIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_REC_DIRSIZE,
+			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = N_SIZE,
+			  .conflicts = { N_LOG,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .is_power_2 = true,
+			  .minval = 1 << XFS_MIN_REC_DIRSIZE,
+			  .maxval = XFS_MAX_BLOCKSIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = N_VERSION,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 2,
+			  .maxval = 2,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = N_FTYPE,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
 		},
-		{ .index = N_FTYPE,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		},
-	},
-};
-
-struct opt_params ropts = {
-	.name = 'r',
-	.subopts = {
-#define	R_EXTSIZE	0
-		"extsize",
-#define	R_SIZE		1
-		"size",
-#define	R_DEV		2
-		"rtdev",
-#define	R_FILE		3
-		"file",
-#define	R_NAME		4
-		"name",
-#define R_NOALIGN	5
-		"noalign",
-		NULL
 	},
-	.subopt_params = {
-		{ .index = R_EXTSIZE,
-		  .conflicts = { LAST_CONFLICT },
-		  .convert = true,
-		  .minval = XFS_MIN_RTEXTSIZE,
-		  .maxval = XFS_MAX_RTEXTSIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
+#define OPT_R	5
+	{
+		.index = OPT_R,
+		.name = 'r',
+		.subopts = {
+	#define	R_EXTSIZE	0
+			"extsize",
+	#define	R_SIZE		1
+			"size",
+	#define	R_DEV		2
+			"rtdev",
+	#define	R_FILE		3
+			"file",
+	#define	R_NAME		4
+			"name",
+	#define R_NOALIGN	5
+			"noalign",
+			NULL
 		},
-		{ .index = R_SIZE,
-		  .conflicts = { LAST_CONFLICT },
-		  .convert = true,
-		  .minval = 0,
-		  .maxval = LLONG_MAX,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = R_DEV,
-		  .conflicts = { LAST_CONFLICT },
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = R_FILE,
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		  .conflicts = { LAST_CONFLICT },
-		},
-		{ .index = R_NAME,
-		  .conflicts = { LAST_CONFLICT },
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = R_NOALIGN,
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		  .conflicts = { LAST_CONFLICT },
+		.subopt_params = {
+			{ .index = R_EXTSIZE,
+			  .conflicts = { LAST_CONFLICT },
+			  .convert = true,
+			  .minval = XFS_MIN_RTEXTSIZE,
+			  .maxval = XFS_MAX_RTEXTSIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = R_SIZE,
+			  .conflicts = { LAST_CONFLICT },
+			  .convert = true,
+			  .minval = 0,
+			  .maxval = LLONG_MAX,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = R_DEV,
+			  .conflicts = { LAST_CONFLICT },
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = R_FILE,
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			  .conflicts = { LAST_CONFLICT },
+			},
+			{ .index = R_NAME,
+			  .conflicts = { LAST_CONFLICT },
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = R_NOALIGN,
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			  .conflicts = { LAST_CONFLICT },
+			},
 		},
 	},
-};
-
-struct opt_params sopts = {
-	.name = 's',
-	.subopts = {
-#define	S_LOG		0
-		"log",
-#define	S_SECTLOG	1
-		"sectlog",
-#define	S_SIZE		2
-		"size",
-#define	S_SECTSIZE	3
-		"sectsize",
-		NULL
-	},
-	.subopt_params = {
-		{ .index = S_LOG,
-		  .conflicts = { S_SIZE,
-				 S_SECTSIZE,
-				 LAST_CONFLICT },
-		  .minval = XFS_MIN_SECTORSIZE_LOG,
-		  .maxval = XFS_MAX_SECTORSIZE_LOG,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = S_SECTLOG,
-		  .conflicts = { S_SIZE,
-				 S_SECTSIZE,
-				 LAST_CONFLICT },
-		  .minval = XFS_MIN_SECTORSIZE_LOG,
-		  .maxval = XFS_MAX_SECTORSIZE_LOG,
-		  .flagval = SUBOPT_NEEDS_VAL,
+#define OPT_S	6
+	{
+		.index = OPT_S,
+		.name = 's',
+		.subopts = {
+	#define	S_LOG		0
+			"log",
+	#define	S_SECTLOG	1
+			"sectlog",
+	#define	S_SIZE		2
+			"size",
+	#define	S_SECTSIZE	3
+			"sectsize",
+			NULL
 		},
-		{ .index = S_SIZE,
-		  .conflicts = { S_LOG,
-				 S_SECTLOG,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .is_power_2 = true,
-		  .minval = XFS_MIN_SECTORSIZE,
-		  .maxval = XFS_MAX_SECTORSIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
+		.subopt_params = {
+			{ .index = S_LOG,
+			  .conflicts = { S_SIZE,
+					 S_SECTSIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_SECTORSIZE_LOG,
+			  .maxval = XFS_MAX_SECTORSIZE_LOG,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = S_SECTLOG,
+			  .conflicts = { S_SIZE,
+					 S_SECTSIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_SECTORSIZE_LOG,
+			  .maxval = XFS_MAX_SECTORSIZE_LOG,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = S_SIZE,
+			  .conflicts = { S_LOG,
+					 S_SECTLOG,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .is_power_2 = true,
+			  .minval = XFS_MIN_SECTORSIZE,
+			  .maxval = XFS_MAX_SECTORSIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = S_SECTSIZE,
+			  .conflicts = { S_LOG,
+					 S_SECTLOG,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .is_power_2 = true,
+			  .minval = XFS_MIN_SECTORSIZE,
+			  .maxval = XFS_MAX_SECTORSIZE,
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
 		},
-		{ .index = S_SECTSIZE,
-		  .conflicts = { S_LOG,
-				 S_SECTLOG,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .is_power_2 = true,
-		  .minval = XFS_MIN_SECTORSIZE,
-		  .maxval = XFS_MAX_SECTORSIZE,
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-	},
-};
-
-struct opt_params mopts = {
-	.name = 'm',
-	.subopts = {
-#define	M_CRC		0
-		"crc",
-#define M_FINOBT	1
-		"finobt",
-#define M_UUID		2
-		"uuid",
-#define M_RMAPBT	3
-		"rmapbt",
-#define M_REFLINK	4
-		"reflink",
-		NULL
 	},
-	.subopt_params = {
-		{ .index = M_CRC,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
+#define OPT_M	7
+	{
+		.index = OPT_M,
+		.name = 'm',
+		.subopts = {
+	#define	M_CRC		0
+			"crc",
+	#define M_FINOBT	1
+			"finobt",
+	#define M_UUID		2
+			"uuid",
+	#define M_RMAPBT	3
+			"rmapbt",
+	#define M_REFLINK	4
+			"reflink",
+			NULL
 		},
-		{ .index = M_FINOBT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 1,
-		},
-		{ .index = M_UUID,
-		  .conflicts = { LAST_CONFLICT },
-		  .flagval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = M_RMAPBT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 0,
-		},
-		{ .index = M_REFLINK,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .flagval = 0,
+		.subopt_params = {
+			{ .index = M_CRC,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
+			{ .index = M_FINOBT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 1,
+			},
+			{ .index = M_UUID,
+			  .conflicts = { LAST_CONFLICT },
+			  .flagval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = M_RMAPBT,
+			.conflicts = { LAST_CONFLICT },
+			.minval = 0,
+			.maxval = 1,
+			.flagval = 0,
+			},
+			{ .index = M_REFLINK,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .flagval = 0,
+			},
 		},
 	},
 };
@@ -754,15 +768,15 @@ struct opt_params mopts = {
 #define WHACK_SIZE (128 * 1024)
 
 static inline void
-set_conf_raw(struct opt_params *opt, int subopt, const char *value)
+set_conf_raw(int opt, int subopt, const char *value)
 {
-	opt->subopt_params[subopt].raw_input = value;
+	opts[opt].subopt_params[subopt].raw_input = value;
 }
 
 static inline const char *
-get_conf_raw(const struct opt_params *opt, int subopt)
+get_conf_raw(int opt, int subopt)
 {
-	return opt->subopt_params[subopt].raw_input;
+	return opts[opt].subopt_params[subopt].raw_input;
 }
 
 /*
@@ -1363,7 +1377,7 @@ getnum(
 	uint64_t		c;
 
 	check_opt(opts, index, false);
-	set_conf_raw(opts, index, str);
+	set_conf_raw(opts->index, index, str);
 	/* empty strings might just return a default value */
 	if (!str || *str == '\0') {
 		if (sp->flagval == SUBOPT_NEEDS_VAL)
@@ -1577,17 +1591,19 @@ main(
 		case 'b':
 			p = optarg;
 			while (*p != '\0') {
-				char	**subopts = (char **)bopts.subopts;
+				char	**subopts =
+						(char **)opts[OPT_B].subopts;
 				char	*value;
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case B_LOG:
-					blocklog = getnum(value, &bopts, B_LOG);
+					blocklog = getnum(value, &opts[OPT_B],
+								B_LOG);
 					blocksize = 1 << blocklog;
 					blflag = 1;
 					break;
 				case B_SIZE:
-					blocksize = getnum(value, &bopts,
+					blocksize = getnum(value, &opts[OPT_B],
 							   B_SIZE);
 					blocklog = libxfs_highbit32(blocksize);
 					bsflag = 1;
@@ -1600,74 +1616,82 @@ main(
 		case 'd':
 			p = optarg;
 			while (*p != '\0') {
-				char	**subopts = (char **)dopts.subopts;
+				char	**subopts =
+						(char **)opts[OPT_D].subopts;
 				char	*value;
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case D_AGCOUNT:
-					agcount = getnum(value, &dopts,
+					agcount = getnum(value, &opts[OPT_D],
 							 D_AGCOUNT);
 					daflag = 1;
 					break;
 				case D_AGSIZE:
-					agsize = getnum(value, &dopts, D_AGSIZE);
+					agsize = getnum(value, &opts[OPT_D],
+								D_AGSIZE);
 					dasize = 1;
 					break;
 				case D_FILE:
-					xi.disfile = getnum(value, &dopts,
-							    D_FILE);
+					xi.disfile = getnum(value,
+						&opts[OPT_D], D_FILE);
 					break;
 				case D_NAME:
-					xi.dname = getstr(value, &dopts, D_NAME);
+					xi.dname = getstr(value, &opts[OPT_D],
+								D_NAME);
 					break;
 				case D_SIZE:
-					dbytes = getnum(value, &dopts, D_SIZE);
+					dbytes = getnum(value, &opts[OPT_D],
+								D_SIZE);
 					break;
 				case D_SUNIT:
-					dsunit = getnum(value, &dopts, D_SUNIT);
+					dsunit = getnum(value, &opts[OPT_D],
+								D_SUNIT);
 					break;
 				case D_SWIDTH:
-					dswidth = getnum(value, &dopts,
+					dswidth = getnum(value, &opts[OPT_D],
 							 D_SWIDTH);
 					break;
 				case D_SU:
-					dsu = getnum(value, &dopts, D_SU);
+					dsu = getnum(value, &opts[OPT_D],
+								D_SU);
 					break;
 				case D_SW:
-					dsw = getnum(value, &dopts, D_SW);
+					dsw = getnum(value, &opts[OPT_D],
+								D_SW);
 					break;
 				case D_NOALIGN:
-					nodsflag = getnum(value, &dopts,
+					nodsflag = getnum(value, &opts[OPT_D],
 								D_NOALIGN);
 					break;
 				case D_SECTLOG:
-					sectorlog = getnum(value, &dopts,
+					sectorlog = getnum(value, &opts[OPT_D],
 							   D_SECTLOG);
 					sectorsize = 1 << sectorlog;
 					slflag = 1;
 					break;
 				case D_SECTSIZE:
-					sectorsize = getnum(value, &dopts,
-							    D_SECTSIZE);
+					sectorsize = getnum(value,
+						&opts[OPT_D], D_SECTSIZE);
 					sectorlog =
 						libxfs_highbit32(sectorsize);
 					ssflag = 1;
 					break;
 				case D_RTINHERIT:
-					c = getnum(value, &dopts, D_RTINHERIT);
+					c = getnum(value, &opts[OPT_D],
+								D_RTINHERIT);
 					if (c)
 						fsx.fsx_xflags |=
 							XFS_DIFLAG_RTINHERIT;
 					break;
 				case D_PROJINHERIT:
-					fsx.fsx_projid = getnum(value, &dopts,
-								D_PROJINHERIT);
+					fsx.fsx_projid = getnum(value,
+						&opts[OPT_D], D_PROJINHERIT);
 					fsx.fsx_xflags |=
 						XFS_DIFLAG_PROJINHERIT;
 					break;
 				case D_EXTSZINHERIT:
-					fsx.fsx_extsize = getnum(value, &dopts,
-								 D_EXTSZINHERIT);
+					fsx.fsx_extsize = getnum(value,
+						&opts[OPT_D], D_EXTSZINHERIT);
 					fsx.fsx_xflags |=
 						XFS_DIFLAG_EXTSZINHERIT;
 					break;
@@ -1679,46 +1703,51 @@ main(
 		case 'i':
 			p = optarg;
 			while (*p != '\0') {
-				char	**subopts = (char **)iopts.subopts;
+				char	**subopts =
+						(char **)opts[OPT_I].subopts;
 				char	*value;
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case I_ALIGN:
 					sb_feat.inode_align = getnum(value,
-								&iopts, I_ALIGN);
+						&opts[OPT_I], I_ALIGN);
 					break;
 				case I_LOG:
-					inodelog = getnum(value, &iopts, I_LOG);
+					inodelog = getnum(value, &opts[OPT_I],
+								I_LOG);
 					isize = 1 << inodelog;
 					ilflag = 1;
 					break;
 				case I_MAXPCT:
-					imaxpct = getnum(value, &iopts,
+					imaxpct = getnum(value, &opts[OPT_I],
 							 I_MAXPCT);
 					imflag = 1;
 					break;
 				case I_PERBLOCK:
-					inopblock = getnum(value, &iopts,
+					inopblock = getnum(value, &opts[OPT_I],
 							   I_PERBLOCK);
 					ipflag = 1;
 					break;
 				case I_SIZE:
-					isize = getnum(value, &iopts, I_SIZE);
+					isize = getnum(value, &opts[OPT_I],
+								I_SIZE);
 					inodelog = libxfs_highbit32(isize);
 					isflag = 1;
 					break;
 				case I_ATTR:
 					sb_feat.attr_version =
-						getnum(value, &iopts, I_ATTR);
+						getnum(value, &opts[OPT_I],
+								I_ATTR);
 					break;
 				case I_PROJID32BIT:
 					sb_feat.projid16bit =
-						!getnum(value, &iopts,
+						!getnum(value, &opts[OPT_I],
 							I_PROJID32BIT);
 					break;
 				case I_SPINODES:
 					sb_feat.spinodes = getnum(value,
-							&iopts, I_SPINODES);
+								&opts[OPT_I],
+								I_SPINODES);
 					break;
 				default:
 					unknown('i', value);
@@ -1728,63 +1757,70 @@ main(
 		case 'l':
 			p = optarg;
 			while (*p != '\0') {
-				char	**subopts = (char **)lopts.subopts;
+				char	**subopts =
+						(char **)opts[OPT_L].subopts;
 				char	*value;
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case L_AGNUM:
-					logagno = getnum(value, &lopts, L_AGNUM);
+					logagno = getnum(value, &opts[OPT_L],
+								L_AGNUM);
 					laflag = 1;
 					break;
 				case L_FILE:
-					xi.lisfile = getnum(value, &lopts,
-							    L_FILE);
+					xi.lisfile = getnum(value,
+						&opts[OPT_L], L_FILE);
 					break;
 				case L_INTERNAL:
-					loginternal = getnum(value, &lopts,
-							     L_INTERNAL);
+					loginternal = getnum(value,
+						&opts[OPT_L], L_INTERNAL);
 					liflag = 1;
 					break;
 				case L_SU:
-					lsu = getnum(value, &lopts, L_SU);
+					lsu = getnum(value, &opts[OPT_L],
+								L_SU);
 					lsuflag = 1;
 					break;
 				case L_SUNIT:
-					lsunit = getnum(value, &lopts, L_SUNIT);
+					lsunit = getnum(value, &opts[OPT_L],
+								L_SUNIT);
 					lsunitflag = 1;
 					break;
 				case L_NAME:
 				case L_DEV:
-					logfile = getstr(value, &lopts, L_NAME);
+					logfile = getstr(value, &opts[OPT_L],
+								L_NAME);
 					xi.logname = logfile;
 					ldflag = 1;
 					loginternal = 0;
 					break;
 				case L_VERSION:
 					sb_feat.log_version =
-						getnum(value, &lopts, L_VERSION);
+						getnum(value, &opts[OPT_L],
+								L_VERSION);
 					lvflag = 1;
 					break;
 				case L_SIZE:
-					logbytes = getnum(value, &lopts, L_SIZE);
+					logbytes = getnum(value,
+						&opts[OPT_L], L_SIZE);
 					break;
 				case L_SECTLOG:
-					lsectorlog = getnum(value, &lopts,
-							    L_SECTLOG);
+					lsectorlog = getnum(value,
+						&opts[OPT_L], L_SECTLOG);
 					lsectorsize = 1 << lsectorlog;
 					lslflag = 1;
 					break;
 				case L_SECTSIZE:
-					lsectorsize = getnum(value, &lopts,
-							     L_SECTSIZE);
+					lsectorsize = getnum(value,
+						&opts[OPT_L], L_SECTSIZE);
 					lsectorlog =
 						libxfs_highbit32(lsectorsize);
 					lssflag = 1;
 					break;
 				case L_LAZYSBCNTR:
 					sb_feat.lazy_sb_counters =
-							getnum(value, &lopts,
-							       L_LAZYSBCNTR);
+						getnum(value, &opts[OPT_L],
+							L_LAZYSBCNTR);
 					break;
 				default:
 					unknown('l', value);
@@ -1799,19 +1835,21 @@ main(
 		case 'm':
 			p = optarg;
 			while (*p != '\0') {
-				char	**subopts = (char **)mopts.subopts;
+				char	**subopts =
+						(char **)opts[OPT_M].subopts;
 				char	*value;
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case M_CRC:
 					sb_feat.crcs_enabled =
-						getnum(value, &mopts, M_CRC);
+						getnum(value, &opts[OPT_M],
+								M_CRC);
 					if (sb_feat.crcs_enabled)
 						sb_feat.dirftype = true;
 					break;
 				case M_FINOBT:
 					sb_feat.finobt = getnum(
-						value, &mopts, M_FINOBT);
+						value, &opts[OPT_M], M_FINOBT);
 					break;
 				case M_UUID:
 					if (!value || *value == '\0')
@@ -1821,11 +1859,12 @@ main(
 					break;
 				case M_RMAPBT:
 					sb_feat.rmapbt = getnum(
-						value, &mopts, M_RMAPBT);
+						value, &opts[OPT_M], M_RMAPBT);
 					break;
 				case M_REFLINK:
-					sb_feat.reflink = getnum(
-						value, &mopts, M_REFLINK);
+					sb_feat.reflink =
+						getnum(value, &opts[OPT_M],
+							M_REFLINK);
 					break;
 				default:
 					unknown('m', value);
@@ -1835,38 +1874,41 @@ main(
 		case 'n':
 			p = optarg;
 			while (*p != '\0') {
-				char	**subopts = (char **)nopts.subopts;
+				char	**subopts =
+						(char **)opts[OPT_N].subopts;
 				char	*value;
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case N_LOG:
-					dirblocklog = getnum(value, &nopts,
-							     N_LOG);
+					dirblocklog = getnum(value,
+						&opts[OPT_N], N_LOG);
 					dirblocksize = 1 << dirblocklog;
 					nlflag = 1;
 					break;
 				case N_SIZE:
-					dirblocksize = getnum(value, &nopts,
-							      N_SIZE);
+					dirblocksize = getnum(value,
+						&opts[OPT_N], N_SIZE);
 					dirblocklog =
 						libxfs_highbit32(dirblocksize);
 					nsflag = 1;
 					break;
 				case N_VERSION:
-					value = getstr(value, &nopts, N_VERSION);
+					value = getstr(value, &opts[OPT_N],
+								N_VERSION);
 					if (!strcasecmp(value, "ci")) {
 						/* ASCII CI mode */
 						sb_feat.nci = true;
 					} else {
 						sb_feat.dir_version =
-							getnum(value, &nopts,
+							getnum(value,
+							       &opts[OPT_N],
 							       N_VERSION);
 					}
 					nvflag = 1;
 					break;
 				case N_FTYPE:
-					sb_feat.dirftype = getnum(value, &nopts,
-								  N_FTYPE);
+					sb_feat.dirftype = getnum(value,
+						&opts[OPT_N], N_FTYPE);
 					break;
 				default:
 					unknown('n', value);
@@ -1890,27 +1932,30 @@ main(
 		case 'r':
 			p = optarg;
 			while (*p != '\0') {
-				char	**subopts = (char **)ropts.subopts;
+				char	**subopts =
+						(char **)opts[OPT_R].subopts;
 				char	*value;
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case R_EXTSIZE:
-					rtextbytes = getnum(value, &ropts, R_EXTSIZE);
+					rtextbytes = getnum(value,
+						&opts[OPT_R], R_EXTSIZE);
 					break;
 				case R_FILE:
-					xi.risfile = getnum(value, &ropts,
-							    R_FILE);
+					xi.risfile = getnum(value,
+						&opts[OPT_R], R_FILE);
 					break;
 				case R_NAME:
 				case R_DEV:
-					xi.rtname = getstr(value, &ropts,
+					xi.rtname = getstr(value, &opts[OPT_R],
 							   R_NAME);
 					break;
 				case R_SIZE:
-					rtbytes = getnum(value, &ropts, R_SIZE);
+					rtbytes = getnum(value, &opts[OPT_R],
+								R_SIZE);
 					break;
 				case R_NOALIGN:
-					norsflag = getnum(value, &ropts,
+					norsflag = getnum(value, &opts[OPT_R],
 								R_NOALIGN);
 					break;
 				default:
@@ -1921,7 +1966,8 @@ main(
 		case 's':
 			p = optarg;
 			while (*p != '\0') {
-				char	**subopts = (char **)sopts.subopts;
+				char	**subopts =
+						(char **)opts[OPT_S].subopts;
 				char	*value;
 
 				switch (getsubopt(&p, subopts, &value)) {
@@ -1929,8 +1975,9 @@ main(
 				case S_SECTLOG:
 					if (lssflag)
 						conflict('s', subopts,
-							 S_SECTSIZE, S_SECTLOG);
-					sectorlog = getnum(value, &sopts,
+							 S_SECTSIZE,
+							 S_SECTLOG);
+					sectorlog = getnum(value, &opts[OPT_S],
 							   S_SECTLOG);
 					lsectorlog = sectorlog;
 					sectorsize = 1 << sectorlog;
@@ -1940,10 +1987,11 @@ main(
 				case S_SIZE:
 				case S_SECTSIZE:
 					if (lslflag)
-						conflict('s', subopts, S_SECTLOG,
+						conflict('s', subopts,
+							 S_SECTLOG,
 							 S_SECTSIZE);
-					sectorsize = getnum(value, &sopts,
-							    S_SECTSIZE);
+					sectorsize = getnum(value,
+						&opts[OPT_S], S_SECTSIZE);
 					lsectorsize = sectorsize;
 					sectorlog =
 						libxfs_highbit32(sectorsize);
@@ -1966,7 +2014,8 @@ main(
 		fprintf(stderr, _("extra arguments\n"));
 		usage();
 	} else if (argc - optind == 1) {
-		dfile = xi.volname = getstr(argv[optind], &dopts, D_NAME);
+		dfile = xi.volname = getstr(argv[optind],
+					&opts[OPT_D], D_NAME);
 	} else
 		dfile = xi.dname;
 
@@ -2145,7 +2194,8 @@ _("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
 		 * then issue an error.
 		 * The same is also for sparse inodes.
 		 */
-		if (sb_feat.finobt && mopts.subopt_params[M_FINOBT].seen) {
+		if (sb_feat.finobt &&
+		    opts[OPT_M].subopt_params[M_FINOBT].seen) {
 			fprintf(stderr,
 _("finobt not supported without CRC support\n"));
 			usage();
@@ -2390,7 +2440,7 @@ _("rmapbt not supported with realtime devices\n"));
 		fprintf(stderr,
 			_("size %s specified for data subvolume is too large, "
 			"maximum is %"PRIu64" blocks\n"),
-			get_conf_raw(&dopts, D_SIZE),
+			get_conf_raw(OPT_D, D_SIZE),
 			(uint64_t)DTOBT(xi.dsize));
 		usage();
 	} else if (!dbytes && xi.dsize > 0)
@@ -2439,7 +2489,7 @@ reported by the device (%u).\n"),
 		fprintf(stderr,
 			_("size %s specified for rt subvolume is too large, "
 			"maximum is %"PRIu64" blocks\n"),
-			get_conf_raw(&ropts, R_SIZE),
+			get_conf_raw(OPT_R, R_SIZE),
 			(uint64_t)DTOBT(xi.rtsize));
 		usage();
 	} else if (!rtbytes && xi.rtsize > 0)
@@ -2654,7 +2704,7 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
 	if (logbytes && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
 		fprintf(stderr,
 _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks\n"),
-			get_conf_raw(&lopts, L_SIZE),
+			get_conf_raw(OPT_L, L_SIZE),
 			(uint64_t)DTOBT(xi.logBBsize));
 		usage();
 	} else if (!logbytes && xi.logBBsize > 0) {
-- 
2.1.4


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

* [PATCH 05/12] mkfs: extend opt_params with a value field
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (3 preceding siblings ...)
  2017-04-23 18:54 ` [PATCH 04/12] mkfs: merge tables for opts parsing into one table Jan Tulak
@ 2017-04-23 18:54 ` Jan Tulak
  2017-04-25  3:13   ` Luis R. Rodriguez
  2017-04-23 18:54 ` [PATCH 06/12] mkfs: create get/set functions for opts table Jan Tulak
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:54 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Add a new field int opt_params - value, which is filled with user input.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 513e106..c2ffd91 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -128,6 +128,12 @@ uint64_t		sectorsize;
  *     Filled raw string from the user, so we never lose that information e.g.
  *     to print it back in case of an issue.
  *
+ *   value OPTIONAL
+ *     The value that is to be used if the given subopt is not specified at all.
+ *     This is filled with user input and anything you write here now is
+ *     overwritten if user specifies the subopt. (If the user input is a string
+ *     and not a number, this value is set to a positive non-zero number.)
+ *
  * !!! NOTE ==================================================================
  *
  * If you are adding a new option, or changing an existing one,
@@ -152,6 +158,7 @@ struct opt_params {
 		uint64_t	maxval;
 		uint64_t	flagval;
 		const char	*raw_input;
+		uint64_t	value;
 	}		subopt_params[MAX_SUBOPTS];
 } opts[MAX_OPTS] = {
 #define OPT_B	0
-- 
2.1.4


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

* [PATCH 06/12] mkfs: create get/set functions for opts table
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (4 preceding siblings ...)
  2017-04-23 18:54 ` [PATCH 05/12] mkfs: extend opt_params with a value field Jan Tulak
@ 2017-04-23 18:54 ` Jan Tulak
  2017-04-25  3:40   ` Luis R. Rodriguez
  2017-04-23 18:54 ` [PATCH 07/12] mkfs: save user input values into opts Jan Tulak
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:54 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Add functions that can be used to get/set values to opts table.

Signed-off-by: Jan Tulak <jtulak@redhat.com>

---
 mkfs/xfs_mkfs.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index c2ffd91..4caf93c 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -786,6 +786,38 @@ get_conf_raw(int opt, int subopt)
 	return opts[opt].subopt_params[subopt].raw_input;
 }
 
+static uint64_t getnum(const char *str, struct opt_params *opts, int index);
+
+/*
+ * Get and set values to the opts table.
+ */
+static inline uint64_t
+get_conf_val(int opt, int subopt)
+{
+	return opts[opt].subopt_params[subopt].value;
+}
+
+static void
+set_conf_val(int opt, int subopt, uint64_t val)
+{
+	struct subopt_param *sp = &opts[opt].subopt_params[subopt];
+
+	sp->value = val;
+}
+
+/*
+ * A wrapper for getnum and set_conf_val.
+ */
+static inline uint64_t
+parse_conf_val(int opt, int subopt, char *value)
+{
+	uint64_t num = getnum(value, &opts[opt], subopt);
+
+	set_conf_val(opt, subopt, num);
+	return num;
+}
+
+
 /*
  * Convert lsu to lsunit for 512 bytes blocks and check validity of the values.
  */
-- 
2.1.4


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

* [PATCH 07/12] mkfs: save user input values into opts
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (5 preceding siblings ...)
  2017-04-23 18:54 ` [PATCH 06/12] mkfs: create get/set functions for opts table Jan Tulak
@ 2017-04-23 18:54 ` Jan Tulak
  2017-04-25  5:19   ` Luis R. Rodriguez
  2017-04-23 18:54 ` [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options Jan Tulak
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:54 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Save the parsed values from users into the opts table.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 260 +++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 165 insertions(+), 95 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 4caf93c..362c9b4 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1636,16 +1636,19 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case B_LOG:
-					blocklog = getnum(value, &opts[OPT_B],
-								B_LOG);
+					blocklog = parse_conf_val(OPT_B, B_LOG,
+								  value);
 					blocksize = 1 << blocklog;
 					blflag = 1;
+					set_conf_val(OPT_B, B_SIZE, blocksize);
 					break;
 				case B_SIZE:
-					blocksize = getnum(value, &opts[OPT_B],
-							   B_SIZE);
+					blocksize = parse_conf_val(OPT_B,
+								   B_SIZE,
+								   value);
 					blocklog = libxfs_highbit32(blocksize);
 					bsflag = 1;
+					set_conf_val(OPT_B, B_LOG, blocklog);
 					break;
 				default:
 					unknown('b', value);
@@ -1661,76 +1664,92 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case D_AGCOUNT:
-					agcount = getnum(value, &opts[OPT_D],
-							 D_AGCOUNT);
+					agcount = parse_conf_val(OPT_D,
+								 D_AGCOUNT,
+								 value);
 					daflag = 1;
 					break;
 				case D_AGSIZE:
-					agsize = getnum(value, &opts[OPT_D],
-								D_AGSIZE);
+					agsize = parse_conf_val(OPT_D,
+								D_AGSIZE,
+								value);
 					dasize = 1;
 					break;
 				case D_FILE:
-					xi.disfile = getnum(value,
-						&opts[OPT_D], D_FILE);
+					xi.disfile = parse_conf_val(OPT_D,
+								    D_FILE,
+								    value);
 					break;
 				case D_NAME:
 					xi.dname = getstr(value, &opts[OPT_D],
 								D_NAME);
+					set_conf_val(OPT_D, D_NAME,  1);
 					break;
 				case D_SIZE:
-					dbytes = getnum(value, &opts[OPT_D],
-								D_SIZE);
+					dbytes = parse_conf_val(OPT_D, D_SIZE,
+								value);
 					break;
 				case D_SUNIT:
-					dsunit = getnum(value, &opts[OPT_D],
-								D_SUNIT);
+					dsunit = parse_conf_val(OPT_D, D_SUNIT,
+								value);
 					break;
 				case D_SWIDTH:
-					dswidth = getnum(value, &opts[OPT_D],
-							 D_SWIDTH);
+					dswidth = parse_conf_val(OPT_D,
+								 D_SWIDTH,
+								 value);
 					break;
 				case D_SU:
-					dsu = getnum(value, &opts[OPT_D],
-								D_SU);
+					dsu = parse_conf_val(OPT_D, D_SU,
+							     value);
 					break;
 				case D_SW:
-					dsw = getnum(value, &opts[OPT_D],
-								D_SW);
+					dsw = parse_conf_val(OPT_D, D_SW,
+							     value);
 					break;
 				case D_NOALIGN:
-					nodsflag = getnum(value, &opts[OPT_D],
-								D_NOALIGN);
+					nodsflag = parse_conf_val(OPT_D,
+								  D_NOALIGN,
+								  value);
 					break;
 				case D_SECTLOG:
-					sectorlog = getnum(value, &opts[OPT_D],
-							   D_SECTLOG);
+					sectorlog = parse_conf_val(OPT_D,
+								   D_SECTLOG,
+								   value);
 					sectorsize = 1 << sectorlog;
 					slflag = 1;
+					set_conf_val(OPT_D, D_SECTSIZE,
+						     sectorsize);
 					break;
 				case D_SECTSIZE:
-					sectorsize = getnum(value,
-						&opts[OPT_D], D_SECTSIZE);
+					sectorsize = parse_conf_val(OPT_D,
+								    D_SECTSIZE,
+								    value);
 					sectorlog =
 						libxfs_highbit32(sectorsize);
 					ssflag = 1;
+					set_conf_val(OPT_D, D_SECTLOG,
+						     sectorlog);
 					break;
 				case D_RTINHERIT:
-					c = getnum(value, &opts[OPT_D],
-								D_RTINHERIT);
+					c = parse_conf_val(OPT_D, D_RTINHERIT,
+							   value);
 					if (c)
 						fsx.fsx_xflags |=
 							XFS_DIFLAG_RTINHERIT;
 					break;
 				case D_PROJINHERIT:
-					fsx.fsx_projid = getnum(value,
-						&opts[OPT_D], D_PROJINHERIT);
+					fsx.fsx_projid =
+						parse_conf_val(OPT_D,
+							       D_PROJINHERIT,
+							       value);
 					fsx.fsx_xflags |=
 						XFS_DIFLAG_PROJINHERIT;
 					break;
 				case D_EXTSZINHERIT:
-					fsx.fsx_extsize = getnum(value,
-						&opts[OPT_D], D_EXTSZINHERIT);
+					fsx.fsx_extsize =
+						parse_conf_val(OPT_D,
+							       D_EXTSZINHERIT,
+							       value);
 					fsx.fsx_xflags |=
 						XFS_DIFLAG_EXTSZINHERIT;
 					break;
@@ -1748,45 +1767,53 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case I_ALIGN:
-					sb_feat.inode_align = getnum(value,
-						&opts[OPT_I], I_ALIGN);
+					sb_feat.inode_align =
+						parse_conf_val(OPT_I, I_ALIGN,
+							       value);
 					break;
 				case I_LOG:
-					inodelog = getnum(value, &opts[OPT_I],
-								I_LOG);
+					inodelog = parse_conf_val(OPT_I, I_LOG,
+								  value);
 					isize = 1 << inodelog;
 					ilflag = 1;
+					set_conf_val(OPT_I, I_SIZE, isize);
 					break;
 				case I_MAXPCT:
-					imaxpct = getnum(value, &opts[OPT_I],
-							 I_MAXPCT);
+					imaxpct = parse_conf_val(OPT_I,
+								 I_MAXPCT,
+								 value);
 					imflag = 1;
 					break;
 				case I_PERBLOCK:
-					inopblock = getnum(value, &opts[OPT_I],
-							   I_PERBLOCK);
+					inopblock = parse_conf_val(OPT_I,
+								   I_PERBLOCK,
+								   value);
 					ipflag = 1;
 					break;
 				case I_SIZE:
-					isize = getnum(value, &opts[OPT_I],
-								I_SIZE);
+					isize = parse_conf_val(OPT_I, I_SIZE,
+							       value);
 					inodelog = libxfs_highbit32(isize);
 					isflag = 1;
+					set_conf_val(OPT_I, I_LOG, inodelog);
 					break;
 				case I_ATTR:
 					sb_feat.attr_version =
-						getnum(value, &opts[OPT_I],
-								I_ATTR);
+						parse_conf_val(OPT_I, I_ATTR,
+							       value);
 					break;
 				case I_PROJID32BIT:
 					sb_feat.projid16bit =
 						!getnum(value, &opts[OPT_I],
 							I_PROJID32BIT);
+					set_conf_val(OPT_I, I_PROJID32BIT,
+						     sb_feat.projid16bit);
 					break;
 				case I_SPINODES:
-					sb_feat.spinodes = getnum(value,
-								&opts[OPT_I],
-								I_SPINODES);
+					sb_feat.spinodes =
+						parse_conf_val(OPT_I,
+							       I_SPINODES,
+							       value);
 					break;
 				default:
 					unknown('i', value);
@@ -1802,27 +1829,31 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case L_AGNUM:
-					logagno = getnum(value, &opts[OPT_L],
-								L_AGNUM);
+					logagno = parse_conf_val(OPT_L,
+								 L_AGNUM,
+								 value);
 					laflag = 1;
 					break;
 				case L_FILE:
-					xi.lisfile = getnum(value,
-						&opts[OPT_L], L_FILE);
+					xi.lisfile = parse_conf_val(OPT_L,
+								    L_FILE,
+								    value);
 					break;
 				case L_INTERNAL:
-					loginternal = getnum(value,
-						&opts[OPT_L], L_INTERNAL);
+					loginternal =
+						parse_conf_val(OPT_L,
+							       L_INTERNAL,
+							       value);
 					liflag = 1;
 					break;
 				case L_SU:
-					lsu = getnum(value, &opts[OPT_L],
-								L_SU);
+					lsu = parse_conf_val(OPT_L, L_SU,
+							     value);
 					lsuflag = 1;
 					break;
 				case L_SUNIT:
-					lsunit = getnum(value, &opts[OPT_L],
-								L_SUNIT);
+					lsunit = parse_conf_val(OPT_L, L_SUNIT,
+								value);
 					lsunitflag = 1;
 					break;
 				case L_NAME:
@@ -1832,34 +1863,48 @@ main(
 					xi.logname = logfile;
 					ldflag = 1;
 					loginternal = 0;
+					set_conf_val(OPT_L, L_NAME, 1);
+					set_conf_val(OPT_L, L_DEV, 1);
 					break;
 				case L_VERSION:
 					sb_feat.log_version =
-						getnum(value, &opts[OPT_L],
-								L_VERSION);
+						parse_conf_val(OPT_L,
+							       L_VERSION,
+							       value);
 					lvflag = 1;
+					set_conf_val(OPT_L, L_VERSION,
+						     sb_feat.log_version);
 					break;
 				case L_SIZE:
-					logbytes = getnum(value,
-						&opts[OPT_L], L_SIZE);
+					logbytes = parse_conf_val(OPT_L,
+								  L_SIZE,
+								  value);
 					break;
 				case L_SECTLOG:
-					lsectorlog = getnum(value,
-						&opts[OPT_L], L_SECTLOG);
+					lsectorlog = parse_conf_val(OPT_L,
+								    L_SECTLOG,
+								    value);
 					lsectorsize = 1 << lsectorlog;
 					lslflag = 1;
+					set_conf_val(OPT_L, L_SECTSIZE,
+						     lsectorsize);
 					break;
 				case L_SECTSIZE:
-					lsectorsize = getnum(value,
-						&opts[OPT_L], L_SECTSIZE);
+					lsectorsize =
+						parse_conf_val(OPT_L,
+							       L_SECTSIZE,
+							       value);
 					lsectorlog =
 						libxfs_highbit32(lsectorsize);
 					lssflag = 1;
+					set_conf_val(OPT_L, L_SECTLOG,
+						     lsectorlog);
 					break;
 				case L_LAZYSBCNTR:
 					sb_feat.lazy_sb_counters =
-						getnum(value, &opts[OPT_L],
-							L_LAZYSBCNTR);
+						parse_conf_val(OPT_L,
+							       L_LAZYSBCNTR,
+							       value);
 					break;
 				default:
 					unknown('l', value);
@@ -1881,29 +1926,35 @@ main(
 				switch (getsubopt(&p, subopts, &value)) {
 				case M_CRC:
 					sb_feat.crcs_enabled =
-						getnum(value, &opts[OPT_M],
-								M_CRC);
+						parse_conf_val(OPT_M, M_CRC,
+							       value);
 					if (sb_feat.crcs_enabled)
 						sb_feat.dirftype = true;
 					break;
 				case M_FINOBT:
-					sb_feat.finobt = getnum(
-						value, &opts[OPT_M], M_FINOBT);
+					sb_feat.finobt =
+						parse_conf_val(OPT_M, M_FINOBT,
+							       value);
+					set_conf_val(OPT_M, M_FINOBT,
+						     sb_feat.finobt);
 					break;
 				case M_UUID:
 					if (!value || *value == '\0')
 						reqval('m', subopts, M_UUID);
 					if (platform_uuid_parse(value, &uuid))
 						illegal(optarg, "m uuid");
+					set_conf_val(OPT_M, M_UUID, 1);
 					break;
 				case M_RMAPBT:
-					sb_feat.rmapbt = getnum(
-						value, &opts[OPT_M], M_RMAPBT);
+					sb_feat.rmapbt =
+						parse_conf_val(OPT_M, M_RMAPBT,
+							       value);
 					break;
 				case M_REFLINK:
 					sb_feat.reflink =
-						getnum(value, &opts[OPT_M],
-							M_REFLINK);
+						parse_conf_val(OPT_M,
+							       M_REFLINK,
+							       value);
 					break;
 				default:
 					unknown('m', value);
@@ -1919,17 +1970,23 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case N_LOG:
-					dirblocklog = getnum(value,
-						&opts[OPT_N], N_LOG);
+					dirblocklog = parse_conf_val(OPT_N,
+								     N_LOG,
+								     value);
 					dirblocksize = 1 << dirblocklog;
 					nlflag = 1;
+					set_conf_val(OPT_N, N_SIZE,
+						     dirblocksize);
 					break;
 				case N_SIZE:
-					dirblocksize = getnum(value,
-						&opts[OPT_N], N_SIZE);
+					dirblocksize = parse_conf_val(OPT_N,
+								      N_SIZE,
+								      value);
 					dirblocklog =
 						libxfs_highbit32(dirblocksize);
 					nsflag = 1;
+					set_conf_val(OPT_N, N_LOG,
+						     dirblocklog);
 					break;
 				case N_VERSION:
 					value = getstr(value, &opts[OPT_N],
@@ -1940,14 +1997,17 @@ main(
 					} else {
 						sb_feat.dir_version =
 							getnum(value,
-							       &opts[OPT_N],
-							       N_VERSION);
+								&opts[OPT_N],
+								N_VERSION);
 					}
 					nvflag = 1;
+					set_conf_val(OPT_N, N_VERSION,
+						     sb_feat.dir_version);
 					break;
 				case N_FTYPE:
-					sb_feat.dirftype = getnum(value,
-						&opts[OPT_N], N_FTYPE);
+					sb_feat.dirftype =
+						parse_conf_val(OPT_N, N_FTYPE,
+							       value);
 					break;
 				default:
 					unknown('n', value);
@@ -1977,25 +2037,30 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case R_EXTSIZE:
-					rtextbytes = getnum(value,
-						&opts[OPT_R], R_EXTSIZE);
+					rtextbytes = parse_conf_val(OPT_R,
+								    R_EXTSIZE,
+								    value);
 					break;
 				case R_FILE:
-					xi.risfile = getnum(value,
-						&opts[OPT_R], R_FILE);
+					xi.risfile = parse_conf_val(OPT_R,
+								    R_FILE,
+								    value);
 					break;
 				case R_NAME:
 				case R_DEV:
 					xi.rtname = getstr(value, &opts[OPT_R],
 							   R_NAME);
+					set_conf_val(OPT_R, R_NAME, 1);
+					set_conf_val(OPT_R, R_DEV, 1);
 					break;
 				case R_SIZE:
-					rtbytes = getnum(value, &opts[OPT_R],
-								R_SIZE);
+					rtbytes = parse_conf_val(OPT_R, R_SIZE,
+								 value);
 					break;
 				case R_NOALIGN:
-					norsflag = getnum(value, &opts[OPT_R],
-								R_NOALIGN);
+					norsflag = parse_conf_val(OPT_R,
+								  R_NOALIGN,
+								  value);
 					break;
 				default:
 					unknown('r', value);
@@ -2016,12 +2081,14 @@ main(
 						conflict('s', subopts,
 							 S_SECTSIZE,
 							 S_SECTLOG);
-					sectorlog = getnum(value, &opts[OPT_S],
-							   S_SECTLOG);
+					sectorlog = parse_conf_val(OPT_S,
+								   S_SECTLOG,
+								   value);
 					lsectorlog = sectorlog;
 					sectorsize = 1 << sectorlog;
 					lsectorsize = sectorsize;
 					lslflag = slflag = 1;
+					set_conf_val(OPT_S, S_LOG, sectorsize);
 					break;
 				case S_SIZE:
 				case S_SECTSIZE:
@@ -2029,13 +2096,16 @@ main(
 						conflict('s', subopts,
 							 S_SECTLOG,
 							 S_SECTSIZE);
-					sectorsize = getnum(value,
-						&opts[OPT_S], S_SECTSIZE);
+					sectorsize = parse_conf_val(OPT_S,
+								    S_SECTSIZE,
+								    value);
 					lsectorsize = sectorsize;
 					sectorlog =
 						libxfs_highbit32(sectorsize);
 					lsectorlog = sectorlog;
 					lssflag = ssflag = 1;
+					set_conf_val(OPT_S,
+						     S_SIZE, sectorlog);
 					break;
 				default:
 					unknown('s', value);
-- 
2.1.4


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

* [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (6 preceding siblings ...)
  2017-04-23 18:54 ` [PATCH 07/12] mkfs: save user input values into opts Jan Tulak
@ 2017-04-23 18:54 ` Jan Tulak
  2017-04-25  5:27   ` Luis R. Rodriguez
  2017-04-23 18:55 ` [PATCH 09/12] mkfs: replace variables with opts table: -i options Jan Tulak
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:54 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Remove variables that can be replaced with a direct access to the opts table,
so we have it all in a single place, acessible from anywhere.

In future, we can remove some passing of values forth and back, but now limit
the changes to simple replacement without a change in the logic.

This is first of multiple similar patches that do the same, but for other
options.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 814 ++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 503 insertions(+), 311 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 362c9b4..6857c30 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -35,13 +35,6 @@ static void respec(char opt, char *tab[], int idx);
 static void unknown(char opt, char *s);
 static int  ispow2(unsigned int i);
 
-/*
- * The configured block and sector sizes are defined as global variables so
- * that they don't need to be passed to functions that require them.
- */
-uint64_t		blocksize;
-uint64_t		sectorsize;
-
 #define MAX_OPTS	16
 #define MAX_SUBOPTS	16
 #define SUBOPT_NEEDS_VAL	(-1LL)
@@ -757,7 +750,8 @@ struct opt_params {
 /*
  * Use this macro before we have superblock and mount structure
  */
-#define	DTOBT(d)	((xfs_rfsblock_t)((d) >> (blocklog - BBSHIFT)))
+#define	DTOBT(d) \
+	((xfs_rfsblock_t)((d) >> (get_conf_val(OPT_B, B_LOG) - BBSHIFT)))
 
 /*
  * Use this for block reservations needed for mkfs's conditions
@@ -872,16 +866,16 @@ calc_stripe_factors(
 		*lsunit = BTOBBT(lsu);
 
 	/* verify if lsu/lsunit is a multiple block size */
-	if (lsu % blocksize != 0) {
+	if (lsu % get_conf_val(OPT_B, B_SIZE) != 0) {
 		fprintf(stderr,
 _("log stripe unit (%d) must be a multiple of the block size (%"PRIu64")\n"),
-		lsu, blocksize);
+		lsu, get_conf_val(OPT_B, B_SIZE));
 		exit(1);
 	}
-	if ((BBTOB(*lsunit) % blocksize != 0)) {
+	if ((BBTOB(*lsunit) % get_conf_val(OPT_B, B_SIZE) != 0)) {
 		fprintf(stderr,
 _("log stripe unit (%"PRIu64") must be a multiple of the block size (%"PRIu64")\n"),
-		BBTOB(*lsunit), blocksize);
+		BBTOB(*lsunit), get_conf_val(OPT_B, B_SIZE));
 		exit(1);
 	}
 }
@@ -1037,7 +1031,7 @@ validate_log_size(uint64_t logblocks, int blocklog, int min_logblocks)
 			logblocks, XFS_MAX_LOG_BLOCKS);
 		usage();
 	}
-	if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) {
+	if ((logblocks << get_conf_val(OPT_B, B_LOG)) > XFS_MAX_LOG_BYTES) {
 		fprintf(stderr,
 	_("log size %"PRIu64" bytes too large, maximum size is %lld bytes\n"),
 			(logblocks << blocklog), XFS_MAX_LOG_BYTES);
@@ -1131,9 +1125,9 @@ validate_ag_geometry(
 	}
 
 	/*
-	 * If agcount is too large, make it smaller.
+	 * If D_AGCOUNT is too large, make it smaller.
 	 */
-	if (agcount > XFS_MAX_AGNUMBER + 1) {
+	if (get_conf_val(OPT_D, D_AGCOUNT) > XFS_MAX_AGNUMBER + 1) {
 		fprintf(stderr,
 	_("%"PRIu64" allocation groups is too many, maximum is %"PRIu64"\n"),
 			agcount, (uint64_t)XFS_MAX_AGNUMBER + 1);
@@ -1439,7 +1433,8 @@ getnum(
 	 * number.
 	 */
 	if (sp->convert)
-		c = cvtnum(blocksize, sectorsize, str);
+		c = cvtnum(get_conf_val(OPT_B, B_SIZE),
+			   get_conf_val(OPT_D, D_SECTSIZE), str);
 	else {
 		char		*str_end;
 
@@ -1485,15 +1480,12 @@ main(
 	int			argc,
 	char			**argv)
 {
-	uint64_t		agcount;
 	xfs_agf_t		*agf;
 	xfs_agi_t		*agi;
 	xfs_agnumber_t		agno;
-	uint64_t		agsize;
 	xfs_alloc_rec_t		*arec;
 	struct xfs_btree_block	*block;
 	bool			blflag;
-	uint64_t		blocklog;
 	bool			bsflag;
 	uint64_t		bsize;
 	xfs_buf_t		*buf;
@@ -1504,11 +1496,6 @@ main(
 	char			*dfile;
 	uint64_t		dirblocklog;
 	uint64_t		dirblocksize;
-	uint64_t		dbytes;
-	uint64_t		dsu;
-	uint64_t		dsw;
-	uint64_t		dsunit;
-	uint64_t		dswidth;
 	bool			force_overwrite;
 	struct fsxattr		fsx;
 	bool			ilflag;
@@ -1545,7 +1532,6 @@ main(
 	xfs_mount_t		mbuf;
 	xfs_extlen_t		nbmblocks;
 	bool			nlflag;
-	bool			nodsflag;
 	bool			norsflag;
 	xfs_alloc_rec_t		*nrec;
 	bool			nsflag;
@@ -1563,7 +1549,6 @@ main(
 	uint64_t		rtextbytes;
 	char			*rtfile;
 	xfs_sb_t		*sbp;
-	uint64_t		sectorlog;
 	uint64_t		sector_mask;
 	bool			slflag;
 	bool			ssflag;
@@ -1596,10 +1581,9 @@ main(
 	textdomain(PACKAGE);
 
 	blflag = bsflag = slflag = ssflag = lslflag = lssflag = 0;
-	blocklog = blocksize = 0;
-	sectorlog = lsectorlog = 0;
-	sectorsize = lsectorsize = 0;
-	agsize = dasize = dblocks = 0;
+	lsectorlog = 0;
+	lsectorsize = 0;
+	dasize = dblocks = 0;
 	daflag = ilflag = imflag = ipflag = isflag = false;
 	liflag = laflag = lsflag = lsuflag = lsunitflag = ldflag = lvflag = false;
 	loginternal = 1;
@@ -1610,9 +1594,9 @@ main(
 	imaxpct = inodelog = inopblock = isize = 0;
 	dfile = logfile = rtfile = NULL;
 	protofile = NULL;
-	rtbytes = rtextbytes = logbytes = dbytes = 0;
-	dsu = dsw = dsunit = dswidth = lalign = lsu = lsunit = 0;
-	nodsflag = norsflag = false;
+	rtbytes = rtextbytes = logbytes = 0;
+	lalign = lsu = lsunit = 0;
+	norsflag = false;
 	force_overwrite = false;
 	worst_freelist = 0;
 	memset(&fsx, 0, sizeof(fsx));
@@ -1629,6 +1613,7 @@ main(
 			break;
 		case 'b':
 			p = optarg;
+			uint64_t tmp;
 			while (*p != '\0') {
 				char	**subopts =
 						(char **)opts[OPT_B].subopts;
@@ -1636,19 +1621,17 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case B_LOG:
-					blocklog = parse_conf_val(OPT_B, B_LOG,
-								  value);
-					blocksize = 1 << blocklog;
+					tmp = parse_conf_val(OPT_B, B_LOG,
+							     value);
+					set_conf_val(OPT_B, B_SIZE, 1 << tmp);
 					blflag = 1;
-					set_conf_val(OPT_B, B_SIZE, blocksize);
 					break;
 				case B_SIZE:
-					blocksize = parse_conf_val(OPT_B,
-								   B_SIZE,
-								   value);
-					blocklog = libxfs_highbit32(blocksize);
+					tmp = parse_conf_val(OPT_B, B_SIZE,
+							     value);
+					set_conf_val(OPT_B, B_LOG,
+						libxfs_highbit32(tmp));
 					bsflag = 1;
-					set_conf_val(OPT_B, B_LOG, blocklog);
 					break;
 				default:
 					unknown('b', value);
@@ -1661,18 +1644,17 @@ main(
 				char	**subopts =
 						(char **)opts[OPT_D].subopts;
 				char	*value;
+				uint64_t tmp;
+
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case D_AGCOUNT:
-					agcount = parse_conf_val(OPT_D,
-								 D_AGCOUNT,
-								 value);
+					parse_conf_val(OPT_D, D_AGCOUNT,
+						       value);
 					daflag = 1;
 					break;
 				case D_AGSIZE:
-					agsize = parse_conf_val(OPT_D,
-								D_AGSIZE,
-								value);
+					parse_conf_val(OPT_D, D_AGSIZE, value);
 					dasize = 1;
 					break;
 				case D_FILE:
@@ -1686,49 +1668,70 @@ main(
 					set_conf_val(OPT_D, D_NAME,  1);
 					break;
 				case D_SIZE:
-					dbytes = parse_conf_val(OPT_D, D_SIZE,
-								value);
+					parse_conf_val(OPT_D, D_SIZE, value);
 					break;
 				case D_SUNIT:
-					dsunit = parse_conf_val(OPT_D, D_SUNIT,
-								value);
+					parse_conf_val(OPT_D, D_SUNIT, value);
 					break;
 				case D_SWIDTH:
-					dswidth = parse_conf_val(OPT_D,
-								 D_SWIDTH,
-								 value);
+					parse_conf_val(OPT_D, D_SWIDTH, value);
 					break;
 				case D_SU:
-					dsu = parse_conf_val(OPT_D, D_SU,
-							     value);
+					parse_conf_val(OPT_D, D_SU, value);
 					break;
 				case D_SW:
-					dsw = parse_conf_val(OPT_D, D_SW,
-							     value);
+					parse_conf_val(OPT_D, D_SW, value);
 					break;
 				case D_NOALIGN:
-					nodsflag = parse_conf_val(OPT_D,
-								  D_NOALIGN,
-								  value);
+					parse_conf_val(OPT_D, D_NOALIGN,
+						       value);
 					break;
 				case D_SECTLOG:
-					sectorlog = parse_conf_val(OPT_D,
-								   D_SECTLOG,
-								   value);
-					sectorsize = 1 << sectorlog;
-					slflag = 1;
+					/*
+					 * we can set sector size both as
+					 * -d sectsize/sectlog and as -s option.
+					 * Thus we need to fill the same value
+					 * into multiple options to make sure
+					 * that we are doing the parsing right.
+					 * Only D_SECTSIZE/D_SECTLOG is used
+					 * later in the code, though.
+					 */
+					tmp = parse_conf_val(OPT_D, D_SECTLOG,
+							     value);
+
+					set_conf_val(OPT_S, S_LOG, tmp);
+					set_conf_val(OPT_S, S_SECTLOG, tmp);
 					set_conf_val(OPT_D, D_SECTSIZE,
-						     sectorsize);
+						     1 << tmp);
+					set_conf_val(OPT_S, S_SECTSIZE,
+						     1 << tmp);
+					set_conf_val(OPT_S, S_SIZE,
+						     1 << tmp);
+					slflag = 1;
 					break;
 				case D_SECTSIZE:
-					sectorsize = parse_conf_val(OPT_D,
-								    D_SECTSIZE,
-								    value);
-					sectorlog =
-						libxfs_highbit32(sectorsize);
-					ssflag = 1;
+					/*
+					 * we can set sector size both as
+					 * -d sectsize/sectlog and as -s option.
+					 * Thus we need to fill the same value
+					 * into multiple options to make sure
+					 * that we are doing the parsing right.
+					 * Only D_SECTSIZE/D_SECTLOG is used
+					 * later in the code, though.
+					 */
+					tmp = parse_conf_val(OPT_D, D_SECTSIZE,
+							     value);
+
+					set_conf_val(OPT_S, S_SIZE, tmp);
+					set_conf_val(OPT_S, S_SECTSIZE, tmp);
 					set_conf_val(OPT_D, D_SECTLOG,
-						     sectorlog);
+						libxfs_highbit32(tmp));
+					set_conf_val(OPT_S, S_LOG,
+						libxfs_highbit32(tmp));
+					set_conf_val(OPT_S, S_SECTLOG,
+						libxfs_highbit32(tmp));
+
+					ssflag = 1;
 					break;
 				case D_RTINHERIT:
 					c = parse_conf_val(OPT_D, D_RTINHERIT,
@@ -2073,6 +2076,16 @@ main(
 				char	**subopts =
 						(char **)opts[OPT_S].subopts;
 				char	*value;
+				uint64_t tmp;
+				/*
+				 * we can set sector size both as
+				 * -d sectsize/sectlog and as -s option.
+				 * Thus we need to fill the same value
+				 * into multiple options to make sure
+				 * that we are doing the parsing right.
+				 * Only D_SECTSIZE/D_SECTLOG is used
+				 * later in the code, though.
+				 */
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case S_LOG:
@@ -2081,14 +2094,21 @@ main(
 						conflict('s', subopts,
 							 S_SECTSIZE,
 							 S_SECTLOG);
-					sectorlog = parse_conf_val(OPT_S,
+					tmp = parse_conf_val(OPT_S,
 								   S_SECTLOG,
 								   value);
-					lsectorlog = sectorlog;
-					sectorsize = 1 << sectorlog;
-					lsectorsize = sectorsize;
+
+					set_conf_val(OPT_S, S_LOG, tmp);
+					set_conf_val(OPT_D, D_SECTLOG, tmp);
+					lsectorlog = tmp;
+					set_conf_val(OPT_D, D_SECTSIZE,
+						     1 << tmp);
+					set_conf_val(OPT_S, S_SIZE, 1 << tmp);
+					set_conf_val(OPT_S, S_SECTSIZE,
+						     1 << tmp);
+
+					lsectorsize = tmp;
 					lslflag = slflag = 1;
-					set_conf_val(OPT_S, S_LOG, sectorsize);
 					break;
 				case S_SIZE:
 				case S_SECTSIZE:
@@ -2096,16 +2116,22 @@ main(
 						conflict('s', subopts,
 							 S_SECTLOG,
 							 S_SECTSIZE);
-					sectorsize = parse_conf_val(OPT_S,
+					tmp = parse_conf_val(OPT_S,
 								    S_SECTSIZE,
 								    value);
-					lsectorsize = sectorsize;
-					sectorlog =
-						libxfs_highbit32(sectorsize);
-					lsectorlog = sectorlog;
+
+					set_conf_val(OPT_S, S_SIZE, tmp);
+					set_conf_val(OPT_D, D_SECTSIZE, tmp);
+					lsectorsize = tmp;
+					set_conf_val(OPT_D, D_SECTLOG,
+						libxfs_highbit32(tmp));
+					set_conf_val(OPT_S, S_LOG,
+						libxfs_highbit32(tmp));
+					set_conf_val(OPT_S, S_SECTLOG,
+						libxfs_highbit32(tmp));
+					lsectorlog = libxfs_highbit32(tmp);
+
 					lssflag = ssflag = 1;
-					set_conf_val(OPT_S,
-						     S_SIZE, sectorlog);
 					break;
 				default:
 					unknown('s', value);
@@ -2129,19 +2155,22 @@ main(
 		dfile = xi.dname;
 
 	/*
-	 * Blocksize and sectorsize first, other things depend on them
+	 * Blocksize and D_SECTSIZE first, other things depend on them
 	 * For RAID4/5/6 we want to align sector size and block size,
 	 * so we need to start with the device geometry extraction too.
 	 */
 	if (!blflag && !bsflag) {
-		blocklog = XFS_DFL_BLOCKSIZE_LOG;
-		blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG;
+		set_conf_val(OPT_B, B_LOG, XFS_DFL_BLOCKSIZE_LOG);
+		set_conf_val(OPT_B, B_SIZE, 1 << XFS_DFL_BLOCKSIZE_LOG);
 	}
-	if (blocksize < XFS_MIN_BLOCKSIZE || blocksize > XFS_MAX_BLOCKSIZE) {
-		fprintf(stderr, _("illegal block size %"PRIu64"\n"), blocksize);
+	if (get_conf_val(OPT_B, B_SIZE) < XFS_MIN_BLOCKSIZE ||
+	    get_conf_val(OPT_B, B_SIZE) > XFS_MAX_BLOCKSIZE) {
+		fprintf(stderr, _("illegal block size %"PRIu64"\n"),
+			get_conf_val(OPT_B, B_SIZE));
 		usage();
 	}
-	if (sb_feat.crcs_enabled && blocksize < XFS_MIN_CRC_BLOCKSIZE) {
+	if (sb_feat.crcs_enabled &&
+	    get_conf_val(OPT_B, B_SIZE) < XFS_MIN_CRC_BLOCKSIZE) {
 		fprintf(stderr,
 _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 			XFS_MIN_CRC_BLOCKSIZE);
@@ -2153,12 +2182,12 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 	}
 
 	if (!slflag && !ssflag) {
-		sectorlog = XFS_MIN_SECTORSIZE_LOG;
-		sectorsize = XFS_MIN_SECTORSIZE;
+		set_conf_val(OPT_D, D_SECTLOG, XFS_MIN_SECTORSIZE_LOG);
+		set_conf_val(OPT_D, D_SECTSIZE, XFS_MIN_SECTORSIZE);
 	}
 	if (!lslflag && !lssflag) {
-		lsectorlog = sectorlog;
-		lsectorsize = sectorsize;
+		lsectorlog = get_conf_val(OPT_D, D_SECTLOG);
+		lsectorsize = get_conf_val(OPT_D, D_SECTSIZE);
 	}
 
 	/*
@@ -2168,7 +2197,8 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 	 * sector size mismatches between the new filesystem and the underlying
 	 * host filesystem.
 	 */
-	check_device_type(dfile, &xi.disfile, !dbytes, !dfile,
+	check_device_type(dfile, &xi.disfile, !get_conf_val(OPT_D, D_SIZE),
+			  !dfile,
 			  Nflag ? NULL : &xi.dcreat, force_overwrite, "d");
 	if (!loginternal)
 		check_device_type(xi.logname, &xi.lisfile, !logbytes,
@@ -2197,50 +2227,58 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 		if (!ft.psectorsize)
 			ft.psectorsize = ft.lsectorsize;
 
-		sectorsize = ft.psectorsize ? ft.psectorsize :
-					      XFS_MIN_SECTORSIZE;
+		set_conf_val(OPT_D, D_SECTSIZE,
+			     ft.psectorsize ? ft.psectorsize :
+					      XFS_MIN_SECTORSIZE);
 
-		if ((blocksize < sectorsize) && (blocksize >= ft.lsectorsize)) {
+		if ((get_conf_val(OPT_B, B_SIZE) <
+		     get_conf_val(OPT_D, D_SECTSIZE)) &&
+		    (get_conf_val(OPT_B, B_SIZE) >= ft.lsectorsize)) {
 			fprintf(stderr,
 _("specified blocksize %"PRIu64" is less than device physical sector size %d\n"),
-				blocksize, ft.psectorsize);
+				get_conf_val(OPT_B, B_SIZE), ft.psectorsize);
 			fprintf(stderr,
 _("switching to logical sector size %d\n"),
 				ft.lsectorsize);
-			sectorsize = ft.lsectorsize ? ft.lsectorsize :
-						      XFS_MIN_SECTORSIZE;
+			set_conf_val(OPT_D, D_SECTSIZE,
+				     ft.lsectorsize ? ft.lsectorsize :
+						      XFS_MIN_SECTORSIZE);
 		}
 	}
 
 	if (!ssflag) {
-		sectorlog = libxfs_highbit32(sectorsize);
+		set_conf_val(OPT_D, D_SECTLOG,
+			     libxfs_highbit32(get_conf_val(OPT_D, D_SECTSIZE)));
 		if (loginternal) {
-			lsectorsize = sectorsize;
-			lsectorlog = sectorlog;
+			lsectorsize = get_conf_val(OPT_D, D_SECTSIZE);
+			lsectorlog = get_conf_val(OPT_D, D_SECTLOG);
 		}
 	}
 
-	if (sectorsize < XFS_MIN_SECTORSIZE ||
-	    sectorsize > XFS_MAX_SECTORSIZE || sectorsize > blocksize) {
+	if (get_conf_val(OPT_D, D_SECTSIZE) < XFS_MIN_SECTORSIZE ||
+	    get_conf_val(OPT_D, D_SECTSIZE) > XFS_MAX_SECTORSIZE ||
+	    get_conf_val(OPT_D, D_SECTSIZE) > get_conf_val(OPT_B, B_SIZE)) {
 		if (ssflag)
-			fprintf(stderr, _("illegal sector size %"PRIu64"\n"), sectorsize);
+			fprintf(stderr, _("illegal sector size %"PRIu64"\n"),
+				get_conf_val(OPT_D, D_SECTSIZE));
 		else
 			fprintf(stderr,
 _("block size %"PRIu64" cannot be smaller than logical sector size %d\n"),
-				blocksize, ft.lsectorsize);
+				get_conf_val(OPT_B, B_SIZE), ft.lsectorsize);
 		usage();
 	}
-	if (sectorsize < ft.lsectorsize) {
+	if (get_conf_val(OPT_D, D_SECTSIZE) < ft.lsectorsize) {
 		fprintf(stderr, _("illegal sector size %"PRIu64"; hw sector is %d\n"),
-			sectorsize, ft.lsectorsize);
+			get_conf_val(OPT_D, D_SECTSIZE), ft.lsectorsize);
 		usage();
 	}
 	if (lsectorsize < XFS_MIN_SECTORSIZE ||
-	    lsectorsize > XFS_MAX_SECTORSIZE || lsectorsize > blocksize) {
+	    lsectorsize > XFS_MAX_SECTORSIZE ||
+	    lsectorsize > get_conf_val(OPT_B, B_SIZE)) {
 		fprintf(stderr, _("illegal log sector size %"PRIu64"\n"), lsectorsize);
 		usage();
 	} else if (lsectorsize > XFS_MIN_SECTORSIZE && !lsu && !lsunit) {
-		lsu = blocksize;
+		lsu = get_conf_val(OPT_B, B_SIZE);
 		sb_feat.log_version = 2;
 	}
 
@@ -2342,37 +2380,41 @@ _("rmapbt not supported with realtime devices\n"));
 	}
 
 	if (nsflag || nlflag) {
-		if (dirblocksize < blocksize ||
+		if (dirblocksize < get_conf_val(OPT_B, B_SIZE) ||
 					dirblocksize > XFS_MAX_BLOCKSIZE) {
 			fprintf(stderr, _("illegal directory block size %"PRIu64"\n"),
 				dirblocksize);
 			usage();
 		}
 	} else {
-		if (blocksize < (1 << XFS_MIN_REC_DIRSIZE))
+		if (get_conf_val(OPT_B, B_SIZE) < (1 << XFS_MIN_REC_DIRSIZE))
 			dirblocklog = XFS_MIN_REC_DIRSIZE;
 		else
-			dirblocklog = blocklog;
+			dirblocklog = get_conf_val(OPT_B, B_LOG);
 		dirblocksize = 1 << dirblocklog;
 	}
 
 
-	if (dbytes) {
-		if (dbytes % XFS_MIN_BLOCKSIZE) {
+	if (get_conf_val(OPT_D, D_SIZE)) {
+		if (get_conf_val(OPT_D, D_SIZE) % XFS_MIN_BLOCKSIZE) {
 			fprintf(stderr,
 			_("illegal data length %"PRIu64", not a multiple of %d\n"),
-				dbytes, XFS_MIN_BLOCKSIZE);
+				get_conf_val(OPT_D, D_SIZE), XFS_MIN_BLOCKSIZE);
 			usage();
 		}
-		dblocks = (xfs_rfsblock_t)(dbytes >> blocklog);
-		if (dbytes % blocksize)
+		dblocks = (xfs_rfsblock_t)(get_conf_val(OPT_D, D_SIZE) >>
+					   get_conf_val(OPT_B, B_LOG));
+		if (get_conf_val(OPT_D, D_SIZE) % get_conf_val(OPT_B, B_SIZE))
 			fprintf(stderr, _("warning: "
 	"data length %"PRIu64" not a multiple of %"PRIu64", truncated to %"PRIu64"\n"),
-				dbytes, blocksize,
-				(uint64_t)(dblocks << blocklog));
+				get_conf_val(OPT_D, D_SIZE),
+				get_conf_val(OPT_B, B_SIZE),
+				(uint64_t)(dblocks <<
+					   get_conf_val(OPT_B, B_LOG)));
 	}
 	if (ipflag) {
-		inodelog = blocklog - libxfs_highbit32(inopblock);
+		inodelog = get_conf_val(OPT_B, B_LOG) -
+			libxfs_highbit32(inopblock);
 		isize = 1 << inodelog;
 	} else if (!ilflag && !isflag) {
 		inodelog = sb_feat.crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
@@ -2393,12 +2435,14 @@ _("rmapbt not supported with realtime devices\n"));
 				logbytes, XFS_MIN_BLOCKSIZE);
 			usage();
 		}
-		logblocks = (xfs_rfsblock_t)(logbytes >> blocklog);
-		if (logbytes % blocksize)
+		logblocks = (xfs_rfsblock_t)(logbytes >>
+					     get_conf_val(OPT_B, B_LOG));
+		if (logbytes % get_conf_val(OPT_B, B_SIZE))
 			fprintf(stderr,
 	_("warning: log length %"PRIu64" not a multiple of %"PRIu64", truncated to %"PRIu64"\n"),
-				logbytes, blocksize,
-				(uint64_t)(logblocks << blocklog));
+				logbytes, get_conf_val(OPT_B, B_SIZE),
+				(uint64_t)(logblocks <<
+					   get_conf_val(OPT_B, B_LOG)));
 	}
 	if (rtbytes) {
 		if (rtbytes % XFS_MIN_BLOCKSIZE) {
@@ -2407,24 +2451,27 @@ _("rmapbt not supported with realtime devices\n"));
 				rtbytes, XFS_MIN_BLOCKSIZE);
 			usage();
 		}
-		rtblocks = (xfs_rfsblock_t)(rtbytes >> blocklog);
-		if (rtbytes % blocksize)
+		rtblocks = (xfs_rfsblock_t)(rtbytes >>
+					    get_conf_val(OPT_B, B_LOG));
+		if (rtbytes % get_conf_val(OPT_B, B_SIZE))
 			fprintf(stderr,
 	_("warning: rt length %"PRIu64" not a multiple of %"PRIu64", truncated to %"PRIu64"\n"),
-				rtbytes, blocksize,
-				(uint64_t)(rtblocks << blocklog));
+				rtbytes, get_conf_val(OPT_B, B_SIZE),
+				(uint64_t)(rtblocks <<
+					   get_conf_val(OPT_B, B_LOG)));
 	}
 	/*
 	 * If specified, check rt extent size against its constraints.
 	 */
 	if (rtextbytes) {
-		if (rtextbytes % blocksize) {
+		if (rtextbytes % get_conf_val(OPT_B, B_SIZE)) {
 			fprintf(stderr,
 		_("illegal rt extent size %"PRIu64", not a multiple of %"PRIu64"\n"),
-				rtextbytes, blocksize);
+				rtextbytes, get_conf_val(OPT_B, B_SIZE));
 			usage();
 		}
-		rtextblocks = (xfs_extlen_t)(rtextbytes >> blocklog);
+		rtextblocks = (xfs_extlen_t)(rtextbytes >>
+					     get_conf_val(OPT_B, B_LOG));
 	} else {
 		/*
 		 * If realtime extsize has not been specified by the user,
@@ -2439,18 +2486,21 @@ _("rmapbt not supported with realtime devices\n"));
 		else
 			rswidth = 0;
 
-		/* check that rswidth is a multiple of fs blocksize */
-		if (!norsflag && rswidth && !(BBTOB(rswidth) % blocksize)) {
+		/* check that rswidth is a multiple of fs B_SIZE */
+		if (!norsflag && rswidth &&
+		    !(BBTOB(rswidth) % get_conf_val(OPT_B, B_SIZE))) {
 			rswidth = DTOBT(rswidth);
-			rtextbytes = rswidth << blocklog;
+			rtextbytes = rswidth << get_conf_val(OPT_B, B_LOG);
 			if (XFS_MIN_RTEXTSIZE <= rtextbytes &&
 			    (rtextbytes <= XFS_MAX_RTEXTSIZE)) {
 				rtextblocks = rswidth;
 			}
 		}
 		if (!rtextblocks) {
-			rtextblocks = (blocksize < XFS_MIN_RTEXTSIZE) ?
-					XFS_MIN_RTEXTSIZE >> blocklog : 1;
+			rtextblocks = (get_conf_val(OPT_B, B_SIZE) <
+				       XFS_MIN_RTEXTSIZE) ?
+				       XFS_MIN_RTEXTSIZE >>
+				       get_conf_val(OPT_B, B_LOG) : 1;
 		}
 	}
 	ASSERT(rtextblocks);
@@ -2458,22 +2508,25 @@ _("rmapbt not supported with realtime devices\n"));
 	/*
 	 * Check some argument sizes against mins, maxes.
 	 */
-	if (isize > blocksize / XFS_MIN_INODE_PERBLOCK ||
+	if (isize > get_conf_val(OPT_B, B_SIZE) / XFS_MIN_INODE_PERBLOCK ||
 	    isize < XFS_DINODE_MIN_SIZE ||
 	    isize > XFS_DINODE_MAX_SIZE) {
 		int	maxsz;
 
 		fprintf(stderr, _("illegal inode size %"PRIu64"\n"), isize);
-		maxsz = MIN(blocksize / XFS_MIN_INODE_PERBLOCK,
+		maxsz = MIN(get_conf_val(OPT_B, B_SIZE) /
+			    XFS_MIN_INODE_PERBLOCK,
 			    XFS_DINODE_MAX_SIZE);
 		if (XFS_DINODE_MIN_SIZE == maxsz)
 			fprintf(stderr,
 			_("allowable inode size with %"PRIu64" byte blocks is %d\n"),
-				blocksize, XFS_DINODE_MIN_SIZE);
+				get_conf_val(OPT_B, B_SIZE),
+				XFS_DINODE_MIN_SIZE);
 		else
 			fprintf(stderr,
 	_("allowable inode size with %"PRIu64" byte blocks is between %d and %d\n"),
-				blocksize, XFS_DINODE_MIN_SIZE, maxsz);
+				get_conf_val(OPT_B, B_SIZE),
+				XFS_DINODE_MIN_SIZE, maxsz);
 		exit(1);
 	}
 
@@ -2484,10 +2537,20 @@ _("rmapbt not supported with realtime devices\n"));
 		sb_feat.log_version = 2;
 	}
 
-	calc_stripe_factors(dsu, dsw, sectorsize, lsu, lsectorsize,
+	uint64_t dsunit = get_conf_val(OPT_D, D_SUNIT);
+	uint64_t dswidth = get_conf_val(OPT_D, D_SWIDTH);
+
+	calc_stripe_factors(get_conf_val(OPT_D, D_SU),
+			    get_conf_val(OPT_D, D_SW),
+			    get_conf_val(OPT_D, D_SECTSIZE),
+			    lsu,
+			    lsectorsize,
 				&dsunit, &dswidth, &lsunit);
 
-	xi.setblksize = sectorsize;
+	set_conf_val(OPT_D, D_SUNIT, dsunit);
+	set_conf_val(OPT_D, D_SWIDTH, dswidth);
+
+	xi.setblksize = get_conf_val(OPT_D, D_SECTSIZE);
 
 	/*
 	 * Initialize.  This will open the log and rt devices as well.
@@ -2510,7 +2573,8 @@ _("rmapbt not supported with realtime devices\n"));
 	 * multiple of the sector size, or 1024, whichever is larger.
 	 */
 
-	sector_mask = (uint64_t)-1 << (MAX(sectorlog, 10) - BBSHIFT);
+	sector_mask = (uint64_t)-1 <<
+		(MAX(get_conf_val(OPT_D, D_SECTLOG), 10) - BBSHIFT);
 	xi.dsize &= sector_mask;
 	xi.rtsize &= sector_mask;
 	xi.logBBsize &= (uint64_t)-1 << (MAX(lsectorlog, 10) - BBSHIFT);
@@ -2545,16 +2609,17 @@ _("rmapbt not supported with realtime devices\n"));
 		rtfile = _("volume rt");
 	else if (!xi.rtdev)
 		rtfile = _("none");
-	if (dbytes && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
+	if (get_conf_val(OPT_D, D_SIZE) &&
+	    xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
 		fprintf(stderr,
 			_("size %s specified for data subvolume is too large, "
 			"maximum is %"PRIu64" blocks\n"),
 			get_conf_raw(OPT_D, D_SIZE),
 			(uint64_t)DTOBT(xi.dsize));
 		usage();
-	} else if (!dbytes && xi.dsize > 0)
+	} else if (!get_conf_val(OPT_D, D_SIZE) && xi.dsize > 0)
 		dblocks = DTOBT(xi.dsize);
-	else if (!dbytes) {
+	else if (!get_conf_val(OPT_D, D_SIZE)) {
 		fprintf(stderr, _("can't get size of data subvolume\n"));
 		usage();
 	}
@@ -2569,17 +2634,18 @@ _("rmapbt not supported with realtime devices\n"));
 		fprintf(stderr,
 			_("can't have both external and internal logs\n"));
 		usage();
-	} else if (loginternal && sectorsize != lsectorsize) {
+	} else if (loginternal &&
+		   get_conf_val(OPT_D, D_SECTSIZE) != lsectorsize) {
 		fprintf(stderr,
 	_("data and log sector sizes must be equal for internal logs\n"));
 		usage();
 	}
 
-	if (xi.dbsize > sectorsize) {
+	if (xi.dbsize > get_conf_val(OPT_D, D_SECTSIZE)) {
 		fprintf(stderr, _(
 "Warning: the data subvolume sector size %"PRIu64" is less than the sector size \n\
 reported by the device (%u).\n"),
-			sectorsize, xi.dbsize);
+			get_conf_val(OPT_D, D_SECTSIZE), xi.dbsize);
 	}
 	if (!loginternal && xi.lbsize > lsectorsize) {
 		fprintf(stderr, _(
@@ -2587,11 +2653,12 @@ reported by the device (%u).\n"),
 reported by the device (%u).\n"),
 			lsectorsize, xi.lbsize);
 	}
-	if (rtbytes && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
+	if (rtbytes && xi.rtsize > 0 &&
+	    xi.rtbsize > get_conf_val(OPT_D, D_SECTSIZE)) {
 		fprintf(stderr, _(
 "Warning: the realtime subvolume sector size %"PRIu64" is less than the sector size\n\
 reported by the device (%u).\n"),
-			sectorsize, xi.rtbsize);
+			get_conf_val(OPT_D, D_SECTSIZE), xi.rtbsize);
 	}
 
 	if (rtbytes && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
@@ -2610,119 +2677,173 @@ reported by the device (%u).\n"),
 	}
 	if (xi.rtdev) {
 		rtextents = rtblocks / rtextblocks;
-		nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY * blocksize);
+		nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY *
+						  get_conf_val(OPT_B, B_SIZE));
 	} else {
 		rtextents = rtblocks = 0;
 		nbmblocks = 0;
 	}
 
-	if (!nodsflag) {
-		if (dsunit) {
-			if (ft.dsunit && ft.dsunit != dsunit) {
+	if (!get_conf_val(OPT_D, D_NOALIGN)) {
+		if (get_conf_val(OPT_D, D_SUNIT)) {
+			if (ft.dsunit &&
+			    ft.dsunit != get_conf_val(OPT_D, D_SUNIT)) {
 				fprintf(stderr,
 					_("%s: Specified data stripe unit %"PRIu64" "
 					"is not the same as the volume stripe "
 					"unit %d\n"),
-					progname, dsunit, ft.dsunit);
+					progname,
+					get_conf_val(OPT_D, D_SUNIT),
+					ft.dsunit);
 			}
-			if (ft.dswidth && ft.dswidth != dswidth) {
+			if (ft.dswidth &&
+			    ft.dswidth != get_conf_val(OPT_D, D_SWIDTH)) {
 				fprintf(stderr,
 					_("%s: Specified data stripe width %"PRIu64" "
 					"is not the same as the volume stripe "
 					"width %d\n"),
-					progname, dswidth, ft.dswidth);
+					progname,
+					get_conf_val(OPT_D, D_SWIDTH),
+					ft.dswidth);
 			}
 		} else {
-			dsunit = ft.dsunit;
-			dswidth = ft.dswidth;
-			nodsflag = 1;
+			set_conf_val(OPT_D, D_SUNIT, ft.dsunit);
+			set_conf_val(OPT_D, D_SWIDTH, ft.dswidth);
+			set_conf_val(OPT_D, D_NOALIGN, 1);
 		}
-	} /* else dsunit & dswidth can't be set if nodsflag is set */
+	} /* else D_SUNIT & D_SWIDTH can't be set if D_NOALIGN is set */
 
 	if (dasize) {		/* User-specified AG size */
 		/*
-		 * Check specified agsize is a multiple of blocksize.
+		 * Check specified D_AGSIZE is a multiple of B_SIZE.
 		 */
-		if (agsize % blocksize) {
+		if (get_conf_val(OPT_D, D_AGSIZE) %
+		    get_conf_val(OPT_B, B_SIZE)) {
 			fprintf(stderr,
 		_("agsize (%"PRIu64") not a multiple of fs blk size (%"PRIu64")\n"),
-				agsize, blocksize);
+				get_conf_val(OPT_D, D_AGSIZE),
+				get_conf_val(OPT_B, B_SIZE));
 			usage();
 		}
-		agsize /= blocksize;
-		agcount = dblocks / agsize + (dblocks % agsize != 0);
+		set_conf_val(OPT_D, D_AGSIZE,
+			     get_conf_val(OPT_D, D_AGSIZE) /
+			     get_conf_val(OPT_B, B_SIZE));
+		set_conf_val(OPT_D, D_AGCOUNT,
+			     dblocks / get_conf_val(OPT_D, D_AGSIZE) +
+			     (dblocks % get_conf_val(OPT_D, D_AGSIZE) != 0));
 
 	} else if (daflag) {	/* User-specified AG count */
-		agsize = dblocks / agcount + (dblocks % agcount != 0);
+		set_conf_val(OPT_D, D_AGSIZE,
+			     dblocks / get_conf_val(OPT_D, D_AGCOUNT) +
+			     (dblocks % get_conf_val(OPT_D, D_AGCOUNT) != 0));
 	} else {
-		calc_default_ag_geometry(blocklog, dblocks,
-				dsunit | dswidth, &agsize, &agcount);
+		uint64_t agcount = get_conf_val(OPT_D, D_AGCOUNT);
+		uint64_t agsize = get_conf_val(OPT_D, D_AGSIZE);
+
+		calc_default_ag_geometry(get_conf_val(OPT_B, B_LOG),
+					 dblocks, get_conf_val(OPT_D, D_SUNIT)
+					 | get_conf_val(OPT_D, D_SWIDTH),
+					 &agsize, &agcount);
+		set_conf_val(OPT_D, D_AGCOUNT, agcount);
+		set_conf_val(OPT_D, D_AGSIZE, agsize);
 	}
 
 	/*
-	 * If dsunit is a multiple of fs blocksize, then check that is a
-	 * multiple of the agsize too
+	 * If D_SUNIT is a multiple of fs B_SIZE,
+	 * then check that is a multiple of the D_AGSIZE too
 	 */
-	if (dsunit && !(BBTOB(dsunit) % blocksize) &&
-	    dswidth && !(BBTOB(dswidth) % blocksize)) {
-
-		/* convert from 512 byte blocks to fs blocksize */
-		dsunit = DTOBT(dsunit);
-		dswidth = DTOBT(dswidth);
+	if (get_conf_val(OPT_D, D_SUNIT) &&
+	    !(BBTOB(get_conf_val(OPT_D, D_SUNIT)) %
+	      get_conf_val(OPT_B, B_SIZE)) &&
+	    get_conf_val(OPT_D, D_SWIDTH) &&
+	    !(BBTOB(get_conf_val(OPT_D, D_SWIDTH)) %
+	      get_conf_val(OPT_B, B_SIZE))) {
+
+		/* convert from 512 byte blocks to fs B_SIZE
+		 */
+		set_conf_val(OPT_D, D_SUNIT,
+			     DTOBT(get_conf_val(OPT_D, D_SUNIT)));
+		set_conf_val(OPT_D, D_SWIDTH,
+			     DTOBT(get_conf_val(OPT_D, D_SWIDTH)));
 
 		/*
-		 * agsize is not a multiple of dsunit
+		 * D_AGSIZE is not a multiple of D_SUNIT
 		 */
-		if ((agsize % dsunit) != 0) {
+		if ((get_conf_val(OPT_D, D_AGSIZE) %
+		     get_conf_val(OPT_D, D_SUNIT)) != 0) {
 			/*
 			 * Round up to stripe unit boundary. Also make sure
-			 * that agsize is still larger than
-			 * XFS_AG_MIN_BLOCKS(blocklog)
+			 * that D_AGSIZE is still larger than
+			 * XFS_AG_MIN_BLOCKS(get_conf_val(OPT_B, B_LOG))
 		 	 */
-			tmp_agsize = ((agsize + (dsunit - 1))/ dsunit) * dsunit;
+			tmp_agsize = ((get_conf_val(OPT_D, D_AGSIZE) +
+				       (get_conf_val(OPT_D, D_SUNIT) - 1)) /
+				      get_conf_val(OPT_D, D_SUNIT)) *
+				get_conf_val(OPT_D, D_SUNIT);
 			/*
 			 * Round down to stripe unit boundary if rounding up
 			 * created an AG size that is larger than the AG max.
 			 */
-			if (tmp_agsize > XFS_AG_MAX_BLOCKS(blocklog))
-				tmp_agsize = ((agsize) / dsunit) * dsunit;
-
-			if ((tmp_agsize >= XFS_AG_MIN_BLOCKS(blocklog)) &&
-			    (tmp_agsize <= XFS_AG_MAX_BLOCKS(blocklog))) {
-				agsize = tmp_agsize;
+			if (tmp_agsize >
+			    XFS_AG_MAX_BLOCKS(get_conf_val(OPT_B, B_LOG)))
+				tmp_agsize = ((get_conf_val(OPT_D, D_AGSIZE)) /
+					      get_conf_val(OPT_D, D_SUNIT)) *
+					get_conf_val(OPT_D, D_SUNIT);
+
+			if ((tmp_agsize >=
+			     XFS_AG_MIN_BLOCKS(get_conf_val(OPT_B, B_LOG))) &&
+			    (tmp_agsize <=
+			     XFS_AG_MAX_BLOCKS(get_conf_val(OPT_B, B_LOG)))) {
+				set_conf_val(OPT_D, D_AGSIZE, tmp_agsize);
 				if (!daflag)
-					agcount = dblocks/agsize +
-						(dblocks % agsize != 0);
+					set_conf_val(OPT_D, D_AGCOUNT,
+						dblocks /
+						get_conf_val(OPT_D, D_AGSIZE) +
+						(dblocks %
+						 get_conf_val(OPT_D, D_AGSIZE)
+						!= 0));
 				if (dasize)
 					fprintf(stderr,
 				_("agsize rounded to %"PRIu64", swidth = %"PRIu64"\n"),
-						agsize, dswidth);
+						get_conf_val(OPT_D, D_AGSIZE),
+						get_conf_val(OPT_D, D_SWIDTH));
 			} else {
-				if (nodsflag) {
-					dsunit = dswidth = 0;
+				if (get_conf_val(OPT_D, D_NOALIGN)) {
+					set_conf_val(OPT_D, D_SUNIT, 0);
+					set_conf_val(OPT_D, D_SWIDTH, 0);
 				} else {
 					/*
-					 * agsize is out of bounds, this will
+					 * D_AGSIZE is out of bounds, this will
 					 * print nice details & exit.
 					 */
-					validate_ag_geometry(blocklog, dblocks,
-							    agsize, agcount);
+					validate_ag_geometry(
+						get_conf_val(OPT_B, B_LOG),
+						dblocks,
+						get_conf_val(OPT_D, D_AGSIZE),
+						get_conf_val(OPT_D, D_AGCOUNT));
 					exit(1);
 				}
 			}
 		}
-		if (dswidth && ((agsize % dswidth) == 0) && (agcount > 1)) {
+		if (get_conf_val(OPT_D, D_SWIDTH) &&
+		    ((get_conf_val(OPT_D, D_AGSIZE) %
+		      get_conf_val(OPT_D, D_SWIDTH)) == 0) &&
+		    (get_conf_val(OPT_D, D_AGCOUNT) > 1)) {
 			/* This is a non-optimal configuration because all AGs
 			 * start on the same disk in the stripe.  Changing
 			 * the AG size by one sunit will guarantee that this
 			 * does not happen.
 			 */
-			tmp_agsize = agsize - dsunit;
-			if (tmp_agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
-				tmp_agsize = agsize + dsunit;
-				if (dblocks < agsize) {
+			tmp_agsize = get_conf_val(OPT_D, D_AGSIZE) -
+				get_conf_val(OPT_D, D_SUNIT);
+			if (tmp_agsize <
+			    XFS_AG_MIN_BLOCKS(get_conf_val(OPT_B, B_LOG))) {
+				tmp_agsize = get_conf_val(OPT_D, D_AGSIZE) +
+					get_conf_val(OPT_D, D_SUNIT);
+				if (dblocks < get_conf_val(OPT_D, D_AGSIZE)) {
 					/* oh well, nothing to do */
-					tmp_agsize = agsize;
+					tmp_agsize =
+						get_conf_val(OPT_D, D_AGSIZE);
 				}
 			}
 			if (daflag || dasize) {
@@ -2732,30 +2853,46 @@ problems by aligning all AGs on the same disk.  To avoid this, run mkfs with\n\
 an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
 					tmp_agsize);
 			} else {
-				agsize = tmp_agsize;
-				agcount = dblocks/agsize + (dblocks % agsize != 0);
+				set_conf_val(OPT_D, D_AGSIZE, tmp_agsize);
+				set_conf_val(OPT_D, D_AGCOUNT,
+					dblocks/get_conf_val(OPT_D, D_AGSIZE) +
+					     (dblocks %
+					      get_conf_val(OPT_D, D_AGSIZE)
+					      != 0));
 				/*
 				 * If the last AG is too small, reduce the
 				 * filesystem size and drop the blocks.
 				 */
-				if ( dblocks % agsize != 0 &&
-				    (dblocks % agsize <
-				    XFS_AG_MIN_BLOCKS(blocklog))) {
-					dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
-					agcount--;
-					ASSERT(agcount != 0);
+				if (dblocks % get_conf_val(OPT_D, D_AGSIZE)
+				    != 0 &&
+				    (dblocks % get_conf_val(OPT_D, D_AGSIZE) <
+				    XFS_AG_MIN_BLOCKS(
+					get_conf_val(OPT_B, B_LOG)))) {
+
+					dblocks = (xfs_rfsblock_t)(
+						(get_conf_val(OPT_D, D_AGCOUNT)
+						 - 1) *
+						get_conf_val(OPT_D, D_AGSIZE));
+					set_conf_val(OPT_D, D_AGCOUNT,
+						get_conf_val(OPT_D, D_AGCOUNT)
+						- 1);
+					ASSERT(get_conf_val(OPT_D, D_AGCOUNT)
+					       != 0);
 				}
 			}
 		}
 	} else {
-		if (nodsflag)
-			dsunit = dswidth = 0;
-		else {
+		if (get_conf_val(OPT_D, D_NOALIGN)) {
+			set_conf_val(OPT_D, D_SWIDTH, 0);
+			set_conf_val(OPT_D, D_SUNIT, 0);
+		} else {
 			fprintf(stderr,
 				_("%s: Stripe unit(%"PRIu64") or stripe width(%"PRIu64") is "
 				"not a multiple of the block size(%"PRIu64")\n"),
-				progname, BBTOB(dsunit), BBTOB(dswidth),
-				blocksize);
+				progname,
+				BBTOB(get_conf_val(OPT_D, D_SUNIT)),
+				BBTOB(get_conf_val(OPT_D, D_SWIDTH)),
+				get_conf_val(OPT_B, B_SIZE));
 			exit(1);
 		}
 	}
@@ -2764,52 +2901,68 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
 	 * If the last AG is too small, reduce the filesystem size
 	 * and drop the blocks.
 	 */
-	if ( dblocks % agsize != 0 &&
-	     (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
+	if (dblocks % get_conf_val(OPT_D, D_AGSIZE) != 0 &&
+	     (dblocks % get_conf_val(OPT_D, D_AGSIZE) <
+	      XFS_AG_MIN_BLOCKS(get_conf_val(OPT_B, B_LOG)))) {
 		ASSERT(!daflag);
-		dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
-		agcount--;
-		ASSERT(agcount != 0);
+		dblocks = (xfs_rfsblock_t)(
+				(get_conf_val(OPT_D, D_AGCOUNT) - 1) *
+				get_conf_val(OPT_D, D_AGSIZE));
+		set_conf_val(OPT_D, D_AGCOUNT,
+			     get_conf_val(OPT_D, D_AGCOUNT) - 1);
+		ASSERT(get_conf_val(OPT_D, D_AGCOUNT) != 0);
 	}
 
-	validate_ag_geometry(blocklog, dblocks, agsize, agcount);
+	validate_ag_geometry(get_conf_val(OPT_B, B_LOG),
+			     dblocks,
+			     get_conf_val(OPT_D, D_AGSIZE),
+			     get_conf_val(OPT_D, D_AGCOUNT));
 
 	if (!imflag)
-		imaxpct = calc_default_imaxpct(blocklog, dblocks);
+		imaxpct = calc_default_imaxpct(get_conf_val(OPT_B, B_LOG),
+					       dblocks);
 
 	/*
-	 * check that log sunit is modulo fsblksize or default it to dsunit.
+	 * check that log sunit is modulo fsblksize or default it to D_SUNIT.
 	 */
 
 	if (lsunit) {
 		/* convert from 512 byte blocks to fs blocks */
 		lsunit = DTOBT(lsunit);
-	} else if (sb_feat.log_version == 2 && loginternal && dsunit) {
-		/* lsunit and dsunit now in fs blocks */
-		lsunit = dsunit;
+	} else if (sb_feat.log_version == 2 &&
+		   loginternal &&
+		   get_conf_val(OPT_D, D_SUNIT)) {
+		/* lsunit and get_conf_val(OPT_D, D_SUNIT) now in fs blocks */
+		lsunit = get_conf_val(OPT_D, D_SUNIT);
 	}
 
-	if (sb_feat.log_version == 2 && (lsunit * blocksize) > 256 * 1024) {
+	if (sb_feat.log_version == 2 &&
+	    (lsunit * get_conf_val(OPT_B, B_SIZE)) > 256 * 1024) {
 		/* Warn only if specified on commandline */
 		if (lsuflag || lsunitflag) {
 			fprintf(stderr,
 	_("log stripe unit (%"PRIu64" bytes) is too large (maximum is 256KiB)\n"),
-				(lsunit * blocksize));
+				(lsunit * get_conf_val(OPT_B, B_SIZE)));
 			fprintf(stderr,
 	_("log stripe unit adjusted to 32KiB\n"));
 		}
-		lsunit = (32 * 1024) >> blocklog;
+		lsunit = (32 * 1024) >> get_conf_val(OPT_B, B_LOG);
 	}
 
-	min_logblocks = max_trans_res(agsize,
+	min_logblocks = max_trans_res(get_conf_val(OPT_D, D_AGSIZE),
 				   sb_feat.crcs_enabled, sb_feat.dir_version,
-				   sectorlog, blocklog, inodelog, dirblocklog,
+				   get_conf_val(OPT_D, D_SECTLOG),
+				   get_conf_val(OPT_B, B_LOG),
+				   inodelog, dirblocklog,
 				   sb_feat.log_version, lsunit, sb_feat.finobt,
 				   sb_feat.rmapbt, sb_feat.reflink);
 	ASSERT(min_logblocks);
 	min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
-	if (!logbytes && dblocks >= (1024*1024*1024) >> blocklog)
-		min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
+	if (!logbytes &&
+	    dblocks >= (1024*1024*1024) >> get_conf_val(OPT_B, B_LOG))
+		min_logblocks = MAX(min_logblocks,
+				    XFS_MIN_LOG_BYTES >>
+				    get_conf_val(OPT_B, B_LOG));
 	if (logbytes && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
 		fprintf(stderr,
 _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks\n"),
@@ -2830,17 +2983,19 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		logblocks = 0;
 	} else if (loginternal && !logbytes) {
 
-		if (dblocks < GIGABYTES(1, blocklog)) {
+		if (dblocks < GIGABYTES(1, get_conf_val(OPT_B, B_LOG))) {
 			/* tiny filesystems get minimum sized logs. */
 			logblocks = min_logblocks;
-		} else if (dblocks < GIGABYTES(16, blocklog)) {
+		} else if (dblocks <
+			   GIGABYTES(16, get_conf_val(OPT_B, B_LOG))) {
 
 			/*
 			 * For small filesystems, we want to use the
 			 * XFS_MIN_LOG_BYTES for filesystems smaller than 16G if
 			 * at all possible, ramping up to 128MB at 256GB.
 			 */
-			logblocks = MIN(XFS_MIN_LOG_BYTES >> blocklog,
+			logblocks = MIN(XFS_MIN_LOG_BYTES >>
+					get_conf_val(OPT_B, B_LOG),
 					min_logblocks * XFS_DFL_LOG_FACTOR);
 		} else {
 			/*
@@ -2849,34 +3004,38 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 			 * max log size of 128M at 256GB fs size. IOWs,
 			 * the ratio of fs size to log size is 2048:1.
 			 */
-			logblocks = (dblocks << blocklog) / 2048;
-			logblocks = logblocks >> blocklog;
+			logblocks = (dblocks <<
+				     get_conf_val(OPT_B, B_LOG)) / 2048;
+			logblocks = logblocks >> get_conf_val(OPT_B, B_LOG);
 		}
 
 		/* Ensure the chosen size meets minimum log size requirements */
 		logblocks = MAX(min_logblocks, logblocks);
 
 		/* make sure the log fits wholly within an AG */
-		if (logblocks >= agsize)
+		if (logblocks >= get_conf_val(OPT_D, D_AGSIZE))
 			logblocks = min_logblocks;
 
 		/* and now clamp the size to the maximum supported size */
 		logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS);
-		if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES)
-			logblocks = XFS_MAX_LOG_BYTES >> blocklog;
+		if ((logblocks << get_conf_val(OPT_B, B_LOG)) >
+		    XFS_MAX_LOG_BYTES)
+			logblocks = XFS_MAX_LOG_BYTES >>
+				get_conf_val(OPT_B, B_LOG);
 
 	}
-	validate_log_size(logblocks, blocklog, min_logblocks);
+	validate_log_size(logblocks, get_conf_val(OPT_B, B_LOG), min_logblocks);
 
 	protostring = setup_proto(protofile);
-	bsize = 1 << (blocklog - BBSHIFT);
+	bsize = 1 << (get_conf_val(OPT_B, B_LOG) - BBSHIFT);
 	mp = &mbuf;
 	sbp = &mp->m_sb;
 	memset(mp, 0, sizeof(xfs_mount_t));
-	sbp->sb_blocklog = (__uint8_t)blocklog;
-	sbp->sb_sectlog = (__uint8_t)sectorlog;
-	sbp->sb_agblklog = (__uint8_t)libxfs_log2_roundup((unsigned int)agsize);
-	sbp->sb_agblocks = (xfs_agblock_t)agsize;
+	sbp->sb_blocklog = (__uint8_t)get_conf_val(OPT_B, B_LOG);
+	sbp->sb_sectlog = (__uint8_t)get_conf_val(OPT_D, D_SECTLOG);
+	sbp->sb_agblklog = (__uint8_t)libxfs_log2_roundup(
+				(unsigned int)get_conf_val(OPT_D, D_AGSIZE));
+	sbp->sb_agblocks = (xfs_agblock_t)get_conf_val(OPT_D, D_AGSIZE);
 	mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
 	mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
 
@@ -2884,7 +3043,10 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	 * sb_versionnum, finobt and rmapbt flags must be set before we use
 	 * libxfs_prealloc_blocks().
 	 */
-	sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
+	sb_set_features(&mp->m_sb, &sb_feat,
+			get_conf_val(OPT_D, D_SECTSIZE),
+			lsectorsize,
+			get_conf_val(OPT_D, D_SUNIT));
 
 
 	if (loginternal) {
@@ -2897,9 +3059,12 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 					libxfs_alloc_ag_max_usable(mp));
 
 			/* revalidate the log size is valid if we changed it */
-			validate_log_size(logblocks, blocklog, min_logblocks);
+			validate_log_size(logblocks,
+					  get_conf_val(OPT_B, B_LOG),
+					  min_logblocks);
 		}
-		if (logblocks > agsize - libxfs_prealloc_blocks(mp)) {
+		if (logblocks > get_conf_val(OPT_D, D_AGSIZE) -
+		    libxfs_prealloc_blocks(mp)) {
 			fprintf(stderr,
 	_("internal log size %"PRIu64" too large, must fit in allocation group\n"),
 				logblocks);
@@ -2907,14 +3072,16 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		}
 
 		if (laflag) {
-			if (logagno >= agcount) {
+			if (logagno >= get_conf_val(OPT_D, D_AGCOUNT)) {
 				fprintf(stderr,
 		_("log ag number %d too large, must be less than %"PRIu64"\n"),
-					logagno, agcount);
+					logagno,
+					get_conf_val(OPT_D, D_AGCOUNT));
 				usage();
 			}
 		} else
-			logagno = (xfs_agnumber_t)(agcount / 2);
+			logagno = (xfs_agnumber_t)(
+					get_conf_val(OPT_D, D_AGCOUNT) / 2);
 
 		logstart = XFS_AGB_TO_FSB(mp, logagno, libxfs_prealloc_blocks(mp));
 		/*
@@ -2922,20 +3089,25 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		 */
 		if (lsunit) {
 			logstart = fixup_internal_log_stripe(mp,
-					lsflag, logstart, agsize, lsunit,
-					&logblocks, blocklog, &lalign);
-		} else if (dsunit) {
+					lsflag, logstart,
+					get_conf_val(OPT_D, D_AGSIZE), lsunit,
+					&logblocks,
+					get_conf_val(OPT_B, B_LOG), &lalign);
+		} else if (get_conf_val(OPT_D, D_SUNIT)) {
 			logstart = fixup_internal_log_stripe(mp,
-					lsflag, logstart, agsize, dsunit,
-					&logblocks, blocklog, &lalign);
+					lsflag, logstart,
+					get_conf_val(OPT_D, D_AGSIZE),
+					get_conf_val(OPT_D, D_SUNIT),
+					&logblocks,
+					get_conf_val(OPT_B, B_LOG), &lalign);
 		}
 	} else {
 		logstart = 0;
 		if (lsunit)
 			fixup_log_stripe_unit(lsflag, lsunit,
-					&logblocks, blocklog);
+					&logblocks, get_conf_val(OPT_B, B_LOG));
 	}
-	validate_log_size(logblocks, blocklog, min_logblocks);
+	validate_log_size(logblocks, get_conf_val(OPT_B, B_LOG), min_logblocks);
 
 	if (!qflag || Nflag) {
 		printf(_(
@@ -2948,19 +3120,22 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		   "log      =%-22s bsize=%-6d blocks=%"PRIu64", version=%d\n"
 		   "         =%-22s sectsz=%-5lu sunit=%"PRIu64" blks, lazy-count=%d\n"
 		   "realtime =%-22s extsz=%-6d blocks=%"PRIu64", rtextents=%"PRIu64"\n"),
-			dfile, isize, agcount, agsize,
-			"", sectorsize, sb_feat.attr_version,
+			dfile, isize, get_conf_val(OPT_D, D_AGCOUNT),
+			get_conf_val(OPT_D, D_AGSIZE),
+			"", get_conf_val(OPT_D, D_SECTSIZE),
+			sb_feat.attr_version,
 				    !sb_feat.projid16bit,
 			"", sb_feat.crcs_enabled, sb_feat.finobt, sb_feat.spinodes,
 			sb_feat.rmapbt, sb_feat.reflink,
-			"", blocksize, dblocks, imaxpct,
-			"", dsunit, dswidth,
+			"", get_conf_val(OPT_B, B_SIZE), dblocks, imaxpct,
+			"", get_conf_val(OPT_D, D_SUNIT),
+			get_conf_val(OPT_D, D_SWIDTH),
 			sb_feat.dir_version, dirblocksize, sb_feat.nci,
 				sb_feat.dirftype,
-			logfile, 1 << blocklog, logblocks,
+			logfile, 1 << get_conf_val(OPT_B, B_LOG), logblocks,
 			sb_feat.log_version, "", lsectorsize, lsunit,
 				sb_feat.lazy_sb_counters,
-			rtfile, rtextblocks << blocklog,
+			rtfile, rtextblocks << get_conf_val(OPT_B, B_LOG),
 			rtblocks, rtextents);
 		if (Nflag)
 			exit(0);
@@ -2969,7 +3144,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	if (label)
 		strncpy(sbp->sb_fname, label, sizeof(sbp->sb_fname));
 	sbp->sb_magicnum = XFS_SB_MAGIC;
-	sbp->sb_blocksize = blocksize;
+	sbp->sb_blocksize = get_conf_val(OPT_B, B_SIZE);
 	sbp->sb_dblocks = dblocks;
 	sbp->sb_rblocks = rtblocks;
 	sbp->sb_rextents = rtextents;
@@ -2979,15 +3154,15 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	sbp->sb_logstart = logstart;
 	sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO;
 	sbp->sb_rextsize = rtextblocks;
-	sbp->sb_agcount = (xfs_agnumber_t)agcount;
+	sbp->sb_agcount = (xfs_agnumber_t)get_conf_val(OPT_D, D_AGCOUNT);
 	sbp->sb_rbmblocks = nbmblocks;
 	sbp->sb_logblocks = (xfs_extlen_t)logblocks;
-	sbp->sb_sectsize = (__uint16_t)sectorsize;
+	sbp->sb_sectsize = (__uint16_t)get_conf_val(OPT_D, D_SECTSIZE);
 	sbp->sb_inodesize = (__uint16_t)isize;
-	sbp->sb_inopblock = (__uint16_t)(blocksize / isize);
-	sbp->sb_sectlog = (__uint8_t)sectorlog;
+	sbp->sb_inopblock = (__uint16_t)(get_conf_val(OPT_B, B_SIZE) / isize);
+	sbp->sb_sectlog = (__uint8_t)get_conf_val(OPT_D, D_SECTLOG);
 	sbp->sb_inodelog = (__uint8_t)inodelog;
-	sbp->sb_inopblog = (__uint8_t)(blocklog - inodelog);
+	sbp->sb_inopblog = (__uint8_t)(get_conf_val(OPT_B, B_LOG) - inodelog);
 	sbp->sb_rextslog =
 		(__uint8_t)(rtextents ?
 			libxfs_highbit32((unsigned int)rtextents) : 0);
@@ -2995,14 +3170,15 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	sbp->sb_imax_pct = imaxpct;
 	sbp->sb_icount = 0;
 	sbp->sb_ifree = 0;
-	sbp->sb_fdblocks = dblocks - agcount * libxfs_prealloc_blocks(mp) -
+	sbp->sb_fdblocks = dblocks -
+		get_conf_val(OPT_D, D_AGCOUNT) * libxfs_prealloc_blocks(mp) -
 		(loginternal ? logblocks : 0);
 	sbp->sb_frextents = 0;	/* will do a free later */
 	sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0;
 	sbp->sb_qflags = 0;
-	sbp->sb_unit = dsunit;
-	sbp->sb_width = dswidth;
-	sbp->sb_dirblklog = dirblocklog - blocklog;
+	sbp->sb_unit = get_conf_val(OPT_D, D_SUNIT);
+	sbp->sb_width = get_conf_val(OPT_D, D_SWIDTH);
+	sbp->sb_dirblklog = dirblocklog - get_conf_val(OPT_B, B_LOG);
 	if (sb_feat.log_version == 2) {	/* This is stored in bytes */
 		lsunit = (lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, lsunit);
 		sbp->sb_logsunit = lsunit;
@@ -3012,11 +3188,12 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		int	cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
 		if (sb_feat.crcs_enabled)
 			cluster_size *= isize / XFS_DINODE_MIN_SIZE;
-		sbp->sb_inoalignmt = cluster_size >> blocklog;
+		sbp->sb_inoalignmt = cluster_size >> get_conf_val(OPT_B, B_LOG);
 		sb_feat.inode_align = sbp->sb_inoalignmt != 0;
 	} else
 		sbp->sb_inoalignmt = 0;
-	if (lsectorsize != BBSIZE || sectorsize != BBSIZE) {
+	if (lsectorsize != BBSIZE ||
+	    get_conf_val(OPT_D, D_SECTSIZE) != BBSIZE) {
 		sbp->sb_logsectlog = (__uint8_t)lsectorlog;
 		sbp->sb_logsectsize = (__uint16_t)lsectorsize;
 	} else {
@@ -3024,7 +3201,10 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		sbp->sb_logsectsize = 0;
 	}
 
-	sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
+	sb_set_features(&mp->m_sb, &sb_feat,
+			get_conf_val(OPT_D, D_SECTSIZE),
+			lsectorsize,
+			get_conf_val(OPT_D, D_SUNIT));
 
 	if (force_overwrite)
 		zero_old_xfs_structures(&xi, sbp);
@@ -3044,7 +3224,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	/* OK, now write the superblock */
 	buf = libxfs_getbuf(mp->m_ddev_targp, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1));
 	buf->b_ops = &xfs_sb_buf_ops;
-	memset(XFS_BUF_PTR(buf), 0, sectorsize);
+	memset(XFS_BUF_PTR(buf), 0, get_conf_val(OPT_D, D_SECTSIZE));
 	libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
 	libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
 	libxfs_purgebuf(buf);
@@ -3054,8 +3234,10 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	 * if needed so that the reads for the end of the device in the mount
 	 * code will succeed.
 	 */
-	if (xi.disfile && xi.dsize * xi.dbsize < dblocks * blocksize) {
-		if (ftruncate(xi.dfd, dblocks * blocksize) < 0) {
+	if (xi.disfile &&
+	    xi.dsize * xi.dbsize < dblocks * get_conf_val(OPT_B, B_SIZE)) {
+		if (ftruncate(xi.dfd,
+			     dblocks * get_conf_val(OPT_B, B_SIZE)) < 0) {
 			fprintf(stderr,
 				_("%s: Growing the data section failed\n"),
 				progname);
@@ -3097,7 +3279,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	 * These initialisations should be pulled into libxfs to keep the
 	 * kernel/userspace header initialisation code the same.
 	 */
-	for (agno = 0; agno < agcount; agno++) {
+	for (agno = 0; agno < get_conf_val(OPT_D, D_AGCOUNT); agno++) {
 		struct xfs_agfl	*agfl;
 		int		bucket;
 		struct xfs_perag *pag = libxfs_perag_get(mp, agno);
@@ -3109,7 +3291,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 				XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
 				XFS_FSS_TO_BB(mp, 1));
 		buf->b_ops = &xfs_sb_buf_ops;
-		memset(XFS_BUF_PTR(buf), 0, sectorsize);
+		memset(XFS_BUF_PTR(buf), 0, get_conf_val(OPT_D, D_SECTSIZE));
 		libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
 		libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
 
@@ -3121,13 +3303,17 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 				XFS_FSS_TO_BB(mp, 1));
 		buf->b_ops = &xfs_agf_buf_ops;
 		agf = XFS_BUF_TO_AGF(buf);
-		memset(agf, 0, sectorsize);
-		if (agno == agcount - 1)
-			agsize = dblocks - (xfs_rfsblock_t)(agno * agsize);
+		memset(agf, 0, get_conf_val(OPT_D, D_SECTSIZE));
+		if (agno == get_conf_val(OPT_D, D_AGCOUNT) - 1)
+			set_conf_val(OPT_D, D_AGSIZE,
+				dblocks -
+				(xfs_rfsblock_t)(agno *
+					get_conf_val(OPT_D, D_AGSIZE)));
+
 		agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
 		agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
 		agf->agf_seqno = cpu_to_be32(agno);
-		agf->agf_length = cpu_to_be32(agsize);
+		agf->agf_length = cpu_to_be32(get_conf_val(OPT_D, D_AGSIZE));
 		agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
 		agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
 		agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
@@ -3149,7 +3335,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		agf->agf_flfirst = 0;
 		agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
 		agf->agf_flcount = 0;
-		nbmblocks = (xfs_extlen_t)(agsize - libxfs_prealloc_blocks(mp));
+		nbmblocks = (xfs_extlen_t)(get_conf_val(OPT_D, D_AGSIZE) -
+					   libxfs_prealloc_blocks(mp));
 		agf->agf_freeblks = cpu_to_be32(nbmblocks);
 		agf->agf_longest = cpu_to_be32(nbmblocks);
 		if (xfs_sb_version_hascrc(&mp->m_sb))
@@ -3157,7 +3344,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 
 		if (loginternal && agno == logagno) {
 			be32_add_cpu(&agf->agf_freeblks, -logblocks);
-			agf->agf_longest = cpu_to_be32(agsize -
+			agf->agf_longest =
+				cpu_to_be32(get_conf_val(OPT_D, D_AGSIZE) -
 				XFS_FSB_TO_AGBNO(mp, logstart) - logblocks);
 		}
 		if (libxfs_alloc_min_freelist(mp, pag) > worst_freelist)
@@ -3173,7 +3361,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		buf->b_ops = &xfs_agfl_buf_ops;
 		agfl = XFS_BUF_TO_AGFL(buf);
 		/* setting to 0xff results in initialisation to NULLAGBLOCK */
-		memset(agfl, 0xff, sectorsize);
+		memset(agfl, 0xff, get_conf_val(OPT_D, D_SECTSIZE));
 		if (xfs_sb_version_hascrc(&mp->m_sb)) {
 			agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
 			agfl->agfl_seqno = cpu_to_be32(agno);
@@ -3192,11 +3380,13 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 				XFS_FSS_TO_BB(mp, 1));
 		agi = XFS_BUF_TO_AGI(buf);
 		buf->b_ops = &xfs_agi_buf_ops;
-		memset(agi, 0, sectorsize);
+		memset(agi, 0, get_conf_val(OPT_D, D_SECTSIZE));
 		agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
 		agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
 		agi->agi_seqno = cpu_to_be32(agno);
-		agi->agi_length = cpu_to_be32((xfs_agblock_t)agsize);
+		agi->agi_length =
+			cpu_to_be32(
+				(xfs_agblock_t)get_conf_val(OPT_D, D_AGSIZE));
 		agi->agi_count = 0;
 		agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
 		agi->agi_level = cpu_to_be32(1);
@@ -3221,7 +3411,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 				bsize);
 		buf->b_ops = &xfs_allocbt_buf_ops;
 		block = XFS_BUF_TO_BLOCK(buf);
-		memset(block, 0, blocksize);
+		memset(block, 0, get_conf_val(OPT_B, B_SIZE));
 		libxfs_btree_init_block(mp, buf, XFS_BTNUM_BNO, 0, 1, agno, 0);
 
 		arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
@@ -3256,7 +3446,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		 * so, reset the record count to 0 to avoid exposure of an invalid
 		 * record start block.
 		 */
-		arec->ar_blockcount = cpu_to_be32(agsize -
+		arec->ar_blockcount =
+			cpu_to_be32(get_conf_val(OPT_D, D_AGSIZE) -
 					be32_to_cpu(arec->ar_startblock));
 		if (!arec->ar_blockcount)
 			block->bb_numrecs = 0;
@@ -3271,7 +3462,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 				bsize);
 		buf->b_ops = &xfs_allocbt_buf_ops;
 		block = XFS_BUF_TO_BLOCK(buf);
-		memset(block, 0, blocksize);
+		memset(block, 0, get_conf_val(OPT_B, B_SIZE));
 		libxfs_btree_init_block(mp, buf, XFS_BTNUM_CNT, 0, 1, agno, 0);
 
 		arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
@@ -3296,7 +3487,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		 * so, reset the record count to 0 to avoid exposure of an invalid
 		 * record start block.
 		 */
-		arec->ar_blockcount = cpu_to_be32(agsize -
+		arec->ar_blockcount =
+			cpu_to_be32(get_conf_val(OPT_D, D_AGSIZE) -
 					be32_to_cpu(arec->ar_startblock));
 		if (!arec->ar_blockcount)
 			block->bb_numrecs = 0;
@@ -3314,7 +3506,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 			buf->b_ops = &xfs_refcountbt_buf_ops;
 
 			block = XFS_BUF_TO_BLOCK(buf);
-			memset(block, 0, blocksize);
+			memset(block, 0, get_conf_val(OPT_B, B_SIZE));
 			libxfs_btree_init_block(mp, buf, XFS_BTNUM_REFC, 0,
 						0, agno, 0);
 
@@ -3329,7 +3521,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 				bsize);
 		buf->b_ops = &xfs_inobt_buf_ops;
 		block = XFS_BUF_TO_BLOCK(buf);
-		memset(block, 0, blocksize);
+		memset(block, 0, get_conf_val(OPT_B, B_SIZE));
 		libxfs_btree_init_block(mp, buf, XFS_BTNUM_INO, 0, 0, agno, 0);
 		libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
 
@@ -3342,7 +3534,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 					bsize);
 			buf->b_ops = &xfs_inobt_buf_ops;
 			block = XFS_BUF_TO_BLOCK(buf);
-			memset(block, 0, blocksize);
+			memset(block, 0, get_conf_val(OPT_B, B_SIZE));
 			libxfs_btree_init_block(mp, buf, XFS_BTNUM_FINO, 0, 0, agno, 0);
 			libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
 		}
@@ -3356,7 +3548,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 				bsize);
 			buf->b_ops = &xfs_rmapbt_buf_ops;
 			block = XFS_BUF_TO_BLOCK(buf);
-			memset(block, 0, blocksize);
+			memset(block, 0, get_conf_val(OPT_B, B_SIZE));
 
 			libxfs_btree_init_block(mp, buf, XFS_BTNUM_RMAP, 0, 0, agno, 0);
 
@@ -3432,7 +3624,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	 */
 	buf = libxfs_getbuf(mp->m_ddev_targp,
 		(xfs_daddr_t)XFS_FSB_TO_BB(mp, dblocks - 1LL), bsize);
-	memset(XFS_BUF_PTR(buf), 0, blocksize);
+	memset(XFS_BUF_PTR(buf), 0, get_conf_val(OPT_B, B_SIZE));
 	libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
 
 	/*
@@ -3441,14 +3633,14 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	if (mp->m_rtdev_targp->dev && rtblocks > 0) {
 		buf = libxfs_getbuf(mp->m_rtdev_targp,
 				XFS_FSB_TO_BB(mp, rtblocks - 1LL), bsize);
-		memset(XFS_BUF_PTR(buf), 0, blocksize);
+		memset(XFS_BUF_PTR(buf), 0, get_conf_val(OPT_B, B_SIZE));
 		libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
 	}
 
 	/*
 	 * BNO, CNT free block list
 	 */
-	for (agno = 0; agno < agcount; agno++) {
+	for (agno = 0; agno < get_conf_val(OPT_D, D_AGCOUNT); agno++) {
 		xfs_alloc_arg_t	args;
 		xfs_trans_t	*tp;
 		struct xfs_trans_res tres = {0};
-- 
2.1.4


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

* [PATCH 09/12] mkfs: replace variables with opts table: -i options
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (7 preceding siblings ...)
  2017-04-23 18:54 ` [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options Jan Tulak
@ 2017-04-23 18:55 ` Jan Tulak
  2017-04-23 18:55 ` [PATCH 10/12] mkfs: replace variables with opts table: -l options Jan Tulak
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:55 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Remove variables that can be replaced with a direct access to the opts table,
so we have it all in a single place, acessible from anywhere.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 86 ++++++++++++++++++++++++++++++---------------------------
 1 file changed, 45 insertions(+), 41 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 6857c30..a5e7c7e 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1499,13 +1499,9 @@ main(
 	bool			force_overwrite;
 	struct fsxattr		fsx;
 	bool			ilflag;
-	uint64_t		imaxpct;
 	bool			imflag;
-	uint64_t		inodelog;
-	uint64_t		inopblock;
 	bool			ipflag;
 	bool			isflag;
-	uint64_t		isize;
 	char			*label = NULL;
 	bool			laflag;
 	uint64_t		lalign;
@@ -1591,7 +1587,6 @@ main(
 	Nflag = nlflag = nsflag = nvflag = false;
 	dirblocklog = dirblocksize = 0;
 	qflag = false;
-	imaxpct = inodelog = inopblock = isize = 0;
 	dfile = logfile = rtfile = NULL;
 	protofile = NULL;
 	rtbytes = rtextbytes = logbytes = 0;
@@ -1767,6 +1762,7 @@ main(
 				char	**subopts =
 						(char **)opts[OPT_I].subopts;
 				char	*value;
+				uint64_t tmp;
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case I_ALIGN:
@@ -1775,30 +1771,26 @@ main(
 							       value);
 					break;
 				case I_LOG:
-					inodelog = parse_conf_val(OPT_I, I_LOG,
-								  value);
-					isize = 1 << inodelog;
+					tmp = parse_conf_val(OPT_I, I_LOG,
+							     value);
+					set_conf_val(OPT_I, I_SIZE, 1 << tmp);
 					ilflag = 1;
-					set_conf_val(OPT_I, I_SIZE, isize);
 					break;
 				case I_MAXPCT:
-					imaxpct = parse_conf_val(OPT_I,
-								 I_MAXPCT,
-								 value);
+					parse_conf_val(OPT_I, I_MAXPCT, value);
 					imflag = 1;
 					break;
 				case I_PERBLOCK:
-					inopblock = parse_conf_val(OPT_I,
-								   I_PERBLOCK,
-								   value);
+					parse_conf_val(OPT_I, I_PERBLOCK,
+						       value);
 					ipflag = 1;
 					break;
 				case I_SIZE:
-					isize = parse_conf_val(OPT_I, I_SIZE,
+					tmp = parse_conf_val(OPT_I, I_SIZE,
 							       value);
-					inodelog = libxfs_highbit32(isize);
+					set_conf_val(OPT_I, I_LOG,
+						     libxfs_highbit32(tmp));
 					isflag = 1;
-					set_conf_val(OPT_I, I_LOG, inodelog);
 					break;
 				case I_ATTR:
 					sb_feat.attr_version =
@@ -2289,7 +2281,8 @@ _("block size %"PRIu64" cannot be smaller than logical sector size %d\n"),
 	 */
 	if (sb_feat.crcs_enabled) {
 		/* minimum inode size is 512 bytes, ipflag checked later */
-		if ((isflag || ilflag) && inodelog < XFS_DINODE_DFL_CRC_LOG) {
+		if ((isflag || ilflag) &&
+		    get_conf_val(OPT_I, I_LOG) < XFS_DINODE_DFL_CRC_LOG) {
 			fprintf(stderr,
 _("Minimum inode size for CRCs is %d bytes\n"),
 				1 << XFS_DINODE_DFL_CRC_LOG);
@@ -2413,15 +2406,17 @@ _("rmapbt not supported with realtime devices\n"));
 					   get_conf_val(OPT_B, B_LOG)));
 	}
 	if (ipflag) {
-		inodelog = get_conf_val(OPT_B, B_LOG) -
-			libxfs_highbit32(inopblock);
-		isize = 1 << inodelog;
+		set_conf_val(OPT_I, I_LOG, get_conf_val(OPT_B, B_LOG) -
+			libxfs_highbit32(get_conf_val(OPT_I, I_PERBLOCK)));
+		set_conf_val(OPT_I, I_SIZE, 1 << get_conf_val(OPT_I, I_LOG));
 	} else if (!ilflag && !isflag) {
-		inodelog = sb_feat.crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
-						: XFS_DINODE_DFL_LOG;
-		isize = 1 << inodelog;
+		set_conf_val(OPT_I, I_LOG,
+			     sb_feat.crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
+						: XFS_DINODE_DFL_LOG);
+		set_conf_val(OPT_I, I_SIZE, 1 << get_conf_val(OPT_I, I_LOG));
 	}
-	if (sb_feat.crcs_enabled && inodelog < XFS_DINODE_DFL_CRC_LOG) {
+	if (sb_feat.crcs_enabled && get_conf_val(OPT_I, I_LOG) <
+	    XFS_DINODE_DFL_CRC_LOG) {
 		fprintf(stderr,
 		_("Minimum inode size for CRCs is %d bytes\n"),
 			1 << XFS_DINODE_DFL_CRC_LOG);
@@ -2508,12 +2503,14 @@ _("rmapbt not supported with realtime devices\n"));
 	/*
 	 * Check some argument sizes against mins, maxes.
 	 */
-	if (isize > get_conf_val(OPT_B, B_SIZE) / XFS_MIN_INODE_PERBLOCK ||
-	    isize < XFS_DINODE_MIN_SIZE ||
-	    isize > XFS_DINODE_MAX_SIZE) {
+	if (get_conf_val(OPT_I, I_SIZE) >
+	    get_conf_val(OPT_B, B_SIZE) / XFS_MIN_INODE_PERBLOCK ||
+	    get_conf_val(OPT_I, I_SIZE) < XFS_DINODE_MIN_SIZE ||
+	    get_conf_val(OPT_I, I_SIZE) > XFS_DINODE_MAX_SIZE) {
 		int	maxsz;
 
-		fprintf(stderr, _("illegal inode size %"PRIu64"\n"), isize);
+		fprintf(stderr, _("illegal inode size %"PRIu64"\n"),
+			get_conf_val(OPT_I, I_SIZE));
 		maxsz = MIN(get_conf_val(OPT_B, B_SIZE) /
 			    XFS_MIN_INODE_PERBLOCK,
 			    XFS_DINODE_MAX_SIZE);
@@ -2919,8 +2916,9 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
 			     get_conf_val(OPT_D, D_AGCOUNT));
 
 	if (!imflag)
-		imaxpct = calc_default_imaxpct(get_conf_val(OPT_B, B_LOG),
-					       dblocks);
+		set_conf_val(OPT_I, I_MAXPCT,
+			     calc_default_imaxpct(get_conf_val(OPT_B, B_LOG),
+					       dblocks));
 
 	/*
 	 * check that log sunit is modulo fsblksize or default it to D_SUNIT.
@@ -2953,7 +2951,7 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
 				   sb_feat.crcs_enabled, sb_feat.dir_version,
 				   get_conf_val(OPT_D, D_SECTLOG),
 				   get_conf_val(OPT_B, B_LOG),
-				   inodelog, dirblocklog,
+				   get_conf_val(OPT_I, I_LOG), dirblocklog,
 				   sb_feat.log_version, lsunit, sb_feat.finobt,
 				   sb_feat.rmapbt, sb_feat.reflink);
 	ASSERT(min_logblocks);
@@ -3120,14 +3118,17 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		   "log      =%-22s bsize=%-6d blocks=%"PRIu64", version=%d\n"
 		   "         =%-22s sectsz=%-5lu sunit=%"PRIu64" blks, lazy-count=%d\n"
 		   "realtime =%-22s extsz=%-6d blocks=%"PRIu64", rtextents=%"PRIu64"\n"),
-			dfile, isize, get_conf_val(OPT_D, D_AGCOUNT),
+			dfile, get_conf_val(OPT_I, I_SIZE),
+			get_conf_val(OPT_D, D_AGCOUNT),
 			get_conf_val(OPT_D, D_AGSIZE),
 			"", get_conf_val(OPT_D, D_SECTSIZE),
 			sb_feat.attr_version,
 				    !sb_feat.projid16bit,
 			"", sb_feat.crcs_enabled, sb_feat.finobt, sb_feat.spinodes,
 			sb_feat.rmapbt, sb_feat.reflink,
-			"", get_conf_val(OPT_B, B_SIZE), dblocks, imaxpct,
+			"", get_conf_val(OPT_B, B_SIZE),
+			dblocks,
+			get_conf_val(OPT_I, I_MAXPCT),
 			"", get_conf_val(OPT_D, D_SUNIT),
 			get_conf_val(OPT_D, D_SWIDTH),
 			sb_feat.dir_version, dirblocksize, sb_feat.nci,
@@ -3158,16 +3159,18 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	sbp->sb_rbmblocks = nbmblocks;
 	sbp->sb_logblocks = (xfs_extlen_t)logblocks;
 	sbp->sb_sectsize = (__uint16_t)get_conf_val(OPT_D, D_SECTSIZE);
-	sbp->sb_inodesize = (__uint16_t)isize;
-	sbp->sb_inopblock = (__uint16_t)(get_conf_val(OPT_B, B_SIZE) / isize);
+	sbp->sb_inodesize = (__uint16_t)get_conf_val(OPT_I, I_SIZE);
+	sbp->sb_inopblock = (__uint16_t)(get_conf_val(OPT_B, B_SIZE) /
+					 get_conf_val(OPT_I, I_SIZE));
 	sbp->sb_sectlog = (__uint8_t)get_conf_val(OPT_D, D_SECTLOG);
-	sbp->sb_inodelog = (__uint8_t)inodelog;
-	sbp->sb_inopblog = (__uint8_t)(get_conf_val(OPT_B, B_LOG) - inodelog);
+	sbp->sb_inodelog = (__uint8_t)get_conf_val(OPT_I, I_LOG);
+	sbp->sb_inopblog = (__uint8_t)(get_conf_val(OPT_B, B_LOG) -
+				       get_conf_val(OPT_I, I_LOG));
 	sbp->sb_rextslog =
 		(__uint8_t)(rtextents ?
 			libxfs_highbit32((unsigned int)rtextents) : 0);
 	sbp->sb_inprogress = 1;	/* mkfs is in progress */
-	sbp->sb_imax_pct = imaxpct;
+	sbp->sb_imax_pct = get_conf_val(OPT_I, I_MAXPCT);
 	sbp->sb_icount = 0;
 	sbp->sb_ifree = 0;
 	sbp->sb_fdblocks = dblocks -
@@ -3187,7 +3190,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	if (sb_feat.inode_align) {
 		int	cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
 		if (sb_feat.crcs_enabled)
-			cluster_size *= isize / XFS_DINODE_MIN_SIZE;
+			cluster_size *= get_conf_val(OPT_I, I_SIZE) /
+				XFS_DINODE_MIN_SIZE;
 		sbp->sb_inoalignmt = cluster_size >> get_conf_val(OPT_B, B_LOG);
 		sb_feat.inode_align = sbp->sb_inoalignmt != 0;
 	} else
-- 
2.1.4


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

* [PATCH 10/12] mkfs: replace variables with opts table: -l options
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (8 preceding siblings ...)
  2017-04-23 18:55 ` [PATCH 09/12] mkfs: replace variables with opts table: -i options Jan Tulak
@ 2017-04-23 18:55 ` Jan Tulak
  2017-04-23 18:55 ` [PATCH 11/12] mkfs: replace variables with opts table: -n options Jan Tulak
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:55 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Remove variables that can be replaced with a direct access to the opts table,
so we have it all in a single place, acessible from anywhere.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 253 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 136 insertions(+), 117 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index a5e7c7e..7d85471 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -465,6 +465,7 @@ struct opt_params {
 			  .minval = 0,
 			  .maxval = 1,
 			  .flagval = 1,
+			  .value = 1,
 			},
 			{ .index = L_SIZE,
 			  .conflicts = { LAST_CONFLICT },
@@ -813,7 +814,8 @@ parse_conf_val(int opt, int subopt, char *value)
 
 
 /*
- * Convert lsu to lsunit for 512 bytes blocks and check validity of the values.
+ * Convert L_SU to L_SUNIT for 512 bytes blocks and check validity of the
+ * values.
  */
 static void
 calc_stripe_factors(
@@ -865,7 +867,7 @@ calc_stripe_factors(
 	if (lsu)
 		*lsunit = BTOBBT(lsu);
 
-	/* verify if lsu/lsunit is a multiple block size */
+	/* verify if L_SU/L_SUNIT is a multiple block size */
 	if (lsu % get_conf_val(OPT_B, B_SIZE) != 0) {
 		fprintf(stderr,
 _("log stripe unit (%d) must be a multiple of the block size (%"PRIu64")\n"),
@@ -1507,22 +1509,15 @@ main(
 	uint64_t		lalign;
 	bool			ldflag;
 	bool			liflag;
-	xfs_agnumber_t		logagno;
 	xfs_rfsblock_t		logblocks;
 	char			*logfile;
-	uint64_t		loginternal;
-	uint64_t		logbytes;
 	xfs_fsblock_t		logstart;
 	bool			lvflag;
 	bool			lsflag;
 	bool			lsuflag;
 	bool			lsunitflag;
-	uint64_t		lsectorlog;
-	uint64_t		lsectorsize;
 	bool			lslflag;
 	bool			lssflag;
-	uint64_t		lsu;
-	uint64_t		lsunit;
 	uint64_t		min_logblocks;
 	xfs_mount_t		*mp;
 	xfs_mount_t		mbuf;
@@ -1577,20 +1572,17 @@ main(
 	textdomain(PACKAGE);
 
 	blflag = bsflag = slflag = ssflag = lslflag = lssflag = 0;
-	lsectorlog = 0;
-	lsectorsize = 0;
 	dasize = dblocks = 0;
 	daflag = ilflag = imflag = ipflag = isflag = false;
 	liflag = laflag = lsflag = lsuflag = lsunitflag = ldflag = lvflag = false;
-	loginternal = 1;
-	logagno = logblocks = rtblocks = rtextblocks = 0;
+	logblocks = rtblocks = rtextblocks = 0;
 	Nflag = nlflag = nsflag = nvflag = false;
 	dirblocklog = dirblocksize = 0;
 	qflag = false;
 	dfile = logfile = rtfile = NULL;
 	protofile = NULL;
-	rtbytes = rtextbytes = logbytes = 0;
-	lalign = lsu = lsunit = 0;
+	rtbytes = rtextbytes = 0;
+	lalign = 0;
 	norsflag = false;
 	force_overwrite = false;
 	worst_freelist = 0;
@@ -1824,9 +1816,7 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case L_AGNUM:
-					logagno = parse_conf_val(OPT_L,
-								 L_AGNUM,
-								 value);
+					parse_conf_val(OPT_L, L_AGNUM, value);
 					laflag = 1;
 					break;
 				case L_FILE:
@@ -1835,20 +1825,16 @@ main(
 								    value);
 					break;
 				case L_INTERNAL:
-					loginternal =
-						parse_conf_val(OPT_L,
-							       L_INTERNAL,
-							       value);
+					parse_conf_val(OPT_L, L_INTERNAL,
+						       value);
 					liflag = 1;
 					break;
 				case L_SU:
-					lsu = parse_conf_val(OPT_L, L_SU,
-							     value);
+					parse_conf_val(OPT_L, L_SU, value);
 					lsuflag = 1;
 					break;
 				case L_SUNIT:
-					lsunit = parse_conf_val(OPT_L, L_SUNIT,
-								value);
+					parse_conf_val(OPT_L, L_SUNIT, value);
 					lsunitflag = 1;
 					break;
 				case L_NAME:
@@ -1857,7 +1843,7 @@ main(
 								L_NAME);
 					xi.logname = logfile;
 					ldflag = 1;
-					loginternal = 0;
+					set_conf_val(OPT_L, L_INTERNAL, 0);
 					set_conf_val(OPT_L, L_NAME, 1);
 					set_conf_val(OPT_L, L_DEV, 1);
 					break;
@@ -1871,29 +1857,24 @@ main(
 						     sb_feat.log_version);
 					break;
 				case L_SIZE:
-					logbytes = parse_conf_val(OPT_L,
-								  L_SIZE,
-								  value);
+					parse_conf_val(OPT_L, L_SIZE, value);
 					break;
 				case L_SECTLOG:
-					lsectorlog = parse_conf_val(OPT_L,
+					tmp = parse_conf_val(OPT_L,
 								    L_SECTLOG,
 								    value);
-					lsectorsize = 1 << lsectorlog;
-					lslflag = 1;
 					set_conf_val(OPT_L, L_SECTSIZE,
-						     lsectorsize);
+						     1 << tmp);
+					lslflag = 1;
 					break;
 				case L_SECTSIZE:
-					lsectorsize =
+					tmp =
 						parse_conf_val(OPT_L,
 							       L_SECTSIZE,
 							       value);
-					lsectorlog =
-						libxfs_highbit32(lsectorsize);
-					lssflag = 1;
 					set_conf_val(OPT_L, L_SECTLOG,
-						     lsectorlog);
+						     libxfs_highbit32(tmp));
+					lssflag = 1;
 					break;
 				case L_LAZYSBCNTR:
 					sb_feat.lazy_sb_counters =
@@ -2092,14 +2073,14 @@ main(
 
 					set_conf_val(OPT_S, S_LOG, tmp);
 					set_conf_val(OPT_D, D_SECTLOG, tmp);
-					lsectorlog = tmp;
+					set_conf_val(OPT_L, L_SECTLOG, tmp);
 					set_conf_val(OPT_D, D_SECTSIZE,
 						     1 << tmp);
 					set_conf_val(OPT_S, S_SIZE, 1 << tmp);
 					set_conf_val(OPT_S, S_SECTSIZE,
 						     1 << tmp);
 
-					lsectorsize = tmp;
+					set_conf_val(OPT_L, L_SECTSIZE, tmp);
 					lslflag = slflag = 1;
 					break;
 				case S_SIZE:
@@ -2114,14 +2095,13 @@ main(
 
 					set_conf_val(OPT_S, S_SIZE, tmp);
 					set_conf_val(OPT_D, D_SECTSIZE, tmp);
-					lsectorsize = tmp;
+					set_conf_val(OPT_L, L_SECTSIZE, tmp);
 					set_conf_val(OPT_D, D_SECTLOG,
 						libxfs_highbit32(tmp));
 					set_conf_val(OPT_S, S_LOG,
 						libxfs_highbit32(tmp));
 					set_conf_val(OPT_S, S_SECTLOG,
 						libxfs_highbit32(tmp));
-					lsectorlog = libxfs_highbit32(tmp);
 
 					lssflag = ssflag = 1;
 					break;
@@ -2178,8 +2158,9 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 		set_conf_val(OPT_D, D_SECTSIZE, XFS_MIN_SECTORSIZE);
 	}
 	if (!lslflag && !lssflag) {
-		lsectorlog = get_conf_val(OPT_D, D_SECTLOG);
-		lsectorsize = get_conf_val(OPT_D, D_SECTSIZE);
+		set_conf_val(OPT_L, L_SECTLOG, get_conf_val(OPT_D, D_SECTLOG));
+		set_conf_val(OPT_L, L_SECTSIZE,
+			     get_conf_val(OPT_D, D_SECTSIZE));
 	}
 
 	/*
@@ -2192,8 +2173,9 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 	check_device_type(dfile, &xi.disfile, !get_conf_val(OPT_D, D_SIZE),
 			  !dfile,
 			  Nflag ? NULL : &xi.dcreat, force_overwrite, "d");
-	if (!loginternal)
-		check_device_type(xi.logname, &xi.lisfile, !logbytes,
+	if (!get_conf_val(OPT_L, L_INTERNAL))
+		check_device_type(xi.logname, &xi.lisfile,
+				  !get_conf_val(OPT_L, L_SIZE),
 				  !xi.logname, Nflag ? NULL : &xi.lcreat,
 				  force_overwrite, "l");
 	if (xi.rtname)
@@ -2241,9 +2223,11 @@ _("switching to logical sector size %d\n"),
 	if (!ssflag) {
 		set_conf_val(OPT_D, D_SECTLOG,
 			     libxfs_highbit32(get_conf_val(OPT_D, D_SECTSIZE)));
-		if (loginternal) {
-			lsectorsize = get_conf_val(OPT_D, D_SECTSIZE);
-			lsectorlog = get_conf_val(OPT_D, D_SECTLOG);
+		if (get_conf_val(OPT_L, L_INTERNAL)) {
+			set_conf_val(OPT_L, L_SECTSIZE,
+				     get_conf_val(OPT_D, D_SECTSIZE));
+			set_conf_val(OPT_L, L_SECTLOG,
+				     get_conf_val(OPT_D, D_SECTLOG));
 		}
 	}
 
@@ -2264,13 +2248,16 @@ _("block size %"PRIu64" cannot be smaller than logical sector size %d\n"),
 			get_conf_val(OPT_D, D_SECTSIZE), ft.lsectorsize);
 		usage();
 	}
-	if (lsectorsize < XFS_MIN_SECTORSIZE ||
-	    lsectorsize > XFS_MAX_SECTORSIZE ||
-	    lsectorsize > get_conf_val(OPT_B, B_SIZE)) {
-		fprintf(stderr, _("illegal log sector size %"PRIu64"\n"), lsectorsize);
+	if (get_conf_val(OPT_L, L_SECTSIZE) < XFS_MIN_SECTORSIZE ||
+	    get_conf_val(OPT_L, L_SECTSIZE) > XFS_MAX_SECTORSIZE ||
+	    get_conf_val(OPT_L, L_SECTSIZE) > get_conf_val(OPT_B, B_SIZE)) {
+		fprintf(stderr, _("illegal log sector size %"PRIu64"\n"),
+			get_conf_val(OPT_L, L_SECTSIZE));
 		usage();
-	} else if (lsectorsize > XFS_MIN_SECTORSIZE && !lsu && !lsunit) {
-		lsu = get_conf_val(OPT_B, B_SIZE);
+	} else if (get_conf_val(OPT_L, L_SECTSIZE) > XFS_MIN_SECTORSIZE &&
+		   !get_conf_val(OPT_L, L_SU) &&
+		   !get_conf_val(OPT_L, L_SUNIT)) {
+		set_conf_val(OPT_L, L_SU, get_conf_val(OPT_B, B_SIZE));
 		sb_feat.log_version = 2;
 	}
 
@@ -2423,19 +2410,20 @@ _("rmapbt not supported with realtime devices\n"));
 		usage();
 	}
 
-	if (logbytes) {
-		if (logbytes % XFS_MIN_BLOCKSIZE) {
+	if (get_conf_val(OPT_L, L_SIZE)) {
+		if (get_conf_val(OPT_L, L_SIZE) % XFS_MIN_BLOCKSIZE) {
 			fprintf(stderr,
 			_("illegal log length %"PRIu64", not a multiple of %d\n"),
-				logbytes, XFS_MIN_BLOCKSIZE);
+				get_conf_val(OPT_L, L_SIZE), XFS_MIN_BLOCKSIZE);
 			usage();
 		}
-		logblocks = (xfs_rfsblock_t)(logbytes >>
+		logblocks = (xfs_rfsblock_t)(get_conf_val(OPT_L, L_SIZE) >>
 					     get_conf_val(OPT_B, B_LOG));
-		if (logbytes % get_conf_val(OPT_B, B_SIZE))
+		if (get_conf_val(OPT_L, L_SIZE) % get_conf_val(OPT_B, B_SIZE))
 			fprintf(stderr,
 	_("warning: log length %"PRIu64" not a multiple of %"PRIu64", truncated to %"PRIu64"\n"),
-				logbytes, get_conf_val(OPT_B, B_SIZE),
+				get_conf_val(OPT_L, L_SIZE),
+				get_conf_val(OPT_B, B_SIZE),
 				(uint64_t)(logblocks <<
 					   get_conf_val(OPT_B, B_LOG)));
 	}
@@ -2527,8 +2515,9 @@ _("rmapbt not supported with realtime devices\n"));
 		exit(1);
 	}
 
-	/* if lsu or lsunit was specified, automatically use v2 logs */
-	if ((lsu || lsunit) && sb_feat.log_version == 1) {
+	/* if L_SU or L_SUNIT was specified, automatically use v2 logs */
+	if ((get_conf_val(OPT_L, L_SU) ||
+	     get_conf_val(OPT_L, L_SUNIT)) && sb_feat.log_version == 1) {
 		fprintf(stderr,
 			_("log stripe unit specified, using v2 logs\n"));
 		sb_feat.log_version = 2;
@@ -2536,16 +2525,18 @@ _("rmapbt not supported with realtime devices\n"));
 
 	uint64_t dsunit = get_conf_val(OPT_D, D_SUNIT);
 	uint64_t dswidth = get_conf_val(OPT_D, D_SWIDTH);
+	uint64_t lsunit = get_conf_val(OPT_L, L_SUNIT);
 
 	calc_stripe_factors(get_conf_val(OPT_D, D_SU),
 			    get_conf_val(OPT_D, D_SW),
 			    get_conf_val(OPT_D, D_SECTSIZE),
-			    lsu,
-			    lsectorsize,
-				&dsunit, &dswidth, &lsunit);
+			    get_conf_val(OPT_L, L_SU),
+			    get_conf_val(OPT_L, L_SECTSIZE),
+			    &dsunit, &dswidth, &lsunit);
 
 	set_conf_val(OPT_D, D_SUNIT, dsunit);
 	set_conf_val(OPT_D, D_SWIDTH, dswidth);
+	set_conf_val(OPT_L, L_SUNIT, lsunit);
 
 	xi.setblksize = get_conf_val(OPT_D, D_SECTSIZE);
 
@@ -2574,7 +2565,8 @@ _("rmapbt not supported with realtime devices\n"));
 		(MAX(get_conf_val(OPT_D, D_SECTLOG), 10) - BBSHIFT);
 	xi.dsize &= sector_mask;
 	xi.rtsize &= sector_mask;
-	xi.logBBsize &= (uint64_t)-1 << (MAX(lsectorlog, 10) - BBSHIFT);
+	xi.logBBsize &= (uint64_t)-1 << (MAX(get_conf_val(OPT_L, L_SECTLOG),
+					     10) - BBSHIFT);
 
 
 	/* don't do discards on print-only runs or on files */
@@ -2588,10 +2580,10 @@ _("rmapbt not supported with realtime devices\n"));
 	}
 
 	if (!liflag && !ldflag)
-		loginternal = xi.logdev == 0;
+		set_conf_val(OPT_L, L_INTERNAL, xi.logdev == 0);
 	if (xi.logname)
 		logfile = xi.logname;
-	else if (loginternal)
+	else if (get_conf_val(OPT_L, L_INTERNAL))
 		logfile = _("internal log");
 	else if (xi.volname && xi.logdev)
 		logfile = _("volume log");
@@ -2627,12 +2619,13 @@ _("rmapbt not supported with realtime devices\n"));
 		usage();
 	}
 
-	if (loginternal && xi.logdev) {
+	if (get_conf_val(OPT_L, L_INTERNAL) && xi.logdev) {
 		fprintf(stderr,
 			_("can't have both external and internal logs\n"));
 		usage();
-	} else if (loginternal &&
-		   get_conf_val(OPT_D, D_SECTSIZE) != lsectorsize) {
+	} else if (get_conf_val(OPT_L, L_INTERNAL) &&
+		   get_conf_val(OPT_D, D_SECTSIZE) !=
+		   get_conf_val(OPT_L, L_SECTSIZE)) {
 		fprintf(stderr,
 	_("data and log sector sizes must be equal for internal logs\n"));
 		usage();
@@ -2644,11 +2637,12 @@ _("rmapbt not supported with realtime devices\n"));
 reported by the device (%u).\n"),
 			get_conf_val(OPT_D, D_SECTSIZE), xi.dbsize);
 	}
-	if (!loginternal && xi.lbsize > lsectorsize) {
+	if (!get_conf_val(OPT_L, L_INTERNAL) &&
+	    xi.lbsize > get_conf_val(OPT_L, L_SECTSIZE)) {
 		fprintf(stderr, _(
 "Warning: the log subvolume sector size %"PRIu64" is less than the sector size\n\
 reported by the device (%u).\n"),
-			lsectorsize, xi.lbsize);
+			get_conf_val(OPT_L, L_SECTSIZE), xi.lbsize);
 	}
 	if (rtbytes && xi.rtsize > 0 &&
 	    xi.rtbsize > get_conf_val(OPT_D, D_SECTSIZE)) {
@@ -2924,27 +2918,31 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
 	 * check that log sunit is modulo fsblksize or default it to D_SUNIT.
 	 */
 
-	if (lsunit) {
+	if (get_conf_val(OPT_L, L_SUNIT)) {
 		/* convert from 512 byte blocks to fs blocks */
-		lsunit = DTOBT(lsunit);
+		set_conf_val(OPT_L, L_SUNIT,
+			     DTOBT(get_conf_val(OPT_L, L_SUNIT)));
 	} else if (sb_feat.log_version == 2 &&
-		   loginternal &&
+		   get_conf_val(OPT_L, L_INTERNAL) &&
 		   get_conf_val(OPT_D, D_SUNIT)) {
-		/* lsunit and get_conf_val(OPT_D, D_SUNIT) now in fs blocks */
-		lsunit = get_conf_val(OPT_D, D_SUNIT);
+		/* L_SUNIT and D_SUNIT now in fs blocks */
+		set_conf_val(OPT_L, L_SUNIT, get_conf_val(OPT_D, D_SUNIT));
 	}
 
 	if (sb_feat.log_version == 2 &&
-	    (lsunit * get_conf_val(OPT_B, B_SIZE)) > 256 * 1024) {
+	    (get_conf_val(OPT_L, L_SUNIT) *
+	     get_conf_val(OPT_B, B_SIZE)) > 256 * 1024) {
 		/* Warn only if specified on commandline */
 		if (lsuflag || lsunitflag) {
 			fprintf(stderr,
 	_("log stripe unit (%"PRIu64" bytes) is too large (maximum is 256KiB)\n"),
-				(lsunit * get_conf_val(OPT_B, B_SIZE)));
+				(get_conf_val(OPT_L, L_SUNIT) *
+				 get_conf_val(OPT_B, B_SIZE)));
 			fprintf(stderr,
 	_("log stripe unit adjusted to 32KiB\n"));
 		}
-		lsunit = (32 * 1024) >> get_conf_val(OPT_B, B_LOG);
+		set_conf_val(OPT_L, L_SUNIT,
+			     (32 * 1024) >> get_conf_val(OPT_B, B_LOG));
 	}
 
 	min_logblocks = max_trans_res(get_conf_val(OPT_D, D_AGSIZE),
@@ -2952,34 +2950,40 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
 				   get_conf_val(OPT_D, D_SECTLOG),
 				   get_conf_val(OPT_B, B_LOG),
 				   get_conf_val(OPT_I, I_LOG), dirblocklog,
-				   sb_feat.log_version, lsunit, sb_feat.finobt,
+				   sb_feat.log_version,
+				   get_conf_val(OPT_L, L_SUNIT),
+				   sb_feat.finobt,
 				   sb_feat.rmapbt, sb_feat.reflink);
 	ASSERT(min_logblocks);
 	min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
-	if (!logbytes &&
+	if (!get_conf_val(OPT_L, L_SIZE) &&
 	    dblocks >= (1024*1024*1024) >> get_conf_val(OPT_B, B_LOG))
 		min_logblocks = MAX(min_logblocks,
 				    XFS_MIN_LOG_BYTES >>
 				    get_conf_val(OPT_B, B_LOG));
-	if (logbytes && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
+	if (get_conf_val(OPT_L, L_SIZE) && xi.logBBsize > 0 &&
+	    logblocks > DTOBT(xi.logBBsize)) {
 		fprintf(stderr,
 _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks\n"),
 			get_conf_raw(OPT_L, L_SIZE),
 			(uint64_t)DTOBT(xi.logBBsize));
 		usage();
-	} else if (!logbytes && xi.logBBsize > 0) {
+	} else if (!get_conf_val(OPT_L, L_SIZE) && xi.logBBsize > 0) {
 		logblocks = DTOBT(xi.logBBsize);
-	} else if (logbytes && !xi.logdev && !loginternal) {
+	} else if (get_conf_val(OPT_L, L_SIZE) && !xi.logdev &&
+		   !get_conf_val(OPT_L, L_INTERNAL)) {
 		fprintf(stderr,
 			_("size specified for non-existent log subvolume\n"));
 		usage();
-	} else if (loginternal && logbytes && logblocks >= dblocks) {
+	} else if (get_conf_val(OPT_L, L_INTERNAL) &&
+		   get_conf_val(OPT_L, L_SIZE) && logblocks >= dblocks) {
 		fprintf(stderr, _("size %"PRIu64" too large for internal log\n"),
 			logblocks);
 		usage();
-	} else if (!loginternal && !xi.logdev) {
+	} else if (!get_conf_val(OPT_L, L_INTERNAL) && !xi.logdev) {
 		logblocks = 0;
-	} else if (loginternal && !logbytes) {
+	} else if (get_conf_val(OPT_L, L_INTERNAL) &&
+		   !get_conf_val(OPT_L, L_SIZE)) {
 
 		if (dblocks < GIGABYTES(1, get_conf_val(OPT_B, B_LOG))) {
 			/* tiny filesystems get minimum sized logs. */
@@ -3043,16 +3047,16 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	 */
 	sb_set_features(&mp->m_sb, &sb_feat,
 			get_conf_val(OPT_D, D_SECTSIZE),
-			lsectorsize,
+			get_conf_val(OPT_L, L_SECTSIZE),
 			get_conf_val(OPT_D, D_SUNIT));
 
 
-	if (loginternal) {
+	if (get_conf_val(OPT_L, L_INTERNAL)) {
 		/*
 		 * Readjust the log size to fit within an AG if it was sized
 		 * automatically.
 		 */
-		if (!logbytes) {
+		if (!get_conf_val(OPT_L, L_SIZE)) {
 			logblocks = MIN(logblocks,
 					libxfs_alloc_ag_max_usable(mp));
 
@@ -3070,25 +3074,28 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		}
 
 		if (laflag) {
-			if (logagno >= get_conf_val(OPT_D, D_AGCOUNT)) {
+			if (get_conf_val(OPT_L, L_AGNUM) >=
+			    get_conf_val(OPT_D, D_AGCOUNT)) {
 				fprintf(stderr,
-		_("log ag number %d too large, must be less than %"PRIu64"\n"),
-					logagno,
+	_("log ag number %"PRIu64" too large, must be less than %"PRIu64"\n"),
+					get_conf_val(OPT_L, L_AGNUM),
 					get_conf_val(OPT_D, D_AGCOUNT));
 				usage();
 			}
 		} else
-			logagno = (xfs_agnumber_t)(
-					get_conf_val(OPT_D, D_AGCOUNT) / 2);
+			set_conf_val(OPT_L, L_AGNUM, (xfs_agnumber_t)(
+					get_conf_val(OPT_D, D_AGCOUNT) / 2));
 
-		logstart = XFS_AGB_TO_FSB(mp, logagno, libxfs_prealloc_blocks(mp));
+		logstart = XFS_AGB_TO_FSB(mp, get_conf_val(OPT_L, L_AGNUM),
+					  libxfs_prealloc_blocks(mp));
 		/*
 		 * Align the logstart at stripe unit boundary.
 		 */
-		if (lsunit) {
+		if (get_conf_val(OPT_L, L_SUNIT)) {
 			logstart = fixup_internal_log_stripe(mp,
 					lsflag, logstart,
-					get_conf_val(OPT_D, D_AGSIZE), lsunit,
+					get_conf_val(OPT_D, D_AGSIZE),
+					get_conf_val(OPT_L, L_SUNIT),
 					&logblocks,
 					get_conf_val(OPT_B, B_LOG), &lalign);
 		} else if (get_conf_val(OPT_D, D_SUNIT)) {
@@ -3101,8 +3108,9 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		}
 	} else {
 		logstart = 0;
-		if (lsunit)
-			fixup_log_stripe_unit(lsflag, lsunit,
+		if (get_conf_val(OPT_L, L_SUNIT))
+			fixup_log_stripe_unit(lsflag,
+					      get_conf_val(OPT_L, L_SUNIT),
 					&logblocks, get_conf_val(OPT_B, B_LOG));
 	}
 	validate_log_size(logblocks, get_conf_val(OPT_B, B_LOG), min_logblocks);
@@ -3134,7 +3142,9 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 			sb_feat.dir_version, dirblocksize, sb_feat.nci,
 				sb_feat.dirftype,
 			logfile, 1 << get_conf_val(OPT_B, B_LOG), logblocks,
-			sb_feat.log_version, "", lsectorsize, lsunit,
+			sb_feat.log_version, "",
+			get_conf_val(OPT_L, L_SECTSIZE),
+			get_conf_val(OPT_L, L_SUNIT),
 				sb_feat.lazy_sb_counters,
 			rtfile, rtextblocks << get_conf_val(OPT_B, B_LOG),
 			rtblocks, rtextents);
@@ -3175,7 +3185,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	sbp->sb_ifree = 0;
 	sbp->sb_fdblocks = dblocks -
 		get_conf_val(OPT_D, D_AGCOUNT) * libxfs_prealloc_blocks(mp) -
-		(loginternal ? logblocks : 0);
+		(get_conf_val(OPT_L, L_INTERNAL) ? logblocks : 0);
 	sbp->sb_frextents = 0;	/* will do a free later */
 	sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0;
 	sbp->sb_qflags = 0;
@@ -3183,8 +3193,11 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	sbp->sb_width = get_conf_val(OPT_D, D_SWIDTH);
 	sbp->sb_dirblklog = dirblocklog - get_conf_val(OPT_B, B_LOG);
 	if (sb_feat.log_version == 2) {	/* This is stored in bytes */
-		lsunit = (lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, lsunit);
-		sbp->sb_logsunit = lsunit;
+		set_conf_val(OPT_L, L_SUNIT,
+			     (get_conf_val(OPT_L, L_SUNIT) == 0) ?
+			     1 : XFS_FSB_TO_B(mp,
+					      get_conf_val(OPT_L, L_SUNIT)));
+		sbp->sb_logsunit = get_conf_val(OPT_L, L_SUNIT);
 	} else
 		sbp->sb_logsunit = 0;
 	if (sb_feat.inode_align) {
@@ -3196,10 +3209,11 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		sb_feat.inode_align = sbp->sb_inoalignmt != 0;
 	} else
 		sbp->sb_inoalignmt = 0;
-	if (lsectorsize != BBSIZE ||
+	if (get_conf_val(OPT_L, L_SECTSIZE) != BBSIZE ||
 	    get_conf_val(OPT_D, D_SECTSIZE) != BBSIZE) {
-		sbp->sb_logsectlog = (__uint8_t)lsectorlog;
-		sbp->sb_logsectsize = (__uint16_t)lsectorsize;
+		sbp->sb_logsectlog = (__uint8_t)get_conf_val(OPT_L, L_SECTLOG);
+		sbp->sb_logsectsize =
+			(__uint16_t)get_conf_val(OPT_L, L_SECTSIZE);
 	} else {
 		sbp->sb_logsectlog = 0;
 		sbp->sb_logsectsize = 0;
@@ -3207,7 +3221,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 
 	sb_set_features(&mp->m_sb, &sb_feat,
 			get_conf_val(OPT_D, D_SECTSIZE),
-			lsectorsize,
+			get_conf_val(OPT_L, L_SECTSIZE),
 			get_conf_val(OPT_D, D_SUNIT));
 
 	if (force_overwrite)
@@ -3269,7 +3283,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	libxfs_log_clear(mp->m_logdev_targp, NULL,
 		XFS_FSB_TO_DADDR(mp, logstart),
 		(xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks),
-		&sbp->sb_uuid, sb_feat.log_version, lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
+		&sbp->sb_uuid, sb_feat.log_version,
+		get_conf_val(OPT_L, L_SUNIT), XLOG_FMT, XLOG_INIT_CYCLE, false);
 
 	mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0);
 	if (mp == NULL) {
@@ -3346,7 +3361,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 		if (xfs_sb_version_hascrc(&mp->m_sb))
 			platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid);
 
-		if (loginternal && agno == logagno) {
+		if (get_conf_val(OPT_L, L_INTERNAL) &&
+		    agno == get_conf_val(OPT_L, L_AGNUM)) {
 			be32_add_cpu(&agf->agf_freeblks, -logblocks);
 			agf->agf_longest =
 				cpu_to_be32(get_conf_val(OPT_D, D_AGSIZE) -
@@ -3420,7 +3436,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 
 		arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
 		arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
-		if (loginternal && agno == logagno) {
+		if (get_conf_val(OPT_L, L_INTERNAL) &&
+		    agno == get_conf_val(OPT_L, L_AGNUM)) {
 			if (lalign) {
 				/*
 				 * Have to insert two records
@@ -3471,7 +3488,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 
 		arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
 		arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
-		if (loginternal && agno == logagno) {
+		if (get_conf_val(OPT_L, L_INTERNAL) &&
+		    agno == get_conf_val(OPT_L, L_AGNUM)) {
 			if (lalign) {
 				arec->ar_blockcount = cpu_to_be32(
 					XFS_FSB_TO_AGBNO(mp, logstart) -
@@ -3606,7 +3624,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 			}
 
 			/* account for the log space */
-			if (loginternal && agno == logagno) {
+			if (get_conf_val(OPT_L, L_INTERNAL) && agno ==
+			    get_conf_val(OPT_L, L_AGNUM)) {
 				rrec = XFS_RMAP_REC_ADDR(block,
 					be16_to_cpu(block->bb_numrecs) + 1);
 				rrec->rm_startblock = cpu_to_be32(
-- 
2.1.4


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

* [PATCH 11/12] mkfs: replace variables with opts table: -n options
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (9 preceding siblings ...)
  2017-04-23 18:55 ` [PATCH 10/12] mkfs: replace variables with opts table: -l options Jan Tulak
@ 2017-04-23 18:55 ` Jan Tulak
  2017-04-23 18:55 ` [PATCH 12/12] mkfs: replace variables with opts table: -r options Jan Tulak
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:55 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Remove variables that can be replaced with a direct access to the opts table,
so we have it all in a single place, acessible from anywhere.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 40 +++++++++++++++++++---------------------
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 7d85471..52591b9 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1496,8 +1496,6 @@ main(
 	uint64_t		dasize;
 	xfs_rfsblock_t		dblocks;
 	char			*dfile;
-	uint64_t		dirblocklog;
-	uint64_t		dirblocksize;
 	bool			force_overwrite;
 	struct fsxattr		fsx;
 	bool			ilflag;
@@ -1577,7 +1575,6 @@ main(
 	liflag = laflag = lsflag = lsuflag = lsunitflag = ldflag = lvflag = false;
 	logblocks = rtblocks = rtextblocks = 0;
 	Nflag = nlflag = nsflag = nvflag = false;
-	dirblocklog = dirblocksize = 0;
 	qflag = false;
 	dfile = logfile = rtfile = NULL;
 	protofile = NULL;
@@ -1943,26 +1940,23 @@ main(
 				char	**subopts =
 						(char **)opts[OPT_N].subopts;
 				char	*value;
+				uint64_t tmp;
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case N_LOG:
-					dirblocklog = parse_conf_val(OPT_N,
+					tmp = parse_conf_val(OPT_N,
 								     N_LOG,
 								     value);
-					dirblocksize = 1 << dirblocklog;
+					set_conf_val(OPT_N, N_SIZE, 1 << tmp);
 					nlflag = 1;
-					set_conf_val(OPT_N, N_SIZE,
-						     dirblocksize);
 					break;
 				case N_SIZE:
-					dirblocksize = parse_conf_val(OPT_N,
+					tmp = parse_conf_val(OPT_N,
 								      N_SIZE,
 								      value);
-					dirblocklog =
-						libxfs_highbit32(dirblocksize);
-					nsflag = 1;
 					set_conf_val(OPT_N, N_LOG,
-						     dirblocklog);
+						     libxfs_highbit32(tmp));
+					nsflag = 1;
 					break;
 				case N_VERSION:
 					value = getstr(value, &opts[OPT_N],
@@ -2360,18 +2354,19 @@ _("rmapbt not supported with realtime devices\n"));
 	}
 
 	if (nsflag || nlflag) {
-		if (dirblocksize < get_conf_val(OPT_B, B_SIZE) ||
-					dirblocksize > XFS_MAX_BLOCKSIZE) {
+		if (get_conf_val(OPT_N, N_SIZE) <
+		    get_conf_val(OPT_B, B_SIZE) ||
+		    get_conf_val(OPT_N, N_SIZE) > XFS_MAX_BLOCKSIZE) {
 			fprintf(stderr, _("illegal directory block size %"PRIu64"\n"),
-				dirblocksize);
+				get_conf_val(OPT_N, N_SIZE));
 			usage();
 		}
 	} else {
 		if (get_conf_val(OPT_B, B_SIZE) < (1 << XFS_MIN_REC_DIRSIZE))
-			dirblocklog = XFS_MIN_REC_DIRSIZE;
+			set_conf_val(OPT_N, N_LOG, XFS_MIN_REC_DIRSIZE);
 		else
-			dirblocklog = get_conf_val(OPT_B, B_LOG);
-		dirblocksize = 1 << dirblocklog;
+			set_conf_val(OPT_N, N_LOG, get_conf_val(OPT_B, B_LOG));
+		set_conf_val(OPT_N, N_SIZE, 1 << get_conf_val(OPT_N, N_LOG));
 	}
 
 
@@ -2949,7 +2944,8 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
 				   sb_feat.crcs_enabled, sb_feat.dir_version,
 				   get_conf_val(OPT_D, D_SECTLOG),
 				   get_conf_val(OPT_B, B_LOG),
-				   get_conf_val(OPT_I, I_LOG), dirblocklog,
+				   get_conf_val(OPT_I, I_LOG),
+				   get_conf_val(OPT_N, N_LOG),
 				   sb_feat.log_version,
 				   get_conf_val(OPT_L, L_SUNIT),
 				   sb_feat.finobt,
@@ -3139,7 +3135,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 			get_conf_val(OPT_I, I_MAXPCT),
 			"", get_conf_val(OPT_D, D_SUNIT),
 			get_conf_val(OPT_D, D_SWIDTH),
-			sb_feat.dir_version, dirblocksize, sb_feat.nci,
+			sb_feat.dir_version,
+			get_conf_val(OPT_N, N_SIZE), sb_feat.nci,
 				sb_feat.dirftype,
 			logfile, 1 << get_conf_val(OPT_B, B_LOG), logblocks,
 			sb_feat.log_version, "",
@@ -3191,7 +3188,8 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
 	sbp->sb_qflags = 0;
 	sbp->sb_unit = get_conf_val(OPT_D, D_SUNIT);
 	sbp->sb_width = get_conf_val(OPT_D, D_SWIDTH);
-	sbp->sb_dirblklog = dirblocklog - get_conf_val(OPT_B, B_LOG);
+	sbp->sb_dirblklog = get_conf_val(OPT_N, N_LOG) -
+		get_conf_val(OPT_B, B_LOG);
 	if (sb_feat.log_version == 2) {	/* This is stored in bytes */
 		set_conf_val(OPT_L, L_SUNIT,
 			     (get_conf_val(OPT_L, L_SUNIT) == 0) ?
-- 
2.1.4


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

* [PATCH 12/12] mkfs: replace variables with opts table: -r options
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (10 preceding siblings ...)
  2017-04-23 18:55 ` [PATCH 11/12] mkfs: replace variables with opts table: -n options Jan Tulak
@ 2017-04-23 18:55 ` Jan Tulak
  2017-04-25  2:52 ` [PATCH 00/12] mkfs: save user input into opts table Luis R. Rodriguez
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-23 18:55 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Remove variables that can be replaced with a direct access to the opts table,
so we have it all in a single place, acessible from anywhere.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 70 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 36 insertions(+), 34 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 52591b9..ef40c9a 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1521,7 +1521,6 @@ main(
 	xfs_mount_t		mbuf;
 	xfs_extlen_t		nbmblocks;
 	bool			nlflag;
-	bool			norsflag;
 	xfs_alloc_rec_t		*nrec;
 	bool			nsflag;
 	bool			nvflag;
@@ -1532,10 +1531,8 @@ main(
 	char			*protostring;
 	bool			qflag;
 	xfs_rfsblock_t		rtblocks;
-	uint64_t		rtbytes;
 	xfs_extlen_t		rtextblocks;
 	xfs_rtblock_t		rtextents;
-	uint64_t		rtextbytes;
 	char			*rtfile;
 	xfs_sb_t		*sbp;
 	uint64_t		sector_mask;
@@ -1578,9 +1575,7 @@ main(
 	qflag = false;
 	dfile = logfile = rtfile = NULL;
 	protofile = NULL;
-	rtbytes = rtextbytes = 0;
 	lalign = 0;
-	norsflag = false;
 	force_overwrite = false;
 	worst_freelist = 0;
 	memset(&fsx, 0, sizeof(fsx));
@@ -2007,9 +2002,8 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case R_EXTSIZE:
-					rtextbytes = parse_conf_val(OPT_R,
-								    R_EXTSIZE,
-								    value);
+					parse_conf_val(OPT_R, R_EXTSIZE,
+						       value);
 					break;
 				case R_FILE:
 					xi.risfile = parse_conf_val(OPT_R,
@@ -2024,13 +2018,11 @@ main(
 					set_conf_val(OPT_R, R_DEV, 1);
 					break;
 				case R_SIZE:
-					rtbytes = parse_conf_val(OPT_R, R_SIZE,
-								 value);
+					parse_conf_val(OPT_R, R_SIZE, value);
 					break;
 				case R_NOALIGN:
-					norsflag = parse_conf_val(OPT_R,
-								  R_NOALIGN,
-								  value);
+					parse_conf_val(OPT_R, R_NOALIGN,
+						       value);
 					break;
 				default:
 					unknown('r', value);
@@ -2173,7 +2165,10 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 				  !xi.logname, Nflag ? NULL : &xi.lcreat,
 				  force_overwrite, "l");
 	if (xi.rtname)
-		check_device_type(xi.rtname, &xi.risfile, !rtbytes, !xi.rtname,
+		check_device_type(xi.rtname,
+				  &xi.risfile,
+				  !get_conf_val(OPT_R, R_SIZE),
+				  !xi.rtname,
 				  Nflag ? NULL : &xi.rcreat,
 				  force_overwrite, "r");
 	if (xi.disfile || xi.lisfile || xi.risfile)
@@ -2422,33 +2417,36 @@ _("rmapbt not supported with realtime devices\n"));
 				(uint64_t)(logblocks <<
 					   get_conf_val(OPT_B, B_LOG)));
 	}
-	if (rtbytes) {
-		if (rtbytes % XFS_MIN_BLOCKSIZE) {
+	if (get_conf_val(OPT_R, R_SIZE)) {
+		if (get_conf_val(OPT_R, R_SIZE) % XFS_MIN_BLOCKSIZE) {
 			fprintf(stderr,
 			_("illegal rt length %"PRIu64", not a multiple of %d\n"),
-				rtbytes, XFS_MIN_BLOCKSIZE);
+				get_conf_val(OPT_R, R_SIZE), XFS_MIN_BLOCKSIZE);
 			usage();
 		}
-		rtblocks = (xfs_rfsblock_t)(rtbytes >>
+		rtblocks = (xfs_rfsblock_t)(get_conf_val(OPT_R, R_SIZE) >>
 					    get_conf_val(OPT_B, B_LOG));
-		if (rtbytes % get_conf_val(OPT_B, B_SIZE))
+		if (get_conf_val(OPT_R, R_SIZE) % get_conf_val(OPT_B, B_SIZE))
 			fprintf(stderr,
 	_("warning: rt length %"PRIu64" not a multiple of %"PRIu64", truncated to %"PRIu64"\n"),
-				rtbytes, get_conf_val(OPT_B, B_SIZE),
+				get_conf_val(OPT_R, R_SIZE),
+				get_conf_val(OPT_B, B_SIZE),
 				(uint64_t)(rtblocks <<
 					   get_conf_val(OPT_B, B_LOG)));
 	}
 	/*
 	 * If specified, check rt extent size against its constraints.
 	 */
-	if (rtextbytes) {
-		if (rtextbytes % get_conf_val(OPT_B, B_SIZE)) {
+	if (get_conf_val(OPT_R, R_EXTSIZE)) {
+		if (get_conf_val(OPT_R, R_EXTSIZE) %
+		    get_conf_val(OPT_B, B_SIZE)) {
 			fprintf(stderr,
 		_("illegal rt extent size %"PRIu64", not a multiple of %"PRIu64"\n"),
-				rtextbytes, get_conf_val(OPT_B, B_SIZE));
+				get_conf_val(OPT_R, R_EXTSIZE),
+				get_conf_val(OPT_B, B_SIZE));
 			usage();
 		}
-		rtextblocks = (xfs_extlen_t)(rtextbytes >>
+		rtextblocks = (xfs_extlen_t)(get_conf_val(OPT_R, R_EXTSIZE) >>
 					     get_conf_val(OPT_B, B_LOG));
 	} else {
 		/*
@@ -2457,20 +2455,23 @@ _("rmapbt not supported with realtime devices\n"));
 		 * to the stripe width.
 		 */
 		uint64_t	rswidth;
-		uint64_t	rtextbytes;
 
-		if (!norsflag && !xi.risfile && !(!rtbytes && xi.disfile))
+		if (!get_conf_val(OPT_R, R_NOALIGN) && !xi.risfile &&
+		    !(!get_conf_val(OPT_R, R_SIZE) && xi.disfile))
 			rswidth = ft.rtswidth;
 		else
 			rswidth = 0;
 
 		/* check that rswidth is a multiple of fs B_SIZE */
-		if (!norsflag && rswidth &&
+		if (!get_conf_val(OPT_R, R_NOALIGN) && rswidth &&
 		    !(BBTOB(rswidth) % get_conf_val(OPT_B, B_SIZE))) {
 			rswidth = DTOBT(rswidth);
-			rtextbytes = rswidth << get_conf_val(OPT_B, B_LOG);
-			if (XFS_MIN_RTEXTSIZE <= rtextbytes &&
-			    (rtextbytes <= XFS_MAX_RTEXTSIZE)) {
+			set_conf_val(OPT_R, R_EXTSIZE,
+				     rswidth << get_conf_val(OPT_B, B_LOG));
+			if (XFS_MIN_RTEXTSIZE <=
+			    get_conf_val(OPT_R, R_EXTSIZE) &&
+			    (get_conf_val(OPT_R, R_EXTSIZE) <=
+			     XFS_MAX_RTEXTSIZE)) {
 				rtextblocks = rswidth;
 			}
 		}
@@ -2639,7 +2640,7 @@ reported by the device (%u).\n"),
 reported by the device (%u).\n"),
 			get_conf_val(OPT_L, L_SECTSIZE), xi.lbsize);
 	}
-	if (rtbytes && xi.rtsize > 0 &&
+	if (get_conf_val(OPT_R, R_SIZE) && xi.rtsize > 0 &&
 	    xi.rtbsize > get_conf_val(OPT_D, D_SECTSIZE)) {
 		fprintf(stderr, _(
 "Warning: the realtime subvolume sector size %"PRIu64" is less than the sector size\n\
@@ -2647,16 +2648,17 @@ reported by the device (%u).\n"),
 			get_conf_val(OPT_D, D_SECTSIZE), xi.rtbsize);
 	}
 
-	if (rtbytes && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
+	if (get_conf_val(OPT_R, R_SIZE) && xi.rtsize > 0 &&
+	    rtblocks > DTOBT(xi.rtsize)) {
 		fprintf(stderr,
 			_("size %s specified for rt subvolume is too large, "
 			"maximum is %"PRIu64" blocks\n"),
 			get_conf_raw(OPT_R, R_SIZE),
 			(uint64_t)DTOBT(xi.rtsize));
 		usage();
-	} else if (!rtbytes && xi.rtsize > 0)
+	} else if (!get_conf_val(OPT_R, R_SIZE) && xi.rtsize > 0)
 		rtblocks = DTOBT(xi.rtsize);
-	else if (rtbytes && !xi.rtdev) {
+	else if (get_conf_val(OPT_R, R_SIZE) && !xi.rtdev) {
 		fprintf(stderr,
 			_("size specified for non-existent rt subvolume\n"));
 		usage();
-- 
2.1.4


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

* Re: [PATCH 00/12] mkfs: save user input into opts table
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (11 preceding siblings ...)
  2017-04-23 18:55 ` [PATCH 12/12] mkfs: replace variables with opts table: -r options Jan Tulak
@ 2017-04-25  2:52 ` Luis R. Rodriguez
  2017-04-25 16:20 ` Eric Sandeen
  2017-06-28 16:18 ` Luis R. Rodriguez
  14 siblings, 0 replies; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-25  2:52 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Sun, Apr 23, 2017 at 08:54:51PM +0200, Jan Tulak wrote:
> Hi guys,
> 
> I decided to split my big patchset into more smaller ones. So, this is the
> first set. It adds set/get functions similar to Dave's suggestion, to save and
> retrieve user values to and from the big opts table and prepares the ground for
> future patches.
> 
> 
> It is a mix of patches I already submitted and new ones:
> Patches 2, 3, 4, 5 are just slightly modified to fix their issues.
> Other patches are new.
> 
> The last few patches could be merged into one, because it should only
> substitute variables for get/set calls, but because there are so many
> places where the changes occurs, I split them into smaller chunks,
> making it (hopefully) easier for you to review.
> 
> This patchset requires my two previous uint patches.
> Git tree: https://github.com/jtulak/xfsprogs-dev/tree/setters

Consider patches 1-3 Reviewed-by: Luis R. Rodriguez <mcgrof@kernel.org>
Feedback will be provided on patch 4.

  Luis

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-23 18:54 ` [PATCH 04/12] mkfs: merge tables for opts parsing into one table Jan Tulak
@ 2017-04-25  3:04   ` Luis R. Rodriguez
  2017-04-25  7:45     ` Jan Tulak
  2017-04-25 21:45   ` Eric Sandeen
  1 sibling, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-25  3:04 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Sun, Apr 23, 2017 at 08:54:55PM +0200, Jan Tulak wrote:
> Merge separate instances of opt_params into one indexable table. Git
> makes this patch looks a bit more complicated, but it does not change
> values or structure of anything else. It only moves all the "struct
> opt_params dopts = {...}", changes indentation for these substructures
> and replaces their usage (dopts -> opts[OPT_D]).
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> ---
>  mkfs/xfs_mkfs.c | 1316 +++++++++++++++++++++++++++++--------------------------
>  1 file changed, 683 insertions(+), 633 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 7a72b11..513e106 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -42,6 +42,7 @@ static int  ispow2(unsigned int i);
>  uint64_t		blocksize;
>  uint64_t		sectorsize;
>  
> +#define MAX_OPTS	16

This is fragile, every time a new opt is added this needs to be updated
and so is the index, and we should be pedantic over not going out of bounds.
We could instead use a flexible array and compute the max opts at run time
as a global. This way the max opts is always updated automatically.

>  #define MAX_SUBOPTS	16
>  #define SUBOPT_NEEDS_VAL	(-1LL)
>  #define MAX_CONFLICTS	8
> @@ -60,6 +61,10 @@ uint64_t		sectorsize;
>   *
>   * Description of the structure members follows:
>   *
> + * index MANDATORY
> + *   An integer denoting the position of the specific option in opts array,
> + *   counting from 0 up to MAX_OPTS.
> + *
>   * name MANDATORY
>   *   Name is a single char, e.g., for '-d file', name is 'd'.
>   *
> @@ -132,6 +137,7 @@ uint64_t		sectorsize;
>   * !!! END OF NOTE ===========================================================
>   */
>  struct opt_params {
> +	int		index;


>  	const char	name;
>  	const char	*subopts[MAX_SUBOPTS];
>  
> @@ -147,584 +153,592 @@ struct opt_params {
>  		uint64_t	flagval;
>  		const char	*raw_input;
>  	}		subopt_params[MAX_SUBOPTS];
> -};
> -
> -struct opt_params bopts = {
> -	.name = 'b',
> -	.subopts = {
> +} 

Do we really need to mesh the struct with the opts below ? I think it would
make your patch easier to read if we kept the old tradition of splitting it,
its not clear to me what the advantage is.

> opts[MAX_OPTS] = {
> +#define OPT_B	0

I find these defines blinding on reading the struct declaration, we could
instead just stuff them into an enum, which would also enable us to shift all
the documentation into the header of the enum using whatever doc format we use.

Below is a simple demo using a basic limited opt just to be clear about what I
am suggesting, modulo, I think we want max_opts to be a global.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

enum opt_idx {
	OPT_ZERO = 0,
	OPT_ONE,
	OPT_TWO,
};

struct opt {
	unsigned int idx;
	unsigned int val;
};

struct opt opts[] = {
	{
		.idx = OPT_ZERO,
		.val = 0,
	},
	{
		.idx = OPT_ONE,
		.val = 1,
	},
	{
		.idx = OPT_TWO,
		.val = 2,
	},
};

int main(int argc, char *argv[])
{
	unsigned int max_opts = ARRAY_SIZE(opts);
	unsigned int i;

	printf("Max size: %lu\n", max_opts);

	for (i = 0; i < max_opts; i++) {
		printf("Val: %lu\n", opts[i].val);
	}

	return 0;
}

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

* Re: [PATCH 05/12] mkfs: extend opt_params with a value field
  2017-04-23 18:54 ` [PATCH 05/12] mkfs: extend opt_params with a value field Jan Tulak
@ 2017-04-25  3:13   ` Luis R. Rodriguez
  2017-04-25  8:04     ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-25  3:13 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Sun, Apr 23, 2017 at 08:54:56PM +0200, Jan Tulak wrote:
> Add a new field int opt_params - value,

Agreed.

> which is filled with user input.

It sounds to me its more than that, its the default value which will be used should
not user input for the option be specified, and if user input value is provided it
will be the passed user input value. If the final value for the respective option.

?

> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> ---
>  mkfs/xfs_mkfs.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 513e106..c2ffd91 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -128,6 +128,12 @@ uint64_t		sectorsize;
>   *     Filled raw string from the user, so we never lose that information e.g.
>   *     to print it back in case of an issue.
>   *
> + *   value OPTIONAL
> + *     The value that is to be used if the given subopt is not specified at all.

It seems to be more than that ?

> + *     This is filled with user input 

This is a bit confusing, isn't it first the default value should no user input
value be passed ? And finally if user input value is passed only then will this
be that value ?

> and anything you write here now is
> + *     overwritten if user specifies the subopt. (If the user input is a string
> + *     and not a number, this value is set to a positive non-zero number.)
> + *
>   * !!! NOTE ==================================================================
>   *
>   * If you are adding a new option, or changing an existing one,
> @@ -152,6 +158,7 @@ struct opt_params {
>  		uint64_t	maxval;
>  		uint64_t	flagval;
>  		const char	*raw_input;
> +		uint64_t	value;
>  	}		subopt_params[MAX_SUBOPTS];
>  } opts[MAX_OPTS] = {
>  #define OPT_B	0

It would seem rather unfair to define this this but not use it in the patch ?

  Luis

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

* Re: [PATCH 06/12] mkfs: create get/set functions for opts table
  2017-04-23 18:54 ` [PATCH 06/12] mkfs: create get/set functions for opts table Jan Tulak
@ 2017-04-25  3:40   ` Luis R. Rodriguez
  2017-04-25  8:11     ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-25  3:40 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Sun, Apr 23, 2017 at 08:54:57PM +0200, Jan Tulak wrote:
> Add functions that can be used to get/set values to opts table.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> 
> ---
>  mkfs/xfs_mkfs.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index c2ffd91..4caf93c 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -786,6 +786,38 @@ get_conf_raw(int opt, int subopt)
>  	return opts[opt].subopt_params[subopt].raw_input;
>  }
>  
> +static uint64_t getnum(const char *str, struct opt_params *opts, int index);

Why not just move getnum() above here. Forward declarations IMHO should not be
needed unless we have odd inclusion issues and I don't think that's the case
here ?

> +
> +/*
> + * Get and set values to the opts table.
> + */
> +static inline uint64_t
> +get_conf_val(int opt, int subopt)
> +{
> +	return opts[opt].subopt_params[subopt].value;
> +}
> +
> +static void
> +set_conf_val(int opt, int subopt, uint64_t val)
> +{
> +	struct subopt_param *sp = &opts[opt].subopt_params[subopt];
> +
> +	sp->value = val;
> +}
> +
> +/*
> + * A wrapper for getnum and set_conf_val.
> + */
> +static inline uint64_t
> +parse_conf_val(int opt, int subopt, char *value)
> +{
> +	uint64_t num = getnum(value, &opts[opt], subopt);
> +
> +	set_conf_val(opt, subopt, num);
> +	return num;
> +}

Very nice thanks!

  Luis

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

* Re: [PATCH 07/12] mkfs: save user input values into opts
  2017-04-23 18:54 ` [PATCH 07/12] mkfs: save user input values into opts Jan Tulak
@ 2017-04-25  5:19   ` Luis R. Rodriguez
  2017-04-25  8:16     ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-25  5:19 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Sun, Apr 23, 2017 at 08:54:58PM +0200, Jan Tulak wrote:
> Save the parsed values from users into the opts table.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> ---
>  mkfs/xfs_mkfs.c | 260 +++++++++++++++++++++++++++++++++++---------------------
>  1 file changed, 165 insertions(+), 95 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 4caf93c..362c9b4 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -1636,16 +1636,19 @@ main(
>  
>  				switch (getsubopt(&p, subopts, &value)) {
>  				case B_LOG:
> -					blocklog = getnum(value, &opts[OPT_B],
> -								B_LOG);
> +					blocklog = parse_conf_val(OPT_B, B_LOG,
> +								  value);
>  					blocksize = 1 << blocklog;
>  					blflag = 1;
> +					set_conf_val(OPT_B, B_SIZE, blocksize);
>  					break;
>  				case B_SIZE:
> -					blocksize = getnum(value, &opts[OPT_B],
> -							   B_SIZE);
> +					blocksize = parse_conf_val(OPT_B,
> +								   B_SIZE,
> +								   value);
>  					blocklog = libxfs_highbit32(blocksize);
>  					bsflag = 1;
> +					set_conf_val(OPT_B, B_LOG, blocklog);
>  					break;
>  				default:
>  					unknown('b', value);

This still means that users of parse_conf_val() must copy the same code
in each case in the above to handle collateral values: if blocklog was
passed we update blocklog *and* blocksize *and* bsflag. Likewise if blocksize
was passed we must update blocksize *and* blocklog *and* blflag. What I had
done on the mkfs.xfs.conf series is put all this functionality into a helper,
and to do this move all needed vars into a struct. You are moving all possible
user params to a option specific table, however the collateral parameters are
kept inside main().

I'll need to do the same again: move the logic above to a helper and move
collateral parameters to a struct, or this could be done in your series by
having parse_conf_val() handle all the needed logic provided say an extra
struct param is passed -- or though some other means.

Duplicating the functionality I'm sure is not desirable, how we handle this
subjective so I'll leave it up to you to advise how you'd like to proceed,
but let me know if the above consideration is clear.

  Luis

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

* Re: [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options
  2017-04-23 18:54 ` [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options Jan Tulak
@ 2017-04-25  5:27   ` Luis R. Rodriguez
  2017-04-25  5:30     ` Luis R. Rodriguez
  2017-04-25  8:37     ` Jan Tulak
  0 siblings, 2 replies; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-25  5:27 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Sun, Apr 23, 2017 at 08:54:59PM +0200, Jan Tulak wrote:
> Remove variables that can be replaced with a direct access to the opts table,
> so we have it all in a single place, acessible from anywhere.
> 
> In future, we can remove some passing of values forth and back, but now limit
> the changes to simple replacement without a change in the logic.

What do you mean passing of values here, as an example with bopts ?

> This is first of multiple similar patches that do the same, but for other
> options.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> ---
>  mkfs/xfs_mkfs.c | 814 ++++++++++++++++++++++++++++++++++----------------------
>  1 file changed, 503 insertions(+), 311 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 362c9b4..6857c30 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -1485,15 +1480,12 @@ main(
>  	int			argc,
>  	char			**argv)
>  {
> -	uint64_t		agcount;
>  	xfs_agf_t		*agf;
>  	xfs_agi_t		*agi;
>  	xfs_agnumber_t		agno;
> -	uint64_t		agsize;
>  	xfs_alloc_rec_t		*arec;
>  	struct xfs_btree_block	*block;
>  	bool			blflag;

Note: blflag

> -	uint64_t		blocklog;
>  	bool			bsflag;

Note: bsflag

>  	memset(&fsx, 0, sizeof(fsx));
> @@ -1629,6 +1613,7 @@ main(
>  			break;
>  		case 'b':
>  			p = optarg;
> +			uint64_t tmp;
>  			while (*p != '\0') {
>  				char	**subopts =
>  						(char **)opts[OPT_B].subopts;
> @@ -1636,19 +1621,17 @@ main(
>  
>  				switch (getsubopt(&p, subopts, &value)) {
>  				case B_LOG:
> -					blocklog = parse_conf_val(OPT_B, B_LOG,
> -								  value);
> -					blocksize = 1 << blocklog;
> +					tmp = parse_conf_val(OPT_B, B_LOG,
> +							     value);
> +					set_conf_val(OPT_B, B_SIZE, 1 << tmp);
>  					blflag = 1;

This is a collateral variable set when blog is set. If we have to parse the
blog again, it means similar code would be needed.

> -					set_conf_val(OPT_B, B_SIZE, blocksize);
>  					break;
>  				case B_SIZE:
> -					blocksize = parse_conf_val(OPT_B,
> -								   B_SIZE,
> -								   value);
> -					blocklog = libxfs_highbit32(blocksize);
> +					tmp = parse_conf_val(OPT_B, B_SIZE,
> +							     value);
> +					set_conf_val(OPT_B, B_LOG,
> +						libxfs_highbit32(tmp));
>  					bsflag = 1;

Likewise for bsflag.

> -					set_conf_val(OPT_B, B_LOG, blocklog);
>  					break;
>  				default:
>  					unknown('b', value);

What I'm questioning is whether or not it makes sense instead for parse_conf_val()
to return void and do all this meddling for us, this would require stuffing any
collateral variables into a struct and passing that to parse_conf_val and using
it on main() as well.

  Luis

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

* Re: [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options
  2017-04-25  5:27   ` Luis R. Rodriguez
@ 2017-04-25  5:30     ` Luis R. Rodriguez
  2017-04-25  8:37     ` Jan Tulak
  1 sibling, 0 replies; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-25  5:30 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Jan Tulak, linux-xfs

On Tue, Apr 25, 2017 at 07:27:21AM +0200, Luis R. Rodriguez wrote:
> On Sun, Apr 23, 2017 at 08:54:59PM +0200, Jan Tulak wrote:
> > Remove variables that can be replaced with a direct access to the opts table,
> > so we have it all in a single place, acessible from anywhere.
> > 
> > In future, we can remove some passing of values forth and back, but now limit
> > the changes to simple replacement without a change in the logic.

FWIW, patches 9-12 go reviewed with the same topical concern as in this patch.

  Luis

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-25  3:04   ` Luis R. Rodriguez
@ 2017-04-25  7:45     ` Jan Tulak
  2017-04-25 13:28       ` Eric Sandeen
  2017-04-26  8:21       ` Luis R. Rodriguez
  0 siblings, 2 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-25  7:45 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Tue, Apr 25, 2017 at 5:04 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Sun, Apr 23, 2017 at 08:54:55PM +0200, Jan Tulak wrote:
>> Merge separate instances of opt_params into one indexable table. Git
>> makes this patch looks a bit more complicated, but it does not change
>> values or structure of anything else. It only moves all the "struct
>> opt_params dopts = {...}", changes indentation for these substructures
>> and replaces their usage (dopts -> opts[OPT_D]).
>>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>> ---
>>  mkfs/xfs_mkfs.c | 1316 +++++++++++++++++++++++++++++--------------------------
>>  1 file changed, 683 insertions(+), 633 deletions(-)
>>
>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>> index 7a72b11..513e106 100644
>> --- a/mkfs/xfs_mkfs.c
>> +++ b/mkfs/xfs_mkfs.c
>> @@ -42,6 +42,7 @@ static int  ispow2(unsigned int i);
>>  uint64_t             blocksize;
>>  uint64_t             sectorsize;
>>
>> +#define MAX_OPTS     16
>
> This is fragile, every time a new opt is added this needs to be updated
> and so is the index, and we should be pedantic over not going out of bounds.
> We could instead use a flexible array and compute the max opts at run time
> as a global. This way the max opts is always updated automatically.


Mmm, that is a good idea and I see no issue with it. But I'm not sure
if it is worth of rewriting this patch as we already use MAX_SUBOPTS
anyway. Rather I see it as a standalone patch in the next set. What do
you think?

>
>>  #define MAX_SUBOPTS  16
>>  #define SUBOPT_NEEDS_VAL     (-1LL)
>>  #define MAX_CONFLICTS        8
>> @@ -60,6 +61,10 @@ uint64_t           sectorsize;
>>   *
>>   * Description of the structure members follows:
>>   *
>> + * index MANDATORY
>> + *   An integer denoting the position of the specific option in opts array,
>> + *   counting from 0 up to MAX_OPTS.
>> + *
>>   * name MANDATORY
>>   *   Name is a single char, e.g., for '-d file', name is 'd'.
>>   *
>> @@ -132,6 +137,7 @@ uint64_t          sectorsize;
>>   * !!! END OF NOTE ===========================================================
>>   */
>>  struct opt_params {
>> +     int             index;
>
>
>>       const char      name;
>>       const char      *subopts[MAX_SUBOPTS];
>>
>> @@ -147,584 +153,592 @@ struct opt_params {
>>               uint64_t        flagval;
>>               const char      *raw_input;
>>       }               subopt_params[MAX_SUBOPTS];
>> -};
>> -
>> -struct opt_params bopts = {
>> -     .name = 'b',
>> -     .subopts = {
>> +}
>
> Do we really need to mesh the struct with the opts below ? I think it would
> make your patch easier to read if we kept the old tradition of splitting it,
> its not clear to me what the advantage is.
>
>> opts[MAX_OPTS] = {
>> +#define OPT_B        0
>
> I find these defines blinding on reading the struct declaration, we could
> instead just stuff them into an enum, which would also enable us to shift all
> the documentation into the header of the enum using whatever doc format we use.

The grouping is here to keep the style as it is with suboptions
index/string. However, all these defines (OPT_X and X_FOO) are
separated and moved into a single place later on in one patch anyway.
I just didn't include that patch in this set as I had to make the line
somewhere if I want to make multiple smaller and easier to review and
merge sets rather than the one big monster as before.

There is one point I'm not sure about, though. We have to restart the
counting for suboptions, like this:

enum subopts {
  B_size = 0,
  B_LOG,
  D_AGCOUNT = 0,
  D_...,
  L_xxx = 0,
  L_...,
}

I didn't found anywhere if it is a good practice or not. But again, I
just submitted it as it was with a note in my TODOs to find out more
out it and update the patch changing it later on.

Jan

>
> Below is a simple demo using a basic limited opt just to be clear about what I
> am suggesting, modulo, I think we want max_opts to be a global.
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <errno.h>
>
> #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
>
> enum opt_idx {
>         OPT_ZERO = 0,
>         OPT_ONE,
>         OPT_TWO,
> };
>
> struct opt {
>         unsigned int idx;
>         unsigned int val;
> };
>
> struct opt opts[] = {
>         {
>                 .idx = OPT_ZERO,
>                 .val = 0,
>         },
>         {
>                 .idx = OPT_ONE,
>                 .val = 1,
>         },
>         {
>                 .idx = OPT_TWO,
>                 .val = 2,
>         },
> };
>
> int main(int argc, char *argv[])
> {
>         unsigned int max_opts = ARRAY_SIZE(opts);
>         unsigned int i;
>
>         printf("Max size: %lu\n", max_opts);
>
>         for (i = 0; i < max_opts; i++) {
>                 printf("Val: %lu\n", opts[i].val);
>         }
>
>         return 0;
> }



-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 05/12] mkfs: extend opt_params with a value field
  2017-04-25  3:13   ` Luis R. Rodriguez
@ 2017-04-25  8:04     ` Jan Tulak
  2017-04-25  9:39       ` Jan Tulak
  2017-04-26  1:10       ` Luis R. Rodriguez
  0 siblings, 2 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-25  8:04 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Tue, Apr 25, 2017 at 5:13 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Sun, Apr 23, 2017 at 08:54:56PM +0200, Jan Tulak wrote:
>> Add a new field int opt_params - value,
>
> Agreed.
>
>> which is filled with user input.
>
> It sounds to me its more than that, its the default value which will be used should
> not user input for the option be specified, and if user input value is provided it
> will be the passed user input value. If the final value for the respective option.
>
> ?

Yes. I see I should make the description better, both here in commit
message and in the code too. It is the same logic as it was for the
old variables like agcount in main(). Initialize it with whatever you
want as the default for pure "mkfs.xfs /some/dev", but if the users
give us the specific option, we are going to overwrite it with their
value.

I don't see any use for remembering the defaults once it is clear that
user wants to use custom values instead. And copying the defaults from
some other field "if the user said nothing" sounds like a recipe for
bugs...

>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>> ---
>>  mkfs/xfs_mkfs.c | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>> index 513e106..c2ffd91 100644
>> --- a/mkfs/xfs_mkfs.c
>> +++ b/mkfs/xfs_mkfs.c
>> @@ -128,6 +128,12 @@ uint64_t         sectorsize;
>>   *     Filled raw string from the user, so we never lose that information e.g.
>>   *     to print it back in case of an issue.
>>   *
>> + *   value OPTIONAL
>> + *     The value that is to be used if the given subopt is not specified at all.
>
> It seems to be more than that ?
>
>> + *     This is filled with user input
>
> This is a bit confusing, isn't it first the default value should no user input
> value be passed ? And finally if user input value is passed only then will this
> be that value ?
>
>> and anything you write here now is
>> + *     overwritten if user specifies the subopt. (If the user input is a string
>> + *     and not a number, this value is set to a positive non-zero number.)
>> + *
>>   * !!! NOTE ==================================================================
>>   *
>>   * If you are adding a new option, or changing an existing one,
>> @@ -152,6 +158,7 @@ struct opt_params {
>>               uint64_t        maxval;
>>               uint64_t        flagval;
>>               const char      *raw_input;
>> +             uint64_t        value;
>>       }               subopt_params[MAX_SUBOPTS];
>>  } opts[MAX_OPTS] = {
>>  #define OPT_B        0
>
> It would seem rather unfair to define this this but not use it in the patch ?

I'm still trying to find out when exactly should I make something two
patches and when one, and it seems to shift case by case... I tried to
separate the adding of new things and rewriting of the existing code,
but do you think, in this case, the new thing is too trivial to have a
standalone patch?

Jan

>
>   Luis



-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 06/12] mkfs: create get/set functions for opts table
  2017-04-25  3:40   ` Luis R. Rodriguez
@ 2017-04-25  8:11     ` Jan Tulak
  2017-04-26  1:43       ` Luis R. Rodriguez
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-25  8:11 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Tue, Apr 25, 2017 at 5:40 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Sun, Apr 23, 2017 at 08:54:57PM +0200, Jan Tulak wrote:
>> Add functions that can be used to get/set values to opts table.
>>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>>
>> ---
>>  mkfs/xfs_mkfs.c | 32 ++++++++++++++++++++++++++++++++
>>  1 file changed, 32 insertions(+)
>>
>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>> index c2ffd91..4caf93c 100644
>> --- a/mkfs/xfs_mkfs.c
>> +++ b/mkfs/xfs_mkfs.c
>> @@ -786,6 +786,38 @@ get_conf_raw(int opt, int subopt)
>>       return opts[opt].subopt_params[subopt].raw_input;
>>  }
>>
>> +static uint64_t getnum(const char *str, struct opt_params *opts, int index);
>
> Why not just move getnum() above here. Forward declarations IMHO should not be
> needed unless we have odd inclusion issues and I don't think that's the case
> here ?

Getnum requires set_conf_raw and illegal_option, but it seems that
they could be moved too. I think there is no circle dependency, I just
didn't want to move so many lines when I can do one declaration. But
if the declaration is an issue, I can shuffle the ~80 lines the three
functions takes.

Jan

>
>> +
>> +/*
>> + * Get and set values to the opts table.
>> + */
>> +static inline uint64_t
>> +get_conf_val(int opt, int subopt)
>> +{
>> +     return opts[opt].subopt_params[subopt].value;
>> +}
>> +
>> +static void
>> +set_conf_val(int opt, int subopt, uint64_t val)
>> +{
>> +     struct subopt_param *sp = &opts[opt].subopt_params[subopt];
>> +
>> +     sp->value = val;
>> +}
>> +
>> +/*
>> + * A wrapper for getnum and set_conf_val.
>> + */
>> +static inline uint64_t
>> +parse_conf_val(int opt, int subopt, char *value)
>> +{
>> +     uint64_t num = getnum(value, &opts[opt], subopt);
>> +
>> +     set_conf_val(opt, subopt, num);
>> +     return num;
>> +}
>
> Very nice thanks!
>
>   Luis



-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 07/12] mkfs: save user input values into opts
  2017-04-25  5:19   ` Luis R. Rodriguez
@ 2017-04-25  8:16     ` Jan Tulak
  2017-04-26  1:47       ` Luis R. Rodriguez
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-25  8:16 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Tue, Apr 25, 2017 at 7:19 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Sun, Apr 23, 2017 at 08:54:58PM +0200, Jan Tulak wrote:
>> Save the parsed values from users into the opts table.
>>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>> ---
>>  mkfs/xfs_mkfs.c | 260 +++++++++++++++++++++++++++++++++++---------------------
>>  1 file changed, 165 insertions(+), 95 deletions(-)
>>
>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>> index 4caf93c..362c9b4 100644
>> --- a/mkfs/xfs_mkfs.c
>> +++ b/mkfs/xfs_mkfs.c
>> @@ -1636,16 +1636,19 @@ main(
>>
>>                               switch (getsubopt(&p, subopts, &value)) {
>>                               case B_LOG:
>> -                                     blocklog = getnum(value, &opts[OPT_B],
>> -                                                             B_LOG);
>> +                                     blocklog = parse_conf_val(OPT_B, B_LOG,
>> +                                                               value);
>>                                       blocksize = 1 << blocklog;
>>                                       blflag = 1;
>> +                                     set_conf_val(OPT_B, B_SIZE, blocksize);
>>                                       break;
>>                               case B_SIZE:
>> -                                     blocksize = getnum(value, &opts[OPT_B],
>> -                                                        B_SIZE);
>> +                                     blocksize = parse_conf_val(OPT_B,
>> +                                                                B_SIZE,
>> +                                                                value);
>>                                       blocklog = libxfs_highbit32(blocksize);
>>                                       bsflag = 1;
>> +                                     set_conf_val(OPT_B, B_LOG, blocklog);
>>                                       break;
>>                               default:
>>                                       unknown('b', value);
>
> This still means that users of parse_conf_val() must copy the same code
> in each case in the above to handle collateral values: if blocklog was
> passed we update blocklog *and* blocksize *and* bsflag. Likewise if blocksize
> was passed we must update blocksize *and* blocklog *and* blflag. What I had
> done on the mkfs.xfs.conf series is put all this functionality into a helper,
> and to do this move all needed vars into a struct. You are moving all possible
> user params to a option specific table, however the collateral parameters are
> kept inside main().
>
> I'll need to do the same again: move the logic above to a helper and move
> collateral parameters to a struct, or this could be done in your series by
> having parse_conf_val() handle all the needed logic provided say an extra
> struct param is passed -- or though some other means.
>
> Duplicating the functionality I'm sure is not desirable, how we handle this
> subjective so I'll leave it up to you to advise how you'd like to proceed,
> but let me know if the above consideration is clear.
>
>   Luis

This is something I want to do, but let's get there step by step.
First make the table working, then remove pieces from the main. If I
try to do everything at once, it won't be ever finished. ;-)

Jan


-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options
  2017-04-25  5:27   ` Luis R. Rodriguez
  2017-04-25  5:30     ` Luis R. Rodriguez
@ 2017-04-25  8:37     ` Jan Tulak
  2017-04-26  0:45       ` Luis R. Rodriguez
  1 sibling, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-25  8:37 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Tue, Apr 25, 2017 at 7:27 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Sun, Apr 23, 2017 at 08:54:59PM +0200, Jan Tulak wrote:
>> Remove variables that can be replaced with a direct access to the opts table,
>> so we have it all in a single place, acessible from anywhere.
>>
>> In future, we can remove some passing of values forth and back, but now limit
>> the changes to simple replacement without a change in the logic.
>
> What do you mean passing of values here, as an example with bopts ?

Passing it to a function and then retrieving with pointers, e.g. change this

static void
calc_stripe_factors(
        int             dsu,
        int             dsw,
        int             dsectsz,
        int             lsu,
        int             lsectsz,
        uint64_t        *dsunit,
        uint64_t        *dswidth,
        uint64_t        *lsunit)


to this

static void
calc_stripe_factors(struct opt_params * opts) // or no argument at all...

Which btw needs to be updated anyway because it is still using int...

>
>> This is first of multiple similar patches that do the same, but for other
>> options.
>>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>> ---
>>  mkfs/xfs_mkfs.c | 814 ++++++++++++++++++++++++++++++++++----------------------
>>  1 file changed, 503 insertions(+), 311 deletions(-)
>>
>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>> index 362c9b4..6857c30 100644
>> --- a/mkfs/xfs_mkfs.c
>> +++ b/mkfs/xfs_mkfs.c
>> @@ -1485,15 +1480,12 @@ main(
>>       int                     argc,
>>       char                    **argv)
>>  {
>> -     uint64_t                agcount;
>>       xfs_agf_t               *agf;
>>       xfs_agi_t               *agi;
>>       xfs_agnumber_t          agno;
>> -     uint64_t                agsize;
>>       xfs_alloc_rec_t         *arec;
>>       struct xfs_btree_block  *block;
>>       bool                    blflag;
>
> Note: blflag
>
>> -     uint64_t                blocklog;
>>       bool                    bsflag;
>
> Note: bsflag
>
>>       memset(&fsx, 0, sizeof(fsx));
>> @@ -1629,6 +1613,7 @@ main(
>>                       break;
>>               case 'b':
>>                       p = optarg;
>> +                     uint64_t tmp;
>>                       while (*p != '\0') {
>>                               char    **subopts =
>>                                               (char **)opts[OPT_B].subopts;
>> @@ -1636,19 +1621,17 @@ main(
>>
>>                               switch (getsubopt(&p, subopts, &value)) {
>>                               case B_LOG:
>> -                                     blocklog = parse_conf_val(OPT_B, B_LOG,
>> -                                                               value);
>> -                                     blocksize = 1 << blocklog;
>> +                                     tmp = parse_conf_val(OPT_B, B_LOG,
>> +                                                          value);
>> +                                     set_conf_val(OPT_B, B_SIZE, 1 << tmp);
>>                                       blflag = 1;
>
> This is a collateral variable set when blog is set. If we have to parse the
> blog again, it means similar code would be needed.
>
>> -                                     set_conf_val(OPT_B, B_SIZE, blocksize);
>>                                       break;
>>                               case B_SIZE:
>> -                                     blocksize = parse_conf_val(OPT_B,
>> -                                                                B_SIZE,
>> -                                                                value);
>> -                                     blocklog = libxfs_highbit32(blocksize);
>> +                                     tmp = parse_conf_val(OPT_B, B_SIZE,
>> +                                                          value);
>> +                                     set_conf_val(OPT_B, B_LOG,
>> +                                             libxfs_highbit32(tmp));
>>                                       bsflag = 1;
>
> Likewise for bsflag.
>
>> -                                     set_conf_val(OPT_B, B_LOG, blocklog);
>>                                       break;
>>                               default:
>>                                       unknown('b', value);
>
> What I'm questioning is whether or not it makes sense instead for parse_conf_val()
> to return void and do all this meddling for us, this would require stuffing any
> collateral variables into a struct and passing that to parse_conf_val and using
> it on main() as well.

Again, this (both logic and flags) is something I want to do later.
And in fact, I think that perhaps the whole manual loop in main() can
be removed in the future once the case logic is moved elsewhere.
Because then we can extract specific cases from the opts table with
the help of some helper functions...

Jan

>
>   Luis



-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 05/12] mkfs: extend opt_params with a value field
  2017-04-25  8:04     ` Jan Tulak
@ 2017-04-25  9:39       ` Jan Tulak
  2017-04-26  1:04         ` Luis R. Rodriguez
  2017-04-26  1:10       ` Luis R. Rodriguez
  1 sibling, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-25  9:39 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

v

On Tue, Apr 25, 2017 at 10:04 AM, Jan Tulak <jtulak@redhat.com> wrote:
> On Tue, Apr 25, 2017 at 5:13 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
>> On Sun, Apr 23, 2017 at 08:54:56PM +0200, Jan Tulak wrote:
>>> Add a new field int opt_params - value,
>>
>> Agreed.
>>
>>> which is filled with user input.
>>
>> It sounds to me its more than that, its the default value which will be used should
>> not user input for the option be specified, and if user input value is provided it
>> will be the passed user input value. If the final value for the respective option.
>>
>> ?
>
> Yes. I see I should make the description better, both here in commit
> message and in the code too. It is the same logic as it was for the
> old variables like agcount in main(). Initialize it with whatever you
> want as the default for pure "mkfs.xfs /some/dev", but if the users
> give us the specific option, we are going to overwrite it with their
> value.
>
> I don't see any use for remembering the defaults once it is clear that
> user wants to use custom values instead. And copying the defaults from
> some other field "if the user said nothing" sounds like a recipe for
> bugs...
>

And rather than submitting repeatedly new versions of the whole
patch... how about this?

 *
 *   value OPTIONAL
 *     The actual value used in computations and for creating the filesystem.
 *     It is filled with user input and anything you write here now is
 *     overwritten if the user specifies the subopt. But he does not,
then whatever
 *     you put there is used as the default. Can be omitted if the default
 *     is 0.
 *     (If the field is a string and not a number, this value is set to
 *     a positive non-zero number on an user input.)

And for the commit message, a bit shortened version:

Add a new field int opt_params - value - which is the actual value
used in computations and for creating the filesystem. It is filled
with user input if the user specifies the subopt. But he does not,
then whatever you put there is used as the default.

Sounds better?

>>
>>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>>> ---
>>>  mkfs/xfs_mkfs.c | 7 +++++++
>>>  1 file changed, 7 insertions(+)
>>>
>>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>>> index 513e106..c2ffd91 100644
>>> --- a/mkfs/xfs_mkfs.c
>>> +++ b/mkfs/xfs_mkfs.c
>>> @@ -128,6 +128,12 @@ uint64_t         sectorsize;
>>>   *     Filled raw string from the user, so we never lose that information e.g.
>>>   *     to print it back in case of an issue.
>>>   *
>>> + *   value OPTIONAL
>>> + *     The value that is to be used if the given subopt is not specified at all.
>>
>> It seems to be more than that ?
>>
>>> + *     This is filled with user input
>>
>> This is a bit confusing, isn't it first the default value should no user input
>> value be passed ? And finally if user input value is passed only then will this
>> be that value ?
>>
>>> and anything you write here now is
>>> + *     overwritten if user specifies the subopt. (If the user input is a string
>>> + *     and not a number, this value is set to a positive non-zero number.)
>>> + *
>>>   * !!! NOTE ==================================================================
>>>   *
>>>   * If you are adding a new option, or changing an existing one,
>>> @@ -152,6 +158,7 @@ struct opt_params {
>>>               uint64_t        maxval;
>>>               uint64_t        flagval;
>>>               const char      *raw_input;
>>> +             uint64_t        value;
>>>       }               subopt_params[MAX_SUBOPTS];
>>>  } opts[MAX_OPTS] = {
>>>  #define OPT_B        0
>>
>> It would seem rather unfair to define this this but not use it in the patch ?
>
> I'm still trying to find out when exactly should I make something two
> patches and when one, and it seems to shift case by case... I tried to
> separate the adding of new things and rewriting of the existing code,
> but do you think, in this case, the new thing is too trivial to have a
> standalone patch?
>
> Jan
>
>>
>>   Luis
>
>
>
> --
> Jan Tulak
> jtulak@redhat.com / jan@tulak.me



-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-25  7:45     ` Jan Tulak
@ 2017-04-25 13:28       ` Eric Sandeen
  2017-04-26  1:38         ` Luis R. Rodriguez
  2017-04-26  8:21       ` Luis R. Rodriguez
  1 sibling, 1 reply; 59+ messages in thread
From: Eric Sandeen @ 2017-04-25 13:28 UTC (permalink / raw)
  To: Jan Tulak, Luis R. Rodriguez; +Cc: linux-xfs



On 4/25/17 2:45 AM, Jan Tulak wrote:
> On Tue, Apr 25, 2017 at 5:04 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
>> On Sun, Apr 23, 2017 at 08:54:55PM +0200, Jan Tulak wrote:
>>> Merge separate instances of opt_params into one indexable table. Git
>>> makes this patch looks a bit more complicated, but it does not change
>>> values or structure of anything else. It only moves all the "struct
>>> opt_params dopts = {...}", changes indentation for these substructures
>>> and replaces their usage (dopts -> opts[OPT_D]).
>>>
>>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>>> ---
>>>  mkfs/xfs_mkfs.c | 1316 +++++++++++++++++++++++++++++--------------------------
>>>  1 file changed, 683 insertions(+), 633 deletions(-)
>>>
>>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>>> index 7a72b11..513e106 100644
>>> --- a/mkfs/xfs_mkfs.c
>>> +++ b/mkfs/xfs_mkfs.c
>>> @@ -42,6 +42,7 @@ static int  ispow2(unsigned int i);
>>>  uint64_t             blocksize;
>>>  uint64_t             sectorsize;
>>>
>>> +#define MAX_OPTS     16
>>
>> This is fragile, every time a new opt is added this needs to be updated

<pedantic>There are only 8 now, so there are still 8 free slots</pedantic>

>> and so is the index, and we should be pedantic over not going out of bounds.
>> We could instead use a flexible array and compute the max opts at run time
>> as a global. This way the max opts is always updated automatically.

I don't think it's all that fragile; this is used only for a global structure
declaration & initialization. If you add too many new members to opt_params,
compilation will issue warnings:

xfs_mkfs.c:342: warning: excess elements in array initializer
xfs_mkfs.c:342: warning: (near initialization for ‘opts’)
xfs_mkfs.c:424: warning: excess elements in array initializer
xfs_mkfs.c:424: warning: (near initialization for ‘opts’)
xfs_mkfs.c:543: warning: excess elements in array initializer
xfs_mkfs.c:543: warning: (near initialization for ‘opts’)
...

and it will be quite obvious, at which point you can bump it up before
you send that patch.  ;)

Anyway, because the the definition is never used at runtime, there's
no need to be computing it at runtime, either.

> Mmm, that is a good idea and I see no issue with it. But I'm not sure
> if it is worth of rewriting this patch as we already use MAX_SUBOPTS
> anyway. Rather I see it as a standalone patch in the next set. What do
> you think?

I think that given how it's used, there is no real need for any extra
complexity.  In any case, any changes around this behavior would certainly
be part of a different patch, because you'd want to be consistent with all
the other structure initializers, and it would be a functionally separate
change if it is warranted at all.

Thanks,
-Eric

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

* Re: [PATCH 00/12] mkfs: save user input into opts table
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (12 preceding siblings ...)
  2017-04-25  2:52 ` [PATCH 00/12] mkfs: save user input into opts table Luis R. Rodriguez
@ 2017-04-25 16:20 ` Eric Sandeen
  2017-04-26  2:02   ` Luis R. Rodriguez
  2017-06-28 16:18 ` Luis R. Rodriguez
  14 siblings, 1 reply; 59+ messages in thread
From: Eric Sandeen @ 2017-04-25 16:20 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 4/23/17 1:54 PM, Jan Tulak wrote:
> Hi guys,
> 
> I decided to split my big patchset into more smaller ones. So, this is the
> first set. It adds set/get functions similar to Dave's suggestion, to save and
> retrieve user values to and from the big opts table and prepares the ground for
> future patches.
> 
> 
> It is a mix of patches I already submitted and new ones:
> Patches 2, 3, 4, 5 are just slightly modified to fix their issues.
> Other patches are new.
> 
> The last few patches could be merged into one, because it should only
> substitute variables for get/set calls, but because there are so many
> places where the changes occurs, I split them into smaller chunks,
> making it (hopefully) easier for you to review.
> 
> This patchset requires my two previous uint patches.

Just to be clear, those were NAK'd, I believe, so these may need
to be rebased without them.

-Eric

> Git tree: https://github.com/jtulak/xfsprogs-dev/tree/setters
> 
> Cheers,
> Jan
> 
> P.S.:
> As a side note, I thought about adding a verification mechanism to
> the set_conf_val() function, which would guarantee that we never have
> an invalid number even later in the code -- an attempt to catch for
> bugs. However, it seems that in some cases, we convert the number
> e.g. from number of 512 byte blocks to fs blocks in situ (L_SUNIT),
> which means that in some occasions, we are getting out of the range
> of allowed values on the input side. So, I'm not adding these checks now,
> but it is an option that could give us a cheap way how to catch some bugs.
> Another question though is, how useful it would be...
> 
> 
> Jan Tulak (12):
>   mkfs: Save raw user input field to the opts struct
>   mkfs: rename defaultval to flagval in opts
>   mkfs: remove intermediate getstr followed by getnum
>   mkfs: merge tables for opts parsing into one table
>   mkfs: extend opt_params with a value field
>   mkfs: create get/set functions for opts table
>   mkfs: save user input values into opts
>   mkfs: replace variables with opts table: -b,d,s options
>   mkfs: replace variables with opts table: -i options
>   mkfs: replace variables with opts table: -l options
>   mkfs: replace variables with opts table: -n options
>   mkfs: replace variables with opts table: -r options
> 
>  mkfs/xfs_mkfs.c | 2457 ++++++++++++++++++++++++++++++++-----------------------
>  1 file changed, 1420 insertions(+), 1037 deletions(-)
> 

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

* Re: [PATCH 02/12] mkfs: rename defaultval to flagval in opts
  2017-04-23 18:54 ` [PATCH 02/12] mkfs: rename defaultval to flagval in opts Jan Tulak
@ 2017-04-25 16:52   ` Eric Sandeen
  2017-04-26  7:30     ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Eric Sandeen @ 2017-04-25 16:52 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 4/23/17 1:54 PM, Jan Tulak wrote:
> The old name 'defaultval' was misleading - it is not the default value,
> but the value the option has when used as a flag by an user.

The value should only ever be 0 or 1, correct?

Ok, so I see something interesting here:

# grep "flagval = " mkfs/xfs_mkfs.c | sort | uniq -c
      1 			  .flagval = 0,
      1 			.flagval = 0,
     14 			  .flagval = 1,
     40 			  .flagval = SUBOPT_NEEDS_VAL,

of the 56 subopts, only 16 are treated as a flag, and only 2 default
to 0, while the rest default to 1.

Those 2 seem like outliers: -m rmapbt and -m reflink.  What's
going on there?

In every other case where there is a subopt which is actually a
boolean flag, a bare specification without a value means "enable
the feature."

It seems very unintuitive to have:

-X THING1 -> THING1 is enabled 14 times, but
-X THING12 - THING2 is still /disabled/ in only 2 cases

I'd argue that "-m rmapbt" and "-m reflink" leaving those features
/disabled/ is a bug, due to misunderstanding of what "defaultval"
means, and that they should be fixed to behave like the other 14
boolean flags.

i.e. I'd argue that a bare boolean flag specification should /always/
enable the feature.  At that point, you can say within your code 
"if min = 0 and max = 1, this is a boolean, and the flag may be specified
without a value, in which case the value is set to 1, and the feature
is enabled."

At that point you don't need this extra structure member, and you won't
have to re-state it 56 times, thus simplifying the code.

What do you think?  I'd happily review and merge 2 patches, which:

1) Makes rmapbt and reflink behave like every other boolean flag, and

2) Removes "defaultval" altogether, and uses min=0/max=1 as a sign that
   the option is a boolean, with a bare flag name allowed to enable it.

-Eric

> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> ---
>  mkfs/xfs_mkfs.c | 120 ++++++++++++++++++++++++++++----------------------------
>  1 file changed, 60 insertions(+), 60 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 84674d5..0a795a6 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -112,7 +112,7 @@ uint64_t		sectorsize;
>   *     to zero. But if one value is different: minval=0 and maxval=1,
>   *     then it is OK.)
>   *
> - *   defaultval MANDATORY
> + *   flagval MANDATORY
>   *     The value used if user specifies the subopt, but no value.
>   *     If the subopt accepts some values (-d file=[1|0]), then this
>   *     sets what is used with simple specifying the subopt (-d file).
> @@ -144,7 +144,7 @@ struct opt_params {
>  		int		conflicts[MAX_CONFLICTS];
>  		uint64_t	minval;
>  		uint64_t	maxval;
> -		uint64_t	defaultval;
> +		uint64_t	flagval;
>  		const char	*raw_input;
>  	}		subopt_params[MAX_SUBOPTS];
>  };
> @@ -164,7 +164,7 @@ struct opt_params bopts = {
>  				 LAST_CONFLICT },
>  		  .minval = XFS_MIN_BLOCKSIZE_LOG,
>  		  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = B_SIZE,
>  		  .convert = true,
> @@ -173,7 +173,7 @@ struct opt_params bopts = {
>  				 LAST_CONFLICT },
>  		  .minval = XFS_MIN_BLOCKSIZE,
>  		  .maxval = XFS_MAX_BLOCKSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  	},
>  };
> @@ -219,24 +219,24 @@ struct opt_params dopts = {
>  				 LAST_CONFLICT },
>  		  .minval = 1,
>  		  .maxval = XFS_MAX_AGNUMBER,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_FILE,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  		{ .index = D_NAME,
>  		  .conflicts = { LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_SIZE,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .convert = true,
>  		  .minval = XFS_AG_MIN_BYTES,
>  		  .maxval = LLONG_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_SUNIT,
>  		  .conflicts = { D_NOALIGN,
> @@ -245,7 +245,7 @@ struct opt_params dopts = {
>  				 LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_SWIDTH,
>  		  .conflicts = { D_NOALIGN,
> @@ -254,7 +254,7 @@ struct opt_params dopts = {
>  				 LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_AGSIZE,
>  		  .conflicts = { D_AGCOUNT,
> @@ -262,7 +262,7 @@ struct opt_params dopts = {
>  		  .convert = true,
>  		  .minval = XFS_AG_MIN_BYTES,
>  		  .maxval = XFS_AG_MAX_BYTES,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_SU,
>  		  .conflicts = { D_NOALIGN,
> @@ -272,7 +272,7 @@ struct opt_params dopts = {
>  		  .convert = true,
>  		  .minval = 0,
>  		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_SW,
>  		  .conflicts = { D_NOALIGN,
> @@ -281,14 +281,14 @@ struct opt_params dopts = {
>  				 LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_SECTLOG,
>  		  .conflicts = { D_SECTSIZE,
>  				 LAST_CONFLICT },
>  		  .minval = XFS_MIN_SECTORSIZE_LOG,
>  		  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_SECTSIZE,
>  		  .conflicts = { D_SECTLOG,
> @@ -297,7 +297,7 @@ struct opt_params dopts = {
>  		  .is_power_2 = true,
>  		  .minval = XFS_MIN_SECTORSIZE,
>  		  .maxval = XFS_MAX_SECTORSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_NOALIGN,
>  		  .conflicts = { D_SU,
> @@ -307,25 +307,25 @@ struct opt_params dopts = {
>  				 LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  		{ .index = D_RTINHERIT,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  		{ .index = D_PROJINHERIT,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = D_EXTSZINHERIT,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  	},
>  };
> @@ -357,7 +357,7 @@ struct opt_params iopts = {
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  		{ .index = I_LOG,
>  		  .conflicts = { I_PERBLOCK,
> @@ -365,13 +365,13 @@ struct opt_params iopts = {
>  				 LAST_CONFLICT },
>  		  .minval = XFS_DINODE_MIN_LOG,
>  		  .maxval = XFS_DINODE_MAX_LOG,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = I_MAXPCT,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 100,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = I_PERBLOCK,
>  		  .conflicts = { I_LOG,
> @@ -380,7 +380,7 @@ struct opt_params iopts = {
>  		  .is_power_2 = true,
>  		  .minval = XFS_MIN_INODE_PERBLOCK,
>  		  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = I_SIZE,
>  		  .conflicts = { I_PERBLOCK,
> @@ -389,25 +389,25 @@ struct opt_params iopts = {
>  		  .is_power_2 = true,
>  		  .minval = XFS_DINODE_MIN_SIZE,
>  		  .maxval = XFS_DINODE_MAX_SIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = I_ATTR,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 2,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = I_PROJID32BIT,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  		{ .index = I_SPINODES,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  	},
>  };
> @@ -447,7 +447,7 @@ struct opt_params lopts = {
>  				 LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = L_INTERNAL,
>  		  .conflicts = { L_FILE,
> @@ -455,27 +455,27 @@ struct opt_params lopts = {
>  				 LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  		{ .index = L_SIZE,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .convert = true,
>  		  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
>  		  .maxval = XFS_MAX_LOG_BYTES,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = L_VERSION,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 1,
>  		  .maxval = 2,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = L_SUNIT,
>  		  .conflicts = { L_SU,
>  				 LAST_CONFLICT },
>  		  .minval = 1,
>  		  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = L_SU,
>  		  .conflicts = { L_SUNIT,
> @@ -483,20 +483,20 @@ struct opt_params lopts = {
>  		  .convert = true,
>  		  .minval = BBTOB(1),
>  		  .maxval = XLOG_MAX_RECORD_BSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = L_DEV,
>  		  .conflicts = { L_AGNUM,
>  				 L_INTERNAL,
>  				 LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = L_SECTLOG,
>  		  .conflicts = { L_SECTSIZE,
>  				 LAST_CONFLICT },
>  		  .minval = XFS_MIN_SECTORSIZE_LOG,
>  		  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = L_SECTSIZE,
>  		  .conflicts = { L_SECTLOG,
> @@ -505,26 +505,26 @@ struct opt_params lopts = {
>  		  .is_power_2 = true,
>  		  .minval = XFS_MIN_SECTORSIZE,
>  		  .maxval = XFS_MAX_SECTORSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = L_FILE,
>  		  .conflicts = { L_INTERNAL,
>  				 LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  		{ .index = L_NAME,
>  		  .conflicts = { L_AGNUM,
>  				 L_INTERNAL,
>  				 LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = L_LAZYSBCNTR,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  	},
>  };
> @@ -548,7 +548,7 @@ struct opt_params nopts = {
>  				 LAST_CONFLICT },
>  		  .minval = XFS_MIN_REC_DIRSIZE,
>  		  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = N_SIZE,
>  		  .conflicts = { N_LOG,
> @@ -557,19 +557,19 @@ struct opt_params nopts = {
>  		  .is_power_2 = true,
>  		  .minval = 1 << XFS_MIN_REC_DIRSIZE,
>  		  .maxval = XFS_MAX_BLOCKSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = N_VERSION,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 2,
>  		  .maxval = 2,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = N_FTYPE,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  	},
>  };
> @@ -597,33 +597,33 @@ struct opt_params ropts = {
>  		  .convert = true,
>  		  .minval = XFS_MIN_RTEXTSIZE,
>  		  .maxval = XFS_MAX_RTEXTSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = R_SIZE,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .convert = true,
>  		  .minval = 0,
>  		  .maxval = LLONG_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = R_DEV,
>  		  .conflicts = { LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = R_FILE,
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		  .conflicts = { LAST_CONFLICT },
>  		},
>  		{ .index = R_NAME,
>  		  .conflicts = { LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = R_NOALIGN,
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		  .conflicts = { LAST_CONFLICT },
>  		},
>  	},
> @@ -649,7 +649,7 @@ struct opt_params sopts = {
>  				 LAST_CONFLICT },
>  		  .minval = XFS_MIN_SECTORSIZE_LOG,
>  		  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = S_SECTLOG,
>  		  .conflicts = { S_SIZE,
> @@ -657,7 +657,7 @@ struct opt_params sopts = {
>  				 LAST_CONFLICT },
>  		  .minval = XFS_MIN_SECTORSIZE_LOG,
>  		  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = S_SIZE,
>  		  .conflicts = { S_LOG,
> @@ -667,7 +667,7 @@ struct opt_params sopts = {
>  		  .is_power_2 = true,
>  		  .minval = XFS_MIN_SECTORSIZE,
>  		  .maxval = XFS_MAX_SECTORSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = S_SECTSIZE,
>  		  .conflicts = { S_LOG,
> @@ -677,7 +677,7 @@ struct opt_params sopts = {
>  		  .is_power_2 = true,
>  		  .minval = XFS_MIN_SECTORSIZE,
>  		  .maxval = XFS_MAX_SECTORSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  	},
>  };
> @@ -702,29 +702,29 @@ struct opt_params mopts = {
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  		{ .index = M_FINOBT,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 1,
> +		  .flagval = 1,
>  		},
>  		{ .index = M_UUID,
>  		  .conflicts = { LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		  .flagval = SUBOPT_NEEDS_VAL,
>  		},
>  		{ .index = M_RMAPBT,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 0,
> +		  .flagval = 0,
>  		},
>  		{ .index = M_REFLINK,
>  		  .conflicts = { LAST_CONFLICT },
>  		  .minval = 0,
>  		  .maxval = 1,
> -		  .defaultval = 0,
> +		  .flagval = 0,
>  		},
>  	},
>  };
> @@ -1365,9 +1365,9 @@ getnum(
>  	check_opt(opts, index, false);
>  	/* empty strings might just return a default value */
>  	if (!str || *str == '\0') {
> -		if (sp->defaultval == SUBOPT_NEEDS_VAL)
> +		if (sp->flagval == SUBOPT_NEEDS_VAL)
>  			reqval(opts->name, (char **)opts->subopts, index);
> -		return sp->defaultval;
> +		return sp->flagval;
>  	}
>  
>  	if (sp->minval == 0 && sp->maxval == 0) {
> 

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

* Re: [PATCH 03/12] mkfs: remove intermediate getstr followed by getnum
  2017-04-23 18:54 ` [PATCH 03/12] mkfs: remove intermediate getstr followed by getnum Jan Tulak
@ 2017-04-25 17:37   ` Eric Sandeen
  2017-04-26  7:40     ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Eric Sandeen @ 2017-04-25 17:37 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 4/23/17 1:54 PM, Jan Tulak wrote:
> Some options loaded a number as a string with getstr and converted it to
> number with getnum later in the code, without any reason for this
> approach.  (They were probably forgotten in some past cleaning.)
> 
> This patch changes them to skip the string and use getnum directly in
> the main option-parsing loop, as do all the other numerical options.
> 
> And as we now have two variables of the same type for the same value,
> merge them together. (e.g. former string dsize and number dbytes).
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> ---
> CHANGES:
> * The first patch now ensures that we still have the raw input and
>   we are not changing the form of user input (i.e. size stays in given
>   units...)
> 
>  mkfs/xfs_mkfs.c | 88 ++++++++++++++++++++++++++-------------------------------
>  1 file changed, 40 insertions(+), 48 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 0a795a6..7a72b11 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -1363,6 +1363,7 @@ getnum(
>  	uint64_t		c;
>  
>  	check_opt(opts, index, false);
> +	set_conf_raw(opts, index, str);

So this is really an unrelated functional change here; ideally, this
patch would come before the "raw option" patch.  Once every option goes
through getnum, /then/ you can add the raw storage to getnum().

Not a huge deal, but if you resend the series, you might consider that
ordering.  Otherwise I think this one looks ok :)

Reviewed-by: Eric Sandeen <sandeen@redhat.com>

>  	/* empty strings might just return a default value */
>  	if (!str || *str == '\0') {
>  		if (sp->flagval == SUBOPT_NEEDS_VAL)
> @@ -1450,7 +1451,7 @@ main(
>  	char			*dfile;
>  	uint64_t		dirblocklog;
>  	uint64_t		dirblocksize;
> -	char			*dsize;
> +	uint64_t		dbytes;
>  	uint64_t		dsu;
>  	uint64_t		dsw;
>  	uint64_t		dsunit;
> @@ -1474,7 +1475,7 @@ main(
>  	xfs_rfsblock_t		logblocks;
>  	char			*logfile;
>  	uint64_t		loginternal;
> -	char			*logsize;
> +	uint64_t		logbytes;
>  	xfs_fsblock_t		logstart;
>  	bool			lvflag;
>  	bool			lsflag;
> @@ -1503,11 +1504,11 @@ main(
>  	char			*protostring;
>  	bool			qflag;
>  	xfs_rfsblock_t		rtblocks;
> +	uint64_t		rtbytes;
>  	xfs_extlen_t		rtextblocks;
>  	xfs_rtblock_t		rtextents;
> -	char			*rtextsize;
> +	uint64_t		rtextbytes;
>  	char			*rtfile;
> -	char			*rtsize;
>  	xfs_sb_t		*sbp;
>  	uint64_t		sectorlog;
>  	uint64_t		sector_mask;
> @@ -1555,7 +1556,8 @@ main(
>  	qflag = false;
>  	imaxpct = inodelog = inopblock = isize = 0;
>  	dfile = logfile = rtfile = NULL;
> -	dsize = logsize = rtsize = rtextsize = protofile = NULL;
> +	protofile = NULL;
> +	rtbytes = rtextbytes = logbytes = dbytes = 0;
>  	dsu = dsw = dsunit = dswidth = lalign = lsu = lsunit = 0;
>  	nodsflag = norsflag = false;
>  	force_overwrite = false;
> @@ -1619,7 +1621,7 @@ main(
>  					xi.dname = getstr(value, &dopts, D_NAME);
>  					break;
>  				case D_SIZE:
> -					dsize = getstr(value, &dopts, D_SIZE);
> +					dbytes = getnum(value, &dopts, D_SIZE);
>  					break;
>  				case D_SUNIT:
>  					dsunit = getnum(value, &dopts, D_SUNIT);
> @@ -1764,7 +1766,7 @@ main(
>  					lvflag = 1;
>  					break;
>  				case L_SIZE:
> -					logsize = getstr(value, &lopts, L_SIZE);
> +					logbytes = getnum(value, &lopts, L_SIZE);
>  					break;
>  				case L_SECTLOG:
>  					lsectorlog = getnum(value, &lopts,
> @@ -1893,8 +1895,7 @@ main(
>  
>  				switch (getsubopt(&p, subopts, &value)) {
>  				case R_EXTSIZE:
> -					rtextsize = getstr(value, &ropts,
> -							   R_EXTSIZE);
> +					rtextbytes = getnum(value, &ropts, R_EXTSIZE);
>  					break;
>  				case R_FILE:
>  					xi.risfile = getnum(value, &ropts,
> @@ -1906,7 +1907,7 @@ main(
>  							   R_NAME);
>  					break;
>  				case R_SIZE:
> -					rtsize = getstr(value, &ropts, R_SIZE);
> +					rtbytes = getnum(value, &ropts, R_SIZE);
>  					break;
>  				case R_NOALIGN:
>  					norsflag = getnum(value, &ropts,
> @@ -2009,14 +2010,14 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
>  	 * sector size mismatches between the new filesystem and the underlying
>  	 * host filesystem.
>  	 */
> -	check_device_type(dfile, &xi.disfile, !dsize, !dfile,
> +	check_device_type(dfile, &xi.disfile, !dbytes, !dfile,
>  			  Nflag ? NULL : &xi.dcreat, force_overwrite, "d");
>  	if (!loginternal)
> -		check_device_type(xi.logname, &xi.lisfile, !logsize, !xi.logname,
> -				  Nflag ? NULL : &xi.lcreat,
> +		check_device_type(xi.logname, &xi.lisfile, !logbytes,
> +				  !xi.logname, Nflag ? NULL : &xi.lcreat,
>  				  force_overwrite, "l");
>  	if (xi.rtname)
> -		check_device_type(xi.rtname, &xi.risfile, !rtsize, !xi.rtname,
> +		check_device_type(xi.rtname, &xi.risfile, !rtbytes, !xi.rtname,
>  				  Nflag ? NULL : &xi.rcreat,
>  				  force_overwrite, "r");
>  	if (xi.disfile || xi.lisfile || xi.risfile)
> @@ -2197,10 +2198,7 @@ _("rmapbt not supported with realtime devices\n"));
>  	}
>  
>  
> -	if (dsize) {
> -		uint64_t dbytes;
> -
> -		dbytes = getnum(dsize, &dopts, D_SIZE);
> +	if (dbytes) {
>  		if (dbytes % XFS_MIN_BLOCKSIZE) {
>  			fprintf(stderr,
>  			_("illegal data length %"PRIu64", not a multiple of %d\n"),
> @@ -2229,10 +2227,7 @@ _("rmapbt not supported with realtime devices\n"));
>  		usage();
>  	}
>  
> -	if (logsize) {
> -		uint64_t logbytes;
> -
> -		logbytes = getnum(logsize, &lopts, L_SIZE);
> +	if (logbytes) {
>  		if (logbytes % XFS_MIN_BLOCKSIZE) {
>  			fprintf(stderr,
>  			_("illegal log length %"PRIu64", not a multiple of %d\n"),
> @@ -2246,10 +2241,7 @@ _("rmapbt not supported with realtime devices\n"));
>  				logbytes, blocksize,
>  				(uint64_t)(logblocks << blocklog));
>  	}
> -	if (rtsize) {
> -		uint64_t rtbytes;
> -
> -		rtbytes = getnum(rtsize, &ropts, R_SIZE);
> +	if (rtbytes) {
>  		if (rtbytes % XFS_MIN_BLOCKSIZE) {
>  			fprintf(stderr,
>  			_("illegal rt length %"PRIu64", not a multiple of %d\n"),
> @@ -2266,10 +2258,7 @@ _("rmapbt not supported with realtime devices\n"));
>  	/*
>  	 * If specified, check rt extent size against its constraints.
>  	 */
> -	if (rtextsize) {
> -		uint64_t rtextbytes;
> -
> -		rtextbytes = getnum(rtextsize, &ropts, R_EXTSIZE);
> +	if (rtextbytes) {
>  		if (rtextbytes % blocksize) {
>  			fprintf(stderr,
>  		_("illegal rt extent size %"PRIu64", not a multiple of %"PRIu64"\n"),
> @@ -2286,7 +2275,7 @@ _("rmapbt not supported with realtime devices\n"));
>  		uint64_t	rswidth;
>  		uint64_t	rtextbytes;
>  
> -		if (!norsflag && !xi.risfile && !(!rtsize && xi.disfile))
> +		if (!norsflag && !xi.risfile && !(!rtbytes && xi.disfile))
>  			rswidth = ft.rtswidth;
>  		else
>  			rswidth = 0;
> @@ -2397,15 +2386,16 @@ _("rmapbt not supported with realtime devices\n"));
>  		rtfile = _("volume rt");
>  	else if (!xi.rtdev)
>  		rtfile = _("none");
> -	if (dsize && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
> +	if (dbytes && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
>  		fprintf(stderr,
>  			_("size %s specified for data subvolume is too large, "
>  			"maximum is %"PRIu64" blocks\n"),
> -			dsize, (uint64_t)DTOBT(xi.dsize));
> +			get_conf_raw(&dopts, D_SIZE),
> +			(uint64_t)DTOBT(xi.dsize));
>  		usage();
> -	} else if (!dsize && xi.dsize > 0)
> +	} else if (!dbytes && xi.dsize > 0)
>  		dblocks = DTOBT(xi.dsize);
> -	else if (!dsize) {
> +	else if (!dbytes) {
>  		fprintf(stderr, _("can't get size of data subvolume\n"));
>  		usage();
>  	}
> @@ -2438,22 +2428,23 @@ reported by the device (%u).\n"),
>  reported by the device (%u).\n"),
>  			lsectorsize, xi.lbsize);
>  	}
> -	if (rtsize && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
> +	if (rtbytes && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
>  		fprintf(stderr, _(
>  "Warning: the realtime subvolume sector size %"PRIu64" is less than the sector size\n\
>  reported by the device (%u).\n"),
>  			sectorsize, xi.rtbsize);
>  	}
>  
> -	if (rtsize && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
> +	if (rtbytes && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
>  		fprintf(stderr,
>  			_("size %s specified for rt subvolume is too large, "
>  			"maximum is %"PRIu64" blocks\n"),
> -			rtsize, (uint64_t)DTOBT(xi.rtsize));
> +			get_conf_raw(&ropts, R_SIZE),
> +			(uint64_t)DTOBT(xi.rtsize));
>  		usage();
> -	} else if (!rtsize && xi.rtsize > 0)
> +	} else if (!rtbytes && xi.rtsize > 0)
>  		rtblocks = DTOBT(xi.rtsize);
> -	else if (rtsize && !xi.rtdev) {
> +	else if (rtbytes && !xi.rtdev) {
>  		fprintf(stderr,
>  			_("size specified for non-existent rt subvolume\n"));
>  		usage();
> @@ -2658,26 +2649,27 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
>  				   sb_feat.rmapbt, sb_feat.reflink);
>  	ASSERT(min_logblocks);
>  	min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
> -	if (!logsize && dblocks >= (1024*1024*1024) >> blocklog)
> +	if (!logbytes && dblocks >= (1024*1024*1024) >> blocklog)
>  		min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
> -	if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
> +	if (logbytes && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
>  		fprintf(stderr,
>  _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks\n"),
> -			logsize, (uint64_t)DTOBT(xi.logBBsize));
> +			get_conf_raw(&lopts, L_SIZE),
> +			(uint64_t)DTOBT(xi.logBBsize));
>  		usage();
> -	} else if (!logsize && xi.logBBsize > 0) {
> +	} else if (!logbytes && xi.logBBsize > 0) {
>  		logblocks = DTOBT(xi.logBBsize);
> -	} else if (logsize && !xi.logdev && !loginternal) {
> +	} else if (logbytes && !xi.logdev && !loginternal) {
>  		fprintf(stderr,
>  			_("size specified for non-existent log subvolume\n"));
>  		usage();
> -	} else if (loginternal && logsize && logblocks >= dblocks) {
> +	} else if (loginternal && logbytes && logblocks >= dblocks) {
>  		fprintf(stderr, _("size %"PRIu64" too large for internal log\n"),
>  			logblocks);
>  		usage();
>  	} else if (!loginternal && !xi.logdev) {
>  		logblocks = 0;
> -	} else if (loginternal && !logsize) {
> +	} else if (loginternal && !logbytes) {
>  
>  		if (dblocks < GIGABYTES(1, blocklog)) {
>  			/* tiny filesystems get minimum sized logs. */
> @@ -2741,7 +2733,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
>  		 * Readjust the log size to fit within an AG if it was sized
>  		 * automatically.
>  		 */
> -		if (!logsize) {
> +		if (!logbytes) {
>  			logblocks = MIN(logblocks,
>  					libxfs_alloc_ag_max_usable(mp));
>  
> 

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

* Re: [PATCH 01/12] mkfs: Save raw user input field to the opts struct
  2017-04-23 18:54 ` [PATCH 01/12] mkfs: Save raw user input field to the opts struct Jan Tulak
@ 2017-04-25 17:38   ` Eric Sandeen
  0 siblings, 0 replies; 59+ messages in thread
From: Eric Sandeen @ 2017-04-25 17:38 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 4/23/17 1:54 PM, Jan Tulak wrote:
> Save exactly what the user gave us for every option.  This way, we will
> never lose the information if we need it to print back an issue.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Hm but no users yet?  I suppose that's ok.  Just adding the infrastructure
here.

Reviewed-by: Eric Sandeen <sandeen@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 83a04fc..84674d5 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -119,6 +119,10 @@ uint64_t		sectorsize;
>   *     A special SUBOPT_NEEDS_VAL can be used to require a user-given
>   *     value in any case.
>   *
> + *   raw_input INTERNAL
> + *     Filled raw string from the user, so we never lose that information e.g.
> + *     to print it back in case of an issue.
> + *
>   * !!! NOTE ==================================================================
>   *
>   * If you are adding a new option, or changing an existing one,
> @@ -141,6 +145,7 @@ struct opt_params {
>  		uint64_t	minval;
>  		uint64_t	maxval;
>  		uint64_t	defaultval;
> +		const char	*raw_input;
>  	}		subopt_params[MAX_SUBOPTS];
>  };
>  
> @@ -748,6 +753,18 @@ struct opt_params mopts = {
>   */
>  #define WHACK_SIZE (128 * 1024)
>  
> +static inline void
> +set_conf_raw(struct opt_params *opt, int subopt, const char *value)
> +{
> +	opt->subopt_params[subopt].raw_input = value;
> +}
> +
> +static inline const char *
> +get_conf_raw(const struct opt_params *opt, int subopt)
> +{
> +	return opt->subopt_params[subopt].raw_input;
> +}
> +
>  /*
>   * Convert lsu to lsunit for 512 bytes blocks and check validity of the values.
>   */
> 

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-23 18:54 ` [PATCH 04/12] mkfs: merge tables for opts parsing into one table Jan Tulak
  2017-04-25  3:04   ` Luis R. Rodriguez
@ 2017-04-25 21:45   ` Eric Sandeen
  2017-04-26  4:09     ` Eric Sandeen
  2017-04-26  8:14     ` Jan Tulak
  1 sibling, 2 replies; 59+ messages in thread
From: Eric Sandeen @ 2017-04-25 21:45 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 4/23/17 1:54 PM, Jan Tulak wrote:
> Merge separate instances of opt_params into one indexable table. Git
> makes this patch looks a bit more complicated, but it does not change
> values or structure of anything else. It only moves all the "struct
> opt_params dopts = {...}", changes indentation for these substructures
> and replaces their usage (dopts -> opts[OPT_D]).

This looks correct.  Can you remind me why it helps?  :)
(the commit log says what you did but not why you did it)


One thing I wondered about to idiot-proof the code a bit (in some
other patch, not this one, but while I'm looking at it):

What about instead of:

    switch (getsubopt(&p, subopts, &value)) {
    case OPT1:
            opt1 = getnum(value, &opts, OPT1);
    case OPT2:
            opt2 = getnum(value, &opts, OPT2);
				...

and making sure there's never a mismatch between the case value and the
value passed to getnum, you could do something like:

    int so = getsubopt(&p, subopts, &value);

    switch (so) {
    case OPT1:
            opt1 = getnum(value, &opts, so);
    case OPT2:
            opt2 = getnum(value, &opts, so);
				...

so that you can never mismatch & pass in the wrong subopt for option
checking; it will always be the subopt matched by the case statement.

I just considered that as I reviewed it and found myself mentally
checking that each case matched.

Thanks,
-Eric

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

* Re: [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options
  2017-04-25  8:37     ` Jan Tulak
@ 2017-04-26  0:45       ` Luis R. Rodriguez
  2017-04-26  9:09         ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  0:45 UTC (permalink / raw)
  To: Jan Tulak; +Cc: Luis R. Rodriguez, linux-xfs

On Tue, Apr 25, 2017 at 10:37:57AM +0200, Jan Tulak wrote:
> On Tue, Apr 25, 2017 at 7:27 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> > On Sun, Apr 23, 2017 at 08:54:59PM +0200, Jan Tulak wrote:
> >> Remove variables that can be replaced with a direct access to the opts table,
> >> so we have it all in a single place, acessible from anywhere.
> >>
> >> In future, we can remove some passing of values forth and back, but now limit
> >> the changes to simple replacement without a change in the logic.
> >
> > What do you mean passing of values here, as an example with bopts ?
> 
> Passing it to a function and then retrieving with pointers, e.g. change this
> 
> static void
> calc_stripe_factors(
>         int             dsu,
>         int             dsw,
>         int             dsectsz,
>         int             lsu,
>         int             lsectsz,
>         uint64_t        *dsunit,
>         uint64_t        *dswidth,
>         uint64_t        *lsunit)
> 
> 
> to this
> 
> static void
> calc_stripe_factors(struct opt_params * opts) // or no argument at all...

Ah, great, but note that not all options have a respective struct subopt_param,
that is -- we don't allow for them to be specified in the command line, but they
are rather collateral values, which depend on other struct subopt_param's. The
lsunit is one example. Its why I ended up just stuffing all of the needed parameters
into one data struct: struct mkfs_xfs_opts. Your patches round up direct
parameters associated with struct subopt_param on the struct opt_params.

Where would things like lsunit be stuffed into ?

> Which btw needs to be updated anyway because it is still using int...

Right I see.

> >> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> >> index 362c9b4..6857c30 100644
> >> --- a/mkfs/xfs_mkfs.c
> >> +++ b/mkfs/xfs_mkfs.c
> >> @@ -1485,15 +1480,12 @@ main(
> >>       int                     argc,
> >>       char                    **argv)
> >>  {
> >> -     uint64_t                agcount;
> >>       xfs_agf_t               *agf;
> >>       xfs_agi_t               *agi;
> >>       xfs_agnumber_t          agno;
> >> -     uint64_t                agsize;
> >>       xfs_alloc_rec_t         *arec;
> >>       struct xfs_btree_block  *block;
> >>       bool                    blflag;
> >
> > Note: blflag
> >
> >> -     uint64_t                blocklog;
> >>       bool                    bsflag;
> >
> > Note: bsflag
> >
> >>       memset(&fsx, 0, sizeof(fsx));
> >> @@ -1629,6 +1613,7 @@ main(
> >>                       break;
> >>               case 'b':
> >>                       p = optarg;
> >> +                     uint64_t tmp;
> >>                       while (*p != '\0') {
> >>                               char    **subopts =
> >>                                               (char **)opts[OPT_B].subopts;
> >> @@ -1636,19 +1621,17 @@ main(
> >>
> >>                               switch (getsubopt(&p, subopts, &value)) {
> >>                               case B_LOG:
> >> -                                     blocklog = parse_conf_val(OPT_B, B_LOG,
> >> -                                                               value);
> >> -                                     blocksize = 1 << blocklog;
> >> +                                     tmp = parse_conf_val(OPT_B, B_LOG,
> >> +                                                          value);
> >> +                                     set_conf_val(OPT_B, B_SIZE, 1 << tmp);
> >>                                       blflag = 1;
> >
> > This is a collateral variable set when blog is set. If we have to parse the
> > blog again, it means similar code would be needed.
> >
> >> -                                     set_conf_val(OPT_B, B_SIZE, blocksize);
> >>                                       break;
> >>                               case B_SIZE:
> >> -                                     blocksize = parse_conf_val(OPT_B,
> >> -                                                                B_SIZE,
> >> -                                                                value);
> >> -                                     blocklog = libxfs_highbit32(blocksize);
> >> +                                     tmp = parse_conf_val(OPT_B, B_SIZE,
> >> +                                                          value);
> >> +                                     set_conf_val(OPT_B, B_LOG,
> >> +                                             libxfs_highbit32(tmp));
> >>                                       bsflag = 1;
> >
> > Likewise for bsflag.
> >
> >> -                                     set_conf_val(OPT_B, B_LOG, blocklog);
> >>                                       break;
> >>                               default:
> >>                                       unknown('b', value);
> >
> > What I'm questioning is whether or not it makes sense instead for parse_conf_val()
> > to return void and do all this meddling for us, this would require stuffing any
> > collateral variables into a struct and passing that to parse_conf_val and using
> > it on main() as well.
> 
> Again, this (both logic and flags) is something I want to do later.

Ah great.

> And in fact, I think that perhaps the whole manual loop in main() can
> be removed in the future once the case logic is moved elsewhere.
> Because then we can extract specific cases from the opts table with
> the help of some helper functions...

Nice yes that would be good.

OK, understood, just so its clear, only once all the direct subopts and collateral
values for subopts for the following main opts are stuffed into a data structure
somehow (and perhaps the logic of processing them are stuffed into a routine) can
the mkfs.xfs.conf blend in well, given the same logic would be used:

                case 'b':                                                       
                case 'd':                                                       
                case 'i':                                                       
                case 'l':                                                       
                case 'm':                                                       
                case 'n':                                                       
                case 'r':                                                       
                case 's':                                                       
                        p = optarg;                                             
                        parse_subopts(c, p, &params); 

So I'll have to hold off my patches until something like this is available, but
knowing its an end goal helps in the review process.

  Luis

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

* Re: [PATCH 05/12] mkfs: extend opt_params with a value field
  2017-04-25  9:39       ` Jan Tulak
@ 2017-04-26  1:04         ` Luis R. Rodriguez
  2017-04-26  8:51           ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  1:04 UTC (permalink / raw)
  To: Jan Tulak; +Cc: Luis R. Rodriguez, linux-xfs

On Tue, Apr 25, 2017 at 11:39:00AM +0200, Jan Tulak wrote:
> And rather than submitting repeatedly new versions of the whole
> patch... how about this?
> 
>  *
>  *   value OPTIONAL
>  *     The actual value used in computations and for creating the filesystem.
>  *     It is filled with user input and anything you write here now is

I think its easier to read if you are clear from the start user input is
optional, and so a default value is used first, and use input overrides
these initial system defaults.

>  *     overwritten if the user specifies the subopt. But he does not,
> then whatever

"But he does not", I guess you meant, "But if he does not"...

>  *     you put there is used as the default. Can be omitted if the default
>  *     is 0.

Hm, how about:

The actual value used in computations for creating the filesystem.
This is initialized with sensible default values, if initialized to 0
the value is considered disabled. User input can optionally override
default values. If the field is a string and not a number, the value
is set to a positive non-zero number when user input has been supplied.

>  *     (If the field is a string and not a number, this value is set to
>  *     a positive non-zero number on an user input.)
> 
> And for the commit message, a bit shortened version:
> 
> Add a new field int opt_params - value - which is the actual value
> used in computations and for creating the filesystem. It is filled
> with user input if the user specifies the subopt. But he does not,
> then whatever you put there is used as the default.

Modulo "But he does not"/ "but if no user input is not passed then
the originally set defaults will be used"

  Luis

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

* Re: [PATCH 05/12] mkfs: extend opt_params with a value field
  2017-04-25  8:04     ` Jan Tulak
  2017-04-25  9:39       ` Jan Tulak
@ 2017-04-26  1:10       ` Luis R. Rodriguez
  2017-04-26  2:50         ` Eric Sandeen
  1 sibling, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  1:10 UTC (permalink / raw)
  To: Jan Tulak; +Cc: Luis R. Rodriguez, linux-xfs

On Tue, Apr 25, 2017 at 10:04:39AM +0200, Jan Tulak wrote:
> On Tue, Apr 25, 2017 at 5:13 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> > On Sun, Apr 23, 2017 at 08:54:56PM +0200, Jan Tulak wrote:
> >
> >> and anything you write here now is
> >> + *     overwritten if user specifies the subopt. (If the user input is a string
> >> + *     and not a number, this value is set to a positive non-zero number.)
> >> + *
> >>   * !!! NOTE ==================================================================
> >>   *
> >>   * If you are adding a new option, or changing an existing one,
> >> @@ -152,6 +158,7 @@ struct opt_params {
> >>               uint64_t        maxval;
> >>               uint64_t        flagval;
> >>               const char      *raw_input;
> >> +             uint64_t        value;
> >>       }               subopt_params[MAX_SUBOPTS];
> >>  } opts[MAX_OPTS] = {
> >>  #define OPT_B        0
> >
> > It would seem rather unfair to define this this but not use it in the patch ?
> 
> I'm still trying to find out when exactly should I make something two
> patches and when one, and it seems to shift case by case... I tried to
> separate the adding of new things and rewriting of the existing code,
> but do you think, in this case, the new thing is too trivial to have a
> standalone patch?

Ah, I see, this was split out to be separate given a slew of subopts in turn
later use it. The nasty alternative for review would be to have all subopts
converted in one shot. I suppose a middle ground would be to have this patch
squashed with just one of the subopt users, and then each other subopt ported
atomically. That would make the addition of the value and definition in effect
as soon as its added.

Just my 0.02 CRC but its up to Eric as this is rather subjective and tree dependent.

  Luis

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-25 13:28       ` Eric Sandeen
@ 2017-04-26  1:38         ` Luis R. Rodriguez
  2017-04-26  1:45           ` Luis R. Rodriguez
  2017-04-26  2:00           ` Eric Sandeen
  0 siblings, 2 replies; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  1:38 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Jan Tulak, Luis R. Rodriguez, linux-xfs

On Tue, Apr 25, 2017 at 08:28:23AM -0500, Eric Sandeen wrote:
> On 4/25/17 2:45 AM, Jan Tulak wrote:
> > On Tue, Apr 25, 2017 at 5:04 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> >> On Sun, Apr 23, 2017 at 08:54:55PM +0200, Jan Tulak wrote:
> >>> Merge separate instances of opt_params into one indexable table. Git
> >>> makes this patch looks a bit more complicated, but it does not change
> >>> values or structure of anything else. It only moves all the "struct
> >>> opt_params dopts = {...}", changes indentation for these substructures
> >>> and replaces their usage (dopts -> opts[OPT_D]).
> >>>
> >>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> >>> ---
> >>>  mkfs/xfs_mkfs.c | 1316 +++++++++++++++++++++++++++++--------------------------
> >>>  1 file changed, 683 insertions(+), 633 deletions(-)
> >>>
> >>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> >>> index 7a72b11..513e106 100644
> >>> --- a/mkfs/xfs_mkfs.c
> >>> +++ b/mkfs/xfs_mkfs.c
> >>> @@ -42,6 +42,7 @@ static int  ispow2(unsigned int i);
> >>>  uint64_t             blocksize;
> >>>  uint64_t             sectorsize;
> >>>
> >>> +#define MAX_OPTS     16
> >>
> >> This is fragile, every time a new opt is added this needs to be updated
> 
> <pedantic>There are only 8 now, so there are still 8 free slots</pedantic>
> 
> >> and so is the index, and we should be pedantic over not going out of bounds.
> >> We could instead use a flexible array and compute the max opts at run time
> >> as a global. This way the max opts is always updated automatically.
> 
> I don't think it's all that fragile;

We can avoid such compilation warnings.

> this is used only for a global structure
> declaration & initialization.

*Currently used*. I'll later use it to bail out early if the mkfs.xfs.conf stat
file size is too big compared to what we max expect prior letting a library
chew on data. This lets us bail out early instead of having the library stall.
Its a rare corner case but can easily be considered and dealt with.

> If you add too many new members to opt_params,
> compilation will issue warnings:
> 
> xfs_mkfs.c:342: warning: excess elements in array initializer
> xfs_mkfs.c:342: warning: (near initialization for ‘opts’)
> xfs_mkfs.c:424: warning: excess elements in array initializer
> xfs_mkfs.c:424: warning: (near initialization for ‘opts’)
> xfs_mkfs.c:543: warning: excess elements in array initializer
> xfs_mkfs.c:543: warning: (near initialization for ‘opts’)
> ...

Warnings are not treated as failures though AFAICT, and if you fly
by through then yes, its fragile and will crash with out of bound
array access / segfault.

> and it will be quite obvious, at which point you can bump it up before
> you send that patch.  ;)

Mater of taste I guess, but then again I tend to only deal with kernel code and
to me the above is just recipe for disaster.

> Anyway, because the the definition is never used at runtime, there's
> no need to be computing it at runtime, either.

Not currently used at run time. I do plan on using it later at run time but its
for a rather odd corner case to avoid stalls on parsing  a large file when we
know its just not possible to be parsing it.

> > Mmm, that is a good idea and I see no issue with it. But I'm not sure
> > if it is worth of rewriting this patch as we already use MAX_SUBOPTS
> > anyway. Rather I see it as a standalone patch in the next set. What do
> > you think?
> 
> I think that given how it's used, there is no real need for any extra
> complexity.

I find it much simpler, but that seems to be subjective.

> In any case, any changes around this behavior would certainly
> be part of a different patch, because you'd want to be consistent with all
> the other structure initializers, and it would be a functionally separate
> change if it is warranted at all.

The opt_params are separate today though, this patch folds them in together,
what I propose is just to use a flexible array to avoid an explicit size
from the start. Not sure how much more functional of a change that is ?

  Luis

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

* Re: [PATCH 06/12] mkfs: create get/set functions for opts table
  2017-04-25  8:11     ` Jan Tulak
@ 2017-04-26  1:43       ` Luis R. Rodriguez
  0 siblings, 0 replies; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  1:43 UTC (permalink / raw)
  To: Jan Tulak; +Cc: Luis R. Rodriguez, linux-xfs

On Tue, Apr 25, 2017 at 10:11:06AM +0200, Jan Tulak wrote:
> On Tue, Apr 25, 2017 at 5:40 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> > On Sun, Apr 23, 2017 at 08:54:57PM +0200, Jan Tulak wrote:
> >> Add functions that can be used to get/set values to opts table.
> >>
> >> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> >>
> >> ---
> >>  mkfs/xfs_mkfs.c | 32 ++++++++++++++++++++++++++++++++
> >>  1 file changed, 32 insertions(+)
> >>
> >> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> >> index c2ffd91..4caf93c 100644
> >> --- a/mkfs/xfs_mkfs.c
> >> +++ b/mkfs/xfs_mkfs.c
> >> @@ -786,6 +786,38 @@ get_conf_raw(int opt, int subopt)
> >>       return opts[opt].subopt_params[subopt].raw_input;
> >>  }
> >>
> >> +static uint64_t getnum(const char *str, struct opt_params *opts, int index);
> >
> > Why not just move getnum() above here. Forward declarations IMHO should not be
> > needed unless we have odd inclusion issues and I don't think that's the case
> > here ?
> 
> Getnum requires set_conf_raw and illegal_option, but it seems that
> they could be moved too. I think there is no circle dependency, I just
> didn't want to move so many lines when I can do one declaration. But
> if the declaration is an issue, I can shuffle the ~80 lines the three
> functions takes.

If we can avoid it I don't see why not, the forward declarations, if not needed
IMHO just leads to lazy code practices. The shift of code up above could /
should be a separate atomic patch as it would be easier to review later.

  Luis

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-26  1:38         ` Luis R. Rodriguez
@ 2017-04-26  1:45           ` Luis R. Rodriguez
  2017-04-26  2:00           ` Eric Sandeen
  1 sibling, 0 replies; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  1:45 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Eric Sandeen, Jan Tulak, linux-xfs

On Wed, Apr 26, 2017 at 03:38:15AM +0200, Luis R. Rodriguez wrote:
> On Tue, Apr 25, 2017 at 08:28:23AM -0500, Eric Sandeen wrote:
> > On 4/25/17 2:45 AM, Jan Tulak wrote:
> > > On Tue, Apr 25, 2017 at 5:04 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> > >> On Sun, Apr 23, 2017 at 08:54:55PM +0200, Jan Tulak wrote:
> > >>> Merge separate instances of opt_params into one indexable table. Git
> > >>> makes this patch looks a bit more complicated, but it does not change
> > >>> values or structure of anything else. It only moves all the "struct
> > >>> opt_params dopts = {...}", changes indentation for these substructures
> > >>> and replaces their usage (dopts -> opts[OPT_D]).
> > >>>
> > >>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> > >>> ---
> > >>>  mkfs/xfs_mkfs.c | 1316 +++++++++++++++++++++++++++++--------------------------
> > >>>  1 file changed, 683 insertions(+), 633 deletions(-)
> > >>>
> > >>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> > >>> index 7a72b11..513e106 100644
> > >>> --- a/mkfs/xfs_mkfs.c
> > >>> +++ b/mkfs/xfs_mkfs.c
> > >>> @@ -42,6 +42,7 @@ static int  ispow2(unsigned int i);
> > >>>  uint64_t             blocksize;
> > >>>  uint64_t             sectorsize;
> > >>>
> > >>> +#define MAX_OPTS     16
> > >>
> > >> This is fragile, every time a new opt is added this needs to be updated
> > 
> > <pedantic>There are only 8 now, so there are still 8 free slots</pedantic>
> > 
> > >> and so is the index, and we should be pedantic over not going out of bounds.
> > >> We could instead use a flexible array and compute the max opts at run time
> > >> as a global. This way the max opts is always updated automatically.
> > 
> > I don't think it's all that fragile;
> 
> We can avoid such compilation warnings.

Oh and save memory by 8 struct opt_params. Why not.

  Luis

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

* Re: [PATCH 07/12] mkfs: save user input values into opts
  2017-04-25  8:16     ` Jan Tulak
@ 2017-04-26  1:47       ` Luis R. Rodriguez
  0 siblings, 0 replies; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  1:47 UTC (permalink / raw)
  To: Jan Tulak; +Cc: Luis R. Rodriguez, linux-xfs

On Tue, Apr 25, 2017 at 10:16:13AM +0200, Jan Tulak wrote:
> On Tue, Apr 25, 2017 at 7:19 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> > On Sun, Apr 23, 2017 at 08:54:58PM +0200, Jan Tulak wrote:
> >> Save the parsed values from users into the opts table.
> >>
> >> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> >> ---
> >>  mkfs/xfs_mkfs.c | 260 +++++++++++++++++++++++++++++++++++---------------------
> >>  1 file changed, 165 insertions(+), 95 deletions(-)
> >>
> >> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> >> index 4caf93c..362c9b4 100644
> >> --- a/mkfs/xfs_mkfs.c
> >> +++ b/mkfs/xfs_mkfs.c
> >> @@ -1636,16 +1636,19 @@ main(
> >>
> >>                               switch (getsubopt(&p, subopts, &value)) {
> >>                               case B_LOG:
> >> -                                     blocklog = getnum(value, &opts[OPT_B],
> >> -                                                             B_LOG);
> >> +                                     blocklog = parse_conf_val(OPT_B, B_LOG,
> >> +                                                               value);
> >>                                       blocksize = 1 << blocklog;
> >>                                       blflag = 1;
> >> +                                     set_conf_val(OPT_B, B_SIZE, blocksize);
> >>                                       break;
> >>                               case B_SIZE:
> >> -                                     blocksize = getnum(value, &opts[OPT_B],
> >> -                                                        B_SIZE);
> >> +                                     blocksize = parse_conf_val(OPT_B,
> >> +                                                                B_SIZE,
> >> +                                                                value);
> >>                                       blocklog = libxfs_highbit32(blocksize);
> >>                                       bsflag = 1;
> >> +                                     set_conf_val(OPT_B, B_LOG, blocklog);
> >>                                       break;
> >>                               default:
> >>                                       unknown('b', value);
> >
> > This still means that users of parse_conf_val() must copy the same code
> > in each case in the above to handle collateral values: if blocklog was
> > passed we update blocklog *and* blocksize *and* bsflag. Likewise if blocksize
> > was passed we must update blocksize *and* blocklog *and* blflag. What I had
> > done on the mkfs.xfs.conf series is put all this functionality into a helper,
> > and to do this move all needed vars into a struct. You are moving all possible
> > user params to a option specific table, however the collateral parameters are
> > kept inside main().
> >
> > I'll need to do the same again: move the logic above to a helper and move
> > collateral parameters to a struct, or this could be done in your series by
> > having parse_conf_val() handle all the needed logic provided say an extra
> > struct param is passed -- or though some other means.
> >
> > Duplicating the functionality I'm sure is not desirable, how we handle this
> > subjective so I'll leave it up to you to advise how you'd like to proceed,
> > but let me know if the above consideration is clear.
> >
> >   Luis
> 
> This is something I want to do, but let's get there step by step.
> First make the table working, then remove pieces from the main. If I
> try to do everything at once, it won't be ever finished. ;-)

Sure, it was not clear if this work was just it, thanks for the clarification.
Will review further patches with this in mind!

  Luis

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-26  1:38         ` Luis R. Rodriguez
  2017-04-26  1:45           ` Luis R. Rodriguez
@ 2017-04-26  2:00           ` Eric Sandeen
  2017-04-26  8:01             ` Luis R. Rodriguez
  1 sibling, 1 reply; 59+ messages in thread
From: Eric Sandeen @ 2017-04-26  2:00 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Jan Tulak, linux-xfs

On 4/25/17 8:38 PM, Luis R. Rodriguez wrote:
> On Tue, Apr 25, 2017 at 08:28:23AM -0500, Eric Sandeen wrote:
>> On 4/25/17 2:45 AM, Jan Tulak wrote:
>>> On Tue, Apr 25, 2017 at 5:04 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
>>>> On Sun, Apr 23, 2017 at 08:54:55PM +0200, Jan Tulak wrote:
>>>>> Merge separate instances of opt_params into one indexable table. Git
>>>>> makes this patch looks a bit more complicated, but it does not change
>>>>> values or structure of anything else. It only moves all the "struct
>>>>> opt_params dopts = {...}", changes indentation for these substructures
>>>>> and replaces their usage (dopts -> opts[OPT_D]).
>>>>>
>>>>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>>>>> ---
>>>>>  mkfs/xfs_mkfs.c | 1316 +++++++++++++++++++++++++++++--------------------------
>>>>>  1 file changed, 683 insertions(+), 633 deletions(-)
>>>>>
>>>>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>>>>> index 7a72b11..513e106 100644
>>>>> --- a/mkfs/xfs_mkfs.c
>>>>> +++ b/mkfs/xfs_mkfs.c
>>>>> @@ -42,6 +42,7 @@ static int  ispow2(unsigned int i);
>>>>>  uint64_t             blocksize;
>>>>>  uint64_t             sectorsize;
>>>>>
>>>>> +#define MAX_OPTS     16
>>>>
>>>> This is fragile, every time a new opt is added this needs to be updated
>>
>> <pedantic>There are only 8 now, so there are still 8 free slots</pedantic>
>>
>>>> and so is the index, and we should be pedantic over not going out of bounds.
>>>> We could instead use a flexible array and compute the max opts at run time
>>>> as a global. This way the max opts is always updated automatically.
>>
>> I don't think it's all that fragile;
> 
> We can avoid such compilation warnings.

Well, post the proposed patch when appropriate, and it can go through review.

...

>> In any case, any changes around this behavior would certainly
>> be part of a different patch, because you'd want to be consistent with all
>> the other structure initializers, and it would be a functionally separate
>> change if it is warranted at all.
> 
> The opt_params are separate today though, this patch folds them in together,
> what I propose is just to use a flexible array to avoid an explicit size
> from the start. Not sure how much more functional of a change that is ?

Because it'd be inconsistent with the other array declarations.

Prior to this patch we had 2 #defines to declare sizes of global
arrays:

#define MAX_SUBOPTS	16
	const char	*subopts[MAX_SUBOPTS];
	}		subopt_params[MAX_SUBOPTS];

#define MAX_CONFLICTS	8
		int		conflicts[MAX_CONFLICTS];

now we add a third:

#define MAX_OPTS	16
} opts[MAX_OPTS] = {

If you're not a fan of #defines to size global arrays that's ok, but
let's be consistent and change them all at once, and not change one
of the 3 as a side-effect of collapsing the separate opts structures
into one.

For now, let's follow the pattern of the existing code, and submit a 
comprehensive functional patch to address this separate change.

Small, reviewable, distinct, functional changes.

Thanks,
-Eric

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

* Re: [PATCH 00/12] mkfs: save user input into opts table
  2017-04-25 16:20 ` Eric Sandeen
@ 2017-04-26  2:02   ` Luis R. Rodriguez
  2017-04-26  2:17     ` Eric Sandeen
  0 siblings, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  2:02 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Jan Tulak, linux-xfs

On Tue, Apr 25, 2017 at 11:20:34AM -0500, Eric Sandeen wrote:
> On 4/23/17 1:54 PM, Jan Tulak wrote:
> > Hi guys,
> > 
> > I decided to split my big patchset into more smaller ones. So, this is the
> > first set. It adds set/get functions similar to Dave's suggestion, to save and
> > retrieve user values to and from the big opts table and prepares the ground for
> > future patches.
> > 
> > 
> > It is a mix of patches I already submitted and new ones:
> > Patches 2, 3, 4, 5 are just slightly modified to fix their issues.
> > Other patches are new.
> > 
> > The last few patches could be merged into one, because it should only
> > substitute variables for get/set calls, but because there are so many
> > places where the changes occurs, I split them into smaller chunks,
> > making it (hopefully) easier for you to review.
> > 
> > This patchset requires my two previous uint patches.
> 
> Just to be clear, those were NAK'd, I believe, so these may need
> to be rebased without them.

I checked and I see concerns for the data types used expressed but from
what I can tell Jan addressed these concerns and followed up with
subsequent patches. Perhaps it was not clear given he only respun one
of the patches multiple times.

Not sure, but the new bool *processing* request you made though seem to
be a type of change that can perhaps be folded in as part of this initial
series.

  Luis

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

* Re: [PATCH 00/12] mkfs: save user input into opts table
  2017-04-26  2:02   ` Luis R. Rodriguez
@ 2017-04-26  2:17     ` Eric Sandeen
  0 siblings, 0 replies; 59+ messages in thread
From: Eric Sandeen @ 2017-04-26  2:17 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Jan Tulak, linux-xfs

On 4/25/17 9:02 PM, Luis R. Rodriguez wrote:
> On Tue, Apr 25, 2017 at 11:20:34AM -0500, Eric Sandeen wrote:
>> On 4/23/17 1:54 PM, Jan Tulak wrote:
>>> Hi guys,
>>>
>>> I decided to split my big patchset into more smaller ones. So, this is the
>>> first set. It adds set/get functions similar to Dave's suggestion, to save and
>>> retrieve user values to and from the big opts table and prepares the ground for
>>> future patches.
>>>
>>>
>>> It is a mix of patches I already submitted and new ones:
>>> Patches 2, 3, 4, 5 are just slightly modified to fix their issues.
>>> Other patches are new.
>>>
>>> The last few patches could be merged into one, because it should only
>>> substitute variables for get/set calls, but because there are so many
>>> places where the changes occurs, I split them into smaller chunks,
>>> making it (hopefully) easier for you to review.
>>>
>>> This patchset requires my two previous uint patches.
>>
>> Just to be clear, those were NAK'd, I believe, so these may need
>> to be rebased without them.
> 
> I checked and I see concerns for the data types used expressed but from
> what I can tell Jan addressed these concerns and followed up with
> subsequent patches. Perhaps it was not clear given he only respun one
> of the patches multiple times.

I apologize - somehow I missed the re-submission.  I'll take a look.

-Eric

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

* Re: [PATCH 05/12] mkfs: extend opt_params with a value field
  2017-04-26  1:10       ` Luis R. Rodriguez
@ 2017-04-26  2:50         ` Eric Sandeen
  2017-04-26  8:52           ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Eric Sandeen @ 2017-04-26  2:50 UTC (permalink / raw)
  To: Luis R. Rodriguez, Jan Tulak; +Cc: linux-xfs

On 4/25/17 8:10 PM, Luis R. Rodriguez wrote:
> On Tue, Apr 25, 2017 at 10:04:39AM +0200, Jan Tulak wrote:
>> On Tue, Apr 25, 2017 at 5:13 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
>>> On Sun, Apr 23, 2017 at 08:54:56PM +0200, Jan Tulak wrote:
>>>
>>>> and anything you write here now is
>>>> + *     overwritten if user specifies the subopt. (If the user input is a string
>>>> + *     and not a number, this value is set to a positive non-zero number.)
>>>> + *
>>>>   * !!! NOTE ==================================================================
>>>>   *
>>>>   * If you are adding a new option, or changing an existing one,
>>>> @@ -152,6 +158,7 @@ struct opt_params {
>>>>               uint64_t        maxval;
>>>>               uint64_t        flagval;
>>>>               const char      *raw_input;
>>>> +             uint64_t        value;
>>>>       }               subopt_params[MAX_SUBOPTS];
>>>>  } opts[MAX_OPTS] = {
>>>>  #define OPT_B        0
>>>
>>> It would seem rather unfair to define this this but not use it in the patch ?
>>
>> I'm still trying to find out when exactly should I make something two
>> patches and when one, and it seems to shift case by case... I tried to
>> separate the adding of new things and rewriting of the existing code,
>> but do you think, in this case, the new thing is too trivial to have a
>> standalone patch?
> 
> Ah, I see, this was split out to be separate given a slew of subopts in turn
> later use it. The nasty alternative for review would be to have all subopts
> converted in one shot. I suppose a middle ground would be to have this patch
> squashed with just one of the subopt users, and then each other subopt ported
> atomically. That would make the addition of the value and definition in effect
> as soon as its added.
> 
> Just my 0.02 CRC but its up to Eric as this is rather subjective and tree dependent.

I think the way Jan did this is fine.  Ideally the commit would explain a bit more,
i.e. "This patch simply adds the value field.  Subsequent patches will utilize
this new field."

Then the reviewers know what to expect from the start, and we avoid the back and
forth of figuring out why it was done as it was done.  ;)

However, I think 5 & 6 could easily be combined - add the field and the routines
to manipulate it, /then/ start adding users of that new infrastructure.

I haven't really reviewed from here on out yet, but from a "how should I break
up patches" point of view, that's my ... $0.02.  :)

-Eric

> 
>   Luis
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-25 21:45   ` Eric Sandeen
@ 2017-04-26  4:09     ` Eric Sandeen
  2017-04-26  8:14     ` Jan Tulak
  1 sibling, 0 replies; 59+ messages in thread
From: Eric Sandeen @ 2017-04-26  4:09 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 4/25/17 4:45 PM, Eric Sandeen wrote:
> and making sure there's never a mismatch between the case value and the
> value passed to getnum, you could do something like:
> 
>     int so = getsubopt(&p, subopts, &value);
> 
>     switch (so) {
>     case OPT1:
>             opt1 = getnum(value, &opts, so);
>     case OPT2:
>             opt2 = getnum(value, &opts, so);

(but not "so" - not sure why I typed that.  Perhaps "subopt")

-Eric

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

* Re: [PATCH 02/12] mkfs: rename defaultval to flagval in opts
  2017-04-25 16:52   ` Eric Sandeen
@ 2017-04-26  7:30     ` Jan Tulak
  2017-04-26 13:02       ` Eric Sandeen
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-26  7:30 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Tue, Apr 25, 2017 at 6:52 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 4/23/17 1:54 PM, Jan Tulak wrote:
>> The old name 'defaultval' was misleading - it is not the default value,
>> but the value the option has when used as a flag by an user.
>
> The value should only ever be 0 or 1, correct?

Not necessarily. I think we are not using anything else, but
technically, it is possible to have any number here. I admit it is
hard to came up with any useful case for what we have in mkfs, though.

>
> Ok, so I see something interesting here:
>
> # grep "flagval = " mkfs/xfs_mkfs.c | sort | uniq -c
>       1                           .flagval = 0,
>       1                         .flagval = 0,
>      14                           .flagval = 1,
>      40                           .flagval = SUBOPT_NEEDS_VAL,
>
> of the 56 subopts, only 16 are treated as a flag, and only 2 default
> to 0, while the rest default to 1.
>
> Those 2 seem like outliers: -m rmapbt and -m reflink.  What's
> going on there?
>
> In every other case where there is a subopt which is actually a
> boolean flag, a bare specification without a value means "enable
> the feature."
>
> It seems very unintuitive to have:
>
> -X THING1 -> THING1 is enabled 14 times, but
> -X THING12 - THING2 is still /disabled/ in only 2 cases
>
> I'd argue that "-m rmapbt" and "-m reflink" leaving those features
> /disabled/ is a bug, due to misunderstanding of what "defaultval"
> means, and that they should be fixed to behave like the other 14
> boolean flags.

I agree. It looks this way...

>
> i.e. I'd argue that a bare boolean flag specification should /always/
> enable the feature.  At that point, you can say within your code
> "if min = 0 and max = 1, this is a boolean, and the flag may be specified
> without a value, in which case the value is set to 1, and the feature
> is enabled."
>
> At that point you don't need this extra structure member, and you won't
> have to re-state it 56 times, thus simplifying the code.
>
> What do you think?  I'd happily review and merge 2 patches, which:
>
> 1) Makes rmapbt and reflink behave like every other boolean flag, and
>
This sounds reasonable.

> 2) Removes "defaultval" altogether, and uses min=0/max=1 as a sign that
>    the option is a boolean, with a bare flag name allowed to enable it.
>
I wonder if a .is_flag = true (and no other min/max/defaultval...)
wouldn't be better solution. the min=0/max=1 detection is a bit
implicit and may not be apparent in the future. If we limit flags to
0/1 values, then defaultval can be removed either way, but it is clear
on the first glance what the option does.

Jan

> -Eric
>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>> ---
>>  mkfs/xfs_mkfs.c | 120 ++++++++++++++++++++++++++++----------------------------
>>  1 file changed, 60 insertions(+), 60 deletions(-)
>>
>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>> index 84674d5..0a795a6 100644
>> --- a/mkfs/xfs_mkfs.c
>> +++ b/mkfs/xfs_mkfs.c
>> @@ -112,7 +112,7 @@ uint64_t          sectorsize;
>>   *     to zero. But if one value is different: minval=0 and maxval=1,
>>   *     then it is OK.)
>>   *
>> - *   defaultval MANDATORY
>> + *   flagval MANDATORY
>>   *     The value used if user specifies the subopt, but no value.
>>   *     If the subopt accepts some values (-d file=[1|0]), then this
>>   *     sets what is used with simple specifying the subopt (-d file).
>> @@ -144,7 +144,7 @@ struct opt_params {
>>               int             conflicts[MAX_CONFLICTS];
>>               uint64_t        minval;
>>               uint64_t        maxval;
>> -             uint64_t        defaultval;
>> +             uint64_t        flagval;
>>               const char      *raw_input;
>>       }               subopt_params[MAX_SUBOPTS];
>>  };
>> @@ -164,7 +164,7 @@ struct opt_params bopts = {
>>                                LAST_CONFLICT },
>>                 .minval = XFS_MIN_BLOCKSIZE_LOG,
>>                 .maxval = XFS_MAX_BLOCKSIZE_LOG,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = B_SIZE,
>>                 .convert = true,
>> @@ -173,7 +173,7 @@ struct opt_params bopts = {
>>                                LAST_CONFLICT },
>>                 .minval = XFS_MIN_BLOCKSIZE,
>>                 .maxval = XFS_MAX_BLOCKSIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>       },
>>  };
>> @@ -219,24 +219,24 @@ struct opt_params dopts = {
>>                                LAST_CONFLICT },
>>                 .minval = 1,
>>                 .maxval = XFS_MAX_AGNUMBER,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_FILE,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>               { .index = D_NAME,
>>                 .conflicts = { LAST_CONFLICT },
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_SIZE,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .convert = true,
>>                 .minval = XFS_AG_MIN_BYTES,
>>                 .maxval = LLONG_MAX,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_SUNIT,
>>                 .conflicts = { D_NOALIGN,
>> @@ -245,7 +245,7 @@ struct opt_params dopts = {
>>                                LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = UINT_MAX,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_SWIDTH,
>>                 .conflicts = { D_NOALIGN,
>> @@ -254,7 +254,7 @@ struct opt_params dopts = {
>>                                LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = UINT_MAX,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_AGSIZE,
>>                 .conflicts = { D_AGCOUNT,
>> @@ -262,7 +262,7 @@ struct opt_params dopts = {
>>                 .convert = true,
>>                 .minval = XFS_AG_MIN_BYTES,
>>                 .maxval = XFS_AG_MAX_BYTES,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_SU,
>>                 .conflicts = { D_NOALIGN,
>> @@ -272,7 +272,7 @@ struct opt_params dopts = {
>>                 .convert = true,
>>                 .minval = 0,
>>                 .maxval = UINT_MAX,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_SW,
>>                 .conflicts = { D_NOALIGN,
>> @@ -281,14 +281,14 @@ struct opt_params dopts = {
>>                                LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = UINT_MAX,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_SECTLOG,
>>                 .conflicts = { D_SECTSIZE,
>>                                LAST_CONFLICT },
>>                 .minval = XFS_MIN_SECTORSIZE_LOG,
>>                 .maxval = XFS_MAX_SECTORSIZE_LOG,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_SECTSIZE,
>>                 .conflicts = { D_SECTLOG,
>> @@ -297,7 +297,7 @@ struct opt_params dopts = {
>>                 .is_power_2 = true,
>>                 .minval = XFS_MIN_SECTORSIZE,
>>                 .maxval = XFS_MAX_SECTORSIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_NOALIGN,
>>                 .conflicts = { D_SU,
>> @@ -307,25 +307,25 @@ struct opt_params dopts = {
>>                                LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>               { .index = D_RTINHERIT,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>               { .index = D_PROJINHERIT,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = UINT_MAX,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = D_EXTSZINHERIT,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = UINT_MAX,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>       },
>>  };
>> @@ -357,7 +357,7 @@ struct opt_params iopts = {
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>               { .index = I_LOG,
>>                 .conflicts = { I_PERBLOCK,
>> @@ -365,13 +365,13 @@ struct opt_params iopts = {
>>                                LAST_CONFLICT },
>>                 .minval = XFS_DINODE_MIN_LOG,
>>                 .maxval = XFS_DINODE_MAX_LOG,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = I_MAXPCT,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 100,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = I_PERBLOCK,
>>                 .conflicts = { I_LOG,
>> @@ -380,7 +380,7 @@ struct opt_params iopts = {
>>                 .is_power_2 = true,
>>                 .minval = XFS_MIN_INODE_PERBLOCK,
>>                 .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = I_SIZE,
>>                 .conflicts = { I_PERBLOCK,
>> @@ -389,25 +389,25 @@ struct opt_params iopts = {
>>                 .is_power_2 = true,
>>                 .minval = XFS_DINODE_MIN_SIZE,
>>                 .maxval = XFS_DINODE_MAX_SIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = I_ATTR,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 2,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = I_PROJID32BIT,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>               { .index = I_SPINODES,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>       },
>>  };
>> @@ -447,7 +447,7 @@ struct opt_params lopts = {
>>                                LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = UINT_MAX,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = L_INTERNAL,
>>                 .conflicts = { L_FILE,
>> @@ -455,27 +455,27 @@ struct opt_params lopts = {
>>                                LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>               { .index = L_SIZE,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .convert = true,
>>                 .minval = 2 * 1024 * 1024LL,  /* XXX: XFS_MIN_LOG_BYTES */
>>                 .maxval = XFS_MAX_LOG_BYTES,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = L_VERSION,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 1,
>>                 .maxval = 2,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = L_SUNIT,
>>                 .conflicts = { L_SU,
>>                                LAST_CONFLICT },
>>                 .minval = 1,
>>                 .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = L_SU,
>>                 .conflicts = { L_SUNIT,
>> @@ -483,20 +483,20 @@ struct opt_params lopts = {
>>                 .convert = true,
>>                 .minval = BBTOB(1),
>>                 .maxval = XLOG_MAX_RECORD_BSIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = L_DEV,
>>                 .conflicts = { L_AGNUM,
>>                                L_INTERNAL,
>>                                LAST_CONFLICT },
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = L_SECTLOG,
>>                 .conflicts = { L_SECTSIZE,
>>                                LAST_CONFLICT },
>>                 .minval = XFS_MIN_SECTORSIZE_LOG,
>>                 .maxval = XFS_MAX_SECTORSIZE_LOG,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = L_SECTSIZE,
>>                 .conflicts = { L_SECTLOG,
>> @@ -505,26 +505,26 @@ struct opt_params lopts = {
>>                 .is_power_2 = true,
>>                 .minval = XFS_MIN_SECTORSIZE,
>>                 .maxval = XFS_MAX_SECTORSIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = L_FILE,
>>                 .conflicts = { L_INTERNAL,
>>                                LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>               { .index = L_NAME,
>>                 .conflicts = { L_AGNUM,
>>                                L_INTERNAL,
>>                                LAST_CONFLICT },
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = L_LAZYSBCNTR,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>       },
>>  };
>> @@ -548,7 +548,7 @@ struct opt_params nopts = {
>>                                LAST_CONFLICT },
>>                 .minval = XFS_MIN_REC_DIRSIZE,
>>                 .maxval = XFS_MAX_BLOCKSIZE_LOG,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = N_SIZE,
>>                 .conflicts = { N_LOG,
>> @@ -557,19 +557,19 @@ struct opt_params nopts = {
>>                 .is_power_2 = true,
>>                 .minval = 1 << XFS_MIN_REC_DIRSIZE,
>>                 .maxval = XFS_MAX_BLOCKSIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = N_VERSION,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 2,
>>                 .maxval = 2,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = N_FTYPE,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>       },
>>  };
>> @@ -597,33 +597,33 @@ struct opt_params ropts = {
>>                 .convert = true,
>>                 .minval = XFS_MIN_RTEXTSIZE,
>>                 .maxval = XFS_MAX_RTEXTSIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = R_SIZE,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .convert = true,
>>                 .minval = 0,
>>                 .maxval = LLONG_MAX,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = R_DEV,
>>                 .conflicts = { LAST_CONFLICT },
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = R_FILE,
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>                 .conflicts = { LAST_CONFLICT },
>>               },
>>               { .index = R_NAME,
>>                 .conflicts = { LAST_CONFLICT },
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = R_NOALIGN,
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>                 .conflicts = { LAST_CONFLICT },
>>               },
>>       },
>> @@ -649,7 +649,7 @@ struct opt_params sopts = {
>>                                LAST_CONFLICT },
>>                 .minval = XFS_MIN_SECTORSIZE_LOG,
>>                 .maxval = XFS_MAX_SECTORSIZE_LOG,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = S_SECTLOG,
>>                 .conflicts = { S_SIZE,
>> @@ -657,7 +657,7 @@ struct opt_params sopts = {
>>                                LAST_CONFLICT },
>>                 .minval = XFS_MIN_SECTORSIZE_LOG,
>>                 .maxval = XFS_MAX_SECTORSIZE_LOG,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = S_SIZE,
>>                 .conflicts = { S_LOG,
>> @@ -667,7 +667,7 @@ struct opt_params sopts = {
>>                 .is_power_2 = true,
>>                 .minval = XFS_MIN_SECTORSIZE,
>>                 .maxval = XFS_MAX_SECTORSIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = S_SECTSIZE,
>>                 .conflicts = { S_LOG,
>> @@ -677,7 +677,7 @@ struct opt_params sopts = {
>>                 .is_power_2 = true,
>>                 .minval = XFS_MIN_SECTORSIZE,
>>                 .maxval = XFS_MAX_SECTORSIZE,
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>       },
>>  };
>> @@ -702,29 +702,29 @@ struct opt_params mopts = {
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>               { .index = M_FINOBT,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 1,
>> +               .flagval = 1,
>>               },
>>               { .index = M_UUID,
>>                 .conflicts = { LAST_CONFLICT },
>> -               .defaultval = SUBOPT_NEEDS_VAL,
>> +               .flagval = SUBOPT_NEEDS_VAL,
>>               },
>>               { .index = M_RMAPBT,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 0,
>> +               .flagval = 0,
>>               },
>>               { .index = M_REFLINK,
>>                 .conflicts = { LAST_CONFLICT },
>>                 .minval = 0,
>>                 .maxval = 1,
>> -               .defaultval = 0,
>> +               .flagval = 0,
>>               },
>>       },
>>  };
>> @@ -1365,9 +1365,9 @@ getnum(
>>       check_opt(opts, index, false);
>>       /* empty strings might just return a default value */
>>       if (!str || *str == '\0') {
>> -             if (sp->defaultval == SUBOPT_NEEDS_VAL)
>> +             if (sp->flagval == SUBOPT_NEEDS_VAL)
>>                       reqval(opts->name, (char **)opts->subopts, index);
>> -             return sp->defaultval;
>> +             return sp->flagval;
>>       }
>>
>>       if (sp->minval == 0 && sp->maxval == 0) {
>>



-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 03/12] mkfs: remove intermediate getstr followed by getnum
  2017-04-25 17:37   ` Eric Sandeen
@ 2017-04-26  7:40     ` Jan Tulak
  2017-04-26 13:13       ` Eric Sandeen
  0 siblings, 1 reply; 59+ messages in thread
From: Jan Tulak @ 2017-04-26  7:40 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Tue, Apr 25, 2017 at 7:37 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 4/23/17 1:54 PM, Jan Tulak wrote:
>> Some options loaded a number as a string with getstr and converted it to
>> number with getnum later in the code, without any reason for this
>> approach.  (They were probably forgotten in some past cleaning.)
>>
>> This patch changes them to skip the string and use getnum directly in
>> the main option-parsing loop, as do all the other numerical options.
>>
>> And as we now have two variables of the same type for the same value,
>> merge them together. (e.g. former string dsize and number dbytes).
>>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>> ---
>> CHANGES:
>> * The first patch now ensures that we still have the raw input and
>>   we are not changing the form of user input (i.e. size stays in given
>>   units...)
>>
>>  mkfs/xfs_mkfs.c | 88 ++++++++++++++++++++++++++-------------------------------
>>  1 file changed, 40 insertions(+), 48 deletions(-)
>>
>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>> index 0a795a6..7a72b11 100644
>> --- a/mkfs/xfs_mkfs.c
>> +++ b/mkfs/xfs_mkfs.c
>> @@ -1363,6 +1363,7 @@ getnum(
>>       uint64_t                c;
>>
>>       check_opt(opts, index, false);
>> +     set_conf_raw(opts, index, str);
>
> So this is really an unrelated functional change here; ideally, this
> patch would come before the "raw option" patch.  Once every option goes
> through getnum, /then/ you can add the raw storage to getnum().
>
> Not a huge deal, but if you resend the series, you might consider that
> ordering.  Otherwise I think this one looks ok :)

Well, we are saving the raw here ... and then reading it in printfs.
So if we want to avoid the situation from the previous set, where
input error prints changed the values (printing "1024" instead of
user-given "1k"), we have to use raw before we remove the getstr(),
not later. But then we might try to print something that didn't go
through getnum yet, so we don't have the string saved... which is why
I made it as one patch.

Jan

>
> Reviewed-by: Eric Sandeen <sandeen@redhat.com>
>
>>       /* empty strings might just return a default value */
>>       if (!str || *str == '\0') {
>>               if (sp->flagval == SUBOPT_NEEDS_VAL)
>> @@ -1450,7 +1451,7 @@ main(
>>       char                    *dfile;
>>       uint64_t                dirblocklog;
>>       uint64_t                dirblocksize;
>> -     char                    *dsize;
>> +     uint64_t                dbytes;
>>       uint64_t                dsu;
>>       uint64_t                dsw;
>>       uint64_t                dsunit;
>> @@ -1474,7 +1475,7 @@ main(
>>       xfs_rfsblock_t          logblocks;
>>       char                    *logfile;
>>       uint64_t                loginternal;
>> -     char                    *logsize;
>> +     uint64_t                logbytes;
>>       xfs_fsblock_t           logstart;
>>       bool                    lvflag;
>>       bool                    lsflag;
>> @@ -1503,11 +1504,11 @@ main(
>>       char                    *protostring;
>>       bool                    qflag;
>>       xfs_rfsblock_t          rtblocks;
>> +     uint64_t                rtbytes;
>>       xfs_extlen_t            rtextblocks;
>>       xfs_rtblock_t           rtextents;
>> -     char                    *rtextsize;
>> +     uint64_t                rtextbytes;
>>       char                    *rtfile;
>> -     char                    *rtsize;
>>       xfs_sb_t                *sbp;
>>       uint64_t                sectorlog;
>>       uint64_t                sector_mask;
>> @@ -1555,7 +1556,8 @@ main(
>>       qflag = false;
>>       imaxpct = inodelog = inopblock = isize = 0;
>>       dfile = logfile = rtfile = NULL;
>> -     dsize = logsize = rtsize = rtextsize = protofile = NULL;
>> +     protofile = NULL;
>> +     rtbytes = rtextbytes = logbytes = dbytes = 0;
>>       dsu = dsw = dsunit = dswidth = lalign = lsu = lsunit = 0;
>>       nodsflag = norsflag = false;
>>       force_overwrite = false;
>> @@ -1619,7 +1621,7 @@ main(
>>                                       xi.dname = getstr(value, &dopts, D_NAME);
>>                                       break;
>>                               case D_SIZE:
>> -                                     dsize = getstr(value, &dopts, D_SIZE);
>> +                                     dbytes = getnum(value, &dopts, D_SIZE);
>>                                       break;
>>                               case D_SUNIT:
>>                                       dsunit = getnum(value, &dopts, D_SUNIT);
>> @@ -1764,7 +1766,7 @@ main(
>>                                       lvflag = 1;
>>                                       break;
>>                               case L_SIZE:
>> -                                     logsize = getstr(value, &lopts, L_SIZE);
>> +                                     logbytes = getnum(value, &lopts, L_SIZE);
>>                                       break;
>>                               case L_SECTLOG:
>>                                       lsectorlog = getnum(value, &lopts,
>> @@ -1893,8 +1895,7 @@ main(
>>
>>                               switch (getsubopt(&p, subopts, &value)) {
>>                               case R_EXTSIZE:
>> -                                     rtextsize = getstr(value, &ropts,
>> -                                                        R_EXTSIZE);
>> +                                     rtextbytes = getnum(value, &ropts, R_EXTSIZE);
>>                                       break;
>>                               case R_FILE:
>>                                       xi.risfile = getnum(value, &ropts,
>> @@ -1906,7 +1907,7 @@ main(
>>                                                          R_NAME);
>>                                       break;
>>                               case R_SIZE:
>> -                                     rtsize = getstr(value, &ropts, R_SIZE);
>> +                                     rtbytes = getnum(value, &ropts, R_SIZE);
>>                                       break;
>>                               case R_NOALIGN:
>>                                       norsflag = getnum(value, &ropts,
>> @@ -2009,14 +2010,14 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
>>        * sector size mismatches between the new filesystem and the underlying
>>        * host filesystem.
>>        */
>> -     check_device_type(dfile, &xi.disfile, !dsize, !dfile,
>> +     check_device_type(dfile, &xi.disfile, !dbytes, !dfile,
>>                         Nflag ? NULL : &xi.dcreat, force_overwrite, "d");
>>       if (!loginternal)
>> -             check_device_type(xi.logname, &xi.lisfile, !logsize, !xi.logname,
>> -                               Nflag ? NULL : &xi.lcreat,
>> +             check_device_type(xi.logname, &xi.lisfile, !logbytes,
>> +                               !xi.logname, Nflag ? NULL : &xi.lcreat,
>>                                 force_overwrite, "l");
>>       if (xi.rtname)
>> -             check_device_type(xi.rtname, &xi.risfile, !rtsize, !xi.rtname,
>> +             check_device_type(xi.rtname, &xi.risfile, !rtbytes, !xi.rtname,
>>                                 Nflag ? NULL : &xi.rcreat,
>>                                 force_overwrite, "r");
>>       if (xi.disfile || xi.lisfile || xi.risfile)
>> @@ -2197,10 +2198,7 @@ _("rmapbt not supported with realtime devices\n"));
>>       }
>>
>>
>> -     if (dsize) {
>> -             uint64_t dbytes;
>> -
>> -             dbytes = getnum(dsize, &dopts, D_SIZE);
>> +     if (dbytes) {
>>               if (dbytes % XFS_MIN_BLOCKSIZE) {
>>                       fprintf(stderr,
>>                       _("illegal data length %"PRIu64", not a multiple of %d\n"),
>> @@ -2229,10 +2227,7 @@ _("rmapbt not supported with realtime devices\n"));
>>               usage();
>>       }
>>
>> -     if (logsize) {
>> -             uint64_t logbytes;
>> -
>> -             logbytes = getnum(logsize, &lopts, L_SIZE);
>> +     if (logbytes) {
>>               if (logbytes % XFS_MIN_BLOCKSIZE) {
>>                       fprintf(stderr,
>>                       _("illegal log length %"PRIu64", not a multiple of %d\n"),
>> @@ -2246,10 +2241,7 @@ _("rmapbt not supported with realtime devices\n"));
>>                               logbytes, blocksize,
>>                               (uint64_t)(logblocks << blocklog));
>>       }
>> -     if (rtsize) {
>> -             uint64_t rtbytes;
>> -
>> -             rtbytes = getnum(rtsize, &ropts, R_SIZE);
>> +     if (rtbytes) {
>>               if (rtbytes % XFS_MIN_BLOCKSIZE) {
>>                       fprintf(stderr,
>>                       _("illegal rt length %"PRIu64", not a multiple of %d\n"),
>> @@ -2266,10 +2258,7 @@ _("rmapbt not supported with realtime devices\n"));
>>       /*
>>        * If specified, check rt extent size against its constraints.
>>        */
>> -     if (rtextsize) {
>> -             uint64_t rtextbytes;
>> -
>> -             rtextbytes = getnum(rtextsize, &ropts, R_EXTSIZE);
>> +     if (rtextbytes) {
>>               if (rtextbytes % blocksize) {
>>                       fprintf(stderr,
>>               _("illegal rt extent size %"PRIu64", not a multiple of %"PRIu64"\n"),
>> @@ -2286,7 +2275,7 @@ _("rmapbt not supported with realtime devices\n"));
>>               uint64_t        rswidth;
>>               uint64_t        rtextbytes;
>>
>> -             if (!norsflag && !xi.risfile && !(!rtsize && xi.disfile))
>> +             if (!norsflag && !xi.risfile && !(!rtbytes && xi.disfile))
>>                       rswidth = ft.rtswidth;
>>               else
>>                       rswidth = 0;
>> @@ -2397,15 +2386,16 @@ _("rmapbt not supported with realtime devices\n"));
>>               rtfile = _("volume rt");
>>       else if (!xi.rtdev)
>>               rtfile = _("none");
>> -     if (dsize && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
>> +     if (dbytes && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
>>               fprintf(stderr,
>>                       _("size %s specified for data subvolume is too large, "
>>                       "maximum is %"PRIu64" blocks\n"),
>> -                     dsize, (uint64_t)DTOBT(xi.dsize));
>> +                     get_conf_raw(&dopts, D_SIZE),
>> +                     (uint64_t)DTOBT(xi.dsize));
>>               usage();
>> -     } else if (!dsize && xi.dsize > 0)
>> +     } else if (!dbytes && xi.dsize > 0)
>>               dblocks = DTOBT(xi.dsize);
>> -     else if (!dsize) {
>> +     else if (!dbytes) {
>>               fprintf(stderr, _("can't get size of data subvolume\n"));
>>               usage();
>>       }
>> @@ -2438,22 +2428,23 @@ reported by the device (%u).\n"),
>>  reported by the device (%u).\n"),
>>                       lsectorsize, xi.lbsize);
>>       }
>> -     if (rtsize && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
>> +     if (rtbytes && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
>>               fprintf(stderr, _(
>>  "Warning: the realtime subvolume sector size %"PRIu64" is less than the sector size\n\
>>  reported by the device (%u).\n"),
>>                       sectorsize, xi.rtbsize);
>>       }
>>
>> -     if (rtsize && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
>> +     if (rtbytes && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
>>               fprintf(stderr,
>>                       _("size %s specified for rt subvolume is too large, "
>>                       "maximum is %"PRIu64" blocks\n"),
>> -                     rtsize, (uint64_t)DTOBT(xi.rtsize));
>> +                     get_conf_raw(&ropts, R_SIZE),
>> +                     (uint64_t)DTOBT(xi.rtsize));
>>               usage();
>> -     } else if (!rtsize && xi.rtsize > 0)
>> +     } else if (!rtbytes && xi.rtsize > 0)
>>               rtblocks = DTOBT(xi.rtsize);
>> -     else if (rtsize && !xi.rtdev) {
>> +     else if (rtbytes && !xi.rtdev) {
>>               fprintf(stderr,
>>                       _("size specified for non-existent rt subvolume\n"));
>>               usage();
>> @@ -2658,26 +2649,27 @@ an AG size that is one stripe unit smaller, for example %"PRIu64".\n"),
>>                                  sb_feat.rmapbt, sb_feat.reflink);
>>       ASSERT(min_logblocks);
>>       min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
>> -     if (!logsize && dblocks >= (1024*1024*1024) >> blocklog)
>> +     if (!logbytes && dblocks >= (1024*1024*1024) >> blocklog)
>>               min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
>> -     if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
>> +     if (logbytes && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
>>               fprintf(stderr,
>>  _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks\n"),
>> -                     logsize, (uint64_t)DTOBT(xi.logBBsize));
>> +                     get_conf_raw(&lopts, L_SIZE),
>> +                     (uint64_t)DTOBT(xi.logBBsize));
>>               usage();
>> -     } else if (!logsize && xi.logBBsize > 0) {
>> +     } else if (!logbytes && xi.logBBsize > 0) {
>>               logblocks = DTOBT(xi.logBBsize);
>> -     } else if (logsize && !xi.logdev && !loginternal) {
>> +     } else if (logbytes && !xi.logdev && !loginternal) {
>>               fprintf(stderr,
>>                       _("size specified for non-existent log subvolume\n"));
>>               usage();
>> -     } else if (loginternal && logsize && logblocks >= dblocks) {
>> +     } else if (loginternal && logbytes && logblocks >= dblocks) {
>>               fprintf(stderr, _("size %"PRIu64" too large for internal log\n"),
>>                       logblocks);
>>               usage();
>>       } else if (!loginternal && !xi.logdev) {
>>               logblocks = 0;
>> -     } else if (loginternal && !logsize) {
>> +     } else if (loginternal && !logbytes) {
>>
>>               if (dblocks < GIGABYTES(1, blocklog)) {
>>                       /* tiny filesystems get minimum sized logs. */
>> @@ -2741,7 +2733,7 @@ _("size %s specified for log subvolume is too large, maximum is %"PRIu64" blocks
>>                * Readjust the log size to fit within an AG if it was sized
>>                * automatically.
>>                */
>> -             if (!logsize) {
>> +             if (!logbytes) {
>>                       logblocks = MIN(logblocks,
>>                                       libxfs_alloc_ag_max_usable(mp));
>>
>>



-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-26  2:00           ` Eric Sandeen
@ 2017-04-26  8:01             ` Luis R. Rodriguez
  2017-04-26  8:24               ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  8:01 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Luis R. Rodriguez, Jan Tulak, linux-xfs

On Tue, Apr 25, 2017 at 09:00:40PM -0500, Eric Sandeen wrote:
> On 4/25/17 8:38 PM, Luis R. Rodriguez wrote:
> >>>>> +#define MAX_OPTS     16
> >>>>
> >>>> This is fragile, every time a new opt is added this needs to be updated
> >>
> >> <pedantic>There are only 8 now, so there are still 8 free slots</pedantic>
> >>
> >>>> and so is the index, and we should be pedantic over not going out of bounds.
> >>>> We could instead use a flexible array and compute the max opts at run time
> >>>> as a global. This way the max opts is always updated automatically.
> >>
> >> I don't think it's all that fragile;
> > 
> > We can avoid such compilation warnings.
> 
> Well, post the proposed patch when appropriate, and it can go through review.
> 
> ...

Well it is Jan's patch I am reviewing, not mine. I was happy to help with all this
given I had dome similar work as Jan is doing, we determined it was best to wait
for Jan's table work to fold in as it was compatible with my own goals. But I
think we all agree that while we're making all these changes to the opts / subopts
best to strive for anything that makes things better. Its part of my review.

> >> In any case, any changes around this behavior would certainly
> >> be part of a different patch, because you'd want to be consistent with all
> >> the other structure initializers, and it would be a functionally separate
> >> change if it is warranted at all.
> > 
> > The opt_params are separate today though, this patch folds them in together,
> > what I propose is just to use a flexible array to avoid an explicit size
> > from the start. Not sure how much more functional of a change that is ?
> 
> Because it'd be inconsistent with the other array declarations.
> 
> Prior to this patch we had 2 #defines to declare sizes of global
> arrays:
> 
> #define MAX_SUBOPTS	16
> 	const char	*subopts[MAX_SUBOPTS];
> 	}		subopt_params[MAX_SUBOPTS];
> 
> #define MAX_CONFLICTS	8
> 		int		conflicts[MAX_CONFLICTS];
> 
> now we add a third:
> 
> #define MAX_OPTS	16
> } opts[MAX_OPTS] = {

Ah yes in that sense yes, it would be inconsistent with the old way
of using defines for arrays. But then again the struct opt_params never
had this define, and its "old way" was to declare each on its own.

> If you're not a fan of #defines to size global arrays that's ok, but
> let's be consistent and change them all at once, and not change one
> of the 3 as a side-effect of collapsing the separate opts structures
> into one.

Hm, changing all 3 of these of these: opts, suboopts, conflicts to flexible
array may be possible without making the patch impossible to review, but its not
clear to me, I'd be surprised though.

Anyway in case its useful to Jan or others here's an example of what it using
flexible arrays could look like for an opt/subopt framework:

http://drvbp1.linux-foundation.org/~mcgrof/demos/demo-flexible-array-subopts.c

> For now, let's follow the pattern of the existing code, and submit a 
> comprehensive functional patch to address this separate change.
> 
> Small, reviewable, distinct, functional changes.

This patch moves the opts to the 'old' way of doing things with no good reason
other than its the old style. I find more reasons to move away from it, to enable
later making subopts and conflicts also use flexible array (if this is agreed
suitable).

  Luis

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-25 21:45   ` Eric Sandeen
  2017-04-26  4:09     ` Eric Sandeen
@ 2017-04-26  8:14     ` Jan Tulak
  1 sibling, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-26  8:14 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Tue, Apr 25, 2017 at 11:45 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 4/23/17 1:54 PM, Jan Tulak wrote:
>> Merge separate instances of opt_params into one indexable table. Git
>> makes this patch looks a bit more complicated, but it does not change
>> values or structure of anything else. It only moves all the "struct
>> opt_params dopts = {...}", changes indentation for these substructures
>> and replaces their usage (dopts -> opts[OPT_D]).
>
> This looks correct.  Can you remind me why it helps?  :)
> (the commit log says what you did but not why you did it)
>

A groundwork to be able to address any option from any other one. So
we can have conflicts pointing from -m crc to -i align...

>
> One thing I wondered about to idiot-proof the code a bit (in some
> other patch, not this one, but while I'm looking at it):
>
> What about instead of:
>
>     switch (getsubopt(&p, subopts, &value)) {
>     case OPT1:
>             opt1 = getnum(value, &opts, OPT1);
>     case OPT2:
>             opt2 = getnum(value, &opts, OPT2);
>                                 ...
>
> and making sure there's never a mismatch between the case value and the
> value passed to getnum, you could do something like:
>
>     int so = getsubopt(&p, subopts, &value);
>
>     switch (so) {
>     case OPT1:
>             opt1 = getnum(value, &opts, so);
>     case OPT2:
>             opt2 = getnum(value, &opts, so);
>                                 ...
>
> so that you can never mismatch & pass in the wrong subopt for option
> checking; it will always be the subopt matched by the case statement.
>
> I just considered that as I reviewed it and found myself mentally
> checking that each case matched.
>

Well, I think that once we remove every bit of logic from the main
loop and put it into some helper functions, we can ditch these manual
switches entirely and construct it dynamically from what we have in
opts (and the helpers).

Cheers,
Jan

> Thanks,
> -Eric



-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-25  7:45     ` Jan Tulak
  2017-04-25 13:28       ` Eric Sandeen
@ 2017-04-26  8:21       ` Luis R. Rodriguez
  2017-04-26  8:38         ` Jan Tulak
  1 sibling, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-04-26  8:21 UTC (permalink / raw)
  To: Jan Tulak; +Cc: Luis R. Rodriguez, linux-xfs

On Tue, Apr 25, 2017 at 09:45:53AM +0200, Jan Tulak wrote:
> On Tue, Apr 25, 2017 at 5:04 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> > On Sun, Apr 23, 2017 at 08:54:55PM +0200, Jan Tulak wrote:
> >> opts[MAX_OPTS] = {
> >> +#define OPT_B        0
> >
> > I find these defines blinding on reading the struct declaration, we could
> > instead just stuff them into an enum, which would also enable us to shift all
> > the documentation into the header of the enum using whatever doc format we use.
> 
> The grouping is here to keep the style as it is with suboptions
> index/string. However, all these defines (OPT_X and X_FOO) are
> separated and moved into a single place later on in one patch anyway.
> I just didn't include that patch in this set as I had to make the line
> somewhere if I want to make multiple smaller and easier to review and
> merge sets rather than the one big monster as before.

Makes sense.

> There is one point I'm not sure about, though. We have to restart the
> counting for suboptions, like this:
> 
> enum subopts {
>   B_size = 0,
>   B_LOG,
>   D_AGCOUNT = 0,
>   D_...,
>   L_xxx = 0,
>   L_...,
> }
> 
> I didn't found anywhere if it is a good practice or not. But again, I
> just submitted it as it was with a note in my TODOs to find out more
> out it and update the patch changing it later on.

Ugh yeah no that would be pretty terrible, how about something like:

enum subopt_zero_idx {
	SUBOPT_ZERO_A = 0,
	SUBOPT_ZERO_B,
	SUBOPT_ZERO_C,
};

enum subopt_one_idx {
	SUBOPT_ONE_A = 0,
	SUBOPT_ONE_B,
};

enum subopt_two_idx {
	SUBOPT_TWO_A = 0,
};

union subopt_idx {
	enum subopt_zero_idx subopt_zero;
	enum subopt_one_idx subopt_one;
	enum subopt_two_idx subopt_two;
};

Demo: http://drvbp1.linux-foundation.org/~mcgrof/demos/demo-flexible-array-subopts.c 

 Luis

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-26  8:01             ` Luis R. Rodriguez
@ 2017-04-26  8:24               ` Jan Tulak
  0 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-26  8:24 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Eric Sandeen, linux-xfs

On Wed, Apr 26, 2017 at 10:01 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Tue, Apr 25, 2017 at 09:00:40PM -0500, Eric Sandeen wrote:
>> On 4/25/17 8:38 PM, Luis R. Rodriguez wrote:
>> If you're not a fan of #defines to size global arrays that's ok, but
>> let's be consistent and change them all at once, and not change one
>> of the 3 as a side-effect of collapsing the separate opts structures
>> into one.
>
> Hm, changing all 3 of these of these: opts, suboopts, conflicts to flexible
> array may be possible without making the patch impossible to review, but its not
> clear to me, I'd be surprised though.
>
> Anyway in case its useful to Jan or others here's an example of what it using
> flexible arrays could look like for an opt/subopt framework:
>
> http://drvbp1.linux-foundation.org/~mcgrof/demos/demo-flexible-array-subopts.c

Thanks.

>
>> For now, let's follow the pattern of the existing code, and submit a
>> comprehensive functional patch to address this separate change.
>>
>> Small, reviewable, distinct, functional changes.
>
> This patch moves the opts to the 'old' way of doing things with no good reason
> other than its the old style. I find more reasons to move away from it, to enable
> later making subopts and conflicts also use flexible array (if this is agreed
> suitable).

Changing it this later (and all the other size definitions too) sounds
like a better idea to me: this static initialization doesn't add any
work that would be useless after it is turned to flexible, so it is
only about "make it flexible now, or later?" And given the number of
changes I have now, I'm up for making this change later on.

Cheers,
Jan

-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 04/12] mkfs: merge tables for opts parsing into one table
  2017-04-26  8:21       ` Luis R. Rodriguez
@ 2017-04-26  8:38         ` Jan Tulak
  0 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-26  8:38 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Wed, Apr 26, 2017 at 10:21 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Tue, Apr 25, 2017 at 09:45:53AM +0200, Jan Tulak wrote:
>> On Tue, Apr 25, 2017 at 5:04 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
>> > On Sun, Apr 23, 2017 at 08:54:55PM +0200, Jan Tulak wrote:
>> >> opts[MAX_OPTS] = {
>> >> +#define OPT_B        0
>> >
>> > I find these defines blinding on reading the struct declaration, we could
>> > instead just stuff them into an enum, which would also enable us to shift all
>> > the documentation into the header of the enum using whatever doc format we use.
>>
>> The grouping is here to keep the style as it is with suboptions
>> index/string. However, all these defines (OPT_X and X_FOO) are
>> separated and moved into a single place later on in one patch anyway.
>> I just didn't include that patch in this set as I had to make the line
>> somewhere if I want to make multiple smaller and easier to review and
>> merge sets rather than the one big monster as before.
>
> Makes sense.
>
>> There is one point I'm not sure about, though. We have to restart the
>> counting for suboptions, like this:
>>
>> enum subopts {
>>   B_size = 0,
>>   B_LOG,
>>   D_AGCOUNT = 0,
>>   D_...,
>>   L_xxx = 0,
>>   L_...,
>> }
>>
>> I didn't found anywhere if it is a good practice or not. But again, I
>> just submitted it as it was with a note in my TODOs to find out more
>> out it and update the patch changing it later on.
>
> Ugh yeah no that would be pretty terrible, how about something like:
>
> enum subopt_zero_idx {
>         SUBOPT_ZERO_A = 0,
>         SUBOPT_ZERO_B,
>         SUBOPT_ZERO_C,
> };
>
> enum subopt_one_idx {
>         SUBOPT_ONE_A = 0,
>         SUBOPT_ONE_B,
> };
>
> enum subopt_two_idx {
>         SUBOPT_TWO_A = 0,
> };
>
> union subopt_idx {
>         enum subopt_zero_idx subopt_zero;
>         enum subopt_one_idx subopt_one;
>         enum subopt_two_idx subopt_two;
> };
>
> Demo: http://drvbp1.linux-foundation.org/~mcgrof/demos/demo-flexible-array-subopts.c
>
>  Luis

Ah, unions didn't cross my mind for this. And the demo is nice. I keep
the #defines in this patch, but this definitely deserves its patch or
two too.

Cheers,
Jan


-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 05/12] mkfs: extend opt_params with a value field
  2017-04-26  1:04         ` Luis R. Rodriguez
@ 2017-04-26  8:51           ` Jan Tulak
  0 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-26  8:51 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Wed, Apr 26, 2017 at 3:04 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Tue, Apr 25, 2017 at 11:39:00AM +0200, Jan Tulak wrote:
> Hm, how about:
>
> The actual value used in computations for creating the filesystem.
> This is initialized with sensible default values, if initialized to 0
> the value is considered disabled. User input can optionally override
> default values. If the field is a string and not a number, the value
> is set to a positive non-zero number when user input has been supplied.
>
>>  *     (If the field is a string and not a number, this value is set to
>>  *     a positive non-zero number on an user input.)
>>
>> And for the commit message, a bit shortened version:
>>
>> Add a new field int opt_params - value - which is the actual value
>> used in computations and for creating the filesystem. It is filled
>> with user input if the user specifies the subopt. But he does not,
>> then whatever you put there is used as the default.
>
> Modulo "But he does not"/ "but if no user input is not passed then
> the originally set defaults will be used"
>
>   Luis

Sounds good. I will use your version.

Thanks,
Jan

-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 05/12] mkfs: extend opt_params with a value field
  2017-04-26  2:50         ` Eric Sandeen
@ 2017-04-26  8:52           ` Jan Tulak
  0 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-26  8:52 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Luis R. Rodriguez, linux-xfs

On Wed, Apr 26, 2017 at 4:50 AM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 4/25/17 8:10 PM, Luis R. Rodriguez wrote:
>> On Tue, Apr 25, 2017 at 10:04:39AM +0200, Jan Tulak wrote:
>>> On Tue, Apr 25, 2017 at 5:13 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
>>>> On Sun, Apr 23, 2017 at 08:54:56PM +0200, Jan Tulak wrote:
>>>>
>>>>> and anything you write here now is
>>>>> + *     overwritten if user specifies the subopt. (If the user input is a string
>>>>> + *     and not a number, this value is set to a positive non-zero number.)
>>>>> + *
>>>>>   * !!! NOTE ==================================================================
>>>>>   *
>>>>>   * If you are adding a new option, or changing an existing one,
>>>>> @@ -152,6 +158,7 @@ struct opt_params {
>>>>>               uint64_t        maxval;
>>>>>               uint64_t        flagval;
>>>>>               const char      *raw_input;
>>>>> +             uint64_t        value;
>>>>>       }               subopt_params[MAX_SUBOPTS];
>>>>>  } opts[MAX_OPTS] = {
>>>>>  #define OPT_B        0
>>>>
>>>> It would seem rather unfair to define this this but not use it in the patch ?
>>>
>>> I'm still trying to find out when exactly should I make something two
>>> patches and when one, and it seems to shift case by case... I tried to
>>> separate the adding of new things and rewriting of the existing code,
>>> but do you think, in this case, the new thing is too trivial to have a
>>> standalone patch?
>>
>> Ah, I see, this was split out to be separate given a slew of subopts in turn
>> later use it. The nasty alternative for review would be to have all subopts
>> converted in one shot. I suppose a middle ground would be to have this patch
>> squashed with just one of the subopt users, and then each other subopt ported
>> atomically. That would make the addition of the value and definition in effect
>> as soon as its added.
>>
>> Just my 0.02 CRC but its up to Eric as this is rather subjective and tree dependent.
>
> I think the way Jan did this is fine.  Ideally the commit would explain a bit more,
> i.e. "This patch simply adds the value field.  Subsequent patches will utilize
> this new field."
>
> Then the reviewers know what to expect from the start, and we avoid the back and
> forth of figuring out why it was done as it was done.  ;)
>
> However, I think 5 & 6 could easily be combined - add the field and the routines
> to manipulate it, /then/ start adding users of that new infrastructure.
>
> I haven't really reviewed from here on out yet, but from a "how should I break
> up patches" point of view, that's my ... $0.02.  :)
>

Yeah, that sounds reasonable, I'm squashing it for the next version
(and adding the notice).

Jan


-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options
  2017-04-26  0:45       ` Luis R. Rodriguez
@ 2017-04-26  9:09         ` Jan Tulak
  0 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-26  9:09 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Wed, Apr 26, 2017 at 2:45 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Tue, Apr 25, 2017 at 10:37:57AM +0200, Jan Tulak wrote:
>> On Tue, Apr 25, 2017 at 7:27 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
>> > On Sun, Apr 23, 2017 at 08:54:59PM +0200, Jan Tulak wrote:
>> >> Remove variables that can be replaced with a direct access to the opts table,
>> >> so we have it all in a single place, acessible from anywhere.
>> >>
>> >> In future, we can remove some passing of values forth and back, but now limit
>> >> the changes to simple replacement without a change in the logic.
>> >
>> > What do you mean passing of values here, as an example with bopts ?
>>
>> Passing it to a function and then retrieving with pointers, e.g. change this
>>
>> static void
>> calc_stripe_factors(
>>         int             dsu,
>>         int             dsw,
>>         int             dsectsz,
>>         int             lsu,
>>         int             lsectsz,
>>         uint64_t        *dsunit,
>>         uint64_t        *dswidth,
>>         uint64_t        *lsunit)
>>
>>
>> to this
>>
>> static void
>> calc_stripe_factors(struct opt_params * opts) // or no argument at all...
>
> Ah, great, but note that not all options have a respective struct subopt_param,
> that is -- we don't allow for them to be specified in the command line, but they
> are rather collateral values, which depend on other struct subopt_param's. The
> lsunit is one example. Its why I ended up just stuffing all of the needed parameters
> into one data struct: struct mkfs_xfs_opts. Your patches round up direct
> parameters associated with struct subopt_param on the struct opt_params.
>
> Where would things like lsunit be stuffed into ?

I  thought about making a "special option", like OPT_INTERNAL, that
would group these variables.

And as I mentioned in the post scriptum in the cover letter, I think
about how to make sure we have valid values 100% of the time, that is,
how to validate every time we use set_conf_val(). Together, these two
things would mean that we could specify validity ranges and conditions
for any variable where we know them and ensure that they cannot
deviate. It might be an overkill, but it seems like something useful
we could get pretty cheap....

At this moment, this all is just an abstract idea, though.

>
> OK, understood, just so its clear, only once all the direct subopts and collateral
> values for subopts for the following main opts are stuffed into a data structure
> somehow (and perhaps the logic of processing them are stuffed into a routine) can
> the mkfs.xfs.conf blend in well, given the same logic would be used:
>
>                 case 'b':
>                 case 'd':
>                 case 'i':
>                 case 'l':
>                 case 'm':
>                 case 'n':
>                 case 'r':
>                 case 's':
>                         p = optarg;
>                         parse_subopts(c, p, &params);
>
> So I'll have to hold off my patches until something like this is available, but
> knowing its an end goal helps in the review process.
>
>   Luis

Yes, I want to end up with something like this.

Cheers,
Jan


-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 02/12] mkfs: rename defaultval to flagval in opts
  2017-04-26  7:30     ` Jan Tulak
@ 2017-04-26 13:02       ` Eric Sandeen
  2017-04-26 13:20         ` Jan Tulak
  0 siblings, 1 reply; 59+ messages in thread
From: Eric Sandeen @ 2017-04-26 13:02 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On 4/26/17 2:30 AM, Jan Tulak wrote:
> On Tue, Apr 25, 2017 at 6:52 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
>> On 4/23/17 1:54 PM, Jan Tulak wrote:
>>> The old name 'defaultval' was misleading - it is not the default value,
>>> but the value the option has when used as a flag by an user.
>>
>> The value should only ever be 0 or 1, correct?
> 
> Not necessarily. I think we are not using anything else, but
> technically, it is possible to have any number here. I admit it is
> hard to came up with any useful case for what we have in mkfs, though.

Then let's just declare it to be so.  ;)
 
>>
>> Ok, so I see something interesting here:
>>
>> # grep "flagval = " mkfs/xfs_mkfs.c | sort | uniq -c
>>       1                           .flagval = 0,
>>       1                         .flagval = 0,
>>      14                           .flagval = 1,
>>      40                           .flagval = SUBOPT_NEEDS_VAL,
>>
>> of the 56 subopts, only 16 are treated as a flag, and only 2 default
>> to 0, while the rest default to 1.
>>
>> Those 2 seem like outliers: -m rmapbt and -m reflink.  What's
>> going on there?
>>
>> In every other case where there is a subopt which is actually a
>> boolean flag, a bare specification without a value means "enable
>> the feature."
>>
>> It seems very unintuitive to have:
>>
>> -X THING1 -> THING1 is enabled 14 times, but
>> -X THING12 - THING2 is still /disabled/ in only 2 cases
>>
>> I'd argue that "-m rmapbt" and "-m reflink" leaving those features
>> /disabled/ is a bug, due to misunderstanding of what "defaultval"
>> means, and that they should be fixed to behave like the other 14
>> boolean flags.
> 
> I agree. It looks this way...
> 
>>
>> i.e. I'd argue that a bare boolean flag specification should /always/
>> enable the feature.  At that point, you can say within your code
>> "if min = 0 and max = 1, this is a boolean, and the flag may be specified
>> without a value, in which case the value is set to 1, and the feature
>> is enabled."
>>
>> At that point you don't need this extra structure member, and you won't
>> have to re-state it 56 times, thus simplifying the code.
>>
>> What do you think?  I'd happily review and merge 2 patches, which:
>>
>> 1) Makes rmapbt and reflink behave like every other boolean flag, and
>>
> This sounds reasonable.
> 
>> 2) Removes "defaultval" altogether, and uses min=0/max=1 as a sign that
>>    the option is a boolean, with a bare flag name allowed to enable it.
>>
> I wonder if a .is_flag = true (and no other min/max/defaultval...)
> wouldn't be better solution. the min=0/max=1 detection is a bit
> implicit and may not be apparent in the future. If we limit flags to
> 0/1 values, then defaultval can be removed either way, but it is clear
> on the first glance what the option does.

Well, yes, it is implicit - but an option with a minimum 0 and maximum 1
can be interpreted no other way, IMHO.  You could document it as such
for clarity.  But I can see the value in a single "is_flag" marker
I suppose.

If you want to start typing options, you may want to consider also
adding .is_string, and then check the option against these
rules in getnum and getstr - i.e. if is_flag or is_string are set,
then minval, maxval, is_power_2 must not not set, etc, so the
developer can't get it wrong.

We'd end up with something like this:

                { .index = D_FILE,
                  .conflicts = { LAST_CONFLICT },
                  .is_flag = 1,
                },
                { .index = D_NAME,
                  .conflicts = { LAST_CONFLICT },
                  .is_string = true,
                },

which seems reasonable to me.

Thanks,
-Eric

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

* Re: [PATCH 03/12] mkfs: remove intermediate getstr followed by getnum
  2017-04-26  7:40     ` Jan Tulak
@ 2017-04-26 13:13       ` Eric Sandeen
  0 siblings, 0 replies; 59+ messages in thread
From: Eric Sandeen @ 2017-04-26 13:13 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On 4/26/17 2:40 AM, Jan Tulak wrote:
> On Tue, Apr 25, 2017 at 7:37 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
>> On 4/23/17 1:54 PM, Jan Tulak wrote:

...

>>> +     set_conf_raw(opts, index, str);
>> So this is really an unrelated functional change here; ideally, this
>> patch would come before the "raw option" patch.  Once every option goes
>> through getnum, /then/ you can add the raw storage to getnum().
>>
>> Not a huge deal, but if you resend the series, you might consider that
>> ordering.  Otherwise I think this one looks ok :)
> Well, we are saving the raw here ... and then reading it in printfs.
> So if we want to avoid the situation from the previous set, where
> input error prints changed the values (printing "1024" instead of
> user-given "1k"), we have to use raw before we remove the getstr(),
> not later. But then we might try to print something that didn't go
> through getnum yet, so we don't have the string saved... which is why
> I made it as one patch.

Oh, I see.  Ok, thanks - sorry for missing that.

-Eric

> Jan
> 

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

* Re: [PATCH 02/12] mkfs: rename defaultval to flagval in opts
  2017-04-26 13:02       ` Eric Sandeen
@ 2017-04-26 13:20         ` Jan Tulak
  0 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-04-26 13:20 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Wed, Apr 26, 2017 at 3:02 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 4/26/17 2:30 AM, Jan Tulak wrote:
>> On Tue, Apr 25, 2017 at 6:52 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
>>>
>>> i.e. I'd argue that a bare boolean flag specification should /always/
>>> enable the feature.  At that point, you can say within your code
>>> "if min = 0 and max = 1, this is a boolean, and the flag may be specified
>>> without a value, in which case the value is set to 1, and the feature
>>> is enabled."
>>>
>>> At that point you don't need this extra structure member, and you won't
>>> have to re-state it 56 times, thus simplifying the code.
>>>
>>> What do you think?  I'd happily review and merge 2 patches, which:
>>>
>>> 1) Makes rmapbt and reflink behave like every other boolean flag, and
>>>
>> This sounds reasonable.
>>
>>> 2) Removes "defaultval" altogether, and uses min=0/max=1 as a sign that
>>>    the option is a boolean, with a bare flag name allowed to enable it.
>>>
>> I wonder if a .is_flag = true (and no other min/max/defaultval...)
>> wouldn't be better solution. the min=0/max=1 detection is a bit
>> implicit and may not be apparent in the future. If we limit flags to
>> 0/1 values, then defaultval can be removed either way, but it is clear
>> on the first glance what the option does.
>
> Well, yes, it is implicit - but an option with a minimum 0 and maximum 1
> can be interpreted no other way, IMHO.  You could document it as such
> for clarity.  But I can see the value in a single "is_flag" marker
> I suppose.
>
> If you want to start typing options, you may want to consider also
> adding .is_string, and then check the option against these
> rules in getnum and getstr - i.e. if is_flag or is_string are set,
> then minval, maxval, is_power_2 must not not set, etc, so the
> developer can't get it wrong.
>
> We'd end up with something like this:
>
>                 { .index = D_FILE,
>                   .conflicts = { LAST_CONFLICT },
>                   .is_flag = 1,
>                 },
>                 { .index = D_NAME,
>                   .conflicts = { LAST_CONFLICT },
>                   .is_string = true,
>                 },
>
> which seems reasonable to me.
>

Well, the actual code will be something like this:

                { .index = D_FILE,
                  .conflicts = { LAST_CONFLICT },
                  .type = BOOL,
                },
                { .index = D_NAME,
                  .conflicts = { LAST_CONFLICT },
                  .type = STRING,
                },

because I already have patches that adds type (if you remember the
union stuff from my last big set). I just didn't realised I have this
code just waiting for some rebase and fixes when I wrote the reply.

So for now, I will keep this as it is and once the type is introduced,
the defaultval can be removed.

Cheers,
Jan

> Thanks,
> -Eric



-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 00/12] mkfs: save user input into opts table
  2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
                   ` (13 preceding siblings ...)
  2017-04-25 16:20 ` Eric Sandeen
@ 2017-06-28 16:18 ` Luis R. Rodriguez
  2017-06-29  7:56   ` Jan Tulak
  14 siblings, 1 reply; 59+ messages in thread
From: Luis R. Rodriguez @ 2017-06-28 16:18 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Sun, Apr 23, 2017 at 08:54:51PM +0200, Jan Tulak wrote:
> Hi guys,
> 
> I decided to split my big patchset into more smaller ones. So, this is the
> first set. It adds set/get functions similar to Dave's suggestion, to save and
> retrieve user values to and from the big opts table and prepares the ground for
> future patches.

*poke* just curious if you were planning on respining these any time soon.

  Luis

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

* Re: [PATCH 00/12] mkfs: save user input into opts table
  2017-06-28 16:18 ` Luis R. Rodriguez
@ 2017-06-29  7:56   ` Jan Tulak
  0 siblings, 0 replies; 59+ messages in thread
From: Jan Tulak @ 2017-06-29  7:56 UTC (permalink / raw)
  To: linux-xfs

On Wed, Jun 28, 2017 at 6:18 PM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Sun, Apr 23, 2017 at 08:54:51PM +0200, Jan Tulak wrote:
>> Hi guys,
>>
>> I decided to split my big patchset into more smaller ones. So, this is the
>> first set. It adds set/get functions similar to Dave's suggestion, to save and
>> retrieve user values to and from the big opts table and prepares the ground for
>> future patches.
>
> *poke* just curious if you were planning on respining these any time soon.
>
>   Luis

Sure, I was off for some time and focusing on school. I got back few
days ago, so give me a week or two before I get the patchset up to
date...

Cheers,
Jan

-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

end of thread, other threads:[~2017-06-29  7:57 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-23 18:54 [PATCH 00/12] mkfs: save user input into opts table Jan Tulak
2017-04-23 18:54 ` [PATCH 01/12] mkfs: Save raw user input field to the opts struct Jan Tulak
2017-04-25 17:38   ` Eric Sandeen
2017-04-23 18:54 ` [PATCH 02/12] mkfs: rename defaultval to flagval in opts Jan Tulak
2017-04-25 16:52   ` Eric Sandeen
2017-04-26  7:30     ` Jan Tulak
2017-04-26 13:02       ` Eric Sandeen
2017-04-26 13:20         ` Jan Tulak
2017-04-23 18:54 ` [PATCH 03/12] mkfs: remove intermediate getstr followed by getnum Jan Tulak
2017-04-25 17:37   ` Eric Sandeen
2017-04-26  7:40     ` Jan Tulak
2017-04-26 13:13       ` Eric Sandeen
2017-04-23 18:54 ` [PATCH 04/12] mkfs: merge tables for opts parsing into one table Jan Tulak
2017-04-25  3:04   ` Luis R. Rodriguez
2017-04-25  7:45     ` Jan Tulak
2017-04-25 13:28       ` Eric Sandeen
2017-04-26  1:38         ` Luis R. Rodriguez
2017-04-26  1:45           ` Luis R. Rodriguez
2017-04-26  2:00           ` Eric Sandeen
2017-04-26  8:01             ` Luis R. Rodriguez
2017-04-26  8:24               ` Jan Tulak
2017-04-26  8:21       ` Luis R. Rodriguez
2017-04-26  8:38         ` Jan Tulak
2017-04-25 21:45   ` Eric Sandeen
2017-04-26  4:09     ` Eric Sandeen
2017-04-26  8:14     ` Jan Tulak
2017-04-23 18:54 ` [PATCH 05/12] mkfs: extend opt_params with a value field Jan Tulak
2017-04-25  3:13   ` Luis R. Rodriguez
2017-04-25  8:04     ` Jan Tulak
2017-04-25  9:39       ` Jan Tulak
2017-04-26  1:04         ` Luis R. Rodriguez
2017-04-26  8:51           ` Jan Tulak
2017-04-26  1:10       ` Luis R. Rodriguez
2017-04-26  2:50         ` Eric Sandeen
2017-04-26  8:52           ` Jan Tulak
2017-04-23 18:54 ` [PATCH 06/12] mkfs: create get/set functions for opts table Jan Tulak
2017-04-25  3:40   ` Luis R. Rodriguez
2017-04-25  8:11     ` Jan Tulak
2017-04-26  1:43       ` Luis R. Rodriguez
2017-04-23 18:54 ` [PATCH 07/12] mkfs: save user input values into opts Jan Tulak
2017-04-25  5:19   ` Luis R. Rodriguez
2017-04-25  8:16     ` Jan Tulak
2017-04-26  1:47       ` Luis R. Rodriguez
2017-04-23 18:54 ` [PATCH 08/12] mkfs: replace variables with opts table: -b,d,s options Jan Tulak
2017-04-25  5:27   ` Luis R. Rodriguez
2017-04-25  5:30     ` Luis R. Rodriguez
2017-04-25  8:37     ` Jan Tulak
2017-04-26  0:45       ` Luis R. Rodriguez
2017-04-26  9:09         ` Jan Tulak
2017-04-23 18:55 ` [PATCH 09/12] mkfs: replace variables with opts table: -i options Jan Tulak
2017-04-23 18:55 ` [PATCH 10/12] mkfs: replace variables with opts table: -l options Jan Tulak
2017-04-23 18:55 ` [PATCH 11/12] mkfs: replace variables with opts table: -n options Jan Tulak
2017-04-23 18:55 ` [PATCH 12/12] mkfs: replace variables with opts table: -r options Jan Tulak
2017-04-25  2:52 ` [PATCH 00/12] mkfs: save user input into opts table Luis R. Rodriguez
2017-04-25 16:20 ` Eric Sandeen
2017-04-26  2:02   ` Luis R. Rodriguez
2017-04-26  2:17     ` Eric Sandeen
2017-06-28 16:18 ` Luis R. Rodriguez
2017-06-29  7:56   ` Jan Tulak

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.