use mkdir instead of mkdirat
[fio.git] / filesetup.c
index 4ceaef6b376716b2ffa0b77aa308e1d741e2c18a..0dd3809baf5fbe648cd55e5599eab2543a8d47f8 100644 (file)
@@ -15,7 +15,6 @@
 #include "os/os.h"
 #include "hash.h"
 #include "lib/axmap.h"
-#include "lib/memalign.h"
 
 #ifdef CONFIG_LINUX_FALLOCATE
 #include <linux/falloc.h>
@@ -147,8 +146,6 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
                flags |= O_CREAT;
        if (new_layout)
                flags |= O_TRUNC;
-       if (td->o.odirect)
-               flags |= OS_O_DIRECT;
 
 #ifdef WIN32
        flags |= _O_BINARY;
@@ -162,14 +159,8 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
                if (err == ENOENT && !td->o.allow_create)
                        log_err("fio: file creation disallowed by "
                                        "allow_file_create=0\n");
-               else {
-                       if (err == EINVAL && (flags & OS_O_DIRECT))
-                               log_err("fio: looks like your filesystem "
-                                       "does not support "
-                                       "direct=1/buffered=0\n");
-
+               else
                        td_verror(td, err, "open");
-               }
                return 1;
        }
 
@@ -196,17 +187,14 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
                }
        }
 
-       if (td->o.odirect && !OS_O_DIRECT && fio_set_directio(td, f))
-               goto err;
-
        left = f->real_file_size;
        bs = td->o.max_bs[DDIR_WRITE];
        if (bs > left)
                bs = left;
 
-       b = fio_memalign(page_size, bs);
+       b = malloc(bs);
        if (!b) {
-               td_verror(td, errno, "fio_memalign");
+               td_verror(td, errno, "malloc");
                goto err;
        }
 
@@ -259,14 +247,14 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
                        f->io_size = f->real_file_size;
        }
 
-       fio_memfree(b, bs);
+       free(b);
 done:
        return 0;
 err:
        close(f->fd);
        f->fd = -1;
        if (b)
-               fio_memfree(b, bs);
+               free(b);
        return 1;
 }
 
@@ -1354,6 +1342,7 @@ void close_and_free_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");
 
@@ -1373,13 +1362,19 @@ void close_and_free_files(struct thread_data *td)
                        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;
@@ -1493,7 +1488,10 @@ static struct fio_file *alloc_new_file(struct thread_data *td)
 {
        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;
@@ -1525,6 +1523,38 @@ bool exists_and_not_regfile(const char *filename)
        return true;
 }
 
+static int 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;
+               if (mkdir(path, 0600) && errno != EEXIST) {
+                       log_err("fio: failed to create dir (%s): %d\n",
+                               start, errno);
+                       return 1;
+               }
+               *end = FIO_OS_PATH_SEPARATOR;
+               end++;
+       }
+       td->flags |= TD_F_DIRS_CREATED;
+       return 0;
+}
+
 int add_file(struct thread_data *td, const char *fname, int numjob, int inc)
 {
        int cur_files = td->files_index;
@@ -1540,6 +1570,11 @@ int add_file(struct thread_data *td, const char *fname, int numjob, int inc)
 
        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))
@@ -1576,7 +1611,10 @@ int add_file(struct thread_data *td, const char *fname, int numjob, int inc)
        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);
 
@@ -1600,7 +1638,8 @@ int add_file(struct thread_data *td, const char *fname, int numjob, int inc)
        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++;
@@ -1723,7 +1762,7 @@ static int recurse_dir(struct thread_data *td, const char *dirname)
                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) {
@@ -1780,7 +1819,10 @@ void dup_files(struct thread_data *td, struct thread_data *org)
                __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);
 
@@ -1862,7 +1904,7 @@ void filesetup_mem_free(void)
 int fio_set_directio(struct thread_data *td, struct fio_file *f)
 {
 #ifdef FIO_OS_DIRECTIO
-       int ret = fio_set_odirect(f->fd);
+       int ret = fio_set_odirect(f);
 
        if (ret) {
                td_verror(td, ret, "fio_set_directio");
@@ -1880,6 +1922,7 @@ int fio_set_directio(struct thread_data *td, struct fio_file *f)
 
        return 0;
 #else
+       log_err("fio: direct IO is not supported on this host operating system\n");
        return -1;
 #endif
 }