Merge branch 'fix-win-raw' of https://github.com/sitsofe/fio
authorJens Axboe <axboe@kernel.dk>
Sun, 1 Mar 2020 22:42:48 +0000 (15:42 -0700)
committerJens Axboe <axboe@kernel.dk>
Sun, 1 Mar 2020 22:42:48 +0000 (15:42 -0700)
* 'fix-win-raw' of https://github.com/sitsofe/fio:
  filesetup: fix win raw disk access and improve dir creation failure msg

filesetup.c
os/os-windows.h

index b45a58265a140700bfb96b4e6dd0930e4ed1a6c2..8a4091fcc25420325f6bb1779dfffa0853f8ee2e 100644 (file)
@@ -913,15 +913,61 @@ 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;
 
        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) {
                        end++;
@@ -930,8 +976,8 @@ static bool create_work_dirs(struct thread_data *td, const char *fname)
                *end = '\0';
                errno = 0;
                if (fio_mkdir(path, 0700) && errno != EEXIST) {
-                       log_err("fio: failed to create dir (%s): %d\n",
-                               start, errno);
+                       log_err("fio: failed to create dir (%s): %s\n",
+                               start, strerror(errno));
                        return false;
                }
                *end = FIO_OS_PATH_SEPARATOR;
index 6d48ffe81819e9e6bd91476acc80c32525aa3b7a..fa2955f98659c84a539e26268bdb5a6673fb31ee 100644 (file)
@@ -203,7 +203,11 @@ static inline int fio_mkdir(const char *path, mode_t mode) {
        }
 
        if (CreateDirectoryA(path, NULL) == 0) {
-               log_err("CreateDirectoryA = %d\n", GetLastError());
+               /* Ignore errors if path is a device namespace */
+               if (strcmp(path, "\\\\.") == 0) {
+                       errno = EEXIST;
+                       return -1;
+               }
                errno = win_to_posix_error(GetLastError());
                return -1;
        }