static const char *opt_type_names[] = {
"OPT_INVALID",
"OPT_STR",
+ "OPT_STR_ULL",
"OPT_STR_MULTI",
"OPT_STR_VAL",
"OPT_STR_VAL_TIME",
"OPT_STR_STORE",
"OPT_RANGE",
"OPT_INT",
+ "OPT_ULL",
"OPT_BOOL",
"OPT_FLOAT_LIST",
"OPT_STR_SET",
"OPT_DEPRECATED",
+ "OPT_SOFT_DEPRECATED",
"OPT_UNSUPPORTED",
};
}
static void show_option_range(const struct fio_option *o,
- size_t (*logger)(const char *format, ...))
+ ssize_t (*logger)(const char *format, ...))
{
if (o->type == FIO_OPT_FLOAT_LIST) {
const char *sep = "";
static void show_option_help(const struct fio_option *o, int is_err)
{
const char *typehelp[] = {
- "invalid",
- "string (opt=bla)",
- "string (opt=bla)",
- "string with possible k/m/g postfix (opt=4k)",
- "string with time postfix (opt=10s)",
- "string (opt=bla)",
- "string with dual range (opt=1k-4k,4k-8k)",
- "integer value (opt=100)",
- "boolean value (opt=1)",
- "list of floating point values separated by ':' (opt=5.9:7.8)",
- "no argument (opt)",
- "deprecated",
- "unsupported",
+ [FIO_OPT_INVALID] = "invalid",
+ [FIO_OPT_STR] = "string (opt=bla)",
+ [FIO_OPT_STR_ULL] = "string (opt=bla)",
+ [FIO_OPT_STR_MULTI] = "string with possible k/m/g postfix (opt=4k)",
+ [FIO_OPT_STR_VAL] = "string (opt=bla)",
+ [FIO_OPT_STR_VAL_TIME] = "string with time postfix (opt=10s)",
+ [FIO_OPT_STR_STORE] = "string (opt=bla)",
+ [FIO_OPT_RANGE] = "one to three ranges (opt=1k-4k[,4k-8k[,1k-8k]])",
+ [FIO_OPT_INT] = "integer value (opt=100)",
+ [FIO_OPT_ULL] = "integer value (opt=100)",
+ [FIO_OPT_BOOL] = "boolean value (opt=1)",
+ [FIO_OPT_FLOAT_LIST] = "list of floating point values separated by ':' (opt=5.9:7.8)",
+ [FIO_OPT_STR_SET] = "empty or boolean value ([0|1])",
+ [FIO_OPT_DEPRECATED] = "deprecated",
+ [FIO_OPT_SOFT_DEPRECATED] = "deprecated",
+ [FIO_OPT_UNSUPPORTED] = "unsupported",
};
- size_t (*logger)(const char *format, ...);
+ ssize_t (*logger)(const char *format, ...);
if (is_err)
logger = log_err;
*(s + 1) = '\0';
}
-static int check_range_bytes(const char *str, long *val, void *data)
+static int check_range_bytes(const char *str, long long *val, void *data)
{
long long __val;
return "OPT_UNKNOWN?";
}
+static bool val_too_large(const struct fio_option *o, unsigned long long val,
+ bool is_uint)
+{
+ if (!o->maxval)
+ return false;
+
+ if (is_uint) {
+ if ((int) val < 0)
+ return (int) val > (int) o->maxval;
+ return (unsigned int) val > o->maxval;
+ }
+
+ return val > o->maxval;
+}
+
+static bool val_too_small(const struct fio_option *o, unsigned long long val,
+ bool is_uint)
+{
+ if (!o->minval)
+ return false;
+
+ if (is_uint)
+ return (int) val < o->minval;
+
+ return val < o->minval;
+}
+
static int __handle_option(const struct fio_option *o, const char *ptr,
void *data, int first, int more, int curr)
{
int il=0, *ilp;
fio_fp64_t *flp;
long long ull, *ullp;
- long ul1, ul2;
+ long ul2;
+ long long ull1, ull2;
double uf;
char **cp = NULL;
int ret = 0, is_time = 0;
switch (o->type) {
case FIO_OPT_STR:
+ case FIO_OPT_STR_ULL:
case FIO_OPT_STR_MULTI: {
fio_opt_str_fn *fn = o->cb;
break;
if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
ret = 0;
- if (o->off1)
+ if (!o->off1)
+ continue;
+ if (o->type == FIO_OPT_STR_ULL)
+ val_store(ullp, vp->oval, o->off1, vp->orval, data, o);
+ else
val_store(ilp, vp->oval, o->off1, vp->orval, data, o);
continue;
}
}
case FIO_OPT_STR_VAL_TIME:
is_time = 1;
+ /* fall through */
+ case FIO_OPT_ULL:
case FIO_OPT_INT:
case FIO_OPT_STR_VAL: {
fio_opt_str_val_fn *fn = o->cb;
if (!is_time && o->is_time)
is_time = o->is_time;
- tmp[sizeof(tmp) - 1] = '\0';
- strncpy(tmp, ptr, sizeof(tmp) - 1);
+ snprintf(tmp, sizeof(tmp), "%s", ptr);
p = strchr(tmp, ',');
if (p)
*p = '\0';
return 1;
}
- if (o->maxval && ull > o->maxval) {
- log_err("max value out of range: %llu"
- " (%u max)\n", ull, o->maxval);
+ if (val_too_large(o, ull, o->type == FIO_OPT_INT)) {
+ log_err("%s: max value out of range: %llu"
+ " (%llu max)\n", o->name, ull, o->maxval);
return 1;
}
- if (o->minval && ull < o->minval) {
- log_err("min value out of range: %lld"
- " (%d min)\n", ull, o->minval);
+ if (val_too_small(o, ull, o->type == FIO_OPT_INT)) {
+ log_err("%s: min value out of range: %lld"
+ " (%d min)\n", o->name, ull, o->minval);
return 1;
}
if (o->posval[0].ival) {
val_store(ilp, ull, o->off3, 0, data, o);
}
}
+ } else if (o->type == FIO_OPT_ULL) {
+ if (first)
+ val_store(ullp, ull, o->off1, 0, data, o);
+ if (curr == 1) {
+ if (o->off2)
+ val_store(ullp, ull, o->off2, 0, data, o);
+ }
+ if (curr == 2) {
+ if (o->off3)
+ val_store(ullp, ull, o->off3, 0, data, o);
+ }
+ if (!more) {
+ if (curr < 1) {
+ if (o->off2)
+ val_store(ullp, ull, o->off2, 0, data, o);
+ }
+ if (curr < 2) {
+ if (o->off3)
+ val_store(ullp, ull, o->off3, 0, data, o);
+ }
+ }
} else {
if (first)
val_store(ullp, ull, o->off1, 0, data, o);
char tmp[128];
char *p1, *p2;
- tmp[sizeof(tmp) - 1] = '\0';
- strncpy(tmp, ptr, sizeof(tmp) - 1);
+ snprintf(tmp, sizeof(tmp), "%s", ptr);
/* Handle bsrange with separate read,write values: */
p1 = strchr(tmp, ',');
p1 = tmp;
ret = 1;
- if (!check_range_bytes(p1, &ul1, data) &&
- !check_range_bytes(p2, &ul2, data)) {
+ if (!check_range_bytes(p1, &ull1, data) &&
+ !check_range_bytes(p2, &ull2, data)) {
ret = 0;
- if (ul1 > ul2) {
- unsigned long foo = ul1;
+ if (ull1 > ull2) {
+ unsigned long long foo = ull1;
- ul1 = ul2;
- ul2 = foo;
+ ull1 = ull2;
+ ull2 = foo;
}
if (first) {
- val_store(ilp, ul1, o->off1, 0, data, o);
- val_store(ilp, ul2, o->off2, 0, data, o);
+ val_store(ullp, ull1, o->off1, 0, data, o);
+ val_store(ullp, ull2, o->off2, 0, data, o);
}
if (curr == 1) {
if (o->off3 && o->off4) {
- val_store(ilp, ul1, o->off3, 0, data, o);
- val_store(ilp, ul2, o->off4, 0, data, o);
+ val_store(ullp, ull1, o->off3, 0, data, o);
+ val_store(ullp, ull2, o->off4, 0, data, o);
}
}
if (curr == 2) {
if (o->off5 && o->off6) {
- val_store(ilp, ul1, o->off5, 0, data, o);
- val_store(ilp, ul2, o->off6, 0, data, o);
+ val_store(ullp, ull1, o->off5, 0, data, o);
+ val_store(ullp, ull2, o->off6, 0, data, o);
}
}
if (!more) {
if (curr < 1) {
if (o->off3 && o->off4) {
- val_store(ilp, ul1, o->off3, 0, data, o);
- val_store(ilp, ul2, o->off4, 0, data, o);
+ val_store(ullp, ull1, o->off3, 0, data, o);
+ val_store(ullp, ull2, o->off4, 0, data, o);
}
}
if (curr < 2) {
if (o->off5 && o->off6) {
- val_store(ilp, ul1, o->off5, 0, data, o);
- val_store(ilp, ul2, o->off6, 0, data, o);
+ val_store(ullp, ull1, o->off5, 0, data, o);
+ val_store(ullp, ull2, o->off6, 0, data, o);
}
}
}
break;
if (o->maxval && il > (int) o->maxval) {
- log_err("max value out of range: %d (%d max)\n",
+ log_err("max value out of range: %d (%llu max)\n",
il, o->maxval);
return 1;
}
break;
}
case FIO_OPT_DEPRECATED:
- log_info("Option %s is deprecated\n", o->name);
ret = 1;
+ /* fall through */
+ case FIO_OPT_SOFT_DEPRECATED:
+ log_info("Option %s is deprecated\n", o->name);
break;
default:
log_err("Bad option type %u\n", o->type);
if (ptr &&
(o->type != FIO_OPT_STR_STORE) &&
(o->type != FIO_OPT_STR) &&
+ (o->type != FIO_OPT_STR_ULL) &&
(o->type != FIO_OPT_FLOAT_LIST)) {
ptr2 = strchr(ptr, ',');
if (ptr2 && *(ptr2 + 1) == '\0')
for (o = &options[0]; o->name; o++) {
int match = 0;
- if (o->type == FIO_OPT_DEPRECATED)
+ if (o->type == FIO_OPT_DEPRECATED ||
+ o->type == FIO_OPT_SOFT_DEPRECATED)
continue;
if (!exec_profile && o->prof_name)
continue;
static void option_init(struct fio_option *o)
{
- if (o->type == FIO_OPT_DEPRECATED || o->type == FIO_OPT_UNSUPPORTED)
+ if (o->type == FIO_OPT_DEPRECATED || o->type == FIO_OPT_UNSUPPORTED ||
+ o->type == FIO_OPT_SOFT_DEPRECATED)
return;
if (o->name && !o->lname)
log_err("Option %s: missing long option name\n", o->name);
if (!o->maxval)
o->maxval = UINT_MAX;
}
+ if (o->type == FIO_OPT_ULL) {
+ if (!o->maxval)
+ o->maxval = ULLONG_MAX;
+ }
if (o->type == FIO_OPT_STR_SET && o->def && !o->no_warn_def) {
log_err("Option %s: string set option with"
" default will always be true\n", o->name);
o->category = FIO_OPT_C_GENERAL;
o->group = FIO_OPT_G_INVALID;
}
- if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE ||
- o->type == FIO_OPT_STR_MULTI)
- return;
}
/*