namei: Abstract out OGM functions a bit more
[openafs.git] / src / vol / namei_ops.c
index 62191d9..a02600d 100644 (file)
@@ -29,7 +29,6 @@
 #include <direct.h>
 #endif
 
-#include <afs/afs_assert.h>
 #include <lock.h>
 #include <afs/afsutil.h>
 #include <lwp.h>
@@ -78,7 +77,10 @@ namei_iread(IHandle_t * h, afs_foff_t offset, char *buf, afs_fsize_t size)
        return -1;
 
     nBytes = FDH_PREAD(fdP, buf, size, offset);
-    FDH_CLOSE(fdP);
+    if (nBytes < 0)
+       FDH_REALLYCLOSE(fdP);
+    else
+       FDH_CLOSE(fdP);
     return nBytes;
 }
 
@@ -93,7 +95,10 @@ namei_iwrite(IHandle_t * h, afs_foff_t offset, char *buf, afs_fsize_t size)
        return -1;
 
     nBytes = FDH_PWRITE(fdP, buf, size, offset);
-    FDH_CLOSE(fdP);
+    if (nBytes < 0)
+       FDH_REALLYCLOSE(fdP);
+    else
+       FDH_CLOSE(fdP);
     return nBytes;
 }
 
@@ -613,23 +618,48 @@ SetOGM(FD_t fd, int parm, int tag)
 }
 
 static int
-CheckOGM(namei_t *name, FdHandle_t *fdP, int p1)
+SetWinOGM(FD_t fd, int p1, int p2)
 {
-    WIN32_FIND_DATA info;
-    HANDLE dirH;
+    BOOL code;
+    FILETIME ftime;
+
+    ftime.dwHighDateTime = p1;
+    ftime.dwLowDateTime = p2;
+
+    code = SetFileTime(fd, &ftime, NULL /*access*/, NULL /*write*/);
+    if (!code)
+       return -1;
+    return 0;
+}
+
+static int
+GetWinOGM(FD_t fd, int *p1, int *p2)
+{
+    BOOL code;
+    FILETIME ftime;
+
+    code = GetFileTime(fd, &ftime, NULL /*access*/, NULL /*write*/);
+    if (!code)
+       return -1;
 
-    dirH =
-       FindFirstFileEx(name->n_path, FindExInfoStandard, &info,
-                       FindExSearchNameMatch, NULL,
-                       FIND_FIRST_EX_CASE_SENSITIVE);
+    *p1 = ftime.dwHighDateTime;
+    *p2 = ftime.dwLowDateTime;
 
-    if (!dirH)
-       return -1;          /* Can't get info, leave alone */
+    return 0;
+}
 
-    FindClose(dirH);
+static int
+CheckOGM(FdHandle_t *fdP, int p1)
+{
+    int ogm_p1, ogm_p2;
 
-    if (info.ftCreationTime.dwHighDateTime != (unsigned int)p1)
+    if (GetWinOGM(fdP->fd_fd, &ogm_p1, &ogm_p2)) {
        return -1;
+    }
+
+    if (ogm_p1 != p1) {
+       return -1;
+    }
 
     return 0;
 }
@@ -667,14 +697,22 @@ GetOGMFromStat(struct afs_stat_st *status, int *parm, int *tag)
 }
 
 static int
-CheckOGM(namei_t *name, FdHandle_t *fdP, int p1)
+GetOGM(FdHandle_t *fdP, int *parm, int *tag)
 {
     struct afs_stat_st status;
-    int parm, tag;
     if (afs_fstat(fdP->fd_fd, &status) < 0)
        return -1;
+    GetOGMFromStat(&status, parm, tag);
+    return 0;
+}
 
-    GetOGMFromStat(&status, &parm, &tag);
+static int
+CheckOGM(FdHandle_t *fdP, int p1)
+{
+    int parm, tag;
+
+    if (GetOGM(fdP, &parm, &tag) < 0)
+       return -1;
     if (parm != p1)
        return -1;
 
@@ -699,7 +737,7 @@ namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint
     FdHandle_t *fdP;
     FdHandle_t tfd;
     int type, tag;
-    FILETIME ftime;
+    int ogm_p1, ogm_p2;
     char *p;
     b32_string_t str1;
 
@@ -719,8 +757,8 @@ namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint
         * p3 - type
         * p4 - parent volume id
         */
-        ftime.dwHighDateTime = p1;
-        ftime.dwLowDateTime = p2;
+        ogm_p1 = p1;
+        ogm_p2 = p2;
        type = p3;
        tmp.ih_vid = p4;        /* Use parent volume id, where this file will be. */
        tmp.ih_ino = namei_MakeSpecIno(p1, p3);
@@ -741,8 +779,8 @@ namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint
 
        tmp.ih_vid = p1;
        tmp.ih_ino = (Inode) p2;
-       ftime.dwHighDateTime = p3;
-        ftime.dwLowDateTime = p4;
+       ogm_p1 = p3;
+        ogm_p2 = p4;
     }
 
     namei_HandleToName(&name, &tmp);
