]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
vol: Fix ntops to provide expected semantics
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 15 Jan 2011 16:07:19 +0000 (11:07 -0500)
committerDerrick Brashear <shadow@dementia.org>
Thu, 3 Feb 2011 20:02:25 +0000 (12:02 -0800)
nt_open() can be asked to open a file with a path containing
directory components that do not yet exist.  Modify nt_open()
to automatically create directories if necessary.

nt_read() and nt_pread() should not treat partial reads due
to reaching EOF as an error.  Instead, return the bytes read.

Reviewed-on: http://gerrit.openafs.org/3666
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
(cherry picked from commit 714b3ffb2258b316621415c2e81372dc48b4119d)

Change-Id: I4a4c8a4894aa25bec883154cb73d1ee24986ba15
Reviewed-on: http://gerrit.openafs.org/3828
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
src/vol/ntops.c

index 5ee3f2f4e208c0d70045b8211409e617e08bf31a..471307d55c3e08b1d1b2cef06738aab67f578c0c 100644 (file)
@@ -115,11 +115,44 @@ nt_open(char *name, int flags, int mode)
        break;
     }
 
+  retry:
     fh = CreateFile(name, nt_access, nt_share, NULL, nt_create, FandA, NULL);
-
     if (fh == INVALID_HANDLE_VALUE) {
-       fh = INVALID_FD;
-       errno = nterr_nt2unix(GetLastError(), EBADF);
+        DWORD gle = GetLastError();
+
+        if (gle == ERROR_PATH_NOT_FOUND) {
+            /*
+             * one or more of the directories in the path
+             * does not exist.  We must create them and
+             * try again to create the file.
+             */
+            char * p;
+
+            for (p=name; *p && *p != OS_DIRSEPC; p++);
+            while (*p == OS_DIRSEPC) p++;    /* ignore the first dirsep */
+            for (; *p; p++) {
+                if (*p == OS_DIRSEPC) {
+                    *p = '\0';
+                    if (CreateDirectory(name, NULL))
+                        gle = 0;
+                    else
+                        gle = GetLastError();
+                    *p = OS_DIRSEPC;
+                    if (gle != ERROR_SUCCESS &&
+                         gle != ERROR_ALREADY_EXISTS) {
+                        /* The directory creation failed. */
+                        fh = INVALID_FD;
+                        break;
+                    } else {
+                        while (*(p+1) == OS_DIRSEPC) p++;
+                    }
+                }
+            }
+
+            if (!*p) /* successful creation of the path */
+                goto retry;
+        }
+        errno = nterr_nt2unix(gle, EBADF);
     }
     return fh;
 }
@@ -186,8 +219,11 @@ nt_read(FD_t fd, char *buf, size_t size)
     code = ReadFile((HANDLE) fd, (void *)buf, (DWORD) size, &nbytes, NULL);
 
     if (!code) {
-       errno = nterr_nt2unix(GetLastError(), EBADF);
-       return -1;
+        DWORD gle = GetLastError();
+        if (gle != ERROR_HANDLE_EOF) {
+               errno = nterr_nt2unix(GetLastError(), EBADF);
+               return -1;
+        }
     }
     return (int)nbytes;
 }
@@ -213,8 +249,11 @@ nt_pread(FD_t fd, void * buf, size_t count, afs_foff_t offset)
     code = ReadFile((HANDLE) fd, (void *)buf, (DWORD) count, &nbytes, &overlap);
 
     if (!code) {
-       errno = nterr_nt2unix(GetLastError(), EBADF);
-       return -1;
+        DWORD gle = GetLastError();
+        if (gle != ERROR_HANDLE_EOF) {
+               errno = nterr_nt2unix(GetLastError(), EBADF);
+               return -1;
+        }
     }
     return (ssize_t)nbytes;
 }