From: Jeffrey Altman Date: Sat, 8 Oct 2005 04:49:50 +0000 (+0000) Subject: windows-byte-range-locks-20051007 X-Git-Tag: openafs-devel-1_5_0~274 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=2dcb1cdc3d6f10b366d2b93970f5f1f83287e157 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. --- diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index b29d845..ae7b9f2 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 b99c633..1ffb478 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 11336d2..707c9aa 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; @@ -3046,7 +3049,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) @@ -3169,6 +3172,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 @@ -3251,6 +3257,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 @@ -3503,7 +3512,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"); } @@ -3541,8 +3550,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; @@ -3565,7 +3572,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); } @@ -4062,9 +4069,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; } @@ -4075,8 +4081,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)) { @@ -4130,6 +4142,7 @@ void cm_CheckLocks() scp = fileLock->scp; osi_assert(scp != NULL); + cm_HoldSCacheNoLock(scp); #ifdef DEBUG @@ -4387,8 +4400,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;