create subdirs if specified in the filename_format
authorJosef Bacik <jbacik@fb.com>
Wed, 11 Oct 2017 18:58:12 +0000 (14:58 -0400)
committerJens Axboe <axboe@kernel.dk>
Wed, 11 Oct 2017 19:03:11 +0000 (13:03 -0600)
Currently there's no way for a user to specify a directory that doesn't
exist yet for a job.  Fix this by looking for paths in the file name
provided by the job and creating any subdirectories that may be
required.

Signed-off-by: Josef Bacik <jbacik@fb.com>
Removed TD_ENG_FLAG_SHIFT change, not needed.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
filesetup.c
fio.h

index a7bbcede08d199cb7660a2771f4b715600ca8af3..b390caa295263e1327d56cc250dee84485edf46a 100644 (file)
@@ -1523,6 +1523,45 @@ bool exists_and_not_regfile(const char *filename)
        return true;
 }
 
+static void create_work_dirs(struct thread_data *td, const char *fname)
+{
+       char path[PATH_MAX];
+       char *start, *end;
+       int dirfd;
+       bool need_close = true;
+
+       if (td->o.directory) {
+               dirfd = open(td->o.directory, O_DIRECTORY | O_RDONLY);
+               if (dirfd < 0) {
+                       log_err("fio: failed to open dir (%s): %d\n",
+                               td->o.directory, errno);
+                       assert(0);
+               }
+       } else {
+               dirfd = AT_FDCWD;
+               need_close = false;
+       }
+
+       memcpy(path, fname, PATH_MAX);
+       start = end = path;
+       while ((end = strchr(end, FIO_OS_PATH_SEPARATOR)) != NULL) {
+               if (end == start)
+                       break;
+               *end = '\0';
+               errno = 0;
+               if (mkdirat(dirfd, start, 0600) && errno != EEXIST) {
+                       log_err("fio: failed to create dir (%s): %d\n",
+                               start, errno);
+                       assert(0);
+               }
+               *end = FIO_OS_PATH_SEPARATOR;
+               end++;
+       }
+       if (need_close)
+               close(dirfd);
+       td->flags |= TD_F_DIRS_CREATED;
+}
+
 int add_file(struct thread_data *td, const char *fname, int numjob, int inc)
 {
        int cur_files = td->files_index;
@@ -1538,6 +1577,10 @@ 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);
+
        /* clean cloned siblings using existing files */
        if (numjob && is_already_allocated(file_name) &&
            !exists_and_not_regfile(fname))
diff --git a/fio.h b/fio.h
index 28d064cfe868b43ba0bf56e3bcecbcec082807be..4809b99ae44ce6001caca81bc996e5d8708b47ab 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -87,6 +87,7 @@ enum {
        __TD_F_NO_PROGRESS,
        __TD_F_REGROW_LOGS,
        __TD_F_MMAP_KEEP,
+       __TD_F_DIRS_CREATED,
        __TD_F_LAST,            /* not a real bit, keep last */
 };
 
@@ -106,6 +107,7 @@ enum {
        TD_F_NO_PROGRESS        = 1U << __TD_F_NO_PROGRESS,
        TD_F_REGROW_LOGS        = 1U << __TD_F_REGROW_LOGS,
        TD_F_MMAP_KEEP          = 1U << __TD_F_MMAP_KEEP,
+       TD_F_DIRS_CREATED       = 1U << __TD_F_DIRS_CREATED,
 };
 
 enum {