From 70f54edf7bea9bfc29b4eccf435b27b8c635cfec Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 8 Oct 2005 04:51:26 +0000 Subject: [PATCH] STABLE14-windows-byte-range-locks-20051007 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 | 2 +- src/WINNT/afsd/cm_scache.h | 1 + src/WINNT/afsd/cm_vnodeops.c | 37 ++++++++++++++++++++++++------------ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index b29d845ea..ae7b9f2d3 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -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, diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index b99c63351..1ffb478fe 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -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 */ diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index b8ff5cf85..af340603d 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -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; -- 2.39.5