]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-windows-byte-range-locks-20051007
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 8 Oct 2005 04:51:26 +0000 (04:51 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 8 Oct 2005 04:51:26 +0000 (04:51 +0000)
There was a race condition associated with maintaining the
CM_FILELOCK_FLAG_CLIENTONLY flag on locks bound to scache entries
for Read Only volumes.   Therefore, we remove the use of the flag
and simply test the RO status of the scache entry.

(cherry picked from commit 2dcb1cdc3d6f10b366d2b93970f5f1f83287e157)

src/WINNT/afsd/cm_dcache.c
src/WINNT/afsd/cm_scache.h
src/WINNT/afsd/cm_vnodeops.c

index b29d845ea4cfeeaf0a75fd7e9c23a8cfa6925fc5..ae7b9f2d3573b36b0c80f0e778bf020270994486 100644 (file)
@@ -1263,7 +1263,7 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up,
         callp = rx_NewCall(rxconnp);
         rx_PutConnection(rxconnp);
 
-        osi_Log3(afsd_logp, "CALL FetchData vp %x, off 0x%x, size 0x%x",
+        osi_Log3(afsd_logp, "CALL FetchData scp 0x%x, off 0x%x, size 0x%x",
                   (long) scp, biod.offset.LowPart, biod.length);
 
         code = StartRXAFS_FetchData(callp, &tfid, biod.offset.LowPart,
index b99c63351824cdfc93f1549fe338a8938de7bcec..1ffb478fea81270f911b6c0905d501a30fc7608e 100644 (file)
@@ -75,6 +75,7 @@ typedef struct cm_file_lock {
 #define CM_FILELOCK_FLAG_WAITLOCK        0x04
 #define CM_FILELOCK_FLAG_WAITUNLOCK      0x0C
 
+/* the following is only to be used for locks on non-RO volumes */
 #define CM_FILELOCK_FLAG_CLIENTONLY      0x100
 
 typedef struct cm_prefetch {           /* last region scanned for prefetching */
index b8ff5cf858f02bc2bc997fc4a05d21ad27b13d75..af340603df1627b2a8e7943234b500092a879d27 100644 (file)
@@ -283,6 +283,7 @@ long cm_CheckOpen(cm_scache_t *scp, int openMode, int trunc, cm_user_t *userp,
         else
             sLockType = LOCKING_ANDX_SHARED_LOCK;
 
+        /* single byte lock at offset 0x0000 0001 0000 0000 */
         LOffset.HighPart = 1;
         LOffset.LowPart = 0;
         LLength.HighPart = 0;
@@ -358,6 +359,8 @@ long cm_CheckNTOpen(cm_scache_t *scp, unsigned int desiredAccess,
             sLockType = 0;
         else
             sLockType = LOCKING_ANDX_SHARED_LOCK;
+
+        /* single byte lock at offset 0x0000 0001 0000 0000 */
         LOffset.HighPart = 1;
         LOffset.LowPart = 0;
         LLength.HighPart = 0;
@@ -3029,7 +3032,7 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, cm_scache_t *newDscp,
 
 #define IS_LOCK_EFFECTIVE(lockp)  (IS_LOCK_ACTIVE(lockp) || IS_LOCK_LOST(lockp))
 
-#define IS_LOCK_CLIENTONLY(lockp) (((lockp)->flags & CM_FILELOCK_FLAG_CLIENTONLY) == CM_FILELOCK_FLAG_CLIENTONLY)
+#define IS_LOCK_CLIENTONLY(lockp) ((((lockp)->scp->flags & CM_SCACHEFLAG_RO) == CM_SCACHEFLAG_RO) || (((lockp)->flags & CM_FILELOCK_FLAG_CLIENTONLY) == CM_FILELOCK_FLAG_CLIENTONLY))
 
 #define INTERSECT_RANGE(r1,r2) (((r2).offset+(r2).length) > (r1).offset && ((r1).offset +(r1).length) > (r2).offset)
 
@@ -3152,6 +3155,9 @@ long cm_LockCheckRead(cm_scache_t *scp,
 
     lock_ReleaseRead(&cm_scacheLock);
 
+    osi_Log4(afsd_logp, "cm_LockCheckRead scp 0x%x offset %d length %d code 0x%x",
+             scp, (unsigned long)LOffset.QuadPart, (unsigned long)LLength.QuadPart, code);
+
     return code;
 
 #else
@@ -3234,6 +3240,9 @@ long cm_LockCheckWrite(cm_scache_t *scp,
 
     lock_ReleaseRead(&cm_scacheLock);
 
+    osi_Log4(afsd_logp, "cm_LockCheckWrite scp 0x%x offset %d length %d code 0x%x",
+             scp, (unsigned long)LOffset.QuadPart, (unsigned long)LLength.QuadPart, code);
+
     return code;
 
 #else
@@ -3486,7 +3495,7 @@ long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
                 }
             }
         }
-    } else if (scp->flags & CM_SCACHEFLAG_RO) {
+    } else if (code == 0 && (scp->flags & CM_SCACHEFLAG_RO)) {
         osi_Log0(afsd_logp, "  Skipping server lock for RO scp");
     }
 
@@ -3524,8 +3533,6 @@ long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
                            ((wait_unlock)?
                             CM_FILELOCK_FLAG_WAITUNLOCK :
                             CM_FILELOCK_FLAG_WAITLOCK));
-        if (scp->flags & CM_SCACHEFLAG_RO)
-            fileLock->flags |= CM_FILELOCK_FLAG_CLIENTONLY;
 
         fileLock->lastUpdate = (code == 0) ? time(NULL) : 0;
 
@@ -3548,7 +3555,7 @@ long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
                 scp->exclusiveLocks++;
         }
 
-        osi_Log1(afsd_logp, "cm_Lock Lock added 0x%x", (long) fileLock);
+        osi_Log2(afsd_logp, "cm_Lock Lock added 0x%x flags 0x%x", (long) fileLock, fileLock->flags);
         osi_Log4(afsd_logp, "   scp[0x%x] exclusives[%d] shared[%d] serverLock[%d]",
                  scp, scp->exclusiveLocks, scp->sharedLocks, (int)(signed char) scp->serverLock);
     }
@@ -4045,9 +4052,8 @@ long cm_Unlock(cm_scache_t *scp,
 
  done:
 
-    osi_Log1(afsd_logp, "cm_Unlock code 0x%x", code);
-    osi_Log3(afsd_logp, "   Leaving scp with exclusives[%d], shared[%d], serverLock[%d]",
-             scp->exclusiveLocks, scp->sharedLocks, (int)(signed char) scp->serverLock);
+    osi_Log4(afsd_logp, "cm_Unlock code 0x%x leaving scp with exclusives[%d], shared[%d], serverLock[%d]",
+             code, scp->exclusiveLocks, scp->sharedLocks, (int)(signed char) scp->serverLock);
 
     return code;
 }
@@ -4058,8 +4064,14 @@ static void cm_LockMarkSCacheLost(cm_scache_t * scp)
     cm_file_lock_t *fileLock;
     osi_queue_t *q;
 
-    /* cm_scacheLock needed because we are modifying
-       fileLock->flags */
+    osi_Log1(afsd_logp, "cm_LockMarkSCacheLost scp 0x%x", scp);
+
+#ifdef DEBUG
+    /* With the current code, we can't lose a lock on a RO scp */
+    osi_assert(!(scp->flags & CM_SCACHEFLAG_RO));
+#endif
+
+    /* cm_scacheLock needed because we are modifying fileLock->flags */
     lock_ObtainWrite(&cm_scacheLock);
 
     for(q = scp->fileLocksH; q; q = osi_QNext(q)) {
@@ -4113,6 +4125,7 @@ void cm_CheckLocks()
 
             scp = fileLock->scp;
             osi_assert(scp != NULL);
+
             cm_HoldSCacheNoLock(scp);
 
 #ifdef DEBUG
@@ -4370,8 +4383,8 @@ long cm_RetryLock(cm_file_lock_t *oldFileLock, int client_is_dead)
     }
 
     if (scp->serverLock == oldFileLock->lockType ||
-        (oldFileLock->lockType == LockRead && 
-         scp->serverLock == LockWrite)) {
+        (oldFileLock->lockType == LockRead && scp->serverLock == LockWrite) ||
+        (scp->flags & CM_SCACHEFLAG_RO)) {
 
         oldFileLock->flags &= ~CM_FILELOCK_FLAG_WAITLOCK;