venus: Remove dedebug
[openafs.git] / src / WINNT / afsrdr / user / RDRFunction.c
index 690930a..cffb9b5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008 Secure Endpoints, Inc.
- * Copyright (c) 2009-2013 Your File System, Inc.
+ * Copyright (c) 2009-2014 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -482,7 +482,8 @@ RDR_PopulateCurrentEntry( IN  AFSDirEnumEntry * pCurrentEntry,
                 if (code) {
                     osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry RDR_BulkStatLookup failed for scp=0x%p code=0x%x",
                              scp, code);
-                    return code;
+                   if (code != CM_ERROR_NOACCESS)
+                       return code;
                 }
                 lock_ObtainWrite(&scp->rw);
                 /*
@@ -532,7 +533,8 @@ RDR_PopulateCurrentEntry( IN  AFSDirEnumEntry * pCurrentEntry,
     pCurrentEntry->ChangeTime = pCurrentEntry->CreationTime;
 
     pCurrentEntry->EndOfFile = scp->length;
-    pCurrentEntry->AllocationSize = scp->length;
+    pCurrentEntry->AllocationSize.QuadPart =
+       ((scp->length.QuadPart/1024)+1)*1024;
 
     if (bMustFake) {
         switch (scp->fileType) {
@@ -584,11 +586,9 @@ RDR_PopulateCurrentEntry( IN  AFSDirEnumEntry * pCurrentEntry,
     if (!(dwFlags & RDR_POP_NO_GETSTATUS))
         cm_SyncOpDone( scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
 
-    if ((dwFlags & RDR_POP_NO_GETSTATUS) || !cm_HaveCallback(scp)) {
-        pCurrentEntry->TargetNameOffset = 0;
-        pCurrentEntry->TargetNameLength = 0;
-    }
-    else
+    pCurrentEntry->TargetNameOffset = 0;
+    pCurrentEntry->TargetNameLength = 0;
+    if (!(dwFlags & RDR_POP_NO_GETSTATUS) && cm_HaveCallback(scp)) {
     switch (scp->fileType) {
     case CM_SCACHETYPE_MOUNTPOINT:
        {
@@ -626,6 +626,8 @@ RDR_PopulateCurrentEntry( IN  AFSDirEnumEntry * pCurrentEntry,
                    } else {
                        osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry cm_FollowMountPoint failed scp=0x%p code=0x%x",
                                  scp, code2);
+                       if (code2 == CM_ERROR_TOO_MANY_SYMLINKS)
+                           code = CM_ERROR_TOO_MANY_SYMLINKS;
                    }
                 }
             } else {
@@ -644,12 +646,11 @@ RDR_PopulateCurrentEntry( IN  AFSDirEnumEntry * pCurrentEntry,
 
                 code2 = cm_HandleLink(scp, userp, reqp);
                 if (code2 == 0) {
-                    size_t wtarget_len = 0;
-
                     if (scp->mountPointStringp[0]) {
                         char * mp;
                         char * s;
                         size_t offset = 0;
+                       size_t wtarget_len = 0;
 
                         len = strlen(scp->mountPointStringp) + 1;
                         mp = strdup(scp->mountPointStringp);
@@ -742,9 +743,9 @@ RDR_PopulateCurrentEntry( IN  AFSDirEnumEntry * pCurrentEntry,
                         }
 
                         free(mp);
-                    }
 
-                    pCurrentEntry->TargetNameLength = (ULONG)(sizeof(WCHAR) * (wtarget_len - 1));
+                       pCurrentEntry->TargetNameLength = (ULONG)(sizeof(WCHAR) * (wtarget_len - 1));
+                   }
                 } else {
                     osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry cm_HandleLink failed scp=0x%p code=0x%x",
                              scp, code2);
@@ -758,6 +759,7 @@ RDR_PopulateCurrentEntry( IN  AFSDirEnumEntry * pCurrentEntry,
         pCurrentEntry->TargetNameOffset = 0;
         pCurrentEntry->TargetNameLength = 0;
     }
+    }
     lock_ReleaseWrite(&scp->rw);
 
     dwEntryLength += pCurrentEntry->FileNameLength + pCurrentEntry->TargetNameLength;
@@ -1103,8 +1105,8 @@ RDR_EvaluateNodeByName( IN cm_user_t *userp,
                         IN BOOL     CaseSensitive,
                         IN BOOL     LastComponent,
                         IN BOOL     bWow64,
-                        IN BOOL     bHoldFid,
                         IN BOOL     bNoFollow,
+                        IN BOOL     bHoldFid,
                         IN DWORD    ResultBufferLength,
                         IN OUT AFSCommResult **ResultCB)
 {
@@ -1277,7 +1279,8 @@ RDR_EvaluateNodeByName( IN cm_user_t *userp,
                                         dscp, scp, userp, &req,
                                         FileName, shortName,
                                         (bWow64 ? RDR_POP_WOW64 : 0) |
-                                        (bNoFollow ? 0 : (RDR_POP_FOLLOW_MOUNTPOINTS | RDR_POP_EVALUATE_SYMLINKS)),
+                                       (bNoFollow ? 0 : RDR_POP_FOLLOW_MOUNTPOINTS) |
+                                       RDR_POP_EVALUATE_SYMLINKS,
                                         0, NULL, &dwRemaining);
         if (bHoldFid)
             RDR_FlagScpInUse( scp, FALSE );
@@ -1433,7 +1436,8 @@ RDR_EvaluateNodeByID( IN cm_user_t *userp,
     code = RDR_PopulateCurrentEntry(pCurrentEntry, dwRemaining,
                                     dscp, scp, userp, &req, NULL, NULL,
                                     (bWow64 ? RDR_POP_WOW64 : 0) |
-                                    (bNoFollow ? 0 : (RDR_POP_FOLLOW_MOUNTPOINTS | RDR_POP_EVALUATE_SYMLINKS)),
+                                   (bNoFollow ? 0 : RDR_POP_FOLLOW_MOUNTPOINTS) |
+                                   RDR_POP_EVALUATE_SYMLINKS,
                                     0, NULL, &dwRemaining);
 
     if (bHoldFid)
@@ -2150,7 +2154,7 @@ RDR_CleanupFileEntry( IN cm_user_t *userp,
             bScpLocked = TRUE;
         }
         code = cm_SyncOp(scp, NULL, userp, &req, 0,
-                          CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+                        CM_SCACHESYNC_LOCK);
         if (code) {
             osi_Log2(afsd_logp, "RDR_CleanupFileEntry cm_SyncOp (2) failure scp=0x%p code=0x%x",
                      scp, code);
@@ -2164,7 +2168,7 @@ RDR_CleanupFileEntry( IN cm_user_t *userp,
                               bDeleteFile ? CM_UNLOCK_FLAG_BY_FID : 0,
                               userp, &req);
 
-        cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+       cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
 
         if (code)
             goto on_error;
@@ -2305,7 +2309,7 @@ RDR_DeleteFileEntry( IN cm_user_t *userp,
     }
 
     code = cm_Lookup(dscp, FileName, 0, userp, &req, &scp);
-    if (code) {
+    if (code && code != CM_ERROR_INEXACT_MATCH) {
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
         (*ResultCB)->ResultStatus = status;
         (*ResultCB)->ResultBufferLength = 0;
@@ -2364,7 +2368,7 @@ RDR_DeleteFileEntry( IN cm_user_t *userp,
     if (!bCheckOnly) {
         /* Drop all locks since the file is being deleted */
         code = cm_SyncOp(scp, NULL, userp, &req, 0,
-                         CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+                        CM_SCACHESYNC_LOCK);
         if (code) {
             smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
             (*ResultCB)->ResultStatus = status;
@@ -2383,7 +2387,7 @@ RDR_DeleteFileEntry( IN cm_user_t *userp,
                               CM_UNLOCK_FLAG_BY_FID,
                               userp, &req);
 
-        cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+       cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
         lock_ReleaseWrite(&scp->rw);
 
         if (scp->fileType == CM_SCACHETYPE_DIRECTORY)
@@ -2593,7 +2597,7 @@ RDR_RenameFileEntry( IN cm_user_t *userp,
             cm_EndDirOp(&dirop);
         }
 
-        if (code != 0) {
+       if (code != 0 && code != CM_ERROR_INEXACT_MATCH) {
             osi_Log1(afsd_logp, "RDR_RenameFileEntry cm_BPlusDirLookup failed code 0x%x",
                      code);
             (*ResultCB)->ResultStatus = STATUS_OBJECT_PATH_INVALID;
@@ -2919,7 +2923,7 @@ RDR_HardLinkFileEntry( IN cm_user_t *userp,
             cm_EndDirOp(&dirop);
         }
 
-        if (code != 0) {
+       if (code != 0 && code != CM_ERROR_INEXACT_MATCH) {
             osi_Log1(afsd_logp, "RDR_HardLinkFileEntry cm_BPlusDirLookup failed code 0x%x",
                      code);
             (*ResultCB)->ResultStatus = STATUS_OBJECT_PATH_INVALID;
@@ -4087,24 +4091,6 @@ RDR_RequestFileExtentsAsync( IN cm_user_t *userp,
                 bHaveBuffer = TRUE;
             } else if (bufp->flags & CM_BUF_DIRTY) {
                 bHaveBuffer = FALSE;
-#if 0
-                code = buf_CleanAsyncLocked(scp, bufp, &req, 0, NULL);
-                switch (code) {
-                case 0:
-                    bHaveBuffer = TRUE;
-                    break;
-                case CM_ERROR_RETRY:
-                    /* Couldn't flush it, obtain it asynchronously so we don't block the thread. */
-                    bHaveBuffer = FALSE;
-                    code = 0;
-                    break;
-                default:
-                    smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
-                    RDR_SetFileStatus(&FileId, &userp->authgroup, status);
-                    bHaveBuffer = FALSE;
-                    code = 0;
-                }
-#endif
             } else {
                 osi_hyper_t minLength;  /* effective end of file */
 
@@ -5358,7 +5344,7 @@ RDR_PioctlOpen( IN cm_user_t *userp,
     cm_fid_t    RootFid;
     cm_req_t    req;
 
-    RDR_InitReq(&req, bWow64);
+    cm_InitReq(&req);
 
     *ResultCB = (AFSCommResult *)malloc( sizeof( AFSCommResult));
     if (!(*ResultCB))
@@ -5426,7 +5412,7 @@ RDR_PioctlWrite( IN cm_user_t *userp,
     cm_req_t    req;
     DWORD       status;
 
-    RDR_InitReq(&req, bWow64);
+    cm_InitReq(&req);
 
     *ResultCB = (AFSCommResult *)malloc( sizeof( AFSCommResult) + sizeof(AFSPIOCtlIOResultCB));
     if (!(*ResultCB))
@@ -5465,7 +5451,7 @@ RDR_PioctlRead( IN cm_user_t *userp,
     DWORD       status;
     afs_uint32  pflags = (bIsLocalSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
 
-    RDR_InitReq(&req, bWow64);
+    cm_InitReq(&req);
 
     *ResultCB = (AFSCommResult *)malloc( sizeof( AFSCommResult) + sizeof(AFSPIOCtlIOResultCB));
     if (!(*ResultCB))
@@ -5558,7 +5544,7 @@ RDR_ByteRangeLockSync( IN cm_user_t     *userp,
 
     /* start by looking up the file's end */
     code = cm_SyncOp(scp, NULL, userp, &req, 0,
-                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+                    CM_SCACHESYNC_LOCK);
     if (code) {
         lock_ReleaseWrite(&scp->rw);
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
@@ -5606,7 +5592,7 @@ RDR_ByteRangeLockSync( IN cm_user_t     *userp,
         }
     }
 
-    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
     lock_ReleaseWrite(&scp->rw);
     cm_ReleaseSCache(scp);
 
@@ -5684,7 +5670,7 @@ RDR_ByteRangeUnlock( IN cm_user_t     *userp,
 
     /* start by looking up the file's end */
     code = cm_SyncOp(scp, NULL, userp, &req, 0,
-                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+                    CM_SCACHESYNC_LOCK);
     if (code) {
         lock_ReleaseWrite(&scp->rw);
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
@@ -5722,7 +5708,7 @@ RDR_ByteRangeUnlock( IN cm_user_t     *userp,
         pResultCB->Result[i].Status = status;
     }
 
-    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
     lock_ReleaseWrite(&scp->rw);
     cm_ReleaseSCache(scp);
 
@@ -5785,7 +5771,7 @@ RDR_ByteRangeUnlockAll( IN cm_user_t     *userp,
 
     /* start by looking up the file's end */
     code = cm_SyncOp(scp, NULL, userp, &req, 0,
-                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+                    CM_SCACHESYNC_LOCK);
     if (code) {
         lock_ReleaseWrite(&scp->rw);
         smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE);
@@ -5801,7 +5787,7 @@ RDR_ByteRangeUnlockAll( IN cm_user_t     *userp,
 
     code = cm_UnlockByKey(scp, key, 0, userp, &req);
 
-    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
+    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
     lock_ReleaseWrite(&scp->rw);
     cm_ReleaseSCache(scp);
 
@@ -5833,7 +5819,6 @@ RDR_GetVolumeInfo( IN cm_user_t     *userp,
     cm_req_t    req;
     DWORD       status;
     FILETIME ft = {0x832cf000, 0x01abfcc4}; /* October 1, 1982 00:00:00 +0600 */
-    afs_uint32  flags;
 
     char volName[32]="(unknown)";
     char offLineMsg[256]="server temporarily inaccessible";
@@ -5844,7 +5829,6 @@ RDR_GetVolumeInfo( IN cm_user_t     *userp,
     char *OfflineMsg;
     char *MOTD;
     struct rx_connection * rxconnp;
-    int sync_done = 0;
     int scp_locked = 0;
 
     RDR_InitReq(&req, bWow64);
@@ -5918,11 +5902,12 @@ RDR_GetVolumeInfo( IN cm_user_t     *userp,
         if ( pResultCB->CellLength )
             pResultCB->CellLength--;
     } else {
-        volp = cm_GetVolumeByFID(&scp->fid);
-        if (!volp) {
+       volp = cm_FindVolumeByFID(&scp->fid, userp, &req);
+       if (!volp) {
             code = CM_ERROR_NOSUCHVOLUME;
             goto _done;
         }
+
         volType = cm_VolumeType(volp, scp->fid.volume);
 
         if (cm_volumeInfoReadOnlyFlag && (volType == ROVOL || volType == BACKVOL))
@@ -5943,40 +5928,30 @@ RDR_GetVolumeInfo( IN cm_user_t     *userp,
         
         if (code == -1)
         {
-            flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS;
-            if (scp->volumeCreationDate == 0)
-                flags |= CM_SCACHESYNC_FORCECB;
-            code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ, flags);
-            if (code == 0)
-            {
-                sync_done = 1;
-
-                Name = volName;
-                OfflineMsg = offLineMsg;
-                MOTD = motd;
-                lock_ReleaseWrite(&scp->rw);
-                scp_locked = 0;
-
-                do {
-                    code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
-                    if (code) continue;
-
-                    rxconnp = cm_GetRxConn(connp);
-                    code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume,
-                                                 &volStat, &Name, &OfflineMsg, &MOTD);
-                    rx_PutConnection(rxconnp);
-
-                } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code));
-                code = cm_MapRPCError(code, &req);
-
-                if (code == 0 && volType == ROVOL)
-                {
-
-                    lock_ObtainWrite(&volp->rw);
-                    volp->volumeSizeRO = volStat.BlocksInUse * 1024;
-                    _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID);
-                    lock_ReleaseWrite(&volp->rw);
-                }
+           Name = volName;
+           OfflineMsg = offLineMsg;
+           MOTD = motd;
+           lock_ReleaseWrite(&scp->rw);
+           scp_locked = 0;
+
+           do {
+               code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
+               if (code) continue;
+
+               rxconnp = cm_GetRxConn(connp);
+               code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume,
+                                            &volStat, &Name, &OfflineMsg, &MOTD);
+               rx_PutConnection(rxconnp);
+
+           } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code));
+           code = cm_MapRPCError(code, &req);
+
+           if (code == 0 && volType == ROVOL)
+           {
+               lock_ObtainWrite(&volp->rw);
+               volp->volumeSizeRO = volStat.BlocksInUse * 1024;
+               _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID);
+               lock_ReleaseWrite(&volp->rw);
             }
         }
 
@@ -6047,14 +6022,6 @@ RDR_GetVolumeInfo( IN cm_user_t     *userp,
         /* do not include the trailing nul */
         if ( pResultCB->CellLength )
             pResultCB->CellLength--;
-
-        if (sync_done) {
-            if (!scp_locked) {
-                lock_ObtainWrite(&scp->rw);
-                scp_locked = 1;
-            }
-            cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-        }
     }
     pResultCB->VolumeLabelLength *= sizeof(WCHAR);  /* convert to bytes from chars */
     pResultCB->CellLength *= sizeof(WCHAR);         /* convert to bytes from chars */
@@ -6098,7 +6065,6 @@ RDR_GetVolumeSizeInfo( IN cm_user_t     *userp,
     char *OfflineMsg;
     char *MOTD;
     struct rx_connection * rxconnp;
-    int sync_done = 0;
     int scp_locked = 0;
 
     RDR_InitReq(&req, bWow64);
@@ -6152,8 +6118,8 @@ RDR_GetVolumeSizeInfo( IN cm_user_t     *userp,
         pResultCB->TotalAllocationUnits.QuadPart = 100;
         pResultCB->AvailableAllocationUnits.QuadPart = 0;
     } else {
-        volp = cm_GetVolumeByFID(&scp->fid);
-        if (!volp) {
+       volp = cm_FindVolumeByFID(&scp->fid, userp, &req);
+       if (!volp) {
             code = CM_ERROR_NOSUCHVOLUME;
             goto _done;
         }
@@ -6175,38 +6141,30 @@ RDR_GetVolumeSizeInfo( IN cm_user_t     *userp,
         
         if (code == -1)
         {
-            code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ,
-                              CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-            if (code == 0)
-            {
-                sync_done = 1;
-
-                Name = volName;
-                OfflineMsg = offLineMsg;
-                MOTD = motd;
-                lock_ReleaseWrite(&scp->rw);
-                scp_locked = 0;
-
-                do {
-                    code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
-                    if (code) continue;
-
-                    rxconnp = cm_GetRxConn(connp);
-                    code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume,
-                                                  &volStat, &Name, &OfflineMsg, &MOTD);
-                    rx_PutConnection(rxconnp);
-
-                } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code));
-                code = cm_MapRPCError(code, &req);
-
-                if (code == 0 && volType == ROVOL)
-                {
-
-                    lock_ObtainWrite(&volp->rw);
-                    volp->volumeSizeRO = volStat.BlocksInUse * 1024;
-                    _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID);
-                    lock_ReleaseWrite(&volp->rw);
-                }
+           Name = volName;
+           OfflineMsg = offLineMsg;
+           MOTD = motd;
+           lock_ReleaseWrite(&scp->rw);
+           scp_locked = 0;
+
+           do {
+               code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
+               if (code) continue;
+
+               rxconnp = cm_GetRxConn(connp);
+               code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume,
+                                            &volStat, &Name, &OfflineMsg, &MOTD);
+               rx_PutConnection(rxconnp);
+
+           } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code));
+           code = cm_MapRPCError(code, &req);
+
+           if (code == 0 && volType == ROVOL)
+           {
+               lock_ObtainWrite(&volp->rw);
+               volp->volumeSizeRO = volStat.BlocksInUse * 1024;
+               _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID);
+               lock_ReleaseWrite(&volp->rw);
             }
         }
 
@@ -6236,14 +6194,6 @@ RDR_GetVolumeSizeInfo( IN cm_user_t     *userp,
             pResultCB->AvailableAllocationUnits.QuadPart = (volType == ROVOL || volType == BACKVOL) ? 0 : 0x3F000000;
             code = 0;
         }
-
-        if (sync_done) {
-            if (!scp_locked) {
-                lock_ObtainWrite(&scp->rw);
-                scp_locked = 1;
-            }
-            cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-        }
     }
 
   _done:
@@ -6896,7 +6846,14 @@ RDR_WriteFile( IN cm_user_t     *userp,
 
     /* Ensure that the caller can access this file */
     lock_ObtainWrite(&scp->rw);
-    code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_WRITE,
+    /*
+     * Request PRSFS_WRITE | PRSFS_LOCK in order to bypass the unix mode
+     * check in cm_HaveAccessRights().   By the time RDR_WriteFile is called
+     * it is already too late to deny the write due to the readonly attribute.
+     * The Windows cache may have already accepted the data.  Only if the
+     * user does not have real write permission should the write be denied.
+     */
+    code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_WRITE | PRSFS_LOCK,
                       CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
     if (code == CM_ERROR_NOACCESS && scp->creator == userp) {
         code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_INSERT,