td->verror[0] = '\0';
}
-static inline int native_fallocate(struct thread_data *td, struct fio_file *f)
+static int native_fallocate(struct thread_data *td, struct fio_file *f)
{
bool success;
!success ? "un": "");
if (success)
- return 0;
+ return false;
if (errno == ENOSYS)
dprint(FD_FILE, "native fallocate is not implemented\n");
- return -1;
+ return true;
}
static void fallocate_file(struct thread_data *td, struct fio_file *f)
{
- int r;
-
if (td->o.fill_device)
return;
switch (td->o.fallocate_mode) {
case FIO_FALLOCATE_NATIVE:
- r = native_fallocate(td, f);
- if (r != 0 && errno != ENOSYS)
- log_err("fio: native_fallocate call failed: %s\n",
- strerror(errno));
+ native_fallocate(td, f);
break;
case FIO_FALLOCATE_NONE:
break;
#ifdef CONFIG_POSIX_FALLOCATE
- case FIO_FALLOCATE_POSIX:
+ case FIO_FALLOCATE_POSIX: {
+ int r;
+
dprint(FD_FILE, "posix_fallocate file %s size %llu\n",
f->file_name,
(unsigned long long) f->real_file_size);
if (r > 0)
log_err("fio: posix_fallocate fails: %s\n", strerror(r));
break;
+ }
#endif /* CONFIG_POSIX_FALLOCATE */
#ifdef CONFIG_LINUX_FALLOCATE
- case FIO_FALLOCATE_KEEP_SIZE:
+ case FIO_FALLOCATE_KEEP_SIZE: {
+ int r;
+
dprint(FD_FILE, "fallocate(FALLOC_FL_KEEP_SIZE) "
"file %s size %llu\n", f->file_name,
(unsigned long long) f->real_file_size);
td_verror(td, errno, "fallocate");
break;
+ }
#endif /* CONFIG_LINUX_FALLOCATE */
default:
log_err("fio: unknown fallocate mode: %d\n", td->o.fallocate_mode);
return 1;
}
-static int pre_read_file(struct thread_data *td, struct fio_file *f)
+static bool pre_read_file(struct thread_data *td, struct fio_file *f)
{
- int ret = 0, r, did_open = 0, old_runstate;
+ int r, did_open = 0, old_runstate;
unsigned long long left;
unsigned int bs;
+ bool ret = true;
char *b;
if (td_ioengine_flagged(td, FIO_PIPEIO) ||
td_ioengine_flagged(td, FIO_NOIO))
- return 0;
+ return true;
if (f->filetype == FIO_TYPE_CHAR)
- return 0;
+ return true;
if (!fio_file_open(f)) {
if (td->io_ops->open_file(td, f)) {
log_err("fio: cannot pre-read, failed to open file\n");
- return 1;
+ return false;
}
did_open = 1;
}
b = malloc(bs);
if (!b) {
td_verror(td, errno, "malloc");
- ret = 1;
+ ret = false;
goto error;
}
memset(b, 0, bs);
if (lseek(f->fd, f->file_offset, SEEK_SET) < 0) {
td_verror(td, errno, "lseek");
log_err("fio: failed to lseek pre-read file\n");
- ret = 1;
+ ret = false;
goto error;
}
if (o->start_offset_percent > 0) {
/*
- * if blockalign is provided, find the min across read, write,
- * and trim
+ * if offset_align is provided, set initial offset
*/
- if (fio_option_is_set(o, ba)) {
- align_bs = (unsigned long long) min(o->ba[DDIR_READ], o->ba[DDIR_WRITE]);
- align_bs = min((unsigned long long) o->ba[DDIR_TRIM], align_bs);
+ if (fio_option_is_set(o, start_offset_align)) {
+ align_bs = o->start_offset_align;
} else {
/* else take the minimum block size */
align_bs = td_min_bs(td);
return 1;
}
-int pre_read_files(struct thread_data *td)
+bool pre_read_files(struct thread_data *td)
{
struct fio_file *f;
unsigned int i;
dprint(FD_FILE, "pre_read files\n");
for_each_file(td, f, i) {
- if (pre_read_file(td, f))
- return -1;
+ if (!pre_read_file(td, f))
+ return false;
}
- return 0;
+ return true;
}
-static int __init_rand_distribution(struct thread_data *td, struct fio_file *f)
+static void __init_rand_distribution(struct thread_data *td, struct fio_file *f)
{
unsigned int range_size, seed;
unsigned long nranges;
pareto_init(&f->zipf, nranges, td->o.pareto_h.u.f, seed);
else if (td->o.random_distribution == FIO_RAND_DIST_GAUSS)
gauss_init(&f->gauss, nranges, td->o.gauss_dev.u.f, seed);
-
- return 1;
}
-static int init_rand_distribution(struct thread_data *td)
+static bool init_rand_distribution(struct thread_data *td)
{
struct fio_file *f;
unsigned int i;
int state;
if (td->o.random_distribution == FIO_RAND_DIST_RANDOM)
- return 0;
+ return false;
state = td_bump_runstate(td, TD_SETTING_UP);
__init_rand_distribution(td, f);
td_restore_runstate(td, state);
-
- return 1;
+ return true;
}
/*
return 0;
}
-int init_random_map(struct thread_data *td)
+bool init_random_map(struct thread_data *td)
{
unsigned long long blocks;
struct fio_file *f;
unsigned int i;
if (init_rand_distribution(td))
- return 0;
+ return true;
if (!td_random(td))
- return 0;
+ return true;
for_each_file(td, f, i) {
uint64_t fsize = min(f->real_file_size, f->io_size);
blocks = fsize / (unsigned long long) td->o.rw_min_bs;
if (check_rand_gen_limits(td, f, blocks))
- return 1;
+ return false;
if (td->o.random_generator == FIO_RAND_GEN_LFSR) {
unsigned long seed;
" a large number of jobs, try the 'norandommap'"
" option or set 'softrandommap'. Or give"
" a larger --alloc-size to fio.\n");
- return 1;
+ return false;
}
log_info("fio: file %s failed allocating random map. Running "
"job without.\n", f->file_name);
}
- return 0;
+ return true;
}
void close_files(struct thread_data *td)
{
struct fio_file *f;
unsigned int i;
+ bool use_free = td_ioengine_flagged(td, FIO_NOFILEHASH);
dprint(FD_FILE, "close files\n");
td_io_unlink_file(td, f);
}
- sfree(f->file_name);
+ if (use_free)
+ free(f->file_name);
+ else
+ sfree(f->file_name);
f->file_name = NULL;
if (fio_file_axmap(f)) {
axmap_free(f->io_axmap);
f->io_axmap = NULL;
}
- sfree(f);
+ if (use_free)
+ free(f);
+ else
+ sfree(f);
}
td->o.filename = NULL;
{
struct fio_file *f;
- f = smalloc(sizeof(*f));
+ if (td_ioengine_flagged(td, FIO_NOFILEHASH))
+ f = calloc(1, sizeof(*f));
+ else
+ f = smalloc(sizeof(*f));
if (!f) {
assert(0);
return NULL;
return true;
}
+static bool create_work_dirs(struct thread_data *td, const char *fname)
+{
+ char path[PATH_MAX];
+ char *start, *end;
+
+ if (td->o.directory) {
+ snprintf(path, PATH_MAX, "%s%c%s", td->o.directory,
+ FIO_OS_PATH_SEPARATOR, fname);
+ start = strstr(path, fname);
+ } else {
+ snprintf(path, PATH_MAX, "%s", fname);
+ start = path;
+ }
+
+ end = start;
+ while ((end = strchr(end, FIO_OS_PATH_SEPARATOR)) != NULL) {
+ if (end == start)
+ break;
+ *end = '\0';
+ errno = 0;
+#ifdef CONFIG_HAVE_MKDIR_TWO
+ if (mkdir(path, 0600) && errno != EEXIST) {
+#else
+ if (mkdir(path) && errno != EEXIST) {
+#endif
+ log_err("fio: failed to create dir (%s): %d\n",
+ start, errno);
+ return false;
+ }
+ *end = FIO_OS_PATH_SEPARATOR;
+ end++;
+ }
+ td->flags |= TD_F_DIRS_CREATED;
+ return true;
+}
+
int add_file(struct thread_data *td, const char *fname, int numjob, int inc)
{
int cur_files = td->files_index;
sprintf(file_name + len, "%s", fname);
+ if (strchr(fname, FIO_OS_PATH_SEPARATOR) &&
+ !(td->flags & TD_F_DIRS_CREATED) &&
+ !create_work_dirs(td, fname))
+ return 1;
+
/* clean cloned siblings using existing files */
if (numjob && is_already_allocated(file_name) &&
!exists_and_not_regfile(fname))
if (td->io_ops && td_ioengine_flagged(td, FIO_DISKLESSIO))
f->real_file_size = -1ULL;
- f->file_name = smalloc_strdup(file_name);
+ if (td_ioengine_flagged(td, FIO_NOFILEHASH))
+ f->file_name = strdup(file_name);
+ else
+ f->file_name = smalloc_strdup(file_name);
if (!f->file_name)
assert(0);
if (f->filetype == FIO_TYPE_FILE)
td->nr_normal_files++;
- set_already_allocated(file_name);
+ if (td->o.numjobs > 1)
+ set_already_allocated(file_name);
if (inc)
td->o.nr_files++;
unlock_file(td, f);
}
-static int recurse_dir(struct thread_data *td, const char *dirname)
+static bool recurse_dir(struct thread_data *td, const char *dirname)
{
struct dirent *dir;
- int ret = 0;
+ bool ret = false;
DIR *D;
D = opendir(dirname);
snprintf(buf, FIO_VERROR_SIZE, "opendir(%s)", dirname);
td_verror(td, errno, buf);
- return 1;
+ return true;
}
while ((dir = readdir(D)) != NULL) {
if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))
continue;
- sprintf(full_path, "%s%s%s", dirname, FIO_OS_PATH_SEPARATOR, dir->d_name);
+ sprintf(full_path, "%s%c%s", dirname, FIO_OS_PATH_SEPARATOR, dir->d_name);
if (lstat(full_path, &sb) == -1) {
if (errno != ENOENT) {
td_verror(td, errno, "stat");
- ret = 1;
+ ret = true;
break;
}
}
__f = alloc_new_file(td);
if (f->file_name) {
- __f->file_name = smalloc_strdup(f->file_name);
+ if (td_ioengine_flagged(td, FIO_NOFILEHASH))
+ __f->file_name = strdup(f->file_name);
+ else
+ __f->file_name = smalloc_strdup(f->file_name);
if (!__f->file_name)
assert(0);
return 0;
#else
+ log_err("fio: direct IO is not supported on this host operating system\n");
return -1;
#endif
}