All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks
@ 2016-12-07 13:27 Jan Tulak
  2016-12-07 13:27 ` [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum Jan Tulak
                   ` (25 more replies)
  0 siblings, 26 replies; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Hi guys,

this set is a follow-up of some old discussions and further attempts to untangle
the spaghetti in options parsing. In short, this patchset allows to define
cross-option conflicts and makes the conflicts detection more robust.

Until now, we had the ability to define conflicts within one option (e.g. -d
sunit/su), but things like -i attr=1 -m crc=1 conflict had to be watched for on
case by case basis somewhere in the code. Now, when even those situations are
handled by the same code, it is enough to just add a new entry into a table of
options. Thus, a reduced chance for an error and easier adding of new cases.

One of the biggest changes in this set is that user input is now stored in
directly in the opts table defining allowed range and the like, and variables
in the main() of mkfs.xfs are now just aliases/pointers. This allows as to do
conditional checks based on actual values, not only on occurence of an option.

(A technical note here is that not every value can be saved in a single place
like this. Some values are already stored in a table or structure and I wanted
to avoid modifying anything outside of xfs_mkfs.c.)

I tested it with full xfstests suit and the only failed tests I saw are because
some ambiguity in arguments parsing was removed. E.g. sometimes it was possible
to specify size in blocks without stating the blocksize first, even if manpage
explicitly requires -b or -s to be used before.

I already submitted part of this patchset as RFC before, but as I got no reply,
I tried to finish it before submitting again. So, this set works as it is. I
still have some questions, but they can be answered with "let's keep it as it
is."

Number one is simple: What values can use block/sector sizes as user input?
There is an inconsistency or ambiguity between manual page and the code. Look
at man page for -d agsize.

	agsize=value
		This is an alternative to using the  agcount  subop‐
		tion.  The  value is the desired size of the alloca‐
		tion group expressed in bytes (usually using  the  m
		                     ^^^^^^^^
		or  g  suffixes).   This value must be a multiple of
		[ ... ]


The option -d agsize explicitly states that it accepts size in bytes, in a
similar tone to the one used for describe allowed values for -s/-b size:

	value in bytes with size=value
	      ^^^^^^^^

However, -d agsize=1234s input was accepted as valid until now. Is the manual
page misleading, or are the options where b/s suffix is forbidden are
block/sector size definitions? I decided to err on the compatibility side and
kept the current behaviour - only blocksize or sectorsize can't be stated in
blocks and sectors, but it can be easily changed.

I will send an update for xfstests once I know what behaviour is correct.


The other question about this patchset is: As we are saving all the values in
the opt_params table, and the values have different types, I thought it
necessary to not use a single data type for everything and created an union
field (could be easily changed to struct, that would not change anything
important). Do you see any non-adressed issue with this approach? Is there
another way how to solve the problem?

If nothing else, numbers and strings can't be easily saved in a single
variable. Also, as we are using shift operations, any type conversions
(like storing everything in long long type) could cause trouble. This is one of
the reasons why I'm changed the variables in main() to pointers. This allows
for simple and easy access to the correct union field, so unless one is adding
a new option, there should be no need to remember the correct date type. If the
pointer assignment is done correctly, then GCC will watch for type mismatch.

I really couldn't find out better solution, but see for yourself, this change
is done in "mkfs: Change all value fields in opt structures into unions"
and "mkfs: use old variables as pointers to the new opts struct values".


So, I think this is all I wanted to cover in the cover letter. :-)
I will be glad for any comments or bugs you find out.

Thanks for your time,

Jan


Jan Tulak (22):
  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: change conflicts array into a table capable of cross-option
    addressing
  mkfs: add a check for conflicting values
  mkfs: add cross-section conflict checks
  mkfs: Move opts related #define to one place
  mkfs: move conflicts into the table
  mkfs: change conflict checks to utilize the new conflict structure
  mkfs: change when to mark an option as seen
  mkfs: add test_default_value into conflict struct
  mkfs: expand conflicts declarations to named declaration
  mkfs: remove zeroed items from conflicts declaration
  mkfs: rename defaultval to flagval in opts
  mkfs: replace SUBOPT_NEEDS_VAL for a flag
  mkfs: Change all value fields in opt structures into unions
  mkfs: use old variables as pointers to the new opts struct values
  mkfs: prevent sector/blocksize to be specified as a number of blocks
  mkfs: subopt flags should be saved as bool
  mkfs: move uuid empty string test to getstr()
  mkfs: remove duplicit checks
  mkfs: prevent multiple specifications of a single option

 mkfs/xfs_mkfs.c | 2952 +++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 1864 insertions(+), 1088 deletions(-)

-- 
2.8.1


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

* [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 16:56   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 02/22] mkfs: merge tables for opts parsing into one table Jan Tulak
                   ` (24 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 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>
---
 mkfs/xfs_mkfs.c | 88 +++++++++++++++++++++++++--------------------------------
 1 file changed, 38 insertions(+), 50 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index affa405..b3bc218 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1417,7 +1417,7 @@ main(
 	char			*dfile;
 	int			dirblocklog;
 	int			dirblocksize;
-	char			*dsize;
+	__uint64_t 		dbytes;
 	int			dsu;
 	int			dsw;
 	int			dsunit;
@@ -1441,7 +1441,7 @@ main(
 	xfs_rfsblock_t		logblocks;
 	char			*logfile;
 	int			loginternal;
-	char			*logsize;
+	__uint64_t 		logbytes;
 	xfs_fsblock_t		logstart;
 	int			lvflag;
 	int			lsflag;
@@ -1470,11 +1470,11 @@ main(
 	char			*protostring;
 	int			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;
 	int			sectorlog;
 	__uint64_t		sector_mask;
@@ -1522,7 +1522,8 @@ main(
 	qflag = 0;
 	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 = 0;
 	force_overwrite = 0;
@@ -1586,7 +1587,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);
@@ -1731,7 +1732,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,
@@ -1860,8 +1861,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,
@@ -1873,7 +1873,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,
@@ -1976,14 +1976,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,
+		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)
@@ -2164,10 +2164,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 %lld, not a multiple of %d\n"),
@@ -2196,10 +2193,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 %lld, not a multiple of %d\n"),
@@ -2213,10 +2207,7 @@ _("rmapbt not supported with realtime devices\n"));
 				(long long)logbytes, blocksize,
 				(long long)(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 %lld, not a multiple of %d\n"),
@@ -2233,10 +2224,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 %lld, not a multiple of %d\n"),
@@ -2253,7 +2241,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;
@@ -2364,15 +2352,15 @@ _("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, "
+			_("size %lld specified for data subvolume is too large, "
 			"maximum is %lld blocks\n"),
-			dsize, (long long)DTOBT(xi.dsize));
+			(long long)dbytes, (long long)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();
 	}
@@ -2405,22 +2393,22 @@ 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 %u 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, "
+			_("size %lld specified for rt subvolume is too large, "
 			"maximum is %lld blocks\n"),
-			rtsize, (long long)DTOBT(xi.rtsize));
+			(long long)rtbytes, (long long)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();
@@ -2625,26 +2613,26 @@ an AG size that is one stripe unit smaller, for example %llu.\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 %lld blocks\n"),
-			logsize, (long long)DTOBT(xi.logBBsize));
+_("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"),
+			(long long)logbytes, (long long)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 %lld too large for internal log\n"),
 			(long long)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. */
@@ -2708,7 +2696,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
 		 * 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.8.1


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

* [PATCH 02/22] mkfs: merge tables for opts parsing into one table
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
  2016-12-07 13:27 ` [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 16:57   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 03/22] mkfs: extend opt_params with a value field Jan Tulak
                   ` (23 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 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 | 1250 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 642 insertions(+), 608 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index b3bc218..372c620 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -42,6 +42,7 @@ static int  ispow2(unsigned int i);
 unsigned int		blocksize;
 unsigned int		sectorsize;
 
+#define MAX_OPTS	16
 #define MAX_SUBOPTS	16
 #define SUBOPT_NEEDS_VAL	(-1LL)
 #define MAX_CONFLICTS	8
@@ -52,6 +53,10 @@ unsigned int		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'.
  *
@@ -112,6 +117,7 @@ unsigned int		sectorsize;
  *     value in any case.
  */
 struct opt_params {
+	int		index;
 	const char	name;
 	const char	*subopts[MAX_SUBOPTS];
 
@@ -126,584 +132,592 @@ struct opt_params {
 		long long	maxval;
 		long long	defaultval;
 	}		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,
-		  .defaultval = 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,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		.subopt_params = {
+			{ .index = B_LOG,
+			  .conflicts = { B_SIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_BLOCKSIZE_LOG,
+			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
+			  .defaultval = 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,
+			  .defaultval = 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,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_FILE,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 1,
-		},
-		{ .index = D_NAME,
-		  .conflicts = { LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SIZE,
-		  .conflicts = { LAST_CONFLICT },
-		  .convert = true,
-		  .minval = XFS_AG_MIN_BYTES,
-		  .maxval = LLONG_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SUNIT,
-		  .conflicts = { D_NOALIGN,
-				 D_SU,
-				 D_SW,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SWIDTH,
-		  .conflicts = { D_NOALIGN,
-				 D_SU,
-				 D_SW,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_AGSIZE,
-		  .conflicts = { D_AGCOUNT,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .minval = XFS_AG_MIN_BYTES,
-		  .maxval = XFS_AG_MAX_BYTES,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SU,
-		  .conflicts = { D_NOALIGN,
-				 D_SUNIT,
-				 D_SWIDTH,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_SW,
-		  .conflicts = { D_NOALIGN,
-				 D_SUNIT,
-				 D_SWIDTH,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .defaultval = 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,
-		},
-		{ .index = D_SECTSIZE,
-		  .conflicts = { D_SECTLOG,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .is_power_2 = true,
-		  .minval = XFS_MIN_SECTORSIZE,
-		  .maxval = XFS_MAX_SECTORSIZE,
-		  .defaultval = 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,
-		  .defaultval = 1,
-		},
-		{ .index = D_RTINHERIT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 1,
-		  .maxval = 1,
-		  .defaultval = 1,
-		},
-		{ .index = D_PROJINHERIT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = D_EXTSZINHERIT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = UINT_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		.subopt_params = {
+			{ .index = D_AGCOUNT,
+			  .conflicts = { D_AGSIZE,
+					 LAST_CONFLICT },
+			  .minval = 1,
+			  .maxval = XFS_MAX_AGNUMBER,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_FILE,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			},
+			{ .index = D_NAME,
+			  .conflicts = { LAST_CONFLICT },
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SIZE,
+			  .conflicts = { LAST_CONFLICT },
+			  .convert = true,
+			  .minval = XFS_AG_MIN_BYTES,
+			  .maxval = LLONG_MAX,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SUNIT,
+			  .conflicts = { D_NOALIGN,
+					 D_SU,
+					 D_SW,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SWIDTH,
+			  .conflicts = { D_NOALIGN,
+					 D_SU,
+					 D_SW,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_AGSIZE,
+			  .conflicts = { D_AGCOUNT,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .minval = XFS_AG_MIN_BYTES,
+			  .maxval = XFS_AG_MAX_BYTES,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SU,
+			  .conflicts = { D_NOALIGN,
+					 D_SUNIT,
+					 D_SWIDTH,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_SW,
+			  .conflicts = { D_NOALIGN,
+					 D_SUNIT,
+					 D_SWIDTH,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .defaultval = 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,
+			},
+			{ .index = D_SECTSIZE,
+			  .conflicts = { D_SECTLOG,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .is_power_2 = true,
+			  .minval = XFS_MIN_SECTORSIZE,
+			  .maxval = XFS_MAX_SECTORSIZE,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_NOALIGN,
+			  .conflicts = { D_SU,
+					 D_SW,
+					 D_SUNIT,
+					 D_SWIDTH,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			},
+			{ .index = D_RTINHERIT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 1,
+			  .maxval = 1,
+			  .defaultval = 1,
+			},
+			{ .index = D_PROJINHERIT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = D_EXTSZINHERIT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .defaultval = 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,
-		  .defaultval = 1,
-		},
-		{ .index = I_LOG,
-		  .conflicts = { I_PERBLOCK,
-				 I_SIZE,
-				 LAST_CONFLICT },
-		  .minval = XFS_DINODE_MIN_LOG,
-		  .maxval = XFS_DINODE_MAX_LOG,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+			"sparse",
+			NULL
 		},
-		{ .index = I_MAXPCT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 100,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		.subopt_params = {
+			{ .index = I_ALIGN,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			},
+			{ .index = I_LOG,
+			  .conflicts = { I_PERBLOCK,
+					 I_SIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_DINODE_MIN_LOG,
+			  .maxval = XFS_DINODE_MAX_LOG,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = I_MAXPCT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 100,
+			  .defaultval = 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,
+			  .defaultval = 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,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = I_ATTR,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 2,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = I_PROJID32BIT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			},
+			{ .index = I_SPINODES,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			},
 		},
-		{ .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,
-		  .defaultval = 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,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = I_ATTR,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 2,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = I_PROJID32BIT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 1,
-		},
-		{ .index = I_SPINODES,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 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,
-		  .defaultval = SUBOPT_NEEDS_VAL,
+#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_INTERNAL,
-		  .conflicts = { L_FILE,
-				 L_DEV,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 1,
+		.subopt_params = {
+			{ .index = L_AGNUM,
+			  .conflicts = { L_DEV,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = UINT_MAX,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_INTERNAL,
+			  .conflicts = { L_FILE,
+					 L_DEV,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 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,
+			},
+			{ .index = L_VERSION,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 1,
+			  .maxval = 2,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_SUNIT,
+			  .conflicts = { L_SU,
+					 LAST_CONFLICT },
+			  .minval = 1,
+			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_SU,
+			  .conflicts = { L_SUNIT,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .minval = BBTOB(1),
+			  .maxval = XLOG_MAX_RECORD_BSIZE,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_DEV,
+			  .conflicts = { L_AGNUM,
+					 L_INTERNAL,
+					 LAST_CONFLICT },
+			  .defaultval = 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,
+			},
+			{ .index = L_SECTSIZE,
+			  .conflicts = { L_SECTLOG,
+					 LAST_CONFLICT },
+			  .convert = true,
+			  .is_power_2 = true,
+			  .minval = XFS_MIN_SECTORSIZE,
+			  .maxval = XFS_MAX_SECTORSIZE,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_FILE,
+			  .conflicts = { L_INTERNAL,
+					 LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			},
+			{ .index = L_NAME,
+			  .conflicts = { L_AGNUM,
+					 L_INTERNAL,
+					 LAST_CONFLICT },
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = L_LAZYSBCNTR,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 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,
-		},
-		{ .index = L_VERSION,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 1,
-		  .maxval = 2,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_SUNIT,
-		  .conflicts = { L_SU,
-				 LAST_CONFLICT },
-		  .minval = 1,
-		  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_SU,
-		  .conflicts = { L_SUNIT,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .minval = BBTOB(1),
-		  .maxval = XLOG_MAX_RECORD_BSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_DEV,
-		  .conflicts = { L_AGNUM,
-				 L_INTERNAL,
-				 LAST_CONFLICT },
-		  .defaultval = 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,
-		},
-		{ .index = L_SECTSIZE,
-		  .conflicts = { L_SECTLOG,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .is_power_2 = true,
-		  .minval = XFS_MIN_SECTORSIZE,
-		  .maxval = XFS_MAX_SECTORSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_FILE,
-		  .conflicts = { L_INTERNAL,
-				 LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 1,
-		},
-		{ .index = L_NAME,
-		  .conflicts = { L_AGNUM,
-				 L_INTERNAL,
-				 LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = L_LAZYSBCNTR,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 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,
-		  .defaultval = 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_SIZE,
-		  .conflicts = { N_LOG,
-				 LAST_CONFLICT },
-		  .convert = true,
-		  .is_power_2 = true,
-		  .minval = 1 << XFS_MIN_REC_DIRSIZE,
-		  .maxval = XFS_MAX_BLOCKSIZE,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = N_VERSION,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 2,
-		  .maxval = 2,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = N_FTYPE,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 1,
+		.subopt_params = {
+			{ .index = N_LOG,
+			  .conflicts = { N_SIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_REC_DIRSIZE,
+			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
+			  .defaultval = 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,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = N_VERSION,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 2,
+			  .maxval = 2,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = N_FTYPE,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 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,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = R_SIZE,
-		  .conflicts = { LAST_CONFLICT },
-		  .convert = true,
-		  .minval = 0,
-		  .maxval = LLONG_MAX,
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = R_DEV,
-		  .conflicts = { LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = R_FILE,
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 1,
-		  .conflicts = { LAST_CONFLICT },
+#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_NAME,
-		  .conflicts = { LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
+		.subopt_params = {
+			{ .index = R_EXTSIZE,
+			  .conflicts = { LAST_CONFLICT },
+			  .convert = true,
+			  .minval = XFS_MIN_RTEXTSIZE,
+			  .maxval = XFS_MAX_RTEXTSIZE,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = R_SIZE,
+			  .conflicts = { LAST_CONFLICT },
+			  .convert = true,
+			  .minval = 0,
+			  .maxval = LLONG_MAX,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = R_DEV,
+			  .conflicts = { LAST_CONFLICT },
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = R_FILE,
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			  .conflicts = { LAST_CONFLICT },
+			},
+			{ .index = R_NAME,
+			  .conflicts = { LAST_CONFLICT },
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = R_NOALIGN,
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			  .conflicts = { LAST_CONFLICT },
+			},
 		},
-		{ .index = R_NOALIGN,
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 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,
-		  .defaultval = 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_SECTLOG,
-		  .conflicts = { S_SIZE,
-				 S_SECTSIZE,
-				 LAST_CONFLICT },
-		  .minval = XFS_MIN_SECTORSIZE_LOG,
-		  .maxval = XFS_MAX_SECTORSIZE_LOG,
-		  .defaultval = 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,
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = S_SECTLOG,
+			  .conflicts = { S_SIZE,
+					 S_SECTSIZE,
+					 LAST_CONFLICT },
+			  .minval = XFS_MIN_SECTORSIZE_LOG,
+			  .maxval = XFS_MAX_SECTORSIZE_LOG,
+			  .defaultval = 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,
+			  .defaultval = 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,
+			  .defaultval = 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,
-		  .defaultval = 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,
-		  .defaultval = 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,
-		  .defaultval = 1,
-		},
-		{ .index = M_FINOBT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 1,
-		},
-		{ .index = M_UUID,
-		  .conflicts = { LAST_CONFLICT },
-		  .defaultval = SUBOPT_NEEDS_VAL,
-		},
-		{ .index = M_RMAPBT,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 0,
+#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_REFLINK,
-		  .conflicts = { LAST_CONFLICT },
-		  .minval = 0,
-		  .maxval = 1,
-		  .defaultval = 0,
+		.subopt_params = {
+			{ .index = M_CRC,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			},
+			{ .index = M_FINOBT,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 1,
+			},
+			{ .index = M_UUID,
+			  .conflicts = { LAST_CONFLICT },
+			  .defaultval = SUBOPT_NEEDS_VAL,
+			},
+			{ .index = M_RMAPBT,
+			.conflicts = { LAST_CONFLICT },
+			.minval = 0,
+			.maxval = 1,
+			.defaultval = 0,
+			},
+			{ .index = M_REFLINK,
+			  .conflicts = { LAST_CONFLICT },
+			  .minval = 0,
+			  .maxval = 1,
+			  .defaultval = 0,
+			},
 		},
 	},
 };
@@ -1543,17 +1557,18 @@ 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;
@@ -1566,73 +1581,78 @@ 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,
+					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,
+					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,
+					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,
+					fsx.fsx_extsize = getnum(value, &opts[OPT_D],
 								 D_EXTSZINHERIT);
 					fsx.fsx_xflags |=
 						XFS_DIFLAG_EXTSZINHERIT;
@@ -1645,46 +1665,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);
@@ -1694,54 +1719,59 @@ 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,
+					xi.lisfile = getnum(value, &opts[OPT_L],
 							    L_FILE);
 					break;
 				case L_INTERNAL:
-					loginternal = getnum(value, &lopts,
+					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,
+					lsectorlog = getnum(value, &opts[OPT_L],
 							    L_SECTLOG);
 					lsectorsize = 1 << lsectorlog;
 					lslflag = 1;
 					break;
 				case L_SECTSIZE:
-					lsectorsize = getnum(value, &lopts,
+					lsectorsize = getnum(value, &opts[OPT_L],
 							     L_SECTSIZE);
 					lsectorlog =
 						libxfs_highbit32(lsectorsize);
@@ -1749,7 +1779,7 @@ main(
 					break;
 				case L_LAZYSBCNTR:
 					sb_feat.lazy_sb_counters =
-							getnum(value, &lopts,
+							getnum(value, &opts[OPT_L],
 							       L_LAZYSBCNTR);
 					break;
 				default:
@@ -1765,19 +1795,20 @@ 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')
@@ -1787,11 +1818,11 @@ 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);
+						value, &opts[OPT_M], M_REFLINK);
 					break;
 				default:
 					unknown('m', value);
@@ -1801,37 +1832,38 @@ 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,
+					dirblocklog = getnum(value, &opts[OPT_N],
 							     N_LOG);
 					dirblocksize = 1 << dirblocklog;
 					nlflag = 1;
 					break;
 				case N_SIZE:
-					dirblocksize = getnum(value, &nopts,
+					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,
+					sb_feat.dirftype = getnum(value, &opts[OPT_N],
 								  N_FTYPE);
 					break;
 				default:
@@ -1856,27 +1888,29 @@ 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,
+					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:
@@ -1887,7 +1921,7 @@ 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)) {
@@ -1896,7 +1930,7 @@ main(
 					if (lssflag)
 						conflict('s', subopts,
 							 S_SECTSIZE, S_SECTLOG);
-					sectorlog = getnum(value, &sopts,
+					sectorlog = getnum(value, &opts[OPT_S],
 							   S_SECTLOG);
 					lsectorlog = sectorlog;
 					sectorsize = 1 << sectorlog;
@@ -1908,7 +1942,7 @@ main(
 					if (lslflag)
 						conflict('s', subopts, S_SECTLOG,
 							 S_SECTSIZE);
-					sectorsize = getnum(value, &sopts,
+					sectorsize = getnum(value, &opts[OPT_S],
 							    S_SECTSIZE);
 					lsectorsize = sectorsize;
 					sectorlog =
@@ -1932,7 +1966,7 @@ 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;
 
@@ -2111,7 +2145,7 @@ _("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();
-- 
2.8.1


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

* [PATCH 03/22] mkfs: extend opt_params with a value field
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
  2016-12-07 13:27 ` [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum Jan Tulak
  2016-12-07 13:27 ` [PATCH 02/22] mkfs: merge tables for opts parsing into one table Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 16:55   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing Jan Tulak
                   ` (22 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 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 | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 372c620..edcfdc0 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -115,6 +115,12 @@ unsigned int		sectorsize;
  *     sets what is used with simple specifying the subopt (-d file).
  *     A special SUBOPT_NEEDS_VAL can be used to require a user-given
  *     value in any case.
+ *
+ *   value INTERNAL
+ *     Do not set this on initialization. Use defaultval for what you want
+ *     to do. This is filled with user input and anything you write here now
+ *     is overwritten. (If the user input is a string and not a number, this
+ *     value is set to a positive non-zero number.)
  */
 struct opt_params {
 	int		index;
@@ -131,6 +137,7 @@ struct opt_params {
 		long long	minval;
 		long long	maxval;
 		long long	defaultval;
+		long long	value;
 	}		subopt_params[MAX_SUBOPTS];
 } opts[MAX_OPTS] = {
 #define OPT_B	0
@@ -1566,12 +1573,20 @@ main(
 								B_LOG);
 					blocksize = 1 << blocklog;
 					blflag = 1;
+					opts[OPT_B].subopt_params[B_LOG].value =
+							blocklog;
+					opts[OPT_B].subopt_params[B_SIZE].value =
+							blocksize;
 					break;
 				case B_SIZE:
 					blocksize = getnum(value, &opts[OPT_B],
 							   B_SIZE);
 					blocklog = libxfs_highbit32(blocksize);
 					bsflag = 1;
+					opts[OPT_B].subopt_params[B_LOG].value =
+							blocklog;
+					opts[OPT_B].subopt_params[B_SIZE].value =
+							blocksize;
 					break;
 				default:
 					unknown('b', value);
@@ -1589,47 +1604,70 @@ main(
 					agcount = getnum(value, &opts[OPT_D],
 							 D_AGCOUNT);
 					daflag = 1;
+					opts[OPT_D].subopt_params[D_AGCOUNT].value =
+							agcount;
 					break;
 				case D_AGSIZE:
 					agsize = getnum(value, &opts[OPT_D],
 								D_AGSIZE);
 					dasize = 1;
+					opts[OPT_D].subopt_params[D_AGSIZE].value =
+							agsize;
 					break;
 				case D_FILE:
 					xi.disfile = getnum(value, &opts[OPT_D],
 							    D_FILE);
+					opts[OPT_D].subopt_params[D_FILE].value =
+							xi.disfile;
 					break;
 				case D_NAME:
 					xi.dname = getstr(value, &opts[OPT_D],
 								D_NAME);
+					opts[OPT_D].subopt_params[D_NAME].value = 1;
 					break;
 				case D_SIZE:
 					dbytes = getnum(value, &opts[OPT_D],
 								D_SIZE);
+					opts[OPT_D].subopt_params[D_SIZE].value =
+							dbytes;
 					break;
 				case D_SUNIT:
 					dsunit = getnum(value, &opts[OPT_D],
 								D_SUNIT);
+					opts[OPT_D].subopt_params[D_SUNIT].value =
+							dsunit;
 					break;
 				case D_SWIDTH:
 					dswidth = getnum(value, &opts[OPT_D],
 							 D_SWIDTH);
+					opts[OPT_D].subopt_params[D_SWIDTH].value =
+							dswidth;
 					break;
 				case D_SU:
 					dsu = getnum(value, &opts[OPT_D], D_SU);
+					opts[OPT_D].subopt_params[D_SU].value =
+							dsu;
 					break;
 				case D_SW:
 					dsw = getnum(value, &opts[OPT_D], D_SW);
+					opts[OPT_D].subopt_params[D_SW].value =
+							dsw;
 					break;
 				case D_NOALIGN:
 					nodsflag = getnum(value, &opts[OPT_D],
 								D_NOALIGN);
+					opts[OPT_D].subopt_params[D_NOALIGN].value =
+							nodsflag;
 					break;
 				case D_SECTLOG:
 					sectorlog = getnum(value, &opts[OPT_D],
 							   D_SECTLOG);
 					sectorsize = 1 << sectorlog;
 					slflag = 1;
+					opts[OPT_D].subopt_params[D_SECTSIZE].value =
+							sectorsize;
+					opts[OPT_D].subopt_params[D_SECTLOG].value =
+							sectorlog;
 					break;
 				case D_SECTSIZE:
 					sectorsize = getnum(value, &opts[OPT_D],
@@ -1637,6 +1675,10 @@ main(
 					sectorlog =
 						libxfs_highbit32(sectorsize);
 					ssflag = 1;
+					opts[OPT_D].subopt_params[D_SECTSIZE].value =
+							sectorsize;
+					opts[OPT_D].subopt_params[D_SECTLOG].value =
+							sectorlog;
 					break;
 				case D_RTINHERIT:
 					c = getnum(value, &opts[OPT_D],
@@ -1644,18 +1686,24 @@ main(
 					if (c)
 						fsx.fsx_xflags |=
 							XFS_DIFLAG_RTINHERIT;
+					opts[OPT_D].subopt_params[D_RTINHERIT].value =
+							c;
 					break;
 				case D_PROJINHERIT:
 					fsx.fsx_projid = getnum(value, &opts[OPT_D],
 								D_PROJINHERIT);
 					fsx.fsx_xflags |=
 						XFS_DIFLAG_PROJINHERIT;
+					opts[OPT_D].subopt_params[D_PROJINHERIT].value =
+							fsx.fsx_projid;
 					break;
 				case D_EXTSZINHERIT:
 					fsx.fsx_extsize = getnum(value, &opts[OPT_D],
 								 D_EXTSZINHERIT);
 					fsx.fsx_xflags |=
 						XFS_DIFLAG_EXTSZINHERIT;
+					opts[OPT_D].subopt_params[D_EXTSZINHERIT].value =
+							fsx.fsx_extsize;
 					break;
 				default:
 					unknown('d', value);
@@ -1673,43 +1721,64 @@ main(
 					sb_feat.inode_align = getnum(value,
 								&opts[OPT_I],
 								I_ALIGN);
+					opts[OPT_I].subopt_params[I_ALIGN].value =
+							sb_feat.inode_align;
 					break;
 				case I_LOG:
 					inodelog = getnum(value, &opts[OPT_I],
 								I_LOG);
 					isize = 1 << inodelog;
 					ilflag = 1;
+					opts[OPT_I].subopt_params[I_SIZE].value =
+							isize;
+					opts[OPT_I].subopt_params[I_LOG].value =
+							inodelog;
 					break;
 				case I_MAXPCT:
 					imaxpct = getnum(value, &opts[OPT_I],
 							 I_MAXPCT);
 					imflag = 1;
+					opts[OPT_I].subopt_params[I_MAXPCT].value =
+							imaxpct;
 					break;
 				case I_PERBLOCK:
 					inopblock = getnum(value, &opts[OPT_I],
 							   I_PERBLOCK);
 					ipflag = 1;
+					opts[OPT_I].subopt_params[I_PERBLOCK].value =
+							inopblock;
 					break;
 				case I_SIZE:
 					isize = getnum(value, &opts[OPT_I],
 								I_SIZE);
 					inodelog = libxfs_highbit32(isize);
 					isflag = 1;
+					opts[OPT_I].subopt_params[I_SIZE].value =
+							isize;
+					opts[OPT_I].subopt_params[I_LOG].value =
+							inodelog;
 					break;
 				case I_ATTR:
 					sb_feat.attr_version =
+
 						getnum(value, &opts[OPT_I],
 								I_ATTR);
+					opts[OPT_I].subopt_params[I_ATTR].value =
+							sb_feat.attr_version;
 					break;
 				case I_PROJID32BIT:
 					sb_feat.projid16bit =
 						!getnum(value, &opts[OPT_I],
 							I_PROJID32BIT);
+					opts[OPT_I].subopt_params[I_PROJID32BIT].value =
+							sb_feat.projid16bit;
 					break;
 				case I_SPINODES:
 					sb_feat.spinodes = getnum(value,
 								&opts[OPT_I],
 								I_SPINODES);
+					opts[OPT_I].subopt_params[I_SPINODES].value =
+							sb_feat.spinodes;
 					break;
 				default:
 					unknown('i', value);
@@ -1727,24 +1796,34 @@ main(
 					logagno = getnum(value, &opts[OPT_L],
 								L_AGNUM);
 					laflag = 1;
+					opts[OPT_L].subopt_params[L_AGNUM].value =
+							logagno;
 					break;
 				case L_FILE:
 					xi.lisfile = getnum(value, &opts[OPT_L],
 							    L_FILE);
+					opts[OPT_L].subopt_params[L_FILE].value =
+							xi.lisfile;
 					break;
 				case L_INTERNAL:
 					loginternal = getnum(value, &opts[OPT_L],
 							     L_INTERNAL);
 					liflag = 1;
+					opts[OPT_L].subopt_params[L_INTERNAL].value =
+							loginternal;
 					break;
 				case L_SU:
 					lsu = getnum(value, &opts[OPT_L], L_SU);
 					lsuflag = 1;
+					opts[OPT_L].subopt_params[L_SU].value =
+							lsu;
 					break;
 				case L_SUNIT:
 					lsunit = getnum(value, &opts[OPT_L],
 								L_SUNIT);
 					lsunitflag = 1;
+					opts[OPT_L].subopt_params[L_SUNIT].value =
+							lsunit;
 					break;
 				case L_NAME:
 				case L_DEV:
@@ -1753,22 +1832,32 @@ main(
 					xi.logname = logfile;
 					ldflag = 1;
 					loginternal = 0;
+					opts[OPT_L].subopt_params[L_NAME].value = 1;
+					opts[OPT_L].subopt_params[L_DEV].value = 1;
 					break;
 				case L_VERSION:
 					sb_feat.log_version =
 						getnum(value, &opts[OPT_L],
 								L_VERSION);
 					lvflag = 1;
+					opts[OPT_L].subopt_params[L_VERSION].value =
+							sb_feat.log_version;
 					break;
 				case L_SIZE:
 					logbytes = getnum(value, &opts[OPT_L],
 								L_SIZE);
+					opts[OPT_L].subopt_params[L_SIZE].value =
+							logbytes;
 					break;
 				case L_SECTLOG:
 					lsectorlog = getnum(value, &opts[OPT_L],
 							    L_SECTLOG);
 					lsectorsize = 1 << lsectorlog;
 					lslflag = 1;
+					opts[OPT_L].subopt_params[L_SECTSIZE].value =
+							lsectorsize;
+					opts[OPT_L].subopt_params[L_SECTLOG].value =
+							lsectorlog;
 					break;
 				case L_SECTSIZE:
 					lsectorsize = getnum(value, &opts[OPT_L],
@@ -1776,11 +1865,17 @@ main(
 					lsectorlog =
 						libxfs_highbit32(lsectorsize);
 					lssflag = 1;
+					opts[OPT_L].subopt_params[L_SECTSIZE].value =
+							lsectorsize;
+					opts[OPT_L].subopt_params[L_SECTLOG].value =
+							lsectorlog;
 					break;
 				case L_LAZYSBCNTR:
 					sb_feat.lazy_sb_counters =
 							getnum(value, &opts[OPT_L],
 							       L_LAZYSBCNTR);
+					opts[OPT_L].subopt_params[L_LAZYSBCNTR].value =
+							sb_feat.lazy_sb_counters;
 					break;
 				default:
 					unknown('l', value);
@@ -1805,20 +1900,27 @@ main(
 								M_CRC);
 					if (sb_feat.crcs_enabled)
 						sb_feat.dirftype = true;
+					opts[OPT_M].subopt_params[M_CRC].value =
+							sb_feat.crcs_enabled;
 					break;
 				case M_FINOBT:
 					sb_feat.finobt = getnum(
 						value, &opts[OPT_M], M_FINOBT);
+					opts[OPT_M].subopt_params[M_FINOBT].value =
+							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");
+					opts[OPT_M].subopt_params[M_UUID].value = 1;
 					break;
 				case M_RMAPBT:
 					sb_feat.rmapbt = getnum(
 						value, &opts[OPT_M], M_RMAPBT);
+					opts[OPT_M].subopt_params[M_RMAPBT].value = 
+						sb_feat.rmapbt;
 					break;
 				case M_REFLINK:
 					sb_feat.reflink = getnum(
@@ -1841,6 +1943,10 @@ main(
 							     N_LOG);
 					dirblocksize = 1 << dirblocklog;
 					nlflag = 1;
+					opts[OPT_N].subopt_params[N_SIZE].value =
+							dirblocksize;
+					opts[OPT_N].subopt_params[N_LOG].value =
+							dirblocklog;
 					break;
 				case N_SIZE:
 					dirblocksize = getnum(value, &opts[OPT_N],
@@ -1848,6 +1954,10 @@ main(
 					dirblocklog =
 						libxfs_highbit32(dirblocksize);
 					nsflag = 1;
+					opts[OPT_N].subopt_params[N_SIZE].value =
+							dirblocksize;
+					opts[OPT_N].subopt_params[N_LOG].value =
+							dirblocklog;
 					break;
 				case N_VERSION:
 					value = getstr(value, &opts[OPT_N],
@@ -1861,10 +1971,14 @@ main(
 							       N_VERSION);
 					}
 					nvflag = 1;
+					opts[OPT_N].subopt_params[N_VERSION].value =
+							sb_feat.dir_version;
 					break;
 				case N_FTYPE:
 					sb_feat.dirftype = getnum(value, &opts[OPT_N],
 								  N_FTYPE);
+					opts[OPT_N].subopt_params[N_FTYPE].value =
+							sb_feat.dirftype;
 					break;
 				default:
 					unknown('n', value);
@@ -1895,23 +2009,33 @@ main(
 				case R_EXTSIZE:
 					rtextbytes = getnum(value, &opts[OPT_R],
 								R_EXTSIZE);
+					opts[OPT_R].subopt_params[R_EXTSIZE].value =
+							rtextbytes;
 					break;
 				case R_FILE:
 					xi.risfile = getnum(value, &opts[OPT_R],
 							    R_FILE);
+					opts[OPT_R].subopt_params[R_FILE].value =
+							xi.risfile;
 					break;
 				case R_NAME:
 				case R_DEV:
 					xi.rtname = getstr(value, &opts[OPT_R],
 							   R_NAME);
+					opts[OPT_R].subopt_params[R_NAME].value = 1;
+					opts[OPT_R].subopt_params[R_DEV].value = 1;
 					break;
 				case R_SIZE:
 					rtbytes = getnum(value, &opts[OPT_R],
 								R_SIZE);
+					opts[OPT_R].subopt_params[R_SIZE].value =
+							rtbytes;
 					break;
 				case R_NOALIGN:
 					norsflag = getnum(value, &opts[OPT_R],
 								R_NOALIGN);
+					opts[OPT_R].subopt_params[R_NOALIGN].value =
+							norsflag;
 					break;
 				default:
 					unknown('r', value);
@@ -1936,6 +2060,10 @@ main(
 					sectorsize = 1 << sectorlog;
 					lsectorsize = sectorsize;
 					lslflag = slflag = 1;
+					opts[OPT_S].subopt_params[S_LOG].value =
+							sectorsize;
+					opts[OPT_S].subopt_params[S_SECTLOG].value =
+							sectorsize;
 					break;
 				case S_SIZE:
 				case S_SECTSIZE:
@@ -1949,6 +2077,10 @@ main(
 						libxfs_highbit32(sectorsize);
 					lsectorlog = sectorlog;
 					lssflag = ssflag = 1;
+					opts[OPT_S].subopt_params[S_SIZE].value =
+							sectorlog;
+					opts[OPT_S].subopt_params[S_SECTSIZE].value =
+							sectorlog;
 					break;
 				default:
 					unknown('s', value);
-- 
2.8.1


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

* [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (2 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 03/22] mkfs: extend opt_params with a value field Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 17:56   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 05/22] mkfs: add a check for conflicting values Jan Tulak
                   ` (21 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Change subopt_param.conflicts from array of integers into array of structures.
This prepares the ground for more universal conflict detection in future
patches.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index edcfdc0..b47cdae 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -93,8 +93,16 @@ unsigned int		sectorsize;
  *
  *   conflicts MANDATORY
  *     If your subopt is in a conflict with some other option, specify it.
- *     Accepts the .index values of the conflicting subopts and the last
- *     member of this list has to be LAST_CONFLICT.
+ *     Accepts the .index values of the conflicting subopt as .opt (e.g. OPT_D)
+ *     and .subopt (e.g. D_FILE). If .test_values is true, then the conflict
+ *     is raised only when the "remote" suboption .value is equal to
+ *     .invalid_value field and the "current" suboption has .value equal to
+ *     .at_value.
+ *     If .test_values is false, a conflict is raised when the suboption appears
+ *     on the CLI, no matter its value. The field .message contains an optional
+ *     explanatory string for the user. This string can't be translated here,
+ *     so it has to be enveloped with _() when printed.
+ *     The last member of this list has to be {LAST_CONFLICT}.
  *
  *   minval, maxval OPTIONAL
  *     These options are used for automatic range check and they have to be
@@ -133,7 +141,14 @@ struct opt_params {
 		bool		str_seen;
 		bool		convert;
 		bool		is_power_2;
-		int		conflicts[MAX_CONFLICTS];
+		struct subopt_conflict {
+			int		opt;
+			int		subopt;
+			bool		test_values;
+			long long	invalid_value;
+			long long	at_value;
+			const char	*message;
+		} 		conflicts [MAX_CONFLICTS];
 		long long	minval;
 		long long	maxval;
 		long long	defaultval;
@@ -153,8 +168,8 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = B_LOG,
-			  .conflicts = { B_SIZE,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_B, B_SIZE, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE_LOG,
 			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -162,8 +177,8 @@ struct opt_params {
 			{ .index = B_SIZE,
 			  .convert = true,
 			  .is_power_2 = true,
-			  .conflicts = { B_LOG,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_B, B_LOG, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE,
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -209,84 +224,84 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = D_AGCOUNT,
-			  .conflicts = { D_AGSIZE,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_D, D_AGSIZE, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = XFS_MAX_AGNUMBER,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_FILE,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = D_NAME,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SIZE,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = XFS_AG_MIN_BYTES,
 			  .maxval = LLONG_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SUNIT,
-			  .conflicts = { D_NOALIGN,
-					 D_SU,
-					 D_SW,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
+					 {OPT_D, D_SU, false, 0, 0},
+					 {OPT_D, D_SW, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SWIDTH,
-			  .conflicts = { D_NOALIGN,
-					 D_SU,
-					 D_SW,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
+					 {OPT_D, D_SU, false, 0, 0},
+					 {OPT_D, D_SW, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_AGSIZE,
-			  .conflicts = { D_AGCOUNT,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_D, D_AGCOUNT, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = XFS_AG_MIN_BYTES,
 			  .maxval = XFS_AG_MAX_BYTES,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SU,
-			  .conflicts = { D_NOALIGN,
-					 D_SUNIT,
-					 D_SWIDTH,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
+					 {OPT_D, D_SUNIT, false, 0, 0},
+					 {OPT_D, D_SWIDTH, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SW,
-			  .conflicts = { D_NOALIGN,
-					 D_SUNIT,
-					 D_SWIDTH,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
+					 {OPT_D, D_SUNIT, false, 0, 0},
+					 {OPT_D, D_SWIDTH, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SECTLOG,
-			  .conflicts = { D_SECTSIZE,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_D, D_SECTSIZE, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SECTSIZE,
-			  .conflicts = { D_SECTLOG,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_D, D_SECTLOG, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
@@ -294,29 +309,29 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_NOALIGN,
-			  .conflicts = { D_SU,
-					 D_SW,
-					 D_SUNIT,
-					 D_SWIDTH,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_D, D_SU, false, 0, 0},
+					 {OPT_D, D_SW, false, 0, 0},
+					 {OPT_D, D_SUNIT, false, 0, 0},
+					 {OPT_D, D_SWIDTH, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = D_RTINHERIT,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = D_PROJINHERIT,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_EXTSZINHERIT,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -348,57 +363,57 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = I_ALIGN,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = I_LOG,
-			  .conflicts = { I_PERBLOCK,
-					 I_SIZE,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_I, I_PERBLOCK, false, 0, 0},
+					 {OPT_I, I_SIZE, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = XFS_DINODE_MIN_LOG,
 			  .maxval = XFS_DINODE_MAX_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_MAXPCT,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 100,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_PERBLOCK,
-			  .conflicts = { I_LOG,
-					 I_SIZE,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_I, I_LOG, false, 0, 0},
+					 {OPT_I, I_SIZE, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_INODE_PERBLOCK,
 			  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_SIZE,
-			  .conflicts = { I_PERBLOCK,
-					 I_LOG,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_I, I_PERBLOCK, false, 0, 0},
+					 {OPT_I, I_LOG, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
 			  .minval = XFS_DINODE_MIN_SIZE,
 			  .maxval = XFS_DINODE_MAX_SIZE,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_ATTR,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 2,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_PROJID32BIT,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = I_SPINODES,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
@@ -438,64 +453,64 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = L_AGNUM,
-			  .conflicts = { L_DEV,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_L, L_DEV, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_INTERNAL,
-			  .conflicts = { L_FILE,
-					 L_DEV,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_L, L_FILE, false, 0, 0},
+					 {OPT_L, L_DEV, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = L_SIZE,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
 			  .maxval = XFS_MAX_LOG_BYTES,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_VERSION,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = 2,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SUNIT,
-			  .conflicts = { L_SU,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_L, L_SU, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SU,
-			  .conflicts = { L_SUNIT,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_L, L_SUNIT, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = BBTOB(1),
 			  .maxval = XLOG_MAX_RECORD_BSIZE,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_DEV,
-			  .conflicts = { L_AGNUM,
-					 L_INTERNAL,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_L, L_AGNUM, false, 0, 0},
+					 {OPT_L, L_INTERNAL, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SECTLOG,
-			  .conflicts = { L_SECTSIZE,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_L, L_SECTSIZE, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SECTSIZE,
-			  .conflicts = { L_SECTLOG,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_L, L_SECTLOG, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
@@ -503,20 +518,20 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_FILE,
-			  .conflicts = { L_INTERNAL,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_L, L_INTERNAL, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = L_NAME,
-			  .conflicts = { L_AGNUM,
-					 L_INTERNAL,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_L, L_AGNUM, false, 0, 0},
+					 {OPT_L, L_INTERNAL, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_LAZYSBCNTR,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
@@ -540,15 +555,15 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = N_LOG,
-			  .conflicts = { N_SIZE,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_N, N_SIZE, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_REC_DIRSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = N_SIZE,
-			  .conflicts = { N_LOG,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_N, N_LOG, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
 			  .minval = 1 << XFS_MIN_REC_DIRSIZE,
@@ -556,13 +571,13 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = N_VERSION,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 2,
 			  .maxval = 2,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = N_FTYPE,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
@@ -590,38 +605,38 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = R_EXTSIZE,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = XFS_MIN_RTEXTSIZE,
 			  .maxval = XFS_MAX_RTEXTSIZE,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_SIZE,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = 0,
 			  .maxval = LLONG_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_DEV,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_FILE,
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			},
 			{ .index = R_NAME,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_NOALIGN,
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			},
 		},
 	},
@@ -642,25 +657,25 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = S_LOG,
-			  .conflicts = { S_SIZE,
-					 S_SECTSIZE,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_S, S_SIZE, false, 0, 0},
+					 {OPT_S, S_SECTSIZE, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SECTLOG,
-			  .conflicts = { S_SIZE,
-					 S_SECTSIZE,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_S, S_SIZE, false, 0, 0},
+					 {OPT_S, S_SECTSIZE, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SIZE,
-			  .conflicts = { S_LOG,
-					 S_SECTLOG,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_S, S_LOG, false, 0, 0},
+					 {OPT_S, S_SECTLOG, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
@@ -668,9 +683,9 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SECTSIZE,
-			  .conflicts = { S_LOG,
-					 S_SECTLOG,
-					 LAST_CONFLICT },
+			  .conflicts = { {OPT_S, S_LOG, false, 0, 0},
+					 {OPT_S, S_SECTLOG, false, 0, 0},
+					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
@@ -698,29 +713,29 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = M_CRC,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = M_FINOBT,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = M_UUID,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = M_RMAPBT,
-			.conflicts = { LAST_CONFLICT },
+			.conflicts = { {LAST_CONFLICT} },
 			.minval = 0,
 			.maxval = 1,
 			.defaultval = 0,
 			},
 			{ .index = M_REFLINK,
-			  .conflicts = { LAST_CONFLICT },
+			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 0,
@@ -1330,14 +1345,14 @@ check_opt(
 
 	/* check for conflicts with the option */
 	for (i = 0; i < MAX_CONFLICTS; i++) {
-		int conflict_opt = sp->conflicts[i];
+		struct subopt_conflict conflict_opt = sp->conflicts[i];
 
-		if (conflict_opt == LAST_CONFLICT)
+		if (conflict_opt.opt == LAST_CONFLICT)
 			break;
-		if (opts->subopt_params[conflict_opt].seen ||
-		    opts->subopt_params[conflict_opt].str_seen)
+		if (opts->subopt_params[conflict_opt.subopt].seen ||
+		    opts->subopt_params[conflict_opt.subopt].str_seen)
 			conflict(opts->name, (char **)opts->subopts,
-				 conflict_opt, index);
+				 conflict_opt.subopt, index);
 	}
 }
 
-- 
2.8.1


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

* [PATCH 05/22] mkfs: add a check for conflicting values
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (3 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 17:58   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 06/22] mkfs: add cross-section conflict checks Jan Tulak
                   ` (20 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Add a check that reports a conflict only when subopts are mixed with specific values.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index b47cdae..3bb9f09 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1311,18 +1311,18 @@ illegal_option(
  */
 static void
 check_opt(
-	struct opt_params	*opts,
+	struct opt_params	*opt,
 	int			index,
 	bool			str_seen)
 {
-	struct subopt_param	*sp = &opts->subopt_params[index];
+	struct subopt_param	*sp = &opt->subopt_params[index];
 	int			i;
 
 	if (sp->index != index) {
 		fprintf(stderr,
 	("Developer screwed up option parsing (%d/%d)! Please report!\n"),
 			sp->index, index);
-		reqval(opts->name, (char **)opts->subopts, index);
+		reqval(opt->name, (char **)opt->subopts, index);
 	}
 
 	/*
@@ -1335,11 +1335,11 @@ check_opt(
 	 */
 	if (!str_seen) {
 		if (sp->seen)
-			respec(opts->name, (char **)opts->subopts, index);
+			respec(opt->name, (char **)opt->subopts, index);
 		sp->seen = true;
 	} else {
 		if (sp->str_seen)
-			respec(opts->name, (char **)opts->subopts, index);
+			respec(opt->name, (char **)opt->subopts, index);
 		sp->str_seen = true;
 	}
 
@@ -1349,10 +1349,44 @@ check_opt(
 
 		if (conflict_opt.opt == LAST_CONFLICT)
 			break;
-		if (opts->subopt_params[conflict_opt.subopt].seen ||
-		    opts->subopt_params[conflict_opt.subopt].str_seen)
-			conflict(opts->name, (char **)opts->subopts,
+		if (conflict_opt.test_values)
+			break;
+		if (opt->subopt_params[conflict_opt.subopt].seen ||
+		    opt->subopt_params[conflict_opt.subopt].str_seen) {
+			conflict(opt->name, (char **)opt->subopts,
 				 conflict_opt.subopt, index);
+		}
+	}
+}
+
+/*
+ * Check for conflict values between options.
+ */
+static void
+check_opt_value(
+	struct opt_params	*opt,
+	int			index,
+	long long 		value)
+{
+	struct subopt_param	*sp = &opt->subopt_params[index];
+	int			i;
+
+	/* check for conflicts with the option */
+	for (i = 0; i < MAX_CONFLICTS; i++) {
+		struct subopt_conflict conflict_opt = sp->conflicts[i];
+
+		if (conflict_opt.opt == LAST_CONFLICT)
+			break;
+		if (!conflict_opt.test_values)
+			break;
+		if ((opt->subopt_params[conflict_opt.subopt].seen ||
+				    opt->subopt_params[conflict_opt.subopt].str_seen) &&
+		    opt->subopt_params[conflict_opt.subopt].value
+				== conflict_opt.invalid_value &&
+		    value == conflict_opt.at_value) {
+			conflict(opt->name, (char **)opt->subopts,
+				 conflict_opt.subopt, index);
+		}
 	}
 }
 
@@ -1399,6 +1433,8 @@ getnum(
 			illegal_option(str, opts, index, NULL);
 	}
 
+	check_opt_value(opts, index, c);
+
 	/* Validity check the result. */
 	if (c < sp->minval)
 		illegal_option(str, opts, index, _("value is too small"));
-- 
2.8.1


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

* [PATCH 06/22] mkfs: add cross-section conflict checks
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (4 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 05/22] mkfs: add a check for conflicting values Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 21:18   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 07/22] mkfs: Move opts related #define to one place Jan Tulak
                   ` (19 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Checks are modified to work with cross-section conflicts (data, metada, log, ...).

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 3bb9f09..e46b55c 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -744,6 +744,9 @@ struct opt_params {
 	},
 };
 
+static void conflict_struct(struct opt_params 	*opt, struct subopt_param *subopt,
+			struct subopt_conflict 	*conflict);
+
 #define TERABYTES(count, blog)	((__uint64_t)(count) << (40 - (blog)))
 #define GIGABYTES(count, blog)	((__uint64_t)(count) << (30 - (blog)))
 #define MEGABYTES(count, blog)	((__uint64_t)(count) << (20 - (blog)))
@@ -1351,10 +1354,9 @@ check_opt(
 			break;
 		if (conflict_opt.test_values)
 			break;
-		if (opt->subopt_params[conflict_opt.subopt].seen ||
-		    opt->subopt_params[conflict_opt.subopt].str_seen) {
-			conflict(opt->name, (char **)opt->subopts,
-				 conflict_opt.subopt, index);
+		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
+		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].str_seen) {
+			conflict_struct(opt, sp, &conflict_opt);
 		}
 	}
 }
@@ -1379,13 +1381,12 @@ check_opt_value(
 			break;
 		if (!conflict_opt.test_values)
 			break;
-		if ((opt->subopt_params[conflict_opt.subopt].seen ||
-				    opt->subopt_params[conflict_opt.subopt].str_seen) &&
-		    opt->subopt_params[conflict_opt.subopt].value
+		if ((opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
+		     opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].str_seen) &&
+		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value
 				== conflict_opt.invalid_value &&
 		    value == conflict_opt.at_value) {
-			conflict(opt->name, (char **)opt->subopts,
-				 conflict_opt.subopt, index);
+			conflict_struct(opt, sp, &conflict_opt);
 		}
 	}
 }
@@ -3586,12 +3587,36 @@ conflict(
 	char		*tab[],
 	int		oldidx,
 	int		newidx)
+
 {
 	fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
 		opt, tab[oldidx], opt, tab[newidx]);
 	usage();
 }
 
+static void
+conflict_struct(
+	struct opt_params 	*opt,
+	struct subopt_param	*subopt,
+	struct subopt_conflict 	*conflict)
+{
+	if(conflict->message) {
+		fprintf(stderr, _("Cannot specify both -%c %s and -%c %s: %s\n"),
+			opt->name,
+			opt->subopts[subopt->index],
+			opts[conflict->opt].name,
+			opts[conflict->opt].subopts[conflict->subopt],
+			_(conflict->message));
+	} else {
+		fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
+			opt->name,
+			opt->subopts[subopt->index],
+			opts[conflict->opt].name,
+			opts[conflict->opt].subopts[conflict->subopt]);
+	}
+	usage();
+}
+
 
 static void
 illegal(
-- 
2.8.1


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

* [PATCH 07/22] mkfs: Move opts related #define to one place
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (5 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 06/22] mkfs: add cross-section conflict checks Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 21:19   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 08/22] mkfs: move conflicts into the table Jan Tulak
                   ` (18 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Takes all the "#define M_CRC x" from struct opt_params declaration and moves
them into a single place before the struct. This is because we need to
cross-link conflicts and we can't link -l version to -m crc if M_CRC is defined
after the conflict section.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index e46b55c..2122d1c 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -48,6 +48,80 @@ unsigned int		sectorsize;
 #define MAX_CONFLICTS	8
 #define LAST_CONFLICT	(-1)
 
+#define OPT_B		0
+#define B_LOG		0
+#define B_SIZE		1
+
+#define OPT_D		1
+#define D_AGCOUNT	0
+#define D_FILE		1
+#define D_NAME		2
+#define D_SIZE		3
+#define D_SUNIT 	4
+#define D_SWIDTH	5
+#define D_AGSIZE	6
+#define D_SU		7
+#define D_SW		8
+#define D_SECTLOG	9
+#define D_SECTSIZE	10
+#define D_NOALIGN	11
+#define D_RTINHERIT	12
+#define D_PROJINHERIT	13
+#define D_EXTSZINHERIT	14
+
+
+#define OPT_I		2
+#define I_ALIGN 	0
+#define I_LOG		1
+#define I_MAXPCT	2
+#define I_PERBLOCK	3
+#define I_SIZE		4
+#define I_ATTR		5
+#define I_PROJID32BIT	6
+#define I_SPINODES	7
+
+#define OPT_L		3
+#define L_AGNUM 	0
+#define L_INTERNAL	1
+#define L_SIZE		2
+#define L_VERSION	3
+#define L_SUNIT 	4
+#define L_SU		5
+#define L_DEV		6
+#define L_SECTLOG	7
+#define L_SECTSIZE	8
+#define L_FILE		9
+#define L_NAME		10
+#define L_LAZYSBCNTR	11
+
+
+#define OPT_N		4
+#define N_LOG		0
+#define N_SIZE		1
+#define N_VERSION	2
+#define N_FTYPE 	3
+
+#define OPT_R		5
+#define R_EXTSIZE	0
+#define R_SIZE		1
+#define R_DEV		2
+#define R_FILE		3
+#define R_NAME		4
+#define R_NOALIGN	5
+
+#define OPT_S		6
+#define S_LOG		0
+#define S_SECTLOG	1
+#define S_SIZE		2
+#define S_SECTSIZE	3
+
+#define OPT_M		7
+#define M_CRC		0
+#define M_FINOBT	1
+#define M_UUID		2
+#define M_RMAPBT	3
+#define M_REFLINK	4
+
 /*
  * Table for parsing mkfs parameters.
  *
@@ -155,14 +229,11 @@ struct opt_params {
 		long long	value;
 	}		subopt_params[MAX_SUBOPTS];
 } opts[MAX_OPTS] = {
-#define OPT_B	0
 	{
 		.index = OPT_B,
 		.name = 'b',
 		.subopts = {
-#define	B_LOG		0
 			"log",
-#define	B_SIZE		1
 			"size",
 			NULL
 		},
@@ -185,40 +256,24 @@ struct opt_params {
 			},
 		},
 	},
-#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
 		},
@@ -338,26 +393,17 @@ struct opt_params {
 			},
 		},
 	},
-#define OPT_I	2
 	{
 		.index = OPT_I,
 		.name = 'i',
 		.subopts = {
-#define	I_ALIGN		0
 			"align",
-#define	I_LOG		1
 			"log",
-#define	I_MAXPCT	2
 			"maxpct",
-#define	I_PERBLOCK	3
 			"perblock",
-#define	I_SIZE		4
 			"size",
-#define	I_ATTR		5
 			"attr",
-#define	I_PROJID32BIT	6
 			"projid32bit",
-#define I_SPINODES	7
 			"sparse",
 			NULL
 		},
@@ -420,34 +466,21 @@ struct opt_params {
 			},
 		},
 	},
-#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
 		},
@@ -538,18 +571,13 @@ struct opt_params {
 			},
 		},
 	},
-#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,
 		},
@@ -584,22 +612,15 @@ struct opt_params {
 			},
 		},
 	},
-#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
 		},
@@ -640,18 +661,13 @@ struct opt_params {
 			},
 		},
 	},
-#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
 		},
@@ -694,20 +710,14 @@ struct opt_params {
 			},
 		},
 	},
-#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
 		},
-- 
2.8.1


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

* [PATCH 08/22] mkfs: move conflicts into the table
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (6 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 07/22] mkfs: Move opts related #define to one place Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 21:20   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure Jan Tulak
                   ` (17 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Fill the table with conflicts data and remove now-duplicate code for their
detection from other parts of mkfs.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 2122d1c..30618ff 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -45,7 +45,7 @@ unsigned int		sectorsize;
 #define MAX_OPTS	16
 #define MAX_SUBOPTS	16
 #define SUBOPT_NEEDS_VAL	(-1LL)
-#define MAX_CONFLICTS	8
+#define MAX_CONFLICTS	32
 #define LAST_CONFLICT	(-1)
 
 #define OPT_B		0
@@ -409,7 +409,9 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = I_ALIGN,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
+		"Inodes always aligned for CRC enabled filesytems."},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
@@ -447,19 +449,26 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_ATTR,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_CRC, true, 1, 1,
+		"V2 attribute format always enabled on CRC enabled filesytems."},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 2,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_PROJID32BIT,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
+		"32 bit Project IDs always enabled on CRC enabled filesytems."},
+					 {LAST_CONFLICT} },
+
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = I_SPINODES,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
+		"Sparse inodes not supported without CRC support."},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
@@ -508,7 +517,9 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_VERSION,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_CRC, true, 1, 1,
+				"V2 logs are required for CRC enabled filesystems."},
+					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = 2,
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -564,7 +575,9 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_LAZYSBCNTR,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
+		"Lazy superblock counted always enabled for CRC enabled filesytems."},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
@@ -605,7 +618,9 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = N_FTYPE,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = {  {OPT_M, M_CRC, true, 1, 0,
+		"Cannot disable ftype with crcs enabled."},
+					  {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
@@ -640,7 +655,9 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_DEV,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_RMAPBT, false, 0, 0,
+		"rmapbt not supported without CRC support."},
+					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_FILE,
@@ -650,7 +667,9 @@ struct opt_params {
 			  .conflicts = { {LAST_CONFLICT} },
 			},
 			{ .index = R_NAME,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_RMAPBT, false, 0, 0,
+		"rmapbt not supported without CRC support."},
+					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_NOALIGN,
@@ -723,13 +742,35 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = M_CRC,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_L, L_VERSION, true, 1, 1,
+		"V2 logs are required for CRC enabled filesystems."},
+					 {OPT_I, I_ALIGN, true, 0, 1,
+		"Inodes always aligned for CRC enabled filesytems."},
+					 {OPT_I, I_PROJID32BIT, true, 0, 1,
+		"32 bit Project IDs always enabled on CRC enabled filesytems."},
+					 {OPT_I, I_ATTR, true, 1, 1,
+		"V2 attribute format always enabled on CRC enabled filesytems."},
+					 {OPT_L, L_LAZYSBCNTR, true, 0, 1,
+		"Lazy superblock counted always enabled for CRC enabled filesytems."},
+					 {OPT_M, M_FINOBT, true, 1, 0,
+		"Finobt not supported without CRC support."},
+					 {OPT_M, M_RMAPBT, true, 1, 0,
+		"rmapbt not supported without CRC support."},
+					 {OPT_M, M_REFLINK, true, 1, 0,
+		"reflink not supported without CRC support."},
+					 {OPT_I, I_SPINODES, true, 1, 0,
+		"Sparse inodes not supported without CRC support."},
+					 {OPT_N, N_FTYPE, true, 0, 1,
+		"Cannot disable ftype with crcs enabled."},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = M_FINOBT,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
+		"Finobt not supported without CRC support\n"},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
@@ -739,13 +780,21 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = M_RMAPBT,
-			.conflicts = { {LAST_CONFLICT} },
+			.conflicts = { {OPT_M, M_CRC, true, 0, 1,
+		"rmapbt not supported without CRC support."},
+					{OPT_R, R_NAME, false, 0, 0,
+		"rmapbt not supported with realtime devices."},
+					{OPT_R, R_DEV, false, 0, 0,
+		"rmapbt not supported with realtime devices."},
+				       {LAST_CONFLICT} },
 			.minval = 0,
 			.maxval = 1,
 			.defaultval = 0,
 			},
 			{ .index = M_REFLINK,
-			  .conflicts = { {LAST_CONFLICT} },
+			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
+		"reflink not supported without CRC support."},
+					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 0,
@@ -2183,11 +2232,16 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 			XFS_MIN_CRC_BLOCKSIZE);
 		usage();
 	}
+
+	/*
+	 * If user explicitly stated -m crc=1 -n ftype=0, an error was already
+	 * issued. But if -n ftype=0 was stated alone, then it is a conflict
+	 * with a default value for crc enabled and has to be detected here.
+	 */
 	if (sb_feat.crcs_enabled && !sb_feat.dirftype) {
 		fprintf(stderr, _("cannot disable ftype with crcs enabled\n"));
 		usage();
 	}
-
 	if (!slflag && !ssflag) {
 		sectorlog = XFS_MIN_SECTORSIZE_LOG;
 		sectorsize = XFS_MIN_SECTORSIZE;
@@ -2293,42 +2347,6 @@ _("Minimum inode size for CRCs is %d bytes\n"),
 				1 << XFS_DINODE_DFL_CRC_LOG);
 			usage();
 		}
-
-		/* inodes always aligned */
-		if (!sb_feat.inode_align) {
-			fprintf(stderr,
-_("Inodes always aligned for CRC enabled filesytems\n"));
-			usage();
-		}
-
-		/* lazy sb counters always on */
-		if (!sb_feat.lazy_sb_counters) {
-			fprintf(stderr,
-_("Lazy superblock counted always enabled for CRC enabled filesytems\n"));
-			usage();
-		}
-
-		/* version 2 logs always on */
-		if (sb_feat.log_version != 2) {
-			fprintf(stderr,
-_("V2 logs always enabled for CRC enabled filesytems\n"));
-			usage();
-		}
-
-		/* attr2 always on */
-		if (sb_feat.attr_version != 2) {
-			fprintf(stderr,
-_("V2 attribute format always enabled on CRC enabled filesytems\n"));
-			usage();
-		}
-
-		/* 32 bit project quota always on */
-		/* attr2 always on */
-		if (sb_feat.projid16bit) {
-			fprintf(stderr,
-_("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
-			usage();
-		}
 	} else {
 		/*
 		 * The kernel doesn't currently support crc=0,finobt=1
@@ -2336,46 +2354,16 @@ _("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
 		 * explicitly turned finobt on, then silently turn it off to
 		 * avoid an unnecessary warning.
 		 * If the user explicitly tried to use crc=0,finobt=1,
-		 * then issue an error.
+		 * the error was already issued during args parsing.
 		 * The same is also for sparse inodes.
 		 */
-		if (sb_feat.finobt && opts[OPT_M].subopt_params[M_FINOBT].seen) {
-			fprintf(stderr,
-_("finobt not supported without CRC support\n"));
-			usage();
-		}
 		sb_feat.finobt = 0;
-
-		if (sb_feat.spinodes) {
-			fprintf(stderr,
-_("sparse inodes not supported without CRC support\n"));
-			usage();
-		}
 		sb_feat.spinodes = 0;
 
-		if (sb_feat.rmapbt) {
-			fprintf(stderr,
-_("rmapbt not supported without CRC support\n"));
-			usage();
-		}
 		sb_feat.rmapbt = false;
-
-		if (sb_feat.reflink) {
-			fprintf(stderr,
-_("reflink not supported without CRC support\n"));
-			usage();
-		}
 		sb_feat.reflink = false;
 	}
 
-
-	if (sb_feat.rmapbt && xi.rtname) {
-		fprintf(stderr,
-_("rmapbt not supported with realtime devices\n"));
-		usage();
-		sb_feat.rmapbt = false;
-	}
-
 	if (nsflag || nlflag) {
 		if (dirblocksize < blocksize ||
 					dirblocksize > XFS_MAX_BLOCKSIZE) {
-- 
2.8.1


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

* [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (7 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 08/22] mkfs: move conflicts into the table Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 17:08   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 10/22] mkfs: change when to mark an option as seen Jan Tulak
                   ` (16 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Bring the conflicts detection up to date with conflicts declaration.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 30618ff..d11fad6 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1372,7 +1372,7 @@ illegal_option(
  * Check for conflicts and option respecification.
  */
 static void
-check_opt(
+check_subopt_conflicts(
 	struct opt_params	*opt,
 	int			index,
 	bool			str_seen)
@@ -1424,7 +1424,7 @@ check_opt(
  * Check for conflict values between options.
  */
 static void
-check_opt_value(
+check_subopt_value(
 	struct opt_params	*opt,
 	int			index,
 	long long 		value)
@@ -1450,6 +1450,32 @@ check_opt_value(
 	}
 }
 
+/**
+ * Go through entire opt_params table and check every option for valid values
+ * and for conflicts.
+ */
+static void
+check_opt(
+	struct opt_params *opts,
+	int opti)
+{
+	int index;
+	struct opt_params *opt = &opts[opti];
+	for (index = 0; index < MAX_SUBOPTS; index++) {
+		struct subopt_param *sp = &opt->subopt_params[index];
+		check_subopt_conflicts(opt, index, false);
+		check_subopt_value(opt, index, sp->value);
+	}
+}
+static void
+check_all_opts(struct opt_params *opts)
+{
+	int opti;
+	for (opti = 0; opti < MAX_OPTS; opti++) {
+		check_opt(opts, opti);
+	}
+}
+
 static long long
 getnum(
 	const char		*str,
@@ -1459,7 +1485,6 @@ getnum(
 	struct subopt_param	*sp = &opts->subopt_params[index];
 	long long		c;
 
-	check_opt(opts, index, false);
 	/* empty strings might just return a default value */
 	if (!str || *str == '\0') {
 		if (sp->defaultval == SUBOPT_NEEDS_VAL)
@@ -1493,8 +1518,6 @@ getnum(
 			illegal_option(str, opts, index, NULL);
 	}
 
-	check_opt_value(opts, index, c);
-
 	/* Validity check the result. */
 	if (c < sp->minval)
 		illegal_option(str, opts, index, _("value is too small"));
@@ -1517,7 +1540,7 @@ getstr(
 	struct opt_params	*opts,
 	int			index)
 {
-	check_opt(opts, index, true);
+	check_subopt(opts, index, true);
 
 	/* empty strings for string options are not valid */
 	if (!str || *str == '\0')
@@ -2213,6 +2236,8 @@ main(
 	} else
 		dfile = xi.dname;
 
+	check_all_opts(opts);
+
 	/*
 	 * Blocksize and sectorsize first, other things depend on them
 	 * For RAID4/5/6 we want to align sector size and block size,
-- 
2.8.1


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

* [PATCH 10/22] mkfs: change when to mark an option as seen
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (8 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 21:20   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 11/22] mkfs: add test_default_value into conflict struct Jan Tulak
                   ` (15 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Make the check for seen option more useful for new conflict detection
by moving it's logic to new place - we are no longer doing the
respecification as before.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index d11fad6..b3625ed 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -152,10 +152,6 @@ unsigned int		sectorsize;
  *     Do not set this flag when definning a subopt. It is used to remeber that
  *     this subopt was already seen, for example for conflicts detection.
  *
- *   str_seen INTERNAL
- *     Do not set. It is used internally for respecification, when some options
- *     has to be parsed twice - at first as a string, then later as a number.
- *
  *   convert OPTIONAL
  *     A flag signalling whether the user-given value can use suffixes.
  *     If you want to allow the use of user-friendly values like 13k, 42G,
@@ -212,7 +208,6 @@ struct opt_params {
 	struct subopt_param {
 		int		index;
 		bool		seen;
-		bool		str_seen;
 		bool		convert;
 		bool		is_power_2;
 		struct subopt_conflict {
@@ -1375,7 +1370,7 @@ static void
 check_subopt_conflicts(
 	struct opt_params	*opt,
 	int			index,
-	bool			str_seen)
+	bool			seen)
 {
 	struct subopt_param	*sp = &opt->subopt_params[index];
 	int			i;
@@ -1387,23 +1382,6 @@ check_subopt_conflicts(
 		reqval(opt->name, (char **)opt->subopts, index);
 	}
 
-	/*
-	 * Check for respecification of the option. This is more complex than it
-	 * seems because some options are parsed twice - once as a string during
-	 * input parsing, then later the string is passed to getnum for
-	 * conversion into a number and bounds checking. Hence the two variables
-	 * used to track the different uses based on the @str parameter passed
-	 * to us.
-	 */
-	if (!str_seen) {
-		if (sp->seen)
-			respec(opt->name, (char **)opt->subopts, index);
-		sp->seen = true;
-	} else {
-		if (sp->str_seen)
-			respec(opt->name, (char **)opt->subopts, index);
-		sp->str_seen = true;
-	}
 
 	/* check for conflicts with the option */
 	for (i = 0; i < MAX_CONFLICTS; i++) {
@@ -1413,8 +1391,7 @@ check_subopt_conflicts(
 			break;
 		if (conflict_opt.test_values)
 			break;
-		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
-		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].str_seen) {
+		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen) {
 			conflict_struct(opt, sp, &conflict_opt);
 		}
 	}
@@ -1440,8 +1417,7 @@ check_subopt_value(
 			break;
 		if (!conflict_opt.test_values)
 			break;
-		if ((opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
-		     opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].str_seen) &&
+		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen &&
 		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value
 				== conflict_opt.invalid_value &&
 		    value == conflict_opt.at_value) {
@@ -1462,7 +1438,11 @@ check_opt(
 	int index;
 	struct opt_params *opt = &opts[opti];
 	for (index = 0; index < MAX_SUBOPTS; index++) {
+		if (opt->subopts[index] == NULL)
+			break;
 		struct subopt_param *sp = &opt->subopt_params[index];
+		if (!sp->seen)
+			continue;
 		check_subopt_conflicts(opt, index, false);
 		check_subopt_value(opt, index, sp->value);
 	}
@@ -1489,9 +1469,12 @@ getnum(
 	if (!str || *str == '\0') {
 		if (sp->defaultval == SUBOPT_NEEDS_VAL)
 			reqval(opts->name, (char **)opts->subopts, index);
+		sp->seen = true;
 		return sp->defaultval;
 	}
 
+	sp->seen = true;
+
 	if (sp->minval == 0 && sp->maxval == 0) {
 		fprintf(stderr,
 			_("Option -%c %s has undefined minval/maxval."
@@ -1540,11 +1523,10 @@ getstr(
 	struct opt_params	*opts,
 	int			index)
 {
-	check_subopt(opts, index, true);
-
 	/* empty strings for string options are not valid */
 	if (!str || *str == '\0')
 		reqval(opts->name, (char **)opts->subopts, index);
+	opts->subopt_params[index].seen = true;
 	return str;
 }
 
-- 
2.8.1


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

* [PATCH 11/22] mkfs: add test_default_value into conflict struct
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (9 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 10/22] mkfs: change when to mark an option as seen Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 21:21   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 12/22] mkfs: expand conflicts declarations to named declaration Jan Tulak
                   ` (14 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Add a flag signalising that a subopt can be conflicting with
default value of another option.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index b3625ed..58cc24a 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -172,6 +172,8 @@ unsigned int		sectorsize;
  *     on the CLI, no matter its value. The field .message contains an optional
  *     explanatory string for the user. This string can't be translated here,
  *     so it has to be enveloped with _() when printed.
+ *     The .test_default_value is used when .test_values is true, and extends
+ *     the check also for default values.
  *     The last member of this list has to be {LAST_CONFLICT}.
  *
  *   minval, maxval OPTIONAL
@@ -214,6 +216,7 @@ struct opt_params {
 			int		opt;
 			int		subopt;
 			bool		test_values;
+			bool		test_default_value;
 			long long	invalid_value;
 			long long	at_value;
 			const char	*message;
@@ -234,7 +237,7 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = B_LOG,
-			  .conflicts = { {OPT_B, B_SIZE, false, 0, 0},
+			  .conflicts = { {OPT_B, B_SIZE, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE_LOG,
 			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
@@ -243,7 +246,7 @@ struct opt_params {
 			{ .index = B_SIZE,
 			  .convert = true,
 			  .is_power_2 = true,
-			  .conflicts = { {OPT_B, B_LOG, false, 0, 0},
+			  .conflicts = { {OPT_B, B_LOG, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE,
@@ -274,7 +277,7 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = D_AGCOUNT,
-			  .conflicts = { {OPT_D, D_AGSIZE, false, 0, 0},
+			  .conflicts = { {OPT_D, D_AGSIZE, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = XFS_MAX_AGNUMBER,
@@ -298,25 +301,25 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SUNIT,
-			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
-					 {OPT_D, D_SU, false, 0, 0},
-					 {OPT_D, D_SW, false, 0, 0},
+			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
+					 {OPT_D, D_SU, false, false, 0, 0},
+					 {OPT_D, D_SW, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SWIDTH,
-			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
-					 {OPT_D, D_SU, false, 0, 0},
-					 {OPT_D, D_SW, false, 0, 0},
+			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
+					 {OPT_D, D_SU, false, false, 0, 0},
+					 {OPT_D, D_SW, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_AGSIZE,
-			  .conflicts = { {OPT_D, D_AGCOUNT, false, 0, 0},
+			  .conflicts = { {OPT_D, D_AGCOUNT, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = XFS_AG_MIN_BYTES,
@@ -324,9 +327,9 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SU,
-			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
-					 {OPT_D, D_SUNIT, false, 0, 0},
-					 {OPT_D, D_SWIDTH, false, 0, 0},
+			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
+					 {OPT_D, D_SUNIT, false, false, 0, 0},
+					 {OPT_D, D_SWIDTH, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = 0,
@@ -334,23 +337,23 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SW,
-			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
-					 {OPT_D, D_SUNIT, false, 0, 0},
-					 {OPT_D, D_SWIDTH, false, 0, 0},
+			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
+					 {OPT_D, D_SUNIT, false, false, 0, 0},
+					 {OPT_D, D_SWIDTH, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SECTLOG,
-			  .conflicts = { {OPT_D, D_SECTSIZE, false, 0, 0},
+			  .conflicts = { {OPT_D, D_SECTSIZE, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SECTSIZE,
-			  .conflicts = { {OPT_D, D_SECTLOG, false, 0, 0},
+			  .conflicts = { {OPT_D, D_SECTLOG, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -359,10 +362,10 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_NOALIGN,
-			  .conflicts = { {OPT_D, D_SU, false, 0, 0},
-					 {OPT_D, D_SW, false, 0, 0},
-					 {OPT_D, D_SUNIT, false, 0, 0},
-					 {OPT_D, D_SWIDTH, false, 0, 0},
+			  .conflicts = { {OPT_D, D_SU, false, false, 0, 0},
+					 {OPT_D, D_SW, false, false, 0, 0},
+					 {OPT_D, D_SUNIT, false, false, 0, 0},
+					 {OPT_D, D_SWIDTH, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
@@ -404,7 +407,7 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = I_ALIGN,
-			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
+			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
 		"Inodes always aligned for CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -412,8 +415,8 @@ struct opt_params {
 			  .defaultval = 1,
 			},
 			{ .index = I_LOG,
-			  .conflicts = { {OPT_I, I_PERBLOCK, false, 0, 0},
-					 {OPT_I, I_SIZE, false, 0, 0},
+			  .conflicts = { {OPT_I, I_PERBLOCK, false, false, 0, 0},
+					 {OPT_I, I_SIZE, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = XFS_DINODE_MIN_LOG,
 			  .maxval = XFS_DINODE_MAX_LOG,
@@ -426,8 +429,8 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_PERBLOCK,
-			  .conflicts = { {OPT_I, I_LOG, false, 0, 0},
-					 {OPT_I, I_SIZE, false, 0, 0},
+			  .conflicts = { {OPT_I, I_LOG, false, false, 0, 0},
+					 {OPT_I, I_SIZE, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_INODE_PERBLOCK,
@@ -435,8 +438,8 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_SIZE,
-			  .conflicts = { {OPT_I, I_PERBLOCK, false, 0, 0},
-					 {OPT_I, I_LOG, false, 0, 0},
+			  .conflicts = { {OPT_I, I_PERBLOCK, false, false, 0, 0},
+					 {OPT_I, I_LOG, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
 			  .minval = XFS_DINODE_MIN_SIZE,
@@ -444,7 +447,7 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_ATTR,
-			  .conflicts = { {OPT_M, M_CRC, true, 1, 1,
+			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 1,
 		"V2 attribute format always enabled on CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -452,7 +455,7 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_PROJID32BIT,
-			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
+			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
 		"32 bit Project IDs always enabled on CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
 
@@ -461,7 +464,7 @@ struct opt_params {
 			  .defaultval = 1,
 			},
 			{ .index = I_SPINODES,
-			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
+			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
 		"Sparse inodes not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -490,15 +493,15 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = L_AGNUM,
-			  .conflicts = { {OPT_L, L_DEV, false, 0, 0},
+			  .conflicts = { {OPT_L, L_DEV, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_INTERNAL,
-			  .conflicts = { {OPT_L, L_FILE, false, 0, 0},
-					 {OPT_L, L_DEV, false, 0, 0},
+			  .conflicts = { {OPT_L, L_FILE, false, false, 0, 0},
+					 {OPT_L, L_DEV, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
@@ -512,7 +515,7 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_VERSION,
-			  .conflicts = { {OPT_M, M_CRC, true, 1, 1,
+			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 1,
 				"V2 logs are required for CRC enabled filesystems."},
 					 {LAST_CONFLICT} },
 			  .minval = 1,
@@ -520,14 +523,14 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SUNIT,
-			  .conflicts = { {OPT_L, L_SU, false, 0, 0},
+			  .conflicts = { {OPT_L, L_SU, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SU,
-			  .conflicts = { {OPT_L, L_SUNIT, false, 0, 0},
+			  .conflicts = { {OPT_L, L_SUNIT, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = BBTOB(1),
@@ -535,20 +538,20 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_DEV,
-			  .conflicts = { {OPT_L, L_AGNUM, false, 0, 0},
-					 {OPT_L, L_INTERNAL, false, 0, 0},
+			  .conflicts = { {OPT_L, L_AGNUM, false, false, 0, 0},
+					 {OPT_L, L_INTERNAL, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SECTLOG,
-			  .conflicts = { {OPT_L, L_SECTSIZE, false, 0, 0},
+			  .conflicts = { {OPT_L, L_SECTSIZE, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SECTSIZE,
-			  .conflicts = { {OPT_L, L_SECTLOG, false, 0, 0},
+			  .conflicts = { {OPT_L, L_SECTLOG, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -557,20 +560,20 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_FILE,
-			  .conflicts = { {OPT_L, L_INTERNAL, false, 0, 0},
+			  .conflicts = { {OPT_L, L_INTERNAL, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = L_NAME,
-			  .conflicts = { {OPT_L, L_AGNUM, false, 0, 0},
-					 {OPT_L, L_INTERNAL, false, 0, 0},
+			  .conflicts = { {OPT_L, L_AGNUM, false, false, 0, 0},
+					 {OPT_L, L_INTERNAL, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_LAZYSBCNTR,
-			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
+			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
 		"Lazy superblock counted always enabled for CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -591,14 +594,14 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = N_LOG,
-			  .conflicts = { {OPT_N, N_SIZE, false, 0, 0},
+			  .conflicts = { {OPT_N, N_SIZE, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_REC_DIRSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = N_SIZE,
-			  .conflicts = { {OPT_N, N_LOG, false, 0, 0},
+			  .conflicts = { {OPT_N, N_LOG, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -613,7 +616,7 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = N_FTYPE,
-			  .conflicts = {  {OPT_M, M_CRC, true, 1, 0,
+			  .conflicts = {  {OPT_M, M_CRC, true, true, 1, 0,
 		"Cannot disable ftype with crcs enabled."},
 					  {LAST_CONFLICT} },
 			  .minval = 0,
@@ -650,7 +653,7 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_DEV,
-			  .conflicts = { {OPT_M, M_RMAPBT, false, 0, 0,
+			  .conflicts = { {OPT_M, M_RMAPBT, false, true, 0, 0,
 		"rmapbt not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -662,7 +665,7 @@ struct opt_params {
 			  .conflicts = { {LAST_CONFLICT} },
 			},
 			{ .index = R_NAME,
-			  .conflicts = { {OPT_M, M_RMAPBT, false, 0, 0,
+			  .conflicts = { {OPT_M, M_RMAPBT, false, true, 0, 0,
 		"rmapbt not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -687,24 +690,24 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = S_LOG,
-			  .conflicts = { {OPT_S, S_SIZE, false, 0, 0},
-					 {OPT_S, S_SECTSIZE, false, 0, 0},
+			  .conflicts = { {OPT_S, S_SIZE, false, false, 0, 0},
+					 {OPT_S, S_SECTSIZE, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SECTLOG,
-			  .conflicts = { {OPT_S, S_SIZE, false, 0, 0},
-					 {OPT_S, S_SECTSIZE, false, 0, 0},
+			  .conflicts = { {OPT_S, S_SIZE, false, false, 0, 0},
+					 {OPT_S, S_SECTSIZE, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SIZE,
-			  .conflicts = { {OPT_S, S_LOG, false, 0, 0},
-					 {OPT_S, S_SECTLOG, false, 0, 0},
+			  .conflicts = { {OPT_S, S_LOG, false, false, 0, 0},
+					 {OPT_S, S_SECTLOG, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -713,8 +716,8 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SECTSIZE,
-			  .conflicts = { {OPT_S, S_LOG, false, 0, 0},
-					 {OPT_S, S_SECTLOG, false, 0, 0},
+			  .conflicts = { {OPT_S, S_LOG, false, false, 0, 0},
+					 {OPT_S, S_SECTLOG, false, false, 0, 0},
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -737,25 +740,25 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = M_CRC,
-			  .conflicts = { {OPT_L, L_VERSION, true, 1, 1,
+			  .conflicts = { {OPT_L, L_VERSION, true, true, 1, 1,
 		"V2 logs are required for CRC enabled filesystems."},
-					 {OPT_I, I_ALIGN, true, 0, 1,
+					 {OPT_I, I_ALIGN, false, true, 0, 1,
 		"Inodes always aligned for CRC enabled filesytems."},
-					 {OPT_I, I_PROJID32BIT, true, 0, 1,
+					 {OPT_I, I_PROJID32BIT, true, true, 0, 1,
 		"32 bit Project IDs always enabled on CRC enabled filesytems."},
-					 {OPT_I, I_ATTR, true, 1, 1,
+					 {OPT_I, I_ATTR, true, true, 1, 1,
 		"V2 attribute format always enabled on CRC enabled filesytems."},
-					 {OPT_L, L_LAZYSBCNTR, true, 0, 1,
+					 {OPT_L, L_LAZYSBCNTR, true, true, 0, 1,
 		"Lazy superblock counted always enabled for CRC enabled filesytems."},
-					 {OPT_M, M_FINOBT, true, 1, 0,
+					 {OPT_M, M_FINOBT, true, true, 1, 0,
 		"Finobt not supported without CRC support."},
-					 {OPT_M, M_RMAPBT, true, 1, 0,
+					 {OPT_M, M_RMAPBT, true, true, 1, 0,
 		"rmapbt not supported without CRC support."},
-					 {OPT_M, M_REFLINK, true, 1, 0,
+					 {OPT_M, M_REFLINK, true, true, 1, 0,
 		"reflink not supported without CRC support."},
-					 {OPT_I, I_SPINODES, true, 1, 0,
+					 {OPT_I, I_SPINODES, true, true, 1, 0,
 		"Sparse inodes not supported without CRC support."},
-					 {OPT_N, N_FTYPE, true, 0, 1,
+					 {OPT_N, N_FTYPE, true, true, 0, 1,
 		"Cannot disable ftype with crcs enabled."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -763,8 +766,8 @@ struct opt_params {
 			  .defaultval = 1,
 			},
 			{ .index = M_FINOBT,
-			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
-		"Finobt not supported without CRC support\n"},
+			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
+		"Finobt not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
@@ -775,11 +778,11 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = M_RMAPBT,
-			.conflicts = { {OPT_M, M_CRC, true, 0, 1,
+			.conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
 		"rmapbt not supported without CRC support."},
-					{OPT_R, R_NAME, false, 0, 0,
+					{OPT_R, R_NAME, false, true, 0, 0,
 		"rmapbt not supported with realtime devices."},
-					{OPT_R, R_DEV, false, 0, 0,
+					{OPT_R, R_DEV, false, true, 0, 0,
 		"rmapbt not supported with realtime devices."},
 				       {LAST_CONFLICT} },
 			.minval = 0,
@@ -787,7 +790,7 @@ struct opt_params {
 			.defaultval = 0,
 			},
 			{ .index = M_REFLINK,
-			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
+			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
 		"reflink not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -1417,7 +1420,8 @@ check_subopt_value(
 			break;
 		if (!conflict_opt.test_values)
 			break;
-		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen &&
+		if ( (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
+		      conflict_opt.test_default_value) &&
 		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value
 				== conflict_opt.invalid_value &&
 		    value == conflict_opt.at_value) {
-- 
2.8.1


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

* [PATCH 12/22] mkfs: expand conflicts declarations to named declaration
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (10 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 11/22] mkfs: add test_default_value into conflict struct Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 17:21   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 13/22] mkfs: remove zeroed items from conflicts declaration Jan Tulak
                   ` (13 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

As we are adding more fields, change from positional to named declarations.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 58cc24a..b0e5d75 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -220,7 +220,7 @@ struct opt_params {
 			long long	invalid_value;
 			long long	at_value;
 			const char	*message;
-		} 		conflicts [MAX_CONFLICTS];
+		}		conflicts [MAX_CONFLICTS];
 		long long	minval;
 		long long	maxval;
 		long long	defaultval;
@@ -237,7 +237,13 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = B_LOG,
-			  .conflicts = { {OPT_B, B_SIZE, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_B,
+					  .subopt = B_SIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE_LOG,
 			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
@@ -246,7 +252,13 @@ struct opt_params {
 			{ .index = B_SIZE,
 			  .convert = true,
 			  .is_power_2 = true,
-			  .conflicts = { {OPT_B, B_LOG, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_B,
+					  .subopt = B_LOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE,
@@ -277,7 +289,13 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = D_AGCOUNT,
-			  .conflicts = { {OPT_D, D_AGSIZE, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_D,
+					  .subopt = D_AGSIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = XFS_MAX_AGNUMBER,
@@ -301,25 +319,67 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SUNIT,
-			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
-					 {OPT_D, D_SU, false, false, 0, 0},
-					 {OPT_D, D_SW, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_D,
+					  .subopt = D_NOALIGN,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SU,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SW,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SWIDTH,
-			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
-					 {OPT_D, D_SU, false, false, 0, 0},
-					 {OPT_D, D_SW, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_D,
+					  .subopt = D_NOALIGN,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SU,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SW,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_AGSIZE,
-			  .conflicts = { {OPT_D, D_AGCOUNT, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_D,
+					  .subopt = D_AGCOUNT,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = XFS_AG_MIN_BYTES,
@@ -327,9 +387,27 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SU,
-			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
-					 {OPT_D, D_SUNIT, false, false, 0, 0},
-					 {OPT_D, D_SWIDTH, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_D,
+					  .subopt = D_NOALIGN,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SUNIT,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SWIDTH,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = 0,
@@ -337,23 +415,53 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SW,
-			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
-					 {OPT_D, D_SUNIT, false, false, 0, 0},
-					 {OPT_D, D_SWIDTH, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_D,
+					  .subopt = D_NOALIGN,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SUNIT,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SWIDTH,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SECTLOG,
-			  .conflicts = { {OPT_D, D_SECTSIZE, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_D,
+					  .subopt = D_SECTSIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SECTSIZE,
-			  .conflicts = { {OPT_D, D_SECTLOG, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_D,
+					  .subopt = D_SECTLOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -362,10 +470,34 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_NOALIGN,
-			  .conflicts = { {OPT_D, D_SU, false, false, 0, 0},
-					 {OPT_D, D_SW, false, false, 0, 0},
-					 {OPT_D, D_SUNIT, false, false, 0, 0},
-					 {OPT_D, D_SWIDTH, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_D,
+					  .subopt = D_SU,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SW,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SUNIT,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_D,
+					  .subopt = D_SWIDTH,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
@@ -407,7 +539,13 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = I_ALIGN,
-			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
+			  .conflicts = { {.opt = OPT_M,
+					  .subopt = M_CRC,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 0,
+					  .message = \
 		"Inodes always aligned for CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -415,8 +553,20 @@ struct opt_params {
 			  .defaultval = 1,
 			},
 			{ .index = I_LOG,
-			  .conflicts = { {OPT_I, I_PERBLOCK, false, false, 0, 0},
-					 {OPT_I, I_SIZE, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_I,
+					  .subopt = I_PERBLOCK,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_I,
+					  .subopt = I_SIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_DINODE_MIN_LOG,
 			  .maxval = XFS_DINODE_MAX_LOG,
@@ -429,8 +579,20 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_PERBLOCK,
-			  .conflicts = { {OPT_I, I_LOG, false, false, 0, 0},
-					 {OPT_I, I_SIZE, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_I,
+					  .subopt = I_LOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_I,
+					  .subopt = I_SIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_INODE_PERBLOCK,
@@ -438,8 +600,20 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_SIZE,
-			  .conflicts = { {OPT_I, I_PERBLOCK, false, false, 0, 0},
-					 {OPT_I, I_LOG, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_I,
+					  .subopt = I_PERBLOCK,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_I,
+					  .subopt = I_LOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
 			  .minval = XFS_DINODE_MIN_SIZE,
@@ -447,7 +621,13 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_ATTR,
-			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 1,
+			  .conflicts = { {.opt = OPT_M,
+					  .subopt = M_CRC,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 1,
+					  .message = \
 		"V2 attribute format always enabled on CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -455,7 +635,13 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_PROJID32BIT,
-			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
+			  .conflicts = { {.opt = OPT_M,
+					  .subopt = M_CRC,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 0,
+					  .message = \
 		"32 bit Project IDs always enabled on CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
 
@@ -464,7 +650,13 @@ struct opt_params {
 			  .defaultval = 1,
 			},
 			{ .index = I_SPINODES,
-			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
+			  .conflicts = { {.opt = OPT_M,
+					  .subopt = M_CRC,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 0,
+					  .at_value = 1,
+					  .message = \
 		"Sparse inodes not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -493,15 +685,33 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = L_AGNUM,
-			  .conflicts = { {OPT_L, L_DEV, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_DEV,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_INTERNAL,
-			  .conflicts = { {OPT_L, L_FILE, false, false, 0, 0},
-					 {OPT_L, L_DEV, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_FILE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_L,
+					  .subopt = L_DEV,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
@@ -515,7 +725,13 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_VERSION,
-			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 1,
+			  .conflicts = {{.opt = OPT_M,
+					  .subopt = M_CRC,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 1,
+					  .message =
 				"V2 logs are required for CRC enabled filesystems."},
 					 {LAST_CONFLICT} },
 			  .minval = 1,
@@ -523,14 +739,26 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SUNIT,
-			  .conflicts = { {OPT_L, L_SU, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_SU,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SU,
-			  .conflicts = { {OPT_L, L_SUNIT, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_SUNIT,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = BBTOB(1),
@@ -538,20 +766,44 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_DEV,
-			  .conflicts = { {OPT_L, L_AGNUM, false, false, 0, 0},
-					 {OPT_L, L_INTERNAL, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_AGNUM,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_L,
+					  .subopt = L_INTERNAL,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SECTLOG,
-			  .conflicts = { {OPT_L, L_SECTSIZE, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_SECTSIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SECTSIZE,
-			  .conflicts = { {OPT_L, L_SECTLOG, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_SECTLOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -560,20 +812,44 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_FILE,
-			  .conflicts = { {OPT_L, L_INTERNAL, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_INTERNAL,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
 			  .defaultval = 1,
 			},
 			{ .index = L_NAME,
-			  .conflicts = { {OPT_L, L_AGNUM, false, false, 0, 0},
-					 {OPT_L, L_INTERNAL, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_AGNUM,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_L,
+					  .subopt = L_INTERNAL,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_LAZYSBCNTR,
-			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
+			  .conflicts = { {.opt = OPT_M,
+					  .subopt = M_CRC,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 0,
+					  .message =
 		"Lazy superblock counted always enabled for CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -594,14 +870,26 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = N_LOG,
-			  .conflicts = { {OPT_N, N_SIZE, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_N,
+					  .subopt = N_SIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_REC_DIRSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = N_SIZE,
-			  .conflicts = { {OPT_N, N_LOG, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_N,
+					  .subopt = N_LOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -616,7 +904,13 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = N_FTYPE,
-			  .conflicts = {  {OPT_M, M_CRC, true, true, 1, 0,
+			  .conflicts = {  {.opt = OPT_M,
+					  .subopt = M_CRC,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 0,
+					  .message =
 		"Cannot disable ftype with crcs enabled."},
 					  {LAST_CONFLICT} },
 			  .minval = 0,
@@ -653,7 +947,13 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_DEV,
-			  .conflicts = { {OPT_M, M_RMAPBT, false, true, 0, 0,
+			  .conflicts = { {.opt = OPT_M,
+				  	  .subopt = M_RMAPBT,
+					  .test_values = false,
+					  .test_default_value = true,
+					  .invalid_value = 0,
+					  .at_value = 0,
+					  .message =
 		"rmapbt not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -665,7 +965,13 @@ struct opt_params {
 			  .conflicts = { {LAST_CONFLICT} },
 			},
 			{ .index = R_NAME,
-			  .conflicts = { {OPT_M, M_RMAPBT, false, true, 0, 0,
+			  .conflicts = { {.opt = OPT_M,
+				  	  .subopt = M_RMAPBT,
+					  .test_values = false,
+					  .test_default_value = true,
+					  .invalid_value = 0,
+					  .at_value = 0,
+					  .message =
 		"rmapbt not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -690,24 +996,60 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = S_LOG,
-			  .conflicts = { {OPT_S, S_SIZE, false, false, 0, 0},
-					 {OPT_S, S_SECTSIZE, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_S,
+					  .subopt = S_SIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_S,
+					  .subopt = S_SECTSIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SECTLOG,
-			  .conflicts = { {OPT_S, S_SIZE, false, false, 0, 0},
-					 {OPT_S, S_SECTSIZE, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_S,
+					  .subopt = S_SIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_S,
+					  .subopt = S_SECTSIZE,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SIZE,
-			  .conflicts = { {OPT_S, S_LOG, false, false, 0, 0},
-					 {OPT_S, S_SECTLOG, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_S,
+					  .subopt = S_LOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_S,
+					  .subopt = S_SECTLOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -716,8 +1058,20 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SECTSIZE,
-			  .conflicts = { {OPT_S, S_LOG, false, false, 0, 0},
-					 {OPT_S, S_SECTLOG, false, false, 0, 0},
+			  .conflicts = { {.opt = OPT_S,
+					  .subopt = S_LOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
+					 {.opt = OPT_S,
+					  .subopt = S_SECTLOG,
+					  .test_values = false,
+					  .test_default_value = false,
+					  .invalid_value = 0,
+					  .at_value = 0
+					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
@@ -740,25 +1094,85 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = M_CRC,
-			  .conflicts = { {OPT_L, L_VERSION, true, true, 1, 1,
+			  .conflicts = { {.opt = OPT_L,
+					  .subopt = L_VERSION,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 1,
+					  .message =
 		"V2 logs are required for CRC enabled filesystems."},
-					 {OPT_I, I_ALIGN, false, true, 0, 1,
+					 {.opt = OPT_I,
+					  .subopt = I_ALIGN,
+					  .test_values = false,
+					  .test_default_value = true,
+					  .invalid_value = 0,
+					  .at_value = 1,
+					  .message =
 		"Inodes always aligned for CRC enabled filesytems."},
-					 {OPT_I, I_PROJID32BIT, true, true, 0, 1,
+					 {.opt = OPT_I,
+					  .subopt = I_PROJID32BIT,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 0,
+					  .at_value = 1,
+					  .message =
 		"32 bit Project IDs always enabled on CRC enabled filesytems."},
-					 {OPT_I, I_ATTR, true, true, 1, 1,
+					 {.opt = OPT_I,
+					  .subopt = I_ATTR,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 1,
+					  .message =
 		"V2 attribute format always enabled on CRC enabled filesytems."},
-					 {OPT_L, L_LAZYSBCNTR, true, true, 0, 1,
+					 {.opt = OPT_L,
+					  .subopt = L_LAZYSBCNTR,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 0,
+					  .at_value = 1,
+					  .message =
 		"Lazy superblock counted always enabled for CRC enabled filesytems."},
-					 {OPT_M, M_FINOBT, true, true, 1, 0,
+					 {.opt = OPT_M,
+					  .subopt = M_FINOBT,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 0,
+					  .message =
 		"Finobt not supported without CRC support."},
-					 {OPT_M, M_RMAPBT, true, true, 1, 0,
+					 {.opt = OPT_M,
+				  	  .subopt = M_RMAPBT,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 0,
+					  .message =
 		"rmapbt not supported without CRC support."},
-					 {OPT_M, M_REFLINK, true, true, 1, 0,
+					 {.opt = OPT_M,
+				  	  .subopt = M_REFLINK,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 0,
+					  .message =
 		"reflink not supported without CRC support."},
-					 {OPT_I, I_SPINODES, true, true, 1, 0,
+					 {.opt = OPT_I,
+					  .subopt = I_SPINODES,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 1,
+					  .at_value = 0,
+					  .message =
 		"Sparse inodes not supported without CRC support."},
-					 {OPT_N, N_FTYPE, true, true, 0, 1,
+					 {.opt = OPT_N,
+					  .subopt = N_FTYPE,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 0,
+					  .at_value = 1,
+					  .message =
 		"Cannot disable ftype with crcs enabled."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -766,7 +1180,13 @@ struct opt_params {
 			  .defaultval = 1,
 			},
 			{ .index = M_FINOBT,
-			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
+			  .conflicts = { {.opt = OPT_M,
+					  .subopt = M_CRC,
+					  .test_values = true,
+					  .test_default_value = true,
+					  .invalid_value = 0,
+					  .at_value = 1,
+					  .message =
 		"Finobt not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -778,11 +1198,29 @@ struct opt_params {
 			  .defaultval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = M_RMAPBT,
-			.conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
+			.conflicts = { {.opt = OPT_M,
+					.subopt = M_CRC,
+					.test_values = true,
+					.test_default_value = true,
+					.invalid_value = 0,
+					.at_value = 1,
+					.message =
 		"rmapbt not supported without CRC support."},
-					{OPT_R, R_NAME, false, true, 0, 0,
+					{.opt = OPT_R,
+					 .subopt = R_NAME,
+					 .test_values = false,
+					 .test_default_value = true,
+					 .invalid_value = 0,
+					 .at_value = 0,
+					 .message =
 		"rmapbt not supported with realtime devices."},
-					{OPT_R, R_DEV, false, true, 0, 0,
+					{.opt = OPT_R,
+					 .subopt = R_DEV,
+					 .test_values = false,
+					 .test_default_value = true,
+					 .invalid_value = 0,
+					 .at_value = 0,
+					 .message =
 		"rmapbt not supported with realtime devices."},
 				       {LAST_CONFLICT} },
 			.minval = 0,
@@ -790,7 +1228,13 @@ struct opt_params {
 			.defaultval = 0,
 			},
 			{ .index = M_REFLINK,
-			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
+			.conflicts = { {.opt = OPT_M,
+					.subopt = M_CRC,
+					.test_values = true,
+					.test_default_value = true,
+					.invalid_value = 0,
+					.at_value = 1,
+					.message =
 		"reflink not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .minval = 0,
-- 
2.8.1


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

* [PATCH 13/22] mkfs: remove zeroed items from conflicts declaration
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (11 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 12/22] mkfs: expand conflicts declarations to named declaration Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-16 14:13   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 14/22] mkfs: rename defaultval to flagval in opts Jan Tulak
                   ` (12 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

opts is a global array of structs, so it is already zeroed. No need
for explicit zeros on items unless we want to highlight the value.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index b0e5d75..61caceb 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -239,10 +239,6 @@ struct opt_params {
 			{ .index = B_LOG,
 			  .conflicts = { {.opt = OPT_B,
 					  .subopt = B_SIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE_LOG,
@@ -254,10 +250,6 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .conflicts = { {.opt = OPT_B,
 					  .subopt = B_LOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE,
@@ -291,10 +283,6 @@ struct opt_params {
 			{ .index = D_AGCOUNT,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_AGSIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = 1,
@@ -321,24 +309,12 @@ struct opt_params {
 			{ .index = D_SUNIT,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_NOALIGN,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SU,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SW,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -348,24 +324,12 @@ struct opt_params {
 			{ .index = D_SWIDTH,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_NOALIGN,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SU,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SW,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -375,10 +339,6 @@ struct opt_params {
 			{ .index = D_AGSIZE,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_AGCOUNT,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
@@ -389,24 +349,12 @@ struct opt_params {
 			{ .index = D_SU,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_NOALIGN,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SUNIT,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SWIDTH,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
@@ -417,24 +365,12 @@ struct opt_params {
 			{ .index = D_SW,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_NOALIGN,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SUNIT,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SWIDTH,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -444,10 +380,6 @@ struct opt_params {
 			{ .index = D_SECTLOG,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_SECTSIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
@@ -457,10 +389,6 @@ struct opt_params {
 			{ .index = D_SECTSIZE,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_SECTLOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
@@ -472,31 +400,15 @@ struct opt_params {
 			{ .index = D_NOALIGN,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_SU,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SW,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SUNIT,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_D,
 					  .subopt = D_SWIDTH,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -555,17 +467,9 @@ struct opt_params {
 			{ .index = I_LOG,
 			  .conflicts = { {.opt = OPT_I,
 					  .subopt = I_PERBLOCK,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_I,
 					  .subopt = I_SIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_DINODE_MIN_LOG,
@@ -581,17 +485,9 @@ struct opt_params {
 			{ .index = I_PERBLOCK,
 			  .conflicts = { {.opt = OPT_I,
 					  .subopt = I_LOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_I,
 					  .subopt = I_SIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
@@ -602,17 +498,9 @@ struct opt_params {
 			{ .index = I_SIZE,
 			  .conflicts = { {.opt = OPT_I,
 					  .subopt = I_PERBLOCK,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_I,
 					  .subopt = I_LOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
@@ -687,10 +575,6 @@ struct opt_params {
 			{ .index = L_AGNUM,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_DEV,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -700,17 +584,9 @@ struct opt_params {
 			{ .index = L_INTERNAL,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_FILE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_L,
 					  .subopt = L_DEV,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -741,10 +617,6 @@ struct opt_params {
 			{ .index = L_SUNIT,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_SU,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = 1,
@@ -754,10 +626,6 @@ struct opt_params {
 			{ .index = L_SU,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_SUNIT,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
@@ -768,17 +636,9 @@ struct opt_params {
 			{ .index = L_DEV,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_AGNUM,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_L,
 					  .subopt = L_INTERNAL,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -786,10 +646,6 @@ struct opt_params {
 			{ .index = L_SECTLOG,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_SECTSIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
@@ -799,10 +655,6 @@ struct opt_params {
 			{ .index = L_SECTSIZE,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_SECTLOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
@@ -814,10 +666,6 @@ struct opt_params {
 			{ .index = L_FILE,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_INTERNAL,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = 0,
@@ -827,17 +675,9 @@ struct opt_params {
 			{ .index = L_NAME,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_AGNUM,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_L,
 					  .subopt = L_INTERNAL,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .defaultval = SUBOPT_NEEDS_VAL,
@@ -872,10 +712,6 @@ struct opt_params {
 			{ .index = N_LOG,
 			  .conflicts = { {.opt = OPT_N,
 					  .subopt = N_SIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_REC_DIRSIZE,
@@ -885,10 +721,6 @@ struct opt_params {
 			{ .index = N_SIZE,
 			  .conflicts = { {.opt = OPT_N,
 					  .subopt = N_LOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
@@ -998,17 +830,9 @@ struct opt_params {
 			{ .index = S_LOG,
 			  .conflicts = { {.opt = OPT_S,
 					  .subopt = S_SIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_S,
 					  .subopt = S_SECTSIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
@@ -1018,17 +842,9 @@ struct opt_params {
 			{ .index = S_SECTLOG,
 			  .conflicts = { {.opt = OPT_S,
 					  .subopt = S_SIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_S,
 					  .subopt = S_SECTSIZE,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
@@ -1038,17 +854,9 @@ struct opt_params {
 			{ .index = S_SIZE,
 			  .conflicts = { {.opt = OPT_S,
 					  .subopt = S_LOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_S,
 					  .subopt = S_SECTLOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
@@ -1060,17 +868,9 @@ struct opt_params {
 			{ .index = S_SECTSIZE,
 			  .conflicts = { {.opt = OPT_S,
 					  .subopt = S_LOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {.opt = OPT_S,
 					  .subopt = S_SECTLOG,
-					  .test_values = false,
-					  .test_default_value = false,
-					  .invalid_value = 0,
-					  .at_value = 0
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
-- 
2.8.1


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

* [PATCH 14/22] mkfs: rename defaultval to flagval in opts
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (12 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 13/22] mkfs: remove zeroed items from conflicts declaration Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-16 14:14   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 15/22] mkfs: replace SUBOPT_NEEDS_VAL for a flag Jan Tulak
                   ` (11 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 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 | 122 ++++++++++++++++++++++++++++----------------------------
 1 file changed, 61 insertions(+), 61 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 61caceb..f7eb191 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -189,7 +189,7 @@ unsigned int		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).
@@ -197,7 +197,7 @@ unsigned int		sectorsize;
  *     value in any case.
  *
  *   value INTERNAL
- *     Do not set this on initialization. Use defaultval for what you want
+ *     Do not set this on initialization. Use flagval for what you want
  *     to do. This is filled with user input and anything you write here now
  *     is overwritten. (If the user input is a string and not a number, this
  *     value is set to a positive non-zero number.)
@@ -223,7 +223,7 @@ struct opt_params {
 		}		conflicts [MAX_CONFLICTS];
 		long long	minval;
 		long long	maxval;
-		long long	defaultval;
+		long long	flagval;
 		long long	value;
 	}		subopt_params[MAX_SUBOPTS];
 } opts[MAX_OPTS] = {
@@ -243,7 +243,7 @@ struct opt_params {
 					 {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,
@@ -254,7 +254,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 		},
 	},
@@ -287,24 +287,24 @@ struct opt_params {
 					 {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 = { {.opt = OPT_D,
@@ -319,7 +319,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SWIDTH,
 			  .conflicts = { {.opt = OPT_D,
@@ -334,7 +334,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_AGSIZE,
 			  .conflicts = { {.opt = OPT_D,
@@ -344,7 +344,7 @@ struct opt_params {
 			  .convert = true,
 			  .minval = XFS_AG_MIN_BYTES,
 			  .maxval = XFS_AG_MAX_BYTES,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SU,
 			  .conflicts = { {.opt = OPT_D,
@@ -360,7 +360,7 @@ struct opt_params {
 			  .convert = true,
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SW,
 			  .conflicts = { {.opt = OPT_D,
@@ -375,7 +375,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SECTLOG,
 			  .conflicts = { {.opt = OPT_D,
@@ -384,7 +384,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_SECTSIZE,
 			  .conflicts = { {.opt = OPT_D,
@@ -395,7 +395,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
 			  .maxval = XFS_MAX_SECTORSIZE,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = D_NOALIGN,
 			  .conflicts = { {.opt = OPT_D,
@@ -413,25 +413,25 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 1,
+			  .flagval = 1,
 			},
 			{ .index = D_RTINHERIT,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 1,
 			  .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,
 			},
 		},
 	},
@@ -462,7 +462,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 1,
+			  .flagval = 1,
 			},
 			{ .index = I_LOG,
 			  .conflicts = { {.opt = OPT_I,
@@ -474,13 +474,13 @@ struct opt_params {
 					 {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 = { {.opt = OPT_I,
@@ -493,7 +493,7 @@ struct opt_params {
 			  .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 = { {.opt = OPT_I,
@@ -506,7 +506,7 @@ struct opt_params {
 			  .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 = { {.opt = OPT_M,
@@ -520,7 +520,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 2,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = I_PROJID32BIT,
 			  .conflicts = { {.opt = OPT_M,
@@ -535,7 +535,7 @@ struct opt_params {
 
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 1,
+			  .flagval = 1,
 			},
 			{ .index = I_SPINODES,
 			  .conflicts = { {.opt = OPT_M,
@@ -549,7 +549,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 1,
+			  .flagval = 1,
 			},
 		},
 	},
@@ -579,7 +579,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_INTERNAL,
 			  .conflicts = { {.opt = OPT_L,
@@ -591,14 +591,14 @@ struct opt_params {
 					 {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 = {{.opt = OPT_M,
@@ -612,7 +612,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = 2,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SUNIT,
 			  .conflicts = { {.opt = OPT_L,
@@ -621,7 +621,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SU,
 			  .conflicts = { {.opt = OPT_L,
@@ -631,7 +631,7 @@ struct opt_params {
 			  .convert = true,
 			  .minval = BBTOB(1),
 			  .maxval = XLOG_MAX_RECORD_BSIZE,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_DEV,
 			  .conflicts = { {.opt = OPT_L,
@@ -641,7 +641,7 @@ struct opt_params {
 					  .subopt = L_INTERNAL,
 					 },
 					 {LAST_CONFLICT} },
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SECTLOG,
 			  .conflicts = { {.opt = OPT_L,
@@ -650,7 +650,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_SECTSIZE,
 			  .conflicts = { {.opt = OPT_L,
@@ -661,7 +661,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
 			  .maxval = XFS_MAX_SECTORSIZE,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_FILE,
 			  .conflicts = { {.opt = OPT_L,
@@ -670,7 +670,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 1,
+			  .flagval = 1,
 			},
 			{ .index = L_NAME,
 			  .conflicts = { {.opt = OPT_L,
@@ -680,7 +680,7 @@ struct opt_params {
 					  .subopt = L_INTERNAL,
 					 },
 					 {LAST_CONFLICT} },
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = L_LAZYSBCNTR,
 			  .conflicts = { {.opt = OPT_M,
@@ -694,7 +694,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 1,
+			  .flagval = 1,
 			},
 		},
 	},
@@ -716,7 +716,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_REC_DIRSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = N_SIZE,
 			  .conflicts = { {.opt = OPT_N,
@@ -727,13 +727,13 @@ struct opt_params {
 			  .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 = {  {.opt = OPT_M,
@@ -747,7 +747,7 @@ struct opt_params {
 					  {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 1,
+			  .flagval = 1,
 			},
 		},
 	},
@@ -769,14 +769,14 @@ struct opt_params {
 			  .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 = { {.opt = OPT_M,
@@ -788,12 +788,12 @@ struct opt_params {
 					  .message =
 		"rmapbt not supported without CRC support."},
 					 {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,
@@ -806,12 +806,12 @@ struct opt_params {
 					  .message =
 		"rmapbt not supported without CRC support."},
 					 {LAST_CONFLICT} },
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = R_NOALIGN,
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 1,
+			  .flagval = 1,
 			  .conflicts = { {LAST_CONFLICT} },
 			},
 		},
@@ -837,7 +837,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SECTLOG,
 			  .conflicts = { {.opt = OPT_S,
@@ -849,7 +849,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SIZE,
 			  .conflicts = { {.opt = OPT_S,
@@ -863,7 +863,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
 			  .maxval = XFS_MAX_SECTORSIZE,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 			{ .index = S_SECTSIZE,
 			  .conflicts = { {.opt = OPT_S,
@@ -877,7 +877,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
 			  .maxval = XFS_MAX_SECTORSIZE,
-			  .defaultval = SUBOPT_NEEDS_VAL,
+			  .flagval = SUBOPT_NEEDS_VAL,
 			},
 		},
 	},
@@ -977,7 +977,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 1,
+			  .flagval = 1,
 			},
 			{ .index = M_FINOBT,
 			  .conflicts = { {.opt = OPT_M,
@@ -991,11 +991,11 @@ struct opt_params {
 					 {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 = { {.opt = OPT_M,
@@ -1025,7 +1025,7 @@ struct opt_params {
 				       {LAST_CONFLICT} },
 			.minval = 0,
 			.maxval = 1,
-			.defaultval = 0,
+			.flagval = 0,
 			},
 			{ .index = M_REFLINK,
 			.conflicts = { {.opt = OPT_M,
@@ -1039,7 +1039,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
-			  .defaultval = 0,
+			  .flagval = 0,
 			},
 		},
 	},
@@ -1715,10 +1715,10 @@ getnum(
 
 	/* 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);
 		sp->seen = true;
-		return sp->defaultval;
+		return sp->flagval;
 	}
 
 	sp->seen = true;
-- 
2.8.1


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

* [PATCH 15/22] mkfs: replace SUBOPT_NEEDS_VAL for a flag
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (13 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 14/22] mkfs: rename defaultval to flagval in opts Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-16 14:14   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 16/22] mkfs: Change all value fields in opt structures into unions Jan Tulak
                   ` (10 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Do not use a special value as a signal for a required value,
as it causes issues when we have more value types.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index f7eb191..7ffe8ff 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -44,7 +44,6 @@ unsigned int		sectorsize;
 
 #define MAX_OPTS	16
 #define MAX_SUBOPTS	16
-#define SUBOPT_NEEDS_VAL	(-1LL)
 #define MAX_CONFLICTS	32
 #define LAST_CONFLICT	(-1)
 
@@ -193,14 +192,17 @@ unsigned int		sectorsize;
  *     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).
- *     A special SUBOPT_NEEDS_VAL can be used to require a user-given
- *     value in any case.
  *
  *   value INTERNAL
  *     Do not set this on initialization. Use flagval for what you want
  *     to do. This is filled with user input and anything you write here now
  *     is overwritten. (If the user input is a string and not a number, this
  *     value is set to a positive non-zero number.)
+ *
+ *   needs_val OPTIONAL
+ *     Set to true if, when user specifies the option, she has to specify
+ *     a value too. That is, if needs_val is true, then it is not possible to
+ *     use the subopt as a flag.
  */
 struct opt_params {
 	int		index;
@@ -225,6 +227,7 @@ struct opt_params {
 		long long	maxval;
 		long long	flagval;
 		long long	value;
+		bool		needs_val;
 	}		subopt_params[MAX_SUBOPTS];
 } opts[MAX_OPTS] = {
 	{
@@ -243,7 +246,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE_LOG,
 			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = B_SIZE,
 			  .convert = true,
@@ -254,7 +257,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_BLOCKSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 		},
 	},
@@ -287,7 +290,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = XFS_MAX_AGNUMBER,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_FILE,
 			  .conflicts = { {LAST_CONFLICT} },
@@ -297,14 +300,14 @@ struct opt_params {
 			},
 			{ .index = D_NAME,
 			  .conflicts = { {LAST_CONFLICT} },
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_SIZE,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = XFS_AG_MIN_BYTES,
 			  .maxval = LLONG_MAX,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_SUNIT,
 			  .conflicts = { {.opt = OPT_D,
@@ -319,7 +322,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_SWIDTH,
 			  .conflicts = { {.opt = OPT_D,
@@ -334,7 +337,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_AGSIZE,
 			  .conflicts = { {.opt = OPT_D,
@@ -344,7 +347,7 @@ struct opt_params {
 			  .convert = true,
 			  .minval = XFS_AG_MIN_BYTES,
 			  .maxval = XFS_AG_MAX_BYTES,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_SU,
 			  .conflicts = { {.opt = OPT_D,
@@ -360,7 +363,7 @@ struct opt_params {
 			  .convert = true,
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_SW,
 			  .conflicts = { {.opt = OPT_D,
@@ -375,7 +378,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_SECTLOG,
 			  .conflicts = { {.opt = OPT_D,
@@ -384,7 +387,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_SECTSIZE,
 			  .conflicts = { {.opt = OPT_D,
@@ -395,7 +398,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
 			  .maxval = XFS_MAX_SECTORSIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_NOALIGN,
 			  .conflicts = { {.opt = OPT_D,
@@ -425,13 +428,13 @@ struct opt_params {
 			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = D_EXTSZINHERIT,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 		},
 	},
@@ -474,13 +477,13 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_DINODE_MIN_LOG,
 			  .maxval = XFS_DINODE_MAX_LOG,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = I_MAXPCT,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 100,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = I_PERBLOCK,
 			  .conflicts = { {.opt = OPT_I,
@@ -493,7 +496,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_INODE_PERBLOCK,
 			  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = I_SIZE,
 			  .conflicts = { {.opt = OPT_I,
@@ -506,7 +509,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_DINODE_MIN_SIZE,
 			  .maxval = XFS_DINODE_MAX_SIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = I_ATTR,
 			  .conflicts = { {.opt = OPT_M,
@@ -520,7 +523,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 2,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = I_PROJID32BIT,
 			  .conflicts = { {.opt = OPT_M,
@@ -579,7 +582,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = UINT_MAX,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = L_INTERNAL,
 			  .conflicts = { {.opt = OPT_L,
@@ -598,7 +601,7 @@ struct opt_params {
 			  .convert = true,
 			  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
 			  .maxval = XFS_MAX_LOG_BYTES,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = L_VERSION,
 			  .conflicts = {{.opt = OPT_M,
@@ -612,7 +615,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = 2,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = L_SUNIT,
 			  .conflicts = { {.opt = OPT_L,
@@ -621,7 +624,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 1,
 			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = L_SU,
 			  .conflicts = { {.opt = OPT_L,
@@ -631,7 +634,7 @@ struct opt_params {
 			  .convert = true,
 			  .minval = BBTOB(1),
 			  .maxval = XLOG_MAX_RECORD_BSIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = L_DEV,
 			  .conflicts = { {.opt = OPT_L,
@@ -641,7 +644,7 @@ struct opt_params {
 					  .subopt = L_INTERNAL,
 					 },
 					 {LAST_CONFLICT} },
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = L_SECTLOG,
 			  .conflicts = { {.opt = OPT_L,
@@ -650,7 +653,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = L_SECTSIZE,
 			  .conflicts = { {.opt = OPT_L,
@@ -661,7 +664,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
 			  .maxval = XFS_MAX_SECTORSIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = L_FILE,
 			  .conflicts = { {.opt = OPT_L,
@@ -680,7 +683,7 @@ struct opt_params {
 					  .subopt = L_INTERNAL,
 					 },
 					 {LAST_CONFLICT} },
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = L_LAZYSBCNTR,
 			  .conflicts = { {.opt = OPT_M,
@@ -716,7 +719,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_REC_DIRSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = N_SIZE,
 			  .conflicts = { {.opt = OPT_N,
@@ -727,13 +730,13 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = 1 << XFS_MIN_REC_DIRSIZE,
 			  .maxval = XFS_MAX_BLOCKSIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = N_VERSION,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .minval = 2,
 			  .maxval = 2,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = N_FTYPE,
 			  .conflicts = {  {.opt = OPT_M,
@@ -769,14 +772,14 @@ struct opt_params {
 			  .convert = true,
 			  .minval = XFS_MIN_RTEXTSIZE,
 			  .maxval = XFS_MAX_RTEXTSIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = R_SIZE,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval = 0,
 			  .maxval = LLONG_MAX,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = R_DEV,
 			  .conflicts = { {.opt = OPT_M,
@@ -788,7 +791,7 @@ struct opt_params {
 					  .message =
 		"rmapbt not supported without CRC support."},
 					 {LAST_CONFLICT} },
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = R_FILE,
 			  .minval = 0,
@@ -806,7 +809,7 @@ struct opt_params {
 					  .message =
 		"rmapbt not supported without CRC support."},
 					 {LAST_CONFLICT} },
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = R_NOALIGN,
 			  .minval = 0,
@@ -837,7 +840,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = S_SECTLOG,
 			  .conflicts = { {.opt = OPT_S,
@@ -849,7 +852,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = XFS_MIN_SECTORSIZE_LOG,
 			  .maxval = XFS_MAX_SECTORSIZE_LOG,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = S_SIZE,
 			  .conflicts = { {.opt = OPT_S,
@@ -863,7 +866,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
 			  .maxval = XFS_MAX_SECTORSIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = S_SECTSIZE,
 			  .conflicts = { {.opt = OPT_S,
@@ -877,7 +880,7 @@ struct opt_params {
 			  .is_power_2 = true,
 			  .minval = XFS_MIN_SECTORSIZE,
 			  .maxval = XFS_MAX_SECTORSIZE,
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 		},
 	},
@@ -995,7 +998,7 @@ struct opt_params {
 			},
 			{ .index = M_UUID,
 			  .conflicts = { {LAST_CONFLICT} },
-			  .flagval = SUBOPT_NEEDS_VAL,
+			  .needs_val = true,
 			},
 			{ .index = M_RMAPBT,
 			.conflicts = { {.opt = OPT_M,
@@ -1039,7 +1042,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .minval = 0,
 			  .maxval = 1,
-			  .flagval = 0,
+			  .needs_val = true,
 			},
 		},
 	},
@@ -1715,7 +1718,7 @@ getnum(
 
 	/* empty strings might just return a default value */
 	if (!str || *str == '\0') {
-		if (sp->flagval == SUBOPT_NEEDS_VAL)
+		if (sp->needs_val)
 			reqval(opts->name, (char **)opts->subopts, index);
 		sp->seen = true;
 		return sp->flagval;
-- 
2.8.1


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

* [PATCH 16/22] mkfs: Change all value fields in opt structures into unions
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (14 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 15/22] mkfs: replace SUBOPT_NEEDS_VAL for a flag Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 17:36   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values Jan Tulak
                   ` (9 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Trying to cover all possible values in a single data type is impossible,
so convert the field from long long type to union. This requires
also some small changes in supporting code, otherwise it would not compile.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 7ffe8ff..afc63d1 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -121,6 +121,231 @@ unsigned int		sectorsize;
 #define M_RMAPBT	3
 #define M_REFLINK	4
 
+enum e_type {
+	TYPE_UNDEF,
+	LONGLONG,
+	BOOL,
+	UINT64,
+	INT,
+	UINT,
+	STRING
+};
+union u_value {
+	long long 	ll;
+	bool		b;
+	__uint64_t	uint64;
+	int		i;
+	unsigned int	u;
+	char		*s;
+};
+static bool
+cmp_uvalues_gt(enum e_type a_type, union u_value a, enum e_type b_type, union u_value b) {
+	if (a_type == STRING || b_type == STRING) {
+		if (a_type == b_type)
+			return strcmp(a.s, b.s);
+		return false;
+	}	switch(a_type){
+	case LONGLONG:
+		switch(b_type){
+		case LONGLONG:
+			return a.ll > b.ll;
+		case BOOL:
+			return a.ll > b.b;
+		case UINT64:
+			return a.ll > b.uint64;
+		case INT:
+			return a.ll > b.i;
+		case UINT:
+			return a.ll > b.u;
+		default:
+			return false;
+		};
+		break;
+	case BOOL:
+		switch(b_type){
+		case LONGLONG:
+			return a.b > b.ll;
+		case BOOL:
+			return a.b > b.b;
+		case UINT64:
+			return a.b > b.uint64;
+		case INT:
+			return a.b > b.i;
+		case UINT:
+			return a.b > b.u;
+		default:
+			return false;
+		};
+		break;
+	case UINT64:
+		switch(b_type){
+		case LONGLONG:
+			return a.uint64 > b.ll;
+		case BOOL:
+			return a.uint64 > b.b;
+		case UINT64:
+			return a.uint64 > b.uint64;
+		case INT:
+			return a.uint64 > b.i;
+		case UINT:
+			return a.uint64 > b.u;
+		default:
+			return false;
+		};
+		break;
+	case INT:
+		switch(b_type){
+		case LONGLONG:
+			return a.i > b.ll;
+		case BOOL:
+			return a.i > b.b;
+		case UINT64:
+			return a.i > b.uint64;
+		case INT:
+			return a.i > b.i;
+		case UINT:
+			return a.i > b.u;
+		default:
+			return false;
+		};
+		break;
+	case UINT:
+		switch(b_type){
+		case LONGLONG:
+			return a.u > b.ll;
+		case BOOL:
+			return a.u > b.b;
+		case UINT64:
+			return a.u > b.uint64;
+		case INT:
+			return a.u > b.i;
+		case UINT:
+			return a.u > b.u;
+		default:
+			return false;
+		};
+		break;
+	default:
+		return false;
+	};
+
+	return false;
+}
+static bool
+cmp_uvalue_gt_num(enum e_type a_type, union u_value a, long long b) {
+	union u_value u;
+	u.ll = b;
+	return cmp_uvalues_gt(a_type, a, LONGLONG, u);
+}
+static bool
+cmp_uvalue_lt_num(enum e_type a_type, union u_value a, long long b) {
+	union u_value u;
+	u.ll = b;
+	return cmp_uvalues_gt(LONGLONG, u, a_type, a);
+}
+
+static bool
+test_uvalues(enum e_type a_type, union u_value a, enum e_type b_type, union u_value b) {
+	if (a_type == STRING || b_type == STRING) {
+		if (a_type == b_type)
+			return strcmp(a.s, b.s) == 0;
+		return false;
+	}
+	switch(a_type){
+	case LONGLONG:
+		switch(b_type){
+		case LONGLONG:
+			return a.ll == b.ll;
+		case BOOL:
+			return a.ll == b.b;
+		case UINT64:
+			return a.ll == b.uint64;
+		case INT:
+			return a.ll == b.i;
+		case UINT:
+			return a.ll == b.u;
+		default:
+			return false;
+		};
+		break;
+	case BOOL:
+		switch(b_type){
+		case LONGLONG:
+			return a.b == b.ll;
+		case BOOL:
+			return a.b == b.b;
+		case UINT64:
+			return a.b == b.uint64;
+		case INT:
+			return a.b == b.i;
+		case UINT:
+			return a.b == b.u;
+		default:
+			return false;
+		};
+		break;
+	case UINT64:
+		switch(b_type){
+		case LONGLONG:
+			return a.uint64 == b.ll;
+		case BOOL:
+			return a.uint64 == b.b;
+		case UINT64:
+			return a.uint64 == b.uint64;
+		case INT:
+			return a.uint64 == b.i;
+		case UINT:
+			return a.uint64 == b.u;
+		default:
+			return false;
+		};
+		break;
+	case INT:
+		switch(b_type){
+		case LONGLONG:
+			return a.i == b.ll;
+		case BOOL:
+			return a.i == b.b;
+		case UINT64:
+			return a.i == b.uint64;
+		case INT:
+			return a.i == b.i;
+		case UINT:
+			return a.i == b.u;
+		default:
+			return false;
+		};
+		break;
+	case UINT:
+		switch(b_type){
+		case LONGLONG:
+			return a.u == b.ll;
+		case BOOL:
+			return a.u == b.b;
+		case UINT64:
+			return a.u == b.uint64;
+		case INT:
+			return a.u == b.i;
+		case UINT:
+			return a.u == b.u;
+		default:
+			return false;
+		};
+		break;
+	default:
+		return false;
+	};
+
+	return false;
+}
+
+static bool
+test_uvalue_num(enum e_type a_type, union u_value a, long long b) {
+	union u_value u;
+	u.ll = b;
+	return test_uvalues(a_type, a, LONGLONG, u);
+}
+
 /*
  * Table for parsing mkfs parameters.
  *
@@ -193,11 +418,15 @@ unsigned int		sectorsize;
  *     If the subopt accepts some values (-d file=[1|0]), then this
  *     sets what is used with simple specifying the subopt (-d file).
  *
- *   value INTERNAL
- *     Do not set this on initialization. Use flagval for what you want
- *     to do. This is filled with user input and anything you write here now
- *     is overwritten. (If the user input is a string and not a number, this
- *     value is set to a positive non-zero number.)
+ *   value MANDATORY
+ *     A value that is used for given field as a default if user doesn't specify
+ *     any change. This is filled with user input and anything you write here
+ *     now is overwritten if the user specifies given option.
+ *
+ *   type MANDATORY
+ *     An enum of what type the values are. Affects every u_value field within
+ *     the suboption except conflict's .invalid_value - this one uses the
+ *     "remote" type.
  *
  *   needs_val OPTIONAL
  *     Set to true if, when user specifies the option, she has to specify
@@ -219,14 +448,15 @@ struct opt_params {
 			int		subopt;
 			bool		test_values;
 			bool		test_default_value;
-			long long	invalid_value;
-			long long	at_value;
+			union u_value	invalid_value;
+			union u_value	at_value;
 			const char	*message;
 		}		conflicts [MAX_CONFLICTS];
-		long long	minval;
-		long long	maxval;
-		long long	flagval;
-		long long	value;
+		union u_value	minval;
+		union u_value	maxval;
+		union u_value	flagval;
+		union u_value value;
+		enum e_type 	type;
 		bool		needs_val;
 	}		subopt_params[MAX_SUBOPTS];
 } opts[MAX_OPTS] = {
@@ -244,9 +474,10 @@ struct opt_params {
 					  .subopt = B_SIZE,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = XFS_MIN_BLOCKSIZE_LOG,
-			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
+			  .minval.i = XFS_MIN_BLOCKSIZE_LOG,
+			  .maxval.i = XFS_MAX_BLOCKSIZE_LOG,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = B_SIZE,
 			  .convert = true,
@@ -255,9 +486,10 @@ struct opt_params {
 					  .subopt = B_LOG,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = XFS_MIN_BLOCKSIZE,
-			  .maxval = XFS_MAX_BLOCKSIZE,
+			  .minval.u = XFS_MIN_BLOCKSIZE,
+			  .maxval.u = XFS_MAX_BLOCKSIZE,
 			  .needs_val = true,
+			  .type = UINT,
 			},
 		},
 	},
@@ -288,26 +520,30 @@ struct opt_params {
 					  .subopt = D_AGSIZE,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = 1,
-			  .maxval = XFS_MAX_AGNUMBER,
+			  .minval.uint64 = 1,
+			  .maxval.uint64 = XFS_MAX_AGNUMBER,
 			  .needs_val = true,
+			  .type = UINT64,
 			},
 			{ .index = D_FILE,
 			  .conflicts = { {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.i = 0,
+			  .maxval.i = 1,
+			  .flagval.i = 1,
+			  .type = INT,
 			},
 			{ .index = D_NAME,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .needs_val = true,
+			  .type = STRING,
 			},
 			{ .index = D_SIZE,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
-			  .minval = XFS_AG_MIN_BYTES,
-			  .maxval = LLONG_MAX,
+			  .minval.uint64 = XFS_AG_MIN_BYTES,
+			  .maxval.uint64 = LLONG_MAX,
 			  .needs_val = true,
+			  .type = UINT64,
 			},
 			{ .index = D_SUNIT,
 			  .conflicts = { {.opt = OPT_D,
@@ -320,9 +556,10 @@ struct opt_params {
 					  .subopt = D_SW,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = UINT_MAX,
+			  .minval.i = 0,
+			  .maxval.i = UINT_MAX,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = D_SWIDTH,
 			  .conflicts = { {.opt = OPT_D,
@@ -335,9 +572,10 @@ struct opt_params {
 					  .subopt = D_SW,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = UINT_MAX,
+			  .minval.i = 0,
+			  .maxval.i = UINT_MAX,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = D_AGSIZE,
 			  .conflicts = { {.opt = OPT_D,
@@ -345,9 +583,10 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
-			  .minval = XFS_AG_MIN_BYTES,
-			  .maxval = XFS_AG_MAX_BYTES,
+			  .minval.uint64 = XFS_AG_MIN_BYTES,
+			  .maxval.uint64 = XFS_AG_MAX_BYTES,
 			  .needs_val = true,
+			  .type = UINT64,
 			},
 			{ .index = D_SU,
 			  .conflicts = { {.opt = OPT_D,
@@ -361,9 +600,10 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
-			  .minval = 0,
-			  .maxval = UINT_MAX,
+			  .minval.i = 0,
+			  .maxval.i = UINT_MAX,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = D_SW,
 			  .conflicts = { {.opt = OPT_D,
@@ -376,18 +616,20 @@ struct opt_params {
 					  .subopt = D_SWIDTH,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = UINT_MAX,
+			  .minval.i = 0,
+			  .maxval.i = UINT_MAX,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = D_SECTLOG,
 			  .conflicts = { {.opt = OPT_D,
 					  .subopt = D_SECTSIZE,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = XFS_MIN_SECTORSIZE_LOG,
-			  .maxval = XFS_MAX_SECTORSIZE_LOG,
+			  .minval.i = XFS_MIN_SECTORSIZE_LOG,
+			  .maxval.i = XFS_MAX_SECTORSIZE_LOG,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = D_SECTSIZE,
 			  .conflicts = { {.opt = OPT_D,
@@ -396,9 +638,10 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
-			  .minval = XFS_MIN_SECTORSIZE,
-			  .maxval = XFS_MAX_SECTORSIZE,
+			  .minval.u = XFS_MIN_SECTORSIZE,
+			  .maxval.u = XFS_MAX_SECTORSIZE,
 			  .needs_val = true,
+			  .type = UINT,
 			},
 			{ .index = D_NOALIGN,
 			  .conflicts = { {.opt = OPT_D,
@@ -414,27 +657,31 @@ struct opt_params {
 					  .subopt = D_SWIDTH,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.i = 0,
+			  .maxval.i = 1,
+			  .flagval.i = 1,
+			  .type = INT,
 			},
 			{ .index = D_RTINHERIT,
 			  .conflicts = { {LAST_CONFLICT} },
-			  .minval = 1,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.u = 1,
+			  .maxval.u = 1,
+			  .flagval.u = 1,
+			  .type = UINT,
 			},
 			{ .index = D_PROJINHERIT,
 			  .conflicts = { {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = UINT_MAX,
+			  .minval.u = 0,
+			  .maxval.u = UINT_MAX,
 			  .needs_val = true,
+			  .type = UINT,
 			},
 			{ .index = D_EXTSZINHERIT,
 			  .conflicts = { {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = UINT_MAX,
+			  .minval.u = 0,
+			  .maxval.u = UINT_MAX,
 			  .needs_val = true,
+			  .type = UINT,
 			},
 		},
 	},
@@ -458,14 +705,15 @@ struct opt_params {
 					  .subopt = M_CRC,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 0,
+					  .invalid_value.b = 1,
+					  .at_value.b = 0,
 					  .message = \
 		"Inodes always aligned for CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			},
 			{ .index = I_LOG,
 			  .conflicts = { {.opt = OPT_I,
@@ -475,15 +723,17 @@ struct opt_params {
 					  .subopt = I_SIZE,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = XFS_DINODE_MIN_LOG,
-			  .maxval = XFS_DINODE_MAX_LOG,
+			  .minval.i = XFS_DINODE_MIN_LOG,
+			  .maxval.i = XFS_DINODE_MAX_LOG,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = I_MAXPCT,
 			  .conflicts = { {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 100,
+			  .minval.i = 0,
+			  .maxval.i = 100,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = I_PERBLOCK,
 			  .conflicts = { {.opt = OPT_I,
@@ -494,9 +744,10 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
-			  .minval = XFS_MIN_INODE_PERBLOCK,
-			  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
+			  .minval.i = XFS_MIN_INODE_PERBLOCK,
+			  .maxval.i = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = I_SIZE,
 			  .conflicts = { {.opt = OPT_I,
@@ -507,52 +758,56 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .is_power_2 = true,
-			  .minval = XFS_DINODE_MIN_SIZE,
-			  .maxval = XFS_DINODE_MAX_SIZE,
+			  .minval.i = XFS_DINODE_MIN_SIZE,
+			  .maxval.i = XFS_DINODE_MAX_SIZE,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = I_ATTR,
 			  .conflicts = { {.opt = OPT_M,
 					  .subopt = M_CRC,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 1,
+					  .invalid_value.b = true,
+					  .at_value.i = 1,
 					  .message = \
 		"V2 attribute format always enabled on CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 2,
+			  .minval.i = 0,
+			  .maxval.i = 2,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = I_PROJID32BIT,
 			  .conflicts = { {.opt = OPT_M,
 					  .subopt = M_CRC,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 0,
+					  .invalid_value.b = true,
+					  .at_value.b = 0,
 					  .message = \
 		"32 bit Project IDs always enabled on CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
 
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			},
 			{ .index = I_SPINODES,
 			  .conflicts = { {.opt = OPT_M,
 					  .subopt = M_CRC,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 0,
-					  .at_value = 1,
+					  .invalid_value.b = 0,
+					  .at_value.i = 1,
 					  .message = \
 		"Sparse inodes not supported without CRC support."},
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.i = 0,
+			  .maxval.i = 1,
+			  .flagval.i = 1,
+			  .type = INT,
 			},
 		},
 	},
@@ -576,13 +831,15 @@ struct opt_params {
 		},
 		.subopt_params = {
 			{ .index = L_AGNUM,
+			  /* FIXME custom type xfs_agnumber_t? */
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_DEV,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = UINT_MAX,
+			  .minval.u = 0,
+			  .maxval.u = UINT_MAX,
 			  .needs_val = true,
+			  .type = UINT,
 			},
 			{ .index = L_INTERNAL,
 			  .conflicts = { {.opt = OPT_L,
@@ -592,39 +849,43 @@ struct opt_params {
 					  .subopt = L_DEV,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.i = 0,
+			  .maxval.i = 1,
+			  .flagval.i = 1,
+			  .type = INT,
 			},
 			{ .index = L_SIZE,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
-			  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
-			  .maxval = XFS_MAX_LOG_BYTES,
+			  .minval.i = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
+			  .maxval.i = XFS_MAX_LOG_BYTES,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = L_VERSION,
 			  .conflicts = {{.opt = OPT_M,
 					  .subopt = M_CRC,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 1,
+					  .invalid_value.b = true,
+					  .at_value.i = 1,
 					  .message =
 				"V2 logs are required for CRC enabled filesystems."},
 					 {LAST_CONFLICT} },
-			  .minval = 1,
-			  .maxval = 2,
+			  .minval.i = 1,
+			  .maxval.i = 2,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = L_SUNIT,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_SU,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = 1,
-			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
+			  .minval.i = 1,
+			  .maxval.i = BTOBB(XLOG_MAX_RECORD_BSIZE),
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = L_SU,
 			  .conflicts = { {.opt = OPT_L,
@@ -632,9 +893,10 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .convert = true,
-			  .minval = BBTOB(1),
-			  .maxval = XLOG_MAX_RECORD_BSIZE,
+			  .minval.i = BBTOB(1),
+			  .maxval.i = XLOG_MAX_RECORD_BSIZE,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = L_DEV,
 			  .conflicts = { {.opt = OPT_L,
@@ -645,15 +907,17 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .needs_val = true,
+			  .type = STRING,
 			},
 			{ .index = L_SECTLOG,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_SECTSIZE,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = XFS_MIN_SECTORSIZE_LOG,
-			  .maxval = XFS_MAX_SECTORSIZE_LOG,
+			  .minval.i = XFS_MIN_SECTORSIZE_LOG,
+			  .maxval.i = XFS_MAX_SECTORSIZE_LOG,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = L_SECTSIZE,
 			  .conflicts = { {.opt = OPT_L,
@@ -662,18 +926,20 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
-			  .minval = XFS_MIN_SECTORSIZE,
-			  .maxval = XFS_MAX_SECTORSIZE,
+			  .minval.i = XFS_MIN_SECTORSIZE,
+			  .maxval.i = XFS_MAX_SECTORSIZE,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = L_FILE,
 			  .conflicts = { {.opt = OPT_L,
 					  .subopt = L_INTERNAL,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.i = 0,
+			  .maxval.i = 1,
+			  .flagval.i = 1,
+			  .type = INT,
 			},
 			{ .index = L_NAME,
 			  .conflicts = { {.opt = OPT_L,
@@ -684,20 +950,22 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .needs_val = true,
+			  .type = STRING,
 			},
 			{ .index = L_LAZYSBCNTR,
 			  .conflicts = { {.opt = OPT_M,
 					  .subopt = M_CRC,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 0,
+					  .invalid_value.b = true,
+					  .at_value.b = false,
 					  .message =
 		"Lazy superblock counted always enabled for CRC enabled filesytems."},
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			},
 		},
 	},
@@ -717,9 +985,10 @@ struct opt_params {
 					  .subopt = N_SIZE,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = XFS_MIN_REC_DIRSIZE,
-			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
+			  .minval.i = XFS_MIN_REC_DIRSIZE,
+			  .maxval.i = XFS_MAX_BLOCKSIZE_LOG,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = N_SIZE,
 			  .conflicts = { {.opt = OPT_N,
@@ -728,29 +997,32 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
-			  .minval = 1 << XFS_MIN_REC_DIRSIZE,
-			  .maxval = XFS_MAX_BLOCKSIZE,
+			  .minval.i = 1 << XFS_MIN_REC_DIRSIZE,
+			  .maxval.i = XFS_MAX_BLOCKSIZE,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = N_VERSION,
 			  .conflicts = { {LAST_CONFLICT} },
-			  .minval = 2,
-			  .maxval = 2,
+			  .minval.i = 2,
+			  .maxval.i = 2,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = N_FTYPE,
 			  .conflicts = {  {.opt = OPT_M,
 					  .subopt = M_CRC,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 0,
+					  .invalid_value.b = true,
+					  .at_value.b = false,
 					  .message =
 		"Cannot disable ftype with crcs enabled."},
 					  {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			},
 		},
 	},
@@ -770,33 +1042,37 @@ struct opt_params {
 			{ .index = R_EXTSIZE,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
-			  .minval = XFS_MIN_RTEXTSIZE,
-			  .maxval = XFS_MAX_RTEXTSIZE,
+			  .minval.uint64 = XFS_MIN_RTEXTSIZE,
+			  .maxval.uint64 = XFS_MAX_RTEXTSIZE,
 			  .needs_val = true,
+			  .type = UINT64,
 			},
 			{ .index = R_SIZE,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .convert = true,
-			  .minval = 0,
-			  .maxval = LLONG_MAX,
+			  .minval.uint64 = 0,
+			  .maxval.uint64 = LLONG_MAX,
 			  .needs_val = true,
+			  .type = UINT64,
 			},
 			{ .index = R_DEV,
 			  .conflicts = { {.opt = OPT_M,
 				  	  .subopt = M_RMAPBT,
 					  .test_values = false,
 					  .test_default_value = true,
-					  .invalid_value = 0,
-					  .at_value = 0,
+					  .invalid_value.b = 0,
+					  .at_value.b = 0,
 					  .message =
 		"rmapbt not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .needs_val = true,
+			  .type = STRING,
 			},
 			{ .index = R_FILE,
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.i = 0,
+			  .maxval.i = 1,
+			  .flagval.i = 1,
+			  .type = INT,
 			  .conflicts = { {LAST_CONFLICT} },
 			},
 			{ .index = R_NAME,
@@ -804,17 +1080,19 @@ struct opt_params {
 				  	  .subopt = M_RMAPBT,
 					  .test_values = false,
 					  .test_default_value = true,
-					  .invalid_value = 0,
-					  .at_value = 0,
+					  .invalid_value.b = 0,
+					  .at_value.b = 0,
 					  .message =
 		"rmapbt not supported without CRC support."},
 					 {LAST_CONFLICT} },
 			  .needs_val = true,
+			  .type = STRING,
 			},
 			{ .index = R_NOALIGN,
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.i = 0,
+			  .maxval.i = 1,
+			  .flagval.i = 1,
+			  .type = INT,
 			  .conflicts = { {LAST_CONFLICT} },
 			},
 		},
@@ -838,9 +1116,10 @@ struct opt_params {
 					  .subopt = S_SECTSIZE,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = XFS_MIN_SECTORSIZE_LOG,
-			  .maxval = XFS_MAX_SECTORSIZE_LOG,
+			  .minval.i = XFS_MIN_SECTORSIZE_LOG,
+			  .maxval.i = XFS_MAX_SECTORSIZE_LOG,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = S_SECTLOG,
 			  .conflicts = { {.opt = OPT_S,
@@ -850,9 +1129,10 @@ struct opt_params {
 					  .subopt = S_SECTSIZE,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval = XFS_MIN_SECTORSIZE_LOG,
-			  .maxval = XFS_MAX_SECTORSIZE_LOG,
+			  .minval.i = XFS_MIN_SECTORSIZE_LOG,
+			  .maxval.i = XFS_MAX_SECTORSIZE_LOG,
 			  .needs_val = true,
+			  .type = INT,
 			},
 			{ .index = S_SIZE,
 			  .conflicts = { {.opt = OPT_S,
@@ -864,9 +1144,10 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
-			  .minval = XFS_MIN_SECTORSIZE,
-			  .maxval = XFS_MAX_SECTORSIZE,
+			  .minval.u = XFS_MIN_SECTORSIZE,
+			  .maxval.u = XFS_MAX_SECTORSIZE,
 			  .needs_val = true,
+			  .type = UINT,
 			},
 			{ .index = S_SECTSIZE,
 			  .conflicts = { {.opt = OPT_S,
@@ -878,9 +1159,10 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .is_power_2 = true,
-			  .minval = XFS_MIN_SECTORSIZE,
-			  .maxval = XFS_MAX_SECTORSIZE,
+			  .minval.u = XFS_MIN_SECTORSIZE,
+			  .maxval.u = XFS_MAX_SECTORSIZE,
 			  .needs_val = true,
+			  .type = UINT,
 			},
 		},
 	},
@@ -901,148 +1183,153 @@ struct opt_params {
 					  .subopt = L_VERSION,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 1,
+					  .invalid_value.i = 1,
+					  .at_value.b = 1,
 					  .message =
 		"V2 logs are required for CRC enabled filesystems."},
 					 {.opt = OPT_I,
 					  .subopt = I_ALIGN,
 					  .test_values = false,
 					  .test_default_value = true,
-					  .invalid_value = 0,
-					  .at_value = 1,
+					  .invalid_value.b = 0,
+					  .at_value.b = 1,
 					  .message =
 		"Inodes always aligned for CRC enabled filesytems."},
 					 {.opt = OPT_I,
 					  .subopt = I_PROJID32BIT,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 0,
-					  .at_value = 1,
+					  .invalid_value.b = 0,
+					  .at_value.b = 1,
 					  .message =
 		"32 bit Project IDs always enabled on CRC enabled filesytems."},
 					 {.opt = OPT_I,
 					  .subopt = I_ATTR,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 1,
+					  .invalid_value.i = 1,
+					  .at_value.b = 1,
 					  .message =
 		"V2 attribute format always enabled on CRC enabled filesytems."},
 					 {.opt = OPT_L,
 					  .subopt = L_LAZYSBCNTR,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 0,
-					  .at_value = 1,
+					  .invalid_value.b = 0,
+					  .at_value.b = 1,
 					  .message =
 		"Lazy superblock counted always enabled for CRC enabled filesytems."},
 					 {.opt = OPT_M,
 					  .subopt = M_FINOBT,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 0,
+					  .invalid_value.i = 1,
+					  .at_value.b = 0,
 					  .message =
 		"Finobt not supported without CRC support."},
 					 {.opt = OPT_M,
 				  	  .subopt = M_RMAPBT,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 0,
+					  .invalid_value.b = 1,
+					  .at_value.b = 0,
 					  .message =
 		"rmapbt not supported without CRC support."},
 					 {.opt = OPT_M,
 				  	  .subopt = M_REFLINK,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 0,
+					  .invalid_value.b = 1,
+					  .at_value.b = 0,
 					  .message =
 		"reflink not supported without CRC support."},
 					 {.opt = OPT_I,
 					  .subopt = I_SPINODES,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 1,
-					  .at_value = 0,
+					  .invalid_value.i = 1,
+					  .at_value.b = 0,
 					  .message =
 		"Sparse inodes not supported without CRC support."},
 					 {.opt = OPT_N,
 					  .subopt = N_FTYPE,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 0,
-					  .at_value = 1,
+					  .invalid_value.b = 0,
+					  .at_value.b = 1,
 					  .message =
 		"Cannot disable ftype with crcs enabled."},
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			},
 			{ .index = M_FINOBT,
 			  .conflicts = { {.opt = OPT_M,
 					  .subopt = M_CRC,
 					  .test_values = true,
 					  .test_default_value = true,
-					  .invalid_value = 0,
-					  .at_value = 1,
+					  .invalid_value.b = 0,
+					  .at_value.i = 1,
 					  .message =
 		"Finobt not supported without CRC support."},
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
-			  .flagval = 1,
+			  .minval.i = 0,
+			  .maxval.i = 1,
+			  .flagval.i = 1,
+			  .type = INT,
 			},
 			{ .index = M_UUID,
 			  .conflicts = { {LAST_CONFLICT} },
 			  .needs_val = true,
+			  .type = STRING,
 			},
 			{ .index = M_RMAPBT,
 			.conflicts = { {.opt = OPT_M,
 					.subopt = M_CRC,
 					.test_values = true,
 					.test_default_value = true,
-					.invalid_value = 0,
-					.at_value = 1,
+					.invalid_value.b = 0,
+					.at_value.b = 1,
 					.message =
 		"rmapbt not supported without CRC support."},
 					{.opt = OPT_R,
 					 .subopt = R_NAME,
 					 .test_values = false,
 					 .test_default_value = true,
-					 .invalid_value = 0,
-					 .at_value = 0,
+					 .invalid_value.b = 0,
+					 .at_value.b = 0,
 					 .message =
 		"rmapbt not supported with realtime devices."},
 					{.opt = OPT_R,
 					 .subopt = R_DEV,
 					 .test_values = false,
 					 .test_default_value = true,
-					 .invalid_value = 0,
-					 .at_value = 0,
+					 .invalid_value.b = 0,
+					 .at_value.b = 0,
 					 .message =
 		"rmapbt not supported with realtime devices."},
 				       {LAST_CONFLICT} },
-			.minval = 0,
-			.maxval = 1,
-			.flagval = 0,
+			.minval.b = false,
+			.maxval.b = true,
+			.flagval.b = false,
+			.type = BOOL,
 			},
 			{ .index = M_REFLINK,
 			.conflicts = { {.opt = OPT_M,
 					.subopt = M_CRC,
 					.test_values = true,
 					.test_default_value = true,
-					.invalid_value = 0,
-					.at_value = 1,
+					.invalid_value.b = 0,
+					.at_value.b = 1,
 					.message =
 		"reflink not supported without CRC support."},
 					 {LAST_CONFLICT} },
-			  .minval = 0,
-			  .maxval = 1,
+			  .minval.b = 0,
+			  .maxval.b = 1,
 			  .needs_val = true,
+			 .type = BOOL,
 			},
 		},
 	},
@@ -1653,8 +1940,7 @@ check_subopt_conflicts(
 static void
 check_subopt_value(
 	struct opt_params	*opt,
-	int			index,
-	long long 		value)
+	int			index)
 {
 	struct subopt_param	*sp = &opt->subopt_params[index];
 	int			i;
@@ -1669,9 +1955,19 @@ check_subopt_value(
 			break;
 		if ( (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
 		      conflict_opt.test_default_value) &&
-		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value
-				== conflict_opt.invalid_value &&
-		    value == conflict_opt.at_value) {
+		      test_uvalues(
+			opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].type,
+			opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value,
+			opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].type,
+			conflict_opt.invalid_value
+		      ) &&
+		      test_uvalues(
+			sp->type,
+			sp->value,
+			sp->type,
+			conflict_opt.at_value
+		      )
+		    ) {
 			conflict_struct(opt, sp, &conflict_opt);
 		}
 	}
@@ -1695,7 +1991,7 @@ check_opt(
 		if (!sp->seen)
 			continue;
 		check_subopt_conflicts(opt, index, false);
-		check_subopt_value(opt, index, sp->value);
+		check_subopt_value(opt, index);
 	}
 }
 static void
@@ -1721,18 +2017,42 @@ getnum(
 		if (sp->needs_val)
 			reqval(opts->name, (char **)opts->subopts, index);
 		sp->seen = true;
-		return sp->flagval;
+		switch(sp->type){
+		case LONGLONG:
+			return sp->flagval.ll;
+		case BOOL:
+			return sp->flagval.b;
+		case UINT64:
+			return sp->flagval.uint64;
+		case INT:
+			return sp->flagval.i;
+		case UINT:
+			return sp->flagval.u;
+		default:
+			fprintf(stderr,
+				_("Option -%c %s called getnum, but is not numeric."
+				  " This is a bug.\n"), opts->name, opts->subopts[index]);
+			exit(1);
+		}
 	}
 
 	sp->seen = true;
 
-	if (sp->minval == 0 && sp->maxval == 0) {
+	if (test_uvalue_num(sp->type, sp->minval, 0) &&
+		test_uvalue_num(sp->type, sp->maxval, 0)) {
 		fprintf(stderr,
 			_("Option -%c %s has undefined minval/maxval."
 			  "Can't verify value range. This is a bug.\n"),
 			opts->name, opts->subopts[index]);
 		exit(1);
 	}
+	if (sp->type == TYPE_UNDEF) {
+		fprintf(stderr,
+			_("Option -%c %s is of undefined type."
+			  "Can't parse value. This is a bug.\n"),
+			opts->name, opts->subopts[index]);
+		exit(1);
+	}
 
 	/*
 	 * Some values are pure numbers, others can have suffixes that define
@@ -1753,9 +2073,9 @@ getnum(
 	}
 
 	/* Validity check the result. */
-	if (c < sp->minval)
+	if (cmp_uvalue_gt_num(sp->type, sp->minval, c))
 		illegal_option(str, opts, index, _("value is too small"));
-	else if (c > sp->maxval)
+	else if (cmp_uvalue_lt_num(sp->type, sp->maxval, c))
 		illegal_option(str, opts, index, _("value is too large"));
 	if (sp->is_power_2 && !ispow2(c))
 		illegal_option(str, opts, index, _("value must be a power of 2"));
@@ -1940,20 +2260,12 @@ main(
 								B_LOG);
 					blocksize = 1 << blocklog;
 					blflag = 1;
-					opts[OPT_B].subopt_params[B_LOG].value =
-							blocklog;
-					opts[OPT_B].subopt_params[B_SIZE].value =
-							blocksize;
 					break;
 				case B_SIZE:
 					blocksize = getnum(value, &opts[OPT_B],
 							   B_SIZE);
 					blocklog = libxfs_highbit32(blocksize);
 					bsflag = 1;
-					opts[OPT_B].subopt_params[B_LOG].value =
-							blocklog;
-					opts[OPT_B].subopt_params[B_SIZE].value =
-							blocksize;
 					break;
 				default:
 					unknown('b', value);
@@ -1971,70 +2283,47 @@ main(
 					agcount = getnum(value, &opts[OPT_D],
 							 D_AGCOUNT);
 					daflag = 1;
-					opts[OPT_D].subopt_params[D_AGCOUNT].value =
-							agcount;
 					break;
 				case D_AGSIZE:
 					agsize = getnum(value, &opts[OPT_D],
 								D_AGSIZE);
 					dasize = 1;
-					opts[OPT_D].subopt_params[D_AGSIZE].value =
-							agsize;
 					break;
 				case D_FILE:
 					xi.disfile = getnum(value, &opts[OPT_D],
 							    D_FILE);
-					opts[OPT_D].subopt_params[D_FILE].value =
-							xi.disfile;
 					break;
 				case D_NAME:
 					xi.dname = getstr(value, &opts[OPT_D],
 								D_NAME);
-					opts[OPT_D].subopt_params[D_NAME].value = 1;
 					break;
 				case D_SIZE:
 					dbytes = getnum(value, &opts[OPT_D],
 								D_SIZE);
-					opts[OPT_D].subopt_params[D_SIZE].value =
-							dbytes;
 					break;
 				case D_SUNIT:
 					dsunit = getnum(value, &opts[OPT_D],
 								D_SUNIT);
-					opts[OPT_D].subopt_params[D_SUNIT].value =
-							dsunit;
 					break;
 				case D_SWIDTH:
 					dswidth = getnum(value, &opts[OPT_D],
 							 D_SWIDTH);
-					opts[OPT_D].subopt_params[D_SWIDTH].value =
-							dswidth;
 					break;
 				case D_SU:
 					dsu = getnum(value, &opts[OPT_D], D_SU);
-					opts[OPT_D].subopt_params[D_SU].value =
-							dsu;
 					break;
 				case D_SW:
 					dsw = getnum(value, &opts[OPT_D], D_SW);
-					opts[OPT_D].subopt_params[D_SW].value =
-							dsw;
 					break;
 				case D_NOALIGN:
 					nodsflag = getnum(value, &opts[OPT_D],
 								D_NOALIGN);
-					opts[OPT_D].subopt_params[D_NOALIGN].value =
-							nodsflag;
 					break;
 				case D_SECTLOG:
 					sectorlog = getnum(value, &opts[OPT_D],
 							   D_SECTLOG);
 					sectorsize = 1 << sectorlog;
 					slflag = 1;
-					opts[OPT_D].subopt_params[D_SECTSIZE].value =
-							sectorsize;
-					opts[OPT_D].subopt_params[D_SECTLOG].value =
-							sectorlog;
 					break;
 				case D_SECTSIZE:
 					sectorsize = getnum(value, &opts[OPT_D],
@@ -2042,10 +2331,6 @@ main(
 					sectorlog =
 						libxfs_highbit32(sectorsize);
 					ssflag = 1;
-					opts[OPT_D].subopt_params[D_SECTSIZE].value =
-							sectorsize;
-					opts[OPT_D].subopt_params[D_SECTLOG].value =
-							sectorlog;
 					break;
 				case D_RTINHERIT:
 					c = getnum(value, &opts[OPT_D],
@@ -2053,24 +2338,18 @@ main(
 					if (c)
 						fsx.fsx_xflags |=
 							XFS_DIFLAG_RTINHERIT;
-					opts[OPT_D].subopt_params[D_RTINHERIT].value =
-							c;
 					break;
 				case D_PROJINHERIT:
 					fsx.fsx_projid = getnum(value, &opts[OPT_D],
 								D_PROJINHERIT);
 					fsx.fsx_xflags |=
 						XFS_DIFLAG_PROJINHERIT;
-					opts[OPT_D].subopt_params[D_PROJINHERIT].value =
-							fsx.fsx_projid;
 					break;
 				case D_EXTSZINHERIT:
 					fsx.fsx_extsize = getnum(value, &opts[OPT_D],
 								 D_EXTSZINHERIT);
 					fsx.fsx_xflags |=
 						XFS_DIFLAG_EXTSZINHERIT;
-					opts[OPT_D].subopt_params[D_EXTSZINHERIT].value =
-							fsx.fsx_extsize;
 					break;
 				default:
 					unknown('d', value);
@@ -2088,64 +2367,44 @@ main(
 					sb_feat.inode_align = getnum(value,
 								&opts[OPT_I],
 								I_ALIGN);
-					opts[OPT_I].subopt_params[I_ALIGN].value =
-							sb_feat.inode_align;
 					break;
 				case I_LOG:
 					inodelog = getnum(value, &opts[OPT_I],
 								I_LOG);
 					isize = 1 << inodelog;
 					ilflag = 1;
-					opts[OPT_I].subopt_params[I_SIZE].value =
-							isize;
-					opts[OPT_I].subopt_params[I_LOG].value =
-							inodelog;
 					break;
 				case I_MAXPCT:
 					imaxpct = getnum(value, &opts[OPT_I],
 							 I_MAXPCT);
 					imflag = 1;
-					opts[OPT_I].subopt_params[I_MAXPCT].value =
-							imaxpct;
 					break;
 				case I_PERBLOCK:
 					inopblock = getnum(value, &opts[OPT_I],
 							   I_PERBLOCK);
 					ipflag = 1;
-					opts[OPT_I].subopt_params[I_PERBLOCK].value =
-							inopblock;
 					break;
 				case I_SIZE:
 					isize = getnum(value, &opts[OPT_I],
 								I_SIZE);
 					inodelog = libxfs_highbit32(isize);
 					isflag = 1;
-					opts[OPT_I].subopt_params[I_SIZE].value =
-							isize;
-					opts[OPT_I].subopt_params[I_LOG].value =
-							inodelog;
 					break;
 				case I_ATTR:
 					sb_feat.attr_version =
 
 						getnum(value, &opts[OPT_I],
 								I_ATTR);
-					opts[OPT_I].subopt_params[I_ATTR].value =
-							sb_feat.attr_version;
 					break;
 				case I_PROJID32BIT:
 					sb_feat.projid16bit =
 						!getnum(value, &opts[OPT_I],
 							I_PROJID32BIT);
-					opts[OPT_I].subopt_params[I_PROJID32BIT].value =
-							sb_feat.projid16bit;
 					break;
 				case I_SPINODES:
 					sb_feat.spinodes = getnum(value,
 								&opts[OPT_I],
 								I_SPINODES);
-					opts[OPT_I].subopt_params[I_SPINODES].value =
-							sb_feat.spinodes;
 					break;
 				default:
 					unknown('i', value);
@@ -2163,34 +2422,24 @@ main(
 					logagno = getnum(value, &opts[OPT_L],
 								L_AGNUM);
 					laflag = 1;
-					opts[OPT_L].subopt_params[L_AGNUM].value =
-							logagno;
 					break;
 				case L_FILE:
 					xi.lisfile = getnum(value, &opts[OPT_L],
 							    L_FILE);
-					opts[OPT_L].subopt_params[L_FILE].value =
-							xi.lisfile;
 					break;
 				case L_INTERNAL:
 					loginternal = getnum(value, &opts[OPT_L],
 							     L_INTERNAL);
 					liflag = 1;
-					opts[OPT_L].subopt_params[L_INTERNAL].value =
-							loginternal;
 					break;
 				case L_SU:
 					lsu = getnum(value, &opts[OPT_L], L_SU);
 					lsuflag = 1;
-					opts[OPT_L].subopt_params[L_SU].value =
-							lsu;
 					break;
 				case L_SUNIT:
 					lsunit = getnum(value, &opts[OPT_L],
 								L_SUNIT);
 					lsunitflag = 1;
-					opts[OPT_L].subopt_params[L_SUNIT].value =
-							lsunit;
 					break;
 				case L_NAME:
 				case L_DEV:
@@ -2199,32 +2448,22 @@ main(
 					xi.logname = logfile;
 					ldflag = 1;
 					loginternal = 0;
-					opts[OPT_L].subopt_params[L_NAME].value = 1;
-					opts[OPT_L].subopt_params[L_DEV].value = 1;
 					break;
 				case L_VERSION:
 					sb_feat.log_version =
 						getnum(value, &opts[OPT_L],
 								L_VERSION);
 					lvflag = 1;
-					opts[OPT_L].subopt_params[L_VERSION].value =
-							sb_feat.log_version;
 					break;
 				case L_SIZE:
 					logbytes = getnum(value, &opts[OPT_L],
 								L_SIZE);
-					opts[OPT_L].subopt_params[L_SIZE].value =
-							logbytes;
 					break;
 				case L_SECTLOG:
 					lsectorlog = getnum(value, &opts[OPT_L],
 							    L_SECTLOG);
 					lsectorsize = 1 << lsectorlog;
 					lslflag = 1;
-					opts[OPT_L].subopt_params[L_SECTSIZE].value =
-							lsectorsize;
-					opts[OPT_L].subopt_params[L_SECTLOG].value =
-							lsectorlog;
 					break;
 				case L_SECTSIZE:
 					lsectorsize = getnum(value, &opts[OPT_L],
@@ -2232,17 +2471,11 @@ main(
 					lsectorlog =
 						libxfs_highbit32(lsectorsize);
 					lssflag = 1;
-					opts[OPT_L].subopt_params[L_SECTSIZE].value =
-							lsectorsize;
-					opts[OPT_L].subopt_params[L_SECTLOG].value =
-							lsectorlog;
 					break;
 				case L_LAZYSBCNTR:
 					sb_feat.lazy_sb_counters =
 							getnum(value, &opts[OPT_L],
 							       L_LAZYSBCNTR);
-					opts[OPT_L].subopt_params[L_LAZYSBCNTR].value =
-							sb_feat.lazy_sb_counters;
 					break;
 				default:
 					unknown('l', value);
@@ -2267,27 +2500,20 @@ main(
 								M_CRC);
 					if (sb_feat.crcs_enabled)
 						sb_feat.dirftype = true;
-					opts[OPT_M].subopt_params[M_CRC].value =
-							sb_feat.crcs_enabled;
 					break;
 				case M_FINOBT:
 					sb_feat.finobt = getnum(
 						value, &opts[OPT_M], M_FINOBT);
-					opts[OPT_M].subopt_params[M_FINOBT].value =
-							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");
-					opts[OPT_M].subopt_params[M_UUID].value = 1;
 					break;
 				case M_RMAPBT:
 					sb_feat.rmapbt = getnum(
 						value, &opts[OPT_M], M_RMAPBT);
-					opts[OPT_M].subopt_params[M_RMAPBT].value = 
-						sb_feat.rmapbt;
 					break;
 				case M_REFLINK:
 					sb_feat.reflink = getnum(
@@ -2310,10 +2536,6 @@ main(
 							     N_LOG);
 					dirblocksize = 1 << dirblocklog;
 					nlflag = 1;
-					opts[OPT_N].subopt_params[N_SIZE].value =
-							dirblocksize;
-					opts[OPT_N].subopt_params[N_LOG].value =
-							dirblocklog;
 					break;
 				case N_SIZE:
 					dirblocksize = getnum(value, &opts[OPT_N],
@@ -2321,10 +2543,6 @@ main(
 					dirblocklog =
 						libxfs_highbit32(dirblocksize);
 					nsflag = 1;
-					opts[OPT_N].subopt_params[N_SIZE].value =
-							dirblocksize;
-					opts[OPT_N].subopt_params[N_LOG].value =
-							dirblocklog;
 					break;
 				case N_VERSION:
 					value = getstr(value, &opts[OPT_N],
@@ -2338,14 +2556,10 @@ main(
 							       N_VERSION);
 					}
 					nvflag = 1;
-					opts[OPT_N].subopt_params[N_VERSION].value =
-							sb_feat.dir_version;
 					break;
 				case N_FTYPE:
 					sb_feat.dirftype = getnum(value, &opts[OPT_N],
 								  N_FTYPE);
-					opts[OPT_N].subopt_params[N_FTYPE].value =
-							sb_feat.dirftype;
 					break;
 				default:
 					unknown('n', value);
@@ -2376,33 +2590,23 @@ main(
 				case R_EXTSIZE:
 					rtextbytes = getnum(value, &opts[OPT_R],
 								R_EXTSIZE);
-					opts[OPT_R].subopt_params[R_EXTSIZE].value =
-							rtextbytes;
 					break;
 				case R_FILE:
 					xi.risfile = getnum(value, &opts[OPT_R],
 							    R_FILE);
-					opts[OPT_R].subopt_params[R_FILE].value =
-							xi.risfile;
 					break;
 				case R_NAME:
 				case R_DEV:
 					xi.rtname = getstr(value, &opts[OPT_R],
 							   R_NAME);
-					opts[OPT_R].subopt_params[R_NAME].value = 1;
-					opts[OPT_R].subopt_params[R_DEV].value = 1;
 					break;
 				case R_SIZE:
 					rtbytes = getnum(value, &opts[OPT_R],
 								R_SIZE);
-					opts[OPT_R].subopt_params[R_SIZE].value =
-							rtbytes;
 					break;
 				case R_NOALIGN:
 					norsflag = getnum(value, &opts[OPT_R],
 								R_NOALIGN);
-					opts[OPT_R].subopt_params[R_NOALIGN].value =
-							norsflag;
 					break;
 				default:
 					unknown('r', value);
@@ -2427,10 +2631,6 @@ main(
 					sectorsize = 1 << sectorlog;
 					lsectorsize = sectorsize;
 					lslflag = slflag = 1;
-					opts[OPT_S].subopt_params[S_LOG].value =
-							sectorsize;
-					opts[OPT_S].subopt_params[S_SECTLOG].value =
-							sectorsize;
 					break;
 				case S_SIZE:
 				case S_SECTSIZE:
@@ -2444,10 +2644,6 @@ main(
 						libxfs_highbit32(sectorsize);
 					lsectorlog = sectorlog;
 					lssflag = ssflag = 1;
-					opts[OPT_S].subopt_params[S_SIZE].value =
-							sectorlog;
-					opts[OPT_S].subopt_params[S_SECTSIZE].value =
-							sectorlog;
 					break;
 				default:
 					unknown('s', value);
-- 
2.8.1


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

* [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (15 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 16/22] mkfs: Change all value fields in opt structures into unions Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-13 17:43   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 18/22] mkfs: prevent sector/blocksize to be specified as a number of blocks Jan Tulak
                   ` (8 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

We need to have the values inside of the opts structure to validate it.
To avoid duplicity and to prevent issues with using a wrong type from
values union (e.g trating an int option as long long), keep the old
variables like agcount, dsunit, ... and just turn them into pointers
to the various opts fields.

However, at this moment, do not touch fields in other structures.
If some option saves the value into the xi or fsx structure, then
simply copy the value at the end of option parsing.

This might be changed in future if there is a nice way how to do it.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index afc63d1..d55eb9a 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -39,7 +39,7 @@ 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.
  */
-unsigned int		blocksize;
+unsigned int		*blocksize;
 unsigned int		sectorsize;
 
 #define MAX_OPTS	16
@@ -557,7 +557,7 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .minval.i = 0,
-			  .maxval.i = UINT_MAX,
+			  .maxval.i = INT_MAX,
 			  .needs_val = true,
 			  .type = INT,
 			},
@@ -573,7 +573,7 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .minval.i = 0,
-			  .maxval.i = UINT_MAX,
+			  .maxval.i = INT_MAX,
 			  .needs_val = true,
 			  .type = INT,
 			},
@@ -601,7 +601,7 @@ struct opt_params {
 					 {LAST_CONFLICT} },
 			  .convert = true,
 			  .minval.i = 0,
-			  .maxval.i = UINT_MAX,
+			  .maxval.i = INT_MAX,
 			  .needs_val = true,
 			  .type = INT,
 			},
@@ -617,7 +617,7 @@ struct opt_params {
 					 },
 					 {LAST_CONFLICT} },
 			  .minval.i = 0,
-			  .maxval.i = UINT_MAX,
+			  .maxval.i = INT_MAX,
 			  .needs_val = true,
 			  .type = INT,
 			},
@@ -853,6 +853,7 @@ struct opt_params {
 			  .maxval.i = 1,
 			  .flagval.i = 1,
 			  .type = INT,
+			  .value.i = 1,
 			},
 			{ .index = L_SIZE,
 			  .conflicts = { {LAST_CONFLICT} },
@@ -1345,7 +1346,7 @@ static void conflict_struct(struct opt_params 	*opt, struct subopt_param *subopt
 /*
  * 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) >> ((*blocklog) - BBSHIFT)))
 
 /*
  * Use this for block reservations needed for mkfs's conditions
@@ -1416,16 +1417,16 @@ calc_stripe_factors(
 		*lsunit = (int)BTOBBT(lsu);
 
 	/* verify if lsu/lsunit is a multiple block size */
-	if (lsu % blocksize != 0) {
+	if (lsu % *blocksize != 0) {
 		fprintf(stderr,
 _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
-		lsu, blocksize);
+		lsu, *blocksize);
 		exit(1);
 	}
-	if ((BBTOB(*lsunit) % blocksize != 0)) {
+	if ((BBTOB(*lsunit) % *blocksize != 0)) {
 		fprintf(stderr,
 _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
-		BBTOB(*lsunit), blocksize);
+		BBTOB(*lsunit), *blocksize);
 		exit(1);
 	}
 }
@@ -2003,6 +2004,10 @@ check_all_opts(struct opt_params *opts)
 	}
 }
 
+/* TODO we might loose some numbers here, if they are unsigned and bigger than
+ * long long max value. So it might be worth to transform this... (think
+ * __uint64_t)
+ */
 static long long
 getnum(
 	const char		*str,
@@ -2061,7 +2066,7 @@ getnum(
 	 * number.
 	 */
 	if (sp->convert)
-		c = cvtnum(blocksize, sectorsize, str);
+		c = cvtnum(*blocksize, sectorsize, str);
 	else {
 		char		*str_end;
 
@@ -2106,15 +2111,15 @@ main(
 	int			argc,
 	char			**argv)
 {
-	__uint64_t		agcount;
+	__uint64_t		*agcount;
 	xfs_agf_t		*agf;
 	xfs_agi_t		*agi;
 	xfs_agnumber_t		agno;
-	__uint64_t		agsize;
+	__uint64_t		*agsize;
 	xfs_alloc_rec_t		*arec;
 	struct xfs_btree_block	*block;
 	int			blflag;
-	int			blocklog;
+	int			*blocklog;
 	int			bsflag;
 	int			bsize;
 	xfs_buf_t		*buf;
@@ -2123,51 +2128,51 @@ main(
 	int			dasize;
 	xfs_rfsblock_t		dblocks;
 	char			*dfile;
-	int			dirblocklog;
-	int			dirblocksize;
-	__uint64_t 		dbytes;
-	int			dsu;
-	int			dsw;
-	int			dsunit;
-	int			dswidth;
+	int			*dirblocklog;
+	int			*dirblocksize;
+	__uint64_t 		*dbytes;
+	int			*dsu;
+	int			*dsw;
+	int			*dsunit;
+	int			*dswidth;
 	int			force_overwrite;
 	struct fsxattr		fsx;
 	int			ilflag;
-	int			imaxpct;
+	int			*imaxpct;
 	int			imflag;
-	int			inodelog;
-	int			inopblock;
+	int			*inodelog;
+	int			*inopblock;
 	int			ipflag;
 	int			isflag;
-	int			isize;
+	int			*isize;
 	char			*label = NULL;
 	int			laflag;
 	int			lalign;
 	int			ldflag;
 	int			liflag;
-	xfs_agnumber_t		logagno;
+	xfs_agnumber_t		*logagno;
 	xfs_rfsblock_t		logblocks;
 	char			*logfile;
-	int			loginternal;
-	__uint64_t 		logbytes;
+	int			*loginternal;
+	__uint64_t 		*logbytes;
 	xfs_fsblock_t		logstart;
 	int			lvflag;
 	int			lsflag;
 	int			lsuflag;
 	int			lsunitflag;
-	int			lsectorlog;
-	int			lsectorsize;
+	int			*lsectorlog;
+	int			*lsectorsize;
 	int			lslflag;
 	int			lssflag;
-	int			lsu;
-	int			lsunit;
+	int			*lsu;
+	int			*lsunit;
 	int			min_logblocks;
 	xfs_mount_t		*mp;
 	xfs_mount_t		mbuf;
 	xfs_extlen_t		nbmblocks;
 	int			nlflag;
-	int			nodsflag;
-	int			norsflag;
+	int			*nodsflag;
+	int			*norsflag;
 	xfs_alloc_rec_t		*nrec;
 	int			nsflag;
 	int			nvflag;
@@ -2178,10 +2183,10 @@ main(
 	char			*protostring;
 	int			qflag;
 	xfs_rfsblock_t		rtblocks;
-	__uint64_t 		rtbytes;
+	__uint64_t 		*rtbytes;
 	xfs_extlen_t		rtextblocks;
 	xfs_rtblock_t		rtextents;
-	__uint64_t 		rtextbytes;
+	__uint64_t 		*rtextbytes;
 	char			*rtfile;
 	xfs_sb_t		*sbp;
 	int			sectorlog;
@@ -2216,24 +2221,51 @@ main(
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
 
+
+	/*
+	 * Set up pointers, so we can use shorter names and to let gcc
+	 * check the correct type. We don't want to inadvertently use an int as
+	 * unsigned int and so on...
+	 */
+	agcount = &opts[OPT_D].subopt_params[D_AGCOUNT].value.uint64;
+	agsize = &opts[OPT_D].subopt_params[D_AGSIZE].value.uint64;
+	dbytes = &opts[OPT_D].subopt_params[D_SIZE].value.uint64;
+	dsunit = &opts[OPT_D].subopt_params[D_SUNIT].value.i;
+	dswidth = &opts[OPT_D].subopt_params[D_SWIDTH].value.i;
+	dsu = &opts[OPT_D].subopt_params[D_SU].value.i;
+	dsw = &opts[OPT_D].subopt_params[D_SW].value.i;
+	nodsflag = &opts[OPT_D].subopt_params[D_NOALIGN].value.i;
+	norsflag = &opts[OPT_R].subopt_params[R_NOALIGN].value.i;
+	logagno = &opts[OPT_L].subopt_params[L_AGNUM].value.u;
+	lsu = &opts[OPT_L].subopt_params[L_SU].value.i;
+	lsunit = &opts[OPT_L].subopt_params[L_SUNIT].value.i;
+	logbytes = &opts[OPT_L].subopt_params[L_SIZE].value.uint64;
+	imaxpct = &opts[OPT_I].subopt_params[I_MAXPCT].value.i;
+	inopblock = &opts[OPT_I].subopt_params[I_PERBLOCK].value.i;
+	dirblocksize = &opts[OPT_N].subopt_params[N_SIZE].value.i;
+	dirblocklog = &opts[OPT_N].subopt_params[N_LOG].value.i;
+	rtextbytes = &opts[OPT_R].subopt_params[R_EXTSIZE].value.uint64;
+	rtbytes = &opts[OPT_R].subopt_params[R_SIZE].value.uint64;
+	blocklog = &opts[OPT_B].subopt_params[B_LOG].value.i;
+	blocksize = &opts[OPT_B].subopt_params[B_SIZE].value.u;
+	isize = &opts[OPT_I].subopt_params[I_SIZE].value.i;
+	inodelog = &opts[OPT_I].subopt_params[I_LOG].value.i;
+	loginternal = &opts[OPT_L].subopt_params[L_INTERNAL].value.i;
+	lsectorsize = &opts[OPT_L].subopt_params[L_SECTSIZE].value.i;
+	lsectorlog = &opts[OPT_L].subopt_params[L_SECTLOG].value.i;
+
 	blflag = bsflag = slflag = ssflag = lslflag = lssflag = 0;
-	blocklog = blocksize = 0;
-	sectorlog = lsectorlog = 0;
-	sectorsize = lsectorsize = 0;
-	agsize = daflag = dasize = dblocks = 0;
+	sectorlog = 0;
+	sectorsize = 0;
+	daflag = dasize = dblocks = 0;
 	ilflag = imflag = ipflag = isflag = 0;
 	liflag = laflag = lsflag = lsuflag = lsunitflag = ldflag = lvflag = 0;
-	loginternal = 1;
-	logagno = logblocks = rtblocks = rtextblocks = 0;
+	logblocks = rtblocks = rtextblocks = 0;
 	Nflag = nlflag = nsflag = nvflag = 0;
-	dirblocklog = dirblocksize = 0;
 	qflag = 0;
-	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 = 0;
+	lalign = 0;
 	force_overwrite = 0;
 	worst_freelist = 0;
 	memset(&fsx, 0, sizeof(fsx));
@@ -2256,15 +2288,15 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case B_LOG:
-					blocklog = getnum(value, &opts[OPT_B],
+					*blocklog = getnum(value, &opts[OPT_B],
 								B_LOG);
-					blocksize = 1 << blocklog;
+					*blocksize = 1 << *blocklog;
 					blflag = 1;
 					break;
 				case B_SIZE:
-					blocksize = getnum(value, &opts[OPT_B],
+					*blocksize = getnum(value, &opts[OPT_B],
 							   B_SIZE);
-					blocklog = libxfs_highbit32(blocksize);
+					*blocklog = libxfs_highbit32(*blocksize);
 					bsflag = 1;
 					break;
 				default:
@@ -2280,12 +2312,12 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case D_AGCOUNT:
-					agcount = getnum(value, &opts[OPT_D],
+					*agcount = getnum(value, &opts[OPT_D],
 							 D_AGCOUNT);
 					daflag = 1;
 					break;
 				case D_AGSIZE:
-					agsize = getnum(value, &opts[OPT_D],
+					*agsize = getnum(value, &opts[OPT_D],
 								D_AGSIZE);
 					dasize = 1;
 					break;
@@ -2298,25 +2330,25 @@ main(
 								D_NAME);
 					break;
 				case D_SIZE:
-					dbytes = getnum(value, &opts[OPT_D],
+					*dbytes = getnum(value, &opts[OPT_D],
 								D_SIZE);
 					break;
 				case D_SUNIT:
-					dsunit = getnum(value, &opts[OPT_D],
+					*dsunit = getnum(value, &opts[OPT_D],
 								D_SUNIT);
 					break;
 				case D_SWIDTH:
-					dswidth = getnum(value, &opts[OPT_D],
+					*dswidth = getnum(value, &opts[OPT_D],
 							 D_SWIDTH);
 					break;
 				case D_SU:
-					dsu = getnum(value, &opts[OPT_D], D_SU);
+					*dsu = getnum(value, &opts[OPT_D], D_SU);
 					break;
 				case D_SW:
-					dsw = getnum(value, &opts[OPT_D], D_SW);
+					*dsw = getnum(value, &opts[OPT_D], D_SW);
 					break;
 				case D_NOALIGN:
-					nodsflag = getnum(value, &opts[OPT_D],
+					*nodsflag = getnum(value, &opts[OPT_D],
 								D_NOALIGN);
 					break;
 				case D_SECTLOG:
@@ -2338,6 +2370,7 @@ main(
 					if (c)
 						fsx.fsx_xflags |=
 							XFS_DIFLAG_RTINHERIT;
+					opts[OPT_D].subopt_params[D_RTINHERIT].value.u = c;
 					break;
 				case D_PROJINHERIT:
 					fsx.fsx_projid = getnum(value, &opts[OPT_D],
@@ -2369,25 +2402,25 @@ main(
 								I_ALIGN);
 					break;
 				case I_LOG:
-					inodelog = getnum(value, &opts[OPT_I],
+					*inodelog = getnum(value, &opts[OPT_I],
 								I_LOG);
-					isize = 1 << inodelog;
+					*isize = 1 << *inodelog;
 					ilflag = 1;
 					break;
 				case I_MAXPCT:
-					imaxpct = getnum(value, &opts[OPT_I],
+					*imaxpct = getnum(value, &opts[OPT_I],
 							 I_MAXPCT);
 					imflag = 1;
 					break;
 				case I_PERBLOCK:
-					inopblock = getnum(value, &opts[OPT_I],
+					*inopblock = getnum(value, &opts[OPT_I],
 							   I_PERBLOCK);
 					ipflag = 1;
 					break;
 				case I_SIZE:
-					isize = getnum(value, &opts[OPT_I],
+					*isize = getnum(value, &opts[OPT_I],
 								I_SIZE);
-					inodelog = libxfs_highbit32(isize);
+					*inodelog = libxfs_highbit32(*isize);
 					isflag = 1;
 					break;
 				case I_ATTR:
@@ -2419,7 +2452,7 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case L_AGNUM:
-					logagno = getnum(value, &opts[OPT_L],
+					*logagno = getnum(value, &opts[OPT_L],
 								L_AGNUM);
 					laflag = 1;
 					break;
@@ -2428,16 +2461,16 @@ main(
 							    L_FILE);
 					break;
 				case L_INTERNAL:
-					loginternal = getnum(value, &opts[OPT_L],
+					*loginternal = getnum(value, &opts[OPT_L],
 							     L_INTERNAL);
 					liflag = 1;
 					break;
 				case L_SU:
-					lsu = getnum(value, &opts[OPT_L], L_SU);
+					*lsu = getnum(value, &opts[OPT_L], L_SU);
 					lsuflag = 1;
 					break;
 				case L_SUNIT:
-					lsunit = getnum(value, &opts[OPT_L],
+					*lsunit = getnum(value, &opts[OPT_L],
 								L_SUNIT);
 					lsunitflag = 1;
 					break;
@@ -2447,7 +2480,7 @@ main(
 								L_NAME);
 					xi.logname = logfile;
 					ldflag = 1;
-					loginternal = 0;
+					*loginternal = 0;
 					break;
 				case L_VERSION:
 					sb_feat.log_version =
@@ -2456,20 +2489,20 @@ main(
 					lvflag = 1;
 					break;
 				case L_SIZE:
-					logbytes = getnum(value, &opts[OPT_L],
+					*logbytes = getnum(value, &opts[OPT_L],
 								L_SIZE);
 					break;
 				case L_SECTLOG:
-					lsectorlog = getnum(value, &opts[OPT_L],
+					*lsectorlog = getnum(value, &opts[OPT_L],
 							    L_SECTLOG);
-					lsectorsize = 1 << lsectorlog;
+					*lsectorsize = 1 << *lsectorlog;
 					lslflag = 1;
 					break;
 				case L_SECTSIZE:
-					lsectorsize = getnum(value, &opts[OPT_L],
+					*lsectorsize = getnum(value, &opts[OPT_L],
 							     L_SECTSIZE);
-					lsectorlog =
-						libxfs_highbit32(lsectorsize);
+					*lsectorlog =
+						libxfs_highbit32(*lsectorsize);
 					lssflag = 1;
 					break;
 				case L_LAZYSBCNTR:
@@ -2510,6 +2543,7 @@ main(
 						reqval('m', subopts, M_UUID);
 					if (platform_uuid_parse(value, &uuid))
 						illegal(optarg, "m uuid");
+					opts[OPT_M].subopt_params[M_UUID].value.s = value;
 					break;
 				case M_RMAPBT:
 					sb_feat.rmapbt = getnum(
@@ -2532,16 +2566,16 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case N_LOG:
-					dirblocklog = getnum(value, &opts[OPT_N],
+					*dirblocklog = getnum(value, &opts[OPT_N],
 							     N_LOG);
-					dirblocksize = 1 << dirblocklog;
+					*dirblocksize = 1 << *dirblocklog;
 					nlflag = 1;
 					break;
 				case N_SIZE:
-					dirblocksize = getnum(value, &opts[OPT_N],
+					*dirblocksize = getnum(value, &opts[OPT_N],
 							      N_SIZE);
-					dirblocklog =
-						libxfs_highbit32(dirblocksize);
+					*dirblocklog =
+						libxfs_highbit32(*dirblocksize);
 					nsflag = 1;
 					break;
 				case N_VERSION:
@@ -2588,7 +2622,7 @@ main(
 
 				switch (getsubopt(&p, subopts, &value)) {
 				case R_EXTSIZE:
-					rtextbytes = getnum(value, &opts[OPT_R],
+					*rtextbytes = getnum(value, &opts[OPT_R],
 								R_EXTSIZE);
 					break;
 				case R_FILE:
@@ -2601,11 +2635,11 @@ main(
 							   R_NAME);
 					break;
 				case R_SIZE:
-					rtbytes = getnum(value, &opts[OPT_R],
+					*rtbytes = getnum(value, &opts[OPT_R],
 								R_SIZE);
 					break;
 				case R_NOALIGN:
-					norsflag = getnum(value, &opts[OPT_R],
+					*norsflag = getnum(value, &opts[OPT_R],
 								R_NOALIGN);
 					break;
 				default:
@@ -2627,9 +2661,9 @@ main(
 							 S_SECTSIZE, S_SECTLOG);
 					sectorlog = getnum(value, &opts[OPT_S],
 							   S_SECTLOG);
-					lsectorlog = sectorlog;
+					*lsectorlog = sectorlog;
 					sectorsize = 1 << sectorlog;
-					lsectorsize = sectorsize;
+					*lsectorsize = sectorsize;
 					lslflag = slflag = 1;
 					break;
 				case S_SIZE:
@@ -2639,10 +2673,10 @@ main(
 							 S_SECTSIZE);
 					sectorsize = getnum(value, &opts[OPT_S],
 							    S_SECTSIZE);
-					lsectorsize = sectorsize;
+					*lsectorsize = sectorsize;
 					sectorlog =
 						libxfs_highbit32(sectorsize);
-					lsectorlog = sectorlog;
+					*lsectorlog = sectorlog;
 					lssflag = ssflag = 1;
 					break;
 				default:
@@ -2665,6 +2699,36 @@ main(
 	} else
 		dfile = xi.dname;
 
+	/*
+	 * Not every field could be connected with a pointer, so just copy
+	 * the values for a options check.
+	 */
+	opts[OPT_D].subopt_params[D_FILE].value.i  = xi.disfile;
+	opts[OPT_D].subopt_params[D_PROJINHERIT].value.u = fsx.fsx_projid;
+	opts[OPT_D].subopt_params[D_EXTSZINHERIT].value.u = fsx.fsx_extsize;
+	opts[OPT_L].subopt_params[L_FILE].value.i = xi.lisfile;
+	opts[OPT_L].subopt_params[L_VERSION].value.i = sb_feat.log_version;
+	opts[OPT_L].subopt_params[L_LAZYSBCNTR].value.b = sb_feat.lazy_sb_counters;
+	opts[OPT_I].subopt_params[I_ATTR].value.i = sb_feat.attr_version ;
+	opts[OPT_I].subopt_params[I_PROJID32BIT].value.b = !sb_feat.projid16bit ;
+	opts[OPT_I].subopt_params[I_SPINODES].value.i = sb_feat.spinodes ;
+	opts[OPT_M].subopt_params[M_FINOBT].value.i = sb_feat.finobt ;
+	opts[OPT_M].subopt_params[M_RMAPBT].value.b = sb_feat.rmapbt ;
+	opts[OPT_R].subopt_params[R_FILE].value.i = xi.risfile ;
+	opts[OPT_R].subopt_params[R_NAME].value.s = xi.rtname;
+	opts[OPT_R].subopt_params[R_DEV].value.s = xi.rtname;
+	opts[OPT_S].subopt_params[S_LOG].value.u = sectorsize;
+	opts[OPT_S].subopt_params[S_SECTLOG].value.u = sectorsize;
+	opts[OPT_D].subopt_params[D_NAME].value.s = xi.dname;
+	opts[OPT_D].subopt_params[D_SECTSIZE].value.u = sectorsize;
+	opts[OPT_D].subopt_params[D_SECTLOG].value.i = sectorlog;
+	opts[OPT_I].subopt_params[I_ALIGN].value.b = sb_feat.inode_align;
+	opts[OPT_L].subopt_params[L_NAME].value.s = xi.logname;
+	opts[OPT_L].subopt_params[L_DEV].value.s = xi.logname;
+	opts[OPT_M].subopt_params[M_CRC].value.b = sb_feat.crcs_enabled;
+	opts[OPT_N].subopt_params[N_VERSION].value.i = sb_feat.dir_version;
+	opts[OPT_N].subopt_params[N_FTYPE].value.b = sb_feat.dirftype;
+
 	check_all_opts(opts);
 
 	/*
@@ -2673,14 +2737,14 @@ main(
 	 * 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;
+		*blocklog = XFS_DFL_BLOCKSIZE_LOG;
+		*blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG;
 	}
-	if (blocksize < XFS_MIN_BLOCKSIZE || blocksize > XFS_MAX_BLOCKSIZE) {
-		fprintf(stderr, _("illegal block size %d\n"), blocksize);
+	if (*blocksize < XFS_MIN_BLOCKSIZE || *blocksize > XFS_MAX_BLOCKSIZE) {
+		fprintf(stderr, _("illegal block size %d\n"), *blocksize);
 		usage();
 	}
-	if (sb_feat.crcs_enabled && blocksize < XFS_MIN_CRC_BLOCKSIZE) {
+	if (sb_feat.crcs_enabled && *blocksize < XFS_MIN_CRC_BLOCKSIZE) {
 		fprintf(stderr,
 _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 			XFS_MIN_CRC_BLOCKSIZE);
@@ -2701,8 +2765,8 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 		sectorsize = XFS_MIN_SECTORSIZE;
 	}
 	if (!lslflag && !lssflag) {
-		lsectorlog = sectorlog;
-		lsectorsize = sectorsize;
+		*lsectorlog = sectorlog;
+		*lsectorsize = sectorsize;
 	}
 
 	/*
@@ -2712,14 +2776,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, !dbytes, !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, !logbytes, !xi.logname,
+	if (!*loginternal)
+		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, !rtbytes, !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)
@@ -2744,10 +2808,10 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
 		sectorsize = ft.psectorsize ? ft.psectorsize :
 					      XFS_MIN_SECTORSIZE;
 
-		if ((blocksize < sectorsize) && (blocksize >= ft.lsectorsize)) {
+		if ((*blocksize < sectorsize) && (*blocksize >= ft.lsectorsize)) {
 			fprintf(stderr,
 _("specified blocksize %d is less than device physical sector size %d\n"),
-				blocksize, ft.psectorsize);
+				*blocksize, ft.psectorsize);
 			fprintf(stderr,
 _("switching to logical sector size %d\n"),
 				ft.lsectorsize);
@@ -2758,20 +2822,20 @@ _("switching to logical sector size %d\n"),
 
 	if (!ssflag) {
 		sectorlog = libxfs_highbit32(sectorsize);
-		if (loginternal) {
-			lsectorsize = sectorsize;
-			lsectorlog = sectorlog;
+		if (*loginternal) {
+			*lsectorsize = sectorsize;
+			*lsectorlog = sectorlog;
 		}
 	}
 
 	if (sectorsize < XFS_MIN_SECTORSIZE ||
-	    sectorsize > XFS_MAX_SECTORSIZE || sectorsize > blocksize) {
+	    sectorsize > XFS_MAX_SECTORSIZE || sectorsize > *blocksize) {
 		if (ssflag)
 			fprintf(stderr, _("illegal sector size %d\n"), sectorsize);
 		else
 			fprintf(stderr,
 _("block size %d cannot be smaller than logical sector size %d\n"),
-				blocksize, ft.lsectorsize);
+				*blocksize, ft.lsectorsize);
 		usage();
 	}
 	if (sectorsize < ft.lsectorsize) {
@@ -2779,12 +2843,12 @@ _("block size %d cannot be smaller than logical sector size %d\n"),
 			sectorsize, ft.lsectorsize);
 		usage();
 	}
-	if (lsectorsize < XFS_MIN_SECTORSIZE ||
-	    lsectorsize > XFS_MAX_SECTORSIZE || lsectorsize > blocksize) {
-		fprintf(stderr, _("illegal log sector size %d\n"), lsectorsize);
+	if (*lsectorsize < XFS_MIN_SECTORSIZE ||
+	    *lsectorsize > XFS_MAX_SECTORSIZE || *lsectorsize > *blocksize) {
+		fprintf(stderr, _("illegal log sector size %d\n"), *lsectorsize);
 		usage();
-	} else if (lsectorsize > XFS_MIN_SECTORSIZE && !lsu && !lsunit) {
-		lsu = blocksize;
+	} else if (*lsectorsize > XFS_MIN_SECTORSIZE && !*lsu && !*lsunit) {
+		*lsu = *blocksize;
 		sb_feat.log_version = 2;
 	}
 
@@ -2795,7 +2859,7 @@ _("block size %d 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) && *inodelog < XFS_DINODE_DFL_CRC_LOG) {
 			fprintf(stderr,
 _("Minimum inode size for CRCs is %d bytes\n"),
 				1 << XFS_DINODE_DFL_CRC_LOG);
@@ -2819,89 +2883,89 @@ _("Minimum inode size for CRCs is %d bytes\n"),
 	}
 
 	if (nsflag || nlflag) {
-		if (dirblocksize < blocksize ||
-					dirblocksize > XFS_MAX_BLOCKSIZE) {
+		if (*dirblocksize < *blocksize ||
+					*dirblocksize > XFS_MAX_BLOCKSIZE) {
 			fprintf(stderr, _("illegal directory block size %d\n"),
-				dirblocksize);
+				*dirblocksize);
 			usage();
 		}
 	} else {
-		if (blocksize < (1 << XFS_MIN_REC_DIRSIZE))
-			dirblocklog = XFS_MIN_REC_DIRSIZE;
+		if (*blocksize < (1 << XFS_MIN_REC_DIRSIZE))
+			*dirblocklog = XFS_MIN_REC_DIRSIZE;
 		else
-			dirblocklog = blocklog;
-		dirblocksize = 1 << dirblocklog;
+			*dirblocklog = *blocklog;
+		*dirblocksize = 1 << *dirblocklog;
 	}
 
 
-	if (dbytes) {
-		if (dbytes % XFS_MIN_BLOCKSIZE) {
+	if (*dbytes) {
+		if (*dbytes % XFS_MIN_BLOCKSIZE) {
 			fprintf(stderr,
 			_("illegal data length %lld, not a multiple of %d\n"),
-				(long long)dbytes, XFS_MIN_BLOCKSIZE);
+				(long long)*dbytes, XFS_MIN_BLOCKSIZE);
 			usage();
 		}
-		dblocks = (xfs_rfsblock_t)(dbytes >> blocklog);
-		if (dbytes % blocksize)
+		dblocks = (xfs_rfsblock_t)(*dbytes >> *blocklog);
+		if (*dbytes % *blocksize)
 			fprintf(stderr, _("warning: "
 	"data length %lld not a multiple of %d, truncated to %lld\n"),
-				(long long)dbytes, blocksize,
-				(long long)(dblocks << blocklog));
+				(long long)*dbytes, *blocksize,
+				(long long)(dblocks << *blocklog));
 	}
 	if (ipflag) {
-		inodelog = blocklog - libxfs_highbit32(inopblock);
-		isize = 1 << inodelog;
+		*inodelog = *blocklog - libxfs_highbit32(*inopblock);
+		*isize = 1 << *inodelog;
 	} else if (!ilflag && !isflag) {
-		inodelog = sb_feat.crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
+		*inodelog = sb_feat.crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
 						: XFS_DINODE_DFL_LOG;
-		isize = 1 << inodelog;
+		*isize = 1 << *inodelog;
 	}
-	if (sb_feat.crcs_enabled && inodelog < XFS_DINODE_DFL_CRC_LOG) {
+	if (sb_feat.crcs_enabled && *inodelog < XFS_DINODE_DFL_CRC_LOG) {
 		fprintf(stderr,
 		_("Minimum inode size for CRCs is %d bytes\n"),
 			1 << XFS_DINODE_DFL_CRC_LOG);
 		usage();
 	}
 
-	if (logbytes) {
-		if (logbytes % XFS_MIN_BLOCKSIZE) {
+	if (*logbytes) {
+		if (*logbytes % XFS_MIN_BLOCKSIZE) {
 			fprintf(stderr,
 			_("illegal log length %lld, not a multiple of %d\n"),
-				(long long)logbytes, XFS_MIN_BLOCKSIZE);
+				(long long)*logbytes, XFS_MIN_BLOCKSIZE);
 			usage();
 		}
-		logblocks = (xfs_rfsblock_t)(logbytes >> blocklog);
-		if (logbytes % blocksize)
+		logblocks = (xfs_rfsblock_t)(*logbytes >> *blocklog);
+		if (*logbytes % *blocksize)
 			fprintf(stderr,
 	_("warning: log length %lld not a multiple of %d, truncated to %lld\n"),
-				(long long)logbytes, blocksize,
-				(long long)(logblocks << blocklog));
+				(long long)*logbytes, *blocksize,
+				(long long)(logblocks << *blocklog));
 	}
-	if (rtbytes) {
-		if (rtbytes % XFS_MIN_BLOCKSIZE) {
+	if (*rtbytes) {
+		if (*rtbytes % XFS_MIN_BLOCKSIZE) {
 			fprintf(stderr,
 			_("illegal rt length %lld, not a multiple of %d\n"),
-				(long long)rtbytes, XFS_MIN_BLOCKSIZE);
+				(long long)*rtbytes, XFS_MIN_BLOCKSIZE);
 			usage();
 		}
-		rtblocks = (xfs_rfsblock_t)(rtbytes >> blocklog);
-		if (rtbytes % blocksize)
+		rtblocks = (xfs_rfsblock_t)(*rtbytes >> *blocklog);
+		if (*rtbytes % *blocksize)
 			fprintf(stderr,
 	_("warning: rt length %lld not a multiple of %d, truncated to %lld\n"),
-				(long long)rtbytes, blocksize,
-				(long long)(rtblocks << blocklog));
+				(long long)*rtbytes, *blocksize,
+				(long long)(rtblocks << *blocklog));
 	}
 	/*
 	 * If specified, check rt extent size against its constraints.
 	 */
-	if (rtextbytes) {
-		if (rtextbytes % blocksize) {
+	if (*rtextbytes) {
+		if (*rtextbytes % *blocksize) {
 			fprintf(stderr,
 		_("illegal rt extent size %lld, not a multiple of %d\n"),
-				(long long)rtextbytes, blocksize);
+				(long long)*rtextbytes, *blocksize);
 			usage();
 		}
-		rtextblocks = (xfs_extlen_t)(rtextbytes >> blocklog);
+		rtextblocks = (xfs_extlen_t)(*rtextbytes >> *blocklog);
 	} else {
 		/*
 		 * If realtime extsize has not been specified by the user,
@@ -2911,23 +2975,23 @@ _("Minimum inode size for CRCs is %d bytes\n"),
 		__uint64_t	rswidth;
 		__uint64_t	rtextbytes;
 
-		if (!norsflag && !xi.risfile && !(!rtbytes && xi.disfile))
+		if (!*norsflag && !xi.risfile && !(!*rtbytes && xi.disfile))
 			rswidth = ft.rtswidth;
 		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 *blocksize */
+		if (!*norsflag && rswidth && !(BBTOB(rswidth) % *blocksize)) {
 			rswidth = DTOBT(rswidth);
-			rtextbytes = rswidth << blocklog;
+			rtextbytes = rswidth << *blocklog;
 			if (XFS_MIN_RTEXTSIZE <= rtextbytes &&
 			    (rtextbytes <= XFS_MAX_RTEXTSIZE)) {
 				rtextblocks = rswidth;
 			}
 		}
 		if (!rtextblocks) {
-			rtextblocks = (blocksize < XFS_MIN_RTEXTSIZE) ?
-					XFS_MIN_RTEXTSIZE >> blocklog : 1;
+			rtextblocks = (*blocksize < XFS_MIN_RTEXTSIZE) ?
+					XFS_MIN_RTEXTSIZE >> *blocklog : 1;
 		}
 	}
 	ASSERT(rtextblocks);
@@ -2935,34 +2999,34 @@ _("Minimum inode size for CRCs is %d bytes\n"),
 	/*
 	 * Check some argument sizes against mins, maxes.
 	 */
-	if (isize > blocksize / XFS_MIN_INODE_PERBLOCK ||
-	    isize < XFS_DINODE_MIN_SIZE ||
-	    isize > XFS_DINODE_MAX_SIZE) {
+	if (*isize > *blocksize / XFS_MIN_INODE_PERBLOCK ||
+	    *isize < XFS_DINODE_MIN_SIZE ||
+	    *isize > XFS_DINODE_MAX_SIZE) {
 		int	maxsz;
 
-		fprintf(stderr, _("illegal inode size %d\n"), isize);
-		maxsz = MIN(blocksize / XFS_MIN_INODE_PERBLOCK,
+		fprintf(stderr, _("illegal inode size %d\n"), *isize);
+		maxsz = MIN(*blocksize / XFS_MIN_INODE_PERBLOCK,
 			    XFS_DINODE_MAX_SIZE);
 		if (XFS_DINODE_MIN_SIZE == maxsz)
 			fprintf(stderr,
 			_("allowable inode size with %d byte blocks is %d\n"),
-				blocksize, XFS_DINODE_MIN_SIZE);
+				*blocksize, XFS_DINODE_MIN_SIZE);
 		else
 			fprintf(stderr,
 	_("allowable inode size with %d byte blocks is between %d and %d\n"),
-				blocksize, XFS_DINODE_MIN_SIZE, maxsz);
+				*blocksize, XFS_DINODE_MIN_SIZE, maxsz);
 		exit(1);
 	}
 
-	/* if lsu or lsunit was specified, automatically use v2 logs */
-	if ((lsu || lsunit) && sb_feat.log_version == 1) {
+	/* if *lsu or *lsunit was specified, automatically use v2 logs */
+	if ((*lsu || *lsunit) && sb_feat.log_version == 1) {
 		fprintf(stderr,
 			_("log stripe unit specified, using v2 logs\n"));
 		sb_feat.log_version = 2;
 	}
 
-	calc_stripe_factors(dsu, dsw, sectorsize, lsu, lsectorsize,
-				&dsunit, &dswidth, &lsunit);
+	calc_stripe_factors(*dsu, *dsw, sectorsize, *lsu, *lsectorsize,
+				dsunit, dswidth, lsunit);
 
 	xi.setblksize = sectorsize;
 
@@ -2990,7 +3054,7 @@ _("Minimum inode size for CRCs is %d bytes\n"),
 	sector_mask = (__uint64_t)-1 << (MAX(sectorlog, 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(*lsectorlog, 10) - BBSHIFT);
 
 
 	/* don't do discards on print-only runs or on files */
@@ -3004,10 +3068,10 @@ _("Minimum inode size for CRCs is %d bytes\n"),
 	}
 
 	if (!liflag && !ldflag)
-		loginternal = xi.logdev == 0;
+		*loginternal = xi.logdev == 0;
 	if (xi.logname)
 		logfile = xi.logname;
-	else if (loginternal)
+	else if (*loginternal)
 		logfile = _("internal log");
 	else if (xi.volname && xi.logdev)
 		logfile = _("volume log");
@@ -3022,15 +3086,15 @@ _("Minimum inode size for CRCs is %d bytes\n"),
 		rtfile = _("volume rt");
 	else if (!xi.rtdev)
 		rtfile = _("none");
-	if (dbytes && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
+	if (*dbytes && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
 		fprintf(stderr,
 			_("size %lld specified for data subvolume is too large, "
 			"maximum is %lld blocks\n"),
-			(long long)dbytes, (long long)DTOBT(xi.dsize));
+			(long long)*dbytes, (long long)DTOBT(xi.dsize));
 		usage();
-	} else if (!dbytes && xi.dsize > 0)
+	} else if (!*dbytes && xi.dsize > 0)
 		dblocks = DTOBT(xi.dsize);
-	else if (!dbytes) {
+	else if (!*dbytes) {
 		fprintf(stderr, _("can't get size of data subvolume\n"));
 		usage();
 	}
@@ -3041,11 +3105,11 @@ _("Minimum inode size for CRCs is %d bytes\n"),
 		usage();
 	}
 
-	if (loginternal && xi.logdev) {
+	if (*loginternal && xi.logdev) {
 		fprintf(stderr,
 			_("can't have both external and internal logs\n"));
 		usage();
-	} else if (loginternal && sectorsize != lsectorsize) {
+	} else if (*loginternal && sectorsize != *lsectorsize) {
 		fprintf(stderr,
 	_("data and log sector sizes must be equal for internal logs\n"));
 		usage();
@@ -3057,147 +3121,147 @@ _("Minimum inode size for CRCs is %d bytes\n"),
 reported by the device (%u).\n"),
 			sectorsize, xi.dbsize);
 	}
-	if (!loginternal && xi.lbsize > lsectorsize) {
+	if (!*loginternal && xi.lbsize > *lsectorsize) {
 		fprintf(stderr, _(
 "Warning: the log subvolume sector size %u is less than the sector size\n\
 reported by the device (%u).\n"),
-			lsectorsize, xi.lbsize);
+			*lsectorsize, xi.lbsize);
 	}
-	if (rtbytes && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
+	if (*rtbytes && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
 		fprintf(stderr, _(
 "Warning: the realtime subvolume sector size %u is less than the sector size\n\
 reported by the device (%u).\n"),
 			sectorsize, xi.rtbsize);
 	}
 
-	if (rtbytes && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
+	if (*rtbytes && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
 		fprintf(stderr,
 			_("size %lld specified for rt subvolume is too large, "
 			"maximum is %lld blocks\n"),
-			(long long)rtbytes, (long long)DTOBT(xi.rtsize));
+			(long long)*rtbytes, (long long)DTOBT(xi.rtsize));
 		usage();
-	} else if (!rtbytes && xi.rtsize > 0)
+	} else if (!*rtbytes && xi.rtsize > 0)
 		rtblocks = DTOBT(xi.rtsize);
-	else if (rtbytes && !xi.rtdev) {
+	else if (*rtbytes && !xi.rtdev) {
 		fprintf(stderr,
 			_("size specified for non-existent rt subvolume\n"));
 		usage();
 	}
 	if (xi.rtdev) {
 		rtextents = rtblocks / rtextblocks;
-		nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY * blocksize);
+		nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY * *blocksize);
 	} else {
 		rtextents = rtblocks = 0;
 		nbmblocks = 0;
 	}
 
-	if (!nodsflag) {
-		if (dsunit) {
-			if (ft.dsunit && ft.dsunit != dsunit) {
+	if (!*nodsflag) {
+		if (*dsunit) {
+			if (ft.dsunit && ft.dsunit != *dsunit) {
 				fprintf(stderr,
 					_("%s: Specified data stripe unit %d "
 					"is not the same as the volume stripe "
 					"unit %d\n"),
-					progname, dsunit, ft.dsunit);
+					progname, *dsunit, ft.dsunit);
 			}
-			if (ft.dswidth && ft.dswidth != dswidth) {
+			if (ft.dswidth && ft.dswidth != *dswidth) {
 				fprintf(stderr,
 					_("%s: Specified data stripe width %d "
 					"is not the same as the volume stripe "
 					"width %d\n"),
-					progname, dswidth, ft.dswidth);
+					progname, *dswidth, ft.dswidth);
 			}
 		} else {
-			dsunit = ft.dsunit;
-			dswidth = ft.dswidth;
-			nodsflag = 1;
+			*dsunit = ft.dsunit;
+			*dswidth = ft.dswidth;
+			*nodsflag = 1;
 		}
-	} /* else dsunit & dswidth can't be set if nodsflag is set */
+	} /* else *dsunit & *dswidth can't be set if *nodsflag is set */
 
 	if (dasize) {		/* User-specified AG size */
 		/*
-		 * Check specified agsize is a multiple of blocksize.
+		 * Check specified agsize is a multiple of *blocksize.
 		 */
-		if (agsize % blocksize) {
+		if (*agsize % *blocksize) {
 			fprintf(stderr,
 		_("agsize (%lld) not a multiple of fs blk size (%d)\n"),
-				(long long)agsize, blocksize);
+				(long long)*agsize, *blocksize);
 			usage();
 		}
-		agsize /= blocksize;
-		agcount = dblocks / agsize + (dblocks % agsize != 0);
+		*agsize /= *blocksize;
+		*agcount = dblocks / *agsize + (dblocks % *agsize != 0);
 
 	} else if (daflag) {	/* User-specified AG count */
-		agsize = dblocks / agcount + (dblocks % agcount != 0);
+		*agsize = dblocks / *agcount + (dblocks % *agcount != 0);
 	} else {
-		calc_default_ag_geometry(blocklog, dblocks,
-				dsunit | dswidth, &agsize, &agcount);
+		calc_default_ag_geometry(*blocklog, dblocks,
+				*dsunit | *dswidth, agsize, agcount);
 	}
 
 	/*
-	 * If dsunit is a multiple of fs blocksize, then check that is a
+	 * If *dsunit is a multiple of fs *blocksize, then check that is a
 	 * multiple of the agsize too
 	 */
-	if (dsunit && !(BBTOB(dsunit) % blocksize) &&
-	    dswidth && !(BBTOB(dswidth) % blocksize)) {
+	if (*dsunit && !(BBTOB(*dsunit) % *blocksize) &&
+	    *dswidth && !(BBTOB(*dswidth) % *blocksize)) {
 
-		/* convert from 512 byte blocks to fs blocksize */
-		dsunit = DTOBT(dsunit);
-		dswidth = DTOBT(dswidth);
+		/* convert from 512 byte blocks to fs *blocksize */
+		*dsunit = DTOBT(*dsunit);
+		*dswidth = DTOBT(*dswidth);
 
 		/*
-		 * agsize is not a multiple of dsunit
+		 * agsize is not a multiple of *dsunit
 		 */
-		if ((agsize % dsunit) != 0) {
+		if ((*agsize % *dsunit) != 0) {
 			/*
 			 * Round up to stripe unit boundary. Also make sure
 			 * that agsize is still larger than
-			 * XFS_AG_MIN_BLOCKS(blocklog)
+			 * XFS_AG_MIN_BLOCKS(*blocklog)
 		 	 */
-			tmp_agsize = ((agsize + (dsunit - 1))/ dsunit) * dsunit;
+			tmp_agsize = ((*agsize + (*dsunit - 1))/ *dsunit) * *dsunit;
 			/*
 			 * 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_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_MIN_BLOCKS(*blocklog)) &&
+			    (tmp_agsize <= XFS_AG_MAX_BLOCKS(*blocklog))) {
+				*agsize = tmp_agsize;
 				if (!daflag)
-					agcount = dblocks/agsize +
-						(dblocks % agsize != 0);
+					*agcount = dblocks/ *agsize +
+						(dblocks % *agsize != 0);
 				if (dasize)
 					fprintf(stderr,
 				_("agsize rounded to %lld, swidth = %d\n"),
-						(long long)agsize, dswidth);
+						(long long)*agsize, *dswidth);
 			} else {
-				if (nodsflag) {
-					dsunit = dswidth = 0;
+				if (*nodsflag) {
+					*dsunit = *dswidth = 0;
 				} else {
 					/*
 					 * agsize is out of bounds, this will
 					 * print nice details & exit.
 					 */
-					validate_ag_geometry(blocklog, dblocks,
-							    agsize, agcount);
+					validate_ag_geometry(*blocklog, dblocks,
+							    *agsize, *agcount);
 					exit(1);
 				}
 			}
 		}
-		if (dswidth && ((agsize % dswidth) == 0) && (agcount > 1)) {
+		if (*dswidth && ((*agsize % *dswidth) == 0) && (*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 = *agsize - *dsunit;
+			if (tmp_agsize < XFS_AG_MIN_BLOCKS(*blocklog)) {
+				tmp_agsize = *agsize + *dsunit;
+				if (dblocks < *agsize) {
 					/* oh well, nothing to do */
-					tmp_agsize = agsize;
+					tmp_agsize = *agsize;
 				}
 			}
 			if (daflag || dasize) {
@@ -3207,30 +3271,30 @@ 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 %llu.\n"),
 					(unsigned long long)tmp_agsize);
 			} else {
-				agsize = tmp_agsize;
-				agcount = dblocks/agsize + (dblocks % agsize != 0);
+				*agsize = tmp_agsize;
+				*agcount = dblocks/ *agsize + (dblocks % *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 % *agsize != 0 &&
+				    (dblocks % *agsize <
+				    XFS_AG_MIN_BLOCKS(*blocklog))) {
+					dblocks = (xfs_rfsblock_t)((*agcount - 1) * *agsize);
+					(*agcount)--;
+					ASSERT(*agcount != 0);
 				}
 			}
 		}
 	} else {
-		if (nodsflag)
-			dsunit = dswidth = 0;
+		if (*nodsflag)
+			*dsunit = *dswidth = 0;
 		else {
 			fprintf(stderr,
 				_("%s: Stripe unit(%d) or stripe width(%d) is "
 				"not a multiple of the block size(%d)\n"),
-				progname, BBTOB(dsunit), BBTOB(dswidth),
-				blocksize);
+				progname, BBTOB(*dsunit), BBTOB(*dswidth),
+				*blocksize);
 			exit(1);
 		}
 	}
@@ -3239,82 +3303,83 @@ an AG size that is one stripe unit smaller, for example %llu.\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 % *agsize != 0 &&
+	     (dblocks % *agsize < XFS_AG_MIN_BLOCKS(*blocklog))) {
 		ASSERT(!daflag);
-		dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
-		agcount--;
-		ASSERT(agcount != 0);
+		dblocks = (xfs_rfsblock_t)((*agcount - 1) * *agsize);
+		(*agcount)--;
+		ASSERT(*agcount != 0);
 	}
 
-	validate_ag_geometry(blocklog, dblocks, agsize, agcount);
+	validate_ag_geometry(*blocklog, dblocks, *agsize, *agcount);
 
 	if (!imflag)
-		imaxpct = calc_default_imaxpct(blocklog, dblocks);
+		*imaxpct = calc_default_imaxpct(*blocklog, dblocks);
 
 	/*
-	 * check that log sunit is modulo fsblksize or default it to dsunit.
+	 * check that log sunit is modulo fsblksize or default it to *dsunit.
 	 */
 
-	if (lsunit) {
+	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;
+		*lsunit = DTOBT(*lsunit);
+	} else if (sb_feat.log_version == 2 && *loginternal && *dsunit) {
+		/* *lsunit and *dsunit now in fs blocks */
+		*lsunit = *dsunit;
 	}
 
-	if (sb_feat.log_version == 2 && (lsunit * blocksize) > 256 * 1024) {
+	if (sb_feat.log_version == 2 && (*lsunit * *blocksize) > 256 * 1024) {
 		/* Warn only if specified on commandline */
 		if (lsuflag || lsunitflag) {
 			fprintf(stderr,
 	_("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n"),
-				(lsunit * blocksize));
+				(*lsunit * *blocksize));
 			fprintf(stderr,
 	_("log stripe unit adjusted to 32KiB\n"));
 		}
-		lsunit = (32 * 1024) >> blocklog;
+		*lsunit = (32 * 1024) >> *blocklog;
 	}
 
-	min_logblocks = max_trans_res(agsize,
+	min_logblocks = max_trans_res(*agsize,
 				   sb_feat.crcs_enabled, sb_feat.dir_version,
-				   sectorlog, blocklog, inodelog, dirblocklog,
-				   sb_feat.log_version, lsunit, sb_feat.finobt,
+				   sectorlog, *blocklog, *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 && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
+	if (!*logbytes && dblocks >= (1024*1024*1024) >> *blocklog)
+		min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>*blocklog);
+	if (*logbytes && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
 		fprintf(stderr,
 _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"),
-			(long long)logbytes, (long long)DTOBT(xi.logBBsize));
+			(long long)*logbytes, (long long)DTOBT(xi.logBBsize));
 		usage();
-	} else if (!logbytes && xi.logBBsize > 0) {
+	} else if (!*logbytes && xi.logBBsize > 0) {
 		logblocks = DTOBT(xi.logBBsize);
-	} else if (logbytes && !xi.logdev && !loginternal) {
+	} else if (*logbytes && !xi.logdev && !*loginternal) {
 		fprintf(stderr,
 			_("size specified for non-existent log subvolume\n"));
 		usage();
-	} else if (loginternal && logbytes && logblocks >= dblocks) {
+	} else if (*loginternal && *logbytes && logblocks >= dblocks) {
 		fprintf(stderr, _("size %lld too large for internal log\n"),
 			(long long)logblocks);
 		usage();
-	} else if (!loginternal && !xi.logdev) {
+	} else if (!*loginternal && !xi.logdev) {
 		logblocks = 0;
-	} else if (loginternal && !logbytes) {
+	} else if (*loginternal && !*logbytes) {
 
-		if (dblocks < GIGABYTES(1, blocklog)) {
+		if (dblocks < GIGABYTES(1, *blocklog)) {
 			/* tiny filesystems get minimum sized logs. */
 			logblocks = min_logblocks;
-		} else if (dblocks < GIGABYTES(16, blocklog)) {
+		} else if (dblocks < GIGABYTES(16, *blocklog)) {
 
 			/*
 			 * 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 >> *blocklog,
 					min_logblocks * XFS_DFL_LOG_FACTOR);
 		} else {
 			/*
@@ -3323,34 +3388,34 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 			 * 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 << *blocklog) / 2048;
+			logblocks = logblocks >> *blocklog;
 		}
 
 		/* 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 >= *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 << *blocklog) > XFS_MAX_LOG_BYTES)
+			logblocks = XFS_MAX_LOG_BYTES >> *blocklog;
 
 	}
-	validate_log_size(logblocks, blocklog, min_logblocks);
+	validate_log_size(logblocks, *blocklog, min_logblocks);
 
 	protostring = setup_proto(protofile);
-	bsize = 1 << (blocklog - BBSHIFT);
+	bsize = 1 << (*blocklog - BBSHIFT);
 	mp = &mbuf;
 	sbp = &mp->m_sb;
 	memset(mp, 0, sizeof(xfs_mount_t));
-	sbp->sb_blocklog = (__uint8_t)blocklog;
+	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_agblklog = (__uint8_t)libxfs_log2_roundup((unsigned int)*agsize);
+	sbp->sb_agblocks = (xfs_agblock_t)*agsize;
 	mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
 	mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
 
@@ -3358,22 +3423,22 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 	 * 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, sectorsize, *lsectorsize, *dsunit);
 
 
-	if (loginternal) {
+	if (*loginternal) {
 		/*
 		 * Readjust the log size to fit within an AG if it was sized
 		 * automatically.
 		 */
-		if (!logbytes) {
+		if (!*logbytes) {
 			logblocks = MIN(logblocks,
 					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, *blocklog, min_logblocks);
 		}
-		if (logblocks > agsize - libxfs_prealloc_blocks(mp)) {
+		if (logblocks > *agsize - libxfs_prealloc_blocks(mp)) {
 			fprintf(stderr,
 	_("internal log size %lld too large, must fit in allocation group\n"),
 				(long long)logblocks);
@@ -3381,35 +3446,35 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 		}
 
 		if (laflag) {
-			if (logagno >= agcount) {
+			if (*logagno >= *agcount) {
 				fprintf(stderr,
 		_("log ag number %d too large, must be less than %lld\n"),
-					logagno, (long long)agcount);
+					*logagno, (long long)*agcount);
 				usage();
 			}
 		} else
-			logagno = (xfs_agnumber_t)(agcount / 2);
+			*logagno = (xfs_agnumber_t)(*agcount / 2);
 
-		logstart = XFS_AGB_TO_FSB(mp, logagno, libxfs_prealloc_blocks(mp));
+		logstart = XFS_AGB_TO_FSB(mp, *logagno, libxfs_prealloc_blocks(mp));
 		/*
 		 * Align the logstart at stripe unit boundary.
 		 */
-		if (lsunit) {
+		if (*lsunit) {
 			logstart = fixup_internal_log_stripe(mp,
-					lsflag, logstart, agsize, lsunit,
-					&logblocks, blocklog, &lalign);
-		} else if (dsunit) {
+					lsflag, logstart, *agsize, *lsunit,
+					&logblocks, *blocklog, &lalign);
+		} else if (*dsunit) {
 			logstart = fixup_internal_log_stripe(mp,
-					lsflag, logstart, agsize, dsunit,
-					&logblocks, blocklog, &lalign);
+					lsflag, logstart, *agsize, *dsunit,
+					&logblocks, *blocklog, &lalign);
 		}
 	} else {
 		logstart = 0;
-		if (lsunit)
-			fixup_log_stripe_unit(lsflag, lsunit,
-					&logblocks, blocklog);
+		if (*lsunit)
+			fixup_log_stripe_unit(lsflag, *lsunit,
+					&logblocks, *blocklog);
 	}
-	validate_log_size(logblocks, blocklog, min_logblocks);
+	validate_log_size(logblocks, *blocklog, min_logblocks);
 
 	if (!qflag || Nflag) {
 		printf(_(
@@ -3422,19 +3487,19 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 		   "log      =%-22s bsize=%-6d blocks=%lld, version=%d\n"
 		   "         =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
 		   "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
-			dfile, isize, (long long)agcount, (long long)agsize,
+			dfile, *isize, (long long)*agcount, (long long)*agsize,
 			"", sectorsize, sb_feat.attr_version,
 				    !sb_feat.projid16bit,
 			"", sb_feat.crcs_enabled, sb_feat.finobt, sb_feat.spinodes,
 			sb_feat.rmapbt, sb_feat.reflink,
-			"", blocksize, (long long)dblocks, imaxpct,
-			"", dsunit, dswidth,
-			sb_feat.dir_version, dirblocksize, sb_feat.nci,
+			"", *blocksize, (long long)dblocks, *imaxpct,
+			"", *dsunit, *dswidth,
+			sb_feat.dir_version, *dirblocksize, sb_feat.nci,
 				sb_feat.dirftype,
-			logfile, 1 << blocklog, (long long)logblocks,
-			sb_feat.log_version, "", lsectorsize, lsunit,
+			logfile, 1 << *blocklog, (long long)logblocks,
+			sb_feat.log_version, "", *lsectorsize, *lsunit,
 				sb_feat.lazy_sb_counters,
-			rtfile, rtextblocks << blocklog,
+			rtfile, rtextblocks << *blocklog,
 			(long long)rtblocks, (long long)rtextents);
 		if (Nflag)
 			exit(0);
@@ -3443,7 +3508,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 	if (label)
 		strncpy(sbp->sb_fname, label, sizeof(sbp->sb_fname));
 	sbp->sb_magicnum = XFS_SB_MAGIC;
-	sbp->sb_blocksize = blocksize;
+	sbp->sb_blocksize = *blocksize;
 	sbp->sb_dblocks = dblocks;
 	sbp->sb_rblocks = rtblocks;
 	sbp->sb_rextents = rtextents;
@@ -3453,52 +3518,52 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 	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)*agcount;
 	sbp->sb_rbmblocks = nbmblocks;
 	sbp->sb_logblocks = (xfs_extlen_t)logblocks;
 	sbp->sb_sectsize = (__uint16_t)sectorsize;
-	sbp->sb_inodesize = (__uint16_t)isize;
-	sbp->sb_inopblock = (__uint16_t)(blocksize / isize);
+	sbp->sb_inodesize = (__uint16_t)*isize;
+	sbp->sb_inopblock = (__uint16_t)(*blocksize / *isize);
 	sbp->sb_sectlog = (__uint8_t)sectorlog;
-	sbp->sb_inodelog = (__uint8_t)inodelog;
-	sbp->sb_inopblog = (__uint8_t)(blocklog - inodelog);
+	sbp->sb_inodelog = (__uint8_t)*inodelog;
+	sbp->sb_inopblog = (__uint8_t)(*blocklog - *inodelog);
 	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 = *imaxpct;
 	sbp->sb_icount = 0;
 	sbp->sb_ifree = 0;
-	sbp->sb_fdblocks = dblocks - agcount * libxfs_prealloc_blocks(mp) -
-		(loginternal ? logblocks : 0);
+	sbp->sb_fdblocks = dblocks - *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 = *dsunit;
+	sbp->sb_width = *dswidth;
+	sbp->sb_dirblklog = *dirblocklog - *blocklog;
 	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;
+		*lsunit = (*lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, *lsunit);
+		sbp->sb_logsunit = *lsunit;
 	} else
 		sbp->sb_logsunit = 0;
 	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;
-		sbp->sb_inoalignmt = cluster_size >> blocklog;
+			cluster_size *= *isize / XFS_DINODE_MIN_SIZE;
+		sbp->sb_inoalignmt = cluster_size >> *blocklog;
 		sb_feat.inode_align = sbp->sb_inoalignmt != 0;
 	} else
 		sbp->sb_inoalignmt = 0;
-	if (lsectorsize != BBSIZE || sectorsize != BBSIZE) {
-		sbp->sb_logsectlog = (__uint8_t)lsectorlog;
-		sbp->sb_logsectsize = (__uint16_t)lsectorsize;
+	if (*lsectorsize != BBSIZE || sectorsize != BBSIZE) {
+		sbp->sb_logsectlog = (__uint8_t)*lsectorlog;
+		sbp->sb_logsectsize = (__uint16_t)*lsectorsize;
 	} else {
 		sbp->sb_logsectlog = 0;
 		sbp->sb_logsectsize = 0;
 	}
 
-	sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
+	sb_set_features(&mp->m_sb, &sb_feat, sectorsize, *lsectorsize, *dsunit);
 
 	if (force_overwrite)
 		zero_old_xfs_structures(&xi, sbp);
@@ -3528,8 +3593,8 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 	 * 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 * *blocksize) {
+		if (ftruncate(xi.dfd, dblocks * *blocksize) < 0) {
 			fprintf(stderr,
 				_("%s: Growing the data section failed\n"),
 				progname);
@@ -3557,7 +3622,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 	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, *lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
 
 	mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0);
 	if (mp == NULL) {
@@ -3571,7 +3636,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 	 * 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 < *agcount; agno++) {
 		struct xfs_agfl	*agfl;
 		int		bucket;
 		struct xfs_perag *pag = libxfs_perag_get(mp, agno);
@@ -3596,12 +3661,12 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 		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);
+		if (agno == *agcount - 1)
+			*agsize = dblocks - (xfs_rfsblock_t)(agno * *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(*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);
@@ -3623,15 +3688,15 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 		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)(*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))
 			platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid);
 
-		if (loginternal && agno == logagno) {
+		if (*loginternal && agno == *logagno) {
 			be32_add_cpu(&agf->agf_freeblks, -logblocks);
-			agf->agf_longest = cpu_to_be32(agsize -
+			agf->agf_longest = cpu_to_be32(*agsize -
 				XFS_FSB_TO_AGBNO(mp, logstart) - logblocks);
 		}
 		if (libxfs_alloc_min_freelist(mp, pag) > worst_freelist)
@@ -3670,7 +3735,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 		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)*agsize);
 		agi->agi_count = 0;
 		agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
 		agi->agi_level = cpu_to_be32(1);
@@ -3695,7 +3760,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 				bsize);
 		buf->b_ops = &xfs_allocbt_buf_ops;
 		block = XFS_BUF_TO_BLOCK(buf);
-		memset(block, 0, blocksize);
+		memset(block, 0, *blocksize);
 		if (xfs_sb_version_hascrc(&mp->m_sb))
 			libxfs_btree_init_block(mp, buf, XFS_ABTB_CRC_MAGIC, 0, 1,
 						agno, XFS_BTREE_CRC_BLOCKS);
@@ -3705,7 +3770,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 
 		arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
 		arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
-		if (loginternal && agno == logagno) {
+		if (*loginternal && agno == *logagno) {
 			if (lalign) {
 				/*
 				 * Have to insert two records
@@ -3735,7 +3800,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 		 * 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(*agsize -
 					be32_to_cpu(arec->ar_startblock));
 		if (!arec->ar_blockcount)
 			block->bb_numrecs = 0;
@@ -3750,7 +3815,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 				bsize);
 		buf->b_ops = &xfs_allocbt_buf_ops;
 		block = XFS_BUF_TO_BLOCK(buf);
-		memset(block, 0, blocksize);
+		memset(block, 0, *blocksize);
 		if (xfs_sb_version_hascrc(&mp->m_sb))
 			libxfs_btree_init_block(mp, buf, XFS_ABTC_CRC_MAGIC, 0, 1,
 						agno, XFS_BTREE_CRC_BLOCKS);
@@ -3760,7 +3825,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 
 		arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
 		arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
-		if (loginternal && agno == logagno) {
+		if (*loginternal && agno == *logagno) {
 			if (lalign) {
 				arec->ar_blockcount = cpu_to_be32(
 					XFS_FSB_TO_AGBNO(mp, logstart) -
@@ -3780,7 +3845,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 		 * 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(*agsize -
 					be32_to_cpu(arec->ar_startblock));
 		if (!arec->ar_blockcount)
 			block->bb_numrecs = 0;
@@ -3798,7 +3863,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 			buf->b_ops = &xfs_refcountbt_buf_ops;
 
 			block = XFS_BUF_TO_BLOCK(buf);
-			memset(block, 0, blocksize);
+			memset(block, 0, *blocksize);
 			libxfs_btree_init_block(mp, buf, XFS_REFC_CRC_MAGIC, 0,
 						0, agno, XFS_BTREE_CRC_BLOCKS);
 
@@ -3813,7 +3878,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 				bsize);
 		buf->b_ops = &xfs_inobt_buf_ops;
 		block = XFS_BUF_TO_BLOCK(buf);
-		memset(block, 0, blocksize);
+		memset(block, 0, *blocksize);
 		if (xfs_sb_version_hascrc(&mp->m_sb))
 			libxfs_btree_init_block(mp, buf, XFS_IBT_CRC_MAGIC, 0, 0,
 						agno, XFS_BTREE_CRC_BLOCKS);
@@ -3831,7 +3896,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 					bsize);
 			buf->b_ops = &xfs_inobt_buf_ops;
 			block = XFS_BUF_TO_BLOCK(buf);
-			memset(block, 0, blocksize);
+			memset(block, 0, *blocksize);
 			if (xfs_sb_version_hascrc(&mp->m_sb))
 				libxfs_btree_init_block(mp, buf, XFS_FIBT_CRC_MAGIC, 0, 0,
 							agno, XFS_BTREE_CRC_BLOCKS);
@@ -3850,7 +3915,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 				bsize);
 			buf->b_ops = &xfs_rmapbt_buf_ops;
 			block = XFS_BUF_TO_BLOCK(buf);
-			memset(block, 0, blocksize);
+			memset(block, 0, *blocksize);
 
 			libxfs_btree_init_block(mp, buf, XFS_RMAP_CRC_MAGIC, 0, 0,
 						agno, XFS_BTREE_CRC_BLOCKS);
@@ -3905,7 +3970,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 			}
 
 			/* account for the log space */
-			if (loginternal && agno == logagno) {
+			if (*loginternal && agno == *logagno) {
 				rrec = XFS_RMAP_REC_ADDR(block,
 					be16_to_cpu(block->bb_numrecs) + 1);
 				rrec->rm_startblock = cpu_to_be32(
@@ -3927,7 +3992,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 	 */
 	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, *blocksize);
 	libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
 
 	/*
@@ -3936,14 +4001,14 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
 	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, *blocksize);
 		libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
 	}
 
 	/*
 	 * BNO, CNT free block list
 	 */
-	for (agno = 0; agno < agcount; agno++) {
+	for (agno = 0; agno < *agcount; agno++) {
 		xfs_alloc_arg_t	args;
 		xfs_trans_t	*tp;
 		struct xfs_trans_res tres = {0};
-- 
2.8.1


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

* [PATCH 18/22] mkfs: prevent sector/blocksize to be specified as a number of blocks
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (16 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-16 14:15   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 19/22] mkfs: subopt flags should be saved as bool Jan Tulak
                   ` (7 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Documentation states that the options blocked in this patch accepts the
size only in bytes. So prevent blocksize or sectorsize to be specified as
a number of blocks or sectors.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index d55eb9a..e8fd49b 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2041,6 +2041,27 @@ getnum(
 		}
 	}
 
+	/* Prevent things like specifying blocksize as a number of blocks. */
+	if (opts->index == OPT_B || opts->index == OPT_S ||
+		(opts->index == OPT_L && (index == L_SECTLOG ||
+			index == L_SECTSIZE)) ||
+		(opts->index == OPT_N && (index == N_SIZE)) ||
+		(opts->index == OPT_D && (index == D_SECTLOG ||
+			index == D_SECTSIZE))
+
+		) {
+		switch (str[strlen(str)-1]) {
+		case 'b':
+		case 's':
+			fprintf(stderr,
+				_("You can't set a sector or block size in "
+				  "number of blocks or sectors (-%c %s).\n"),
+				opts->name, opts->subopts[index]);
+			exit(1);
+		}
+
+	}
+
 	sp->seen = true;
 
 	if (test_uvalue_num(sp->type, sp->minval, 0) &&
-- 
2.8.1


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

* [PATCH 19/22] mkfs: subopt flags should be saved as bool
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (17 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 18/22] mkfs: prevent sector/blocksize to be specified as a number of blocks Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-16 14:16   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 20/22] mkfs: move uuid empty string test to getstr() Jan Tulak
                   ` (6 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Flag suboptions are not united in what data type they use internally.
Unify them as boolean.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index e8fd49b..9e726f7 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -664,10 +664,10 @@ struct opt_params {
 			},
 			{ .index = D_RTINHERIT,
 			  .conflicts = { {LAST_CONFLICT} },
-			  .minval.u = 1,
-			  .maxval.u = 1,
-			  .flagval.u = 1,
-			  .type = UINT,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			},
 			{ .index = D_PROJINHERIT,
 			  .conflicts = { {LAST_CONFLICT} },
@@ -804,10 +804,10 @@ struct opt_params {
 					  .message = \
 		"Sparse inodes not supported without CRC support."},
 					 {LAST_CONFLICT} },
-			  .minval.i = 0,
-			  .maxval.i = 1,
-			  .flagval.i = 1,
-			  .type = INT,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			},
 		},
 	},
@@ -937,10 +937,10 @@ struct opt_params {
 					  .subopt = L_INTERNAL,
 					 },
 					 {LAST_CONFLICT} },
-			  .minval.i = 0,
-			  .maxval.i = 1,
-			  .flagval.i = 1,
-			  .type = INT,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			},
 			{ .index = L_NAME,
 			  .conflicts = { {.opt = OPT_L,
@@ -1070,10 +1070,10 @@ struct opt_params {
 			  .type = STRING,
 			},
 			{ .index = R_FILE,
-			  .minval.i = 0,
-			  .maxval.i = 1,
-			  .flagval.i = 1,
-			  .type = INT,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			  .conflicts = { {LAST_CONFLICT} },
 			},
 			{ .index = R_NAME,
@@ -1090,10 +1090,10 @@ struct opt_params {
 			  .type = STRING,
 			},
 			{ .index = R_NOALIGN,
-			  .minval.i = 0,
-			  .maxval.i = 1,
-			  .flagval.i = 1,
-			  .type = INT,
+			  .minval.b = false,
+			  .maxval.b = true,
+			  .flagval.b = true,
+			  .type = BOOL,
 			  .conflicts = { {LAST_CONFLICT} },
 			},
 		},
@@ -2193,7 +2193,7 @@ main(
 	xfs_extlen_t		nbmblocks;
 	int			nlflag;
 	int			*nodsflag;
-	int			*norsflag;
+	bool			*norsflag;
 	xfs_alloc_rec_t		*nrec;
 	int			nsflag;
 	int			nvflag;
@@ -2256,7 +2256,7 @@ main(
 	dsu = &opts[OPT_D].subopt_params[D_SU].value.i;
 	dsw = &opts[OPT_D].subopt_params[D_SW].value.i;
 	nodsflag = &opts[OPT_D].subopt_params[D_NOALIGN].value.i;
-	norsflag = &opts[OPT_R].subopt_params[R_NOALIGN].value.i;
+	norsflag = &opts[OPT_R].subopt_params[R_NOALIGN].value.b;
 	logagno = &opts[OPT_L].subopt_params[L_AGNUM].value.u;
 	lsu = &opts[OPT_L].subopt_params[L_SU].value.i;
 	lsunit = &opts[OPT_L].subopt_params[L_SUNIT].value.i;
@@ -2391,7 +2391,7 @@ main(
 					if (c)
 						fsx.fsx_xflags |=
 							XFS_DIFLAG_RTINHERIT;
-					opts[OPT_D].subopt_params[D_RTINHERIT].value.u = c;
+					opts[OPT_D].subopt_params[D_RTINHERIT].value.b = c;
 					break;
 				case D_PROJINHERIT:
 					fsx.fsx_projid = getnum(value, &opts[OPT_D],
@@ -2727,15 +2727,15 @@ main(
 	opts[OPT_D].subopt_params[D_FILE].value.i  = xi.disfile;
 	opts[OPT_D].subopt_params[D_PROJINHERIT].value.u = fsx.fsx_projid;
 	opts[OPT_D].subopt_params[D_EXTSZINHERIT].value.u = fsx.fsx_extsize;
-	opts[OPT_L].subopt_params[L_FILE].value.i = xi.lisfile;
+	opts[OPT_L].subopt_params[L_FILE].value.b = xi.lisfile;
 	opts[OPT_L].subopt_params[L_VERSION].value.i = sb_feat.log_version;
 	opts[OPT_L].subopt_params[L_LAZYSBCNTR].value.b = sb_feat.lazy_sb_counters;
 	opts[OPT_I].subopt_params[I_ATTR].value.i = sb_feat.attr_version ;
 	opts[OPT_I].subopt_params[I_PROJID32BIT].value.b = !sb_feat.projid16bit ;
-	opts[OPT_I].subopt_params[I_SPINODES].value.i = sb_feat.spinodes ;
+	opts[OPT_I].subopt_params[I_SPINODES].value.b = sb_feat.spinodes ;
 	opts[OPT_M].subopt_params[M_FINOBT].value.i = sb_feat.finobt ;
 	opts[OPT_M].subopt_params[M_RMAPBT].value.b = sb_feat.rmapbt ;
-	opts[OPT_R].subopt_params[R_FILE].value.i = xi.risfile ;
+	opts[OPT_R].subopt_params[R_FILE].value.b = xi.risfile ;
 	opts[OPT_R].subopt_params[R_NAME].value.s = xi.rtname;
 	opts[OPT_R].subopt_params[R_DEV].value.s = xi.rtname;
 	opts[OPT_S].subopt_params[S_LOG].value.u = sectorsize;
-- 
2.8.1


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

* [PATCH 20/22] mkfs: move uuid empty string test to getstr()
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (18 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 19/22] mkfs: subopt flags should be saved as bool Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-16 14:16   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 21/22] mkfs: remove duplicit checks Jan Tulak
                   ` (5 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

No need for this separate check, when we can use getstr() for opts.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 9e726f7..9c1ad11 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2560,11 +2560,10 @@ main(
 						value, &opts[OPT_M], M_FINOBT);
 					break;
 				case M_UUID:
-					if (!value || *value == '\0')
-						reqval('m', subopts, M_UUID);
+					opts[OPT_M].subopt_params[M_UUID].value.s =
+						getstr(value, &opts[OPT_M], M_UUID);
 					if (platform_uuid_parse(value, &uuid))
 						illegal(optarg, "m uuid");
-					opts[OPT_M].subopt_params[M_UUID].value.s = value;
 					break;
 				case M_RMAPBT:
 					sb_feat.rmapbt = getnum(
-- 
2.8.1


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

* [PATCH 21/22] mkfs: remove duplicit checks
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (19 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 20/22] mkfs: move uuid empty string test to getstr() Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-16 14:17   ` Bill O'Donnell
  2016-12-07 13:27 ` [PATCH 22/22] mkfs: prevent multiple specifications of a single option Jan Tulak
                   ` (4 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Remove old checks that are now done by the conflicts table.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 9c1ad11..cd0eb20 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2760,26 +2760,6 @@ main(
 		*blocklog = XFS_DFL_BLOCKSIZE_LOG;
 		*blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG;
 	}
-	if (*blocksize < XFS_MIN_BLOCKSIZE || *blocksize > XFS_MAX_BLOCKSIZE) {
-		fprintf(stderr, _("illegal block size %d\n"), *blocksize);
-		usage();
-	}
-	if (sb_feat.crcs_enabled && *blocksize < XFS_MIN_CRC_BLOCKSIZE) {
-		fprintf(stderr,
-_("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
-			XFS_MIN_CRC_BLOCKSIZE);
-		usage();
-	}
-
-	/*
-	 * If user explicitly stated -m crc=1 -n ftype=0, an error was already
-	 * issued. But if -n ftype=0 was stated alone, then it is a conflict
-	 * with a default value for crc enabled and has to be detected here.
-	 */
-	if (sb_feat.crcs_enabled && !sb_feat.dirftype) {
-		fprintf(stderr, _("cannot disable ftype with crcs enabled\n"));
-		usage();
-	}
 	if (!slflag && !ssflag) {
 		sectorlog = XFS_MIN_SECTORSIZE_LOG;
 		sectorsize = XFS_MIN_SECTORSIZE;
-- 
2.8.1


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

* [PATCH 22/22] mkfs: prevent multiple specifications of a single option
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (20 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 21/22] mkfs: remove duplicit checks Jan Tulak
@ 2016-12-07 13:27 ` Jan Tulak
  2017-01-16 14:18   ` Bill O'Donnell
  2017-01-06 11:42 ` [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (3 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jan Tulak @ 2016-12-07 13:27 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Because things like -l size=40M,size=50M are clearly wrong and should
not pass. However, in two cases, we do not know if the option is a
string or number - thus the few more lines with can_respec flag.

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

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index cd0eb20..7fe743a 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -432,6 +432,10 @@ test_uvalue_num(enum e_type a_type, union u_value a, long long b) {
  *     Set to true if, when user specifies the option, she has to specify
  *     a value too. That is, if needs_val is true, then it is not possible to
  *     use the subopt as a flag.
+ *
+ *   can_respec OPTIONAL
+ *     If true, then there can come one getnum() after a getstr() call for this
+ *     option.
  */
 struct opt_params {
 	int		index;
@@ -458,6 +462,7 @@ struct opt_params {
 		union u_value value;
 		enum e_type 	type;
 		bool		needs_val;
+		bool		can_respec;
 	}		subopt_params[MAX_SUBOPTS];
 } opts[MAX_OPTS] = {
 	{
@@ -877,6 +882,7 @@ struct opt_params {
 			  .maxval.i = 2,
 			  .needs_val = true,
 			  .type = INT,
+			  .can_respec = true,
 			},
 			{ .index = L_SUNIT,
 			  .conflicts = { {.opt = OPT_L,
@@ -1009,6 +1015,7 @@ struct opt_params {
 			  .maxval.i = 2,
 			  .needs_val = true,
 			  .type = INT,
+			  .can_respec = true,
 			},
 			{ .index = N_FTYPE,
 			  .conflicts = {  {.opt = OPT_M,
@@ -2017,6 +2024,22 @@ getnum(
 	struct subopt_param	*sp = &opts->subopt_params[index];
 	long long		c;
 
+	if (sp->seen){
+		/* If the option has respec flag, it is possible to do ONE
+		 * getnum call even with sp->seen == 1. Do this by disabling
+		 * the respec flag - this time we can continue, but if getnum
+		 * gets called once more, we will fail.
+		 */
+		if (sp->can_respec){
+			sp->can_respec = false;
+		} else {
+			fprintf(stderr,
+			_("You can't use an option multiple times: -%c %s\n"),
+			  opts->name, opts->subopts[index]);
+			usage();
+		}
+	}
+
 	/* empty strings might just return a default value */
 	if (!str || *str == '\0') {
 		if (sp->needs_val)
@@ -2123,6 +2146,12 @@ getstr(
 	/* empty strings for string options are not valid */
 	if (!str || *str == '\0')
 		reqval(opts->name, (char **)opts->subopts, index);
+	if (opts->subopt_params[index].seen){
+		fprintf(stderr,
+		_("You can't use an option multiple times: -%c %s\n"),
+		  opts->name, opts->subopts[index]);
+		usage();
+	}
 	opts->subopt_params[index].seen = true;
 	return str;
 }
-- 
2.8.1


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

* Re: [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (21 preceding siblings ...)
  2016-12-07 13:27 ` [PATCH 22/22] mkfs: prevent multiple specifications of a single option Jan Tulak
@ 2017-01-06 11:42 ` Jan Tulak
  2017-01-09 19:43 ` Eric Sandeen
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jan Tulak @ 2017-01-06 11:42 UTC (permalink / raw)
  To: linux-xfs

On Wed, Dec 7, 2016 at 2:27 PM, Jan Tulak <jtulak@redhat.com> wrote:
> Hi guys,
>
> this set is a follow-up of some old discussions and further attempts to untangle
> the spaghetti in options parsing. In short, this patchset allows to define
> cross-option conflicts and makes the conflicts detection more robust.
>
> Until now, we had the ability to define conflicts within one option (e.g. -d
> sunit/su), but things like -i attr=1 -m crc=1 conflict had to be watched for on
> case by case basis somewhere in the code. Now, when even those situations are
> handled by the same code, it is enough to just add a new entry into a table of
> options. Thus, a reduced chance for an error and easier adding of new cases.
>
> One of the biggest changes in this set is that user input is now stored in
> directly in the opts table defining allowed range and the like, and variables
> in the main() of mkfs.xfs are now just aliases/pointers. This allows as to do
> conditional checks based on actual values, not only on occurence of an option.
>
> (A technical note here is that not every value can be saved in a single place
> like this. Some values are already stored in a table or structure and I wanted
> to avoid modifying anything outside of xfs_mkfs.c.)
>
> I tested it with full xfstests suit and the only failed tests I saw are because
> some ambiguity in arguments parsing was removed. E.g. sometimes it was possible
> to specify size in blocks without stating the blocksize first, even if manpage
> explicitly requires -b or -s to be used before.
>
> I already submitted part of this patchset as RFC before, but as I got no reply,
> I tried to finish it before submitting again. So, this set works as it is. I
> still have some questions, but they can be answered with "let's keep it as it
> is."
>
> Number one is simple: What values can use block/sector sizes as user input?
> There is an inconsistency or ambiguity between manual page and the code. Look
> at man page for -d agsize.
>
>         agsize=value
>                 This is an alternative to using the  agcount  subop‐
>                 tion.  The  value is the desired size of the alloca‐
>                 tion group expressed in bytes (usually using  the  m
>                                      ^^^^^^^^
>                 or  g  suffixes).   This value must be a multiple of
>                 [ ... ]
>
>
> The option -d agsize explicitly states that it accepts size in bytes, in a
> similar tone to the one used for describe allowed values for -s/-b size:
>
>         value in bytes with size=value
>               ^^^^^^^^
>
> However, -d agsize=1234s input was accepted as valid until now. Is the manual
> page misleading, or are the options where b/s suffix is forbidden are
> block/sector size definitions? I decided to err on the compatibility side and
> kept the current behaviour - only blocksize or sectorsize can't be stated in
> blocks and sectors, but it can be easily changed.
>
> I will send an update for xfstests once I know what behaviour is correct.
>
>
> The other question about this patchset is: As we are saving all the values in
> the opt_params table, and the values have different types, I thought it
> necessary to not use a single data type for everything and created an union
> field (could be easily changed to struct, that would not change anything
> important). Do you see any non-adressed issue with this approach? Is there
> another way how to solve the problem?
>
> If nothing else, numbers and strings can't be easily saved in a single
> variable. Also, as we are using shift operations, any type conversions
> (like storing everything in long long type) could cause trouble. This is one of
> the reasons why I'm changed the variables in main() to pointers. This allows
> for simple and easy access to the correct union field, so unless one is adding
> a new option, there should be no need to remember the correct date type. If the
> pointer assignment is done correctly, then GCC will watch for type mismatch.
>
> I really couldn't find out better solution, but see for yourself, this change
> is done in "mkfs: Change all value fields in opt structures into unions"
> and "mkfs: use old variables as pointers to the new opts struct values".
>
>
> So, I think this is all I wanted to cover in the cover letter. :-)
> I will be glad for any comments or bugs you find out.
>
> Thanks for your time,
>
> Jan
>
>
> Jan Tulak (22):
>   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: change conflicts array into a table capable of cross-option
>     addressing
>   mkfs: add a check for conflicting values
>   mkfs: add cross-section conflict checks
>   mkfs: Move opts related #define to one place
>   mkfs: move conflicts into the table
>   mkfs: change conflict checks to utilize the new conflict structure
>   mkfs: change when to mark an option as seen
>   mkfs: add test_default_value into conflict struct
>   mkfs: expand conflicts declarations to named declaration
>   mkfs: remove zeroed items from conflicts declaration
>   mkfs: rename defaultval to flagval in opts
>   mkfs: replace SUBOPT_NEEDS_VAL for a flag
>   mkfs: Change all value fields in opt structures into unions
>   mkfs: use old variables as pointers to the new opts struct values
>   mkfs: prevent sector/blocksize to be specified as a number of blocks
>   mkfs: subopt flags should be saved as bool
>   mkfs: move uuid empty string test to getstr()
>   mkfs: remove duplicit checks
>   mkfs: prevent multiple specifications of a single option
>
>  mkfs/xfs_mkfs.c | 2952 +++++++++++++++++++++++++++++++++++--------------------
>  1 file changed, 1864 insertions(+), 1088 deletions(-)
>
> --
> 2.8.1
>

Hi guys,

I'm just pinging this up. If there are no issues with it, I will
rebase it on top of new releases and send it again without the RFC.

Cheers,
Jan


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

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

* Re: [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (22 preceding siblings ...)
  2017-01-06 11:42 ` [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
@ 2017-01-09 19:43 ` Eric Sandeen
  2017-01-10  9:47   ` Jan Tulak
  2017-01-12 15:46 ` Bill O'Donnell
  2017-01-16 20:14 ` Bill O'Donnell
  25 siblings, 1 reply; 54+ messages in thread
From: Eric Sandeen @ 2017-01-09 19:43 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 12/7/16 7:27 AM, Jan Tulak wrote:
> Hi guys,

...


> Number one is simple: What values can use block/sector sizes as user input?
> There is an inconsistency or ambiguity between manual page and the code. Look
> at man page for -d agsize.
> 
> 	agsize=value
> 		This is an alternative to using the  agcount  subop‐
> 		tion.  The  value is the desired size of the alloca‐
> 		tion group expressed in bytes (usually using  the  m
> 		                     ^^^^^^^^
> 		or  g  suffixes).   This value must be a multiple of
> 		[ ... ]
> 

Ok, 'm' and 'g' are just given as examples here, not an exhaustive list.

> The option -d agsize explicitly states that it accepts size in bytes, in a
> similar tone to the one used for describe allowed values for -s/-b size:
> 
> 	value in bytes with size=value
> 	      ^^^^^^^^
> 
> However, -d agsize=1234s input was accepted as valid until now. Is the manual
> page misleading, or are the options where b/s suffix is forbidden are
> block/sector size definitions? I decided to err on the compatibility side and
> kept the current behaviour - only blocksize or sectorsize can't be stated in
> blocks and sectors, but it can be easily changed.
> 
> I will send an update for xfstests once I know what behaviour is correct.

cvtnum() handles 'b' and 's' along with all the other more normal logarithmic
modifiers (k, m, g, t, p, e) so I think there's no real reason to exclude
'b' or 's' from options that take bytes.  cvtnum() today already makes sure
that the appropriate multiplier unit (for b or s) is available at the time
of the call, so that all seems ok code-wise.

(Honestly, while saying "-s size=512 -b size=8s" seems a bit weird, it's
not wrong, so I see no reason to exclude it.  Of course the sector size
cannot be specified in sector units... :) )

I see no problem with allowing s and b as units for any option as long as
the underlying unit is available by the time it's processed.
 
> 
> The other question about this patchset is: As we are saving all the values in
> the opt_params table, and the values have different types, I thought it
> necessary to not use a single data type for everything and created an union
> field (could be easily changed to struct, that would not change anything
> important). Do you see any non-adressed issue with this approach? Is there
> another way how to solve the problem?

I think it'll take a read through the patches to properly answer this one :)

-Eric

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

* Re: [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2017-01-09 19:43 ` Eric Sandeen
@ 2017-01-10  9:47   ` Jan Tulak
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Tulak @ 2017-01-10  9:47 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Mon, Jan 9, 2017 at 8:43 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 12/7/16 7:27 AM, Jan Tulak wrote:
>> Hi guys,
>
> ...
>
>
>> Number one is simple: What values can use block/sector sizes as user input?
>> There is an inconsistency or ambiguity between manual page and the code. Look
>> at man page for -d agsize.
>>
>>       agsize=value
>>               This is an alternative to using the  agcount  subop‐
>>               tion.  The  value is the desired size of the alloca‐
>>               tion group expressed in bytes (usually using  the  m
>>                                    ^^^^^^^^
>>               or  g  suffixes).   This value must be a multiple of
>>               [ ... ]
>>
>
> Ok, 'm' and 'g' are just given as examples here, not an exhaustive list.
>
>> The option -d agsize explicitly states that it accepts size in bytes, in a
>> similar tone to the one used for describe allowed values for -s/-b size:
>>
>>       value in bytes with size=value
>>             ^^^^^^^^
>>
>> However, -d agsize=1234s input was accepted as valid until now. Is the manual
>> page misleading, or are the options where b/s suffix is forbidden are
>> block/sector size definitions? I decided to err on the compatibility side and
>> kept the current behaviour - only blocksize or sectorsize can't be stated in
>> blocks and sectors, but it can be easily changed.
>>
>> I will send an update for xfstests once I know what behaviour is correct.
>
> cvtnum() handles 'b' and 's' along with all the other more normal logarithmic
> modifiers (k, m, g, t, p, e) so I think there's no real reason to exclude
> 'b' or 's' from options that take bytes.  cvtnum() today already makes sure
> that the appropriate multiplier unit (for b or s) is available at the time
> of the call, so that all seems ok code-wise.
>
> (Honestly, while saying "-s size=512 -b size=8s" seems a bit weird, it's
> not wrong, so I see no reason to exclude it.  Of course the sector size
> cannot be specified in sector units... :) )
>
> I see no problem with allowing s and b as units for any option as long as
> the underlying unit is available by the time it's processed.

I know that the m and g are just examples. The point was only about
whether or not should we take 'b' and 's' everywhere or not. I see
your point, so we can consider this solved. :-)

>
>>
>> The other question about this patchset is: As we are saving all the values in
>> the opt_params table, and the values have different types, I thought it
>> necessary to not use a single data type for everything and created an union
>> field (could be easily changed to struct, that would not change anything
>> important). Do you see any non-adressed issue with this approach? Is there
>> another way how to solve the problem?
>
> I think it'll take a read through the patches to properly answer this one :)
>

Yeah. Take your time. :-)

Thanks,
Jan


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

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

* Re: [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (23 preceding siblings ...)
  2017-01-09 19:43 ` Eric Sandeen
@ 2017-01-12 15:46 ` Bill O'Donnell
  2017-01-16 20:14 ` Bill O'Donnell
  25 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-12 15:46 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:07PM +0100, Jan Tulak wrote:
> Hi guys,
> 
> this set is a follow-up of some old discussions and further attempts to untangle
> the spaghetti in options parsing. In short, this patchset allows to define
> cross-option conflicts and makes the conflicts detection more robust.

concept seems good. I'll review the patches.

> 
> Until now, we had the ability to define conflicts within one option (e.g. -d
> sunit/su), but things like -i attr=1 -m crc=1 conflict had to be watched for on
> case by case basis somewhere in the code. Now, when even those situations are
> handled by the same code, it is enough to just add a new entry into a table of
> options. Thus, a reduced chance for an error and easier adding of new cases.
> 
> One of the biggest changes in this set is that user input is now stored in
> directly in the opts table defining allowed range and the like, and variables
> in the main() of mkfs.xfs are now just aliases/pointers. This allows as to do
> conditional checks based on actual values, not only on occurence of an option.
> 
> (A technical note here is that not every value can be saved in a single place
> like this. Some values are already stored in a table or structure and I wanted
> to avoid modifying anything outside of xfs_mkfs.c.)
> 
> I tested it with full xfstests suit and the only failed tests I saw are because
> some ambiguity in arguments parsing was removed. E.g. sometimes it was possible
> to specify size in blocks without stating the blocksize first, even if manpage
> explicitly requires -b or -s to be used before.
> 
> I already submitted part of this patchset as RFC before, but as I got no reply,
> I tried to finish it before submitting again. So, this set works as it is. I
> still have some questions, but they can be answered with "let's keep it as it
> is."
> 
> Number one is simple: What values can use block/sector sizes as user input?
> There is an inconsistency or ambiguity between manual page and the code. Look
> at man page for -d agsize.
> 
> 	agsize=value
> 		This is an alternative to using the  agcount  subop‐
> 		tion.  The  value is the desired size of the alloca‐
> 		tion group expressed in bytes (usually using  the  m
> 		                     ^^^^^^^^
> 		or  g  suffixes).   This value must be a multiple of
> 		[ ... ]
> 
> 
> The option -d agsize explicitly states that it accepts size in bytes, in a
> similar tone to the one used for describe allowed values for -s/-b size:
> 
> 	value in bytes with size=value
> 	      ^^^^^^^^
> 
> However, -d agsize=1234s input was accepted as valid until now. Is the manual
> page misleading, or are the options where b/s suffix is forbidden are
> block/sector size definitions? I decided to err on the compatibility side and
> kept the current behaviour - only blocksize or sectorsize can't be stated in
> blocks and sectors, but it can be easily changed.
> 
> I will send an update for xfstests once I know what behaviour is correct.
> 
> 
> The other question about this patchset is: As we are saving all the values in
> the opt_params table, and the values have different types, I thought it
> necessary to not use a single data type for everything and created an union
> field (could be easily changed to struct, that would not change anything
> important). Do you see any non-adressed issue with this approach? Is there
> another way how to solve the problem?
> 
> If nothing else, numbers and strings can't be easily saved in a single
> variable. Also, as we are using shift operations, any type conversions
> (like storing everything in long long type) could cause trouble. This is one of
> the reasons why I'm changed the variables in main() to pointers. This allows
> for simple and easy access to the correct union field, so unless one is adding
> a new option, there should be no need to remember the correct date type. If the
> pointer assignment is done correctly, then GCC will watch for type mismatch.
> 
> I really couldn't find out better solution, but see for yourself, this change
> is done in "mkfs: Change all value fields in opt structures into unions"
> and "mkfs: use old variables as pointers to the new opts struct values".
> 
> 
> So, I think this is all I wanted to cover in the cover letter. :-)
> I will be glad for any comments or bugs you find out.
> 
> Thanks for your time,
> 
> Jan
> 
> 
> Jan Tulak (22):
>   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: change conflicts array into a table capable of cross-option
>     addressing
>   mkfs: add a check for conflicting values
>   mkfs: add cross-section conflict checks
>   mkfs: Move opts related #define to one place
>   mkfs: move conflicts into the table
>   mkfs: change conflict checks to utilize the new conflict structure
>   mkfs: change when to mark an option as seen
>   mkfs: add test_default_value into conflict struct
>   mkfs: expand conflicts declarations to named declaration
>   mkfs: remove zeroed items from conflicts declaration
>   mkfs: rename defaultval to flagval in opts
>   mkfs: replace SUBOPT_NEEDS_VAL for a flag
>   mkfs: Change all value fields in opt structures into unions
>   mkfs: use old variables as pointers to the new opts struct values
>   mkfs: prevent sector/blocksize to be specified as a number of blocks
>   mkfs: subopt flags should be saved as bool
>   mkfs: move uuid empty string test to getstr()
>   mkfs: remove duplicit checks
>   mkfs: prevent multiple specifications of a single option
> 
>  mkfs/xfs_mkfs.c | 2952 +++++++++++++++++++++++++++++++++++--------------------
>  1 file changed, 1864 insertions(+), 1088 deletions(-)
> 
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 03/22] mkfs: extend opt_params with a value field
  2016-12-07 13:27 ` [PATCH 03/22] mkfs: extend opt_params with a value field Jan Tulak
@ 2017-01-13 16:55   ` Bill O'Donnell
  2017-01-16 12:42     ` Jan Tulak
  0 siblings, 1 reply; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 16:55 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:10PM +0100, Jan Tulak wrote:
> Add a new field int opt_params - value, which is filled with user input.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Despite a very minor whitespace issue...

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 132 insertions(+)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 372c620..edcfdc0 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -115,6 +115,12 @@ unsigned int		sectorsize;
>   *     sets what is used with simple specifying the subopt (-d file).
>   *     A special SUBOPT_NEEDS_VAL can be used to require a user-given
>   *     value in any case.
> + *
> + *   value INTERNAL
> + *     Do not set this on initialization. Use defaultval for what you want
> + *     to do. This is filled with user input and anything you write here now
> + *     is overwritten. (If the user input is a string and not a number, this
> + *     value is set to a positive non-zero number.)
>   */
>  struct opt_params {
>  	int		index;
> @@ -131,6 +137,7 @@ struct opt_params {
>  		long long	minval;
>  		long long	maxval;
>  		long long	defaultval;
> +		long long	value;
>  	}		subopt_params[MAX_SUBOPTS];
>  } opts[MAX_OPTS] = {
>  #define OPT_B	0
> @@ -1566,12 +1573,20 @@ main(
>  								B_LOG);
>  					blocksize = 1 << blocklog;
>  					blflag = 1;
> +					opts[OPT_B].subopt_params[B_LOG].value =
> +							blocklog;
> +					opts[OPT_B].subopt_params[B_SIZE].value =
> +							blocksize;
>  					break;
>  				case B_SIZE:
>  					blocksize = getnum(value, &opts[OPT_B],
>  							   B_SIZE);
>  					blocklog = libxfs_highbit32(blocksize);
>  					bsflag = 1;
> +					opts[OPT_B].subopt_params[B_LOG].value =
> +							blocklog;
> +					opts[OPT_B].subopt_params[B_SIZE].value =
> +							blocksize;
>  					break;
>  				default:
>  					unknown('b', value);
> @@ -1589,47 +1604,70 @@ main(
>  					agcount = getnum(value, &opts[OPT_D],
>  							 D_AGCOUNT);
>  					daflag = 1;
> +					opts[OPT_D].subopt_params[D_AGCOUNT].value =
> +							agcount;
>  					break;
>  				case D_AGSIZE:
>  					agsize = getnum(value, &opts[OPT_D],
>  								D_AGSIZE);
>  					dasize = 1;
> +					opts[OPT_D].subopt_params[D_AGSIZE].value =
> +							agsize;
>  					break;
>  				case D_FILE:
>  					xi.disfile = getnum(value, &opts[OPT_D],
>  							    D_FILE);
> +					opts[OPT_D].subopt_params[D_FILE].value =
> +							xi.disfile;
>  					break;
>  				case D_NAME:
>  					xi.dname = getstr(value, &opts[OPT_D],
>  								D_NAME);
> +					opts[OPT_D].subopt_params[D_NAME].value = 1;
>  					break;
>  				case D_SIZE:
>  					dbytes = getnum(value, &opts[OPT_D],
>  								D_SIZE);
> +					opts[OPT_D].subopt_params[D_SIZE].value =
> +							dbytes;
>  					break;
>  				case D_SUNIT:
>  					dsunit = getnum(value, &opts[OPT_D],
>  								D_SUNIT);
> +					opts[OPT_D].subopt_params[D_SUNIT].value =
> +							dsunit;
>  					break;
>  				case D_SWIDTH:
>  					dswidth = getnum(value, &opts[OPT_D],
>  							 D_SWIDTH);
> +					opts[OPT_D].subopt_params[D_SWIDTH].value =
> +							dswidth;
>  					break;
>  				case D_SU:
>  					dsu = getnum(value, &opts[OPT_D], D_SU);
> +					opts[OPT_D].subopt_params[D_SU].value =
> +							dsu;
>  					break;
>  				case D_SW:
>  					dsw = getnum(value, &opts[OPT_D], D_SW);
> +					opts[OPT_D].subopt_params[D_SW].value =
> +							dsw;
>  					break;
>  				case D_NOALIGN:
>  					nodsflag = getnum(value, &opts[OPT_D],
>  								D_NOALIGN);
> +					opts[OPT_D].subopt_params[D_NOALIGN].value =
> +							nodsflag;
>  					break;
>  				case D_SECTLOG:
>  					sectorlog = getnum(value, &opts[OPT_D],
>  							   D_SECTLOG);
>  					sectorsize = 1 << sectorlog;
>  					slflag = 1;
> +					opts[OPT_D].subopt_params[D_SECTSIZE].value =
> +							sectorsize;
> +					opts[OPT_D].subopt_params[D_SECTLOG].value =
> +							sectorlog;
>  					break;
>  				case D_SECTSIZE:
>  					sectorsize = getnum(value, &opts[OPT_D],
> @@ -1637,6 +1675,10 @@ main(
>  					sectorlog =
>  						libxfs_highbit32(sectorsize);
>  					ssflag = 1;
> +					opts[OPT_D].subopt_params[D_SECTSIZE].value =
> +							sectorsize;
> +					opts[OPT_D].subopt_params[D_SECTLOG].value =
> +							sectorlog;
>  					break;
>  				case D_RTINHERIT:
>  					c = getnum(value, &opts[OPT_D],
> @@ -1644,18 +1686,24 @@ main(
>  					if (c)
>  						fsx.fsx_xflags |=
>  							XFS_DIFLAG_RTINHERIT;
> +					opts[OPT_D].subopt_params[D_RTINHERIT].value =
> +							c;
>  					break;
>  				case D_PROJINHERIT:
>  					fsx.fsx_projid = getnum(value, &opts[OPT_D],
>  								D_PROJINHERIT);
>  					fsx.fsx_xflags |=
>  						XFS_DIFLAG_PROJINHERIT;
> +					opts[OPT_D].subopt_params[D_PROJINHERIT].value =
> +							fsx.fsx_projid;
>  					break;
>  				case D_EXTSZINHERIT:
>  					fsx.fsx_extsize = getnum(value, &opts[OPT_D],
>  								 D_EXTSZINHERIT);
>  					fsx.fsx_xflags |=
>  						XFS_DIFLAG_EXTSZINHERIT;
> +					opts[OPT_D].subopt_params[D_EXTSZINHERIT].value =
> +							fsx.fsx_extsize;
>  					break;
>  				default:
>  					unknown('d', value);
> @@ -1673,43 +1721,64 @@ main(
>  					sb_feat.inode_align = getnum(value,
>  								&opts[OPT_I],
>  								I_ALIGN);
> +					opts[OPT_I].subopt_params[I_ALIGN].value =
> +							sb_feat.inode_align;
>  					break;
>  				case I_LOG:
>  					inodelog = getnum(value, &opts[OPT_I],
>  								I_LOG);
>  					isize = 1 << inodelog;
>  					ilflag = 1;
> +					opts[OPT_I].subopt_params[I_SIZE].value =
> +							isize;
> +					opts[OPT_I].subopt_params[I_LOG].value =
> +							inodelog;
>  					break;
>  				case I_MAXPCT:
>  					imaxpct = getnum(value, &opts[OPT_I],
>  							 I_MAXPCT);
>  					imflag = 1;
> +					opts[OPT_I].subopt_params[I_MAXPCT].value =
> +							imaxpct;
>  					break;
>  				case I_PERBLOCK:
>  					inopblock = getnum(value, &opts[OPT_I],
>  							   I_PERBLOCK);
>  					ipflag = 1;
> +					opts[OPT_I].subopt_params[I_PERBLOCK].value =
> +							inopblock;
>  					break;
>  				case I_SIZE:
>  					isize = getnum(value, &opts[OPT_I],
>  								I_SIZE);
>  					inodelog = libxfs_highbit32(isize);
>  					isflag = 1;
> +					opts[OPT_I].subopt_params[I_SIZE].value =
> +							isize;
> +					opts[OPT_I].subopt_params[I_LOG].value =
> +							inodelog;
>  					break;
>  				case I_ATTR:
>  					sb_feat.attr_version =
> +
>  						getnum(value, &opts[OPT_I],
>  								I_ATTR);
> +					opts[OPT_I].subopt_params[I_ATTR].value =
> +							sb_feat.attr_version;
>  					break;
>  				case I_PROJID32BIT:
>  					sb_feat.projid16bit =
>  						!getnum(value, &opts[OPT_I],
>  							I_PROJID32BIT);
> +					opts[OPT_I].subopt_params[I_PROJID32BIT].value =
> +							sb_feat.projid16bit;
>  					break;
>  				case I_SPINODES:
>  					sb_feat.spinodes = getnum(value,
>  								&opts[OPT_I],
>  								I_SPINODES);
> +					opts[OPT_I].subopt_params[I_SPINODES].value =
> +							sb_feat.spinodes;
>  					break;
>  				default:
>  					unknown('i', value);
> @@ -1727,24 +1796,34 @@ main(
>  					logagno = getnum(value, &opts[OPT_L],
>  								L_AGNUM);
>  					laflag = 1;
> +					opts[OPT_L].subopt_params[L_AGNUM].value =
> +							logagno;
>  					break;
>  				case L_FILE:
>  					xi.lisfile = getnum(value, &opts[OPT_L],
>  							    L_FILE);
> +					opts[OPT_L].subopt_params[L_FILE].value =
> +							xi.lisfile;
>  					break;
>  				case L_INTERNAL:
>  					loginternal = getnum(value, &opts[OPT_L],
>  							     L_INTERNAL);
>  					liflag = 1;
> +					opts[OPT_L].subopt_params[L_INTERNAL].value =
> +							loginternal;
>  					break;
>  				case L_SU:
>  					lsu = getnum(value, &opts[OPT_L], L_SU);
>  					lsuflag = 1;
> +					opts[OPT_L].subopt_params[L_SU].value =
> +							lsu;
>  					break;
>  				case L_SUNIT:
>  					lsunit = getnum(value, &opts[OPT_L],
>  								L_SUNIT);
>  					lsunitflag = 1;
> +					opts[OPT_L].subopt_params[L_SUNIT].value =
> +							lsunit;
>  					break;
>  				case L_NAME:
>  				case L_DEV:
> @@ -1753,22 +1832,32 @@ main(
>  					xi.logname = logfile;
>  					ldflag = 1;
>  					loginternal = 0;
> +					opts[OPT_L].subopt_params[L_NAME].value = 1;
> +					opts[OPT_L].subopt_params[L_DEV].value = 1;
>  					break;
>  				case L_VERSION:
>  					sb_feat.log_version =
>  						getnum(value, &opts[OPT_L],
>  								L_VERSION);
>  					lvflag = 1;
> +					opts[OPT_L].subopt_params[L_VERSION].value =
> +							sb_feat.log_version;
>  					break;
>  				case L_SIZE:
>  					logbytes = getnum(value, &opts[OPT_L],
>  								L_SIZE);
> +					opts[OPT_L].subopt_params[L_SIZE].value =
> +							logbytes;
>  					break;
>  				case L_SECTLOG:
>  					lsectorlog = getnum(value, &opts[OPT_L],
>  							    L_SECTLOG);
>  					lsectorsize = 1 << lsectorlog;
>  					lslflag = 1;
> +					opts[OPT_L].subopt_params[L_SECTSIZE].value =
> +							lsectorsize;
> +					opts[OPT_L].subopt_params[L_SECTLOG].value =
> +							lsectorlog;
>  					break;
>  				case L_SECTSIZE:
>  					lsectorsize = getnum(value, &opts[OPT_L],
> @@ -1776,11 +1865,17 @@ main(
>  					lsectorlog =
>  						libxfs_highbit32(lsectorsize);
>  					lssflag = 1;
> +					opts[OPT_L].subopt_params[L_SECTSIZE].value =
> +							lsectorsize;
> +					opts[OPT_L].subopt_params[L_SECTLOG].value =
> +							lsectorlog;
>  					break;
>  				case L_LAZYSBCNTR:
>  					sb_feat.lazy_sb_counters =
>  							getnum(value, &opts[OPT_L],
>  							       L_LAZYSBCNTR);
> +					opts[OPT_L].subopt_params[L_LAZYSBCNTR].value =
> +							sb_feat.lazy_sb_counters;
>  					break;
>  				default:
>  					unknown('l', value);
> @@ -1805,20 +1900,27 @@ main(
>  								M_CRC);
>  					if (sb_feat.crcs_enabled)
>  						sb_feat.dirftype = true;
> +					opts[OPT_M].subopt_params[M_CRC].value =
> +							sb_feat.crcs_enabled;
>  					break;
>  				case M_FINOBT:
>  					sb_feat.finobt = getnum(
>  						value, &opts[OPT_M], M_FINOBT);
> +					opts[OPT_M].subopt_params[M_FINOBT].value =
> +							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");
> +					opts[OPT_M].subopt_params[M_UUID].value = 1;
>  					break;
>  				case M_RMAPBT:
>  					sb_feat.rmapbt = getnum(
>  						value, &opts[OPT_M], M_RMAPBT);
> +					opts[OPT_M].subopt_params[M_RMAPBT].value = 

trailing whitespace above ^^^

> +						sb_feat.rmapbt;
>  					break;
>  				case M_REFLINK:
>  					sb_feat.reflink = getnum(
> @@ -1841,6 +1943,10 @@ main(
>  							     N_LOG);
>  					dirblocksize = 1 << dirblocklog;
>  					nlflag = 1;
> +					opts[OPT_N].subopt_params[N_SIZE].value =
> +							dirblocksize;
> +					opts[OPT_N].subopt_params[N_LOG].value =
> +							dirblocklog;
>  					break;
>  				case N_SIZE:
>  					dirblocksize = getnum(value, &opts[OPT_N],
> @@ -1848,6 +1954,10 @@ main(
>  					dirblocklog =
>  						libxfs_highbit32(dirblocksize);
>  					nsflag = 1;
> +					opts[OPT_N].subopt_params[N_SIZE].value =
> +							dirblocksize;
> +					opts[OPT_N].subopt_params[N_LOG].value =
> +							dirblocklog;
>  					break;
>  				case N_VERSION:
>  					value = getstr(value, &opts[OPT_N],
> @@ -1861,10 +1971,14 @@ main(
>  							       N_VERSION);
>  					}
>  					nvflag = 1;
> +					opts[OPT_N].subopt_params[N_VERSION].value =
> +							sb_feat.dir_version;
>  					break;
>  				case N_FTYPE:
>  					sb_feat.dirftype = getnum(value, &opts[OPT_N],
>  								  N_FTYPE);
> +					opts[OPT_N].subopt_params[N_FTYPE].value =
> +							sb_feat.dirftype;
>  					break;
>  				default:
>  					unknown('n', value);
> @@ -1895,23 +2009,33 @@ main(
>  				case R_EXTSIZE:
>  					rtextbytes = getnum(value, &opts[OPT_R],
>  								R_EXTSIZE);
> +					opts[OPT_R].subopt_params[R_EXTSIZE].value =
> +							rtextbytes;
>  					break;
>  				case R_FILE:
>  					xi.risfile = getnum(value, &opts[OPT_R],
>  							    R_FILE);
> +					opts[OPT_R].subopt_params[R_FILE].value =
> +							xi.risfile;
>  					break;
>  				case R_NAME:
>  				case R_DEV:
>  					xi.rtname = getstr(value, &opts[OPT_R],
>  							   R_NAME);
> +					opts[OPT_R].subopt_params[R_NAME].value = 1;
> +					opts[OPT_R].subopt_params[R_DEV].value = 1;
>  					break;
>  				case R_SIZE:
>  					rtbytes = getnum(value, &opts[OPT_R],
>  								R_SIZE);
> +					opts[OPT_R].subopt_params[R_SIZE].value =
> +							rtbytes;
>  					break;
>  				case R_NOALIGN:
>  					norsflag = getnum(value, &opts[OPT_R],
>  								R_NOALIGN);
> +					opts[OPT_R].subopt_params[R_NOALIGN].value =
> +							norsflag;
>  					break;
>  				default:
>  					unknown('r', value);
> @@ -1936,6 +2060,10 @@ main(
>  					sectorsize = 1 << sectorlog;
>  					lsectorsize = sectorsize;
>  					lslflag = slflag = 1;
> +					opts[OPT_S].subopt_params[S_LOG].value =
> +							sectorsize;
> +					opts[OPT_S].subopt_params[S_SECTLOG].value =
> +							sectorsize;
>  					break;
>  				case S_SIZE:
>  				case S_SECTSIZE:
> @@ -1949,6 +2077,10 @@ main(
>  						libxfs_highbit32(sectorsize);
>  					lsectorlog = sectorlog;
>  					lssflag = ssflag = 1;
> +					opts[OPT_S].subopt_params[S_SIZE].value =
> +							sectorlog;
> +					opts[OPT_S].subopt_params[S_SECTSIZE].value =
> +							sectorlog;
>  					break;
>  				default:
>  					unknown('s', value);
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum
  2016-12-07 13:27 ` [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum Jan Tulak
@ 2017-01-13 16:56   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 16:56 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:08PM +0100, 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>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 88 +++++++++++++++++++++++++--------------------------------
>  1 file changed, 38 insertions(+), 50 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index affa405..b3bc218 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -1417,7 +1417,7 @@ main(
>  	char			*dfile;
>  	int			dirblocklog;
>  	int			dirblocksize;
> -	char			*dsize;
> +	__uint64_t 		dbytes;
>  	int			dsu;
>  	int			dsw;
>  	int			dsunit;
> @@ -1441,7 +1441,7 @@ main(
>  	xfs_rfsblock_t		logblocks;
>  	char			*logfile;
>  	int			loginternal;
> -	char			*logsize;
> +	__uint64_t 		logbytes;
>  	xfs_fsblock_t		logstart;
>  	int			lvflag;
>  	int			lsflag;
> @@ -1470,11 +1470,11 @@ main(
>  	char			*protostring;
>  	int			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;
>  	int			sectorlog;
>  	__uint64_t		sector_mask;
> @@ -1522,7 +1522,8 @@ main(
>  	qflag = 0;
>  	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 = 0;
>  	force_overwrite = 0;
> @@ -1586,7 +1587,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);
> @@ -1731,7 +1732,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,
> @@ -1860,8 +1861,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,
> @@ -1873,7 +1873,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,
> @@ -1976,14 +1976,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,
> +		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)
> @@ -2164,10 +2164,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 %lld, not a multiple of %d\n"),
> @@ -2196,10 +2193,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 %lld, not a multiple of %d\n"),
> @@ -2213,10 +2207,7 @@ _("rmapbt not supported with realtime devices\n"));
>  				(long long)logbytes, blocksize,
>  				(long long)(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 %lld, not a multiple of %d\n"),
> @@ -2233,10 +2224,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 %lld, not a multiple of %d\n"),
> @@ -2253,7 +2241,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;
> @@ -2364,15 +2352,15 @@ _("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, "
> +			_("size %lld specified for data subvolume is too large, "
>  			"maximum is %lld blocks\n"),
> -			dsize, (long long)DTOBT(xi.dsize));
> +			(long long)dbytes, (long long)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();
>  	}
> @@ -2405,22 +2393,22 @@ 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 %u 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, "
> +			_("size %lld specified for rt subvolume is too large, "
>  			"maximum is %lld blocks\n"),
> -			rtsize, (long long)DTOBT(xi.rtsize));
> +			(long long)rtbytes, (long long)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();
> @@ -2625,26 +2613,26 @@ an AG size that is one stripe unit smaller, for example %llu.\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 %lld blocks\n"),
> -			logsize, (long long)DTOBT(xi.logBBsize));
> +_("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"),
> +			(long long)logbytes, (long long)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 %lld too large for internal log\n"),
>  			(long long)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. */
> @@ -2708,7 +2696,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
>  		 * 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.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 02/22] mkfs: merge tables for opts parsing into one table
  2016-12-07 13:27 ` [PATCH 02/22] mkfs: merge tables for opts parsing into one table Jan Tulak
@ 2017-01-13 16:57   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 16:57 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:09PM +0100, 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>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 1250 ++++++++++++++++++++++++++++---------------------------
>  1 file changed, 642 insertions(+), 608 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index b3bc218..372c620 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -42,6 +42,7 @@ static int  ispow2(unsigned int i);
>  unsigned int		blocksize;
>  unsigned int		sectorsize;
>  
> +#define MAX_OPTS	16
>  #define MAX_SUBOPTS	16
>  #define SUBOPT_NEEDS_VAL	(-1LL)
>  #define MAX_CONFLICTS	8
> @@ -52,6 +53,10 @@ unsigned int		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'.
>   *
> @@ -112,6 +117,7 @@ unsigned int		sectorsize;
>   *     value in any case.
>   */
>  struct opt_params {
> +	int		index;
>  	const char	name;
>  	const char	*subopts[MAX_SUBOPTS];
>  
> @@ -126,584 +132,592 @@ struct opt_params {
>  		long long	maxval;
>  		long long	defaultval;
>  	}		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,
> -		  .defaultval = 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,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		.subopt_params = {
> +			{ .index = B_LOG,
> +			  .conflicts = { B_SIZE,
> +					 LAST_CONFLICT },
> +			  .minval = XFS_MIN_BLOCKSIZE_LOG,
> +			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> +			  .defaultval = 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,
> +			  .defaultval = 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,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = D_FILE,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 1,
> -		},
> -		{ .index = D_NAME,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = D_SIZE,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .convert = true,
> -		  .minval = XFS_AG_MIN_BYTES,
> -		  .maxval = LLONG_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = D_SUNIT,
> -		  .conflicts = { D_NOALIGN,
> -				 D_SU,
> -				 D_SW,
> -				 LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = D_SWIDTH,
> -		  .conflicts = { D_NOALIGN,
> -				 D_SU,
> -				 D_SW,
> -				 LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = D_AGSIZE,
> -		  .conflicts = { D_AGCOUNT,
> -				 LAST_CONFLICT },
> -		  .convert = true,
> -		  .minval = XFS_AG_MIN_BYTES,
> -		  .maxval = XFS_AG_MAX_BYTES,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = D_SU,
> -		  .conflicts = { D_NOALIGN,
> -				 D_SUNIT,
> -				 D_SWIDTH,
> -				 LAST_CONFLICT },
> -		  .convert = true,
> -		  .minval = 0,
> -		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = D_SW,
> -		  .conflicts = { D_NOALIGN,
> -				 D_SUNIT,
> -				 D_SWIDTH,
> -				 LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = UINT_MAX,
> -		  .defaultval = 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,
> -		},
> -		{ .index = D_SECTSIZE,
> -		  .conflicts = { D_SECTLOG,
> -				 LAST_CONFLICT },
> -		  .convert = true,
> -		  .is_power_2 = true,
> -		  .minval = XFS_MIN_SECTORSIZE,
> -		  .maxval = XFS_MAX_SECTORSIZE,
> -		  .defaultval = 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,
> -		  .defaultval = 1,
> -		},
> -		{ .index = D_RTINHERIT,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 1,
> -		  .maxval = 1,
> -		  .defaultval = 1,
> -		},
> -		{ .index = D_PROJINHERIT,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = D_EXTSZINHERIT,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = UINT_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		.subopt_params = {
> +			{ .index = D_AGCOUNT,
> +			  .conflicts = { D_AGSIZE,
> +					 LAST_CONFLICT },
> +			  .minval = 1,
> +			  .maxval = XFS_MAX_AGNUMBER,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = D_FILE,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			},
> +			{ .index = D_NAME,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = D_SIZE,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .convert = true,
> +			  .minval = XFS_AG_MIN_BYTES,
> +			  .maxval = LLONG_MAX,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = D_SUNIT,
> +			  .conflicts = { D_NOALIGN,
> +					 D_SU,
> +					 D_SW,
> +					 LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = UINT_MAX,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = D_SWIDTH,
> +			  .conflicts = { D_NOALIGN,
> +					 D_SU,
> +					 D_SW,
> +					 LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = UINT_MAX,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = D_AGSIZE,
> +			  .conflicts = { D_AGCOUNT,
> +					 LAST_CONFLICT },
> +			  .convert = true,
> +			  .minval = XFS_AG_MIN_BYTES,
> +			  .maxval = XFS_AG_MAX_BYTES,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = D_SU,
> +			  .conflicts = { D_NOALIGN,
> +					 D_SUNIT,
> +					 D_SWIDTH,
> +					 LAST_CONFLICT },
> +			  .convert = true,
> +			  .minval = 0,
> +			  .maxval = UINT_MAX,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = D_SW,
> +			  .conflicts = { D_NOALIGN,
> +					 D_SUNIT,
> +					 D_SWIDTH,
> +					 LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = UINT_MAX,
> +			  .defaultval = 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,
> +			},
> +			{ .index = D_SECTSIZE,
> +			  .conflicts = { D_SECTLOG,
> +					 LAST_CONFLICT },
> +			  .convert = true,
> +			  .is_power_2 = true,
> +			  .minval = XFS_MIN_SECTORSIZE,
> +			  .maxval = XFS_MAX_SECTORSIZE,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = D_NOALIGN,
> +			  .conflicts = { D_SU,
> +					 D_SW,
> +					 D_SUNIT,
> +					 D_SWIDTH,
> +					 LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			},
> +			{ .index = D_RTINHERIT,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 1,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			},
> +			{ .index = D_PROJINHERIT,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = UINT_MAX,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = D_EXTSZINHERIT,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = UINT_MAX,
> +			  .defaultval = 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,
> -		  .defaultval = 1,
> -		},
> -		{ .index = I_LOG,
> -		  .conflicts = { I_PERBLOCK,
> -				 I_SIZE,
> -				 LAST_CONFLICT },
> -		  .minval = XFS_DINODE_MIN_LOG,
> -		  .maxval = XFS_DINODE_MAX_LOG,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +			"sparse",
> +			NULL
>  		},
> -		{ .index = I_MAXPCT,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 100,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		.subopt_params = {
> +			{ .index = I_ALIGN,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			},
> +			{ .index = I_LOG,
> +			  .conflicts = { I_PERBLOCK,
> +					 I_SIZE,
> +					 LAST_CONFLICT },
> +			  .minval = XFS_DINODE_MIN_LOG,
> +			  .maxval = XFS_DINODE_MAX_LOG,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = I_MAXPCT,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 100,
> +			  .defaultval = 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,
> +			  .defaultval = 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,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = I_ATTR,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 2,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = I_PROJID32BIT,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			},
> +			{ .index = I_SPINODES,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			},
>  		},
> -		{ .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,
> -		  .defaultval = 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,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = I_ATTR,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 2,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = I_PROJID32BIT,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 1,
> -		},
> -		{ .index = I_SPINODES,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 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,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +#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_INTERNAL,
> -		  .conflicts = { L_FILE,
> -				 L_DEV,
> -				 LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 1,
> +		.subopt_params = {
> +			{ .index = L_AGNUM,
> +			  .conflicts = { L_DEV,
> +					 LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = UINT_MAX,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = L_INTERNAL,
> +			  .conflicts = { L_FILE,
> +					 L_DEV,
> +					 LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 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,
> +			},
> +			{ .index = L_VERSION,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 1,
> +			  .maxval = 2,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = L_SUNIT,
> +			  .conflicts = { L_SU,
> +					 LAST_CONFLICT },
> +			  .minval = 1,
> +			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = L_SU,
> +			  .conflicts = { L_SUNIT,
> +					 LAST_CONFLICT },
> +			  .convert = true,
> +			  .minval = BBTOB(1),
> +			  .maxval = XLOG_MAX_RECORD_BSIZE,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = L_DEV,
> +			  .conflicts = { L_AGNUM,
> +					 L_INTERNAL,
> +					 LAST_CONFLICT },
> +			  .defaultval = 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,
> +			},
> +			{ .index = L_SECTSIZE,
> +			  .conflicts = { L_SECTLOG,
> +					 LAST_CONFLICT },
> +			  .convert = true,
> +			  .is_power_2 = true,
> +			  .minval = XFS_MIN_SECTORSIZE,
> +			  .maxval = XFS_MAX_SECTORSIZE,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = L_FILE,
> +			  .conflicts = { L_INTERNAL,
> +					 LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			},
> +			{ .index = L_NAME,
> +			  .conflicts = { L_AGNUM,
> +					 L_INTERNAL,
> +					 LAST_CONFLICT },
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = L_LAZYSBCNTR,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 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,
> -		},
> -		{ .index = L_VERSION,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 1,
> -		  .maxval = 2,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = L_SUNIT,
> -		  .conflicts = { L_SU,
> -				 LAST_CONFLICT },
> -		  .minval = 1,
> -		  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = L_SU,
> -		  .conflicts = { L_SUNIT,
> -				 LAST_CONFLICT },
> -		  .convert = true,
> -		  .minval = BBTOB(1),
> -		  .maxval = XLOG_MAX_RECORD_BSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = L_DEV,
> -		  .conflicts = { L_AGNUM,
> -				 L_INTERNAL,
> -				 LAST_CONFLICT },
> -		  .defaultval = 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,
> -		},
> -		{ .index = L_SECTSIZE,
> -		  .conflicts = { L_SECTLOG,
> -				 LAST_CONFLICT },
> -		  .convert = true,
> -		  .is_power_2 = true,
> -		  .minval = XFS_MIN_SECTORSIZE,
> -		  .maxval = XFS_MAX_SECTORSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = L_FILE,
> -		  .conflicts = { L_INTERNAL,
> -				 LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 1,
> -		},
> -		{ .index = L_NAME,
> -		  .conflicts = { L_AGNUM,
> -				 L_INTERNAL,
> -				 LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = L_LAZYSBCNTR,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 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,
> -		  .defaultval = 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_SIZE,
> -		  .conflicts = { N_LOG,
> -				 LAST_CONFLICT },
> -		  .convert = true,
> -		  .is_power_2 = true,
> -		  .minval = 1 << XFS_MIN_REC_DIRSIZE,
> -		  .maxval = XFS_MAX_BLOCKSIZE,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = N_VERSION,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 2,
> -		  .maxval = 2,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = N_FTYPE,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 1,
> +		.subopt_params = {
> +			{ .index = N_LOG,
> +			  .conflicts = { N_SIZE,
> +					 LAST_CONFLICT },
> +			  .minval = XFS_MIN_REC_DIRSIZE,
> +			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> +			  .defaultval = 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,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = N_VERSION,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 2,
> +			  .maxval = 2,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = N_FTYPE,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 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,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = R_SIZE,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .convert = true,
> -		  .minval = 0,
> -		  .maxval = LLONG_MAX,
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = R_DEV,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = R_FILE,
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 1,
> -		  .conflicts = { LAST_CONFLICT },
> +#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_NAME,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> +		.subopt_params = {
> +			{ .index = R_EXTSIZE,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .convert = true,
> +			  .minval = XFS_MIN_RTEXTSIZE,
> +			  .maxval = XFS_MAX_RTEXTSIZE,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = R_SIZE,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .convert = true,
> +			  .minval = 0,
> +			  .maxval = LLONG_MAX,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = R_DEV,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = R_FILE,
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			  .conflicts = { LAST_CONFLICT },
> +			},
> +			{ .index = R_NAME,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = R_NOALIGN,
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			  .conflicts = { LAST_CONFLICT },
> +			},
>  		},
> -		{ .index = R_NOALIGN,
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 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,
> -		  .defaultval = 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_SECTLOG,
> -		  .conflicts = { S_SIZE,
> -				 S_SECTSIZE,
> -				 LAST_CONFLICT },
> -		  .minval = XFS_MIN_SECTORSIZE_LOG,
> -		  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -		  .defaultval = 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,
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = S_SECTLOG,
> +			  .conflicts = { S_SIZE,
> +					 S_SECTSIZE,
> +					 LAST_CONFLICT },
> +			  .minval = XFS_MIN_SECTORSIZE_LOG,
> +			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> +			  .defaultval = 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,
> +			  .defaultval = 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,
> +			  .defaultval = 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,
> -		  .defaultval = 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,
> -		  .defaultval = 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,
> -		  .defaultval = 1,
> -		},
> -		{ .index = M_FINOBT,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 1,
> -		},
> -		{ .index = M_UUID,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .defaultval = SUBOPT_NEEDS_VAL,
> -		},
> -		{ .index = M_RMAPBT,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 0,
> +#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_REFLINK,
> -		  .conflicts = { LAST_CONFLICT },
> -		  .minval = 0,
> -		  .maxval = 1,
> -		  .defaultval = 0,
> +		.subopt_params = {
> +			{ .index = M_CRC,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			},
> +			{ .index = M_FINOBT,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 1,
> +			},
> +			{ .index = M_UUID,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .defaultval = SUBOPT_NEEDS_VAL,
> +			},
> +			{ .index = M_RMAPBT,
> +			.conflicts = { LAST_CONFLICT },
> +			.minval = 0,
> +			.maxval = 1,
> +			.defaultval = 0,
> +			},
> +			{ .index = M_REFLINK,
> +			  .conflicts = { LAST_CONFLICT },
> +			  .minval = 0,
> +			  .maxval = 1,
> +			  .defaultval = 0,
> +			},
>  		},
>  	},
>  };
> @@ -1543,17 +1557,18 @@ 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;
> @@ -1566,73 +1581,78 @@ 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,
> +					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,
> +					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,
> +					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,
> +					fsx.fsx_extsize = getnum(value, &opts[OPT_D],
>  								 D_EXTSZINHERIT);
>  					fsx.fsx_xflags |=
>  						XFS_DIFLAG_EXTSZINHERIT;
> @@ -1645,46 +1665,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);
> @@ -1694,54 +1719,59 @@ 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,
> +					xi.lisfile = getnum(value, &opts[OPT_L],
>  							    L_FILE);
>  					break;
>  				case L_INTERNAL:
> -					loginternal = getnum(value, &lopts,
> +					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,
> +					lsectorlog = getnum(value, &opts[OPT_L],
>  							    L_SECTLOG);
>  					lsectorsize = 1 << lsectorlog;
>  					lslflag = 1;
>  					break;
>  				case L_SECTSIZE:
> -					lsectorsize = getnum(value, &lopts,
> +					lsectorsize = getnum(value, &opts[OPT_L],
>  							     L_SECTSIZE);
>  					lsectorlog =
>  						libxfs_highbit32(lsectorsize);
> @@ -1749,7 +1779,7 @@ main(
>  					break;
>  				case L_LAZYSBCNTR:
>  					sb_feat.lazy_sb_counters =
> -							getnum(value, &lopts,
> +							getnum(value, &opts[OPT_L],
>  							       L_LAZYSBCNTR);
>  					break;
>  				default:
> @@ -1765,19 +1795,20 @@ 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')
> @@ -1787,11 +1818,11 @@ 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);
> +						value, &opts[OPT_M], M_REFLINK);
>  					break;
>  				default:
>  					unknown('m', value);
> @@ -1801,37 +1832,38 @@ 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,
> +					dirblocklog = getnum(value, &opts[OPT_N],
>  							     N_LOG);
>  					dirblocksize = 1 << dirblocklog;
>  					nlflag = 1;
>  					break;
>  				case N_SIZE:
> -					dirblocksize = getnum(value, &nopts,
> +					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,
> +					sb_feat.dirftype = getnum(value, &opts[OPT_N],
>  								  N_FTYPE);
>  					break;
>  				default:
> @@ -1856,27 +1888,29 @@ 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,
> +					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:
> @@ -1887,7 +1921,7 @@ 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)) {
> @@ -1896,7 +1930,7 @@ main(
>  					if (lssflag)
>  						conflict('s', subopts,
>  							 S_SECTSIZE, S_SECTLOG);
> -					sectorlog = getnum(value, &sopts,
> +					sectorlog = getnum(value, &opts[OPT_S],
>  							   S_SECTLOG);
>  					lsectorlog = sectorlog;
>  					sectorsize = 1 << sectorlog;
> @@ -1908,7 +1942,7 @@ main(
>  					if (lslflag)
>  						conflict('s', subopts, S_SECTLOG,
>  							 S_SECTSIZE);
> -					sectorsize = getnum(value, &sopts,
> +					sectorsize = getnum(value, &opts[OPT_S],
>  							    S_SECTSIZE);
>  					lsectorsize = sectorsize;
>  					sectorlog =
> @@ -1932,7 +1966,7 @@ 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;
>  
> @@ -2111,7 +2145,7 @@ _("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();
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure
  2016-12-07 13:27 ` [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure Jan Tulak
@ 2017-01-13 17:08   ` Bill O'Donnell
  2017-01-16 12:42     ` Jan Tulak
  0 siblings, 1 reply; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 17:08 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:16PM +0100, Jan Tulak wrote:
> Bring the conflicts detection up to date with conflicts declaration.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

There's a missing definition for check_subopt()
FWIW, I see the call gets removed in patch10.

> ---
>  mkfs/xfs_mkfs.c | 37 +++++++++++++++++++++++++++++++------
>  1 file changed, 31 insertions(+), 6 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 30618ff..d11fad6 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -1372,7 +1372,7 @@ illegal_option(
>   * Check for conflicts and option respecification.
>   */
>  static void
> -check_opt(
> +check_subopt_conflicts(
>  	struct opt_params	*opt,
>  	int			index,
>  	bool			str_seen)
> @@ -1424,7 +1424,7 @@ check_opt(
>   * Check for conflict values between options.
>   */
>  static void
> -check_opt_value(
> +check_subopt_value(
>  	struct opt_params	*opt,
>  	int			index,
>  	long long 		value)
> @@ -1450,6 +1450,32 @@ check_opt_value(
>  	}
>  }
>  
> +/**
> + * Go through entire opt_params table and check every option for valid values
> + * and for conflicts.
> + */
> +static void
> +check_opt(
> +	struct opt_params *opts,
> +	int opti)
> +{
> +	int index;
> +	struct opt_params *opt = &opts[opti];
> +	for (index = 0; index < MAX_SUBOPTS; index++) {
> +		struct subopt_param *sp = &opt->subopt_params[index];
> +		check_subopt_conflicts(opt, index, false);
> +		check_subopt_value(opt, index, sp->value);
> +	}
> +}
> +static void
> +check_all_opts(struct opt_params *opts)
> +{
> +	int opti;
> +	for (opti = 0; opti < MAX_OPTS; opti++) {
> +		check_opt(opts, opti);
> +	}
> +}
> +
>  static long long
>  getnum(
>  	const char		*str,
> @@ -1459,7 +1485,6 @@ getnum(
>  	struct subopt_param	*sp = &opts->subopt_params[index];
>  	long long		c;
>  
> -	check_opt(opts, index, false);
>  	/* empty strings might just return a default value */
>  	if (!str || *str == '\0') {
>  		if (sp->defaultval == SUBOPT_NEEDS_VAL)
> @@ -1493,8 +1518,6 @@ getnum(
>  			illegal_option(str, opts, index, NULL);
>  	}
>  
> -	check_opt_value(opts, index, c);
> -
>  	/* Validity check the result. */
>  	if (c < sp->minval)
>  		illegal_option(str, opts, index, _("value is too small"));
> @@ -1517,7 +1540,7 @@ getstr(
>  	struct opt_params	*opts,
>  	int			index)
>  {
> -	check_opt(opts, index, true);
> +	check_subopt(opts, index, true);

check_subopt is undefined. ^^^

>  
>  	/* empty strings for string options are not valid */
>  	if (!str || *str == '\0')
> @@ -2213,6 +2236,8 @@ main(
>  	} else
>  		dfile = xi.dname;
>  
> +	check_all_opts(opts);
> +
>  	/*
>  	 * Blocksize and sectorsize first, other things depend on them
>  	 * For RAID4/5/6 we want to align sector size and block size,
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 12/22] mkfs: expand conflicts declarations to named declaration
  2016-12-07 13:27 ` [PATCH 12/22] mkfs: expand conflicts declarations to named declaration Jan Tulak
@ 2017-01-13 17:21   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 17:21 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:19PM +0100, Jan Tulak wrote:
> As we are adding more fields, change from positional to named declarations.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

minor whitespace issues.

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 594 +++++++++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 519 insertions(+), 75 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 58cc24a..b0e5d75 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -220,7 +220,7 @@ struct opt_params {
>  			long long	invalid_value;
>  			long long	at_value;
>  			const char	*message;
> -		} 		conflicts [MAX_CONFLICTS];
> +		}		conflicts [MAX_CONFLICTS];
>  		long long	minval;
>  		long long	maxval;
>  		long long	defaultval;
> @@ -237,7 +237,13 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = B_LOG,
> -			  .conflicts = { {OPT_B, B_SIZE, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_B,
> +					  .subopt = B_SIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE_LOG,
>  			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> @@ -246,7 +252,13 @@ struct opt_params {
>  			{ .index = B_SIZE,
>  			  .convert = true,
>  			  .is_power_2 = true,
> -			  .conflicts = { {OPT_B, B_LOG, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_B,
> +					  .subopt = B_LOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE,
> @@ -277,7 +289,13 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = D_AGCOUNT,
> -			  .conflicts = { {OPT_D, D_AGSIZE, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_D,
> +					  .subopt = D_AGSIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = XFS_MAX_AGNUMBER,
> @@ -301,25 +319,67 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SUNIT,
> -			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
> -					 {OPT_D, D_SU, false, false, 0, 0},
> -					 {OPT_D, D_SW, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_D,
> +					  .subopt = D_NOALIGN,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SU,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SW,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SWIDTH,
> -			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
> -					 {OPT_D, D_SU, false, false, 0, 0},
> -					 {OPT_D, D_SW, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_D,
> +					  .subopt = D_NOALIGN,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SU,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SW,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_AGSIZE,
> -			  .conflicts = { {OPT_D, D_AGCOUNT, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_D,
> +					  .subopt = D_AGCOUNT,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = XFS_AG_MIN_BYTES,
> @@ -327,9 +387,27 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SU,
> -			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
> -					 {OPT_D, D_SUNIT, false, false, 0, 0},
> -					 {OPT_D, D_SWIDTH, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_D,
> +					  .subopt = D_NOALIGN,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SUNIT,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SWIDTH,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = 0,
> @@ -337,23 +415,53 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SW,
> -			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
> -					 {OPT_D, D_SUNIT, false, false, 0, 0},
> -					 {OPT_D, D_SWIDTH, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_D,
> +					  .subopt = D_NOALIGN,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SUNIT,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SWIDTH,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SECTLOG,
> -			  .conflicts = { {OPT_D, D_SECTSIZE, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_D,
> +					  .subopt = D_SECTSIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SECTSIZE,
> -			  .conflicts = { {OPT_D, D_SECTLOG, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_D,
> +					  .subopt = D_SECTLOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -362,10 +470,34 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_NOALIGN,
> -			  .conflicts = { {OPT_D, D_SU, false, false, 0, 0},
> -					 {OPT_D, D_SW, false, false, 0, 0},
> -					 {OPT_D, D_SUNIT, false, false, 0, 0},
> -					 {OPT_D, D_SWIDTH, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_D,
> +					  .subopt = D_SU,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SW,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SUNIT,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_D,
> +					  .subopt = D_SWIDTH,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> @@ -407,7 +539,13 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = I_ALIGN,
> -			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
> +			  .conflicts = { {.opt = OPT_M,
> +					  .subopt = M_CRC,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 0,
> +					  .message = \
>  		"Inodes always aligned for CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -415,8 +553,20 @@ struct opt_params {
>  			  .defaultval = 1,
>  			},
>  			{ .index = I_LOG,
> -			  .conflicts = { {OPT_I, I_PERBLOCK, false, false, 0, 0},
> -					 {OPT_I, I_SIZE, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_I,
> +					  .subopt = I_PERBLOCK,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_I,
> +					  .subopt = I_SIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_DINODE_MIN_LOG,
>  			  .maxval = XFS_DINODE_MAX_LOG,
> @@ -429,8 +579,20 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_PERBLOCK,
> -			  .conflicts = { {OPT_I, I_LOG, false, false, 0, 0},
> -					 {OPT_I, I_SIZE, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_I,
> +					  .subopt = I_LOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_I,
> +					  .subopt = I_SIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_INODE_PERBLOCK,
> @@ -438,8 +600,20 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_SIZE,
> -			  .conflicts = { {OPT_I, I_PERBLOCK, false, false, 0, 0},
> -					 {OPT_I, I_LOG, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_I,
> +					  .subopt = I_PERBLOCK,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_I,
> +					  .subopt = I_LOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
>  			  .minval = XFS_DINODE_MIN_SIZE,
> @@ -447,7 +621,13 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_ATTR,
> -			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 1,
> +			  .conflicts = { {.opt = OPT_M,
> +					  .subopt = M_CRC,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 1,
> +					  .message = \
>  		"V2 attribute format always enabled on CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -455,7 +635,13 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_PROJID32BIT,
> -			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
> +			  .conflicts = { {.opt = OPT_M,
> +					  .subopt = M_CRC,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 0,
> +					  .message = \
>  		"32 bit Project IDs always enabled on CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
>  
> @@ -464,7 +650,13 @@ struct opt_params {
>  			  .defaultval = 1,
>  			},
>  			{ .index = I_SPINODES,
> -			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
> +			  .conflicts = { {.opt = OPT_M,
> +					  .subopt = M_CRC,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 0,
> +					  .at_value = 1,
> +					  .message = \
>  		"Sparse inodes not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -493,15 +685,33 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = L_AGNUM,
> -			  .conflicts = { {OPT_L, L_DEV, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_DEV,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_INTERNAL,
> -			  .conflicts = { {OPT_L, L_FILE, false, false, 0, 0},
> -					 {OPT_L, L_DEV, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_FILE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_L,
> +					  .subopt = L_DEV,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> @@ -515,7 +725,13 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_VERSION,
> -			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 1,
> +			  .conflicts = {{.opt = OPT_M,
> +					  .subopt = M_CRC,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 1,
> +					  .message =
>  				"V2 logs are required for CRC enabled filesystems."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
> @@ -523,14 +739,26 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SUNIT,
> -			  .conflicts = { {OPT_L, L_SU, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_SU,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SU,
> -			  .conflicts = { {OPT_L, L_SUNIT, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_SUNIT,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = BBTOB(1),
> @@ -538,20 +766,44 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_DEV,
> -			  .conflicts = { {OPT_L, L_AGNUM, false, false, 0, 0},
> -					 {OPT_L, L_INTERNAL, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_AGNUM,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_L,
> +					  .subopt = L_INTERNAL,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SECTLOG,
> -			  .conflicts = { {OPT_L, L_SECTSIZE, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_SECTSIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SECTSIZE,
> -			  .conflicts = { {OPT_L, L_SECTLOG, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_SECTLOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -560,20 +812,44 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_FILE,
> -			  .conflicts = { {OPT_L, L_INTERNAL, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_INTERNAL,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = L_NAME,
> -			  .conflicts = { {OPT_L, L_AGNUM, false, false, 0, 0},
> -					 {OPT_L, L_INTERNAL, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_AGNUM,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_L,
> +					  .subopt = L_INTERNAL,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_LAZYSBCNTR,
> -			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
> +			  .conflicts = { {.opt = OPT_M,
> +					  .subopt = M_CRC,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 0,
> +					  .message =
>  		"Lazy superblock counted always enabled for CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -594,14 +870,26 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = N_LOG,
> -			  .conflicts = { {OPT_N, N_SIZE, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_N,
> +					  .subopt = N_SIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_REC_DIRSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = N_SIZE,
> -			  .conflicts = { {OPT_N, N_LOG, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_N,
> +					  .subopt = N_LOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -616,7 +904,13 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = N_FTYPE,
> -			  .conflicts = {  {OPT_M, M_CRC, true, true, 1, 0,
> +			  .conflicts = {  {.opt = OPT_M,
> +					  .subopt = M_CRC,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 0,
> +					  .message =
>  		"Cannot disable ftype with crcs enabled."},
>  					  {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -653,7 +947,13 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_DEV,
> -			  .conflicts = { {OPT_M, M_RMAPBT, false, true, 0, 0,
> +			  .conflicts = { {.opt = OPT_M,
> +				  	  .subopt = M_RMAPBT,

whitespace issue above ^^^

> +					  .test_values = false,
> +					  .test_default_value = true,
> +					  .invalid_value = 0,
> +					  .at_value = 0,
> +					  .message =
>  		"rmapbt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -665,7 +965,13 @@ struct opt_params {
>  			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  			{ .index = R_NAME,
> -			  .conflicts = { {OPT_M, M_RMAPBT, false, true, 0, 0,
> +			  .conflicts = { {.opt = OPT_M,
> +				  	  .subopt = M_RMAPBT,

whitespace issue above ^^^

> +					  .test_values = false,
> +					  .test_default_value = true,
> +					  .invalid_value = 0,
> +					  .at_value = 0,
> +					  .message =
>  		"rmapbt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -690,24 +996,60 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = S_LOG,
> -			  .conflicts = { {OPT_S, S_SIZE, false, false, 0, 0},
> -					 {OPT_S, S_SECTSIZE, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_S,
> +					  .subopt = S_SIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_S,
> +					  .subopt = S_SECTSIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SECTLOG,
> -			  .conflicts = { {OPT_S, S_SIZE, false, false, 0, 0},
> -					 {OPT_S, S_SECTSIZE, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_S,
> +					  .subopt = S_SIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_S,
> +					  .subopt = S_SECTSIZE,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SIZE,
> -			  .conflicts = { {OPT_S, S_LOG, false, false, 0, 0},
> -					 {OPT_S, S_SECTLOG, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_S,
> +					  .subopt = S_LOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_S,
> +					  .subopt = S_SECTLOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -716,8 +1058,20 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SECTSIZE,
> -			  .conflicts = { {OPT_S, S_LOG, false, false, 0, 0},
> -					 {OPT_S, S_SECTLOG, false, false, 0, 0},
> +			  .conflicts = { {.opt = OPT_S,
> +					  .subopt = S_LOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
> +					 {.opt = OPT_S,
> +					  .subopt = S_SECTLOG,
> +					  .test_values = false,
> +					  .test_default_value = false,
> +					  .invalid_value = 0,
> +					  .at_value = 0
> +					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -740,25 +1094,85 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = M_CRC,
> -			  .conflicts = { {OPT_L, L_VERSION, true, true, 1, 1,
> +			  .conflicts = { {.opt = OPT_L,
> +					  .subopt = L_VERSION,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 1,
> +					  .message =
>  		"V2 logs are required for CRC enabled filesystems."},
> -					 {OPT_I, I_ALIGN, false, true, 0, 1,
> +					 {.opt = OPT_I,
> +					  .subopt = I_ALIGN,
> +					  .test_values = false,
> +					  .test_default_value = true,
> +					  .invalid_value = 0,
> +					  .at_value = 1,
> +					  .message =
>  		"Inodes always aligned for CRC enabled filesytems."},
> -					 {OPT_I, I_PROJID32BIT, true, true, 0, 1,
> +					 {.opt = OPT_I,
> +					  .subopt = I_PROJID32BIT,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 0,
> +					  .at_value = 1,
> +					  .message =
>  		"32 bit Project IDs always enabled on CRC enabled filesytems."},
> -					 {OPT_I, I_ATTR, true, true, 1, 1,
> +					 {.opt = OPT_I,
> +					  .subopt = I_ATTR,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 1,
> +					  .message =
>  		"V2 attribute format always enabled on CRC enabled filesytems."},
> -					 {OPT_L, L_LAZYSBCNTR, true, true, 0, 1,
> +					 {.opt = OPT_L,
> +					  .subopt = L_LAZYSBCNTR,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 0,
> +					  .at_value = 1,
> +					  .message =
>  		"Lazy superblock counted always enabled for CRC enabled filesytems."},
> -					 {OPT_M, M_FINOBT, true, true, 1, 0,
> +					 {.opt = OPT_M,
> +					  .subopt = M_FINOBT,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 0,
> +					  .message =
>  		"Finobt not supported without CRC support."},
> -					 {OPT_M, M_RMAPBT, true, true, 1, 0,
> +					 {.opt = OPT_M,
> +				  	  .subopt = M_RMAPBT,

minor whitespace issue above ^^^

> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 0,
> +					  .message =
>  		"rmapbt not supported without CRC support."},
> -					 {OPT_M, M_REFLINK, true, true, 1, 0,
> +					 {.opt = OPT_M,
> +				  	  .subopt = M_REFLINK,

minor whitespace issue above ^^^

> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 0,
> +					  .message =
>  		"reflink not supported without CRC support."},
> -					 {OPT_I, I_SPINODES, true, true, 1, 0,
> +					 {.opt = OPT_I,
> +					  .subopt = I_SPINODES,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 1,
> +					  .at_value = 0,
> +					  .message =
>  		"Sparse inodes not supported without CRC support."},
> -					 {OPT_N, N_FTYPE, true, true, 0, 1,
> +					 {.opt = OPT_N,
> +					  .subopt = N_FTYPE,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 0,
> +					  .at_value = 1,
> +					  .message =
>  		"Cannot disable ftype with crcs enabled."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -766,7 +1180,13 @@ struct opt_params {
>  			  .defaultval = 1,
>  			},
>  			{ .index = M_FINOBT,
> -			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
> +			  .conflicts = { {.opt = OPT_M,
> +					  .subopt = M_CRC,
> +					  .test_values = true,
> +					  .test_default_value = true,
> +					  .invalid_value = 0,
> +					  .at_value = 1,
> +					  .message =
>  		"Finobt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -778,11 +1198,29 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = M_RMAPBT,
> -			.conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
> +			.conflicts = { {.opt = OPT_M,
> +					.subopt = M_CRC,
> +					.test_values = true,
> +					.test_default_value = true,
> +					.invalid_value = 0,
> +					.at_value = 1,
> +					.message =
>  		"rmapbt not supported without CRC support."},
> -					{OPT_R, R_NAME, false, true, 0, 0,
> +					{.opt = OPT_R,
> +					 .subopt = R_NAME,
> +					 .test_values = false,
> +					 .test_default_value = true,
> +					 .invalid_value = 0,
> +					 .at_value = 0,
> +					 .message =
>  		"rmapbt not supported with realtime devices."},
> -					{OPT_R, R_DEV, false, true, 0, 0,
> +					{.opt = OPT_R,
> +					 .subopt = R_DEV,
> +					 .test_values = false,
> +					 .test_default_value = true,
> +					 .invalid_value = 0,
> +					 .at_value = 0,
> +					 .message =
>  		"rmapbt not supported with realtime devices."},
>  				       {LAST_CONFLICT} },
>  			.minval = 0,
> @@ -790,7 +1228,13 @@ struct opt_params {
>  			.defaultval = 0,
>  			},
>  			{ .index = M_REFLINK,
> -			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
> +			.conflicts = { {.opt = OPT_M,
> +					.subopt = M_CRC,
> +					.test_values = true,
> +					.test_default_value = true,
> +					.invalid_value = 0,
> +					.at_value = 1,
> +					.message =
>  		"reflink not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 16/22] mkfs: Change all value fields in opt structures into unions
  2016-12-07 13:27 ` [PATCH 16/22] mkfs: Change all value fields in opt structures into unions Jan Tulak
@ 2017-01-13 17:36   ` Bill O'Donnell
  2017-01-16 12:44     ` Jan Tulak
  0 siblings, 1 reply; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 17:36 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:23PM +0100, Jan Tulak wrote:
> Trying to cover all possible values in a single data type is impossible,
> so convert the field from long long type to union. This requires
> also some small changes in supporting code, otherwise it would not compile.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> ---
>  mkfs/xfs_mkfs.c | 812 +++++++++++++++++++++++++++++++++++---------------------
>  1 file changed, 504 insertions(+), 308 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 7ffe8ff..afc63d1 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -121,6 +121,231 @@ unsigned int		sectorsize;
>  #define M_RMAPBT	3
>  #define M_REFLINK	4
>  
> +enum e_type {
> +	TYPE_UNDEF,
> +	LONGLONG,
> +	BOOL,
> +	UINT64,
> +	INT,
> +	UINT,
> +	STRING
> +};
> +union u_value {
> +	long long 	ll;
> +	bool		b;
> +	__uint64_t	uint64;
> +	int		i;
> +	unsigned int	u;
> +	char		*s;
> +};
> +static bool
> +cmp_uvalues_gt(enum e_type a_type, union u_value a, enum e_type b_type, union u_value b) {
> +	if (a_type == STRING || b_type == STRING) {
> +		if (a_type == b_type)
> +			return strcmp(a.s, b.s);
> +		return false;
> +	}	switch(a_type){
> +	case LONGLONG:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.ll > b.ll;
> +		case BOOL:
> +			return a.ll > b.b;
> +		case UINT64:
> +			return a.ll > b.uint64;
> +		case INT:
> +			return a.ll > b.i;
> +		case UINT:
> +			return a.ll > b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	case BOOL:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.b > b.ll;
> +		case BOOL:
> +			return a.b > b.b;
> +		case UINT64:
> +			return a.b > b.uint64;
> +		case INT:
> +			return a.b > b.i;
> +		case UINT:
> +			return a.b > b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	case UINT64:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.uint64 > b.ll;
> +		case BOOL:
> +			return a.uint64 > b.b;
> +		case UINT64:
> +			return a.uint64 > b.uint64;
> +		case INT:
> +			return a.uint64 > b.i;
> +		case UINT:
> +			return a.uint64 > b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	case INT:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.i > b.ll;
> +		case BOOL:
> +			return a.i > b.b;
> +		case UINT64:
> +			return a.i > b.uint64;
> +		case INT:
> +			return a.i > b.i;
> +		case UINT:
> +			return a.i > b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	case UINT:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.u > b.ll;
> +		case BOOL:
> +			return a.u > b.b;
> +		case UINT64:
> +			return a.u > b.uint64;
> +		case INT:
> +			return a.u > b.i;
> +		case UINT:
> +			return a.u > b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	default:
> +		return false;
> +	};
> +
> +	return false;
> +}
> +static bool
> +cmp_uvalue_gt_num(enum e_type a_type, union u_value a, long long b) {
> +	union u_value u;
> +	u.ll = b;
> +	return cmp_uvalues_gt(a_type, a, LONGLONG, u);
> +}
> +static bool
> +cmp_uvalue_lt_num(enum e_type a_type, union u_value a, long long b) {
> +	union u_value u;
> +	u.ll = b;
> +	return cmp_uvalues_gt(LONGLONG, u, a_type, a);
> +}
> +
> +static bool
> +test_uvalues(enum e_type a_type, union u_value a, enum e_type b_type, union u_value b) {
> +	if (a_type == STRING || b_type == STRING) {
> +		if (a_type == b_type)
> +			return strcmp(a.s, b.s) == 0;
> +		return false;
> +	}
> +	switch(a_type){
> +	case LONGLONG:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.ll == b.ll;
> +		case BOOL:
> +			return a.ll == b.b;
> +		case UINT64:
> +			return a.ll == b.uint64;
> +		case INT:
> +			return a.ll == b.i;
> +		case UINT:
> +			return a.ll == b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	case BOOL:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.b == b.ll;
> +		case BOOL:
> +			return a.b == b.b;
> +		case UINT64:
> +			return a.b == b.uint64;
> +		case INT:
> +			return a.b == b.i;
> +		case UINT:
> +			return a.b == b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	case UINT64:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.uint64 == b.ll;
> +		case BOOL:
> +			return a.uint64 == b.b;
> +		case UINT64:
> +			return a.uint64 == b.uint64;
> +		case INT:
> +			return a.uint64 == b.i;
> +		case UINT:
> +			return a.uint64 == b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	case INT:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.i == b.ll;
> +		case BOOL:
> +			return a.i == b.b;
> +		case UINT64:
> +			return a.i == b.uint64;
> +		case INT:
> +			return a.i == b.i;
> +		case UINT:
> +			return a.i == b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	case UINT:
> +		switch(b_type){
> +		case LONGLONG:
> +			return a.u == b.ll;
> +		case BOOL:
> +			return a.u == b.b;
> +		case UINT64:
> +			return a.u == b.uint64;
> +		case INT:
> +			return a.u == b.i;
> +		case UINT:
> +			return a.u == b.u;
> +		default:
> +			return false;
> +		};
> +		break;
> +	default:
> +		return false;
> +	};
> +
> +	return false;
> +}
> +
> +static bool
> +test_uvalue_num(enum e_type a_type, union u_value a, long long b) {
> +	union u_value u;
> +	u.ll = b;
> +	return test_uvalues(a_type, a, LONGLONG, u);
> +}
> +
>  /*
>   * Table for parsing mkfs parameters.
>   *
> @@ -193,11 +418,15 @@ unsigned int		sectorsize;
>   *     If the subopt accepts some values (-d file=[1|0]), then this
>   *     sets what is used with simple specifying the subopt (-d file).
>   *
> - *   value INTERNAL
> - *     Do not set this on initialization. Use flagval for what you want
> - *     to do. This is filled with user input and anything you write here now
> - *     is overwritten. (If the user input is a string and not a number, this
> - *     value is set to a positive non-zero number.)
> + *   value MANDATORY
> + *     A value that is used for given field as a default if user doesn't specify
> + *     any change. This is filled with user input and anything you write here
> + *     now is overwritten if the user specifies given option.
> + *
> + *   type MANDATORY
> + *     An enum of what type the values are. Affects every u_value field within
> + *     the suboption except conflict's .invalid_value - this one uses the
> + *     "remote" type.
>   *
>   *   needs_val OPTIONAL
>   *     Set to true if, when user specifies the option, she has to specify
> @@ -219,14 +448,15 @@ struct opt_params {
>  			int		subopt;
>  			bool		test_values;
>  			bool		test_default_value;
> -			long long	invalid_value;
> -			long long	at_value;
> +			union u_value	invalid_value;
> +			union u_value	at_value;
>  			const char	*message;
>  		}		conflicts [MAX_CONFLICTS];
> -		long long	minval;
> -		long long	maxval;
> -		long long	flagval;
> -		long long	value;
> +		union u_value	minval;
> +		union u_value	maxval;
> +		union u_value	flagval;
> +		union u_value value;
> +		enum e_type 	type;
>  		bool		needs_val;
>  	}		subopt_params[MAX_SUBOPTS];
>  } opts[MAX_OPTS] = {
> @@ -244,9 +474,10 @@ struct opt_params {
>  					  .subopt = B_SIZE,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = XFS_MIN_BLOCKSIZE_LOG,
> -			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> +			  .minval.i = XFS_MIN_BLOCKSIZE_LOG,
> +			  .maxval.i = XFS_MAX_BLOCKSIZE_LOG,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = B_SIZE,
>  			  .convert = true,
> @@ -255,9 +486,10 @@ struct opt_params {
>  					  .subopt = B_LOG,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = XFS_MIN_BLOCKSIZE,
> -			  .maxval = XFS_MAX_BLOCKSIZE,
> +			  .minval.u = XFS_MIN_BLOCKSIZE,
> +			  .maxval.u = XFS_MAX_BLOCKSIZE,
>  			  .needs_val = true,
> +			  .type = UINT,
>  			},
>  		},
>  	},
> @@ -288,26 +520,30 @@ struct opt_params {
>  					  .subopt = D_AGSIZE,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = 1,
> -			  .maxval = XFS_MAX_AGNUMBER,
> +			  .minval.uint64 = 1,
> +			  .maxval.uint64 = XFS_MAX_AGNUMBER,
>  			  .needs_val = true,
> +			  .type = UINT64,
>  			},
>  			{ .index = D_FILE,
>  			  .conflicts = { {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.i = 0,
> +			  .maxval.i = 1,
> +			  .flagval.i = 1,
> +			  .type = INT,
>  			},
>  			{ .index = D_NAME,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .needs_val = true,
> +			  .type = STRING,
>  			},
>  			{ .index = D_SIZE,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
> -			  .minval = XFS_AG_MIN_BYTES,
> -			  .maxval = LLONG_MAX,
> +			  .minval.uint64 = XFS_AG_MIN_BYTES,
> +			  .maxval.uint64 = LLONG_MAX,
>  			  .needs_val = true,
> +			  .type = UINT64,
>  			},
>  			{ .index = D_SUNIT,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -320,9 +556,10 @@ struct opt_params {
>  					  .subopt = D_SW,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = UINT_MAX,
> +			  .minval.i = 0,
> +			  .maxval.i = UINT_MAX,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = D_SWIDTH,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -335,9 +572,10 @@ struct opt_params {
>  					  .subopt = D_SW,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = UINT_MAX,
> +			  .minval.i = 0,
> +			  .maxval.i = UINT_MAX,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = D_AGSIZE,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -345,9 +583,10 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> -			  .minval = XFS_AG_MIN_BYTES,
> -			  .maxval = XFS_AG_MAX_BYTES,
> +			  .minval.uint64 = XFS_AG_MIN_BYTES,
> +			  .maxval.uint64 = XFS_AG_MAX_BYTES,
>  			  .needs_val = true,
> +			  .type = UINT64,
>  			},
>  			{ .index = D_SU,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -361,9 +600,10 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> -			  .minval = 0,
> -			  .maxval = UINT_MAX,
> +			  .minval.i = 0,
> +			  .maxval.i = UINT_MAX,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = D_SW,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -376,18 +616,20 @@ struct opt_params {
>  					  .subopt = D_SWIDTH,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = UINT_MAX,
> +			  .minval.i = 0,
> +			  .maxval.i = UINT_MAX,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = D_SECTLOG,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_SECTSIZE,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = XFS_MIN_SECTORSIZE_LOG,
> -			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> +			  .minval.i = XFS_MIN_SECTORSIZE_LOG,
> +			  .maxval.i = XFS_MAX_SECTORSIZE_LOG,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = D_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -396,9 +638,10 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> -			  .minval = XFS_MIN_SECTORSIZE,
> -			  .maxval = XFS_MAX_SECTORSIZE,
> +			  .minval.u = XFS_MIN_SECTORSIZE,
> +			  .maxval.u = XFS_MAX_SECTORSIZE,
>  			  .needs_val = true,
> +			  .type = UINT,
>  			},
>  			{ .index = D_NOALIGN,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -414,27 +657,31 @@ struct opt_params {
>  					  .subopt = D_SWIDTH,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.i = 0,
> +			  .maxval.i = 1,
> +			  .flagval.i = 1,
> +			  .type = INT,
>  			},
>  			{ .index = D_RTINHERIT,
>  			  .conflicts = { {LAST_CONFLICT} },
> -			  .minval = 1,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.u = 1,
> +			  .maxval.u = 1,
> +			  .flagval.u = 1,
> +			  .type = UINT,
>  			},
>  			{ .index = D_PROJINHERIT,
>  			  .conflicts = { {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = UINT_MAX,
> +			  .minval.u = 0,
> +			  .maxval.u = UINT_MAX,
>  			  .needs_val = true,
> +			  .type = UINT,
>  			},
>  			{ .index = D_EXTSZINHERIT,
>  			  .conflicts = { {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = UINT_MAX,
> +			  .minval.u = 0,
> +			  .maxval.u = UINT_MAX,
>  			  .needs_val = true,
> +			  .type = UINT,
>  			},
>  		},
>  	},
> @@ -458,14 +705,15 @@ struct opt_params {
>  					  .subopt = M_CRC,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 0,
> +					  .invalid_value.b = 1,
> +					  .at_value.b = 0,
>  					  .message = \
>  		"Inodes always aligned for CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			},
>  			{ .index = I_LOG,
>  			  .conflicts = { {.opt = OPT_I,
> @@ -475,15 +723,17 @@ struct opt_params {
>  					  .subopt = I_SIZE,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = XFS_DINODE_MIN_LOG,
> -			  .maxval = XFS_DINODE_MAX_LOG,
> +			  .minval.i = XFS_DINODE_MIN_LOG,
> +			  .maxval.i = XFS_DINODE_MAX_LOG,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = I_MAXPCT,
>  			  .conflicts = { {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 100,
> +			  .minval.i = 0,
> +			  .maxval.i = 100,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = I_PERBLOCK,
>  			  .conflicts = { {.opt = OPT_I,
> @@ -494,9 +744,10 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
> -			  .minval = XFS_MIN_INODE_PERBLOCK,
> -			  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
> +			  .minval.i = XFS_MIN_INODE_PERBLOCK,
> +			  .maxval.i = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = I_SIZE,
>  			  .conflicts = { {.opt = OPT_I,
> @@ -507,52 +758,56 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
> -			  .minval = XFS_DINODE_MIN_SIZE,
> -			  .maxval = XFS_DINODE_MAX_SIZE,
> +			  .minval.i = XFS_DINODE_MIN_SIZE,
> +			  .maxval.i = XFS_DINODE_MAX_SIZE,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = I_ATTR,
>  			  .conflicts = { {.opt = OPT_M,
>  					  .subopt = M_CRC,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 1,
> +					  .invalid_value.b = true,
> +					  .at_value.i = 1,
>  					  .message = \
>  		"V2 attribute format always enabled on CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 2,
> +			  .minval.i = 0,
> +			  .maxval.i = 2,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = I_PROJID32BIT,
>  			  .conflicts = { {.opt = OPT_M,
>  					  .subopt = M_CRC,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 0,
> +					  .invalid_value.b = true,
> +					  .at_value.b = 0,
>  					  .message = \
>  		"32 bit Project IDs always enabled on CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
>  
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			},
>  			{ .index = I_SPINODES,
>  			  .conflicts = { {.opt = OPT_M,
>  					  .subopt = M_CRC,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 0,
> -					  .at_value = 1,
> +					  .invalid_value.b = 0,
> +					  .at_value.i = 1,
>  					  .message = \
>  		"Sparse inodes not supported without CRC support."},
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.i = 0,
> +			  .maxval.i = 1,
> +			  .flagval.i = 1,
> +			  .type = INT,
>  			},
>  		},
>  	},
> @@ -576,13 +831,15 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = L_AGNUM,
> +			  /* FIXME custom type xfs_agnumber_t? */

Does something really need to be fixed here?


>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_DEV,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = UINT_MAX,
> +			  .minval.u = 0,
> +			  .maxval.u = UINT_MAX,
>  			  .needs_val = true,
> +			  .type = UINT,
>  			},
>  			{ .index = L_INTERNAL,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -592,39 +849,43 @@ struct opt_params {
>  					  .subopt = L_DEV,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.i = 0,
> +			  .maxval.i = 1,
> +			  .flagval.i = 1,
> +			  .type = INT,
>  			},
>  			{ .index = L_SIZE,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
> -			  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
> -			  .maxval = XFS_MAX_LOG_BYTES,
> +			  .minval.i = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
> +			  .maxval.i = XFS_MAX_LOG_BYTES,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = L_VERSION,
>  			  .conflicts = {{.opt = OPT_M,
>  					  .subopt = M_CRC,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 1,
> +					  .invalid_value.b = true,
> +					  .at_value.i = 1,
>  					  .message =
>  				"V2 logs are required for CRC enabled filesystems."},
>  					 {LAST_CONFLICT} },
> -			  .minval = 1,
> -			  .maxval = 2,
> +			  .minval.i = 1,
> +			  .maxval.i = 2,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = L_SUNIT,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_SU,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = 1,
> -			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
> +			  .minval.i = 1,
> +			  .maxval.i = BTOBB(XLOG_MAX_RECORD_BSIZE),
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = L_SU,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -632,9 +893,10 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> -			  .minval = BBTOB(1),
> -			  .maxval = XLOG_MAX_RECORD_BSIZE,
> +			  .minval.i = BBTOB(1),
> +			  .maxval.i = XLOG_MAX_RECORD_BSIZE,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = L_DEV,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -645,15 +907,17 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .needs_val = true,
> +			  .type = STRING,
>  			},
>  			{ .index = L_SECTLOG,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_SECTSIZE,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = XFS_MIN_SECTORSIZE_LOG,
> -			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> +			  .minval.i = XFS_MIN_SECTORSIZE_LOG,
> +			  .maxval.i = XFS_MAX_SECTORSIZE_LOG,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = L_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -662,18 +926,20 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> -			  .minval = XFS_MIN_SECTORSIZE,
> -			  .maxval = XFS_MAX_SECTORSIZE,
> +			  .minval.i = XFS_MIN_SECTORSIZE,
> +			  .maxval.i = XFS_MAX_SECTORSIZE,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = L_FILE,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_INTERNAL,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.i = 0,
> +			  .maxval.i = 1,
> +			  .flagval.i = 1,
> +			  .type = INT,
>  			},
>  			{ .index = L_NAME,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -684,20 +950,22 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .needs_val = true,
> +			  .type = STRING,
>  			},
>  			{ .index = L_LAZYSBCNTR,
>  			  .conflicts = { {.opt = OPT_M,
>  					  .subopt = M_CRC,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 0,
> +					  .invalid_value.b = true,
> +					  .at_value.b = false,
>  					  .message =
>  		"Lazy superblock counted always enabled for CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			},
>  		},
>  	},
> @@ -717,9 +985,10 @@ struct opt_params {
>  					  .subopt = N_SIZE,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = XFS_MIN_REC_DIRSIZE,
> -			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> +			  .minval.i = XFS_MIN_REC_DIRSIZE,
> +			  .maxval.i = XFS_MAX_BLOCKSIZE_LOG,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = N_SIZE,
>  			  .conflicts = { {.opt = OPT_N,
> @@ -728,29 +997,32 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> -			  .minval = 1 << XFS_MIN_REC_DIRSIZE,
> -			  .maxval = XFS_MAX_BLOCKSIZE,
> +			  .minval.i = 1 << XFS_MIN_REC_DIRSIZE,
> +			  .maxval.i = XFS_MAX_BLOCKSIZE,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = N_VERSION,
>  			  .conflicts = { {LAST_CONFLICT} },
> -			  .minval = 2,
> -			  .maxval = 2,
> +			  .minval.i = 2,
> +			  .maxval.i = 2,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = N_FTYPE,
>  			  .conflicts = {  {.opt = OPT_M,
>  					  .subopt = M_CRC,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 0,
> +					  .invalid_value.b = true,
> +					  .at_value.b = false,
>  					  .message =
>  		"Cannot disable ftype with crcs enabled."},
>  					  {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			},
>  		},
>  	},
> @@ -770,33 +1042,37 @@ struct opt_params {
>  			{ .index = R_EXTSIZE,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
> -			  .minval = XFS_MIN_RTEXTSIZE,
> -			  .maxval = XFS_MAX_RTEXTSIZE,
> +			  .minval.uint64 = XFS_MIN_RTEXTSIZE,
> +			  .maxval.uint64 = XFS_MAX_RTEXTSIZE,
>  			  .needs_val = true,
> +			  .type = UINT64,
>  			},
>  			{ .index = R_SIZE,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
> -			  .minval = 0,
> -			  .maxval = LLONG_MAX,
> +			  .minval.uint64 = 0,
> +			  .maxval.uint64 = LLONG_MAX,
>  			  .needs_val = true,
> +			  .type = UINT64,
>  			},
>  			{ .index = R_DEV,
>  			  .conflicts = { {.opt = OPT_M,
>  				  	  .subopt = M_RMAPBT,
>  					  .test_values = false,
>  					  .test_default_value = true,
> -					  .invalid_value = 0,
> -					  .at_value = 0,
> +					  .invalid_value.b = 0,
> +					  .at_value.b = 0,
>  					  .message =
>  		"rmapbt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .needs_val = true,
> +			  .type = STRING,
>  			},
>  			{ .index = R_FILE,
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.i = 0,
> +			  .maxval.i = 1,
> +			  .flagval.i = 1,
> +			  .type = INT,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  			{ .index = R_NAME,
> @@ -804,17 +1080,19 @@ struct opt_params {
>  				  	  .subopt = M_RMAPBT,
>  					  .test_values = false,
>  					  .test_default_value = true,
> -					  .invalid_value = 0,
> -					  .at_value = 0,
> +					  .invalid_value.b = 0,
> +					  .at_value.b = 0,
>  					  .message =
>  		"rmapbt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .needs_val = true,
> +			  .type = STRING,
>  			},
>  			{ .index = R_NOALIGN,
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.i = 0,
> +			  .maxval.i = 1,
> +			  .flagval.i = 1,
> +			  .type = INT,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  		},
> @@ -838,9 +1116,10 @@ struct opt_params {
>  					  .subopt = S_SECTSIZE,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = XFS_MIN_SECTORSIZE_LOG,
> -			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> +			  .minval.i = XFS_MIN_SECTORSIZE_LOG,
> +			  .maxval.i = XFS_MAX_SECTORSIZE_LOG,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = S_SECTLOG,
>  			  .conflicts = { {.opt = OPT_S,
> @@ -850,9 +1129,10 @@ struct opt_params {
>  					  .subopt = S_SECTSIZE,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval = XFS_MIN_SECTORSIZE_LOG,
> -			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> +			  .minval.i = XFS_MIN_SECTORSIZE_LOG,
> +			  .maxval.i = XFS_MAX_SECTORSIZE_LOG,
>  			  .needs_val = true,
> +			  .type = INT,
>  			},
>  			{ .index = S_SIZE,
>  			  .conflicts = { {.opt = OPT_S,
> @@ -864,9 +1144,10 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> -			  .minval = XFS_MIN_SECTORSIZE,
> -			  .maxval = XFS_MAX_SECTORSIZE,
> +			  .minval.u = XFS_MIN_SECTORSIZE,
> +			  .maxval.u = XFS_MAX_SECTORSIZE,
>  			  .needs_val = true,
> +			  .type = UINT,
>  			},
>  			{ .index = S_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_S,
> @@ -878,9 +1159,10 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> -			  .minval = XFS_MIN_SECTORSIZE,
> -			  .maxval = XFS_MAX_SECTORSIZE,
> +			  .minval.u = XFS_MIN_SECTORSIZE,
> +			  .maxval.u = XFS_MAX_SECTORSIZE,
>  			  .needs_val = true,
> +			  .type = UINT,
>  			},
>  		},
>  	},
> @@ -901,148 +1183,153 @@ struct opt_params {
>  					  .subopt = L_VERSION,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 1,
> +					  .invalid_value.i = 1,
> +					  .at_value.b = 1,
>  					  .message =
>  		"V2 logs are required for CRC enabled filesystems."},
>  					 {.opt = OPT_I,
>  					  .subopt = I_ALIGN,
>  					  .test_values = false,
>  					  .test_default_value = true,
> -					  .invalid_value = 0,
> -					  .at_value = 1,
> +					  .invalid_value.b = 0,
> +					  .at_value.b = 1,
>  					  .message =
>  		"Inodes always aligned for CRC enabled filesytems."},
>  					 {.opt = OPT_I,
>  					  .subopt = I_PROJID32BIT,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 0,
> -					  .at_value = 1,
> +					  .invalid_value.b = 0,
> +					  .at_value.b = 1,
>  					  .message =
>  		"32 bit Project IDs always enabled on CRC enabled filesytems."},
>  					 {.opt = OPT_I,
>  					  .subopt = I_ATTR,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 1,
> +					  .invalid_value.i = 1,
> +					  .at_value.b = 1,
>  					  .message =
>  		"V2 attribute format always enabled on CRC enabled filesytems."},
>  					 {.opt = OPT_L,
>  					  .subopt = L_LAZYSBCNTR,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 0,
> -					  .at_value = 1,
> +					  .invalid_value.b = 0,
> +					  .at_value.b = 1,
>  					  .message =
>  		"Lazy superblock counted always enabled for CRC enabled filesytems."},
>  					 {.opt = OPT_M,
>  					  .subopt = M_FINOBT,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 0,
> +					  .invalid_value.i = 1,
> +					  .at_value.b = 0,
>  					  .message =
>  		"Finobt not supported without CRC support."},
>  					 {.opt = OPT_M,
>  				  	  .subopt = M_RMAPBT,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 0,
> +					  .invalid_value.b = 1,
> +					  .at_value.b = 0,
>  					  .message =
>  		"rmapbt not supported without CRC support."},
>  					 {.opt = OPT_M,
>  				  	  .subopt = M_REFLINK,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 0,
> +					  .invalid_value.b = 1,
> +					  .at_value.b = 0,
>  					  .message =
>  		"reflink not supported without CRC support."},
>  					 {.opt = OPT_I,
>  					  .subopt = I_SPINODES,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 1,
> -					  .at_value = 0,
> +					  .invalid_value.i = 1,
> +					  .at_value.b = 0,
>  					  .message =
>  		"Sparse inodes not supported without CRC support."},
>  					 {.opt = OPT_N,
>  					  .subopt = N_FTYPE,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 0,
> -					  .at_value = 1,
> +					  .invalid_value.b = 0,
> +					  .at_value.b = 1,
>  					  .message =
>  		"Cannot disable ftype with crcs enabled."},
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			},
>  			{ .index = M_FINOBT,
>  			  .conflicts = { {.opt = OPT_M,
>  					  .subopt = M_CRC,
>  					  .test_values = true,
>  					  .test_default_value = true,
> -					  .invalid_value = 0,
> -					  .at_value = 1,
> +					  .invalid_value.b = 0,
> +					  .at_value.i = 1,
>  					  .message =
>  		"Finobt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> -			  .flagval = 1,
> +			  .minval.i = 0,
> +			  .maxval.i = 1,
> +			  .flagval.i = 1,
> +			  .type = INT,
>  			},
>  			{ .index = M_UUID,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .needs_val = true,
> +			  .type = STRING,
>  			},
>  			{ .index = M_RMAPBT,
>  			.conflicts = { {.opt = OPT_M,
>  					.subopt = M_CRC,
>  					.test_values = true,
>  					.test_default_value = true,
> -					.invalid_value = 0,
> -					.at_value = 1,
> +					.invalid_value.b = 0,
> +					.at_value.b = 1,
>  					.message =
>  		"rmapbt not supported without CRC support."},
>  					{.opt = OPT_R,
>  					 .subopt = R_NAME,
>  					 .test_values = false,
>  					 .test_default_value = true,
> -					 .invalid_value = 0,
> -					 .at_value = 0,
> +					 .invalid_value.b = 0,
> +					 .at_value.b = 0,
>  					 .message =
>  		"rmapbt not supported with realtime devices."},
>  					{.opt = OPT_R,
>  					 .subopt = R_DEV,
>  					 .test_values = false,
>  					 .test_default_value = true,
> -					 .invalid_value = 0,
> -					 .at_value = 0,
> +					 .invalid_value.b = 0,
> +					 .at_value.b = 0,
>  					 .message =
>  		"rmapbt not supported with realtime devices."},
>  				       {LAST_CONFLICT} },
> -			.minval = 0,
> -			.maxval = 1,
> -			.flagval = 0,
> +			.minval.b = false,
> +			.maxval.b = true,
> +			.flagval.b = false,
> +			.type = BOOL,
>  			},
>  			{ .index = M_REFLINK,
>  			.conflicts = { {.opt = OPT_M,
>  					.subopt = M_CRC,
>  					.test_values = true,
>  					.test_default_value = true,
> -					.invalid_value = 0,
> -					.at_value = 1,
> +					.invalid_value.b = 0,
> +					.at_value.b = 1,
>  					.message =
>  		"reflink not supported without CRC support."},
>  					 {LAST_CONFLICT} },
> -			  .minval = 0,
> -			  .maxval = 1,
> +			  .minval.b = 0,
> +			  .maxval.b = 1,
>  			  .needs_val = true,
> +			 .type = BOOL,
>  			},
>  		},
>  	},
> @@ -1653,8 +1940,7 @@ check_subopt_conflicts(
>  static void
>  check_subopt_value(
>  	struct opt_params	*opt,
> -	int			index,
> -	long long 		value)
> +	int			index)
>  {
>  	struct subopt_param	*sp = &opt->subopt_params[index];
>  	int			i;
> @@ -1669,9 +1955,19 @@ check_subopt_value(
>  			break;
>  		if ( (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
>  		      conflict_opt.test_default_value) &&
> -		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value
> -				== conflict_opt.invalid_value &&
> -		    value == conflict_opt.at_value) {
> +		      test_uvalues(
> +			opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].type,
> +			opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value,
> +			opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].type,
> +			conflict_opt.invalid_value
> +		      ) &&
> +		      test_uvalues(
> +			sp->type,
> +			sp->value,
> +			sp->type,
> +			conflict_opt.at_value
> +		      )
> +		    ) {
>  			conflict_struct(opt, sp, &conflict_opt);
>  		}
>  	}
> @@ -1695,7 +1991,7 @@ check_opt(
>  		if (!sp->seen)
>  			continue;
>  		check_subopt_conflicts(opt, index, false);
> -		check_subopt_value(opt, index, sp->value);
> +		check_subopt_value(opt, index);
>  	}
>  }
>  static void
> @@ -1721,18 +2017,42 @@ getnum(
>  		if (sp->needs_val)
>  			reqval(opts->name, (char **)opts->subopts, index);
>  		sp->seen = true;
> -		return sp->flagval;
> +		switch(sp->type){
> +		case LONGLONG:
> +			return sp->flagval.ll;
> +		case BOOL:
> +			return sp->flagval.b;
> +		case UINT64:
> +			return sp->flagval.uint64;
> +		case INT:
> +			return sp->flagval.i;
> +		case UINT:
> +			return sp->flagval.u;
> +		default:
> +			fprintf(stderr,
> +				_("Option -%c %s called getnum, but is not numeric."
> +				  " This is a bug.\n"), opts->name, opts->subopts[index]);
> +			exit(1);
> +		}
>  	}
>  
>  	sp->seen = true;
>  
> -	if (sp->minval == 0 && sp->maxval == 0) {
> +	if (test_uvalue_num(sp->type, sp->minval, 0) &&
> +		test_uvalue_num(sp->type, sp->maxval, 0)) {
>  		fprintf(stderr,
>  			_("Option -%c %s has undefined minval/maxval."
>  			  "Can't verify value range. This is a bug.\n"),
>  			opts->name, opts->subopts[index]);
>  		exit(1);
>  	}
> +	if (sp->type == TYPE_UNDEF) {
> +		fprintf(stderr,
> +			_("Option -%c %s is of undefined type."
> +			  "Can't parse value. This is a bug.\n"),
> +			opts->name, opts->subopts[index]);
> +		exit(1);
> +	}
>  
>  	/*
>  	 * Some values are pure numbers, others can have suffixes that define
> @@ -1753,9 +2073,9 @@ getnum(
>  	}
>  
>  	/* Validity check the result. */
> -	if (c < sp->minval)
> +	if (cmp_uvalue_gt_num(sp->type, sp->minval, c))
>  		illegal_option(str, opts, index, _("value is too small"));
> -	else if (c > sp->maxval)
> +	else if (cmp_uvalue_lt_num(sp->type, sp->maxval, c))
>  		illegal_option(str, opts, index, _("value is too large"));
>  	if (sp->is_power_2 && !ispow2(c))
>  		illegal_option(str, opts, index, _("value must be a power of 2"));
> @@ -1940,20 +2260,12 @@ main(
>  								B_LOG);
>  					blocksize = 1 << blocklog;
>  					blflag = 1;
> -					opts[OPT_B].subopt_params[B_LOG].value =
> -							blocklog;
> -					opts[OPT_B].subopt_params[B_SIZE].value =
> -							blocksize;
>  					break;
>  				case B_SIZE:
>  					blocksize = getnum(value, &opts[OPT_B],
>  							   B_SIZE);
>  					blocklog = libxfs_highbit32(blocksize);
>  					bsflag = 1;
> -					opts[OPT_B].subopt_params[B_LOG].value =
> -							blocklog;
> -					opts[OPT_B].subopt_params[B_SIZE].value =
> -							blocksize;
>  					break;
>  				default:
>  					unknown('b', value);
> @@ -1971,70 +2283,47 @@ main(
>  					agcount = getnum(value, &opts[OPT_D],
>  							 D_AGCOUNT);
>  					daflag = 1;
> -					opts[OPT_D].subopt_params[D_AGCOUNT].value =
> -							agcount;
>  					break;
>  				case D_AGSIZE:
>  					agsize = getnum(value, &opts[OPT_D],
>  								D_AGSIZE);
>  					dasize = 1;
> -					opts[OPT_D].subopt_params[D_AGSIZE].value =
> -							agsize;
>  					break;
>  				case D_FILE:
>  					xi.disfile = getnum(value, &opts[OPT_D],
>  							    D_FILE);
> -					opts[OPT_D].subopt_params[D_FILE].value =
> -							xi.disfile;
>  					break;
>  				case D_NAME:
>  					xi.dname = getstr(value, &opts[OPT_D],
>  								D_NAME);
> -					opts[OPT_D].subopt_params[D_NAME].value = 1;
>  					break;
>  				case D_SIZE:
>  					dbytes = getnum(value, &opts[OPT_D],
>  								D_SIZE);
> -					opts[OPT_D].subopt_params[D_SIZE].value =
> -							dbytes;
>  					break;
>  				case D_SUNIT:
>  					dsunit = getnum(value, &opts[OPT_D],
>  								D_SUNIT);
> -					opts[OPT_D].subopt_params[D_SUNIT].value =
> -							dsunit;
>  					break;
>  				case D_SWIDTH:
>  					dswidth = getnum(value, &opts[OPT_D],
>  							 D_SWIDTH);
> -					opts[OPT_D].subopt_params[D_SWIDTH].value =
> -							dswidth;
>  					break;
>  				case D_SU:
>  					dsu = getnum(value, &opts[OPT_D], D_SU);
> -					opts[OPT_D].subopt_params[D_SU].value =
> -							dsu;
>  					break;
>  				case D_SW:
>  					dsw = getnum(value, &opts[OPT_D], D_SW);
> -					opts[OPT_D].subopt_params[D_SW].value =
> -							dsw;
>  					break;
>  				case D_NOALIGN:
>  					nodsflag = getnum(value, &opts[OPT_D],
>  								D_NOALIGN);
> -					opts[OPT_D].subopt_params[D_NOALIGN].value =
> -							nodsflag;
>  					break;
>  				case D_SECTLOG:
>  					sectorlog = getnum(value, &opts[OPT_D],
>  							   D_SECTLOG);
>  					sectorsize = 1 << sectorlog;
>  					slflag = 1;
> -					opts[OPT_D].subopt_params[D_SECTSIZE].value =
> -							sectorsize;
> -					opts[OPT_D].subopt_params[D_SECTLOG].value =
> -							sectorlog;
>  					break;
>  				case D_SECTSIZE:
>  					sectorsize = getnum(value, &opts[OPT_D],
> @@ -2042,10 +2331,6 @@ main(
>  					sectorlog =
>  						libxfs_highbit32(sectorsize);
>  					ssflag = 1;
> -					opts[OPT_D].subopt_params[D_SECTSIZE].value =
> -							sectorsize;
> -					opts[OPT_D].subopt_params[D_SECTLOG].value =
> -							sectorlog;
>  					break;
>  				case D_RTINHERIT:
>  					c = getnum(value, &opts[OPT_D],
> @@ -2053,24 +2338,18 @@ main(
>  					if (c)
>  						fsx.fsx_xflags |=
>  							XFS_DIFLAG_RTINHERIT;
> -					opts[OPT_D].subopt_params[D_RTINHERIT].value =
> -							c;
>  					break;
>  				case D_PROJINHERIT:
>  					fsx.fsx_projid = getnum(value, &opts[OPT_D],
>  								D_PROJINHERIT);
>  					fsx.fsx_xflags |=
>  						XFS_DIFLAG_PROJINHERIT;
> -					opts[OPT_D].subopt_params[D_PROJINHERIT].value =
> -							fsx.fsx_projid;
>  					break;
>  				case D_EXTSZINHERIT:
>  					fsx.fsx_extsize = getnum(value, &opts[OPT_D],
>  								 D_EXTSZINHERIT);
>  					fsx.fsx_xflags |=
>  						XFS_DIFLAG_EXTSZINHERIT;
> -					opts[OPT_D].subopt_params[D_EXTSZINHERIT].value =
> -							fsx.fsx_extsize;
>  					break;
>  				default:
>  					unknown('d', value);
> @@ -2088,64 +2367,44 @@ main(
>  					sb_feat.inode_align = getnum(value,
>  								&opts[OPT_I],
>  								I_ALIGN);
> -					opts[OPT_I].subopt_params[I_ALIGN].value =
> -							sb_feat.inode_align;
>  					break;
>  				case I_LOG:
>  					inodelog = getnum(value, &opts[OPT_I],
>  								I_LOG);
>  					isize = 1 << inodelog;
>  					ilflag = 1;
> -					opts[OPT_I].subopt_params[I_SIZE].value =
> -							isize;
> -					opts[OPT_I].subopt_params[I_LOG].value =
> -							inodelog;
>  					break;
>  				case I_MAXPCT:
>  					imaxpct = getnum(value, &opts[OPT_I],
>  							 I_MAXPCT);
>  					imflag = 1;
> -					opts[OPT_I].subopt_params[I_MAXPCT].value =
> -							imaxpct;
>  					break;
>  				case I_PERBLOCK:
>  					inopblock = getnum(value, &opts[OPT_I],
>  							   I_PERBLOCK);
>  					ipflag = 1;
> -					opts[OPT_I].subopt_params[I_PERBLOCK].value =
> -							inopblock;
>  					break;
>  				case I_SIZE:
>  					isize = getnum(value, &opts[OPT_I],
>  								I_SIZE);
>  					inodelog = libxfs_highbit32(isize);
>  					isflag = 1;
> -					opts[OPT_I].subopt_params[I_SIZE].value =
> -							isize;
> -					opts[OPT_I].subopt_params[I_LOG].value =
> -							inodelog;
>  					break;
>  				case I_ATTR:
>  					sb_feat.attr_version =
>  
>  						getnum(value, &opts[OPT_I],
>  								I_ATTR);
> -					opts[OPT_I].subopt_params[I_ATTR].value =
> -							sb_feat.attr_version;
>  					break;
>  				case I_PROJID32BIT:
>  					sb_feat.projid16bit =
>  						!getnum(value, &opts[OPT_I],
>  							I_PROJID32BIT);
> -					opts[OPT_I].subopt_params[I_PROJID32BIT].value =
> -							sb_feat.projid16bit;
>  					break;
>  				case I_SPINODES:
>  					sb_feat.spinodes = getnum(value,
>  								&opts[OPT_I],
>  								I_SPINODES);
> -					opts[OPT_I].subopt_params[I_SPINODES].value =
> -							sb_feat.spinodes;
>  					break;
>  				default:
>  					unknown('i', value);
> @@ -2163,34 +2422,24 @@ main(
>  					logagno = getnum(value, &opts[OPT_L],
>  								L_AGNUM);
>  					laflag = 1;
> -					opts[OPT_L].subopt_params[L_AGNUM].value =
> -							logagno;
>  					break;
>  				case L_FILE:
>  					xi.lisfile = getnum(value, &opts[OPT_L],
>  							    L_FILE);
> -					opts[OPT_L].subopt_params[L_FILE].value =
> -							xi.lisfile;
>  					break;
>  				case L_INTERNAL:
>  					loginternal = getnum(value, &opts[OPT_L],
>  							     L_INTERNAL);
>  					liflag = 1;
> -					opts[OPT_L].subopt_params[L_INTERNAL].value =
> -							loginternal;
>  					break;
>  				case L_SU:
>  					lsu = getnum(value, &opts[OPT_L], L_SU);
>  					lsuflag = 1;
> -					opts[OPT_L].subopt_params[L_SU].value =
> -							lsu;
>  					break;
>  				case L_SUNIT:
>  					lsunit = getnum(value, &opts[OPT_L],
>  								L_SUNIT);
>  					lsunitflag = 1;
> -					opts[OPT_L].subopt_params[L_SUNIT].value =
> -							lsunit;
>  					break;
>  				case L_NAME:
>  				case L_DEV:
> @@ -2199,32 +2448,22 @@ main(
>  					xi.logname = logfile;
>  					ldflag = 1;
>  					loginternal = 0;
> -					opts[OPT_L].subopt_params[L_NAME].value = 1;
> -					opts[OPT_L].subopt_params[L_DEV].value = 1;
>  					break;
>  				case L_VERSION:
>  					sb_feat.log_version =
>  						getnum(value, &opts[OPT_L],
>  								L_VERSION);
>  					lvflag = 1;
> -					opts[OPT_L].subopt_params[L_VERSION].value =
> -							sb_feat.log_version;
>  					break;
>  				case L_SIZE:
>  					logbytes = getnum(value, &opts[OPT_L],
>  								L_SIZE);
> -					opts[OPT_L].subopt_params[L_SIZE].value =
> -							logbytes;
>  					break;
>  				case L_SECTLOG:
>  					lsectorlog = getnum(value, &opts[OPT_L],
>  							    L_SECTLOG);
>  					lsectorsize = 1 << lsectorlog;
>  					lslflag = 1;
> -					opts[OPT_L].subopt_params[L_SECTSIZE].value =
> -							lsectorsize;
> -					opts[OPT_L].subopt_params[L_SECTLOG].value =
> -							lsectorlog;
>  					break;
>  				case L_SECTSIZE:
>  					lsectorsize = getnum(value, &opts[OPT_L],
> @@ -2232,17 +2471,11 @@ main(
>  					lsectorlog =
>  						libxfs_highbit32(lsectorsize);
>  					lssflag = 1;
> -					opts[OPT_L].subopt_params[L_SECTSIZE].value =
> -							lsectorsize;
> -					opts[OPT_L].subopt_params[L_SECTLOG].value =
> -							lsectorlog;
>  					break;
>  				case L_LAZYSBCNTR:
>  					sb_feat.lazy_sb_counters =
>  							getnum(value, &opts[OPT_L],
>  							       L_LAZYSBCNTR);
> -					opts[OPT_L].subopt_params[L_LAZYSBCNTR].value =
> -							sb_feat.lazy_sb_counters;
>  					break;
>  				default:
>  					unknown('l', value);
> @@ -2267,27 +2500,20 @@ main(
>  								M_CRC);
>  					if (sb_feat.crcs_enabled)
>  						sb_feat.dirftype = true;
> -					opts[OPT_M].subopt_params[M_CRC].value =
> -							sb_feat.crcs_enabled;
>  					break;
>  				case M_FINOBT:
>  					sb_feat.finobt = getnum(
>  						value, &opts[OPT_M], M_FINOBT);
> -					opts[OPT_M].subopt_params[M_FINOBT].value =
> -							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");
> -					opts[OPT_M].subopt_params[M_UUID].value = 1;
>  					break;
>  				case M_RMAPBT:
>  					sb_feat.rmapbt = getnum(
>  						value, &opts[OPT_M], M_RMAPBT);
> -					opts[OPT_M].subopt_params[M_RMAPBT].value = 
> -						sb_feat.rmapbt;
>  					break;
>  				case M_REFLINK:
>  					sb_feat.reflink = getnum(
> @@ -2310,10 +2536,6 @@ main(
>  							     N_LOG);
>  					dirblocksize = 1 << dirblocklog;
>  					nlflag = 1;
> -					opts[OPT_N].subopt_params[N_SIZE].value =
> -							dirblocksize;
> -					opts[OPT_N].subopt_params[N_LOG].value =
> -							dirblocklog;
>  					break;
>  				case N_SIZE:
>  					dirblocksize = getnum(value, &opts[OPT_N],
> @@ -2321,10 +2543,6 @@ main(
>  					dirblocklog =
>  						libxfs_highbit32(dirblocksize);
>  					nsflag = 1;
> -					opts[OPT_N].subopt_params[N_SIZE].value =
> -							dirblocksize;
> -					opts[OPT_N].subopt_params[N_LOG].value =
> -							dirblocklog;
>  					break;
>  				case N_VERSION:
>  					value = getstr(value, &opts[OPT_N],
> @@ -2338,14 +2556,10 @@ main(
>  							       N_VERSION);
>  					}
>  					nvflag = 1;
> -					opts[OPT_N].subopt_params[N_VERSION].value =
> -							sb_feat.dir_version;
>  					break;
>  				case N_FTYPE:
>  					sb_feat.dirftype = getnum(value, &opts[OPT_N],
>  								  N_FTYPE);
> -					opts[OPT_N].subopt_params[N_FTYPE].value =
> -							sb_feat.dirftype;
>  					break;
>  				default:
>  					unknown('n', value);
> @@ -2376,33 +2590,23 @@ main(
>  				case R_EXTSIZE:
>  					rtextbytes = getnum(value, &opts[OPT_R],
>  								R_EXTSIZE);
> -					opts[OPT_R].subopt_params[R_EXTSIZE].value =
> -							rtextbytes;
>  					break;
>  				case R_FILE:
>  					xi.risfile = getnum(value, &opts[OPT_R],
>  							    R_FILE);
> -					opts[OPT_R].subopt_params[R_FILE].value =
> -							xi.risfile;
>  					break;
>  				case R_NAME:
>  				case R_DEV:
>  					xi.rtname = getstr(value, &opts[OPT_R],
>  							   R_NAME);
> -					opts[OPT_R].subopt_params[R_NAME].value = 1;
> -					opts[OPT_R].subopt_params[R_DEV].value = 1;
>  					break;
>  				case R_SIZE:
>  					rtbytes = getnum(value, &opts[OPT_R],
>  								R_SIZE);
> -					opts[OPT_R].subopt_params[R_SIZE].value =
> -							rtbytes;
>  					break;
>  				case R_NOALIGN:
>  					norsflag = getnum(value, &opts[OPT_R],
>  								R_NOALIGN);
> -					opts[OPT_R].subopt_params[R_NOALIGN].value =
> -							norsflag;
>  					break;
>  				default:
>  					unknown('r', value);
> @@ -2427,10 +2631,6 @@ main(
>  					sectorsize = 1 << sectorlog;
>  					lsectorsize = sectorsize;
>  					lslflag = slflag = 1;
> -					opts[OPT_S].subopt_params[S_LOG].value =
> -							sectorsize;
> -					opts[OPT_S].subopt_params[S_SECTLOG].value =
> -							sectorsize;
>  					break;
>  				case S_SIZE:
>  				case S_SECTSIZE:
> @@ -2444,10 +2644,6 @@ main(
>  						libxfs_highbit32(sectorsize);
>  					lsectorlog = sectorlog;
>  					lssflag = ssflag = 1;
> -					opts[OPT_S].subopt_params[S_SIZE].value =
> -							sectorlog;
> -					opts[OPT_S].subopt_params[S_SECTSIZE].value =
> -							sectorlog;
>  					break;
>  				default:
>  					unknown('s', value);
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values
  2016-12-07 13:27 ` [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values Jan Tulak
@ 2017-01-13 17:43   ` Bill O'Donnell
  2017-01-16 12:45     ` Jan Tulak
  0 siblings, 1 reply; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 17:43 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:24PM +0100, Jan Tulak wrote:
> We need to have the values inside of the opts structure to validate it.
> To avoid duplicity and to prevent issues with using a wrong type from
> values union (e.g trating an int option as long long), keep the old
> variables like agcount, dsunit, ... and just turn them into pointers
> to the various opts fields.
> 
> However, at this moment, do not touch fields in other structures.
> If some option saves the value into the xi or fsx structure, then
> simply copy the value at the end of option parsing.
> 
> This might be changed in future if there is a nice way how to do it.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> ---
>  mkfs/xfs_mkfs.c | 771 ++++++++++++++++++++++++++++++--------------------------
>  1 file changed, 418 insertions(+), 353 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index afc63d1..d55eb9a 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -39,7 +39,7 @@ 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.
>   */
> -unsigned int		blocksize;
> +unsigned int		*blocksize;
>  unsigned int		sectorsize;
>  
>  #define MAX_OPTS	16
> @@ -557,7 +557,7 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval.i = 0,
> -			  .maxval.i = UINT_MAX,
> +			  .maxval.i = INT_MAX,
>  			  .needs_val = true,
>  			  .type = INT,
>  			},
> @@ -573,7 +573,7 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval.i = 0,
> -			  .maxval.i = UINT_MAX,
> +			  .maxval.i = INT_MAX,
>  			  .needs_val = true,
>  			  .type = INT,
>  			},
> @@ -601,7 +601,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval.i = 0,
> -			  .maxval.i = UINT_MAX,
> +			  .maxval.i = INT_MAX,
>  			  .needs_val = true,
>  			  .type = INT,
>  			},
> @@ -617,7 +617,7 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval.i = 0,
> -			  .maxval.i = UINT_MAX,
> +			  .maxval.i = INT_MAX,
>  			  .needs_val = true,
>  			  .type = INT,
>  			},
> @@ -853,6 +853,7 @@ struct opt_params {
>  			  .maxval.i = 1,
>  			  .flagval.i = 1,
>  			  .type = INT,
> +			  .value.i = 1,
>  			},
>  			{ .index = L_SIZE,
>  			  .conflicts = { {LAST_CONFLICT} },
> @@ -1345,7 +1346,7 @@ static void conflict_struct(struct opt_params 	*opt, struct subopt_param *subopt
>  /*
>   * 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) >> ((*blocklog) - BBSHIFT)))
>  
>  /*
>   * Use this for block reservations needed for mkfs's conditions
> @@ -1416,16 +1417,16 @@ calc_stripe_factors(
>  		*lsunit = (int)BTOBBT(lsu);
>  
>  	/* verify if lsu/lsunit is a multiple block size */
> -	if (lsu % blocksize != 0) {
> +	if (lsu % *blocksize != 0) {
>  		fprintf(stderr,
>  _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
> -		lsu, blocksize);
> +		lsu, *blocksize);
>  		exit(1);
>  	}
> -	if ((BBTOB(*lsunit) % blocksize != 0)) {
> +	if ((BBTOB(*lsunit) % *blocksize != 0)) {
>  		fprintf(stderr,
>  _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
> -		BBTOB(*lsunit), blocksize);
> +		BBTOB(*lsunit), *blocksize);
>  		exit(1);
>  	}
>  }
> @@ -2003,6 +2004,10 @@ check_all_opts(struct opt_params *opts)
>  	}
>  }
>  
> +/* TODO we might loose some numbers here, if they are unsigned and bigger than
> + * long long max value. So it might be worth to transform this... (think
> + * __uint64_t)
> + */

OK, so is this "might" be recommended or should we go ahead and prevent it in this
implementation? ;)

>  static long long
>  getnum(
>  	const char		*str,
> @@ -2061,7 +2066,7 @@ getnum(
>  	 * number.
>  	 */
>  	if (sp->convert)
> -		c = cvtnum(blocksize, sectorsize, str);
> +		c = cvtnum(*blocksize, sectorsize, str);
>  	else {
>  		char		*str_end;
>  
> @@ -2106,15 +2111,15 @@ main(
>  	int			argc,
>  	char			**argv)
>  {
> -	__uint64_t		agcount;
> +	__uint64_t		*agcount;
>  	xfs_agf_t		*agf;
>  	xfs_agi_t		*agi;
>  	xfs_agnumber_t		agno;
> -	__uint64_t		agsize;
> +	__uint64_t		*agsize;
>  	xfs_alloc_rec_t		*arec;
>  	struct xfs_btree_block	*block;
>  	int			blflag;
> -	int			blocklog;
> +	int			*blocklog;
>  	int			bsflag;
>  	int			bsize;
>  	xfs_buf_t		*buf;
> @@ -2123,51 +2128,51 @@ main(
>  	int			dasize;
>  	xfs_rfsblock_t		dblocks;
>  	char			*dfile;
> -	int			dirblocklog;
> -	int			dirblocksize;
> -	__uint64_t 		dbytes;
> -	int			dsu;
> -	int			dsw;
> -	int			dsunit;
> -	int			dswidth;
> +	int			*dirblocklog;
> +	int			*dirblocksize;
> +	__uint64_t 		*dbytes;
> +	int			*dsu;
> +	int			*dsw;
> +	int			*dsunit;
> +	int			*dswidth;
>  	int			force_overwrite;
>  	struct fsxattr		fsx;
>  	int			ilflag;
> -	int			imaxpct;
> +	int			*imaxpct;
>  	int			imflag;
> -	int			inodelog;
> -	int			inopblock;
> +	int			*inodelog;
> +	int			*inopblock;
>  	int			ipflag;
>  	int			isflag;
> -	int			isize;
> +	int			*isize;
>  	char			*label = NULL;
>  	int			laflag;
>  	int			lalign;
>  	int			ldflag;
>  	int			liflag;
> -	xfs_agnumber_t		logagno;
> +	xfs_agnumber_t		*logagno;
>  	xfs_rfsblock_t		logblocks;
>  	char			*logfile;
> -	int			loginternal;
> -	__uint64_t 		logbytes;
> +	int			*loginternal;
> +	__uint64_t 		*logbytes;
>  	xfs_fsblock_t		logstart;
>  	int			lvflag;
>  	int			lsflag;
>  	int			lsuflag;
>  	int			lsunitflag;
> -	int			lsectorlog;
> -	int			lsectorsize;
> +	int			*lsectorlog;
> +	int			*lsectorsize;
>  	int			lslflag;
>  	int			lssflag;
> -	int			lsu;
> -	int			lsunit;
> +	int			*lsu;
> +	int			*lsunit;
>  	int			min_logblocks;
>  	xfs_mount_t		*mp;
>  	xfs_mount_t		mbuf;
>  	xfs_extlen_t		nbmblocks;
>  	int			nlflag;
> -	int			nodsflag;
> -	int			norsflag;
> +	int			*nodsflag;
> +	int			*norsflag;
>  	xfs_alloc_rec_t		*nrec;
>  	int			nsflag;
>  	int			nvflag;
> @@ -2178,10 +2183,10 @@ main(
>  	char			*protostring;
>  	int			qflag;
>  	xfs_rfsblock_t		rtblocks;
> -	__uint64_t 		rtbytes;
> +	__uint64_t 		*rtbytes;
>  	xfs_extlen_t		rtextblocks;
>  	xfs_rtblock_t		rtextents;
> -	__uint64_t 		rtextbytes;
> +	__uint64_t 		*rtextbytes;
>  	char			*rtfile;
>  	xfs_sb_t		*sbp;
>  	int			sectorlog;
> @@ -2216,24 +2221,51 @@ main(
>  	bindtextdomain(PACKAGE, LOCALEDIR);
>  	textdomain(PACKAGE);
>  
> +
> +	/*
> +	 * Set up pointers, so we can use shorter names and to let gcc
> +	 * check the correct type. We don't want to inadvertently use an int as
> +	 * unsigned int and so on...
> +	 */
> +	agcount = &opts[OPT_D].subopt_params[D_AGCOUNT].value.uint64;
> +	agsize = &opts[OPT_D].subopt_params[D_AGSIZE].value.uint64;
> +	dbytes = &opts[OPT_D].subopt_params[D_SIZE].value.uint64;
> +	dsunit = &opts[OPT_D].subopt_params[D_SUNIT].value.i;
> +	dswidth = &opts[OPT_D].subopt_params[D_SWIDTH].value.i;
> +	dsu = &opts[OPT_D].subopt_params[D_SU].value.i;
> +	dsw = &opts[OPT_D].subopt_params[D_SW].value.i;
> +	nodsflag = &opts[OPT_D].subopt_params[D_NOALIGN].value.i;
> +	norsflag = &opts[OPT_R].subopt_params[R_NOALIGN].value.i;
> +	logagno = &opts[OPT_L].subopt_params[L_AGNUM].value.u;
> +	lsu = &opts[OPT_L].subopt_params[L_SU].value.i;
> +	lsunit = &opts[OPT_L].subopt_params[L_SUNIT].value.i;
> +	logbytes = &opts[OPT_L].subopt_params[L_SIZE].value.uint64;
> +	imaxpct = &opts[OPT_I].subopt_params[I_MAXPCT].value.i;
> +	inopblock = &opts[OPT_I].subopt_params[I_PERBLOCK].value.i;
> +	dirblocksize = &opts[OPT_N].subopt_params[N_SIZE].value.i;
> +	dirblocklog = &opts[OPT_N].subopt_params[N_LOG].value.i;
> +	rtextbytes = &opts[OPT_R].subopt_params[R_EXTSIZE].value.uint64;
> +	rtbytes = &opts[OPT_R].subopt_params[R_SIZE].value.uint64;
> +	blocklog = &opts[OPT_B].subopt_params[B_LOG].value.i;
> +	blocksize = &opts[OPT_B].subopt_params[B_SIZE].value.u;
> +	isize = &opts[OPT_I].subopt_params[I_SIZE].value.i;
> +	inodelog = &opts[OPT_I].subopt_params[I_LOG].value.i;
> +	loginternal = &opts[OPT_L].subopt_params[L_INTERNAL].value.i;
> +	lsectorsize = &opts[OPT_L].subopt_params[L_SECTSIZE].value.i;
> +	lsectorlog = &opts[OPT_L].subopt_params[L_SECTLOG].value.i;
> +
>  	blflag = bsflag = slflag = ssflag = lslflag = lssflag = 0;
> -	blocklog = blocksize = 0;
> -	sectorlog = lsectorlog = 0;
> -	sectorsize = lsectorsize = 0;
> -	agsize = daflag = dasize = dblocks = 0;
> +	sectorlog = 0;
> +	sectorsize = 0;
> +	daflag = dasize = dblocks = 0;
>  	ilflag = imflag = ipflag = isflag = 0;
>  	liflag = laflag = lsflag = lsuflag = lsunitflag = ldflag = lvflag = 0;
> -	loginternal = 1;
> -	logagno = logblocks = rtblocks = rtextblocks = 0;
> +	logblocks = rtblocks = rtextblocks = 0;
>  	Nflag = nlflag = nsflag = nvflag = 0;
> -	dirblocklog = dirblocksize = 0;
>  	qflag = 0;
> -	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 = 0;
> +	lalign = 0;
>  	force_overwrite = 0;
>  	worst_freelist = 0;
>  	memset(&fsx, 0, sizeof(fsx));
> @@ -2256,15 +2288,15 @@ main(
>  
>  				switch (getsubopt(&p, subopts, &value)) {
>  				case B_LOG:
> -					blocklog = getnum(value, &opts[OPT_B],
> +					*blocklog = getnum(value, &opts[OPT_B],
>  								B_LOG);
> -					blocksize = 1 << blocklog;
> +					*blocksize = 1 << *blocklog;
>  					blflag = 1;
>  					break;
>  				case B_SIZE:
> -					blocksize = getnum(value, &opts[OPT_B],
> +					*blocksize = getnum(value, &opts[OPT_B],
>  							   B_SIZE);
> -					blocklog = libxfs_highbit32(blocksize);
> +					*blocklog = libxfs_highbit32(*blocksize);
>  					bsflag = 1;
>  					break;
>  				default:
> @@ -2280,12 +2312,12 @@ main(
>  
>  				switch (getsubopt(&p, subopts, &value)) {
>  				case D_AGCOUNT:
> -					agcount = getnum(value, &opts[OPT_D],
> +					*agcount = getnum(value, &opts[OPT_D],
>  							 D_AGCOUNT);
>  					daflag = 1;
>  					break;
>  				case D_AGSIZE:
> -					agsize = getnum(value, &opts[OPT_D],
> +					*agsize = getnum(value, &opts[OPT_D],
>  								D_AGSIZE);
>  					dasize = 1;
>  					break;
> @@ -2298,25 +2330,25 @@ main(
>  								D_NAME);
>  					break;
>  				case D_SIZE:
> -					dbytes = getnum(value, &opts[OPT_D],
> +					*dbytes = getnum(value, &opts[OPT_D],
>  								D_SIZE);
>  					break;
>  				case D_SUNIT:
> -					dsunit = getnum(value, &opts[OPT_D],
> +					*dsunit = getnum(value, &opts[OPT_D],
>  								D_SUNIT);
>  					break;
>  				case D_SWIDTH:
> -					dswidth = getnum(value, &opts[OPT_D],
> +					*dswidth = getnum(value, &opts[OPT_D],
>  							 D_SWIDTH);
>  					break;
>  				case D_SU:
> -					dsu = getnum(value, &opts[OPT_D], D_SU);
> +					*dsu = getnum(value, &opts[OPT_D], D_SU);
>  					break;
>  				case D_SW:
> -					dsw = getnum(value, &opts[OPT_D], D_SW);
> +					*dsw = getnum(value, &opts[OPT_D], D_SW);
>  					break;
>  				case D_NOALIGN:
> -					nodsflag = getnum(value, &opts[OPT_D],
> +					*nodsflag = getnum(value, &opts[OPT_D],
>  								D_NOALIGN);
>  					break;
>  				case D_SECTLOG:
> @@ -2338,6 +2370,7 @@ main(
>  					if (c)
>  						fsx.fsx_xflags |=
>  							XFS_DIFLAG_RTINHERIT;
> +					opts[OPT_D].subopt_params[D_RTINHERIT].value.u = c;
>  					break;
>  				case D_PROJINHERIT:
>  					fsx.fsx_projid = getnum(value, &opts[OPT_D],
> @@ -2369,25 +2402,25 @@ main(
>  								I_ALIGN);
>  					break;
>  				case I_LOG:
> -					inodelog = getnum(value, &opts[OPT_I],
> +					*inodelog = getnum(value, &opts[OPT_I],
>  								I_LOG);
> -					isize = 1 << inodelog;
> +					*isize = 1 << *inodelog;
>  					ilflag = 1;
>  					break;
>  				case I_MAXPCT:
> -					imaxpct = getnum(value, &opts[OPT_I],
> +					*imaxpct = getnum(value, &opts[OPT_I],
>  							 I_MAXPCT);
>  					imflag = 1;
>  					break;
>  				case I_PERBLOCK:
> -					inopblock = getnum(value, &opts[OPT_I],
> +					*inopblock = getnum(value, &opts[OPT_I],
>  							   I_PERBLOCK);
>  					ipflag = 1;
>  					break;
>  				case I_SIZE:
> -					isize = getnum(value, &opts[OPT_I],
> +					*isize = getnum(value, &opts[OPT_I],
>  								I_SIZE);
> -					inodelog = libxfs_highbit32(isize);
> +					*inodelog = libxfs_highbit32(*isize);
>  					isflag = 1;
>  					break;
>  				case I_ATTR:
> @@ -2419,7 +2452,7 @@ main(
>  
>  				switch (getsubopt(&p, subopts, &value)) {
>  				case L_AGNUM:
> -					logagno = getnum(value, &opts[OPT_L],
> +					*logagno = getnum(value, &opts[OPT_L],
>  								L_AGNUM);
>  					laflag = 1;
>  					break;
> @@ -2428,16 +2461,16 @@ main(
>  							    L_FILE);
>  					break;
>  				case L_INTERNAL:
> -					loginternal = getnum(value, &opts[OPT_L],
> +					*loginternal = getnum(value, &opts[OPT_L],
>  							     L_INTERNAL);
>  					liflag = 1;
>  					break;
>  				case L_SU:
> -					lsu = getnum(value, &opts[OPT_L], L_SU);
> +					*lsu = getnum(value, &opts[OPT_L], L_SU);
>  					lsuflag = 1;
>  					break;
>  				case L_SUNIT:
> -					lsunit = getnum(value, &opts[OPT_L],
> +					*lsunit = getnum(value, &opts[OPT_L],
>  								L_SUNIT);
>  					lsunitflag = 1;
>  					break;
> @@ -2447,7 +2480,7 @@ main(
>  								L_NAME);
>  					xi.logname = logfile;
>  					ldflag = 1;
> -					loginternal = 0;
> +					*loginternal = 0;
>  					break;
>  				case L_VERSION:
>  					sb_feat.log_version =
> @@ -2456,20 +2489,20 @@ main(
>  					lvflag = 1;
>  					break;
>  				case L_SIZE:
> -					logbytes = getnum(value, &opts[OPT_L],
> +					*logbytes = getnum(value, &opts[OPT_L],
>  								L_SIZE);
>  					break;
>  				case L_SECTLOG:
> -					lsectorlog = getnum(value, &opts[OPT_L],
> +					*lsectorlog = getnum(value, &opts[OPT_L],
>  							    L_SECTLOG);
> -					lsectorsize = 1 << lsectorlog;
> +					*lsectorsize = 1 << *lsectorlog;
>  					lslflag = 1;
>  					break;
>  				case L_SECTSIZE:
> -					lsectorsize = getnum(value, &opts[OPT_L],
> +					*lsectorsize = getnum(value, &opts[OPT_L],
>  							     L_SECTSIZE);
> -					lsectorlog =
> -						libxfs_highbit32(lsectorsize);
> +					*lsectorlog =
> +						libxfs_highbit32(*lsectorsize);
>  					lssflag = 1;
>  					break;
>  				case L_LAZYSBCNTR:
> @@ -2510,6 +2543,7 @@ main(
>  						reqval('m', subopts, M_UUID);
>  					if (platform_uuid_parse(value, &uuid))
>  						illegal(optarg, "m uuid");
> +					opts[OPT_M].subopt_params[M_UUID].value.s = value;
>  					break;
>  				case M_RMAPBT:
>  					sb_feat.rmapbt = getnum(
> @@ -2532,16 +2566,16 @@ main(
>  
>  				switch (getsubopt(&p, subopts, &value)) {
>  				case N_LOG:
> -					dirblocklog = getnum(value, &opts[OPT_N],
> +					*dirblocklog = getnum(value, &opts[OPT_N],
>  							     N_LOG);
> -					dirblocksize = 1 << dirblocklog;
> +					*dirblocksize = 1 << *dirblocklog;
>  					nlflag = 1;
>  					break;
>  				case N_SIZE:
> -					dirblocksize = getnum(value, &opts[OPT_N],
> +					*dirblocksize = getnum(value, &opts[OPT_N],
>  							      N_SIZE);
> -					dirblocklog =
> -						libxfs_highbit32(dirblocksize);
> +					*dirblocklog =
> +						libxfs_highbit32(*dirblocksize);
>  					nsflag = 1;
>  					break;
>  				case N_VERSION:
> @@ -2588,7 +2622,7 @@ main(
>  
>  				switch (getsubopt(&p, subopts, &value)) {
>  				case R_EXTSIZE:
> -					rtextbytes = getnum(value, &opts[OPT_R],
> +					*rtextbytes = getnum(value, &opts[OPT_R],
>  								R_EXTSIZE);
>  					break;
>  				case R_FILE:
> @@ -2601,11 +2635,11 @@ main(
>  							   R_NAME);
>  					break;
>  				case R_SIZE:
> -					rtbytes = getnum(value, &opts[OPT_R],
> +					*rtbytes = getnum(value, &opts[OPT_R],
>  								R_SIZE);
>  					break;
>  				case R_NOALIGN:
> -					norsflag = getnum(value, &opts[OPT_R],
> +					*norsflag = getnum(value, &opts[OPT_R],
>  								R_NOALIGN);
>  					break;
>  				default:
> @@ -2627,9 +2661,9 @@ main(
>  							 S_SECTSIZE, S_SECTLOG);
>  					sectorlog = getnum(value, &opts[OPT_S],
>  							   S_SECTLOG);
> -					lsectorlog = sectorlog;
> +					*lsectorlog = sectorlog;
>  					sectorsize = 1 << sectorlog;
> -					lsectorsize = sectorsize;
> +					*lsectorsize = sectorsize;
>  					lslflag = slflag = 1;
>  					break;
>  				case S_SIZE:
> @@ -2639,10 +2673,10 @@ main(
>  							 S_SECTSIZE);
>  					sectorsize = getnum(value, &opts[OPT_S],
>  							    S_SECTSIZE);
> -					lsectorsize = sectorsize;
> +					*lsectorsize = sectorsize;
>  					sectorlog =
>  						libxfs_highbit32(sectorsize);
> -					lsectorlog = sectorlog;
> +					*lsectorlog = sectorlog;
>  					lssflag = ssflag = 1;
>  					break;
>  				default:
> @@ -2665,6 +2699,36 @@ main(
>  	} else
>  		dfile = xi.dname;
>  
> +	/*
> +	 * Not every field could be connected with a pointer, so just copy
> +	 * the values for a options check.
> +	 */
> +	opts[OPT_D].subopt_params[D_FILE].value.i  = xi.disfile;
> +	opts[OPT_D].subopt_params[D_PROJINHERIT].value.u = fsx.fsx_projid;
> +	opts[OPT_D].subopt_params[D_EXTSZINHERIT].value.u = fsx.fsx_extsize;
> +	opts[OPT_L].subopt_params[L_FILE].value.i = xi.lisfile;
> +	opts[OPT_L].subopt_params[L_VERSION].value.i = sb_feat.log_version;
> +	opts[OPT_L].subopt_params[L_LAZYSBCNTR].value.b = sb_feat.lazy_sb_counters;
> +	opts[OPT_I].subopt_params[I_ATTR].value.i = sb_feat.attr_version ;
> +	opts[OPT_I].subopt_params[I_PROJID32BIT].value.b = !sb_feat.projid16bit ;
> +	opts[OPT_I].subopt_params[I_SPINODES].value.i = sb_feat.spinodes ;
> +	opts[OPT_M].subopt_params[M_FINOBT].value.i = sb_feat.finobt ;
> +	opts[OPT_M].subopt_params[M_RMAPBT].value.b = sb_feat.rmapbt ;
> +	opts[OPT_R].subopt_params[R_FILE].value.i = xi.risfile ;
> +	opts[OPT_R].subopt_params[R_NAME].value.s = xi.rtname;
> +	opts[OPT_R].subopt_params[R_DEV].value.s = xi.rtname;
> +	opts[OPT_S].subopt_params[S_LOG].value.u = sectorsize;
> +	opts[OPT_S].subopt_params[S_SECTLOG].value.u = sectorsize;
> +	opts[OPT_D].subopt_params[D_NAME].value.s = xi.dname;
> +	opts[OPT_D].subopt_params[D_SECTSIZE].value.u = sectorsize;
> +	opts[OPT_D].subopt_params[D_SECTLOG].value.i = sectorlog;
> +	opts[OPT_I].subopt_params[I_ALIGN].value.b = sb_feat.inode_align;
> +	opts[OPT_L].subopt_params[L_NAME].value.s = xi.logname;
> +	opts[OPT_L].subopt_params[L_DEV].value.s = xi.logname;
> +	opts[OPT_M].subopt_params[M_CRC].value.b = sb_feat.crcs_enabled;
> +	opts[OPT_N].subopt_params[N_VERSION].value.i = sb_feat.dir_version;
> +	opts[OPT_N].subopt_params[N_FTYPE].value.b = sb_feat.dirftype;
> +
>  	check_all_opts(opts);
>  
>  	/*
> @@ -2673,14 +2737,14 @@ main(
>  	 * 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;
> +		*blocklog = XFS_DFL_BLOCKSIZE_LOG;
> +		*blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG;
>  	}
> -	if (blocksize < XFS_MIN_BLOCKSIZE || blocksize > XFS_MAX_BLOCKSIZE) {
> -		fprintf(stderr, _("illegal block size %d\n"), blocksize);
> +	if (*blocksize < XFS_MIN_BLOCKSIZE || *blocksize > XFS_MAX_BLOCKSIZE) {
> +		fprintf(stderr, _("illegal block size %d\n"), *blocksize);
>  		usage();
>  	}
> -	if (sb_feat.crcs_enabled && blocksize < XFS_MIN_CRC_BLOCKSIZE) {
> +	if (sb_feat.crcs_enabled && *blocksize < XFS_MIN_CRC_BLOCKSIZE) {
>  		fprintf(stderr,
>  _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
>  			XFS_MIN_CRC_BLOCKSIZE);
> @@ -2701,8 +2765,8 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
>  		sectorsize = XFS_MIN_SECTORSIZE;
>  	}
>  	if (!lslflag && !lssflag) {
> -		lsectorlog = sectorlog;
> -		lsectorsize = sectorsize;
> +		*lsectorlog = sectorlog;
> +		*lsectorsize = sectorsize;
>  	}
>  
>  	/*
> @@ -2712,14 +2776,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, !dbytes, !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, !logbytes, !xi.logname,
> +	if (!*loginternal)
> +		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, !rtbytes, !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)
> @@ -2744,10 +2808,10 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
>  		sectorsize = ft.psectorsize ? ft.psectorsize :
>  					      XFS_MIN_SECTORSIZE;
>  
> -		if ((blocksize < sectorsize) && (blocksize >= ft.lsectorsize)) {
> +		if ((*blocksize < sectorsize) && (*blocksize >= ft.lsectorsize)) {
>  			fprintf(stderr,
>  _("specified blocksize %d is less than device physical sector size %d\n"),
> -				blocksize, ft.psectorsize);
> +				*blocksize, ft.psectorsize);
>  			fprintf(stderr,
>  _("switching to logical sector size %d\n"),
>  				ft.lsectorsize);
> @@ -2758,20 +2822,20 @@ _("switching to logical sector size %d\n"),
>  
>  	if (!ssflag) {
>  		sectorlog = libxfs_highbit32(sectorsize);
> -		if (loginternal) {
> -			lsectorsize = sectorsize;
> -			lsectorlog = sectorlog;
> +		if (*loginternal) {
> +			*lsectorsize = sectorsize;
> +			*lsectorlog = sectorlog;
>  		}
>  	}
>  
>  	if (sectorsize < XFS_MIN_SECTORSIZE ||
> -	    sectorsize > XFS_MAX_SECTORSIZE || sectorsize > blocksize) {
> +	    sectorsize > XFS_MAX_SECTORSIZE || sectorsize > *blocksize) {
>  		if (ssflag)
>  			fprintf(stderr, _("illegal sector size %d\n"), sectorsize);
>  		else
>  			fprintf(stderr,
>  _("block size %d cannot be smaller than logical sector size %d\n"),
> -				blocksize, ft.lsectorsize);
> +				*blocksize, ft.lsectorsize);
>  		usage();
>  	}
>  	if (sectorsize < ft.lsectorsize) {
> @@ -2779,12 +2843,12 @@ _("block size %d cannot be smaller than logical sector size %d\n"),
>  			sectorsize, ft.lsectorsize);
>  		usage();
>  	}
> -	if (lsectorsize < XFS_MIN_SECTORSIZE ||
> -	    lsectorsize > XFS_MAX_SECTORSIZE || lsectorsize > blocksize) {
> -		fprintf(stderr, _("illegal log sector size %d\n"), lsectorsize);
> +	if (*lsectorsize < XFS_MIN_SECTORSIZE ||
> +	    *lsectorsize > XFS_MAX_SECTORSIZE || *lsectorsize > *blocksize) {
> +		fprintf(stderr, _("illegal log sector size %d\n"), *lsectorsize);
>  		usage();
> -	} else if (lsectorsize > XFS_MIN_SECTORSIZE && !lsu && !lsunit) {
> -		lsu = blocksize;
> +	} else if (*lsectorsize > XFS_MIN_SECTORSIZE && !*lsu && !*lsunit) {
> +		*lsu = *blocksize;
>  		sb_feat.log_version = 2;
>  	}
>  
> @@ -2795,7 +2859,7 @@ _("block size %d 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) && *inodelog < XFS_DINODE_DFL_CRC_LOG) {
>  			fprintf(stderr,
>  _("Minimum inode size for CRCs is %d bytes\n"),
>  				1 << XFS_DINODE_DFL_CRC_LOG);
> @@ -2819,89 +2883,89 @@ _("Minimum inode size for CRCs is %d bytes\n"),
>  	}
>  
>  	if (nsflag || nlflag) {
> -		if (dirblocksize < blocksize ||
> -					dirblocksize > XFS_MAX_BLOCKSIZE) {
> +		if (*dirblocksize < *blocksize ||
> +					*dirblocksize > XFS_MAX_BLOCKSIZE) {
>  			fprintf(stderr, _("illegal directory block size %d\n"),
> -				dirblocksize);
> +				*dirblocksize);
>  			usage();
>  		}
>  	} else {
> -		if (blocksize < (1 << XFS_MIN_REC_DIRSIZE))
> -			dirblocklog = XFS_MIN_REC_DIRSIZE;
> +		if (*blocksize < (1 << XFS_MIN_REC_DIRSIZE))
> +			*dirblocklog = XFS_MIN_REC_DIRSIZE;
>  		else
> -			dirblocklog = blocklog;
> -		dirblocksize = 1 << dirblocklog;
> +			*dirblocklog = *blocklog;
> +		*dirblocksize = 1 << *dirblocklog;
>  	}
>  
>  
> -	if (dbytes) {
> -		if (dbytes % XFS_MIN_BLOCKSIZE) {
> +	if (*dbytes) {
> +		if (*dbytes % XFS_MIN_BLOCKSIZE) {
>  			fprintf(stderr,
>  			_("illegal data length %lld, not a multiple of %d\n"),
> -				(long long)dbytes, XFS_MIN_BLOCKSIZE);
> +				(long long)*dbytes, XFS_MIN_BLOCKSIZE);
>  			usage();
>  		}
> -		dblocks = (xfs_rfsblock_t)(dbytes >> blocklog);
> -		if (dbytes % blocksize)
> +		dblocks = (xfs_rfsblock_t)(*dbytes >> *blocklog);
> +		if (*dbytes % *blocksize)
>  			fprintf(stderr, _("warning: "
>  	"data length %lld not a multiple of %d, truncated to %lld\n"),
> -				(long long)dbytes, blocksize,
> -				(long long)(dblocks << blocklog));
> +				(long long)*dbytes, *blocksize,
> +				(long long)(dblocks << *blocklog));
>  	}
>  	if (ipflag) {
> -		inodelog = blocklog - libxfs_highbit32(inopblock);
> -		isize = 1 << inodelog;
> +		*inodelog = *blocklog - libxfs_highbit32(*inopblock);
> +		*isize = 1 << *inodelog;
>  	} else if (!ilflag && !isflag) {
> -		inodelog = sb_feat.crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
> +		*inodelog = sb_feat.crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
>  						: XFS_DINODE_DFL_LOG;
> -		isize = 1 << inodelog;
> +		*isize = 1 << *inodelog;
>  	}
> -	if (sb_feat.crcs_enabled && inodelog < XFS_DINODE_DFL_CRC_LOG) {
> +	if (sb_feat.crcs_enabled && *inodelog < XFS_DINODE_DFL_CRC_LOG) {
>  		fprintf(stderr,
>  		_("Minimum inode size for CRCs is %d bytes\n"),
>  			1 << XFS_DINODE_DFL_CRC_LOG);
>  		usage();
>  	}
>  
> -	if (logbytes) {
> -		if (logbytes % XFS_MIN_BLOCKSIZE) {
> +	if (*logbytes) {
> +		if (*logbytes % XFS_MIN_BLOCKSIZE) {
>  			fprintf(stderr,
>  			_("illegal log length %lld, not a multiple of %d\n"),
> -				(long long)logbytes, XFS_MIN_BLOCKSIZE);
> +				(long long)*logbytes, XFS_MIN_BLOCKSIZE);
>  			usage();
>  		}
> -		logblocks = (xfs_rfsblock_t)(logbytes >> blocklog);
> -		if (logbytes % blocksize)
> +		logblocks = (xfs_rfsblock_t)(*logbytes >> *blocklog);
> +		if (*logbytes % *blocksize)
>  			fprintf(stderr,
>  	_("warning: log length %lld not a multiple of %d, truncated to %lld\n"),
> -				(long long)logbytes, blocksize,
> -				(long long)(logblocks << blocklog));
> +				(long long)*logbytes, *blocksize,
> +				(long long)(logblocks << *blocklog));
>  	}
> -	if (rtbytes) {
> -		if (rtbytes % XFS_MIN_BLOCKSIZE) {
> +	if (*rtbytes) {
> +		if (*rtbytes % XFS_MIN_BLOCKSIZE) {
>  			fprintf(stderr,
>  			_("illegal rt length %lld, not a multiple of %d\n"),
> -				(long long)rtbytes, XFS_MIN_BLOCKSIZE);
> +				(long long)*rtbytes, XFS_MIN_BLOCKSIZE);
>  			usage();
>  		}
> -		rtblocks = (xfs_rfsblock_t)(rtbytes >> blocklog);
> -		if (rtbytes % blocksize)
> +		rtblocks = (xfs_rfsblock_t)(*rtbytes >> *blocklog);
> +		if (*rtbytes % *blocksize)
>  			fprintf(stderr,
>  	_("warning: rt length %lld not a multiple of %d, truncated to %lld\n"),
> -				(long long)rtbytes, blocksize,
> -				(long long)(rtblocks << blocklog));
> +				(long long)*rtbytes, *blocksize,
> +				(long long)(rtblocks << *blocklog));
>  	}
>  	/*
>  	 * If specified, check rt extent size against its constraints.
>  	 */
> -	if (rtextbytes) {
> -		if (rtextbytes % blocksize) {
> +	if (*rtextbytes) {
> +		if (*rtextbytes % *blocksize) {
>  			fprintf(stderr,
>  		_("illegal rt extent size %lld, not a multiple of %d\n"),
> -				(long long)rtextbytes, blocksize);
> +				(long long)*rtextbytes, *blocksize);
>  			usage();
>  		}
> -		rtextblocks = (xfs_extlen_t)(rtextbytes >> blocklog);
> +		rtextblocks = (xfs_extlen_t)(*rtextbytes >> *blocklog);
>  	} else {
>  		/*
>  		 * If realtime extsize has not been specified by the user,
> @@ -2911,23 +2975,23 @@ _("Minimum inode size for CRCs is %d bytes\n"),
>  		__uint64_t	rswidth;
>  		__uint64_t	rtextbytes;
>  
> -		if (!norsflag && !xi.risfile && !(!rtbytes && xi.disfile))
> +		if (!*norsflag && !xi.risfile && !(!*rtbytes && xi.disfile))
>  			rswidth = ft.rtswidth;
>  		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 *blocksize */
> +		if (!*norsflag && rswidth && !(BBTOB(rswidth) % *blocksize)) {
>  			rswidth = DTOBT(rswidth);
> -			rtextbytes = rswidth << blocklog;
> +			rtextbytes = rswidth << *blocklog;
>  			if (XFS_MIN_RTEXTSIZE <= rtextbytes &&
>  			    (rtextbytes <= XFS_MAX_RTEXTSIZE)) {
>  				rtextblocks = rswidth;
>  			}
>  		}
>  		if (!rtextblocks) {
> -			rtextblocks = (blocksize < XFS_MIN_RTEXTSIZE) ?
> -					XFS_MIN_RTEXTSIZE >> blocklog : 1;
> +			rtextblocks = (*blocksize < XFS_MIN_RTEXTSIZE) ?
> +					XFS_MIN_RTEXTSIZE >> *blocklog : 1;
>  		}
>  	}
>  	ASSERT(rtextblocks);
> @@ -2935,34 +2999,34 @@ _("Minimum inode size for CRCs is %d bytes\n"),
>  	/*
>  	 * Check some argument sizes against mins, maxes.
>  	 */
> -	if (isize > blocksize / XFS_MIN_INODE_PERBLOCK ||
> -	    isize < XFS_DINODE_MIN_SIZE ||
> -	    isize > XFS_DINODE_MAX_SIZE) {
> +	if (*isize > *blocksize / XFS_MIN_INODE_PERBLOCK ||
> +	    *isize < XFS_DINODE_MIN_SIZE ||
> +	    *isize > XFS_DINODE_MAX_SIZE) {
>  		int	maxsz;
>  
> -		fprintf(stderr, _("illegal inode size %d\n"), isize);
> -		maxsz = MIN(blocksize / XFS_MIN_INODE_PERBLOCK,
> +		fprintf(stderr, _("illegal inode size %d\n"), *isize);
> +		maxsz = MIN(*blocksize / XFS_MIN_INODE_PERBLOCK,
>  			    XFS_DINODE_MAX_SIZE);
>  		if (XFS_DINODE_MIN_SIZE == maxsz)
>  			fprintf(stderr,
>  			_("allowable inode size with %d byte blocks is %d\n"),
> -				blocksize, XFS_DINODE_MIN_SIZE);
> +				*blocksize, XFS_DINODE_MIN_SIZE);
>  		else
>  			fprintf(stderr,
>  	_("allowable inode size with %d byte blocks is between %d and %d\n"),
> -				blocksize, XFS_DINODE_MIN_SIZE, maxsz);
> +				*blocksize, XFS_DINODE_MIN_SIZE, maxsz);
>  		exit(1);
>  	}
>  
> -	/* if lsu or lsunit was specified, automatically use v2 logs */
> -	if ((lsu || lsunit) && sb_feat.log_version == 1) {
> +	/* if *lsu or *lsunit was specified, automatically use v2 logs */
> +	if ((*lsu || *lsunit) && sb_feat.log_version == 1) {
>  		fprintf(stderr,
>  			_("log stripe unit specified, using v2 logs\n"));
>  		sb_feat.log_version = 2;
>  	}
>  
> -	calc_stripe_factors(dsu, dsw, sectorsize, lsu, lsectorsize,
> -				&dsunit, &dswidth, &lsunit);
> +	calc_stripe_factors(*dsu, *dsw, sectorsize, *lsu, *lsectorsize,
> +				dsunit, dswidth, lsunit);
>  
>  	xi.setblksize = sectorsize;
>  
> @@ -2990,7 +3054,7 @@ _("Minimum inode size for CRCs is %d bytes\n"),
>  	sector_mask = (__uint64_t)-1 << (MAX(sectorlog, 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(*lsectorlog, 10) - BBSHIFT);
>  
>  
>  	/* don't do discards on print-only runs or on files */
> @@ -3004,10 +3068,10 @@ _("Minimum inode size for CRCs is %d bytes\n"),
>  	}
>  
>  	if (!liflag && !ldflag)
> -		loginternal = xi.logdev == 0;
> +		*loginternal = xi.logdev == 0;
>  	if (xi.logname)
>  		logfile = xi.logname;
> -	else if (loginternal)
> +	else if (*loginternal)
>  		logfile = _("internal log");
>  	else if (xi.volname && xi.logdev)
>  		logfile = _("volume log");
> @@ -3022,15 +3086,15 @@ _("Minimum inode size for CRCs is %d bytes\n"),
>  		rtfile = _("volume rt");
>  	else if (!xi.rtdev)
>  		rtfile = _("none");
> -	if (dbytes && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
> +	if (*dbytes && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
>  		fprintf(stderr,
>  			_("size %lld specified for data subvolume is too large, "
>  			"maximum is %lld blocks\n"),
> -			(long long)dbytes, (long long)DTOBT(xi.dsize));
> +			(long long)*dbytes, (long long)DTOBT(xi.dsize));
>  		usage();
> -	} else if (!dbytes && xi.dsize > 0)
> +	} else if (!*dbytes && xi.dsize > 0)
>  		dblocks = DTOBT(xi.dsize);
> -	else if (!dbytes) {
> +	else if (!*dbytes) {
>  		fprintf(stderr, _("can't get size of data subvolume\n"));
>  		usage();
>  	}
> @@ -3041,11 +3105,11 @@ _("Minimum inode size for CRCs is %d bytes\n"),
>  		usage();
>  	}
>  
> -	if (loginternal && xi.logdev) {
> +	if (*loginternal && xi.logdev) {
>  		fprintf(stderr,
>  			_("can't have both external and internal logs\n"));
>  		usage();
> -	} else if (loginternal && sectorsize != lsectorsize) {
> +	} else if (*loginternal && sectorsize != *lsectorsize) {
>  		fprintf(stderr,
>  	_("data and log sector sizes must be equal for internal logs\n"));
>  		usage();
> @@ -3057,147 +3121,147 @@ _("Minimum inode size for CRCs is %d bytes\n"),
>  reported by the device (%u).\n"),
>  			sectorsize, xi.dbsize);
>  	}
> -	if (!loginternal && xi.lbsize > lsectorsize) {
> +	if (!*loginternal && xi.lbsize > *lsectorsize) {
>  		fprintf(stderr, _(
>  "Warning: the log subvolume sector size %u is less than the sector size\n\
>  reported by the device (%u).\n"),
> -			lsectorsize, xi.lbsize);
> +			*lsectorsize, xi.lbsize);
>  	}
> -	if (rtbytes && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
> +	if (*rtbytes && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
>  		fprintf(stderr, _(
>  "Warning: the realtime subvolume sector size %u is less than the sector size\n\
>  reported by the device (%u).\n"),
>  			sectorsize, xi.rtbsize);
>  	}
>  
> -	if (rtbytes && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
> +	if (*rtbytes && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
>  		fprintf(stderr,
>  			_("size %lld specified for rt subvolume is too large, "
>  			"maximum is %lld blocks\n"),
> -			(long long)rtbytes, (long long)DTOBT(xi.rtsize));
> +			(long long)*rtbytes, (long long)DTOBT(xi.rtsize));
>  		usage();
> -	} else if (!rtbytes && xi.rtsize > 0)
> +	} else if (!*rtbytes && xi.rtsize > 0)
>  		rtblocks = DTOBT(xi.rtsize);
> -	else if (rtbytes && !xi.rtdev) {
> +	else if (*rtbytes && !xi.rtdev) {
>  		fprintf(stderr,
>  			_("size specified for non-existent rt subvolume\n"));
>  		usage();
>  	}
>  	if (xi.rtdev) {
>  		rtextents = rtblocks / rtextblocks;
> -		nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY * blocksize);
> +		nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY * *blocksize);
>  	} else {
>  		rtextents = rtblocks = 0;
>  		nbmblocks = 0;
>  	}
>  
> -	if (!nodsflag) {
> -		if (dsunit) {
> -			if (ft.dsunit && ft.dsunit != dsunit) {
> +	if (!*nodsflag) {
> +		if (*dsunit) {
> +			if (ft.dsunit && ft.dsunit != *dsunit) {
>  				fprintf(stderr,
>  					_("%s: Specified data stripe unit %d "
>  					"is not the same as the volume stripe "
>  					"unit %d\n"),
> -					progname, dsunit, ft.dsunit);
> +					progname, *dsunit, ft.dsunit);
>  			}
> -			if (ft.dswidth && ft.dswidth != dswidth) {
> +			if (ft.dswidth && ft.dswidth != *dswidth) {
>  				fprintf(stderr,
>  					_("%s: Specified data stripe width %d "
>  					"is not the same as the volume stripe "
>  					"width %d\n"),
> -					progname, dswidth, ft.dswidth);
> +					progname, *dswidth, ft.dswidth);
>  			}
>  		} else {
> -			dsunit = ft.dsunit;
> -			dswidth = ft.dswidth;
> -			nodsflag = 1;
> +			*dsunit = ft.dsunit;
> +			*dswidth = ft.dswidth;
> +			*nodsflag = 1;
>  		}
> -	} /* else dsunit & dswidth can't be set if nodsflag is set */
> +	} /* else *dsunit & *dswidth can't be set if *nodsflag is set */
>  
>  	if (dasize) {		/* User-specified AG size */
>  		/*
> -		 * Check specified agsize is a multiple of blocksize.
> +		 * Check specified agsize is a multiple of *blocksize.
>  		 */
> -		if (agsize % blocksize) {
> +		if (*agsize % *blocksize) {
>  			fprintf(stderr,
>  		_("agsize (%lld) not a multiple of fs blk size (%d)\n"),
> -				(long long)agsize, blocksize);
> +				(long long)*agsize, *blocksize);
>  			usage();
>  		}
> -		agsize /= blocksize;
> -		agcount = dblocks / agsize + (dblocks % agsize != 0);
> +		*agsize /= *blocksize;
> +		*agcount = dblocks / *agsize + (dblocks % *agsize != 0);
>  
>  	} else if (daflag) {	/* User-specified AG count */
> -		agsize = dblocks / agcount + (dblocks % agcount != 0);
> +		*agsize = dblocks / *agcount + (dblocks % *agcount != 0);
>  	} else {
> -		calc_default_ag_geometry(blocklog, dblocks,
> -				dsunit | dswidth, &agsize, &agcount);
> +		calc_default_ag_geometry(*blocklog, dblocks,
> +				*dsunit | *dswidth, agsize, agcount);
>  	}
>  
>  	/*
> -	 * If dsunit is a multiple of fs blocksize, then check that is a
> +	 * If *dsunit is a multiple of fs *blocksize, then check that is a
>  	 * multiple of the agsize too
>  	 */
> -	if (dsunit && !(BBTOB(dsunit) % blocksize) &&
> -	    dswidth && !(BBTOB(dswidth) % blocksize)) {
> +	if (*dsunit && !(BBTOB(*dsunit) % *blocksize) &&
> +	    *dswidth && !(BBTOB(*dswidth) % *blocksize)) {
>  
> -		/* convert from 512 byte blocks to fs blocksize */
> -		dsunit = DTOBT(dsunit);
> -		dswidth = DTOBT(dswidth);
> +		/* convert from 512 byte blocks to fs *blocksize */
> +		*dsunit = DTOBT(*dsunit);
> +		*dswidth = DTOBT(*dswidth);
>  
>  		/*
> -		 * agsize is not a multiple of dsunit
> +		 * agsize is not a multiple of *dsunit
>  		 */
> -		if ((agsize % dsunit) != 0) {
> +		if ((*agsize % *dsunit) != 0) {
>  			/*
>  			 * Round up to stripe unit boundary. Also make sure
>  			 * that agsize is still larger than
> -			 * XFS_AG_MIN_BLOCKS(blocklog)
> +			 * XFS_AG_MIN_BLOCKS(*blocklog)
>  		 	 */
> -			tmp_agsize = ((agsize + (dsunit - 1))/ dsunit) * dsunit;
> +			tmp_agsize = ((*agsize + (*dsunit - 1))/ *dsunit) * *dsunit;
>  			/*
>  			 * 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_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_MIN_BLOCKS(*blocklog)) &&
> +			    (tmp_agsize <= XFS_AG_MAX_BLOCKS(*blocklog))) {
> +				*agsize = tmp_agsize;
>  				if (!daflag)
> -					agcount = dblocks/agsize +
> -						(dblocks % agsize != 0);
> +					*agcount = dblocks/ *agsize +
> +						(dblocks % *agsize != 0);
>  				if (dasize)
>  					fprintf(stderr,
>  				_("agsize rounded to %lld, swidth = %d\n"),
> -						(long long)agsize, dswidth);
> +						(long long)*agsize, *dswidth);
>  			} else {
> -				if (nodsflag) {
> -					dsunit = dswidth = 0;
> +				if (*nodsflag) {
> +					*dsunit = *dswidth = 0;
>  				} else {
>  					/*
>  					 * agsize is out of bounds, this will
>  					 * print nice details & exit.
>  					 */
> -					validate_ag_geometry(blocklog, dblocks,
> -							    agsize, agcount);
> +					validate_ag_geometry(*blocklog, dblocks,
> +							    *agsize, *agcount);
>  					exit(1);
>  				}
>  			}
>  		}
> -		if (dswidth && ((agsize % dswidth) == 0) && (agcount > 1)) {
> +		if (*dswidth && ((*agsize % *dswidth) == 0) && (*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 = *agsize - *dsunit;
> +			if (tmp_agsize < XFS_AG_MIN_BLOCKS(*blocklog)) {
> +				tmp_agsize = *agsize + *dsunit;
> +				if (dblocks < *agsize) {
>  					/* oh well, nothing to do */
> -					tmp_agsize = agsize;
> +					tmp_agsize = *agsize;
>  				}
>  			}
>  			if (daflag || dasize) {
> @@ -3207,30 +3271,30 @@ 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 %llu.\n"),
>  					(unsigned long long)tmp_agsize);
>  			} else {
> -				agsize = tmp_agsize;
> -				agcount = dblocks/agsize + (dblocks % agsize != 0);
> +				*agsize = tmp_agsize;
> +				*agcount = dblocks/ *agsize + (dblocks % *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 % *agsize != 0 &&
> +				    (dblocks % *agsize <
> +				    XFS_AG_MIN_BLOCKS(*blocklog))) {
> +					dblocks = (xfs_rfsblock_t)((*agcount - 1) * *agsize);
> +					(*agcount)--;
> +					ASSERT(*agcount != 0);
>  				}
>  			}
>  		}
>  	} else {
> -		if (nodsflag)
> -			dsunit = dswidth = 0;
> +		if (*nodsflag)
> +			*dsunit = *dswidth = 0;
>  		else {
>  			fprintf(stderr,
>  				_("%s: Stripe unit(%d) or stripe width(%d) is "
>  				"not a multiple of the block size(%d)\n"),
> -				progname, BBTOB(dsunit), BBTOB(dswidth),
> -				blocksize);
> +				progname, BBTOB(*dsunit), BBTOB(*dswidth),
> +				*blocksize);
>  			exit(1);
>  		}
>  	}
> @@ -3239,82 +3303,83 @@ an AG size that is one stripe unit smaller, for example %llu.\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 % *agsize != 0 &&
> +	     (dblocks % *agsize < XFS_AG_MIN_BLOCKS(*blocklog))) {
>  		ASSERT(!daflag);
> -		dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
> -		agcount--;
> -		ASSERT(agcount != 0);
> +		dblocks = (xfs_rfsblock_t)((*agcount - 1) * *agsize);
> +		(*agcount)--;
> +		ASSERT(*agcount != 0);
>  	}
>  
> -	validate_ag_geometry(blocklog, dblocks, agsize, agcount);
> +	validate_ag_geometry(*blocklog, dblocks, *agsize, *agcount);
>  
>  	if (!imflag)
> -		imaxpct = calc_default_imaxpct(blocklog, dblocks);
> +		*imaxpct = calc_default_imaxpct(*blocklog, dblocks);
>  
>  	/*
> -	 * check that log sunit is modulo fsblksize or default it to dsunit.
> +	 * check that log sunit is modulo fsblksize or default it to *dsunit.
>  	 */
>  
> -	if (lsunit) {
> +	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;
> +		*lsunit = DTOBT(*lsunit);
> +	} else if (sb_feat.log_version == 2 && *loginternal && *dsunit) {
> +		/* *lsunit and *dsunit now in fs blocks */
> +		*lsunit = *dsunit;
>  	}
>  
> -	if (sb_feat.log_version == 2 && (lsunit * blocksize) > 256 * 1024) {
> +	if (sb_feat.log_version == 2 && (*lsunit * *blocksize) > 256 * 1024) {
>  		/* Warn only if specified on commandline */
>  		if (lsuflag || lsunitflag) {
>  			fprintf(stderr,
>  	_("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n"),
> -				(lsunit * blocksize));
> +				(*lsunit * *blocksize));
>  			fprintf(stderr,
>  	_("log stripe unit adjusted to 32KiB\n"));
>  		}
> -		lsunit = (32 * 1024) >> blocklog;
> +		*lsunit = (32 * 1024) >> *blocklog;
>  	}
>  
> -	min_logblocks = max_trans_res(agsize,
> +	min_logblocks = max_trans_res(*agsize,
>  				   sb_feat.crcs_enabled, sb_feat.dir_version,
> -				   sectorlog, blocklog, inodelog, dirblocklog,
> -				   sb_feat.log_version, lsunit, sb_feat.finobt,
> +				   sectorlog, *blocklog, *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 && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
> +	if (!*logbytes && dblocks >= (1024*1024*1024) >> *blocklog)
> +		min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>*blocklog);
> +	if (*logbytes && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
>  		fprintf(stderr,
>  _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"),
> -			(long long)logbytes, (long long)DTOBT(xi.logBBsize));
> +			(long long)*logbytes, (long long)DTOBT(xi.logBBsize));
>  		usage();
> -	} else if (!logbytes && xi.logBBsize > 0) {
> +	} else if (!*logbytes && xi.logBBsize > 0) {
>  		logblocks = DTOBT(xi.logBBsize);
> -	} else if (logbytes && !xi.logdev && !loginternal) {
> +	} else if (*logbytes && !xi.logdev && !*loginternal) {
>  		fprintf(stderr,
>  			_("size specified for non-existent log subvolume\n"));
>  		usage();
> -	} else if (loginternal && logbytes && logblocks >= dblocks) {
> +	} else if (*loginternal && *logbytes && logblocks >= dblocks) {
>  		fprintf(stderr, _("size %lld too large for internal log\n"),
>  			(long long)logblocks);
>  		usage();
> -	} else if (!loginternal && !xi.logdev) {
> +	} else if (!*loginternal && !xi.logdev) {
>  		logblocks = 0;
> -	} else if (loginternal && !logbytes) {
> +	} else if (*loginternal && !*logbytes) {
>  
> -		if (dblocks < GIGABYTES(1, blocklog)) {
> +		if (dblocks < GIGABYTES(1, *blocklog)) {
>  			/* tiny filesystems get minimum sized logs. */
>  			logblocks = min_logblocks;
> -		} else if (dblocks < GIGABYTES(16, blocklog)) {
> +		} else if (dblocks < GIGABYTES(16, *blocklog)) {
>  
>  			/*
>  			 * 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 >> *blocklog,
>  					min_logblocks * XFS_DFL_LOG_FACTOR);
>  		} else {
>  			/*
> @@ -3323,34 +3388,34 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  			 * 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 << *blocklog) / 2048;
> +			logblocks = logblocks >> *blocklog;
>  		}
>  
>  		/* 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 >= *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 << *blocklog) > XFS_MAX_LOG_BYTES)
> +			logblocks = XFS_MAX_LOG_BYTES >> *blocklog;
>  
>  	}
> -	validate_log_size(logblocks, blocklog, min_logblocks);
> +	validate_log_size(logblocks, *blocklog, min_logblocks);
>  
>  	protostring = setup_proto(protofile);
> -	bsize = 1 << (blocklog - BBSHIFT);
> +	bsize = 1 << (*blocklog - BBSHIFT);
>  	mp = &mbuf;
>  	sbp = &mp->m_sb;
>  	memset(mp, 0, sizeof(xfs_mount_t));
> -	sbp->sb_blocklog = (__uint8_t)blocklog;
> +	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_agblklog = (__uint8_t)libxfs_log2_roundup((unsigned int)*agsize);
> +	sbp->sb_agblocks = (xfs_agblock_t)*agsize;
>  	mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
>  	mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
>  
> @@ -3358,22 +3423,22 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  	 * 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, sectorsize, *lsectorsize, *dsunit);
>  
>  
> -	if (loginternal) {
> +	if (*loginternal) {
>  		/*
>  		 * Readjust the log size to fit within an AG if it was sized
>  		 * automatically.
>  		 */
> -		if (!logbytes) {
> +		if (!*logbytes) {
>  			logblocks = MIN(logblocks,
>  					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, *blocklog, min_logblocks);
>  		}
> -		if (logblocks > agsize - libxfs_prealloc_blocks(mp)) {
> +		if (logblocks > *agsize - libxfs_prealloc_blocks(mp)) {
>  			fprintf(stderr,
>  	_("internal log size %lld too large, must fit in allocation group\n"),
>  				(long long)logblocks);
> @@ -3381,35 +3446,35 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  		}
>  
>  		if (laflag) {
> -			if (logagno >= agcount) {
> +			if (*logagno >= *agcount) {
>  				fprintf(stderr,
>  		_("log ag number %d too large, must be less than %lld\n"),
> -					logagno, (long long)agcount);
> +					*logagno, (long long)*agcount);
>  				usage();
>  			}
>  		} else
> -			logagno = (xfs_agnumber_t)(agcount / 2);
> +			*logagno = (xfs_agnumber_t)(*agcount / 2);
>  
> -		logstart = XFS_AGB_TO_FSB(mp, logagno, libxfs_prealloc_blocks(mp));
> +		logstart = XFS_AGB_TO_FSB(mp, *logagno, libxfs_prealloc_blocks(mp));
>  		/*
>  		 * Align the logstart at stripe unit boundary.
>  		 */
> -		if (lsunit) {
> +		if (*lsunit) {
>  			logstart = fixup_internal_log_stripe(mp,
> -					lsflag, logstart, agsize, lsunit,
> -					&logblocks, blocklog, &lalign);
> -		} else if (dsunit) {
> +					lsflag, logstart, *agsize, *lsunit,
> +					&logblocks, *blocklog, &lalign);
> +		} else if (*dsunit) {
>  			logstart = fixup_internal_log_stripe(mp,
> -					lsflag, logstart, agsize, dsunit,
> -					&logblocks, blocklog, &lalign);
> +					lsflag, logstart, *agsize, *dsunit,
> +					&logblocks, *blocklog, &lalign);
>  		}
>  	} else {
>  		logstart = 0;
> -		if (lsunit)
> -			fixup_log_stripe_unit(lsflag, lsunit,
> -					&logblocks, blocklog);
> +		if (*lsunit)
> +			fixup_log_stripe_unit(lsflag, *lsunit,
> +					&logblocks, *blocklog);
>  	}
> -	validate_log_size(logblocks, blocklog, min_logblocks);
> +	validate_log_size(logblocks, *blocklog, min_logblocks);
>  
>  	if (!qflag || Nflag) {
>  		printf(_(
> @@ -3422,19 +3487,19 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  		   "log      =%-22s bsize=%-6d blocks=%lld, version=%d\n"
>  		   "         =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
>  		   "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
> -			dfile, isize, (long long)agcount, (long long)agsize,
> +			dfile, *isize, (long long)*agcount, (long long)*agsize,
>  			"", sectorsize, sb_feat.attr_version,
>  				    !sb_feat.projid16bit,
>  			"", sb_feat.crcs_enabled, sb_feat.finobt, sb_feat.spinodes,
>  			sb_feat.rmapbt, sb_feat.reflink,
> -			"", blocksize, (long long)dblocks, imaxpct,
> -			"", dsunit, dswidth,
> -			sb_feat.dir_version, dirblocksize, sb_feat.nci,
> +			"", *blocksize, (long long)dblocks, *imaxpct,
> +			"", *dsunit, *dswidth,
> +			sb_feat.dir_version, *dirblocksize, sb_feat.nci,
>  				sb_feat.dirftype,
> -			logfile, 1 << blocklog, (long long)logblocks,
> -			sb_feat.log_version, "", lsectorsize, lsunit,
> +			logfile, 1 << *blocklog, (long long)logblocks,
> +			sb_feat.log_version, "", *lsectorsize, *lsunit,
>  				sb_feat.lazy_sb_counters,
> -			rtfile, rtextblocks << blocklog,
> +			rtfile, rtextblocks << *blocklog,
>  			(long long)rtblocks, (long long)rtextents);
>  		if (Nflag)
>  			exit(0);
> @@ -3443,7 +3508,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  	if (label)
>  		strncpy(sbp->sb_fname, label, sizeof(sbp->sb_fname));
>  	sbp->sb_magicnum = XFS_SB_MAGIC;
> -	sbp->sb_blocksize = blocksize;
> +	sbp->sb_blocksize = *blocksize;
>  	sbp->sb_dblocks = dblocks;
>  	sbp->sb_rblocks = rtblocks;
>  	sbp->sb_rextents = rtextents;
> @@ -3453,52 +3518,52 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  	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)*agcount;
>  	sbp->sb_rbmblocks = nbmblocks;
>  	sbp->sb_logblocks = (xfs_extlen_t)logblocks;
>  	sbp->sb_sectsize = (__uint16_t)sectorsize;
> -	sbp->sb_inodesize = (__uint16_t)isize;
> -	sbp->sb_inopblock = (__uint16_t)(blocksize / isize);
> +	sbp->sb_inodesize = (__uint16_t)*isize;
> +	sbp->sb_inopblock = (__uint16_t)(*blocksize / *isize);
>  	sbp->sb_sectlog = (__uint8_t)sectorlog;
> -	sbp->sb_inodelog = (__uint8_t)inodelog;
> -	sbp->sb_inopblog = (__uint8_t)(blocklog - inodelog);
> +	sbp->sb_inodelog = (__uint8_t)*inodelog;
> +	sbp->sb_inopblog = (__uint8_t)(*blocklog - *inodelog);
>  	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 = *imaxpct;
>  	sbp->sb_icount = 0;
>  	sbp->sb_ifree = 0;
> -	sbp->sb_fdblocks = dblocks - agcount * libxfs_prealloc_blocks(mp) -
> -		(loginternal ? logblocks : 0);
> +	sbp->sb_fdblocks = dblocks - *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 = *dsunit;
> +	sbp->sb_width = *dswidth;
> +	sbp->sb_dirblklog = *dirblocklog - *blocklog;
>  	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;
> +		*lsunit = (*lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, *lsunit);
> +		sbp->sb_logsunit = *lsunit;
>  	} else
>  		sbp->sb_logsunit = 0;
>  	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;
> -		sbp->sb_inoalignmt = cluster_size >> blocklog;
> +			cluster_size *= *isize / XFS_DINODE_MIN_SIZE;
> +		sbp->sb_inoalignmt = cluster_size >> *blocklog;
>  		sb_feat.inode_align = sbp->sb_inoalignmt != 0;
>  	} else
>  		sbp->sb_inoalignmt = 0;
> -	if (lsectorsize != BBSIZE || sectorsize != BBSIZE) {
> -		sbp->sb_logsectlog = (__uint8_t)lsectorlog;
> -		sbp->sb_logsectsize = (__uint16_t)lsectorsize;
> +	if (*lsectorsize != BBSIZE || sectorsize != BBSIZE) {
> +		sbp->sb_logsectlog = (__uint8_t)*lsectorlog;
> +		sbp->sb_logsectsize = (__uint16_t)*lsectorsize;
>  	} else {
>  		sbp->sb_logsectlog = 0;
>  		sbp->sb_logsectsize = 0;
>  	}
>  
> -	sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
> +	sb_set_features(&mp->m_sb, &sb_feat, sectorsize, *lsectorsize, *dsunit);
>  
>  	if (force_overwrite)
>  		zero_old_xfs_structures(&xi, sbp);
> @@ -3528,8 +3593,8 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  	 * 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 * *blocksize) {
> +		if (ftruncate(xi.dfd, dblocks * *blocksize) < 0) {
>  			fprintf(stderr,
>  				_("%s: Growing the data section failed\n"),
>  				progname);
> @@ -3557,7 +3622,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  	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, *lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
>  
>  	mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0);
>  	if (mp == NULL) {
> @@ -3571,7 +3636,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  	 * 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 < *agcount; agno++) {
>  		struct xfs_agfl	*agfl;
>  		int		bucket;
>  		struct xfs_perag *pag = libxfs_perag_get(mp, agno);
> @@ -3596,12 +3661,12 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  		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);
> +		if (agno == *agcount - 1)
> +			*agsize = dblocks - (xfs_rfsblock_t)(agno * *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(*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);
> @@ -3623,15 +3688,15 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  		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)(*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))
>  			platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid);
>  
> -		if (loginternal && agno == logagno) {
> +		if (*loginternal && agno == *logagno) {
>  			be32_add_cpu(&agf->agf_freeblks, -logblocks);
> -			agf->agf_longest = cpu_to_be32(agsize -
> +			agf->agf_longest = cpu_to_be32(*agsize -
>  				XFS_FSB_TO_AGBNO(mp, logstart) - logblocks);
>  		}
>  		if (libxfs_alloc_min_freelist(mp, pag) > worst_freelist)
> @@ -3670,7 +3735,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  		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)*agsize);
>  		agi->agi_count = 0;
>  		agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
>  		agi->agi_level = cpu_to_be32(1);
> @@ -3695,7 +3760,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  				bsize);
>  		buf->b_ops = &xfs_allocbt_buf_ops;
>  		block = XFS_BUF_TO_BLOCK(buf);
> -		memset(block, 0, blocksize);
> +		memset(block, 0, *blocksize);
>  		if (xfs_sb_version_hascrc(&mp->m_sb))
>  			libxfs_btree_init_block(mp, buf, XFS_ABTB_CRC_MAGIC, 0, 1,
>  						agno, XFS_BTREE_CRC_BLOCKS);
> @@ -3705,7 +3770,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  
>  		arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
>  		arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
> -		if (loginternal && agno == logagno) {
> +		if (*loginternal && agno == *logagno) {
>  			if (lalign) {
>  				/*
>  				 * Have to insert two records
> @@ -3735,7 +3800,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  		 * 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(*agsize -
>  					be32_to_cpu(arec->ar_startblock));
>  		if (!arec->ar_blockcount)
>  			block->bb_numrecs = 0;
> @@ -3750,7 +3815,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  				bsize);
>  		buf->b_ops = &xfs_allocbt_buf_ops;
>  		block = XFS_BUF_TO_BLOCK(buf);
> -		memset(block, 0, blocksize);
> +		memset(block, 0, *blocksize);
>  		if (xfs_sb_version_hascrc(&mp->m_sb))
>  			libxfs_btree_init_block(mp, buf, XFS_ABTC_CRC_MAGIC, 0, 1,
>  						agno, XFS_BTREE_CRC_BLOCKS);
> @@ -3760,7 +3825,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  
>  		arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
>  		arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
> -		if (loginternal && agno == logagno) {
> +		if (*loginternal && agno == *logagno) {
>  			if (lalign) {
>  				arec->ar_blockcount = cpu_to_be32(
>  					XFS_FSB_TO_AGBNO(mp, logstart) -
> @@ -3780,7 +3845,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  		 * 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(*agsize -
>  					be32_to_cpu(arec->ar_startblock));
>  		if (!arec->ar_blockcount)
>  			block->bb_numrecs = 0;
> @@ -3798,7 +3863,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  			buf->b_ops = &xfs_refcountbt_buf_ops;
>  
>  			block = XFS_BUF_TO_BLOCK(buf);
> -			memset(block, 0, blocksize);
> +			memset(block, 0, *blocksize);
>  			libxfs_btree_init_block(mp, buf, XFS_REFC_CRC_MAGIC, 0,
>  						0, agno, XFS_BTREE_CRC_BLOCKS);
>  
> @@ -3813,7 +3878,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  				bsize);
>  		buf->b_ops = &xfs_inobt_buf_ops;
>  		block = XFS_BUF_TO_BLOCK(buf);
> -		memset(block, 0, blocksize);
> +		memset(block, 0, *blocksize);
>  		if (xfs_sb_version_hascrc(&mp->m_sb))
>  			libxfs_btree_init_block(mp, buf, XFS_IBT_CRC_MAGIC, 0, 0,
>  						agno, XFS_BTREE_CRC_BLOCKS);
> @@ -3831,7 +3896,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  					bsize);
>  			buf->b_ops = &xfs_inobt_buf_ops;
>  			block = XFS_BUF_TO_BLOCK(buf);
> -			memset(block, 0, blocksize);
> +			memset(block, 0, *blocksize);
>  			if (xfs_sb_version_hascrc(&mp->m_sb))
>  				libxfs_btree_init_block(mp, buf, XFS_FIBT_CRC_MAGIC, 0, 0,
>  							agno, XFS_BTREE_CRC_BLOCKS);
> @@ -3850,7 +3915,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  				bsize);
>  			buf->b_ops = &xfs_rmapbt_buf_ops;
>  			block = XFS_BUF_TO_BLOCK(buf);
> -			memset(block, 0, blocksize);
> +			memset(block, 0, *blocksize);
>  
>  			libxfs_btree_init_block(mp, buf, XFS_RMAP_CRC_MAGIC, 0, 0,
>  						agno, XFS_BTREE_CRC_BLOCKS);
> @@ -3905,7 +3970,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  			}
>  
>  			/* account for the log space */
> -			if (loginternal && agno == logagno) {
> +			if (*loginternal && agno == *logagno) {
>  				rrec = XFS_RMAP_REC_ADDR(block,
>  					be16_to_cpu(block->bb_numrecs) + 1);
>  				rrec->rm_startblock = cpu_to_be32(
> @@ -3927,7 +3992,7 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  	 */
>  	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, *blocksize);
>  	libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
>  
>  	/*
> @@ -3936,14 +4001,14 @@ _("size %lld specified for log subvolume is too large, maximum is %lld blocks\n"
>  	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, *blocksize);
>  		libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
>  	}
>  
>  	/*
>  	 * BNO, CNT free block list
>  	 */
> -	for (agno = 0; agno < agcount; agno++) {
> +	for (agno = 0; agno < *agcount; agno++) {
>  		xfs_alloc_arg_t	args;
>  		xfs_trans_t	*tp;
>  		struct xfs_trans_res tres = {0};
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing
  2016-12-07 13:27 ` [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing Jan Tulak
@ 2017-01-13 17:56   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 17:56 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:11PM +0100, Jan Tulak wrote:
> Change subopt_param.conflicts from array of integers into array of structures.
> This prepares the ground for more universal conflict detection in future
> patches.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 243 ++++++++++++++++++++++++++++++--------------------------
>  1 file changed, 129 insertions(+), 114 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index edcfdc0..b47cdae 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -93,8 +93,16 @@ unsigned int		sectorsize;
>   *
>   *   conflicts MANDATORY
>   *     If your subopt is in a conflict with some other option, specify it.
> - *     Accepts the .index values of the conflicting subopts and the last
> - *     member of this list has to be LAST_CONFLICT.
> + *     Accepts the .index values of the conflicting subopt as .opt (e.g. OPT_D)
> + *     and .subopt (e.g. D_FILE). If .test_values is true, then the conflict
> + *     is raised only when the "remote" suboption .value is equal to
> + *     .invalid_value field and the "current" suboption has .value equal to
> + *     .at_value.
> + *     If .test_values is false, a conflict is raised when the suboption appears
> + *     on the CLI, no matter its value. The field .message contains an optional
> + *     explanatory string for the user. This string can't be translated here,
> + *     so it has to be enveloped with _() when printed.
> + *     The last member of this list has to be {LAST_CONFLICT}.
>   *
>   *   minval, maxval OPTIONAL
>   *     These options are used for automatic range check and they have to be
> @@ -133,7 +141,14 @@ struct opt_params {
>  		bool		str_seen;
>  		bool		convert;
>  		bool		is_power_2;
> -		int		conflicts[MAX_CONFLICTS];
> +		struct subopt_conflict {
> +			int		opt;
> +			int		subopt;
> +			bool		test_values;
> +			long long	invalid_value;
> +			long long	at_value;
> +			const char	*message;
> +		} 		conflicts [MAX_CONFLICTS];
>  		long long	minval;
>  		long long	maxval;
>  		long long	defaultval;
> @@ -153,8 +168,8 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = B_LOG,
> -			  .conflicts = { B_SIZE,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_B, B_SIZE, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE_LOG,
>  			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -162,8 +177,8 @@ struct opt_params {
>  			{ .index = B_SIZE,
>  			  .convert = true,
>  			  .is_power_2 = true,
> -			  .conflicts = { B_LOG,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_B, B_LOG, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -209,84 +224,84 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = D_AGCOUNT,
> -			  .conflicts = { D_AGSIZE,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_D, D_AGSIZE, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = XFS_MAX_AGNUMBER,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_FILE,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = D_NAME,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SIZE,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = XFS_AG_MIN_BYTES,
>  			  .maxval = LLONG_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SUNIT,
> -			  .conflicts = { D_NOALIGN,
> -					 D_SU,
> -					 D_SW,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
> +					 {OPT_D, D_SU, false, 0, 0},
> +					 {OPT_D, D_SW, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SWIDTH,
> -			  .conflicts = { D_NOALIGN,
> -					 D_SU,
> -					 D_SW,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
> +					 {OPT_D, D_SU, false, 0, 0},
> +					 {OPT_D, D_SW, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_AGSIZE,
> -			  .conflicts = { D_AGCOUNT,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_D, D_AGCOUNT, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = XFS_AG_MIN_BYTES,
>  			  .maxval = XFS_AG_MAX_BYTES,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SU,
> -			  .conflicts = { D_NOALIGN,
> -					 D_SUNIT,
> -					 D_SWIDTH,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
> +					 {OPT_D, D_SUNIT, false, 0, 0},
> +					 {OPT_D, D_SWIDTH, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SW,
> -			  .conflicts = { D_NOALIGN,
> -					 D_SUNIT,
> -					 D_SWIDTH,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
> +					 {OPT_D, D_SUNIT, false, 0, 0},
> +					 {OPT_D, D_SWIDTH, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SECTLOG,
> -			  .conflicts = { D_SECTSIZE,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_D, D_SECTSIZE, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SECTSIZE,
> -			  .conflicts = { D_SECTLOG,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_D, D_SECTLOG, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
> @@ -294,29 +309,29 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_NOALIGN,
> -			  .conflicts = { D_SU,
> -					 D_SW,
> -					 D_SUNIT,
> -					 D_SWIDTH,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_D, D_SU, false, 0, 0},
> +					 {OPT_D, D_SW, false, 0, 0},
> +					 {OPT_D, D_SUNIT, false, 0, 0},
> +					 {OPT_D, D_SWIDTH, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = D_RTINHERIT,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = D_PROJINHERIT,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_EXTSZINHERIT,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -348,57 +363,57 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = I_ALIGN,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = I_LOG,
> -			  .conflicts = { I_PERBLOCK,
> -					 I_SIZE,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_I, I_PERBLOCK, false, 0, 0},
> +					 {OPT_I, I_SIZE, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = XFS_DINODE_MIN_LOG,
>  			  .maxval = XFS_DINODE_MAX_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_MAXPCT,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 100,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_PERBLOCK,
> -			  .conflicts = { I_LOG,
> -					 I_SIZE,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_I, I_LOG, false, 0, 0},
> +					 {OPT_I, I_SIZE, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_INODE_PERBLOCK,
>  			  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_SIZE,
> -			  .conflicts = { I_PERBLOCK,
> -					 I_LOG,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_I, I_PERBLOCK, false, 0, 0},
> +					 {OPT_I, I_LOG, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
>  			  .minval = XFS_DINODE_MIN_SIZE,
>  			  .maxval = XFS_DINODE_MAX_SIZE,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_ATTR,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 2,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_PROJID32BIT,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = I_SPINODES,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> @@ -438,64 +453,64 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = L_AGNUM,
> -			  .conflicts = { L_DEV,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_L, L_DEV, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_INTERNAL,
> -			  .conflicts = { L_FILE,
> -					 L_DEV,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_L, L_FILE, false, 0, 0},
> +					 {OPT_L, L_DEV, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = L_SIZE,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
>  			  .maxval = XFS_MAX_LOG_BYTES,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_VERSION,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = 2,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SUNIT,
> -			  .conflicts = { L_SU,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_L, L_SU, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SU,
> -			  .conflicts = { L_SUNIT,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_L, L_SUNIT, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = BBTOB(1),
>  			  .maxval = XLOG_MAX_RECORD_BSIZE,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_DEV,
> -			  .conflicts = { L_AGNUM,
> -					 L_INTERNAL,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_L, L_AGNUM, false, 0, 0},
> +					 {OPT_L, L_INTERNAL, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SECTLOG,
> -			  .conflicts = { L_SECTSIZE,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_L, L_SECTSIZE, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SECTSIZE,
> -			  .conflicts = { L_SECTLOG,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_L, L_SECTLOG, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
> @@ -503,20 +518,20 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_FILE,
> -			  .conflicts = { L_INTERNAL,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_L, L_INTERNAL, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = L_NAME,
> -			  .conflicts = { L_AGNUM,
> -					 L_INTERNAL,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_L, L_AGNUM, false, 0, 0},
> +					 {OPT_L, L_INTERNAL, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_LAZYSBCNTR,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> @@ -540,15 +555,15 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = N_LOG,
> -			  .conflicts = { N_SIZE,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_N, N_SIZE, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_REC_DIRSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = N_SIZE,
> -			  .conflicts = { N_LOG,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_N, N_LOG, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
>  			  .minval = 1 << XFS_MIN_REC_DIRSIZE,
> @@ -556,13 +571,13 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = N_VERSION,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 2,
>  			  .maxval = 2,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = N_FTYPE,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> @@ -590,38 +605,38 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = R_EXTSIZE,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = XFS_MIN_RTEXTSIZE,
>  			  .maxval = XFS_MAX_RTEXTSIZE,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_SIZE,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = 0,
>  			  .maxval = LLONG_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_DEV,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_FILE,
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  			{ .index = R_NAME,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_NOALIGN,
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  		},
>  	},
> @@ -642,25 +657,25 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = S_LOG,
> -			  .conflicts = { S_SIZE,
> -					 S_SECTSIZE,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_S, S_SIZE, false, 0, 0},
> +					 {OPT_S, S_SECTSIZE, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SECTLOG,
> -			  .conflicts = { S_SIZE,
> -					 S_SECTSIZE,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_S, S_SIZE, false, 0, 0},
> +					 {OPT_S, S_SECTSIZE, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SIZE,
> -			  .conflicts = { S_LOG,
> -					 S_SECTLOG,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_S, S_LOG, false, 0, 0},
> +					 {OPT_S, S_SECTLOG, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
> @@ -668,9 +683,9 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SECTSIZE,
> -			  .conflicts = { S_LOG,
> -					 S_SECTLOG,
> -					 LAST_CONFLICT },
> +			  .conflicts = { {OPT_S, S_LOG, false, 0, 0},
> +					 {OPT_S, S_SECTLOG, false, 0, 0},
> +					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
> @@ -698,29 +713,29 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = M_CRC,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = M_FINOBT,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = M_UUID,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = M_RMAPBT,
> -			.conflicts = { LAST_CONFLICT },
> +			.conflicts = { {LAST_CONFLICT} },
>  			.minval = 0,
>  			.maxval = 1,
>  			.defaultval = 0,
>  			},
>  			{ .index = M_REFLINK,
> -			  .conflicts = { LAST_CONFLICT },
> +			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 0,
> @@ -1330,14 +1345,14 @@ check_opt(
>  
>  	/* check for conflicts with the option */
>  	for (i = 0; i < MAX_CONFLICTS; i++) {
> -		int conflict_opt = sp->conflicts[i];
> +		struct subopt_conflict conflict_opt = sp->conflicts[i];
>  
> -		if (conflict_opt == LAST_CONFLICT)
> +		if (conflict_opt.opt == LAST_CONFLICT)
>  			break;
> -		if (opts->subopt_params[conflict_opt].seen ||
> -		    opts->subopt_params[conflict_opt].str_seen)
> +		if (opts->subopt_params[conflict_opt.subopt].seen ||
> +		    opts->subopt_params[conflict_opt.subopt].str_seen)
>  			conflict(opts->name, (char **)opts->subopts,
> -				 conflict_opt, index);
> +				 conflict_opt.subopt, index);
>  	}
>  }
>  
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 05/22] mkfs: add a check for conflicting values
  2016-12-07 13:27 ` [PATCH 05/22] mkfs: add a check for conflicting values Jan Tulak
@ 2017-01-13 17:58   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 17:58 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:12PM +0100, Jan Tulak wrote:
> Add a check that reports a conflict only when subopts are mixed with specific values.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 52 ++++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 44 insertions(+), 8 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index b47cdae..3bb9f09 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -1311,18 +1311,18 @@ illegal_option(
>   */
>  static void
>  check_opt(
> -	struct opt_params	*opts,
> +	struct opt_params	*opt,
>  	int			index,
>  	bool			str_seen)
>  {
> -	struct subopt_param	*sp = &opts->subopt_params[index];
> +	struct subopt_param	*sp = &opt->subopt_params[index];
>  	int			i;
>  
>  	if (sp->index != index) {
>  		fprintf(stderr,
>  	("Developer screwed up option parsing (%d/%d)! Please report!\n"),
>  			sp->index, index);
> -		reqval(opts->name, (char **)opts->subopts, index);
> +		reqval(opt->name, (char **)opt->subopts, index);
>  	}
>  
>  	/*
> @@ -1335,11 +1335,11 @@ check_opt(
>  	 */
>  	if (!str_seen) {
>  		if (sp->seen)
> -			respec(opts->name, (char **)opts->subopts, index);
> +			respec(opt->name, (char **)opt->subopts, index);
>  		sp->seen = true;
>  	} else {
>  		if (sp->str_seen)
> -			respec(opts->name, (char **)opts->subopts, index);
> +			respec(opt->name, (char **)opt->subopts, index);
>  		sp->str_seen = true;
>  	}
>  
> @@ -1349,10 +1349,44 @@ check_opt(
>  
>  		if (conflict_opt.opt == LAST_CONFLICT)
>  			break;
> -		if (opts->subopt_params[conflict_opt.subopt].seen ||
> -		    opts->subopt_params[conflict_opt.subopt].str_seen)
> -			conflict(opts->name, (char **)opts->subopts,
> +		if (conflict_opt.test_values)
> +			break;
> +		if (opt->subopt_params[conflict_opt.subopt].seen ||
> +		    opt->subopt_params[conflict_opt.subopt].str_seen) {
> +			conflict(opt->name, (char **)opt->subopts,
>  				 conflict_opt.subopt, index);
> +		}
> +	}
> +}
> +
> +/*
> + * Check for conflict values between options.
> + */
> +static void
> +check_opt_value(
> +	struct opt_params	*opt,
> +	int			index,
> +	long long 		value)
> +{
> +	struct subopt_param	*sp = &opt->subopt_params[index];
> +	int			i;
> +
> +	/* check for conflicts with the option */
> +	for (i = 0; i < MAX_CONFLICTS; i++) {
> +		struct subopt_conflict conflict_opt = sp->conflicts[i];
> +
> +		if (conflict_opt.opt == LAST_CONFLICT)
> +			break;
> +		if (!conflict_opt.test_values)
> +			break;
> +		if ((opt->subopt_params[conflict_opt.subopt].seen ||
> +				    opt->subopt_params[conflict_opt.subopt].str_seen) &&
> +		    opt->subopt_params[conflict_opt.subopt].value
> +				== conflict_opt.invalid_value &&
> +		    value == conflict_opt.at_value) {
> +			conflict(opt->name, (char **)opt->subopts,
> +				 conflict_opt.subopt, index);
> +		}
>  	}
>  }
>  
> @@ -1399,6 +1433,8 @@ getnum(
>  			illegal_option(str, opts, index, NULL);
>  	}
>  
> +	check_opt_value(opts, index, c);
> +
>  	/* Validity check the result. */
>  	if (c < sp->minval)
>  		illegal_option(str, opts, index, _("value is too small"));
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 06/22] mkfs: add cross-section conflict checks
  2016-12-07 13:27 ` [PATCH 06/22] mkfs: add cross-section conflict checks Jan Tulak
@ 2017-01-13 21:18   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 21:18 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:13PM +0100, Jan Tulak wrote:
> Checks are modified to work with cross-section conflicts (data, metada, log, ...).
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 43 ++++++++++++++++++++++++++++++++++---------
>  1 file changed, 34 insertions(+), 9 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 3bb9f09..e46b55c 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -744,6 +744,9 @@ struct opt_params {
>  	},
>  };
>  
> +static void conflict_struct(struct opt_params 	*opt, struct subopt_param *subopt,
> +			struct subopt_conflict 	*conflict);
> +
>  #define TERABYTES(count, blog)	((__uint64_t)(count) << (40 - (blog)))
>  #define GIGABYTES(count, blog)	((__uint64_t)(count) << (30 - (blog)))
>  #define MEGABYTES(count, blog)	((__uint64_t)(count) << (20 - (blog)))
> @@ -1351,10 +1354,9 @@ check_opt(
>  			break;
>  		if (conflict_opt.test_values)
>  			break;
> -		if (opt->subopt_params[conflict_opt.subopt].seen ||
> -		    opt->subopt_params[conflict_opt.subopt].str_seen) {
> -			conflict(opt->name, (char **)opt->subopts,
> -				 conflict_opt.subopt, index);
> +		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
> +		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].str_seen) {
> +			conflict_struct(opt, sp, &conflict_opt);
>  		}
>  	}
>  }
> @@ -1379,13 +1381,12 @@ check_opt_value(
>  			break;
>  		if (!conflict_opt.test_values)
>  			break;
> -		if ((opt->subopt_params[conflict_opt.subopt].seen ||
> -				    opt->subopt_params[conflict_opt.subopt].str_seen) &&
> -		    opt->subopt_params[conflict_opt.subopt].value
> +		if ((opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
> +		     opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].str_seen) &&
> +		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value
>  				== conflict_opt.invalid_value &&
>  		    value == conflict_opt.at_value) {
> -			conflict(opt->name, (char **)opt->subopts,
> -				 conflict_opt.subopt, index);
> +			conflict_struct(opt, sp, &conflict_opt);
>  		}
>  	}
>  }
> @@ -3586,12 +3587,36 @@ conflict(
>  	char		*tab[],
>  	int		oldidx,
>  	int		newidx)
> +
>  {
>  	fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
>  		opt, tab[oldidx], opt, tab[newidx]);
>  	usage();
>  }
>  
> +static void
> +conflict_struct(
> +	struct opt_params 	*opt,
> +	struct subopt_param	*subopt,
> +	struct subopt_conflict 	*conflict)
> +{
> +	if(conflict->message) {
> +		fprintf(stderr, _("Cannot specify both -%c %s and -%c %s: %s\n"),
> +			opt->name,
> +			opt->subopts[subopt->index],
> +			opts[conflict->opt].name,
> +			opts[conflict->opt].subopts[conflict->subopt],
> +			_(conflict->message));
> +	} else {
> +		fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
> +			opt->name,
> +			opt->subopts[subopt->index],
> +			opts[conflict->opt].name,
> +			opts[conflict->opt].subopts[conflict->subopt]);
> +	}
> +	usage();
> +}
> +
>  
>  static void
>  illegal(
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 07/22] mkfs: Move opts related #define to one place
  2016-12-07 13:27 ` [PATCH 07/22] mkfs: Move opts related #define to one place Jan Tulak
@ 2017-01-13 21:19   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 21:19 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:14PM +0100, Jan Tulak wrote:
> Takes all the "#define M_CRC x" from struct opt_params declaration and moves
> them into a single place before the struct. This is because we need to
> cross-link conflicts and we can't link -l version to -m crc if M_CRC is defined
> after the conflict section.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 138 ++++++++++++++++++++++++++++++--------------------------
>  1 file changed, 74 insertions(+), 64 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index e46b55c..2122d1c 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -48,6 +48,80 @@ unsigned int		sectorsize;
>  #define MAX_CONFLICTS	8
>  #define LAST_CONFLICT	(-1)
>  
> +#define OPT_B		0
> +#define B_LOG		0
> +#define B_SIZE		1
> +
> +#define OPT_D		1
> +#define D_AGCOUNT	0
> +#define D_FILE		1
> +#define D_NAME		2
> +#define D_SIZE		3
> +#define D_SUNIT 	4
> +#define D_SWIDTH	5
> +#define D_AGSIZE	6
> +#define D_SU		7
> +#define D_SW		8
> +#define D_SECTLOG	9
> +#define D_SECTSIZE	10
> +#define D_NOALIGN	11
> +#define D_RTINHERIT	12
> +#define D_PROJINHERIT	13
> +#define D_EXTSZINHERIT	14
> +
> +
> +#define OPT_I		2
> +#define I_ALIGN 	0
> +#define I_LOG		1
> +#define I_MAXPCT	2
> +#define I_PERBLOCK	3
> +#define I_SIZE		4
> +#define I_ATTR		5
> +#define I_PROJID32BIT	6
> +#define I_SPINODES	7
> +
> +#define OPT_L		3
> +#define L_AGNUM 	0
> +#define L_INTERNAL	1
> +#define L_SIZE		2
> +#define L_VERSION	3
> +#define L_SUNIT 	4
> +#define L_SU		5
> +#define L_DEV		6
> +#define L_SECTLOG	7
> +#define L_SECTSIZE	8
> +#define L_FILE		9
> +#define L_NAME		10
> +#define L_LAZYSBCNTR	11
> +
> +
> +#define OPT_N		4
> +#define N_LOG		0
> +#define N_SIZE		1
> +#define N_VERSION	2
> +#define N_FTYPE 	3
> +
> +#define OPT_R		5
> +#define R_EXTSIZE	0
> +#define R_SIZE		1
> +#define R_DEV		2
> +#define R_FILE		3
> +#define R_NAME		4
> +#define R_NOALIGN	5
> +
> +#define OPT_S		6
> +#define S_LOG		0
> +#define S_SECTLOG	1
> +#define S_SIZE		2
> +#define S_SECTSIZE	3
> +
> +#define OPT_M		7
> +#define M_CRC		0
> +#define M_FINOBT	1
> +#define M_UUID		2
> +#define M_RMAPBT	3
> +#define M_REFLINK	4
> +
>  /*
>   * Table for parsing mkfs parameters.
>   *
> @@ -155,14 +229,11 @@ struct opt_params {
>  		long long	value;
>  	}		subopt_params[MAX_SUBOPTS];
>  } opts[MAX_OPTS] = {
> -#define OPT_B	0
>  	{
>  		.index = OPT_B,
>  		.name = 'b',
>  		.subopts = {
> -#define	B_LOG		0
>  			"log",
> -#define	B_SIZE		1
>  			"size",
>  			NULL
>  		},
> @@ -185,40 +256,24 @@ struct opt_params {
>  			},
>  		},
>  	},
> -#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
>  		},
> @@ -338,26 +393,17 @@ struct opt_params {
>  			},
>  		},
>  	},
> -#define OPT_I	2
>  	{
>  		.index = OPT_I,
>  		.name = 'i',
>  		.subopts = {
> -#define	I_ALIGN		0
>  			"align",
> -#define	I_LOG		1
>  			"log",
> -#define	I_MAXPCT	2
>  			"maxpct",
> -#define	I_PERBLOCK	3
>  			"perblock",
> -#define	I_SIZE		4
>  			"size",
> -#define	I_ATTR		5
>  			"attr",
> -#define	I_PROJID32BIT	6
>  			"projid32bit",
> -#define I_SPINODES	7
>  			"sparse",
>  			NULL
>  		},
> @@ -420,34 +466,21 @@ struct opt_params {
>  			},
>  		},
>  	},
> -#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
>  		},
> @@ -538,18 +571,13 @@ struct opt_params {
>  			},
>  		},
>  	},
> -#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,
>  		},
> @@ -584,22 +612,15 @@ struct opt_params {
>  			},
>  		},
>  	},
> -#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
>  		},
> @@ -640,18 +661,13 @@ struct opt_params {
>  			},
>  		},
>  	},
> -#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
>  		},
> @@ -694,20 +710,14 @@ struct opt_params {
>  			},
>  		},
>  	},
> -#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
>  		},
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 08/22] mkfs: move conflicts into the table
  2016-12-07 13:27 ` [PATCH 08/22] mkfs: move conflicts into the table Jan Tulak
@ 2017-01-13 21:20   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 21:20 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:15PM +0100, Jan Tulak wrote:
> Fill the table with conflicts data and remove now-duplicate code for their
> detection from other parts of mkfs.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 152 ++++++++++++++++++++++++++------------------------------
>  1 file changed, 70 insertions(+), 82 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 2122d1c..30618ff 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -45,7 +45,7 @@ unsigned int		sectorsize;
>  #define MAX_OPTS	16
>  #define MAX_SUBOPTS	16
>  #define SUBOPT_NEEDS_VAL	(-1LL)
> -#define MAX_CONFLICTS	8
> +#define MAX_CONFLICTS	32
>  #define LAST_CONFLICT	(-1)
>  
>  #define OPT_B		0
> @@ -409,7 +409,9 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = I_ALIGN,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
> +		"Inodes always aligned for CRC enabled filesytems."},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> @@ -447,19 +449,26 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_ATTR,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_CRC, true, 1, 1,
> +		"V2 attribute format always enabled on CRC enabled filesytems."},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 2,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_PROJID32BIT,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
> +		"32 bit Project IDs always enabled on CRC enabled filesytems."},
> +					 {LAST_CONFLICT} },
> +
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = I_SPINODES,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
> +		"Sparse inodes not supported without CRC support."},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> @@ -508,7 +517,9 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_VERSION,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_CRC, true, 1, 1,
> +				"V2 logs are required for CRC enabled filesystems."},
> +					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = 2,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -564,7 +575,9 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_LAZYSBCNTR,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
> +		"Lazy superblock counted always enabled for CRC enabled filesytems."},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> @@ -605,7 +618,9 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = N_FTYPE,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = {  {OPT_M, M_CRC, true, 1, 0,
> +		"Cannot disable ftype with crcs enabled."},
> +					  {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> @@ -640,7 +655,9 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_DEV,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_RMAPBT, false, 0, 0,
> +		"rmapbt not supported without CRC support."},
> +					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_FILE,
> @@ -650,7 +667,9 @@ struct opt_params {
>  			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  			{ .index = R_NAME,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_RMAPBT, false, 0, 0,
> +		"rmapbt not supported without CRC support."},
> +					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_NOALIGN,
> @@ -723,13 +742,35 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = M_CRC,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_L, L_VERSION, true, 1, 1,
> +		"V2 logs are required for CRC enabled filesystems."},
> +					 {OPT_I, I_ALIGN, true, 0, 1,
> +		"Inodes always aligned for CRC enabled filesytems."},
> +					 {OPT_I, I_PROJID32BIT, true, 0, 1,
> +		"32 bit Project IDs always enabled on CRC enabled filesytems."},
> +					 {OPT_I, I_ATTR, true, 1, 1,
> +		"V2 attribute format always enabled on CRC enabled filesytems."},
> +					 {OPT_L, L_LAZYSBCNTR, true, 0, 1,
> +		"Lazy superblock counted always enabled for CRC enabled filesytems."},
> +					 {OPT_M, M_FINOBT, true, 1, 0,
> +		"Finobt not supported without CRC support."},
> +					 {OPT_M, M_RMAPBT, true, 1, 0,
> +		"rmapbt not supported without CRC support."},
> +					 {OPT_M, M_REFLINK, true, 1, 0,
> +		"reflink not supported without CRC support."},
> +					 {OPT_I, I_SPINODES, true, 1, 0,
> +		"Sparse inodes not supported without CRC support."},
> +					 {OPT_N, N_FTYPE, true, 0, 1,
> +		"Cannot disable ftype with crcs enabled."},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = M_FINOBT,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
> +		"Finobt not supported without CRC support\n"},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
> @@ -739,13 +780,21 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = M_RMAPBT,
> -			.conflicts = { {LAST_CONFLICT} },
> +			.conflicts = { {OPT_M, M_CRC, true, 0, 1,
> +		"rmapbt not supported without CRC support."},
> +					{OPT_R, R_NAME, false, 0, 0,
> +		"rmapbt not supported with realtime devices."},
> +					{OPT_R, R_DEV, false, 0, 0,
> +		"rmapbt not supported with realtime devices."},
> +				       {LAST_CONFLICT} },
>  			.minval = 0,
>  			.maxval = 1,
>  			.defaultval = 0,
>  			},
>  			{ .index = M_REFLINK,
> -			  .conflicts = { {LAST_CONFLICT} },
> +			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
> +		"reflink not supported without CRC support."},
> +					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 0,
> @@ -2183,11 +2232,16 @@ _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
>  			XFS_MIN_CRC_BLOCKSIZE);
>  		usage();
>  	}
> +
> +	/*
> +	 * If user explicitly stated -m crc=1 -n ftype=0, an error was already
> +	 * issued. But if -n ftype=0 was stated alone, then it is a conflict
> +	 * with a default value for crc enabled and has to be detected here.
> +	 */
>  	if (sb_feat.crcs_enabled && !sb_feat.dirftype) {
>  		fprintf(stderr, _("cannot disable ftype with crcs enabled\n"));
>  		usage();
>  	}
> -
>  	if (!slflag && !ssflag) {
>  		sectorlog = XFS_MIN_SECTORSIZE_LOG;
>  		sectorsize = XFS_MIN_SECTORSIZE;
> @@ -2293,42 +2347,6 @@ _("Minimum inode size for CRCs is %d bytes\n"),
>  				1 << XFS_DINODE_DFL_CRC_LOG);
>  			usage();
>  		}
> -
> -		/* inodes always aligned */
> -		if (!sb_feat.inode_align) {
> -			fprintf(stderr,
> -_("Inodes always aligned for CRC enabled filesytems\n"));
> -			usage();
> -		}
> -
> -		/* lazy sb counters always on */
> -		if (!sb_feat.lazy_sb_counters) {
> -			fprintf(stderr,
> -_("Lazy superblock counted always enabled for CRC enabled filesytems\n"));
> -			usage();
> -		}
> -
> -		/* version 2 logs always on */
> -		if (sb_feat.log_version != 2) {
> -			fprintf(stderr,
> -_("V2 logs always enabled for CRC enabled filesytems\n"));
> -			usage();
> -		}
> -
> -		/* attr2 always on */
> -		if (sb_feat.attr_version != 2) {
> -			fprintf(stderr,
> -_("V2 attribute format always enabled on CRC enabled filesytems\n"));
> -			usage();
> -		}
> -
> -		/* 32 bit project quota always on */
> -		/* attr2 always on */
> -		if (sb_feat.projid16bit) {
> -			fprintf(stderr,
> -_("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
> -			usage();
> -		}
>  	} else {
>  		/*
>  		 * The kernel doesn't currently support crc=0,finobt=1
> @@ -2336,46 +2354,16 @@ _("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
>  		 * explicitly turned finobt on, then silently turn it off to
>  		 * avoid an unnecessary warning.
>  		 * If the user explicitly tried to use crc=0,finobt=1,
> -		 * then issue an error.
> +		 * the error was already issued during args parsing.
>  		 * The same is also for sparse inodes.
>  		 */
> -		if (sb_feat.finobt && opts[OPT_M].subopt_params[M_FINOBT].seen) {
> -			fprintf(stderr,
> -_("finobt not supported without CRC support\n"));
> -			usage();
> -		}
>  		sb_feat.finobt = 0;
> -
> -		if (sb_feat.spinodes) {
> -			fprintf(stderr,
> -_("sparse inodes not supported without CRC support\n"));
> -			usage();
> -		}
>  		sb_feat.spinodes = 0;
>  
> -		if (sb_feat.rmapbt) {
> -			fprintf(stderr,
> -_("rmapbt not supported without CRC support\n"));
> -			usage();
> -		}
>  		sb_feat.rmapbt = false;
> -
> -		if (sb_feat.reflink) {
> -			fprintf(stderr,
> -_("reflink not supported without CRC support\n"));
> -			usage();
> -		}
>  		sb_feat.reflink = false;
>  	}
>  
> -
> -	if (sb_feat.rmapbt && xi.rtname) {
> -		fprintf(stderr,
> -_("rmapbt not supported with realtime devices\n"));
> -		usage();
> -		sb_feat.rmapbt = false;
> -	}
> -
>  	if (nsflag || nlflag) {
>  		if (dirblocksize < blocksize ||
>  					dirblocksize > XFS_MAX_BLOCKSIZE) {
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 10/22] mkfs: change when to mark an option as seen
  2016-12-07 13:27 ` [PATCH 10/22] mkfs: change when to mark an option as seen Jan Tulak
@ 2017-01-13 21:20   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 21:20 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:17PM +0100, Jan Tulak wrote:
> Make the check for seen option more useful for new conflict detection
> by moving it's logic to new place - we are no longer doing the
> respecification as before.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 40 +++++++++++-----------------------------
>  1 file changed, 11 insertions(+), 29 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index d11fad6..b3625ed 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -152,10 +152,6 @@ unsigned int		sectorsize;
>   *     Do not set this flag when definning a subopt. It is used to remeber that
>   *     this subopt was already seen, for example for conflicts detection.
>   *
> - *   str_seen INTERNAL
> - *     Do not set. It is used internally for respecification, when some options
> - *     has to be parsed twice - at first as a string, then later as a number.
> - *
>   *   convert OPTIONAL
>   *     A flag signalling whether the user-given value can use suffixes.
>   *     If you want to allow the use of user-friendly values like 13k, 42G,
> @@ -212,7 +208,6 @@ struct opt_params {
>  	struct subopt_param {
>  		int		index;
>  		bool		seen;
> -		bool		str_seen;
>  		bool		convert;
>  		bool		is_power_2;
>  		struct subopt_conflict {
> @@ -1375,7 +1370,7 @@ static void
>  check_subopt_conflicts(
>  	struct opt_params	*opt,
>  	int			index,
> -	bool			str_seen)
> +	bool			seen)
>  {
>  	struct subopt_param	*sp = &opt->subopt_params[index];
>  	int			i;
> @@ -1387,23 +1382,6 @@ check_subopt_conflicts(
>  		reqval(opt->name, (char **)opt->subopts, index);
>  	}
>  
> -	/*
> -	 * Check for respecification of the option. This is more complex than it
> -	 * seems because some options are parsed twice - once as a string during
> -	 * input parsing, then later the string is passed to getnum for
> -	 * conversion into a number and bounds checking. Hence the two variables
> -	 * used to track the different uses based on the @str parameter passed
> -	 * to us.
> -	 */
> -	if (!str_seen) {
> -		if (sp->seen)
> -			respec(opt->name, (char **)opt->subopts, index);
> -		sp->seen = true;
> -	} else {
> -		if (sp->str_seen)
> -			respec(opt->name, (char **)opt->subopts, index);
> -		sp->str_seen = true;
> -	}
>  
>  	/* check for conflicts with the option */
>  	for (i = 0; i < MAX_CONFLICTS; i++) {
> @@ -1413,8 +1391,7 @@ check_subopt_conflicts(
>  			break;
>  		if (conflict_opt.test_values)
>  			break;
> -		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
> -		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].str_seen) {
> +		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen) {
>  			conflict_struct(opt, sp, &conflict_opt);
>  		}
>  	}
> @@ -1440,8 +1417,7 @@ check_subopt_value(
>  			break;
>  		if (!conflict_opt.test_values)
>  			break;
> -		if ((opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
> -		     opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].str_seen) &&
> +		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen &&
>  		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value
>  				== conflict_opt.invalid_value &&
>  		    value == conflict_opt.at_value) {
> @@ -1462,7 +1438,11 @@ check_opt(
>  	int index;
>  	struct opt_params *opt = &opts[opti];
>  	for (index = 0; index < MAX_SUBOPTS; index++) {
> +		if (opt->subopts[index] == NULL)
> +			break;
>  		struct subopt_param *sp = &opt->subopt_params[index];
> +		if (!sp->seen)
> +			continue;
>  		check_subopt_conflicts(opt, index, false);
>  		check_subopt_value(opt, index, sp->value);
>  	}
> @@ -1489,9 +1469,12 @@ getnum(
>  	if (!str || *str == '\0') {
>  		if (sp->defaultval == SUBOPT_NEEDS_VAL)
>  			reqval(opts->name, (char **)opts->subopts, index);
> +		sp->seen = true;
>  		return sp->defaultval;
>  	}
>  
> +	sp->seen = true;
> +
>  	if (sp->minval == 0 && sp->maxval == 0) {
>  		fprintf(stderr,
>  			_("Option -%c %s has undefined minval/maxval."
> @@ -1540,11 +1523,10 @@ getstr(
>  	struct opt_params	*opts,
>  	int			index)
>  {
> -	check_subopt(opts, index, true);
> -
>  	/* empty strings for string options are not valid */
>  	if (!str || *str == '\0')
>  		reqval(opts->name, (char **)opts->subopts, index);
> +	opts->subopt_params[index].seen = true;
>  	return str;
>  }
>  
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 11/22] mkfs: add test_default_value into conflict struct
  2016-12-07 13:27 ` [PATCH 11/22] mkfs: add test_default_value into conflict struct Jan Tulak
@ 2017-01-13 21:21   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-13 21:21 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:18PM +0100, Jan Tulak wrote:
> Add a flag signalising that a subopt can be conflicting with
> default value of another option.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 156 +++++++++++++++++++++++++++++---------------------------
>  1 file changed, 80 insertions(+), 76 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index b3625ed..58cc24a 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -172,6 +172,8 @@ unsigned int		sectorsize;
>   *     on the CLI, no matter its value. The field .message contains an optional
>   *     explanatory string for the user. This string can't be translated here,
>   *     so it has to be enveloped with _() when printed.
> + *     The .test_default_value is used when .test_values is true, and extends
> + *     the check also for default values.
>   *     The last member of this list has to be {LAST_CONFLICT}.
>   *
>   *   minval, maxval OPTIONAL
> @@ -214,6 +216,7 @@ struct opt_params {
>  			int		opt;
>  			int		subopt;
>  			bool		test_values;
> +			bool		test_default_value;
>  			long long	invalid_value;
>  			long long	at_value;
>  			const char	*message;
> @@ -234,7 +237,7 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = B_LOG,
> -			  .conflicts = { {OPT_B, B_SIZE, false, 0, 0},
> +			  .conflicts = { {OPT_B, B_SIZE, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE_LOG,
>  			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> @@ -243,7 +246,7 @@ struct opt_params {
>  			{ .index = B_SIZE,
>  			  .convert = true,
>  			  .is_power_2 = true,
> -			  .conflicts = { {OPT_B, B_LOG, false, 0, 0},
> +			  .conflicts = { {OPT_B, B_LOG, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE,
> @@ -274,7 +277,7 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = D_AGCOUNT,
> -			  .conflicts = { {OPT_D, D_AGSIZE, false, 0, 0},
> +			  .conflicts = { {OPT_D, D_AGSIZE, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = XFS_MAX_AGNUMBER,
> @@ -298,25 +301,25 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SUNIT,
> -			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
> -					 {OPT_D, D_SU, false, 0, 0},
> -					 {OPT_D, D_SW, false, 0, 0},
> +			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
> +					 {OPT_D, D_SU, false, false, 0, 0},
> +					 {OPT_D, D_SW, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SWIDTH,
> -			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
> -					 {OPT_D, D_SU, false, 0, 0},
> -					 {OPT_D, D_SW, false, 0, 0},
> +			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
> +					 {OPT_D, D_SU, false, false, 0, 0},
> +					 {OPT_D, D_SW, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_AGSIZE,
> -			  .conflicts = { {OPT_D, D_AGCOUNT, false, 0, 0},
> +			  .conflicts = { {OPT_D, D_AGCOUNT, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = XFS_AG_MIN_BYTES,
> @@ -324,9 +327,9 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SU,
> -			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
> -					 {OPT_D, D_SUNIT, false, 0, 0},
> -					 {OPT_D, D_SWIDTH, false, 0, 0},
> +			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
> +					 {OPT_D, D_SUNIT, false, false, 0, 0},
> +					 {OPT_D, D_SWIDTH, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = 0,
> @@ -334,23 +337,23 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SW,
> -			  .conflicts = { {OPT_D, D_NOALIGN, false, 0, 0},
> -					 {OPT_D, D_SUNIT, false, 0, 0},
> -					 {OPT_D, D_SWIDTH, false, 0, 0},
> +			  .conflicts = { {OPT_D, D_NOALIGN, false, false, 0, 0},
> +					 {OPT_D, D_SUNIT, false, false, 0, 0},
> +					 {OPT_D, D_SWIDTH, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SECTLOG,
> -			  .conflicts = { {OPT_D, D_SECTSIZE, false, 0, 0},
> +			  .conflicts = { {OPT_D, D_SECTSIZE, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SECTSIZE,
> -			  .conflicts = { {OPT_D, D_SECTLOG, false, 0, 0},
> +			  .conflicts = { {OPT_D, D_SECTLOG, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -359,10 +362,10 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_NOALIGN,
> -			  .conflicts = { {OPT_D, D_SU, false, 0, 0},
> -					 {OPT_D, D_SW, false, 0, 0},
> -					 {OPT_D, D_SUNIT, false, 0, 0},
> -					 {OPT_D, D_SWIDTH, false, 0, 0},
> +			  .conflicts = { {OPT_D, D_SU, false, false, 0, 0},
> +					 {OPT_D, D_SW, false, false, 0, 0},
> +					 {OPT_D, D_SUNIT, false, false, 0, 0},
> +					 {OPT_D, D_SWIDTH, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> @@ -404,7 +407,7 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = I_ALIGN,
> -			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
> +			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
>  		"Inodes always aligned for CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -412,8 +415,8 @@ struct opt_params {
>  			  .defaultval = 1,
>  			},
>  			{ .index = I_LOG,
> -			  .conflicts = { {OPT_I, I_PERBLOCK, false, 0, 0},
> -					 {OPT_I, I_SIZE, false, 0, 0},
> +			  .conflicts = { {OPT_I, I_PERBLOCK, false, false, 0, 0},
> +					 {OPT_I, I_SIZE, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_DINODE_MIN_LOG,
>  			  .maxval = XFS_DINODE_MAX_LOG,
> @@ -426,8 +429,8 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_PERBLOCK,
> -			  .conflicts = { {OPT_I, I_LOG, false, 0, 0},
> -					 {OPT_I, I_SIZE, false, 0, 0},
> +			  .conflicts = { {OPT_I, I_LOG, false, false, 0, 0},
> +					 {OPT_I, I_SIZE, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_INODE_PERBLOCK,
> @@ -435,8 +438,8 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_SIZE,
> -			  .conflicts = { {OPT_I, I_PERBLOCK, false, 0, 0},
> -					 {OPT_I, I_LOG, false, 0, 0},
> +			  .conflicts = { {OPT_I, I_PERBLOCK, false, false, 0, 0},
> +					 {OPT_I, I_LOG, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
>  			  .minval = XFS_DINODE_MIN_SIZE,
> @@ -444,7 +447,7 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_ATTR,
> -			  .conflicts = { {OPT_M, M_CRC, true, 1, 1,
> +			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 1,
>  		"V2 attribute format always enabled on CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -452,7 +455,7 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_PROJID32BIT,
> -			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
> +			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
>  		"32 bit Project IDs always enabled on CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
>  
> @@ -461,7 +464,7 @@ struct opt_params {
>  			  .defaultval = 1,
>  			},
>  			{ .index = I_SPINODES,
> -			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
> +			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
>  		"Sparse inodes not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -490,15 +493,15 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = L_AGNUM,
> -			  .conflicts = { {OPT_L, L_DEV, false, 0, 0},
> +			  .conflicts = { {OPT_L, L_DEV, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_INTERNAL,
> -			  .conflicts = { {OPT_L, L_FILE, false, 0, 0},
> -					 {OPT_L, L_DEV, false, 0, 0},
> +			  .conflicts = { {OPT_L, L_FILE, false, false, 0, 0},
> +					 {OPT_L, L_DEV, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> @@ -512,7 +515,7 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_VERSION,
> -			  .conflicts = { {OPT_M, M_CRC, true, 1, 1,
> +			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 1,
>  				"V2 logs are required for CRC enabled filesystems."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
> @@ -520,14 +523,14 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SUNIT,
> -			  .conflicts = { {OPT_L, L_SU, false, 0, 0},
> +			  .conflicts = { {OPT_L, L_SU, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SU,
> -			  .conflicts = { {OPT_L, L_SUNIT, false, 0, 0},
> +			  .conflicts = { {OPT_L, L_SUNIT, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = BBTOB(1),
> @@ -535,20 +538,20 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_DEV,
> -			  .conflicts = { {OPT_L, L_AGNUM, false, 0, 0},
> -					 {OPT_L, L_INTERNAL, false, 0, 0},
> +			  .conflicts = { {OPT_L, L_AGNUM, false, false, 0, 0},
> +					 {OPT_L, L_INTERNAL, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SECTLOG,
> -			  .conflicts = { {OPT_L, L_SECTSIZE, false, 0, 0},
> +			  .conflicts = { {OPT_L, L_SECTSIZE, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SECTSIZE,
> -			  .conflicts = { {OPT_L, L_SECTLOG, false, 0, 0},
> +			  .conflicts = { {OPT_L, L_SECTLOG, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -557,20 +560,20 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_FILE,
> -			  .conflicts = { {OPT_L, L_INTERNAL, false, 0, 0},
> +			  .conflicts = { {OPT_L, L_INTERNAL, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
>  			  .defaultval = 1,
>  			},
>  			{ .index = L_NAME,
> -			  .conflicts = { {OPT_L, L_AGNUM, false, 0, 0},
> -					 {OPT_L, L_INTERNAL, false, 0, 0},
> +			  .conflicts = { {OPT_L, L_AGNUM, false, false, 0, 0},
> +					 {OPT_L, L_INTERNAL, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_LAZYSBCNTR,
> -			  .conflicts = { {OPT_M, M_CRC, true, 1, 0,
> +			  .conflicts = { {OPT_M, M_CRC, true, true, 1, 0,
>  		"Lazy superblock counted always enabled for CRC enabled filesytems."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -591,14 +594,14 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = N_LOG,
> -			  .conflicts = { {OPT_N, N_SIZE, false, 0, 0},
> +			  .conflicts = { {OPT_N, N_SIZE, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_REC_DIRSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = N_SIZE,
> -			  .conflicts = { {OPT_N, N_LOG, false, 0, 0},
> +			  .conflicts = { {OPT_N, N_LOG, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -613,7 +616,7 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = N_FTYPE,
> -			  .conflicts = {  {OPT_M, M_CRC, true, 1, 0,
> +			  .conflicts = {  {OPT_M, M_CRC, true, true, 1, 0,
>  		"Cannot disable ftype with crcs enabled."},
>  					  {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -650,7 +653,7 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_DEV,
> -			  .conflicts = { {OPT_M, M_RMAPBT, false, 0, 0,
> +			  .conflicts = { {OPT_M, M_RMAPBT, false, true, 0, 0,
>  		"rmapbt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -662,7 +665,7 @@ struct opt_params {
>  			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  			{ .index = R_NAME,
> -			  .conflicts = { {OPT_M, M_RMAPBT, false, 0, 0,
> +			  .conflicts = { {OPT_M, M_RMAPBT, false, true, 0, 0,
>  		"rmapbt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -687,24 +690,24 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = S_LOG,
> -			  .conflicts = { {OPT_S, S_SIZE, false, 0, 0},
> -					 {OPT_S, S_SECTSIZE, false, 0, 0},
> +			  .conflicts = { {OPT_S, S_SIZE, false, false, 0, 0},
> +					 {OPT_S, S_SECTSIZE, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SECTLOG,
> -			  .conflicts = { {OPT_S, S_SIZE, false, 0, 0},
> -					 {OPT_S, S_SECTSIZE, false, 0, 0},
> +			  .conflicts = { {OPT_S, S_SIZE, false, false, 0, 0},
> +					 {OPT_S, S_SECTSIZE, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SIZE,
> -			  .conflicts = { {OPT_S, S_LOG, false, 0, 0},
> -					 {OPT_S, S_SECTLOG, false, 0, 0},
> +			  .conflicts = { {OPT_S, S_LOG, false, false, 0, 0},
> +					 {OPT_S, S_SECTLOG, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -713,8 +716,8 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SECTSIZE,
> -			  .conflicts = { {OPT_S, S_LOG, false, 0, 0},
> -					 {OPT_S, S_SECTLOG, false, 0, 0},
> +			  .conflicts = { {OPT_S, S_LOG, false, false, 0, 0},
> +					 {OPT_S, S_SECTLOG, false, false, 0, 0},
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .is_power_2 = true,
> @@ -737,25 +740,25 @@ struct opt_params {
>  		},
>  		.subopt_params = {
>  			{ .index = M_CRC,
> -			  .conflicts = { {OPT_L, L_VERSION, true, 1, 1,
> +			  .conflicts = { {OPT_L, L_VERSION, true, true, 1, 1,
>  		"V2 logs are required for CRC enabled filesystems."},
> -					 {OPT_I, I_ALIGN, true, 0, 1,
> +					 {OPT_I, I_ALIGN, false, true, 0, 1,
>  		"Inodes always aligned for CRC enabled filesytems."},
> -					 {OPT_I, I_PROJID32BIT, true, 0, 1,
> +					 {OPT_I, I_PROJID32BIT, true, true, 0, 1,
>  		"32 bit Project IDs always enabled on CRC enabled filesytems."},
> -					 {OPT_I, I_ATTR, true, 1, 1,
> +					 {OPT_I, I_ATTR, true, true, 1, 1,
>  		"V2 attribute format always enabled on CRC enabled filesytems."},
> -					 {OPT_L, L_LAZYSBCNTR, true, 0, 1,
> +					 {OPT_L, L_LAZYSBCNTR, true, true, 0, 1,
>  		"Lazy superblock counted always enabled for CRC enabled filesytems."},
> -					 {OPT_M, M_FINOBT, true, 1, 0,
> +					 {OPT_M, M_FINOBT, true, true, 1, 0,
>  		"Finobt not supported without CRC support."},
> -					 {OPT_M, M_RMAPBT, true, 1, 0,
> +					 {OPT_M, M_RMAPBT, true, true, 1, 0,
>  		"rmapbt not supported without CRC support."},
> -					 {OPT_M, M_REFLINK, true, 1, 0,
> +					 {OPT_M, M_REFLINK, true, true, 1, 0,
>  		"reflink not supported without CRC support."},
> -					 {OPT_I, I_SPINODES, true, 1, 0,
> +					 {OPT_I, I_SPINODES, true, true, 1, 0,
>  		"Sparse inodes not supported without CRC support."},
> -					 {OPT_N, N_FTYPE, true, 0, 1,
> +					 {OPT_N, N_FTYPE, true, true, 0, 1,
>  		"Cannot disable ftype with crcs enabled."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -763,8 +766,8 @@ struct opt_params {
>  			  .defaultval = 1,
>  			},
>  			{ .index = M_FINOBT,
> -			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
> -		"Finobt not supported without CRC support\n"},
> +			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
> +		"Finobt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> @@ -775,11 +778,11 @@ struct opt_params {
>  			  .defaultval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = M_RMAPBT,
> -			.conflicts = { {OPT_M, M_CRC, true, 0, 1,
> +			.conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
>  		"rmapbt not supported without CRC support."},
> -					{OPT_R, R_NAME, false, 0, 0,
> +					{OPT_R, R_NAME, false, true, 0, 0,
>  		"rmapbt not supported with realtime devices."},
> -					{OPT_R, R_DEV, false, 0, 0,
> +					{OPT_R, R_DEV, false, true, 0, 0,
>  		"rmapbt not supported with realtime devices."},
>  				       {LAST_CONFLICT} },
>  			.minval = 0,
> @@ -787,7 +790,7 @@ struct opt_params {
>  			.defaultval = 0,
>  			},
>  			{ .index = M_REFLINK,
> -			  .conflicts = { {OPT_M, M_CRC, true, 0, 1,
> +			  .conflicts = { {OPT_M, M_CRC, true, true, 0, 1,
>  		"reflink not supported without CRC support."},
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -1417,7 +1420,8 @@ check_subopt_value(
>  			break;
>  		if (!conflict_opt.test_values)
>  			break;
> -		if (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen &&
> +		if ( (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||
> +		      conflict_opt.test_default_value) &&
>  		    opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].value
>  				== conflict_opt.invalid_value &&
>  		    value == conflict_opt.at_value) {
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 03/22] mkfs: extend opt_params with a value field
  2017-01-13 16:55   ` Bill O'Donnell
@ 2017-01-16 12:42     ` Jan Tulak
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Tulak @ 2017-01-16 12:42 UTC (permalink / raw)
  To: Bill O'Donnell; +Cc: linux-xfs

On Fri, Jan 13, 2017 at 5:55 PM, Bill O'Donnell <billodo@redhat.com> wrote:
> On Wed, Dec 07, 2016 at 02:27:10PM +0100, Jan Tulak wrote:
>> Add a new field int opt_params - value, which is filled with user input.
>>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>
> Despite a very minor whitespace issue...
>
> Reviewed-by: Bill O'Donnell <billodo@redhat.com>
>

Whitespace fixed. Thanks for the review. :-)

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

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

* Re: [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure
  2017-01-13 17:08   ` Bill O'Donnell
@ 2017-01-16 12:42     ` Jan Tulak
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Tulak @ 2017-01-16 12:42 UTC (permalink / raw)
  To: Bill O'Donnell; +Cc: linux-xfs

On Fri, Jan 13, 2017 at 6:08 PM, Bill O'Donnell <billodo@redhat.com> wrote:
> On Wed, Dec 07, 2016 at 02:27:16PM +0100, Jan Tulak wrote:
>> Bring the conflicts detection up to date with conflicts declaration.
>>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>
> There's a missing definition for check_subopt()
> FWIW, I see the call gets removed in patch10.
>
>> ---
>>  mkfs/xfs_mkfs.c | 37 +++++++++++++++++++++++++++++++------
>>  1 file changed, 31 insertions(+), 6 deletions(-)
>>
>> [snip...]
>>
>> @@ -1517,7 +1540,7 @@ getstr(
>>       struct opt_params       *opts,
>>       int                     index)
>>  {
>> -     check_opt(opts, index, true);
>> +     check_subopt(opts, index, true);
>
> check_subopt is undefined. ^^^

Should be renamed to check_subopt_conflicts here, even if it is
deleted in the next patch.

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

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

* Re: [PATCH 16/22] mkfs: Change all value fields in opt structures into unions
  2017-01-13 17:36   ` Bill O'Donnell
@ 2017-01-16 12:44     ` Jan Tulak
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Tulak @ 2017-01-16 12:44 UTC (permalink / raw)
  To: Bill O'Donnell; +Cc: linux-xfs

On Fri, Jan 13, 2017 at 6:36 PM, Bill O'Donnell <billodo@redhat.com> wrote:
> On Wed, Dec 07, 2016 at 02:27:23PM +0100, Jan Tulak wrote:
>> Trying to cover all possible values in a single data type is impossible,
>> so convert the field from long long type to union. This requires
>> also some small changes in supporting code, otherwise it would not compile.
>>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>> ---
>>  mkfs/xfs_mkfs.c | 812 +++++++++++++++++++++++++++++++++++---------------------
>>  1 file changed, 504 insertions(+), 308 deletions(-)
>>
>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>> index 7ffe8ff..afc63d1 100644
>> --- a/mkfs/xfs_mkfs.c
>> +++ b/mkfs/xfs_mkfs.c
>> @@ -121,6 +121,231 @@ unsigned int            sectorsize;
>>  #define M_RMAPBT     3
>>  #define M_REFLINK    4
>>
>> [snip]
>>
>> @@ -576,13 +831,15 @@ struct opt_params {
>>               },
>>               .subopt_params = {
>>                       { .index = L_AGNUM,
>> +                       /* FIXME custom type xfs_agnumber_t? */
>
> Does something really need to be fixed here?
>

Maybe: xfs_agnumber_t is defined as __uint32_t, while the code there
is using unsigned int. Which could possibly cause some issues if a
compiler would not treat int as 32 bits. Though we have a lot of other
custom/generic types mismatches around in the code, and it seems
unlikely that GCC or Clang would ever change how big int is... so
perhaps we can let it be. Or maybe let's change the definition of the
union so instead of unsigned int it is __uint32_t?

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

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

* Re: [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values
  2017-01-13 17:43   ` Bill O'Donnell
@ 2017-01-16 12:45     ` Jan Tulak
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Tulak @ 2017-01-16 12:45 UTC (permalink / raw)
  To: Bill O'Donnell; +Cc: linux-xfs

On Fri, Jan 13, 2017 at 6:43 PM, Bill O'Donnell <billodo@redhat.com> wrote:
> On Wed, Dec 07, 2016 at 02:27:24PM +0100, Jan Tulak wrote:
>> We need to have the values inside of the opts structure to validate it.
>> To avoid duplicity and to prevent issues with using a wrong type from
>> values union (e.g trating an int option as long long), keep the old
>> variables like agcount, dsunit, ... and just turn them into pointers
>> to the various opts fields.
>>
>> However, at this moment, do not touch fields in other structures.
>> If some option saves the value into the xi or fsx structure, then
>> simply copy the value at the end of option parsing.
>>
>> This might be changed in future if there is a nice way how to do it.
>>
>> Signed-off-by: Jan Tulak <jtulak@redhat.com>
>> ---
>>  mkfs/xfs_mkfs.c | 771 ++++++++++++++++++++++++++++++--------------------------
>>  1 file changed, 418 insertions(+), 353 deletions(-)
>>
>> [snip]
>>
>> @@ -2003,6 +2004,10 @@ check_all_opts(struct opt_params *opts)
>>       }
>>  }
>>
>> +/* TODO we might loose some numbers here, if they are unsigned and bigger than
>> + * long long max value. So it might be worth to transform this... (think
>> + * __uint64_t)
>> + */
>
> OK, so is this "might" be recommended or should we go ahead and prevent it in this
> implementation? ;)
>

What we are hitting here is similar to the saving the values in the
opts struct. In one case, we can have UINT64_MAX value, in another, it
could be LLONG_MIN. I think that at this moment, it is a bit
theoretical issue as limits of XFS should kick in sooner, but still,
it would be nice to fix it. However, the only way I can see is to
change the return type from long long to something like the union
u_value introduced in this patchset.

I'm still a bit afraid that this thing with multiple types in union
will bite me later, so I kept it here as a TODO for now. Now as I
write this, I realised that maybe the getnum function can be turned
into multiple ones: getnum_int, getnum_uint... as only the last few
lines are really doing the conversion and would differ... Mm... I will
need to think his a bit. Any comments from you?


And thanks for you going through the patchset.

Cheers,
Jan

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

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

* Re: [PATCH 13/22] mkfs: remove zeroed items from conflicts declaration
  2016-12-07 13:27 ` [PATCH 13/22] mkfs: remove zeroed items from conflicts declaration Jan Tulak
@ 2017-01-16 14:13   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-16 14:13 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:20PM +0100, Jan Tulak wrote:
> opts is a global array of structs, so it is already zeroed. No need
> for explicit zeros on items unless we want to highlight the value.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 200 --------------------------------------------------------
>  1 file changed, 200 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index b0e5d75..61caceb 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -239,10 +239,6 @@ struct opt_params {
>  			{ .index = B_LOG,
>  			  .conflicts = { {.opt = OPT_B,
>  					  .subopt = B_SIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE_LOG,
> @@ -254,10 +250,6 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .conflicts = { {.opt = OPT_B,
>  					  .subopt = B_LOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE,
> @@ -291,10 +283,6 @@ struct opt_params {
>  			{ .index = D_AGCOUNT,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_AGSIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
> @@ -321,24 +309,12 @@ struct opt_params {
>  			{ .index = D_SUNIT,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_NOALIGN,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SU,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SW,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -348,24 +324,12 @@ struct opt_params {
>  			{ .index = D_SWIDTH,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_NOALIGN,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SU,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SW,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -375,10 +339,6 @@ struct opt_params {
>  			{ .index = D_AGSIZE,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_AGCOUNT,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> @@ -389,24 +349,12 @@ struct opt_params {
>  			{ .index = D_SU,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_NOALIGN,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SUNIT,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SWIDTH,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> @@ -417,24 +365,12 @@ struct opt_params {
>  			{ .index = D_SW,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_NOALIGN,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SUNIT,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SWIDTH,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -444,10 +380,6 @@ struct opt_params {
>  			{ .index = D_SECTLOG,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_SECTSIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
> @@ -457,10 +389,6 @@ struct opt_params {
>  			{ .index = D_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_SECTLOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> @@ -472,31 +400,15 @@ struct opt_params {
>  			{ .index = D_NOALIGN,
>  			  .conflicts = { {.opt = OPT_D,
>  					  .subopt = D_SU,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SW,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SUNIT,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_D,
>  					  .subopt = D_SWIDTH,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -555,17 +467,9 @@ struct opt_params {
>  			{ .index = I_LOG,
>  			  .conflicts = { {.opt = OPT_I,
>  					  .subopt = I_PERBLOCK,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_I,
>  					  .subopt = I_SIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_DINODE_MIN_LOG,
> @@ -581,17 +485,9 @@ struct opt_params {
>  			{ .index = I_PERBLOCK,
>  			  .conflicts = { {.opt = OPT_I,
>  					  .subopt = I_LOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_I,
>  					  .subopt = I_SIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
> @@ -602,17 +498,9 @@ struct opt_params {
>  			{ .index = I_SIZE,
>  			  .conflicts = { {.opt = OPT_I,
>  					  .subopt = I_PERBLOCK,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_I,
>  					  .subopt = I_LOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .is_power_2 = true,
> @@ -687,10 +575,6 @@ struct opt_params {
>  			{ .index = L_AGNUM,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_DEV,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -700,17 +584,9 @@ struct opt_params {
>  			{ .index = L_INTERNAL,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_FILE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_L,
>  					  .subopt = L_DEV,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -741,10 +617,6 @@ struct opt_params {
>  			{ .index = L_SUNIT,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_SU,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
> @@ -754,10 +626,6 @@ struct opt_params {
>  			{ .index = L_SU,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_SUNIT,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> @@ -768,17 +636,9 @@ struct opt_params {
>  			{ .index = L_DEV,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_AGNUM,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_L,
>  					  .subopt = L_INTERNAL,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -786,10 +646,6 @@ struct opt_params {
>  			{ .index = L_SECTLOG,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_SECTSIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
> @@ -799,10 +655,6 @@ struct opt_params {
>  			{ .index = L_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_SECTLOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> @@ -814,10 +666,6 @@ struct opt_params {
>  			{ .index = L_FILE,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_INTERNAL,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
> @@ -827,17 +675,9 @@ struct opt_params {
>  			{ .index = L_NAME,
>  			  .conflicts = { {.opt = OPT_L,
>  					  .subopt = L_AGNUM,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_L,
>  					  .subopt = L_INTERNAL,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .defaultval = SUBOPT_NEEDS_VAL,
> @@ -872,10 +712,6 @@ struct opt_params {
>  			{ .index = N_LOG,
>  			  .conflicts = { {.opt = OPT_N,
>  					  .subopt = N_SIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_REC_DIRSIZE,
> @@ -885,10 +721,6 @@ struct opt_params {
>  			{ .index = N_SIZE,
>  			  .conflicts = { {.opt = OPT_N,
>  					  .subopt = N_LOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> @@ -998,17 +830,9 @@ struct opt_params {
>  			{ .index = S_LOG,
>  			  .conflicts = { {.opt = OPT_S,
>  					  .subopt = S_SIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_S,
>  					  .subopt = S_SECTSIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
> @@ -1018,17 +842,9 @@ struct opt_params {
>  			{ .index = S_SECTLOG,
>  			  .conflicts = { {.opt = OPT_S,
>  					  .subopt = S_SIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_S,
>  					  .subopt = S_SECTSIZE,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
> @@ -1038,17 +854,9 @@ struct opt_params {
>  			{ .index = S_SIZE,
>  			  .conflicts = { {.opt = OPT_S,
>  					  .subopt = S_LOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_S,
>  					  .subopt = S_SECTLOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> @@ -1060,17 +868,9 @@ struct opt_params {
>  			{ .index = S_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_S,
>  					  .subopt = S_LOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {.opt = OPT_S,
>  					  .subopt = S_SECTLOG,
> -					  .test_values = false,
> -					  .test_default_value = false,
> -					  .invalid_value = 0,
> -					  .at_value = 0
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .convert = true,
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 14/22] mkfs: rename defaultval to flagval in opts
  2016-12-07 13:27 ` [PATCH 14/22] mkfs: rename defaultval to flagval in opts Jan Tulak
@ 2017-01-16 14:14   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-16 14:14 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:21PM +0100, 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.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 122 ++++++++++++++++++++++++++++----------------------------
>  1 file changed, 61 insertions(+), 61 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 61caceb..f7eb191 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -189,7 +189,7 @@ unsigned int		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).
> @@ -197,7 +197,7 @@ unsigned int		sectorsize;
>   *     value in any case.
>   *
>   *   value INTERNAL
> - *     Do not set this on initialization. Use defaultval for what you want
> + *     Do not set this on initialization. Use flagval for what you want
>   *     to do. This is filled with user input and anything you write here now
>   *     is overwritten. (If the user input is a string and not a number, this
>   *     value is set to a positive non-zero number.)
> @@ -223,7 +223,7 @@ struct opt_params {
>  		}		conflicts [MAX_CONFLICTS];
>  		long long	minval;
>  		long long	maxval;
> -		long long	defaultval;
> +		long long	flagval;
>  		long long	value;
>  	}		subopt_params[MAX_SUBOPTS];
>  } opts[MAX_OPTS] = {
> @@ -243,7 +243,7 @@ struct opt_params {
>  					 {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,
> @@ -254,7 +254,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  		},
>  	},
> @@ -287,24 +287,24 @@ struct opt_params {
>  					 {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 = { {.opt = OPT_D,
> @@ -319,7 +319,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SWIDTH,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -334,7 +334,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_AGSIZE,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -344,7 +344,7 @@ struct opt_params {
>  			  .convert = true,
>  			  .minval = XFS_AG_MIN_BYTES,
>  			  .maxval = XFS_AG_MAX_BYTES,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SU,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -360,7 +360,7 @@ struct opt_params {
>  			  .convert = true,
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SW,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -375,7 +375,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SECTLOG,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -384,7 +384,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -395,7 +395,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
>  			  .maxval = XFS_MAX_SECTORSIZE,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = D_NOALIGN,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -413,25 +413,25 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 1,
> +			  .flagval = 1,
>  			},
>  			{ .index = D_RTINHERIT,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .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,
>  			},
>  		},
>  	},
> @@ -462,7 +462,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 1,
> +			  .flagval = 1,
>  			},
>  			{ .index = I_LOG,
>  			  .conflicts = { {.opt = OPT_I,
> @@ -474,13 +474,13 @@ struct opt_params {
>  					 {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 = { {.opt = OPT_I,
> @@ -493,7 +493,7 @@ struct opt_params {
>  			  .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 = { {.opt = OPT_I,
> @@ -506,7 +506,7 @@ struct opt_params {
>  			  .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 = { {.opt = OPT_M,
> @@ -520,7 +520,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 2,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = I_PROJID32BIT,
>  			  .conflicts = { {.opt = OPT_M,
> @@ -535,7 +535,7 @@ struct opt_params {
>  
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 1,
> +			  .flagval = 1,
>  			},
>  			{ .index = I_SPINODES,
>  			  .conflicts = { {.opt = OPT_M,
> @@ -549,7 +549,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 1,
> +			  .flagval = 1,
>  			},
>  		},
>  	},
> @@ -579,7 +579,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_INTERNAL,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -591,14 +591,14 @@ struct opt_params {
>  					 {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 = {{.opt = OPT_M,
> @@ -612,7 +612,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = 2,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SUNIT,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -621,7 +621,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SU,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -631,7 +631,7 @@ struct opt_params {
>  			  .convert = true,
>  			  .minval = BBTOB(1),
>  			  .maxval = XLOG_MAX_RECORD_BSIZE,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_DEV,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -641,7 +641,7 @@ struct opt_params {
>  					  .subopt = L_INTERNAL,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SECTLOG,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -650,7 +650,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -661,7 +661,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
>  			  .maxval = XFS_MAX_SECTORSIZE,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_FILE,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -670,7 +670,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 1,
> +			  .flagval = 1,
>  			},
>  			{ .index = L_NAME,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -680,7 +680,7 @@ struct opt_params {
>  					  .subopt = L_INTERNAL,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = L_LAZYSBCNTR,
>  			  .conflicts = { {.opt = OPT_M,
> @@ -694,7 +694,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 1,
> +			  .flagval = 1,
>  			},
>  		},
>  	},
> @@ -716,7 +716,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_REC_DIRSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = N_SIZE,
>  			  .conflicts = { {.opt = OPT_N,
> @@ -727,13 +727,13 @@ struct opt_params {
>  			  .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 = {  {.opt = OPT_M,
> @@ -747,7 +747,7 @@ struct opt_params {
>  					  {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 1,
> +			  .flagval = 1,
>  			},
>  		},
>  	},
> @@ -769,14 +769,14 @@ struct opt_params {
>  			  .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 = { {.opt = OPT_M,
> @@ -788,12 +788,12 @@ struct opt_params {
>  					  .message =
>  		"rmapbt not supported without CRC support."},
>  					 {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,
> @@ -806,12 +806,12 @@ struct opt_params {
>  					  .message =
>  		"rmapbt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = R_NOALIGN,
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 1,
> +			  .flagval = 1,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  		},
> @@ -837,7 +837,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SECTLOG,
>  			  .conflicts = { {.opt = OPT_S,
> @@ -849,7 +849,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SIZE,
>  			  .conflicts = { {.opt = OPT_S,
> @@ -863,7 +863,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
>  			  .maxval = XFS_MAX_SECTORSIZE,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  			{ .index = S_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_S,
> @@ -877,7 +877,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
>  			  .maxval = XFS_MAX_SECTORSIZE,
> -			  .defaultval = SUBOPT_NEEDS_VAL,
> +			  .flagval = SUBOPT_NEEDS_VAL,
>  			},
>  		},
>  	},
> @@ -977,7 +977,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 1,
> +			  .flagval = 1,
>  			},
>  			{ .index = M_FINOBT,
>  			  .conflicts = { {.opt = OPT_M,
> @@ -991,11 +991,11 @@ struct opt_params {
>  					 {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 = { {.opt = OPT_M,
> @@ -1025,7 +1025,7 @@ struct opt_params {
>  				       {LAST_CONFLICT} },
>  			.minval = 0,
>  			.maxval = 1,
> -			.defaultval = 0,
> +			.flagval = 0,
>  			},
>  			{ .index = M_REFLINK,
>  			.conflicts = { {.opt = OPT_M,
> @@ -1039,7 +1039,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .defaultval = 0,
> +			  .flagval = 0,
>  			},
>  		},
>  	},
> @@ -1715,10 +1715,10 @@ getnum(
>  
>  	/* 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);
>  		sp->seen = true;
> -		return sp->defaultval;
> +		return sp->flagval;
>  	}
>  
>  	sp->seen = true;
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 15/22] mkfs: replace SUBOPT_NEEDS_VAL for a flag
  2016-12-07 13:27 ` [PATCH 15/22] mkfs: replace SUBOPT_NEEDS_VAL for a flag Jan Tulak
@ 2017-01-16 14:14   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-16 14:14 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:22PM +0100, Jan Tulak wrote:
> Do not use a special value as a signal for a required value,
> as it causes issues when we have more value types.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 93 +++++++++++++++++++++++++++++----------------------------
>  1 file changed, 48 insertions(+), 45 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index f7eb191..7ffe8ff 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -44,7 +44,6 @@ unsigned int		sectorsize;
>  
>  #define MAX_OPTS	16
>  #define MAX_SUBOPTS	16
> -#define SUBOPT_NEEDS_VAL	(-1LL)
>  #define MAX_CONFLICTS	32
>  #define LAST_CONFLICT	(-1)
>  
> @@ -193,14 +192,17 @@ unsigned int		sectorsize;
>   *     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).
> - *     A special SUBOPT_NEEDS_VAL can be used to require a user-given
> - *     value in any case.
>   *
>   *   value INTERNAL
>   *     Do not set this on initialization. Use flagval for what you want
>   *     to do. This is filled with user input and anything you write here now
>   *     is overwritten. (If the user input is a string and not a number, this
>   *     value is set to a positive non-zero number.)
> + *
> + *   needs_val OPTIONAL
> + *     Set to true if, when user specifies the option, she has to specify
> + *     a value too. That is, if needs_val is true, then it is not possible to
> + *     use the subopt as a flag.
>   */
>  struct opt_params {
>  	int		index;
> @@ -225,6 +227,7 @@ struct opt_params {
>  		long long	maxval;
>  		long long	flagval;
>  		long long	value;
> +		bool		needs_val;
>  	}		subopt_params[MAX_SUBOPTS];
>  } opts[MAX_OPTS] = {
>  	{
> @@ -243,7 +246,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE_LOG,
>  			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = B_SIZE,
>  			  .convert = true,
> @@ -254,7 +257,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_BLOCKSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  		},
>  	},
> @@ -287,7 +290,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = XFS_MAX_AGNUMBER,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_FILE,
>  			  .conflicts = { {LAST_CONFLICT} },
> @@ -297,14 +300,14 @@ struct opt_params {
>  			},
>  			{ .index = D_NAME,
>  			  .conflicts = { {LAST_CONFLICT} },
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_SIZE,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = XFS_AG_MIN_BYTES,
>  			  .maxval = LLONG_MAX,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_SUNIT,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -319,7 +322,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_SWIDTH,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -334,7 +337,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_AGSIZE,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -344,7 +347,7 @@ struct opt_params {
>  			  .convert = true,
>  			  .minval = XFS_AG_MIN_BYTES,
>  			  .maxval = XFS_AG_MAX_BYTES,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_SU,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -360,7 +363,7 @@ struct opt_params {
>  			  .convert = true,
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_SW,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -375,7 +378,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_SECTLOG,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -384,7 +387,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -395,7 +398,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
>  			  .maxval = XFS_MAX_SECTORSIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_NOALIGN,
>  			  .conflicts = { {.opt = OPT_D,
> @@ -425,13 +428,13 @@ struct opt_params {
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = D_EXTSZINHERIT,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  		},
>  	},
> @@ -474,13 +477,13 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_DINODE_MIN_LOG,
>  			  .maxval = XFS_DINODE_MAX_LOG,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = I_MAXPCT,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 100,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = I_PERBLOCK,
>  			  .conflicts = { {.opt = OPT_I,
> @@ -493,7 +496,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_INODE_PERBLOCK,
>  			  .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = I_SIZE,
>  			  .conflicts = { {.opt = OPT_I,
> @@ -506,7 +509,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_DINODE_MIN_SIZE,
>  			  .maxval = XFS_DINODE_MAX_SIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = I_ATTR,
>  			  .conflicts = { {.opt = OPT_M,
> @@ -520,7 +523,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 2,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = I_PROJID32BIT,
>  			  .conflicts = { {.opt = OPT_M,
> @@ -579,7 +582,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = UINT_MAX,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = L_INTERNAL,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -598,7 +601,7 @@ struct opt_params {
>  			  .convert = true,
>  			  .minval = 2 * 1024 * 1024LL,	/* XXX: XFS_MIN_LOG_BYTES */
>  			  .maxval = XFS_MAX_LOG_BYTES,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = L_VERSION,
>  			  .conflicts = {{.opt = OPT_M,
> @@ -612,7 +615,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = 2,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = L_SUNIT,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -621,7 +624,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 1,
>  			  .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = L_SU,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -631,7 +634,7 @@ struct opt_params {
>  			  .convert = true,
>  			  .minval = BBTOB(1),
>  			  .maxval = XLOG_MAX_RECORD_BSIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = L_DEV,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -641,7 +644,7 @@ struct opt_params {
>  					  .subopt = L_INTERNAL,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = L_SECTLOG,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -650,7 +653,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = L_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -661,7 +664,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
>  			  .maxval = XFS_MAX_SECTORSIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = L_FILE,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -680,7 +683,7 @@ struct opt_params {
>  					  .subopt = L_INTERNAL,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = L_LAZYSBCNTR,
>  			  .conflicts = { {.opt = OPT_M,
> @@ -716,7 +719,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_REC_DIRSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE_LOG,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = N_SIZE,
>  			  .conflicts = { {.opt = OPT_N,
> @@ -727,13 +730,13 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = 1 << XFS_MIN_REC_DIRSIZE,
>  			  .maxval = XFS_MAX_BLOCKSIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = N_VERSION,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .minval = 2,
>  			  .maxval = 2,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = N_FTYPE,
>  			  .conflicts = {  {.opt = OPT_M,
> @@ -769,14 +772,14 @@ struct opt_params {
>  			  .convert = true,
>  			  .minval = XFS_MIN_RTEXTSIZE,
>  			  .maxval = XFS_MAX_RTEXTSIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = R_SIZE,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			  .convert = true,
>  			  .minval = 0,
>  			  .maxval = LLONG_MAX,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = R_DEV,
>  			  .conflicts = { {.opt = OPT_M,
> @@ -788,7 +791,7 @@ struct opt_params {
>  					  .message =
>  		"rmapbt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = R_FILE,
>  			  .minval = 0,
> @@ -806,7 +809,7 @@ struct opt_params {
>  					  .message =
>  		"rmapbt not supported without CRC support."},
>  					 {LAST_CONFLICT} },
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = R_NOALIGN,
>  			  .minval = 0,
> @@ -837,7 +840,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = S_SECTLOG,
>  			  .conflicts = { {.opt = OPT_S,
> @@ -849,7 +852,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = XFS_MIN_SECTORSIZE_LOG,
>  			  .maxval = XFS_MAX_SECTORSIZE_LOG,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = S_SIZE,
>  			  .conflicts = { {.opt = OPT_S,
> @@ -863,7 +866,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
>  			  .maxval = XFS_MAX_SECTORSIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = S_SECTSIZE,
>  			  .conflicts = { {.opt = OPT_S,
> @@ -877,7 +880,7 @@ struct opt_params {
>  			  .is_power_2 = true,
>  			  .minval = XFS_MIN_SECTORSIZE,
>  			  .maxval = XFS_MAX_SECTORSIZE,
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  		},
>  	},
> @@ -995,7 +998,7 @@ struct opt_params {
>  			},
>  			{ .index = M_UUID,
>  			  .conflicts = { {LAST_CONFLICT} },
> -			  .flagval = SUBOPT_NEEDS_VAL,
> +			  .needs_val = true,
>  			},
>  			{ .index = M_RMAPBT,
>  			.conflicts = { {.opt = OPT_M,
> @@ -1039,7 +1042,7 @@ struct opt_params {
>  					 {LAST_CONFLICT} },
>  			  .minval = 0,
>  			  .maxval = 1,
> -			  .flagval = 0,
> +			  .needs_val = true,
>  			},
>  		},
>  	},
> @@ -1715,7 +1718,7 @@ getnum(
>  
>  	/* empty strings might just return a default value */
>  	if (!str || *str == '\0') {
> -		if (sp->flagval == SUBOPT_NEEDS_VAL)
> +		if (sp->needs_val)
>  			reqval(opts->name, (char **)opts->subopts, index);
>  		sp->seen = true;
>  		return sp->flagval;
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 18/22] mkfs: prevent sector/blocksize to be specified as a number of blocks
  2016-12-07 13:27 ` [PATCH 18/22] mkfs: prevent sector/blocksize to be specified as a number of blocks Jan Tulak
@ 2017-01-16 14:15   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-16 14:15 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:25PM +0100, Jan Tulak wrote:
> Documentation states that the options blocked in this patch accepts the
> size only in bytes. So prevent blocksize or sectorsize to be specified as
> a number of blocks or sectors.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index d55eb9a..e8fd49b 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -2041,6 +2041,27 @@ getnum(
>  		}
>  	}
>  
> +	/* Prevent things like specifying blocksize as a number of blocks. */
> +	if (opts->index == OPT_B || opts->index == OPT_S ||
> +		(opts->index == OPT_L && (index == L_SECTLOG ||
> +			index == L_SECTSIZE)) ||
> +		(opts->index == OPT_N && (index == N_SIZE)) ||
> +		(opts->index == OPT_D && (index == D_SECTLOG ||
> +			index == D_SECTSIZE))
> +
> +		) {
> +		switch (str[strlen(str)-1]) {
> +		case 'b':
> +		case 's':
> +			fprintf(stderr,
> +				_("You can't set a sector or block size in "
> +				  "number of blocks or sectors (-%c %s).\n"),
> +				opts->name, opts->subopts[index]);
> +			exit(1);
> +		}
> +
> +	}
> +
>  	sp->seen = true;
>  
>  	if (test_uvalue_num(sp->type, sp->minval, 0) &&
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 19/22] mkfs: subopt flags should be saved as bool
  2016-12-07 13:27 ` [PATCH 19/22] mkfs: subopt flags should be saved as bool Jan Tulak
@ 2017-01-16 14:16   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-16 14:16 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:26PM +0100, Jan Tulak wrote:
> Flag suboptions are not united in what data type they use internally.
> Unify them as boolean.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 52 ++++++++++++++++++++++++++--------------------------
>  1 file changed, 26 insertions(+), 26 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index e8fd49b..9e726f7 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -664,10 +664,10 @@ struct opt_params {
>  			},
>  			{ .index = D_RTINHERIT,
>  			  .conflicts = { {LAST_CONFLICT} },
> -			  .minval.u = 1,
> -			  .maxval.u = 1,
> -			  .flagval.u = 1,
> -			  .type = UINT,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			},
>  			{ .index = D_PROJINHERIT,
>  			  .conflicts = { {LAST_CONFLICT} },
> @@ -804,10 +804,10 @@ struct opt_params {
>  					  .message = \
>  		"Sparse inodes not supported without CRC support."},
>  					 {LAST_CONFLICT} },
> -			  .minval.i = 0,
> -			  .maxval.i = 1,
> -			  .flagval.i = 1,
> -			  .type = INT,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			},
>  		},
>  	},
> @@ -937,10 +937,10 @@ struct opt_params {
>  					  .subopt = L_INTERNAL,
>  					 },
>  					 {LAST_CONFLICT} },
> -			  .minval.i = 0,
> -			  .maxval.i = 1,
> -			  .flagval.i = 1,
> -			  .type = INT,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			},
>  			{ .index = L_NAME,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -1070,10 +1070,10 @@ struct opt_params {
>  			  .type = STRING,
>  			},
>  			{ .index = R_FILE,
> -			  .minval.i = 0,
> -			  .maxval.i = 1,
> -			  .flagval.i = 1,
> -			  .type = INT,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  			{ .index = R_NAME,
> @@ -1090,10 +1090,10 @@ struct opt_params {
>  			  .type = STRING,
>  			},
>  			{ .index = R_NOALIGN,
> -			  .minval.i = 0,
> -			  .maxval.i = 1,
> -			  .flagval.i = 1,
> -			  .type = INT,
> +			  .minval.b = false,
> +			  .maxval.b = true,
> +			  .flagval.b = true,
> +			  .type = BOOL,
>  			  .conflicts = { {LAST_CONFLICT} },
>  			},
>  		},
> @@ -2193,7 +2193,7 @@ main(
>  	xfs_extlen_t		nbmblocks;
>  	int			nlflag;
>  	int			*nodsflag;
> -	int			*norsflag;
> +	bool			*norsflag;
>  	xfs_alloc_rec_t		*nrec;
>  	int			nsflag;
>  	int			nvflag;
> @@ -2256,7 +2256,7 @@ main(
>  	dsu = &opts[OPT_D].subopt_params[D_SU].value.i;
>  	dsw = &opts[OPT_D].subopt_params[D_SW].value.i;
>  	nodsflag = &opts[OPT_D].subopt_params[D_NOALIGN].value.i;
> -	norsflag = &opts[OPT_R].subopt_params[R_NOALIGN].value.i;
> +	norsflag = &opts[OPT_R].subopt_params[R_NOALIGN].value.b;
>  	logagno = &opts[OPT_L].subopt_params[L_AGNUM].value.u;
>  	lsu = &opts[OPT_L].subopt_params[L_SU].value.i;
>  	lsunit = &opts[OPT_L].subopt_params[L_SUNIT].value.i;
> @@ -2391,7 +2391,7 @@ main(
>  					if (c)
>  						fsx.fsx_xflags |=
>  							XFS_DIFLAG_RTINHERIT;
> -					opts[OPT_D].subopt_params[D_RTINHERIT].value.u = c;
> +					opts[OPT_D].subopt_params[D_RTINHERIT].value.b = c;
>  					break;
>  				case D_PROJINHERIT:
>  					fsx.fsx_projid = getnum(value, &opts[OPT_D],
> @@ -2727,15 +2727,15 @@ main(
>  	opts[OPT_D].subopt_params[D_FILE].value.i  = xi.disfile;
>  	opts[OPT_D].subopt_params[D_PROJINHERIT].value.u = fsx.fsx_projid;
>  	opts[OPT_D].subopt_params[D_EXTSZINHERIT].value.u = fsx.fsx_extsize;
> -	opts[OPT_L].subopt_params[L_FILE].value.i = xi.lisfile;
> +	opts[OPT_L].subopt_params[L_FILE].value.b = xi.lisfile;
>  	opts[OPT_L].subopt_params[L_VERSION].value.i = sb_feat.log_version;
>  	opts[OPT_L].subopt_params[L_LAZYSBCNTR].value.b = sb_feat.lazy_sb_counters;
>  	opts[OPT_I].subopt_params[I_ATTR].value.i = sb_feat.attr_version ;
>  	opts[OPT_I].subopt_params[I_PROJID32BIT].value.b = !sb_feat.projid16bit ;
> -	opts[OPT_I].subopt_params[I_SPINODES].value.i = sb_feat.spinodes ;
> +	opts[OPT_I].subopt_params[I_SPINODES].value.b = sb_feat.spinodes ;
>  	opts[OPT_M].subopt_params[M_FINOBT].value.i = sb_feat.finobt ;
>  	opts[OPT_M].subopt_params[M_RMAPBT].value.b = sb_feat.rmapbt ;
> -	opts[OPT_R].subopt_params[R_FILE].value.i = xi.risfile ;
> +	opts[OPT_R].subopt_params[R_FILE].value.b = xi.risfile ;
>  	opts[OPT_R].subopt_params[R_NAME].value.s = xi.rtname;
>  	opts[OPT_R].subopt_params[R_DEV].value.s = xi.rtname;
>  	opts[OPT_S].subopt_params[S_LOG].value.u = sectorsize;
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 20/22] mkfs: move uuid empty string test to getstr()
  2016-12-07 13:27 ` [PATCH 20/22] mkfs: move uuid empty string test to getstr() Jan Tulak
@ 2017-01-16 14:16   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-16 14:16 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:27PM +0100, Jan Tulak wrote:
> No need for this separate check, when we can use getstr() for opts.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 9e726f7..9c1ad11 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -2560,11 +2560,10 @@ main(
>  						value, &opts[OPT_M], M_FINOBT);
>  					break;
>  				case M_UUID:
> -					if (!value || *value == '\0')
> -						reqval('m', subopts, M_UUID);
> +					opts[OPT_M].subopt_params[M_UUID].value.s =
> +						getstr(value, &opts[OPT_M], M_UUID);
>  					if (platform_uuid_parse(value, &uuid))
>  						illegal(optarg, "m uuid");
> -					opts[OPT_M].subopt_params[M_UUID].value.s = value;
>  					break;
>  				case M_RMAPBT:
>  					sb_feat.rmapbt = getnum(
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 21/22] mkfs: remove duplicit checks
  2016-12-07 13:27 ` [PATCH 21/22] mkfs: remove duplicit checks Jan Tulak
@ 2017-01-16 14:17   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-16 14:17 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:28PM +0100, Jan Tulak wrote:
> Remove old checks that are now done by the conflicts table.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 20 --------------------
>  1 file changed, 20 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 9c1ad11..cd0eb20 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -2760,26 +2760,6 @@ main(
>  		*blocklog = XFS_DFL_BLOCKSIZE_LOG;
>  		*blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG;
>  	}
> -	if (*blocksize < XFS_MIN_BLOCKSIZE || *blocksize > XFS_MAX_BLOCKSIZE) {
> -		fprintf(stderr, _("illegal block size %d\n"), *blocksize);
> -		usage();
> -	}
> -	if (sb_feat.crcs_enabled && *blocksize < XFS_MIN_CRC_BLOCKSIZE) {
> -		fprintf(stderr,
> -_("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
> -			XFS_MIN_CRC_BLOCKSIZE);
> -		usage();
> -	}
> -
> -	/*
> -	 * If user explicitly stated -m crc=1 -n ftype=0, an error was already
> -	 * issued. But if -n ftype=0 was stated alone, then it is a conflict
> -	 * with a default value for crc enabled and has to be detected here.
> -	 */
> -	if (sb_feat.crcs_enabled && !sb_feat.dirftype) {
> -		fprintf(stderr, _("cannot disable ftype with crcs enabled\n"));
> -		usage();
> -	}
>  	if (!slflag && !ssflag) {
>  		sectorlog = XFS_MIN_SECTORSIZE_LOG;
>  		sectorsize = XFS_MIN_SECTORSIZE;
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [PATCH 22/22] mkfs: prevent multiple specifications of a single option
  2016-12-07 13:27 ` [PATCH 22/22] mkfs: prevent multiple specifications of a single option Jan Tulak
@ 2017-01-16 14:18   ` Bill O'Donnell
  0 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-16 14:18 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Dec 07, 2016 at 02:27:29PM +0100, Jan Tulak wrote:
> Because things like -l size=40M,size=50M are clearly wrong and should
> not pass. However, in two cases, we do not know if the option is a
> string or number - thus the few more lines with can_respec flag.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index cd0eb20..7fe743a 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -432,6 +432,10 @@ test_uvalue_num(enum e_type a_type, union u_value a, long long b) {
>   *     Set to true if, when user specifies the option, she has to specify
>   *     a value too. That is, if needs_val is true, then it is not possible to
>   *     use the subopt as a flag.
> + *
> + *   can_respec OPTIONAL
> + *     If true, then there can come one getnum() after a getstr() call for this
> + *     option.
>   */
>  struct opt_params {
>  	int		index;
> @@ -458,6 +462,7 @@ struct opt_params {
>  		union u_value value;
>  		enum e_type 	type;
>  		bool		needs_val;
> +		bool		can_respec;
>  	}		subopt_params[MAX_SUBOPTS];
>  } opts[MAX_OPTS] = {
>  	{
> @@ -877,6 +882,7 @@ struct opt_params {
>  			  .maxval.i = 2,
>  			  .needs_val = true,
>  			  .type = INT,
> +			  .can_respec = true,
>  			},
>  			{ .index = L_SUNIT,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -1009,6 +1015,7 @@ struct opt_params {
>  			  .maxval.i = 2,
>  			  .needs_val = true,
>  			  .type = INT,
> +			  .can_respec = true,
>  			},
>  			{ .index = N_FTYPE,
>  			  .conflicts = {  {.opt = OPT_M,
> @@ -2017,6 +2024,22 @@ getnum(
>  	struct subopt_param	*sp = &opts->subopt_params[index];
>  	long long		c;
>  
> +	if (sp->seen){
> +		/* If the option has respec flag, it is possible to do ONE
> +		 * getnum call even with sp->seen == 1. Do this by disabling
> +		 * the respec flag - this time we can continue, but if getnum
> +		 * gets called once more, we will fail.
> +		 */
> +		if (sp->can_respec){
> +			sp->can_respec = false;
> +		} else {
> +			fprintf(stderr,
> +			_("You can't use an option multiple times: -%c %s\n"),
> +			  opts->name, opts->subopts[index]);
> +			usage();
> +		}
> +	}
> +
>  	/* empty strings might just return a default value */
>  	if (!str || *str == '\0') {
>  		if (sp->needs_val)
> @@ -2123,6 +2146,12 @@ getstr(
>  	/* empty strings for string options are not valid */
>  	if (!str || *str == '\0')
>  		reqval(opts->name, (char **)opts->subopts, index);
> +	if (opts->subopt_params[index].seen){
> +		fprintf(stderr,
> +		_("You can't use an option multiple times: -%c %s\n"),
> +		  opts->name, opts->subopts[index]);
> +		usage();
> +	}
>  	opts->subopt_params[index].seen = true;
>  	return str;
>  }
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

* Re: [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (24 preceding siblings ...)
  2017-01-12 15:46 ` Bill O'Donnell
@ 2017-01-16 20:14 ` Bill O'Donnell
  25 siblings, 0 replies; 54+ messages in thread
From: Bill O'Donnell @ 2017-01-16 20:14 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

I ran the patchset through the paces of xfstest -g quick.
Looks good, with the exception of one regression (xfs/191-input-validation).

Cheers-
Bill


On Wed, Dec 07, 2016 at 02:27:07PM +0100, Jan Tulak wrote:
> Hi guys,
> 
> this set is a follow-up of some old discussions and further attempts to untangle
> the spaghetti in options parsing. In short, this patchset allows to define
> cross-option conflicts and makes the conflicts detection more robust.
> 
> Until now, we had the ability to define conflicts within one option (e.g. -d
> sunit/su), but things like -i attr=1 -m crc=1 conflict had to be watched for on
> case by case basis somewhere in the code. Now, when even those situations are
> handled by the same code, it is enough to just add a new entry into a table of
> options. Thus, a reduced chance for an error and easier adding of new cases.
> 
> One of the biggest changes in this set is that user input is now stored in
> directly in the opts table defining allowed range and the like, and variables
> in the main() of mkfs.xfs are now just aliases/pointers. This allows as to do
> conditional checks based on actual values, not only on occurence of an option.
> 
> (A technical note here is that not every value can be saved in a single place
> like this. Some values are already stored in a table or structure and I wanted
> to avoid modifying anything outside of xfs_mkfs.c.)
> 
> I tested it with full xfstests suit and the only failed tests I saw are because
> some ambiguity in arguments parsing was removed. E.g. sometimes it was possible
> to specify size in blocks without stating the blocksize first, even if manpage
> explicitly requires -b or -s to be used before.
> 
> I already submitted part of this patchset as RFC before, but as I got no reply,
> I tried to finish it before submitting again. So, this set works as it is. I
> still have some questions, but they can be answered with "let's keep it as it
> is."
> 
> Number one is simple: What values can use block/sector sizes as user input?
> There is an inconsistency or ambiguity between manual page and the code. Look
> at man page for -d agsize.
> 
> 	agsize=value
> 		This is an alternative to using the  agcount  subop‐
> 		tion.  The  value is the desired size of the alloca‐
> 		tion group expressed in bytes (usually using  the  m
> 		                     ^^^^^^^^
> 		or  g  suffixes).   This value must be a multiple of
> 		[ ... ]
> 
> 
> The option -d agsize explicitly states that it accepts size in bytes, in a
> similar tone to the one used for describe allowed values for -s/-b size:
> 
> 	value in bytes with size=value
> 	      ^^^^^^^^
> 
> However, -d agsize=1234s input was accepted as valid until now. Is the manual
> page misleading, or are the options where b/s suffix is forbidden are
> block/sector size definitions? I decided to err on the compatibility side and
> kept the current behaviour - only blocksize or sectorsize can't be stated in
> blocks and sectors, but it can be easily changed.
> 
> I will send an update for xfstests once I know what behaviour is correct.
> 
> 
> The other question about this patchset is: As we are saving all the values in
> the opt_params table, and the values have different types, I thought it
> necessary to not use a single data type for everything and created an union
> field (could be easily changed to struct, that would not change anything
> important). Do you see any non-adressed issue with this approach? Is there
> another way how to solve the problem?
> 
> If nothing else, numbers and strings can't be easily saved in a single
> variable. Also, as we are using shift operations, any type conversions
> (like storing everything in long long type) could cause trouble. This is one of
> the reasons why I'm changed the variables in main() to pointers. This allows
> for simple and easy access to the correct union field, so unless one is adding
> a new option, there should be no need to remember the correct date type. If the
> pointer assignment is done correctly, then GCC will watch for type mismatch.
> 
> I really couldn't find out better solution, but see for yourself, this change
> is done in "mkfs: Change all value fields in opt structures into unions"
> and "mkfs: use old variables as pointers to the new opts struct values".
> 
> 
> So, I think this is all I wanted to cover in the cover letter. :-)
> I will be glad for any comments or bugs you find out.
> 
> Thanks for your time,
> 
> Jan
> 
> 
> Jan Tulak (22):
>   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: change conflicts array into a table capable of cross-option
>     addressing
>   mkfs: add a check for conflicting values
>   mkfs: add cross-section conflict checks
>   mkfs: Move opts related #define to one place
>   mkfs: move conflicts into the table
>   mkfs: change conflict checks to utilize the new conflict structure
>   mkfs: change when to mark an option as seen
>   mkfs: add test_default_value into conflict struct
>   mkfs: expand conflicts declarations to named declaration
>   mkfs: remove zeroed items from conflicts declaration
>   mkfs: rename defaultval to flagval in opts
>   mkfs: replace SUBOPT_NEEDS_VAL for a flag
>   mkfs: Change all value fields in opt structures into unions
>   mkfs: use old variables as pointers to the new opts struct values
>   mkfs: prevent sector/blocksize to be specified as a number of blocks
>   mkfs: subopt flags should be saved as bool
>   mkfs: move uuid empty string test to getstr()
>   mkfs: remove duplicit checks
>   mkfs: prevent multiple specifications of a single option
> 
>  mkfs/xfs_mkfs.c | 2952 +++++++++++++++++++++++++++++++++++--------------------
>  1 file changed, 1864 insertions(+), 1088 deletions(-)
> 
> -- 
> 2.8.1
> 
> --
> 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] 54+ messages in thread

end of thread, other threads:[~2017-01-16 20:14 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-07 13:27 [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
2016-12-07 13:27 ` [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum Jan Tulak
2017-01-13 16:56   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 02/22] mkfs: merge tables for opts parsing into one table Jan Tulak
2017-01-13 16:57   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 03/22] mkfs: extend opt_params with a value field Jan Tulak
2017-01-13 16:55   ` Bill O'Donnell
2017-01-16 12:42     ` Jan Tulak
2016-12-07 13:27 ` [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing Jan Tulak
2017-01-13 17:56   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 05/22] mkfs: add a check for conflicting values Jan Tulak
2017-01-13 17:58   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 06/22] mkfs: add cross-section conflict checks Jan Tulak
2017-01-13 21:18   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 07/22] mkfs: Move opts related #define to one place Jan Tulak
2017-01-13 21:19   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 08/22] mkfs: move conflicts into the table Jan Tulak
2017-01-13 21:20   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure Jan Tulak
2017-01-13 17:08   ` Bill O'Donnell
2017-01-16 12:42     ` Jan Tulak
2016-12-07 13:27 ` [PATCH 10/22] mkfs: change when to mark an option as seen Jan Tulak
2017-01-13 21:20   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 11/22] mkfs: add test_default_value into conflict struct Jan Tulak
2017-01-13 21:21   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 12/22] mkfs: expand conflicts declarations to named declaration Jan Tulak
2017-01-13 17:21   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 13/22] mkfs: remove zeroed items from conflicts declaration Jan Tulak
2017-01-16 14:13   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 14/22] mkfs: rename defaultval to flagval in opts Jan Tulak
2017-01-16 14:14   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 15/22] mkfs: replace SUBOPT_NEEDS_VAL for a flag Jan Tulak
2017-01-16 14:14   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 16/22] mkfs: Change all value fields in opt structures into unions Jan Tulak
2017-01-13 17:36   ` Bill O'Donnell
2017-01-16 12:44     ` Jan Tulak
2016-12-07 13:27 ` [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values Jan Tulak
2017-01-13 17:43   ` Bill O'Donnell
2017-01-16 12:45     ` Jan Tulak
2016-12-07 13:27 ` [PATCH 18/22] mkfs: prevent sector/blocksize to be specified as a number of blocks Jan Tulak
2017-01-16 14:15   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 19/22] mkfs: subopt flags should be saved as bool Jan Tulak
2017-01-16 14:16   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 20/22] mkfs: move uuid empty string test to getstr() Jan Tulak
2017-01-16 14:16   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 21/22] mkfs: remove duplicit checks Jan Tulak
2017-01-16 14:17   ` Bill O'Donnell
2016-12-07 13:27 ` [PATCH 22/22] mkfs: prevent multiple specifications of a single option Jan Tulak
2017-01-16 14:18   ` Bill O'Donnell
2017-01-06 11:42 ` [RFC PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
2017-01-09 19:43 ` Eric Sandeen
2017-01-10  9:47   ` Jan Tulak
2017-01-12 15:46 ` Bill O'Donnell
2017-01-16 20:14 ` Bill O'Donnell

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.