@@ -750,11 +788,11 @@ namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint
     p++;
     for (tag = 0; tag < NAMEI_MAXVOLS; tag++) {
         *p = *int_to_base32(str1, tag);
-        fd = OS_OPEN((char *)&name.n_path, O_CREAT | O_RDWR | O_TRUNC | O_EXCL, 0666);
+        fd = OS_OPEN((char *)&name.n_path, O_CREAT | O_RDWR | O_EXCL, 0666);
         if (fd == INVALID_FD) {
             if (errno == ENOTDIR || errno == ENOENT) {
                 if (namei_CreateDataDirectories(&name, &created_dir) == 0)
-                    fd = OS_OPEN((char *)&name.n_path, O_CREAT | O_RDWR | O_TRUNC | O_EXCL, 0666);
+                    fd = OS_OPEN((char *)&name.n_path, O_CREAT | O_RDWR | O_EXCL, 0666);
             }
         }
 
@@ -771,7 +809,7 @@ namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint
     tmp.ih_ino |= (((Inode) tag) << NAMEI_TAGSHIFT);
 
     if (!code) {
-        if (!SetFileTime((HANDLE) fd, &ftime, NULL, NULL)) {
+        if (SetWinOGM(fd, ogm_p1, ogm_p2)) {
            errno = OS_ERROR(EBADF);
             code = -1;
         }
@@ -886,12 +924,12 @@ namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint
     }
 
     namei_HandleToName(&name, &tmp);
-    fd = OS_OPEN(name.n_path, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0);
+    fd = OS_OPEN(name.n_path, O_CREAT | O_EXCL | O_RDWR, 0);
     if (fd == INVALID_FD) {
        if (errno == ENOTDIR || errno == ENOENT) {
            if (namei_CreateDataDirectories(&name, &created_dir) < 0)
                goto bad;
-           fd = OS_OPEN(name.n_path, O_CREAT | O_EXCL | O_TRUNC | O_RDWR,
+           fd = OS_OPEN(name.n_path, O_CREAT | O_EXCL | O_RDWR,
                          0);
            if (fd == INVALID_FD)
                goto bad;
@@ -972,7 +1010,7 @@ namei_dec(IHandle_t * ih, Inode ino, int p1)
            return -1;
        }
 
-       if (CheckOGM(&name, fdP, p1) < 0) {
+       if (CheckOGM(fdP, p1) < 0) {
            FDH_REALLYCLOSE(fdP);
            IH_RELEASE(tmp);
            errno = OS_ERROR(EINVAL);
@@ -1007,6 +1045,11 @@ namei_dec(IHandle_t * ih, Inode ino, int p1)
                /* Try to remove directory. If it fails, that's ok.
                 * Salvage will clean up.
                 */
+               char *slash = strrchr(name.n_path, OS_DIRSEPC);
+               if (slash) {
+                   /* avoid an rmdir() on the file we just unlinked */
+                   *slash = '\0';
+               }
                (void)namei_RemoveDataDirectories(&name);
            }
        }
@@ -1138,7 +1181,7 @@ namei_copy_on_write(IHandle_t *h)
        if (!fdP)
            return EIO;
        snprintf(path, sizeof(path), "%s-tmp", name.n_path);
-       fd = OS_OPEN(path, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0);
+       fd = OS_OPEN(path, O_CREAT | O_EXCL | O_RDWR, 0);
        if (fd == INVALID_FD) {
            FDH_CLOSE(fdP);
            return EIO;
@@ -1367,6 +1410,9 @@ namei_GetLinkCount(FdHandle_t * h, Inode ino, int lockit, int fixup, int nowrite
     }
 
     rc = FDH_PREAD(h, (char*)&row, sizeof(row), offset);
+    if (rc == -1)
+       goto bad_getLinkByte;
+
     if ((rc == 0 || !((row >> index) & NAMEI_TAGMASK)) && fixup && nowrite)
         return 1;
     if (rc == 0 && fixup) {
@@ -1470,7 +1516,7 @@ GetFreeTag(IHandle_t * ih, int vno)
     if (FDH_PWRITE(fdP, (char *)&row, sizeof(row), offset) != sizeof(row)) {
        goto badGetFreeTag;
     }
-    FDH_SYNC(fdP);
+    (void)FDH_SYNC(fdP);
     FDH_UNLOCKFILE(fdP, offset);
     FDH_CLOSE(fdP);
     return col;
@@ -1522,7 +1568,7 @@ namei_SetLinkCount(FdHandle_t * fdP, Inode ino, int count, int locked)
        errno = OS_ERROR(EBADF);
        goto bad_SetLinkCount;
     }
-    FDH_SYNC(fdP);
+    (void)FDH_SYNC(fdP);
 
     nBytes = 0;
 
@@ -2891,7 +2937,7 @@ namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
     }
     t_ih.ih_ino = namei_MakeSpecIno(ih->ih_vid, VI_VOLINFO);
     namei_HandleToName(&n, &t_ih);
-    fd2 = OS_OPEN(n.n_path, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0);
+    fd2 = OS_OPEN(n.n_path, O_CREAT | O_EXCL | O_RDWR, 0);
     if (fd2 == INVALID_FD) {
        Log("1 namei_ConvertROtoRWvolume: could not create RW info file: %s\n", n.n_path);
        OS_CLOSE(fd);