Windows: STATUS_OBJECT_PATH_INVALID == invalid parent directory
[openafs.git] / src / WINNT / afsrdr / user / RDRFunction.c
index 1423111..c304802 100644 (file)
@@ -231,8 +231,10 @@ RDR_UserFromAuthGroup( IN GUID *pGuid)
 
     unp = smb_FindUserByName(UuidString, cname, SMB_FLAG_CREATE);
     lock_ObtainMutex(&unp->mx);
-    if (!unp->userp)
+    if (!unp->userp) {
         unp->userp = cm_NewUser();
+        memcpy(&unp->userp->authgroup, pGuid, sizeof(GUID));
+    }
     unp->flags |= SMB_USERNAMEFLAG_SID;
     lock_ReleaseMutex(&unp->mx);
     userp = unp->userp;
@@ -994,6 +996,8 @@ RDR_EvaluateNodeByName( IN cm_user_t *userp,
         if (code) {
             smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
             (*ResultCB)->ResultStatus = status;
+            if ( status == STATUS_INVALID_HANDLE)
+                status = STATUS_OBJECT_PATH_INVALID;
             osi_Log2(afsd_logp, "RDR_EvaluateNodeByName cm_GetSCache parentFID failure code=0x%x status=0x%x",
                       code, status);
             free(wszName);
@@ -1166,6 +1170,8 @@ RDR_EvaluateNodeByID( IN cm_user_t *userp,
         if (code) {
             cm_ReleaseSCache(scp);
             smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
+            if ( status == STATUS_INVALID_HANDLE)
+                status = STATUS_OBJECT_PATH_INVALID;
             (*ResultCB)->ResultStatus = status;
             osi_Log2(afsd_logp, "RDR_EvaluateNodeByID cm_GetSCache parentFID failure code=0x%x status=0x%x",
                       code, status);
@@ -1180,6 +1186,8 @@ RDR_EvaluateNodeByID( IN cm_user_t *userp,
         if (code) {
             cm_ReleaseSCache(scp);
             smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
+            if ( status == STATUS_INVALID_HANDLE)
+                status = STATUS_OBJECT_PATH_INVALID;
             (*ResultCB)->ResultStatus = status;
             osi_Log2(afsd_logp, "RDR_EvaluateNodeByID cm_GetSCache parentFID failure code=0x%x status=0x%x",
                       code, status);
@@ -1295,6 +1303,8 @@ RDR_CreateFileEntry( IN cm_user_t *userp,
     if (code) {
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
         (*ResultCB)->ResultStatus = status;
+        if ( status == STATUS_INVALID_HANDLE)
+            status = STATUS_OBJECT_PATH_INVALID;
         osi_Log2(afsd_logp, "RDR_CreateFileEntry cm_GetSCache ParentFID failure code=0x%x status=0x%x",
                   code, status);
         return;
@@ -1468,6 +1478,8 @@ RDR_UpdateFileEntry( IN cm_user_t *userp,
     if (code) {
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
         (*ResultCB)->ResultStatus = status;
+        if ( status == STATUS_INVALID_HANDLE)
+            status = STATUS_OBJECT_PATH_INVALID;
         osi_Log2(afsd_logp, "RDR_UpdateFileEntry cm_GetSCache ParentFID failure code=0x%x status=0x%x",
                   code, status);
         return;
@@ -1679,6 +1691,8 @@ RDR_CleanupFileEntry( IN cm_user_t *userp,
         code = cm_GetSCache(&parentFid, &dscp, userp, &req);
         if (code) {
             smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
+            if ( status == STATUS_INVALID_HANDLE)
+                status = STATUS_OBJECT_PATH_INVALID;
             (*ResultCB)->ResultStatus = status;
             osi_Log2(afsd_logp, "RDR_CleanupFileEntry cm_GetSCache ParentFID failure code=0x%x status=0x%x",
                      code, status);
@@ -1734,7 +1748,9 @@ RDR_CleanupFileEntry( IN cm_user_t *userp,
     }
     cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
 
-    if (scp->redirBufCount > 0) {
+    if ((bLastHandle || bFlushFile) &&
+        scp->redirBufCount > 0)
+    {
         LARGE_INTEGER heldExtents;
         AFSFileExtentCB extentList[1024];
         DWORD extentCount = 0;
@@ -1797,11 +1813,20 @@ RDR_CleanupFileEntry( IN cm_user_t *userp,
     }
 
     if (bLastHandle || bFlushFile) {
-        if (bScpLocked) {
-            lock_ReleaseWrite(&scp->rw);
-            bScpLocked = FALSE;
+        if (!bScpLocked) {
+            lock_ObtainWrite(&scp->rw);
+            bScpLocked = TRUE;
+        }
+        code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_WRITE,
+                          CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+        if (code == 0) {
+            if (bScpLocked) {
+                lock_ReleaseWrite(&scp->rw);
+                bScpLocked = FALSE;
+            }
+
+            code = cm_FSync(scp, userp, &req, bScpLocked);
         }
-        code = buf_CleanVnode(scp, userp, &req);
         if (bLastHandle && code)
             goto on_error;
     }
@@ -2019,6 +2044,8 @@ RDR_DeleteFileEntry( IN cm_user_t *userp,
     code = cm_GetSCache(&parentFid, &dscp, userp, &req);
     if (code) {
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
+        if ( status == STATUS_INVALID_HANDLE)
+            status = STATUS_OBJECT_PATH_INVALID;
         (*ResultCB)->ResultStatus = status;
         osi_Log2(afsd_logp, "RDR_DeleteFileEntry cm_GetSCache ParentFID failure code=0x%x status=0x%x",
                   code, status);
@@ -2212,6 +2239,8 @@ RDR_RenameFileEntry( IN cm_user_t *userp,
     if (code) {
         osi_Log1(afsd_logp, "RDR_RenameFileEntry cm_GetSCache source parent failed code 0x%x", code);
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
+        if ( status == STATUS_INVALID_HANDLE)
+            status = STATUS_OBJECT_PATH_INVALID;
         (*ResultCB)->ResultStatus = status;
         return;
     }
@@ -2222,6 +2251,8 @@ RDR_RenameFileEntry( IN cm_user_t *userp,
     if (code) {
         osi_Log2(afsd_logp, "RDR_RenameFileEntry cm_SyncOp oldDscp 0x%p failed code 0x%x", oldDscp, code);
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
+        if ( status == STATUS_INVALID_HANDLE)
+            status = STATUS_OBJECT_PATH_INVALID;
         (*ResultCB)->ResultStatus = status;
         lock_ReleaseWrite(&oldDscp->rw);
         cm_ReleaseSCache(oldDscp);
@@ -2888,7 +2919,7 @@ RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_
     FileId.Hash = scp->fid.hash;
 
     if ((GetTickCount() - reqp->startTime) / 1000 > HardDeadtimeout * 5) {
-        RDR_SetFileStatus( &scp->fid, STATUS_IO_TIMEOUT);
+        RDR_SetFileStatus( &scp->fid, &userp->authgroup, STATUS_IO_TIMEOUT);
         return 0;
     }
 
@@ -2918,7 +2949,7 @@ RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_
         osi_Log2(afsd_logp, "RDR_BkgFetch cm_SyncOp failure scp=0x%p code=0x%x",
                  scp, code);
         smb_MapNTError(cm_MapRPCError(code, reqp), &status, TRUE);
-        RDR_SetFileStatus( &scp->fid, status);
+        RDR_SetFileStatus( &scp->fid, &userp->authgroup, status);
         return code;
     }
     lock_ReleaseWrite(&scp->rw);
@@ -2949,7 +2980,7 @@ RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_
              * we need to re-queue this extent fetch.
              */
             force_retry = 1;
-            continue;
+            break;
         }
 
         if (!rwheld) {
@@ -2959,9 +2990,6 @@ RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_
 
         code = cm_GetBuffer(scp, bufp, NULL, userp, reqp);
         if (code == 0) {
-            if (bufp->flags & CM_BUF_DIRTY)
-                cm_BufWrite(scp, &bufp->offset, cm_chunkSize, CM_BUF_WRITE_SCP_LOCKED, userp, reqp);
-
             if (!(bufp->qFlags & CM_BUF_QREDIR)) {
 #ifdef VALIDATE_CHECK_SUM
 #ifdef ODS_DEBUG
@@ -2969,6 +2997,9 @@ RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_
                 char dbgstr[1024];
 #endif
 #endif
+                if (bufp->flags & CM_BUF_DIRTY)
+                    cm_BufWrite(scp, &bufp->offset, cm_data.buf_blockSize, CM_BUF_WRITE_SCP_LOCKED, userp, reqp);
+
                 lock_ObtainWrite(&buf_globalLock);
                 if (!(bufp->flags & CM_BUF_DIRTY) &&
                     bufp->cmFlags == 0 &&
@@ -3050,6 +3081,7 @@ RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_
                  * non-fatal errors.  re-queue the exent
                  */
                 code = CM_ERROR_RETRY;
+                force_retry = 1;
             }
         }
 
@@ -3077,7 +3109,7 @@ RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_
 
     if (reportErrorToRedir) {
         smb_MapNTError(cm_MapRPCError(code, reqp), &status, TRUE);
-        RDR_SetFileStatus( &scp->fid, status);
+        RDR_SetFileStatus( &scp->fid, &userp->authgroup, status);
     }
 
     osi_Log4(afsd_logp, "Ending BKG Fetch scp 0x%p code 0x%x fetched 0x%x:%x",
@@ -3161,7 +3193,7 @@ RDR_RequestFileExtentsAsync( IN cm_user_t *userp,
         osi_Log2(afsd_logp, "RDR_RequestFileExtentsAsync cm_SyncOp failure scp=0x%p code=0x%x",
                  scp, code);
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
-        RDR_SetFileStatus( &scp->fid, status);
+        RDR_SetFileStatus( &scp->fid, &userp->authgroup, status);
         return FALSE;
     }
 
@@ -3199,7 +3231,7 @@ RDR_RequestFileExtentsAsync( IN cm_user_t *userp,
                     break;
                 default:
                     smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
-                    RDR_SetFileStatus(&FileId, status);
+                    RDR_SetFileStatus(&FileId, &userp->authgroup, status);
                     bHaveBuffer = FALSE;
                     code = 0;
                 }
@@ -3215,21 +3247,22 @@ RDR_RequestFileExtentsAsync( IN cm_user_t *userp,
                 else
                     minLength = scp->length;
 
-                if (LargeIntegerGreaterThanOrEqualTo(bufp->offset, minLength)) {
+                if (!bHaveBuffer &&
+                    LargeIntegerGreaterThanOrEqualTo(bufp->offset, minLength)) {
                     memset(bufp->datap, 0, cm_data.buf_blockSize);
                     bufp->dataVersion = scp->dataVersion;
                     bHaveBuffer = TRUE;
                 }
-                lock_ReleaseRead(&scp->rw);
-
-                if ((RequestExtentsCB->Flags & AFS_EXTENT_FLAG_CLEAN) &&
-                     ByteOffset.QuadPart <= bufp->offset.QuadPart &&
-                     EndOffset.QuadPart >= bufp->offset.QuadPart + cm_data.blockSize) {
+                else if ((RequestExtentsCB->Flags & AFS_EXTENT_FLAG_CLEAN) &&
+                         ByteOffset.QuadPart <= bufp->offset.QuadPart &&
+                         EndOffset.QuadPart >= bufp->offset.QuadPart + cm_data.blockSize)
+                {
                     memset(bufp->datap, 0, cm_data.blockSize);
                     bufp->dataVersion = scp->dataVersion;
                     buf_SetDirty(bufp, &req, 0, cm_data.blockSize, userp);
                     bHaveBuffer = TRUE;
                 }
+                lock_ReleaseRead(&scp->rw);
             }
 
             /*
@@ -3286,7 +3319,6 @@ RDR_RequestFileExtentsAsync( IN cm_user_t *userp,
                                  bufp, ByteOffset.QuadPart, bufp->datap - RDR_extentBaseAddress, cm_data.blockSize);
                     } else {
                         lock_ReleaseWrite(&buf_globalLock);
-                        lock_ReleaseWrite(&scp->rw);
                     }
                 } else {
                     if (bBufRelease) {
@@ -3783,7 +3815,12 @@ RDR_ReleaseFileExtents( IN cm_user_t *userp,
 
     if (scp) {
         if (ReleaseExtentsCB->Flags & AFS_EXTENT_FLAG_FLUSH) {
-            code = buf_CleanVnode(scp, userp, &req);
+            lock_ObtainWrite(&scp->rw);
+            code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_WRITE,
+                             CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+            lock_ReleaseWrite(&scp->rw);
+            if (code == 0)
+                code = cm_FSync(scp, userp, &req, FALSE);
         }
         else if (dirty) {
             osi_hyper_t offset = {0,0};