From: Dave Chinner <dchinner@xxxxxxxxxx> CHANGELOG: o Add .conflicts init where it was missing o Add explanation of a new member of opt_params struct. o A long line fix. Many options conflict, so we need to specify which options conflict with each other in a generic manner. We already have a "seen" variable used for respecification detection, so we can also use this code conflict detection. Hence add a "conflicts" array to the sub options parameter definition. Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> Signed-off-by: Jan Tulak <jtulak@xxxxxxxxxx> --- mkfs/xfs_mkfs.c | 258 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 134 insertions(+), 124 deletions(-) diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 1f06110..d119580 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -54,6 +54,9 @@ unsigned int sectorsize; #define MAX_SUBOPTS 16 #define SUBOPT_NEEDS_VAL (-1LL) +#define MAX_CONFLICTS 8 +#define LAST_CONFLICT (-1) + /* * Table for parsing mkfs parameters. * @@ -89,6 +92,11 @@ unsigned int sectorsize; * An optional flag for subopts where the given value has to be a power * of two. * + * 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. + * * minval, maxval OPTIONAL * These options are used for automatic range check and they have to be * always used together in pair. If you don't want to limit the max value, @@ -118,6 +126,7 @@ struct opt_params { bool seen; bool convert; bool is_power_2; + int conflicts[MAX_CONFLICTS]; long long minval; long long maxval; long long defaultval; @@ -135,6 +144,8 @@ struct opt_params bopts = { }, .subopt_params = { { .index = B_LOG, + .conflicts = { B_SIZE, + LAST_CONFLICT }, .minval = XFS_MIN_BLOCKSIZE_LOG, .maxval = XFS_MAX_BLOCKSIZE_LOG, .defaultval = SUBOPT_NEEDS_VAL, @@ -142,6 +153,8 @@ struct opt_params bopts = { { .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, @@ -186,57 +199,84 @@ struct opt_params dopts = { }, .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, @@ -244,21 +284,29 @@ struct opt_params dopts = { .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, @@ -290,43 +338,57 @@ struct opt_params iopts = { }, .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, @@ -365,46 +427,64 @@ struct opt_params lopts = { }, .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 = BTOBB(XLOG_MIN_RECORD_BSIZE), .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE), .defaultval = SUBOPT_NEEDS_VAL, }, { .index = L_SU, + .conflicts = { L_SUNIT, + LAST_CONFLICT }, .convert = true, .minval = XLOG_MIN_RECORD_BSIZE, .maxval = UINT_MAX, .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, @@ -412,14 +492,20 @@ struct opt_params lopts = { .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, @@ -442,11 +528,15 @@ struct opt_params nopts = { }, .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, @@ -454,11 +544,13 @@ struct opt_params nopts = { .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, @@ -485,32 +577,38 @@ struct opt_params ropts = { }, .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 }, }, }, }; @@ -530,16 +628,25 @@ struct opt_params sopts = { }, .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, @@ -547,6 +654,9 @@ struct opt_params sopts = { .defaultval = SUBOPT_NEEDS_VAL, }, { .index = S_SECTSIZE, + .conflicts = { S_LOG, + S_SECTLOG, + LAST_CONFLICT }, .convert = true, .is_power_2 = true, .minval = XFS_MIN_SECTORSIZE, @@ -569,16 +679,19 @@ struct opt_params mopts = { }, .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, }, }, @@ -620,30 +733,14 @@ calc_stripe_factors( int *lsunit) { /* Handle data sunit/swidth options */ - if (*dsunit || *dswidth) { - if (dsu || dsw) { - fprintf(stderr, - _("data su/sw must not be used in " - "conjunction with data sunit/swidth\n")); - usage(); - } - - if ((*dsunit && !*dswidth) || (!*dsunit && *dswidth)) { - fprintf(stderr, - _("both data sunit and data swidth options " - "must be specified\n")); - usage(); - } + if ((*dsunit && !*dswidth) || (!*dsunit && *dswidth)) { + fprintf(stderr, + _("both data sunit and data swidth options " + "must be specified\n")); + usage(); } if (dsu || dsw) { - if (*dsunit || *dswidth) { - fprintf(stderr, - _("data sunit/swidth must not be used in " - "conjunction with data su/sw\n")); - usage(); - } - if ((dsu && !dsw) || (!dsu && dsw)) { fprintf(stderr, _("both data su and data sw options " @@ -671,24 +768,8 @@ calc_stripe_factors( /* Handle log sunit options */ - if (*lsunit) { - if (lsu) { - fprintf(stderr, - _("log su should not be used in " - "conjunction with log sunit\n")); - usage(); - } - } - - if (lsu) { - if (*lsunit) { - fprintf(stderr, - _("log sunit should not be used in " - "conjunction with log su\n")); - usage(); - } + if (lsu) *lsunit = (int)BTOBBT(lsu); - } } /* @@ -1410,6 +1491,17 @@ getnum( respec(opts->name, (char **)opts->subopts, index); sp->seen = true; + /* check for conflicts with the option */ + for (c = 0; c < MAX_CONFLICTS; c++) { + int conflict_opt = sp->conflicts[c]; + + if (conflict_opt == LAST_CONFLICT) + break; + if (opts->subopt_params[conflict_opt].seen) + conflict(opts->name, (char **)opts->subopts, + conflict_opt, index); + } + /* empty strings might just return a default value */ if (!str || *str == '\0') { if (sp->defaultval == SUBOPT_NEEDS_VAL) @@ -1607,17 +1699,11 @@ main( switch (getsubopt(&p, (constpp)subopts, &value)) { case B_LOG: - if (bsflag) - conflict('b', subopts, B_SIZE, - B_LOG); blocklog = getnum(value, &bopts, B_LOG); blocksize = 1 << blocklog; blflag = 1; break; case B_SIZE: - if (blflag) - conflict('b', subopts, B_LOG, - B_SIZE); blocksize = getnum(value, &bopts, B_SIZE); blocklog = libxfs_highbit32(blocksize); @@ -1666,61 +1752,29 @@ main( dsize = value; break; case D_SUNIT: - if (nodsflag) - conflict('d', subopts, D_NOALIGN, - D_SUNIT); dsunit = getnum(value, &dopts, D_SUNIT); break; case D_SWIDTH: - if (nodsflag) - conflict('d', subopts, D_NOALIGN, - D_SWIDTH); dswidth = getnum(value, &dopts, D_SWIDTH); break; case D_SU: - if (nodsflag) - conflict('d', subopts, D_NOALIGN, - D_SU); dsu = getnum(value, &dopts, D_SU); break; case D_SW: - if (nodsflag) - conflict('d', subopts, D_NOALIGN, - D_SW); dsw = getnum(value, &dopts, D_SW); break; case D_NOALIGN: nodsflag = getnum(value, &dopts, - D_NOALIGN); - if (nodsflag) { - if (dsu) - conflict('d', subopts, D_SU, - D_NOALIGN); - if (dsunit) - conflict('d', subopts, D_SUNIT, - D_NOALIGN); - if (dsw) - conflict('d', subopts, D_SW, D_NOALIGN); - if (dswidth) - conflict('d', subopts, D_SWIDTH, - D_NOALIGN); - } break; case D_SECTLOG: - if (ssflag) - conflict('d', subopts, D_SECTSIZE, - D_SECTLOG); sectorlog = getnum(value, &dopts, D_SECTLOG); sectorsize = 1 << sectorlog; slflag = 1; break; case D_SECTSIZE: - if (slflag) - conflict('d', subopts, D_SECTLOG, - D_SECTSIZE); sectorsize = getnum(value, &dopts, D_SECTSIZE); sectorlog = @@ -1763,12 +1817,6 @@ main( &iopts, I_ALIGN); break; case I_LOG: - if (ipflag) - conflict('i', subopts, I_PERBLOCK, - I_LOG); - if (isflag) - conflict('i', subopts, I_SIZE, - I_LOG); inodelog = getnum(value, &iopts, I_LOG); isize = 1 << inodelog; ilflag = 1; @@ -1779,23 +1827,11 @@ main( imflag = 1; break; case I_PERBLOCK: - if (ilflag) - conflict('i', subopts, I_LOG, - I_PERBLOCK); - if (isflag) - conflict('i', subopts, I_SIZE, - I_PERBLOCK); inopblock = getnum(value, &iopts, I_PERBLOCK); ipflag = 1; break; case I_SIZE: - if (ilflag) - conflict('i', subopts, I_LOG, - I_SIZE); - if (ipflag) - conflict('i', subopts, I_PERBLOCK, - I_SIZE); isize = getnum(value, &iopts, I_SIZE); inodelog = libxfs_highbit32(isize); isflag = 1; @@ -1810,9 +1846,8 @@ main( I_PROJID32BIT); break; case I_SPINODES: - sb_feat.spinodes = - getnum(value, &iopts, - I_SPINODES); + sb_feat.spinodes = getnum(value, + &iopts, I_SPINODES); break; default: unknown('i', value); @@ -1828,8 +1863,6 @@ main( switch (getsubopt(&p, (constpp)subopts, &value)) { case L_AGNUM: - if (ldflag) - conflict('l', subopts, L_AGNUM, L_DEV); logagno = getnum(value, &lopts, L_AGNUM); laflag = 1; break; @@ -1843,12 +1876,6 @@ main( xi.lcreat = 1; break; case L_INTERNAL: - if (ldflag) - conflict('l', subopts, L_INTERNAL, L_DEV); - if (xi.lisfile) - conflict('l', subopts, L_FILE, - L_INTERNAL); - loginternal = getnum(value, &lopts, L_INTERNAL); liflag = 1; @@ -1890,18 +1917,12 @@ main( lsflag = 1; break; case L_SECTLOG: - if (lssflag) - conflict('l', subopts, L_SECTSIZE, - L_SECTLOG); lsectorlog = getnum(value, &lopts, L_SECTLOG); lsectorsize = 1 << lsectorlog; lslflag = 1; break; case L_SECTSIZE: - if (lslflag) - conflict('l', subopts, L_SECTLOG, - L_SECTSIZE); lsectorsize = getnum(value, &lopts, L_SECTSIZE); lsectorlog = @@ -1966,18 +1987,12 @@ _("cannot specify both -m crc=1 and -n ftype\n")); switch (getsubopt(&p, (constpp)subopts, &value)) { case N_LOG: - if (nsflag) - conflict('n', subopts, N_SIZE, - N_LOG); dirblocklog = getnum(value, &nopts, N_LOG); dirblocksize = 1 << dirblocklog; nlflag = 1; break; case N_SIZE: - if (nlflag) - conflict('n', subopts, N_LOG, - N_SIZE); dirblocksize = getnum(value, &nopts, N_SIZE); dirblocklog = @@ -2083,7 +2098,7 @@ _("cannot specify both -m crc=1 and -n ftype\n")); &value)) { case S_LOG: case S_SECTLOG: - if (ssflag || lssflag) + if (lssflag) conflict('s', subopts, S_SECTSIZE, S_SECTLOG); sectorlog = getnum(value, &sopts, @@ -2095,7 +2110,7 @@ _("cannot specify both -m crc=1 and -n ftype\n")); break; case S_SIZE: case S_SECTSIZE: - if (slflag || lslflag) + if (lslflag) conflict('s', subopts, S_SECTLOG, S_SECTSIZE); sectorsize = getnum(value, &sopts, @@ -2316,11 +2331,6 @@ _("warning: sparse inodes not supported without CRC support, disabled.\n")); dirblocksize = 1 << dirblocklog; } - if (daflag && dasize) { - fprintf(stderr, - _("both -d agcount= and agsize= specified, use one or the other\n")); - usage(); - } if (xi.disfile && (!dsize || !xi.dname)) { fprintf(stderr, -- 2.6.0 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs