static const struct pattern_fmt_desc fmt_desc[] = {
{
.fmt = "%o",
- .len = FIELD_SIZE(struct io_u *, offset),
+ .len = FIO_FIELD_SIZE(struct io_u *, offset),
.paste = paste_blockoff
},
{ }
return strdup(p);
}
+static bool split_parse_distr(const char *str, double *val, double *center)
+{
+ char *cp, *p;
+ bool r;
+
+ p = strdup(str);
+ if (!p)
+ return false;
+
+ cp = strstr(p, ":");
+ r = true;
+ if (cp) {
+ *cp = '\0';
+ cp++;
+ r = str_to_float(cp, center, 0);
+ }
+ r = r && str_to_float(p, val, 0);
+ free(p);
+ return r;
+}
+
static int bs_cmp(const void *p1, const void *p2)
{
const struct bssplit *bsp1 = p1;
{
struct thread_data *td = cb_data_to_td(data);
double val;
+ double center = -1;
bool done = false;
char *nr;
return 0;
nr = get_opt_postfix(str);
- if (nr && !str_to_float(nr, &val, 0)) {
+ if (nr && !split_parse_distr(nr, &val, ¢er)) {
log_err("fio: file service type random postfix parsing failed\n");
free(nr);
return 1;
free(nr);
+ if (center != -1 && (center < 0.00 || center > 1.00)) {
+ log_err("fio: distribution center out of range (0 <= center <= 1.0)\n");
+ return 1;
+ }
+ td->random_center = center;
+
switch (td->o.file_service_type) {
case FIO_FSERVICE_ZIPF:
if (val == 1.00) {
{
struct thread_data *td = cb_data_to_td(data);
double val;
+ double center = -1;
char *nr;
if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
return 0;
nr = get_opt_postfix(str);
- if (nr && !str_to_float(nr, &val, 0)) {
+ if (nr && !split_parse_distr(nr, &val, ¢er)) {
log_err("fio: random postfix parsing failed\n");
free(nr);
return 1;
free(nr);
+ if (center != -1 && (center < 0.00 || center > 1.00)) {
+ log_err("fio: distribution center out of range (0 <= center <= 1.0)\n");
+ return 1;
+ }
+ td->o.random_center.u.f = center;
+
if (td->o.random_distribution == FIO_RAND_DIST_ZIPF) {
if (val == 1.00) {
log_err("fio: zipf theta must different than 1.0\n");
struct thread_data *td = cb_data_to_td(data);
int ret;
- td->o.verify_fmt_sz = ARRAY_SIZE(td->o.verify_fmt);
+ td->o.verify_fmt_sz = FIO_ARRAY_SIZE(td->o.verify_fmt);
ret = parse_and_fill_pattern(input, strlen(input), td->o.verify_pattern,
MAX_PATTERN_SIZE, fmt_desc,
td->o.verify_fmt, &td->o.verify_fmt_sz);
return 0;
}
+static int str_io_size_cb(void *data, unsigned long long *__val)
+{
+ struct thread_data *td = cb_data_to_td(data);
+ unsigned long long v = *__val;
+
+ if (parse_is_percent_uncapped(v)) {
+ td->o.io_size = 0;
+ td->o.io_size_percent = -1ULL - v;
+ if (td->o.io_size_percent > 100) {
+ log_err("fio: io_size values greater than 100%% aren't supported\n");
+ return 1;
+ }
+ dprint(FD_PARSE, "SET io_size_percent %d\n",
+ td->o.io_size_percent);
+ } else
+ td->o.io_size = v;
+
+ return 0;
+}
+
static int str_write_bw_log_cb(void *data, const char *str)
{
struct thread_data *td = cb_data_to_td(data);
.lname = "Filename(s)",
.type = FIO_OPT_STR_STORE,
.off1 = offsetof(struct thread_options, filename),
+ .maxlen = PATH_MAX,
.cb = str_filename_cb,
.prio = -1, /* must come after "directory" */
.help = "File(s) to use for the workload",
{ .ival = "cpuio",
.help = "CPU cycle burner engine",
},
-#ifdef CONFIG_GUASI
- { .ival = "guasi",
- .help = "GUASI IO engine",
- },
-#endif
#ifdef CONFIG_RDMA
{ .ival = "rdma",
.help = "RDMA IO engine",
.alias = "io_limit",
.lname = "IO Size",
.type = FIO_OPT_STR_VAL,
+ .cb = str_io_size_cb,
.off1 = offsetof(struct thread_options, io_size),
.help = "Total size of I/O to be performed",
.interval = 1024 * 1024,
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_ZONE,
},
+ {
+ .name = "zonecapacity",
+ .lname = "Zone capacity",
+ .type = FIO_OPT_STR_VAL,
+ .off1 = offsetof(struct thread_options, zone_capacity),
+ .help = "Capacity per zone",
+ .def = "0",
+ .interval = 1024 * 1024,
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_ZONE,
+ },
{
.name = "zonerange",
.lname = "Zone range",
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_THINKTIME,
},
+ {
+ .name = "thinktime_blocks_type",
+ .lname = "Thinktime blocks type",
+ .type = FIO_OPT_STR,
+ .off1 = offsetof(struct thread_options, thinktime_blocks_type),
+ .help = "How thinktime_blocks takes effect",
+ .def = "complete",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_THINKTIME,
+ .posval = {
+ { .ival = "complete",
+ .oval = THINKTIME_BLOCKS_TYPE_COMPLETE,
+ .help = "thinktime_blocks takes effect at the completion side",
+ },
+ {
+ .ival = "issue",
+ .oval = THINKTIME_BLOCKS_TYPE_ISSUE,
+ .help = "thinktime_blocks takes effect at the issue side",
+ },
+ },
+ .parent = "thinktime",
+ },
{
.name = "rate",
.lname = "I/O rate",
{
.name = "sync",
.lname = "Synchronous I/O",
- .type = FIO_OPT_BOOL,
+ .type = FIO_OPT_STR,
.off1 = offsetof(struct thread_options, sync_io),
- .help = "Use O_SYNC for buffered writes",
- .def = "0",
- .parent = "buffered",
+ .help = "Use synchronous write IO",
+ .def = "none",
.hide = 1,
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_IO_TYPE,
+ .posval = {
+ { .ival = "none",
+ .oval = 0,
+ },
+ { .ival = "0",
+ .oval = 0,
+ },
+ { .ival = "sync",
+ .oval = O_SYNC,
+ },
+ { .ival = "1",
+ .oval = O_SYNC,
+ },
+#ifdef O_DSYNC
+ { .ival = "dsync",
+ .oval = O_DSYNC,
+ },
+#endif
+ },
},
#ifdef FIO_HAVE_WRITE_HINT
{
.parent = "flow_id",
.hide = 1,
.def = "0",
+ .maxval = FLOW_MAX_WEIGHT,
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_IO_FLOW,
},
{
.name = "flow_watermark",
.lname = "I/O flow watermark",
- .type = FIO_OPT_INT,
- .off1 = offsetof(struct thread_options, flow_watermark),
- .help = "High watermark for flow control. This option"
- " should be set to the same value for all threads"
- " with non-zero flow.",
- .parent = "flow_id",
- .hide = 1,
- .def = "1024",
+ .type = FIO_OPT_SOFT_DEPRECATED,
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_IO_FLOW,
},
struct fio_keyword *kw = &fio_keywords[i];
while ((s = strstr(opt, kw->word)) != NULL) {
- char *new = malloc(strlen(opt) + 1);
+ char *new = calloc(strlen(opt) + 1, 1);
char *o_org = opt;
int olen = s - opt;
int len;
* If there's more in the original string, copy that
* in too
*/
- opt += strlen(kw->word) + olen;
+ opt += olen + strlen(kw->word);
+ /* keeps final zero thanks to calloc */
if (strlen(opt))
- memcpy(new + olen + len, opt, opt - o_org - 1);
+ memcpy(new + olen + len, opt, strlen(opt));
/*
* replace opt and free the old opt