filesetup: fix win raw disk access and improve dir creation failure msg
[fio.git] / filesetup.c
index ed3646a4bbe75e598e556970084bcb328c30fa3e..8a4091fcc25420325f6bb1779dfffa0853f8ee2e 100644 (file)
@@ -913,33 +913,71 @@ uint64_t get_start_offset(struct thread_data *td, struct fio_file *f)
        return offset;
 }
 
+/*
+ * Find longest path component that exists and return its length
+ */
+int longest_existing_path(char *path) {
+       char buf[PATH_MAX];
+       bool done;
+       char *buf_pos;
+       int offset;
+#ifdef WIN32
+       DWORD dwAttr;
+#else
+       struct stat sb;
+#endif
+
+       sprintf(buf, "%s", path);
+       done = false;
+       while (!done) {
+               buf_pos = strrchr(buf, FIO_OS_PATH_SEPARATOR);
+               if (!buf_pos) {
+                       done = true;
+                       offset = 0;
+                       break;
+               }
+
+               *(buf_pos + 1) = '\0';
+
+#ifdef WIN32
+               dwAttr = GetFileAttributesA(buf);
+               if (dwAttr != INVALID_FILE_ATTRIBUTES) {
+                       done = true;
+               }
+#else
+               if (stat(buf, &sb) == 0)
+                       done = true;
+#endif
+               if (done)
+                       offset = buf_pos - buf;
+               else
+                       *buf_pos = '\0';
+       }
+
+       return offset;
+}
+
 static bool create_work_dirs(struct thread_data *td, const char *fname)
 {
        char path[PATH_MAX];
        char *start, *end;
+       int offset;
 
-       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;
-       }
+       snprintf(path, PATH_MAX, "%s", fname);
+       start = path;
 
-       end = start;
+       offset = longest_existing_path(path);
+       end = start + offset;
        while ((end = strchr(end, FIO_OS_PATH_SEPARATOR)) != NULL) {
-               if (end == start)
-                       break;
+               if (end == start) {
+                       end++;
+                       continue;
+               }
                *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);
+               if (fio_mkdir(path, 0700) && errno != EEXIST) {
+                       log_err("fio: failed to create dir (%s): %s\n",
+                               start, strerror(errno));
                        return false;
                }
                *end = FIO_OS_PATH_SEPARATOR;