static int str_exitall_cb(void)
{
- exitall_on_terminate = 1;
+ exitall_on_terminate = true;
return 0;
}
const long max_cpu = cpus_online();
cpus_in_mask = fio_cpu_count(mask);
+ if (!cpus_in_mask)
+ return 0;
+
cpu_index = cpu_index % cpus_in_mask;
index = 0;
return 0;
}
-static void __td_zone_gen_index(struct thread_data *td, enum fio_ddir ddir)
-{
- unsigned int i, j, sprev, aprev;
- uint64_t sprev_sz;
-
- td->zone_state_index[ddir] = malloc(sizeof(struct zone_split_index) * 100);
-
- sprev_sz = sprev = aprev = 0;
- for (i = 0; i < td->o.zone_split_nr[ddir]; i++) {
- struct zone_split *zsp = &td->o.zone_split[ddir][i];
-
- for (j = aprev; j < aprev + zsp->access_perc; j++) {
- struct zone_split_index *zsi = &td->zone_state_index[ddir][j];
-
- zsi->size_perc = sprev + zsp->size_perc;
- zsi->size_perc_prev = sprev;
-
- zsi->size = sprev_sz + zsp->size;
- zsi->size_prev = sprev_sz;
- }
-
- aprev += zsp->access_perc;
- sprev += zsp->size_perc;
- sprev_sz += zsp->size;
- }
-}
-
-/*
- * Generate state table for indexes, so we don't have to do it inline from
- * the hot IO path
- */
-static void td_zone_gen_index(struct thread_data *td)
-{
- int i;
-
- td->zone_state_index = malloc(DDIR_RWDIR_CNT *
- sizeof(struct zone_split_index *));
-
- for (i = 0; i < DDIR_RWDIR_CNT; i++)
- __td_zone_gen_index(td, i);
-}
-
static int parse_zoned_distribution(struct thread_data *td, const char *input,
bool absolute)
{
return ret;
}
- if (!ret)
- td_zone_gen_index(td);
- else {
+ if (ret) {
for (i = 0; i < DDIR_RWDIR_CNT; i++)
td->o.zone_split_nr[i] = 0;
}
* is escaped with a '\', then that ':' is part of the filename and does not
* indicate a new file.
*/
-static char *get_next_name(char **ptr)
+char *get_next_str(char **ptr)
{
char *str = *ptr;
char *p, *start;
}
-static int get_max_name_idx(char *input)
+int get_max_str_idx(char *input)
{
unsigned int cur_idx;
char *str, *p;
p = str = strdup(input);
for (cur_idx = 0; ; cur_idx++)
- if (get_next_name(&str) == NULL)
+ if (get_next_str(&str) == NULL)
break;
free(p);
p = str = strdup(input);
- index %= get_max_name_idx(input);
+ index %= get_max_str_idx(input);
for (cur_idx = 0; cur_idx <= index; cur_idx++)
- fname = get_next_name(&str);
+ fname = get_next_str(&str);
if (client_sockaddr_str[0] && unique_filename) {
len = snprintf(target, tlen, "%s/%s.", fname,
return len;
}
+char* get_name_by_idx(char *input, int index)
+{
+ unsigned int cur_idx;
+ char *fname, *str, *p;
+
+ p = str = strdup(input);
+
+ index %= get_max_str_idx(input);
+ for (cur_idx = 0; cur_idx <= index; cur_idx++)
+ fname = get_next_str(&str);
+
+ fname = strdup(fname);
+ free(p);
+
+ return fname;
+}
+
static int str_filename_cb(void *data, const char *input)
{
struct thread_data *td = cb_data_to_td(data);
if (!td->files_index)
td->o.nr_files = 0;
- while ((fname = get_next_name(&str)) != NULL) {
+ while ((fname = get_next_str(&str)) != NULL) {
if (!strlen(fname))
break;
add_file(td, fname, 0, 1);
return 0;
p = str = strdup(td->o.directory);
- while ((dirname = get_next_name(&str)) != NULL) {
+ while ((dirname = get_next_str(&str)) != NULL) {
if (lstat(dirname, &sb) < 0) {
ret = errno;
.help = "Linux native asynchronous IO",
},
#endif
+#ifdef ARCH_HAVE_IOURING
+ { .ival = "io_uring",
+ .help = "Fast Linux native aio",
+ },
+#endif
#ifdef CONFIG_POSIXAIO
{ .ival = "posixaio",
.help = "POSIX asynchronous IO",
.help = "RDMA IO engine",
},
#endif
-#ifdef CONFIG_FUSION_AW
- { .ival = "fusion-aw-sync",
- .help = "Fusion-io atomic write engine",
- },
-#endif
#ifdef CONFIG_LINUX_EXT4_MOVE_EXTENT
{ .ival = "e4defrag",
.help = "ext4 defrag engine",
},
#endif
+#ifdef CONFIG_IME
+ { .ival = "ime_psync",
+ .help = "DDN's IME synchronous IO engine",
+ },
+ { .ival = "ime_psyncv",
+ .help = "DDN's IME synchronous IO engine using iovecs",
+ },
+ { .ival = "ime_aio",
+ .help = "DDN's IME asynchronous IO engine",
+ },
+#endif
#ifdef CONFIG_LINUX_DEVDAX
{ .ival = "dev-dax",
.help = "DAX Device based IO engine",
.help = "PMDK libpmem based IO engine",
},
#endif
+#ifdef CONFIG_HTTP
+ { .ival = "http",
+ .help = "HTTP (WebDAV/S3) IO engine",
+ },
+#endif
+ { .ival = "nbd",
+ .help = "Network Block Device (NBD) IO engine"
+ },
},
},
{
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_RANDOM,
},
- {
- .name = "use_os_rand",
- .lname = "Use OS random",
- .type = FIO_OPT_DEPRECATED,
- .off1 = offsetof(struct thread_options, dep_use_os_rand),
- .category = FIO_OPT_C_IO,
- .group = FIO_OPT_G_RANDOM,
- },
{
.name = "norandommap",
.lname = "No randommap",
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_IOLOG,
},
+ {
+ .name = "read_iolog_chunked",
+ .lname = "Read I/O log in parts",
+ .type = FIO_OPT_BOOL,
+ .off1 = offsetof(struct thread_options, read_iolog_chunked),
+ .def = "0",
+ .parent = "read_iolog",
+ .help = "Parse IO pattern in chunks",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_IOLOG,
+ },
{
.name = "replay_no_stall",
.lname = "Don't stall on replay",
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_IOLOG,
},
+ {
+ .name = "merge_blktrace_file",
+ .lname = "Merged blktrace output filename",
+ .type = FIO_OPT_STR_STORE,
+ .off1 = offsetof(struct thread_options, merge_blktrace_file),
+ .help = "Merged blktrace output filename",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_IOLOG,
+ },
+ {
+ .name = "merge_blktrace_scalars",
+ .lname = "Percentage to scale each trace",
+ .type = FIO_OPT_FLOAT_LIST,
+ .off1 = offsetof(struct thread_options, merge_blktrace_scalars),
+ .maxlen = FIO_IO_U_LIST_MAX_LEN,
+ .help = "Percentage to scale each trace",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_IOLOG,
+ },
+ {
+ .name = "merge_blktrace_iters",
+ .lname = "Number of iterations to run per trace",
+ .type = FIO_OPT_FLOAT_LIST,
+ .off1 = offsetof(struct thread_options, merge_blktrace_iters),
+ .maxlen = FIO_IO_U_LIST_MAX_LEN,
+ .help = "Number of iterations to run per trace",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_IOLOG,
+ },
{
.name = "exec_prerun",
.lname = "Pre-execute runnable",
.help = "Your platform does not support IO scheduler switching",
},
#endif
+ {
+ .name = "zonemode",
+ .lname = "Zone mode",
+ .help = "Mode for the zonesize, zonerange and zoneskip parameters",
+ .type = FIO_OPT_STR,
+ .off1 = offsetof(struct thread_options, zone_mode),
+ .def = "none",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_ZONE,
+ .posval = {
+ { .ival = "none",
+ .oval = ZONE_MODE_NONE,
+ .help = "no zoning",
+ },
+ { .ival = "strided",
+ .oval = ZONE_MODE_STRIDED,
+ .help = "strided mode - random I/O is restricted to a single zone",
+ },
+ { .ival = "zbd",
+ .oval = ZONE_MODE_ZBD,
+ .help = "zoned block device mode - random I/O selects one of multiple zones randomly",
+ },
+ },
+ },
{
.name = "zonesize",
.lname = "Zone size",
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_ZONE,
},
+ {
+ .name = "read_beyond_wp",
+ .lname = "Allow reads beyond the zone write pointer",
+ .type = FIO_OPT_BOOL,
+ .off1 = offsetof(struct thread_options, read_beyond_wp),
+ .help = "Allow reads beyond the zone write pointer",
+ .def = "0",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_INVALID,
+ },
+ {
+ .name = "max_open_zones",
+ .lname = "Maximum number of open zones",
+ .type = FIO_OPT_INT,
+ .off1 = offsetof(struct thread_options, max_open_zones),
+ .maxval = FIO_MAX_OPEN_ZBD_ZONES,
+ .help = "Limit random writes to SMR drives to the specified"
+ " number of sequential zones",
+ .def = "0",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_INVALID,
+ },
+ {
+ .name = "zone_reset_threshold",
+ .lname = "Zone reset threshold",
+ .help = "Zoned block device reset threshold",
+ .type = FIO_OPT_FLOAT_LIST,
+ .maxlen = 1,
+ .off1 = offsetof(struct thread_options, zrt),
+ .minfp = 0,
+ .maxfp = 1,
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_ZONE,
+ },
+ {
+ .name = "zone_reset_frequency",
+ .lname = "Zone reset frequency",
+ .help = "Zoned block device zone reset frequency in HZ",
+ .type = FIO_OPT_FLOAT_LIST,
+ .maxlen = 1,
+ .off1 = offsetof(struct thread_options, zrf),
+ .minfp = 0,
+ .maxfp = 1,
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_ZONE,
+ },
{
.name = "lockmem",
.lname = "Lock memory",
{
.name = "kb_base",
.lname = "KB Base",
- .type = FIO_OPT_INT,
+ .type = FIO_OPT_STR,
.off1 = offsetof(struct thread_options, kb_base),
.prio = 1,
.def = "1024",
{
.name = "unit_base",
.lname = "Unit for quantities of data (Bits or Bytes)",
- .type = FIO_OPT_INT,
+ .type = FIO_OPT_STR,
.off1 = offsetof(struct thread_options, unit_base),
.prio = 1,
.posval = {