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