All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/22] mkfs.xfs: Make stronger conflict checks
@ 2017-03-15 15:59 Jan Tulak
  2017-03-15 15:59 ` [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum Jan Tulak
                   ` (23 more replies)
  0 siblings, 24 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 15:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak, Luis R . Rodriguez, Eric Sandeen, Dave Chinner

Hi guys,

my RFC didn't got much of attention, so I'm sending it as a merge request.
Hopefully, this will get more eyes on it. ;-) I fixed the few small issues Bill
noticed (Thanks, Bill!) and xfstests runs ok. There is one case where test
xfs/191-input-validation was accepting a behaviour forbidden in man page, so
I'm sending also a xfstests patch:

Specifically, a standalone "-l size=4096b" should fail, because:
              To  specify any options on the command line in units of filesys‐
              tem blocks, this option must be  specified  first  so  that  the
              filesystem block size is applied consistently to all options.

So without the xfstest patch, expect this one test to fail.

The following text is copy&paste from RFC. I only removed/edited one question
I had at the time and was solved in the RFC thread. After that is an addendum
with regards to Luis' config file support.

---

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 a question, but it can be answered with "let's keep it as it
is."

The 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".

---

Config file patches addendum:

(Thread: http://www.spinics.net/lists/linux-xfs/msg04703.html)

I read through the changes, but decided to don't take anything from it.
I think it is time to do something and adding further changes would just
push it down again. Nevertheless, the other patchset contains some changes
(like splitting the main opts loop) that I wanted to add in some later patch
too.

I suggest that we first merge these patches I'm sending, and once it solves
some of the issues Luis hit too, we can look again on the config file thing
and even if the main idea fell out of favor for some reason, there are still
other useful changes.

---

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

PS: I'm traveling at Vault next week, so if you are there too, we can open it
there.

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 | 2961 +++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 1873 insertions(+), 1088 deletions(-)

-- 
2.11.0


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

* [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
@ 2017-03-15 15:59 ` Jan Tulak
  2017-03-16 22:59   ` Eric Sandeen
  2017-03-15 15:59 ` [PATCH 02/22] mkfs: merge tables for opts parsing into one table Jan Tulak
                   ` (22 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 15:59 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 affa4052..b3bc218a 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.11.0


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

* [PATCH 02/22] mkfs: merge tables for opts parsing into one table
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
  2017-03-15 15:59 ` [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum Jan Tulak
@ 2017-03-15 15:59 ` Jan Tulak
  2017-03-15 15:59 ` [PATCH 03/22] mkfs: extend opt_params with a value field Jan Tulak
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 15:59 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 b3bc218a..372c620d 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.11.0


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

* [PATCH 03/22] mkfs: extend opt_params with a value field
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
  2017-03-15 15:59 ` [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum Jan Tulak
  2017-03-15 15:59 ` [PATCH 02/22] mkfs: merge tables for opts parsing into one table Jan Tulak
@ 2017-03-15 15:59 ` Jan Tulak
  2017-03-15 15:59 ` [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing Jan Tulak
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 15:59 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 372c620d..5e15fee2 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.11.0


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

* [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (2 preceding siblings ...)
  2017-03-15 15:59 ` [PATCH 03/22] mkfs: extend opt_params with a value field Jan Tulak
@ 2017-03-15 15:59 ` Jan Tulak
  2017-03-16 17:02   ` Eric Sandeen
  2017-03-15 16:00 ` [PATCH 05/22] mkfs: add a check for conflicting values Jan Tulak
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 15:59 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 5e15fee2..c9861409 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.11.0


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

* [PATCH 05/22] mkfs: add a check for conflicting values
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (3 preceding siblings ...)
  2017-03-15 15:59 ` [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-25  0:36   ` Eric Sandeen
  2017-03-15 16:00 ` [PATCH 06/22] mkfs: add cross-section conflict checks Jan Tulak
                   ` (18 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 c9861409..7e0a4159 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.11.0


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

* [PATCH 06/22] mkfs: add cross-section conflict checks
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (4 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 05/22] mkfs: add a check for conflicting values Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-25  0:31   ` Eric Sandeen
  2017-03-15 16:00 ` [PATCH 07/22] mkfs: Move opts related #define to one place Jan Tulak
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 7e0a4159..0877c196 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.11.0


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

* [PATCH 07/22] mkfs: Move opts related #define to one place
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (5 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 06/22] mkfs: add cross-section conflict checks Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-16 23:25   ` Luis R. Rodriguez
  2017-03-15 16:00 ` [PATCH 08/22] mkfs: move conflicts into the table Jan Tulak
                   ` (16 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 0877c196..4ba6df05 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.11.0


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

* [PATCH 08/22] mkfs: move conflicts into the table
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (6 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 07/22] mkfs: Move opts related #define to one place Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-16 18:04   ` Eric Sandeen
                     ` (2 more replies)
  2017-03-15 16:00 ` [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure Jan Tulak
                   ` (15 subsequent siblings)
  23 siblings, 3 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 4ba6df05..c100fef9 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.11.0


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

* [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (7 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 08/22] mkfs: move conflicts into the table Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 10/22] mkfs: change when to mark an option as seen Jan Tulak
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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>

---
v2: A call rename was fixed from check_subopt to check_subopt_conflicts
---
 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 c100fef9..c3ab9221 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_conflicts(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.11.0


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

* [PATCH 10/22] mkfs: change when to mark an option as seen
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (8 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 09/22] mkfs: change conflict checks to utilize the new conflict structure Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 11/22] mkfs: add test_default_value into conflict struct Jan Tulak
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 c3ab9221..db82a528 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_conflicts(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.11.0


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

* [PATCH 11/22] mkfs: add test_default_value into conflict struct
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (9 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 10/22] mkfs: change when to mark an option as seen Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-25  0:09   ` Eric Sandeen
  2017-03-15 16:00 ` [PATCH 12/22] mkfs: expand conflicts declarations to named declaration Jan Tulak
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 db82a528..19024847 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.11.0


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

* [PATCH 12/22] mkfs: expand conflicts declarations to named declaration
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (10 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 11/22] mkfs: add test_default_value into conflict struct Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 13/22] mkfs: remove zeroed items from conflicts declaration Jan Tulak
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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>

---
v2: whitespace fixes
---
 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 19024847..3ba71cdc 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.11.0


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

* [PATCH 13/22] mkfs: remove zeroed items from conflicts declaration
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (11 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 12/22] mkfs: expand conflicts declarations to named declaration Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 14/22] mkfs: rename defaultval to flagval in opts Jan Tulak
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 3ba71cdc..a604c801 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.11.0


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

* [PATCH 14/22] mkfs: rename defaultval to flagval in opts
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (12 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 13/22] mkfs: remove zeroed items from conflicts declaration Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-16 23:20   ` Luis R. Rodriguez
  2017-03-15 16:00 ` [PATCH 15/22] mkfs: replace SUBOPT_NEEDS_VAL for a flag Jan Tulak
                   ` (9 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 a604c801..273cdbc4 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.11.0


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

* [PATCH 15/22] mkfs: replace SUBOPT_NEEDS_VAL for a flag
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (13 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 14/22] mkfs: rename defaultval to flagval in opts Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 16/22] mkfs: Change all value fields in opt structures into unions Jan Tulak
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 273cdbc4..55b8c674 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.11.0


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

* [PATCH 16/22] mkfs: Change all value fields in opt structures into unions
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (14 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 15/22] mkfs: replace SUBOPT_NEEDS_VAL for a flag Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values Jan Tulak
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 UTC (permalink / raw)
  To: linux-xfs; +Cc: Jan Tulak

Trying to cover all possible values in a single date 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>

---
EDIT:
  * remove a fixme comment that isn't needed
---
 mkfs/xfs_mkfs.c | 811 +++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 503 insertions(+), 308 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 55b8c674..3698fc52 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,
 			},
 		},
 	},
@@ -580,9 +835,10 @@ struct opt_params {
 					  .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 +848,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 +892,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 +906,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 +925,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 +949,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 +984,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 +996,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 +1041,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 +1079,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 +1115,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 +1128,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 +1143,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 +1158,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 +1182,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 +1939,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 +1954,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 +1990,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 +2016,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 +2072,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 +2259,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 +2282,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 +2330,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 +2337,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 +2366,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 +2421,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 +2447,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 +2470,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 +2499,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 +2535,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 +2542,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 +2555,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 +2589,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 +2630,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 +2643,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.11.0


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

* [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (15 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 16/22] mkfs: Change all value fields in opt structures into unions Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-17  0:48   ` Eric Sandeen
  2017-03-15 16:00 ` [PATCH 18/22] mkfs: prevent sector/blocksize to be specified as a number of blocks Jan Tulak
                   ` (6 subsequent siblings)
  23 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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>

---
EDIT:
  * Expanded the TODO comment about getnum
---
 mkfs/xfs_mkfs.c | 775 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 422 insertions(+), 353 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 3698fc52..bd2d81a3 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,
 			},
@@ -852,6 +852,7 @@ struct opt_params {
 			  .maxval.i = 1,
 			  .flagval.i = 1,
 			  .type = INT,
+			  .value.i = 1,
 			},
 			{ .index = L_SIZE,
 			  .conflicts = { {LAST_CONFLICT} },
@@ -1344,7 +1345,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
@@ -1415,16 +1416,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);
 	}
 }
@@ -2002,6 +2003,14 @@ 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.
+ *
+ * However, I can't find any good solution for this and at this moment, it
+ * is a rather theoretical issue (real-world limits will kicks in long before
+ * it gets there). So, I'm going to keep this comment here for now, until
+ * someone gets an idea what to do with it.
+ */
 static long long
 getnum(
 	const char		*str,
@@ -2060,7 +2069,7 @@ getnum(
 	 * number.
 	 */
 	if (sp->convert)
-		c = cvtnum(blocksize, sectorsize, str);
+		c = cvtnum(*blocksize, sectorsize, str);
 	else {
 		char		*str_end;
 
@@ -2105,15 +2114,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;
@@ -2122,51 +2131,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;
@@ -2177,10 +2186,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;
@@ -2215,24 +2224,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));
@@ -2255,15 +2291,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:
@@ -2279,12 +2315,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;
@@ -2297,25 +2333,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:
@@ -2337,6 +2373,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],
@@ -2368,25 +2405,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:
@@ -2418,7 +2455,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;
@@ -2427,16 +2464,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;
@@ -2446,7 +2483,7 @@ main(
 								L_NAME);
 					xi.logname = logfile;
 					ldflag = 1;
-					loginternal = 0;
+					*loginternal = 0;
 					break;
 				case L_VERSION:
 					sb_feat.log_version =
@@ -2455,20 +2492,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:
@@ -2509,6 +2546,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(
@@ -2531,16 +2569,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:
@@ -2587,7 +2625,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:
@@ -2600,11 +2638,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:
@@ -2626,9 +2664,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:
@@ -2638,10 +2676,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:
@@ -2664,6 +2702,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);
 
 	/*
@@ -2672,14 +2740,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);
@@ -2700,8 +2768,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;
 	}
 
 	/*
@@ -2711,14 +2779,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)
@@ -2743,10 +2811,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);
@@ -2757,20 +2825,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) {
@@ -2778,12 +2846,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;
 	}
 
@@ -2794,7 +2862,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);
@@ -2818,89 +2886,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,
@@ -2910,23 +2978,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);
@@ -2934,34 +3002,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;
 
@@ -2989,7 +3057,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 */
@@ -3003,10 +3071,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");
@@ -3021,15 +3089,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();
 	}
@@ -3040,11 +3108,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();
@@ -3056,147 +3124,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) {
@@ -3206,30 +3274,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);
 		}
 	}
@@ -3238,82 +3306,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 {
 			/*
@@ -3322,34 +3391,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;
 
@@ -3357,22 +3426,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);
@@ -3380,35 +3449,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(_(
@@ -3421,19 +3490,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);
@@ -3442,7 +3511,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;
@@ -3452,52 +3521,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);
@@ -3527,8 +3596,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);
@@ -3556,7 +3625,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) {
@@ -3570,7 +3639,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);
@@ -3595,12 +3664,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);
@@ -3622,15 +3691,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)
@@ -3669,7 +3738,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);
@@ -3694,7 +3763,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);
@@ -3704,7 +3773,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
@@ -3734,7 +3803,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;
@@ -3749,7 +3818,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);
@@ -3759,7 +3828,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) -
@@ -3779,7 +3848,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;
@@ -3797,7 +3866,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);
 
@@ -3812,7 +3881,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);
@@ -3830,7 +3899,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);
@@ -3849,7 +3918,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);
@@ -3904,7 +3973,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(
@@ -3926,7 +3995,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);
 
 	/*
@@ -3935,14 +4004,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.11.0


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

* [PATCH 18/22] mkfs: prevent sector/blocksize to be specified as a number of blocks
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (16 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 19/22] mkfs: subopt flags should be saved as bool Jan Tulak
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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>

--
Change:
  * sectsize can be set in blocks and vice versa now
---
 mkfs/xfs_mkfs.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

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


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

* [PATCH 19/22] mkfs: subopt flags should be saved as bool
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (17 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 18/22] mkfs: prevent sector/blocksize to be specified as a number of blocks Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 20/22] mkfs: move uuid empty string test to getstr() Jan Tulak
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 767aeeea..914af9d3 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,
 			},
 		},
 	},
@@ -936,10 +936,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,
@@ -1069,10 +1069,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,
@@ -1089,10 +1089,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} },
 			},
 		},
@@ -2202,7 +2202,7 @@ main(
 	xfs_extlen_t		nbmblocks;
 	int			nlflag;
 	int			*nodsflag;
-	int			*norsflag;
+	bool			*norsflag;
 	xfs_alloc_rec_t		*nrec;
 	int			nsflag;
 	int			nvflag;
@@ -2265,7 +2265,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;
@@ -2400,7 +2400,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],
@@ -2736,15 +2736,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.11.0


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

* [PATCH 20/22] mkfs: move uuid empty string test to getstr()
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (18 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 19/22] mkfs: subopt flags should be saved as bool Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 21/22] mkfs: remove duplicit checks Jan Tulak
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 914af9d3..865bd389 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2569,11 +2569,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.11.0


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

* [PATCH 21/22] mkfs: remove duplicit checks
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (19 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 20/22] mkfs: move uuid empty string test to getstr() Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-15 16:00 ` [PATCH 22/22] mkfs: prevent multiple specifications of a single option Jan Tulak
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 865bd389..dfb5e300 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2769,26 +2769,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.11.0


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

* [PATCH 22/22] mkfs: prevent multiple specifications of a single option
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (20 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 21/22] mkfs: remove duplicit checks Jan Tulak
@ 2017-03-15 16:00 ` Jan Tulak
  2017-03-16 17:19 ` [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Eric Sandeen
  2017-03-16 23:38 ` Luis R. Rodriguez
  23 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-15 16:00 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 dfb5e300..a472b92c 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] = {
 	{
@@ -876,6 +881,7 @@ struct opt_params {
 			  .maxval.i = 2,
 			  .needs_val = true,
 			  .type = INT,
+			  .can_respec = true,
 			},
 			{ .index = L_SUNIT,
 			  .conflicts = { {.opt = OPT_L,
@@ -1008,6 +1014,7 @@ struct opt_params {
 			  .maxval.i = 2,
 			  .needs_val = true,
 			  .type = INT,
+			  .can_respec = true,
 			},
 			{ .index = N_FTYPE,
 			  .conflicts = {  {.opt = OPT_M,
@@ -2020,6 +2027,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)
@@ -2132,6 +2155,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.11.0


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

* Re: [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing
  2017-03-15 15:59 ` [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing Jan Tulak
@ 2017-03-16 17:02   ` Eric Sandeen
  2017-03-16 17:21     ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-16 17:02 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 3/15/17 8:59 AM, 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>
> ---
>  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 5e15fee2..c9861409 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.

You also still need to mark each string initializer you added in the array
in patch 08 with N_(" ... ") or gettext won't know about it. 
(I think that's the right way to go about it)

-Eric

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

* Re: [PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (21 preceding siblings ...)
  2017-03-15 16:00 ` [PATCH 22/22] mkfs: prevent multiple specifications of a single option Jan Tulak
@ 2017-03-16 17:19 ` Eric Sandeen
  2017-03-16 17:23   ` Jan Tulak
  2017-03-16 23:38 ` Luis R. Rodriguez
  23 siblings, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-16 17:19 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs; +Cc: Luis R . Rodriguez, Dave Chinner

On 3/15/17 8:59 AM, Jan Tulak wrote:
> Hi guys,
> 
> my RFC didn't got much of attention, so I'm sending it as a merge request.
> Hopefully, this will get more eyes on it. ;-) I fixed the few small issues Bill
> noticed (Thanks, Bill!) and xfstests runs ok. There is one case where test
> xfs/191-input-validation was accepting a behaviour forbidden in man page, so
> I'm sending also a xfstests patch:
> 
> Specifically, a standalone "-l size=4096b" should fail, because:
>               To  specify any options on the command line in units of filesys‐
>               tem blocks, this option must be  specified  first  so  that  the
>               filesystem block size is applied consistently to all options.
> 
> So without the xfstest patch, expect this one test to fail.
> 
> The following text is copy&paste from RFC. I only removed/edited one question
> I had at the time and was solved in the RFC thread. After that is an addendum
> with regards to Luis' config file support.

Hi Jan -

I'm finally trying to take some time and give this serious review.

At a top level, though, please fix up coding style issues which are
introduced throughout the series.

As Dave has said before, checkpatch.pl in the kernel tree isn't perfect,
and we need to apply understanding and reason to its results, but it's
a place to start looking - for a sampling,

WARNING: please, no space before tabs
#29: FILE: mkfs/xfs_mkfs.c:59:
+#define D_SUNIT ^I4$

ERROR: space required before the open brace '{'
#117: FILE: mkfs/xfs_mkfs.c:147:
+	}	switch(a_type){

(also switch shouldn't be on the same line as the closing brace)

ERROR: space required before the open brace '{'
#119: FILE: mkfs/xfs_mkfs.c:149:
+		switch(b_type){

ERROR: space prohibited before open square bracket '['
#417: FILE: mkfs/xfs_mkfs.c:458:
+		}		conflicts [MAX_CONFLICTS];

WARNING: line over 80 characters
#992: FILE: mkfs/xfs_mkfs.c:779:
+		"V2 attribute format always enabled on CRC enabled filesytems."},

(usually we tab that sort of thing back to fit if possible)

WARNING: Avoid unnecessary line continuations
#1006: FILE: mkfs/xfs_mkfs.c:793:
+					  .message = \

ERROR: space prohibited after that open parenthesis '('
#1976: FILE: mkfs/xfs_mkfs.c:1963:
+		if ( (opts[conflict_opt.opt].subopt_params[conflict_opt.subopt].seen ||

(and it may be an > 80-char line; again judgement here, this
might be hard to make nice)

ERROR: space required before the open brace '{'
#2042: FILE: mkfs/xfs_mkfs.c:2030:
+	if (sp->seen){

ERROR: else should follow close brace '}'
#2097: FILE: mkfs/xfs_mkfs.c:2082:
+	}
+	else if (opts->index == OPT_S ||

ERROR: space required before the open parenthesis '('
#4104: FILE: mkfs/xfs_mkfs.c:4158:
+	if(conflict->message) {


and many, many more.  

So use your good judgement, but please fix as many of these as you can;
it's important to have a consistent coding style throughout the xfsprogs
codebase.

Thanks,
-Eric

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

* Re: [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing
  2017-03-16 17:02   ` Eric Sandeen
@ 2017-03-16 17:21     ` Jan Tulak
  2017-03-16 17:41       ` Eric Sandeen
  0 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-16 17:21 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Thu, Mar 16, 2017 at 6:02 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 3/15/17 8:59 AM, 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>
>> ---
>>  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 5e15fee2..c9861409 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.
>
> You also still need to mark each string initializer you added in the array
> in patch 08 with N_(" ... ") or gettext won't know about it.
> (I think that's the right way to go about it)
>
> -Eric

See patch 06, the last chunk. It adds printing of the error with
"_(conflict->message)".
So if C gettext is a function evaluated on the run and not a macro
evaluated on the compile time, then it should be ok. (And everywhere I
looked, I saw it mentioned as a function... Although I admit I didn't
tested it.)

Jan




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

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

* Re: [PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2017-03-16 17:19 ` [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Eric Sandeen
@ 2017-03-16 17:23   ` Jan Tulak
  0 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-16 17:23 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs, Luis R . Rodriguez, Dave Chinner

On Thu, Mar 16, 2017 at 6:19 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 3/15/17 8:59 AM, Jan Tulak wrote:
>> Hi guys,
>>
>> my RFC didn't got much of attention, so I'm sending it as a merge request.
>> Hopefully, this will get more eyes on it. ;-) I fixed the few small issues Bill
>> noticed (Thanks, Bill!) and xfstests runs ok. There is one case where test
>> xfs/191-input-validation was accepting a behaviour forbidden in man page, so
>> I'm sending also a xfstests patch:
>>
>> Specifically, a standalone "-l size=4096b" should fail, because:
>>               To  specify any options on the command line in units of filesys‐
>>               tem blocks, this option must be  specified  first  so  that  the
>>               filesystem block size is applied consistently to all options.
>>
>> So without the xfstest patch, expect this one test to fail.
>>
>> The following text is copy&paste from RFC. I only removed/edited one question
>> I had at the time and was solved in the RFC thread. After that is an addendum
>> with regards to Luis' config file support.
>
> Hi Jan -
>
> I'm finally trying to take some time and give this serious review.
>
> At a top level, though, please fix up coding style issues which are
> introduced throughout the series.
>
> As Dave has said before, checkpatch.pl in the kernel tree isn't perfect,
> and we need to apply understanding and reason to its results, but it's
> a place to start looking - for a sampling,
>
> [snip]
>
> So use your good judgement, but please fix as many of these as you can;
> it's important to have a consistent coding style throughout the xfsprogs
> codebase.
>

OK, thanks. I will run it and see what I can do. And thanks for
looking on this. :-)

Cheers,
Jan


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

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

* Re: [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing
  2017-03-16 17:21     ` Jan Tulak
@ 2017-03-16 17:41       ` Eric Sandeen
  2017-03-16 17:47         ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-16 17:41 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On 3/16/17 10:21 AM, Jan Tulak wrote:
> On Thu, Mar 16, 2017 at 6:02 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
>> On 3/15/17 8:59 AM, 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>
>>> ---
>>>  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 5e15fee2..c9861409 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.
>>
>> You also still need to mark each string initializer you added in the array
>> in patch 08 with N_(" ... ") or gettext won't know about it.
>> (I think that's the right way to go about it)
>>
>> -Eric
> 
> See patch 06, the last chunk. It adds printing of the error with
> "_(conflict->message)".

yes, but nothing tags the actual conflict strings as needing translation.

https://www.gnu.org/software/gettext/manual/html_node/Special-cases.html#Special-cases

might help.

note that we use macros - N_() is gettext_noop(), and _() is gettext()

> So if C gettext is a function evaluated on the run and not a macro
> evaluated on the compile time, then it should be ok. (And everywhere I
> looked, I saw it mentioned as a function... Although I admit I didn't
> tested it.)

Well, give it a test.  If it works, fine, but I do not see these strings
ending up in the .pot file so I'm skeptical.

-Eric

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

* Re: [PATCH 04/22] mkfs: change conflicts array into a table capable of cross-option addressing
  2017-03-16 17:41       ` Eric Sandeen
@ 2017-03-16 17:47         ` Jan Tulak
  0 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-16 17:47 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Thu, Mar 16, 2017 at 6:41 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 3/16/17 10:21 AM, Jan Tulak wrote:
>> On Thu, Mar 16, 2017 at 6:02 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
>>> On 3/15/17 8:59 AM, 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>
>>>> ---
>>>>  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 5e15fee2..c9861409 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.
>>>
>>> You also still need to mark each string initializer you added in the array
>>> in patch 08 with N_(" ... ") or gettext won't know about it.
>>> (I think that's the right way to go about it)
>>>
>>> -Eric
>>
>> See patch 06, the last chunk. It adds printing of the error with
>> "_(conflict->message)".
>
> yes, but nothing tags the actual conflict strings as needing translation.
>
> https://www.gnu.org/software/gettext/manual/html_node/Special-cases.html#Special-cases
>
> might help.
>
> note that we use macros - N_() is gettext_noop(), and _() is gettext()
>
>> So if C gettext is a function evaluated on the run and not a macro
>> evaluated on the compile time, then it should be ok. (And everywhere I
>> looked, I saw it mentioned as a function... Although I admit I didn't
>> tested it.)
>
> Well, give it a test.  If it works, fine, but I do not see these strings
> ending up in the .pot file so I'm skeptical.
>
> -Eric

Ah, it makes sense this way - the translation works, but the new
strings are not marked without the _() or N_().

Jan

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

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

* Re: [PATCH 08/22] mkfs: move conflicts into the table
  2017-03-15 16:00 ` [PATCH 08/22] mkfs: move conflicts into the table Jan Tulak
@ 2017-03-16 18:04   ` Eric Sandeen
  2017-03-16 18:39   ` Eric Sandeen
  2017-03-24 23:53   ` Eric Sandeen
  2 siblings, 0 replies; 56+ messages in thread
From: Eric Sandeen @ 2017-03-16 18:04 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs



On 3/15/17 9:00 AM, Jan Tulak wrote:
> @@ -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,

Ah, and I know this is just a copy from elsewhere, but this string
has a typo; it should be "Lazy superblock counters always enabled ..."
so this might be a decent time to fix it.

-Eric

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

* Re: [PATCH 08/22] mkfs: move conflicts into the table
  2017-03-15 16:00 ` [PATCH 08/22] mkfs: move conflicts into the table Jan Tulak
  2017-03-16 18:04   ` Eric Sandeen
@ 2017-03-16 18:39   ` Eric Sandeen
  2017-03-16 18:45     ` Darrick J. Wong
  2017-03-24 23:53   ` Eric Sandeen
  2 siblings, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-16 18:39 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 3/15/17 9:00 AM, Jan Tulak wrote:
> @@ -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,

These two should be:

"rmapbt not supported with realtime devices."

I think.

(sorry for the scattershot review, I'll try to get organized going forward) ;)

-Eric

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

* Re: [PATCH 08/22] mkfs: move conflicts into the table
  2017-03-16 18:39   ` Eric Sandeen
@ 2017-03-16 18:45     ` Darrick J. Wong
  0 siblings, 0 replies; 56+ messages in thread
From: Darrick J. Wong @ 2017-03-16 18:45 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Jan Tulak, linux-xfs

On Thu, Mar 16, 2017 at 11:39:11AM -0700, Eric Sandeen wrote:
> On 3/15/17 9:00 AM, Jan Tulak wrote:
> > @@ -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,
> 
> These two should be:
> 
> "rmapbt not supported with realtime devices."
> 
> I think.

Yes, rmapbt isn't supported with realtime devices yet.

FWIW we ought to lock out realtime+reflink for the time being too.

At one point I had a prototype for reflink on the rtdev but it bitrotted
and died when the iomap rework came along.  I'll get back to it some
day, but first I need to reduce the number of out of tree patches in
djwong-wtf. :)

--D

> 
> (sorry for the scattershot review, I'll try to get organized going forward) ;)
> 
> -Eric
> --
> 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] 56+ messages in thread

* Re: [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum
  2017-03-15 15:59 ` [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum Jan Tulak
@ 2017-03-16 22:59   ` Eric Sandeen
  2017-04-05 13:00     ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-16 22:59 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 3/15/17 8:59 AM, 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).

The only downside I see to this is that we used to echo back the same
form that was specified, i.e. -

# mkfs.xfs -f -d size=4e fsfile
size 4e specified for data subvolume is too large, maximum is 262144 blocks
# mkfs.xfs -f -d size=4611686018427387904 fsfile
size 4611686018427387904 specified for data subvolume is too large, maximum is 262144 blocks
# mkfs.xfs -f -d size=1125899906842624b fsfile
size 1125899906842624b specified for data subvolume is too large, maximum is 262144 blocks

now we always get back the raw byte value:

# mkfs/mkfs.xfs -f -d size=4e fsfile
size 4611686018427387904 specified for data subvolume is too large, maximum is 262144 blocks

Anything that fails the getnum() checks echo back the original
form on the cmdline; this case is different because getnum() passes,
but by the time we do value checking all we have is the bytes.  Is
that intentional/desirable?

So it's a change, not necessarily incorrect or unacceptable, but
I wanted to highlight it and check.  It wouldn't be too hard to
convert it right away, but keep the string around for error printing
purposes, I suppose.

-Eric

> 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 affa4052..b3bc218a 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));
>  
> 

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

* Re: [PATCH 14/22] mkfs: rename defaultval to flagval in opts
  2017-03-15 16:00 ` [PATCH 14/22] mkfs: rename defaultval to flagval in opts Jan Tulak
@ 2017-03-16 23:20   ` Luis R. Rodriguez
  2017-03-17 12:06     ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Luis R. Rodriguez @ 2017-03-16 23:20 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Mar 15, 2017 at 05:00:09PM +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>
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -189,7 +189,7 @@ unsigned int		sectorsize;
> @@ -223,7 +223,7 @@ struct opt_params {
>  		}		conflicts [MAX_CONFLICTS];
>  		long long	minval;
>  		long long	maxval;
> -		long long	defaultval;
> +		long long	flagval;

David suggested that in the future the config value(mkfs.xfs.conf) will override
the defaultval, in this case since you are renaming this, just want to be sure
the new name we choose can fit its later use also with the config. Perhaps
userval ?

  Luis

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

* Re: [PATCH 07/22] mkfs: Move opts related #define to one place
  2017-03-15 16:00 ` [PATCH 07/22] mkfs: Move opts related #define to one place Jan Tulak
@ 2017-03-16 23:25   ` Luis R. Rodriguez
  2017-03-17 12:11     ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Luis R. Rodriguez @ 2017-03-16 23:25 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Wed, Mar 15, 2017 at 05:00:02PM +0100, Jan Tulak wrote:
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 0877c196..4ba6df05 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

How about instead using enums, this way if we use kdoc format (hey the new
kernel doc format is producing nicer docs) we can then document what the
hell each of these things are nicely. Also, when enums are used in switches
the compiler will nag at you if you happened to have missed a case, unless you
have a default.

We could have an enum for the opts and then one for each subopt group.

  Luis

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

* Re: [PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2017-03-15 15:59 [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Jan Tulak
                   ` (22 preceding siblings ...)
  2017-03-16 17:19 ` [PATCH 00/22] mkfs.xfs: Make stronger conflict checks Eric Sandeen
@ 2017-03-16 23:38 ` Luis R. Rodriguez
  2017-03-16 23:47   ` Eric Sandeen
  2017-03-17 12:20   ` Jan Tulak
  23 siblings, 2 replies; 56+ messages in thread
From: Luis R. Rodriguez @ 2017-03-16 23:38 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs, Luis R . Rodriguez, Eric Sandeen, Dave Chinner

On Wed, Mar 15, 2017 at 04:59:55PM +0100, Jan Tulak wrote:
> 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.

This series is pretty large. There are quite a bit of patches which just rename
something, or just shove code from one place to another. Can you group up
non-functional changes together first, and send a small series of simple stuff
with no functional changes first?

That should reduce the size of the functional patch set, and make it clearer
which patches require much careful eyeballing. It should also put out of your
queue tons of changes which are trivial and can go in rather sooner.

> Config file patches addendum:
> 
> (Thread: http://www.spinics.net/lists/linux-xfs/msg04703.html)
> 
> I read through the changes, but decided to don't take anything from it.

The last 2 patches of my config series are really the functional change there,
the rest is fluff to account for the insanity we have now.

> I think it is time to do something and adding further changes would just
> push it down again. Nevertheless, the other patchset contains some changes
> (like splitting the main opts loop) that I wanted to add in some later patch
> too.

OK.

> I suggest that we first merge these patches I'm sending, and once it solves
> some of the issues Luis hit too, we can look again on the config file thing
> and even if the main idea fell out of favor for some reason, there are still
> other useful changes.

Sure, I'm fine with this, do you have a git tree ? Once you rev and post new
series if you can provide a git URL that'd be great as then I can just work
off of that.

> PS: I'm traveling at Vault next week, so if you are there too, we can open it
> there.

I'm up for beers there.

  Luis

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

* Re: [PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2017-03-16 23:38 ` Luis R. Rodriguez
@ 2017-03-16 23:47   ` Eric Sandeen
  2017-03-17 12:57     ` Jan Tulak
  2017-03-17 12:20   ` Jan Tulak
  1 sibling, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-16 23:47 UTC (permalink / raw)
  To: Luis R. Rodriguez, Jan Tulak; +Cc: linux-xfs, Dave Chinner

On 3/16/17 4:38 PM, Luis R. Rodriguez wrote:
> On Wed, Mar 15, 2017 at 04:59:55PM +0100, Jan Tulak wrote:
>> 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.
> 
> This series is pretty large. There are quite a bit of patches which just rename
> something, or just shove code from one place to another. Can you group up
> non-functional changes together first, and send a small series of simple stuff
> with no functional changes first?

I have to say I'm still struggling with it as well.  Apologies for the 
random detail nitpicking, I'm trying to look through it all to get a better
big picture.

And as far as "no-op changes" it's imperative to make them really no-op.
Make sure that other random changes aren't stuck into the middle of anything...

I'll probably keep flinging comments on various patches as I read them,
some of it may be helpful in terms of just learning some best practice
for patches, but TBH I'm still trying to wrap my head around the big change
and purpose.

-Eric

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

* Re: [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values
  2017-03-15 16:00 ` [PATCH 17/22] mkfs: use old variables as pointers to the new opts struct values Jan Tulak
@ 2017-03-17  0:48   ` Eric Sandeen
  0 siblings, 0 replies; 56+ messages in thread
From: Eric Sandeen @ 2017-03-17  0:48 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 3/15/17 9:00 AM, 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.

This seems like it should be very mechanical, but there are a few
unexpected bits, notes below inline.

> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> 
> ---
> EDIT:
>   * Expanded the TODO comment about getnum
> ---
>  mkfs/xfs_mkfs.c | 775 ++++++++++++++++++++++++++++++--------------------------
>  1 file changed, 422 insertions(+), 353 deletions(-)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 3698fc52..bd2d81a3 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;

Is there a a reason sectorsize is untouched?  I expected an 

unsigned int	*sectorsize;

sectorsize = &opts[OPT_S].subopt_params[S_SIZE].value.u;

(oh - reading further down, I see we have 6 ways to specify
sectorsize.  joy.)

>  #define MAX_OPTS	16
> @@ -557,7 +557,7 @@ struct opt_params {
>  					 },
>  					 {LAST_CONFLICT} },
>  			  .minval.i = 0,
> -			  .maxval.i = UINT_MAX,
> +			  .maxval.i = INT_MAX,

Is this related to this patch?  It seems unrelated.

>  			  .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,
>  			},
> @@ -852,6 +852,7 @@ struct opt_params {
>  			  .maxval.i = 1,
>  			  .flagval.i = 1,
>  			  .type = INT,
> +			  .value.i = 1,

Hmm - No other value is set in the intializers AFAICT.
It just seems odd; we had "loginternal = 1" before, but I'm surprised
that this is the only option with a default in the structure.  Is
that expected?  Hm - Ok, I guess this was the only non-zero global...

>  			},
>  			{ .index = L_SIZE,
>  			  .conflicts = { {LAST_CONFLICT} },
> @@ -1344,7 +1345,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
> @@ -1415,16 +1416,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);
>  	}
>  }
> @@ -2002,6 +2003,14 @@ check_all_opts(struct opt_params *opts)
>  	}
>  }
>  
> +/* TODO we might loose some numbers here, if they are unsigned and bigger than

s/loose/lose/ - pet peeve ;)

> + * long long max value.
> + *
> + * However, I can't find any good solution for this and at this moment, it
> + * is a rather theoretical issue (real-world limits will kicks in long before
> + * it gets there). So, I'm going to keep this comment here for now, until
> + * someone gets an idea what to do with it.
> + */

this also has nothing to do with this change, right?  :)

>  static long long
>  getnum(
>  	const char		*str,
> @@ -2060,7 +2069,7 @@ getnum(
>  	 * number.
>  	 */
>  	if (sp->convert)
> -		c = cvtnum(blocksize, sectorsize, str);
> +		c = cvtnum(*blocksize, sectorsize, str);
>  	else {
>  		char		*str_end;
>  
> @@ -2105,15 +2114,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;
> @@ -2122,51 +2131,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;
> @@ -2177,10 +2186,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;
> @@ -2215,24 +2224,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;

Hm ok, there was that magical "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));
> @@ -2255,15 +2291,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:
> @@ -2279,12 +2315,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;
> @@ -2297,25 +2333,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:
> @@ -2337,6 +2373,7 @@ main(
>  					if (c)
>  						fsx.fsx_xflags |=
>  							XFS_DIFLAG_RTINHERIT;
> +					opts[OPT_D].subopt_params[D_RTINHERIT].value.u = c;

what's this?  (oof... is "-d rtinherit" documented anywhere?  Nope, not since it
was added in 2005, sigh.)

This was removed in "mkfs: Change all value fields in opt structures into unions"
but re-added here, why?

But even if this needs assignment here, an aside: isn't RTINHERIT actually a boolean?

>  					break;
>  				case D_PROJINHERIT:
>  					fsx.fsx_projid = getnum(value, &opts[OPT_D],

Not re-added here... above might be an error, then?

> @@ -2368,25 +2405,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:
> @@ -2418,7 +2455,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;
> @@ -2427,16 +2464,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;
> @@ -2446,7 +2483,7 @@ main(
>  								L_NAME);
>  					xi.logname = logfile;
>  					ldflag = 1;
> -					loginternal = 0;
> +					*loginternal = 0;
>  					break;
>  				case L_VERSION:
>  					sb_feat.log_version =
> @@ -2455,20 +2492,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:
> @@ -2509,6 +2546,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;

another unexpected addition?  Does this ever even get used?

>  					break;
>  				case M_RMAPBT:
>  					sb_feat.rmapbt = getnum(
> @@ -2531,16 +2569,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:
> @@ -2587,7 +2625,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:
> @@ -2600,11 +2638,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:
> @@ -2626,9 +2664,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:
> @@ -2638,10 +2676,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:
> @@ -2664,6 +2702,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;

= sectorlog.

> +	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;
> +
>  		

well, I guess this explains why you've left sectorsize as a global var, apparently
we have 6 ways to specify the sector size:  :(

-s log=
-s sectlog=
-s size=
-s sectsize=
-d sectlog=
-d sectsize=

Ow my brain.  We should start deprecating the ones that aren't in the manpage.

Anyway, I digress.

I won't keep going through this one for now, but 2 thoughts:

1) keep changes like this mechanical, no extraneous changes
2) For options with multiple ways to specify, can they map down onto
   just one of the giant args structure instead of carrying it around
   6(!) different ways?

-Eric
 
>  	/*
> @@ -2672,14 +2740,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);
> @@ -2700,8 +2768,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;
>  	}
>  
>  	/*
> @@ -2711,14 +2779,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)
> @@ -2743,10 +2811,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);
> @@ -2757,20 +2825,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) {
> @@ -2778,12 +2846,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;
>  	}
>  
> @@ -2794,7 +2862,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);
> @@ -2818,89 +2886,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,
> @@ -2910,23 +2978,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);
> @@ -2934,34 +3002,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;
>  
> @@ -2989,7 +3057,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 */
> @@ -3003,10 +3071,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");
> @@ -3021,15 +3089,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();
>  	}
> @@ -3040,11 +3108,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();
> @@ -3056,147 +3124,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) {
> @@ -3206,30 +3274,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);
>  		}
>  	}
> @@ -3238,82 +3306,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 {
>  			/*
> @@ -3322,34 +3391,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;
>  
> @@ -3357,22 +3426,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);
> @@ -3380,35 +3449,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(_(
> @@ -3421,19 +3490,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);
> @@ -3442,7 +3511,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;
> @@ -3452,52 +3521,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);
> @@ -3527,8 +3596,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);
> @@ -3556,7 +3625,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) {
> @@ -3570,7 +3639,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);
> @@ -3595,12 +3664,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);
> @@ -3622,15 +3691,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)
> @@ -3669,7 +3738,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);
> @@ -3694,7 +3763,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);
> @@ -3704,7 +3773,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
> @@ -3734,7 +3803,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;
> @@ -3749,7 +3818,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);
> @@ -3759,7 +3828,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) -
> @@ -3779,7 +3848,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;
> @@ -3797,7 +3866,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);
>  
> @@ -3812,7 +3881,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);
> @@ -3830,7 +3899,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);
> @@ -3849,7 +3918,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);
> @@ -3904,7 +3973,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(
> @@ -3926,7 +3995,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);
>  
>  	/*
> @@ -3935,14 +4004,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};
> 

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

* Re: [PATCH 14/22] mkfs: rename defaultval to flagval in opts
  2017-03-16 23:20   ` Luis R. Rodriguez
@ 2017-03-17 12:06     ` Jan Tulak
  0 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-17 12:06 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Fri, Mar 17, 2017 at 12:20 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Wed, Mar 15, 2017 at 05:00:09PM +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>
>> --- a/mkfs/xfs_mkfs.c
>> +++ b/mkfs/xfs_mkfs.c
>> @@ -189,7 +189,7 @@ unsigned int              sectorsize;
>> @@ -223,7 +223,7 @@ struct opt_params {
>>               }               conflicts [MAX_CONFLICTS];
>>               long long       minval;
>>               long long       maxval;
>> -             long long       defaultval;
>> +             long long       flagval;
>
> David suggested that in the future the config value(mkfs.xfs.conf) will override
> the defaultval, in this case since you are renaming this, just want to be sure
> the new name we choose can fit its later use also with the config. Perhaps
> userval ?
>
>   Luis

Your question is exactly why I'm renaming it. :-) This is not the
value that is used when no option is passed, but when an option
doesn't have an argument. So we don't require "-m crc=0|1", but "-m
crc" is enough.

Jan

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

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

* Re: [PATCH 07/22] mkfs: Move opts related #define to one place
  2017-03-16 23:25   ` Luis R. Rodriguez
@ 2017-03-17 12:11     ` Jan Tulak
  0 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-17 12:11 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs

On Fri, Mar 17, 2017 at 12:25 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Wed, Mar 15, 2017 at 05:00:02PM +0100, Jan Tulak wrote:
>> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
>> index 0877c196..4ba6df05 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
>
> How about instead using enums, this way if we use kdoc format (hey the new
> kernel doc format is producing nicer docs) we can then document what the
> hell each of these things are nicely. Also, when enums are used in switches
> the compiler will nag at you if you happened to have missed a case, unless you
> have a default.
>
> We could have an enum for the opts and then one for each subopt group.
>
>   Luis

Good point. I kept it as defines, but given how I'm shuffling it, I
might turn it into enum as well. This change should cause no issue
except separating option/suboption definition. I will think about it,
but now I'm more for the enums.

Jan

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

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

* Re: [PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2017-03-16 23:38 ` Luis R. Rodriguez
  2017-03-16 23:47   ` Eric Sandeen
@ 2017-03-17 12:20   ` Jan Tulak
  1 sibling, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-17 12:20 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-xfs, Eric Sandeen, Dave Chinner

On Fri, Mar 17, 2017 at 12:38 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Wed, Mar 15, 2017 at 04:59:55PM +0100, Jan Tulak wrote:
>> 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.
>
> This series is pretty large. There are quite a bit of patches which just rename
> something, or just shove code from one place to another. Can you group up
> non-functional changes together first, and send a small series of simple stuff
> with no functional changes first?
>
> That should reduce the size of the functional patch set, and make it clearer
> which patches require much careful eyeballing. It should also put out of your
> queue tons of changes which are trivial and can go in rather sooner.
>

I see... I will see how I can split it better. I guess not everything
can be moved like this, but at least some changes can be moved.

>> Config file patches addendum:
>>
>> (Thread: http://www.spinics.net/lists/linux-xfs/msg04703.html)
>>
>> I read through the changes, but decided to don't take anything from it.
>
> The last 2 patches of my config series are really the functional change there,
> the rest is fluff to account for the insanity we have now.
>
>> I think it is time to do something and adding further changes would just
>> push it down again. Nevertheless, the other patchset contains some changes
>> (like splitting the main opts loop) that I wanted to add in some later patch
>> too.
>
> OK.
>
>> I suggest that we first merge these patches I'm sending, and once it solves
>> some of the issues Luis hit too, we can look again on the config file thing
>> and even if the main idea fell out of favor for some reason, there are still
>> other useful changes.
>
> Sure, I'm fine with this, do you have a git tree ? Once you rev and post new
> series if you can provide a git URL that'd be great as then I can just work
> off of that.
>
>> PS: I'm traveling at Vault next week, so if you are there too, we can open it
>> there.
>
> I'm up for beers there.
>

Great. :-)

Cheers,
Jan



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

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

* Re: [PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2017-03-16 23:47   ` Eric Sandeen
@ 2017-03-17 12:57     ` Jan Tulak
  2017-03-18  7:08       ` Dave Chinner
  0 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-17 12:57 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Luis R. Rodriguez, linux-xfs, Dave Chinner

On Fri, Mar 17, 2017 at 12:47 AM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 3/16/17 4:38 PM, Luis R. Rodriguez wrote:
>> On Wed, Mar 15, 2017 at 04:59:55PM +0100, Jan Tulak wrote:
>>> 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.
>>
>> This series is pretty large. There are quite a bit of patches which just rename
>> something, or just shove code from one place to another. Can you group up
>> non-functional changes together first, and send a small series of simple stuff
>> with no functional changes first?
>
> I have to say I'm still struggling with it as well.  Apologies for the
> random detail nitpicking, I'm trying to look through it all to get a better
> big picture.

No issue. I guess that if I split the changes differently, it might be
easier to read.
I need to find a better way how to present/group the changes.

>
> And as far as "no-op changes" it's imperative to make them really no-op.
> Make sure that other random changes aren't stuck into the middle of anything...
>

Of course. :-)

> I'll probably keep flinging comments on various patches as I read them,
> some of it may be helpful in terms of just learning some best practice
> for patches, but TBH I'm still trying to wrap my head around the big change
> and purpose.
>

OK. We can talk about it next week personally if needed. And decide
whether it is worth to reorganise this set into no-op and op changes.

Cheers,
Jan



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

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

* Re: [PATCH 00/22] mkfs.xfs: Make stronger conflict checks
  2017-03-17 12:57     ` Jan Tulak
@ 2017-03-18  7:08       ` Dave Chinner
  0 siblings, 0 replies; 56+ messages in thread
From: Dave Chinner @ 2017-03-18  7:08 UTC (permalink / raw)
  To: Jan Tulak; +Cc: Eric Sandeen, Luis R. Rodriguez, linux-xfs

On Fri, Mar 17, 2017 at 01:57:10PM +0100, Jan Tulak wrote:
> On Fri, Mar 17, 2017 at 12:47 AM, Eric Sandeen <sandeen@sandeen.net> wrote:
> > On 3/16/17 4:38 PM, Luis R. Rodriguez wrote:
> >> On Wed, Mar 15, 2017 at 04:59:55PM +0100, Jan Tulak wrote:
> > I'll probably keep flinging comments on various patches as I read them,
> > some of it may be helpful in terms of just learning some best practice
> > for patches, but TBH I'm still trying to wrap my head around the big change
> > and purpose.
> >
> 
> OK. We can talk about it next week personally if needed. And decide
> whether it is worth to reorganise this set into no-op and op changes.

It's better to discuss this sort of thing on the mailing list so
that every sees the explanations and understands the reasons for the
changes being made....

-Dave.
-- 
Dave Chinner
david@fromorbit.com

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

* Re: [PATCH 08/22] mkfs: move conflicts into the table
  2017-03-15 16:00 ` [PATCH 08/22] mkfs: move conflicts into the table Jan Tulak
  2017-03-16 18:04   ` Eric Sandeen
  2017-03-16 18:39   ` Eric Sandeen
@ 2017-03-24 23:53   ` Eric Sandeen
  2017-03-29 14:57     ` Jan Tulak
  2 siblings, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-24 23:53 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 3/15/17 11:00 AM, Jan Tulak wrote:
> Fill the table with conflicts data and remove now-duplicate code for their
> detection from other parts of mkfs.

One other thing that I've noticed is that if you do:

# mkfs.xfs -i align=0 /dev/foo

that passes now, and it shouldn't.  Prior to this patch, it said:

Inodes always aligned for CRC enabled filesytems

The above testcase actually alternates between pass & fail over
the next several patches.  If you have testcases for these conflicts,
please try to make sure that they don't regress throughout the
series.

-Eric

> 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 4ba6df05..c100fef9 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) {
> 

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

* Re: [PATCH 11/22] mkfs: add test_default_value into conflict struct
  2017-03-15 16:00 ` [PATCH 11/22] mkfs: add test_default_value into conflict struct Jan Tulak
@ 2017-03-25  0:09   ` Eric Sandeen
  2017-03-29 14:57     ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-25  0:09 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 3/15/17 11:00 AM, Jan Tulak wrote:
> Add a flag signalising that a subopt can be conflicting with
> default value of another option.

I'm a little confused about why we would not /always/ test against
the default value.  When is it ever appropriate to ignore it?

I was also going to suggest flags rather than the two booleans,
i.e. something like "CONFLICT_OPTION_ALWAYS" or "CONFLICT_OPTION_AT_VALUE"
vs. the true, false / true, true / false, false ... etc,
but I guess the next patch that adds named initializers might
help a little in that respect.  Still, flags named like this
might be clearer in the code...

Also, I am confused by:

"The .test_default_value is used when .test_values is true"

and yet I see:

>  			{ .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."},

so it is also used when it is false?  So we do not test the values
specified, but we do test the default values?  that seems odd, is
it correct?  I'm not sure what this means.  The unique combination of
"false, true" actually only occurs 5 times.

There also seems to be a mismatch between the M_CRC -> I_ALIGN conflict,
vs. the I_ALIGN -> M_CRC conflict.

... and that highlights one of my concerns about this patchset - while it is at
least moving towards encoding every conflict into this (giant) structure,
it also seems a bit error prone.  The opt_params structure is now nearly
1000 lines of code.  I'm not quite sure how to make this more maintainable,
but it seems difficult right now...

Thanks,
-Eric
 
> 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 db82a528..19024847 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) {
> 

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

* Re: [PATCH 06/22] mkfs: add cross-section conflict checks
  2017-03-15 16:00 ` [PATCH 06/22] mkfs: add cross-section conflict checks Jan Tulak
@ 2017-03-25  0:31   ` Eric Sandeen
  2017-03-29 14:57     ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-25  0:31 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 3/15/17 11:00 AM, Jan Tulak wrote:
> Checks are modified to work with cross-section conflicts (data, metada, log, ...).

More information in the changelog please; this doesn't
tell us a whole lot about what this is actually doing.
 
> 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 7e0a4159..0877c196 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,

weird tabs there

> +			struct subopt_conflict 	*conflict);

"conflict_struct" seems like a variable name, not a function name.  :)

What does this function actually do?

> +
>  #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)
> +

that newline should not be here ...

>  {
>  	fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
>  		opt, tab[oldidx], opt, tab[newidx]);
>  	usage();
>  }

A comment about what this function actually /does/ would be good.

All it really does is printf, I guess - so a function name more
like show_conflict() might make more sense?  conflict_struct just
isn't a good descriptive name.

> +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]);
> +	}

I wonder if this can be done w/o the cut and paste?

> +	usage();
> +}
> +
>  
>  static void
>  illegal(
> 

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

* Re: [PATCH 05/22] mkfs: add a check for conflicting values
  2017-03-15 16:00 ` [PATCH 05/22] mkfs: add a check for conflicting values Jan Tulak
@ 2017-03-25  0:36   ` Eric Sandeen
  2017-03-29 14:58     ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Eric Sandeen @ 2017-03-25  0:36 UTC (permalink / raw)
  To: Jan Tulak, linux-xfs

On 3/15/17 11:00 AM, Jan Tulak wrote:
> Add a check that reports a conflict only when subopts are mixed with specific values.

Can you explain more about what changes here, maybe with an example?

...

> 
> 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 c9861409..7e0a4159 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;
>  	}

Up to here you have only changed a variable name; I'm not sure why?
 
> @@ -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);

now the name change is mixed with a functional change in the middle,
so it's harder to see... a non-functional patch for the name change
would be better, if it's necessary.

> +		}
> +	}
> +}
> +
> +/*
> + * 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"));
> 

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

* Re: [PATCH 11/22] mkfs: add test_default_value into conflict struct
  2017-03-25  0:09   ` Eric Sandeen
@ 2017-03-29 14:57     ` Jan Tulak
  2017-03-29 16:33       ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-29 14:57 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Sat, Mar 25, 2017 at 1:09 AM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 3/15/17 11:00 AM, Jan Tulak wrote:
>> Add a flag signalising that a subopt can be conflicting with
>> default value of another option.
>
> I'm a little confused about why we would not /always/ test against
> the default value.  When is it ever appropriate to ignore it?

Just a quick search: if the user disables crc, but doesn't touch
finobt, we are making a silent sb_feat.finobt=0. So we can't raise a
conflict with default value, but it is a conflict if it is an explicit
value. And maybe there are other similar cases tangled in the forest
of ifs in main().

>
> I was also going to suggest flags rather than the two booleans,
> i.e. something like "CONFLICT_OPTION_ALWAYS" or "CONFLICT_OPTION_AT_VALUE"
> vs. the true, false / true, true / false, false ... etc,
> but I guess the next patch that adds named initializers might
> help a little in that respect.  Still, flags named like this
> might be clearer in the code...

Using a bit flag instead? Mmm, that might help with readability.
Maybe. Not just these two options, but others as well:
.flags = CONFLICT_OPTION_ALWAYS | NEEDS_VAL | IS_POWER_2 etc...

>
> Also, I am confused by:
>
> "The .test_default_value is used when .test_values is true"
>
> and yet I see:
>
>>                       { .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."},
>
> so it is also used when it is false?  So we do not test the values
> specified, but we do test the default values?  that seems odd, is
> it correct?  I'm not sure what this means.  The unique combination of
> "false, true" actually only occurs 5 times.

Eh... this seems to be an error, it should be false, false. The true
makes no sense there - the conflict checks never gets to the true if
the first one is false, and a quick test with xfs/191-input-validation
confirms this: no difference between false, true and false, false, but
true, true causes multiple errors.

>
> There also seems to be a mismatch between the M_CRC -> I_ALIGN conflict,
> vs. the I_ALIGN -> M_CRC conflict.

Yes, this shouldn't bee so.

>
> ... and that highlights one of my concerns about this patchset - while it is at
> least moving towards encoding every conflict into this (giant) structure,
> it also seems a bit error prone.  The opt_params structure is now nearly
> 1000 lines of code.  I'm not quite sure how to make this more maintainable,
> but it seems difficult right now...
>

Yeah, it has grown fairly long. However, a lot of those errors I have
here is caused by the fact that I moved a lot of the options at once
and probably sometimes looked on some other line than I should, or
copy&paste thing. Later, when they are added/changed once in a long
time, it should be more reliable.

And I'm adding a validating function to spot this kind of errors
before the program does anything else.

Thanks,
Jan

> Thanks,
> -Eric
>
>> 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 db82a528..19024847 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) {
>>



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

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

* Re: [PATCH 08/22] mkfs: move conflicts into the table
  2017-03-24 23:53   ` Eric Sandeen
@ 2017-03-29 14:57     ` Jan Tulak
  0 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-29 14:57 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Sat, Mar 25, 2017 at 12:53 AM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 3/15/17 11:00 AM, Jan Tulak wrote:
>> Fill the table with conflicts data and remove now-duplicate code for their
>> detection from other parts of mkfs.
>
> One other thing that I've noticed is that if you do:
>
> # mkfs.xfs -i align=0 /dev/foo
>
> that passes now, and it shouldn't.  Prior to this patch, it said:
>
> Inodes always aligned for CRC enabled filesytems
>
> The above testcase actually alternates between pass & fail over
> the next several patches.  If you have testcases for these conflicts,
> please try to make sure that they don't regress throughout the
> series.

I'll fix it.

Thanks,
Jan

>
> -Eric
>
>> 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 4ba6df05..c100fef9 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) {
>>
> --
> 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



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

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

* Re: [PATCH 06/22] mkfs: add cross-section conflict checks
  2017-03-25  0:31   ` Eric Sandeen
@ 2017-03-29 14:57     ` Jan Tulak
  0 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-29 14:57 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Sat, Mar 25, 2017 at 1:31 AM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 3/15/17 11:00 AM, Jan Tulak wrote:
>> Checks are modified to work with cross-section conflicts (data, metada, log, ...).
>
> More information in the changelog please; this doesn't
> tell us a whole lot about what this is actually doing.

Like this?

Checks are modified to work with cross-section conflicts (data,
metada, log, ...).
So, it is now possible to detect a conflict between -m foo and -d bar
options.

This patch only extends checks to test for conflicts across all
options instead of only the current one, the opts struct already can
declare it.

>
>> 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 7e0a4159..0877c196 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,
>
> weird tabs there
>
>> +                     struct subopt_conflict  *conflict);
>
> "conflict_struct" seems like a variable name, not a function name.  :)
>
> What does this function actually do?

See bellow at the definition of this function (your other comment).

>
>> +
>>  #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)
>> +
>
> that newline should not be here ...
>
>>  {
>>       fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
>>               opt, tab[oldidx], opt, tab[newidx]);
>>       usage();
>>  }
>
> A comment about what this function actually /does/ would be good.
>
> All it really does is printf, I guess - so a function name more
> like show_conflict() might make more sense?  conflict_struct just
> isn't a good descriptive name.

Agreed, renamed to print_conflict_struct. The _struct is to
differentiate it from the conflict() function that has a different set
of arguments and can't print out the optional message conflicts
definitions can have.

>
>> +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]);
>> +     }
>
> I wonder if this can be done w/o the cut and paste?

Yes. After few minutes of thinking how to nicely concatenate strings
while avoiding allocs, I realised I can just print out the basic
error, conditionally print the conflict->message and then always print
"\n". I guess I overcomplicate things sometimes... :-/ Anyway, changed
for the next version of this patch.

>
>> +     usage();
>> +}
>> +
>>
>>  static void
>>  illegal(
>>



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

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

* Re: [PATCH 05/22] mkfs: add a check for conflicting values
  2017-03-25  0:36   ` Eric Sandeen
@ 2017-03-29 14:58     ` Jan Tulak
  0 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-29 14:58 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Sat, Mar 25, 2017 at 1:36 AM, Eric Sandeen <sandeen@sandeen.net> wrote:
> On 3/15/17 11:00 AM, Jan Tulak wrote:
>> Add a check that reports a conflict only when subopts are mixed with specific values.
>
> Can you explain more about what changes here, maybe with an example?
>

For example, this should fail: -i attr=1 -m crc=1
But these should pass: -i attr=1 -m crc=0 or -i attr=2 -m crc=1
So we need a way how to raise conflict on these occassions. This does
not set the conflicting attributes in the options, but it prepares the
ground for it.

I will add something like this directly to the commit message.

> ...
>
>>
>> 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 c9861409..7e0a4159 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;
>>       }
>
> Up to here you have only changed a variable name; I'm not sure why?

Mmm, honestly, I don't know now. It seems unnecessary to me too.

>
>> @@ -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);
>
> now the name change is mixed with a functional change in the middle,
> so it's harder to see... a non-functional patch for the name change
> would be better, if it's necessary.

Yeah, I will split the patches.

>
>> +             }
>> +     }
>> +}
>> +
>> +/*
>> + * 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"));
>>



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

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

* Re: [PATCH 11/22] mkfs: add test_default_value into conflict struct
  2017-03-29 14:57     ` Jan Tulak
@ 2017-03-29 16:33       ` Jan Tulak
  2017-03-31  1:40         ` Luis R. Rodriguez
  0 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-03-29 16:33 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs, Luis R. Rodriguez

On Wed, Mar 29, 2017 at 4:57 PM, Jan Tulak <jtulak@redhat.com> wrote:
>
> And I'm adding a validating function to spot this kind of errors
> before the program does anything else.

I made a first quick fire on this and even the half-baked version that
can only find if a conflict is missing its counterpart has found two
issues (L_AGNUM doesn't have an entry about L_NAME, but L_NAME points
at L_AGNUM. Ditto for L_INTERNAL and L_NAME.)

Let's see what it finds out when it also compares if the values are
set accordingly.

Also, I have published my git tree on github. It is in middle of
changes according to things reported here in mailing list and you
already have it locally, but if it is any help to you or Luis
(CCed)... I will update it once I send updated patchset, and maybe few
times before that (if I will find it helpful).

https://github.com/jtulak/xfsprogs-dev

(Ah, and ignore the name of the last commit, it is just a note for me
what to pick on tomorrow - I'm ending for today.)

Jan

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

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

* Re: [PATCH 11/22] mkfs: add test_default_value into conflict struct
  2017-03-29 16:33       ` Jan Tulak
@ 2017-03-31  1:40         ` Luis R. Rodriguez
  2017-03-31  7:35           ` Jan Tulak
  0 siblings, 1 reply; 56+ messages in thread
From: Luis R. Rodriguez @ 2017-03-31  1:40 UTC (permalink / raw)
  To: Jan Tulak; +Cc: Eric Sandeen, linux-xfs, Luis R. Rodriguez

On Wed, Mar 29, 2017 at 06:33:38PM +0200, Jan Tulak wrote:
> https://github.com/jtulak/xfsprogs-dev

FWIW

mcgrof@ergon ~/devel $ git clone https://github.com/jtulak/xfsprogs-dev.git jtulak-xfsprogs
Cloning into 'jtulak-xfsprogs'...
remote: Counting objects: 20082, done.
remote: Compressing objects: 100% (3760/3760), done.
remote: Total 20082 (delta 16302), reused 20082 (delta 16302), pack-reused 0
Receiving objects: 100% (20082/20082), 5.99 MiB | 9.80 MiB/s, done.
Resolving deltas: 100% (16302/16302), done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.

mcgrof@ergon ~/devel $ git clone https://github.com/jtulak/xfsprogs-dev.git --reference xfsprogs-dev/.git jtulak-xfsprogs
Cloning into 'jtulak-xfsprogs'...
remote: Counting objects: 96, done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 96 (delta 72), reused 91 (delta 67), pack-reused 0
Unpacking objects: 100% (96/96), done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.

A branch does work:

mcgrof@ergon ~/devel/xfsprogs-dev (git::master)$ git remote add jtulak https://github.com/jtulak/xfsprogs-dev.git 
mcgrof@ergon ~/devel/xfsprogs-dev (git::master)$ git fetch jtulak
remote: Counting objects: 96, done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 96 (delta 72), reused 91 (delta 67), pack-reused 0
Unpacking objects: 100% (96/96), done.
>From https://github.com/jtulak/xfsprogs-dev
 * [new branch]                github     -> jtulak/github

So one can just do:

git clone https://github.com/jtulak/xfsprogs-dev -b github j-xfs --reference  /home/mcgrof/devel/xfsprogs-dev/.git
Cloning into 'j-xfs'...

  Luis

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

* Re: [PATCH 11/22] mkfs: add test_default_value into conflict struct
  2017-03-31  1:40         ` Luis R. Rodriguez
@ 2017-03-31  7:35           ` Jan Tulak
  0 siblings, 0 replies; 56+ messages in thread
From: Jan Tulak @ 2017-03-31  7:35 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Eric Sandeen, linux-xfs

On Fri, Mar 31, 2017 at 3:40 AM, Luis R. Rodriguez <mcgrof@kernel.org> wrote:
> On Wed, Mar 29, 2017 at 06:33:38PM +0200, Jan Tulak wrote:
>> https://github.com/jtulak/xfsprogs-dev
>
> FWIW
>
> mcgrof@ergon ~/devel $ git clone https://github.com/jtulak/xfsprogs-dev.git jtulak-xfsprogs
> Cloning into 'jtulak-xfsprogs'...
> remote: Counting objects: 20082, done.
> remote: Compressing objects: 100% (3760/3760), done.
> remote: Total 20082 (delta 16302), reused 20082 (delta 16302), pack-reused 0
> Receiving objects: 100% (20082/20082), 5.99 MiB | 9.80 MiB/s, done.
> Resolving deltas: 100% (16302/16302), done.
> warning: remote HEAD refers to nonexistent ref, unable to checkout.
>
> mcgrof@ergon ~/devel $ git clone https://github.com/jtulak/xfsprogs-dev.git --reference xfsprogs-dev/.git jtulak-xfsprogs
> Cloning into 'jtulak-xfsprogs'...
> remote: Counting objects: 96, done.
> remote: Compressing objects: 100% (29/29), done.
> remote: Total 96 (delta 72), reused 91 (delta 67), pack-reused 0
> Unpacking objects: 100% (96/96), done.
> warning: remote HEAD refers to nonexistent ref, unable to checkout.
>
> A branch does work:
>
> mcgrof@ergon ~/devel/xfsprogs-dev (git::master)$ git remote add jtulak https://github.com/jtulak/xfsprogs-dev.git
> mcgrof@ergon ~/devel/xfsprogs-dev (git::master)$ git fetch jtulak
> remote: Counting objects: 96, done.
> remote: Compressing objects: 100% (29/29), done.
> remote: Total 96 (delta 72), reused 91 (delta 67), pack-reused 0
> Unpacking objects: 100% (96/96), done.
> From https://github.com/jtulak/xfsprogs-dev
>  * [new branch]                github     -> jtulak/github
>
> So one can just do:
>
> git clone https://github.com/jtulak/xfsprogs-dev -b github j-xfs --reference  /home/mcgrof/devel/xfsprogs-dev/.git
> Cloning into 'j-xfs'...
>
>   Luis

o_O This is something I didn't think that there could be any issue.
Well, next time I know that I need to push all branches this specific
one originates from. Anyway, fixed, I pushed master branch on github
too. Mine branch should be the default one, but git now knows the
ref...

$ git clone https://github.com/jtulak/xfsprogs-dev.git jtulak-xfsprogs
Cloning into 'jtulak-xfsprogs'...
remote: Counting objects: 20082, done.
remote: Compressing objects: 100% (3760/3760), done.
remote: Total 20082 (delta 16302), reused 20082 (delta 16302), pack-reused 0
Receiving objects: 100% (20082/20082), 5.99 MiB | 3.39 MiB/s, done.
Resolving deltas: 100% (16302/16302), done.
$

Thanks,
Jan

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

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

* Re: [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum
  2017-03-16 22:59   ` Eric Sandeen
@ 2017-04-05 13:00     ` Jan Tulak
  2017-04-05 14:05       ` Eric Sandeen
  0 siblings, 1 reply; 56+ messages in thread
From: Jan Tulak @ 2017-04-05 13:00 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Thu, Mar 16, 2017 at 11:59 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
> The only downside I see to this is that we used to echo back the same
> form that was specified, i.e. -
>
> # mkfs.xfs -f -d size=4e fsfile
> size 4e specified for data subvolume is too large, maximum is 262144 blocks
> # mkfs.xfs -f -d size=4611686018427387904 fsfile
> size 4611686018427387904 specified for data subvolume is too large, maximum is 262144 blocks
> # mkfs.xfs -f -d size=1125899906842624b fsfile
> size 1125899906842624b specified for data subvolume is too large, maximum is 262144 blocks
>
> now we always get back the raw byte value:
>
> # mkfs/mkfs.xfs -f -d size=4e fsfile
> size 4611686018427387904 specified for data subvolume is too large, maximum is 262144 blocks
>
> Anything that fails the getnum() checks echo back the original
> form on the cmdline; this case is different because getnum() passes,
> but by the time we do value checking all we have is the bytes.  Is
> that intentional/desirable?
>
> So it's a change, not necessarily incorrect or unacceptable, but
> I wanted to highlight it and check.  It wouldn't be too hard to
> convert it right away, but keep the string around for error printing
> purposes, I suppose.
>

It goes back into the original reporting style later in the set. I
tried to change the patch to avoid this temporary change, but the
issue is, I loose the old raw strings before I have access to the
necessary indexes for the option table to read the raw string from it,
or before a code shuffling brings the reporting closer to where the
raw string still exists.

Given that it is only a temporary change of style and it seems to be
too deeply depending on other changes, I'm keeping it as a TODO, but
not a blocker. Maybe if the patch can be split and one of the parts
moved after other commits...

Jan

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

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

* Re: [PATCH 01/22] mkfs: remove intermediate getstr followed by getnum
  2017-04-05 13:00     ` Jan Tulak
@ 2017-04-05 14:05       ` Eric Sandeen
  0 siblings, 0 replies; 56+ messages in thread
From: Eric Sandeen @ 2017-04-05 14:05 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On 4/5/17 8:00 AM, Jan Tulak wrote:
> On Thu, Mar 16, 2017 at 11:59 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
>> The only downside I see to this is that we used to echo back the same
>> form that was specified, i.e. -
>>
>> # mkfs.xfs -f -d size=4e fsfile
>> size 4e specified for data subvolume is too large, maximum is 262144 blocks
>> # mkfs.xfs -f -d size=4611686018427387904 fsfile
>> size 4611686018427387904 specified for data subvolume is too large, maximum is 262144 blocks
>> # mkfs.xfs -f -d size=1125899906842624b fsfile
>> size 1125899906842624b specified for data subvolume is too large, maximum is 262144 blocks
>>
>> now we always get back the raw byte value:
>>
>> # mkfs/mkfs.xfs -f -d size=4e fsfile
>> size 4611686018427387904 specified for data subvolume is too large, maximum is 262144 blocks
>>
>> Anything that fails the getnum() checks echo back the original
>> form on the cmdline; this case is different because getnum() passes,
>> but by the time we do value checking all we have is the bytes.  Is
>> that intentional/desirable?
>>
>> So it's a change, not necessarily incorrect or unacceptable, but
>> I wanted to highlight it and check.  It wouldn't be too hard to
>> convert it right away, but keep the string around for error printing
>> purposes, I suppose.
>>
> 
> It goes back into the original reporting style later in the set. I
> tried to change the patch to avoid this temporary change, but the
> issue is, I loose the old raw strings before I have access to the
> necessary indexes for the option table to read the raw string from it,
> or before a code shuffling brings the reporting closer to where the
> raw string still exists.
> 
> Given that it is only a temporary change of style and it seems to be
> too deeply depending on other changes, I'm keeping it as a TODO, but
> not a blocker. Maybe if the patch can be split and one of the parts
> moved after other commits...

Even simply noting in the changelog that it's temporary, and the reason
for the change, would be helpful.  It's a big enough patchset that it's
hard for the reviewer to keep everything in mind across 20+ patches.  ;)

Thanks,
-Eric

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

end of thread, other threads:[~2017-04-05 14:05 UTC | newest]

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

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