From a6138b412d3b4197b22ca7fb63d8cdc9671ef67c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 18 Aug 2011 21:53:45 -0400 Subject: [PATCH] Windows: Track file server lock count The fsLockCount field is the lock count reported by the file server as part of the status info. Lock acquisition and releasing does not obtain new status info but we can estimate what the lock count is by tracking it ourselves for each of our successful RXAFS_SetLock and RXAFS_ReleaseLock RPCs and failed RXAFS_ExtendLock RPCs. Change-Id: Ib5dc5853d82a1292e848bf67d4d9932485177d91 Reviewed-on: http://gerrit.openafs.org/5298 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_scache.c | 4 +++- src/WINNT/afsd/cm_scache.h | 6 ++++-- src/WINNT/afsd/cm_vnodeops.c | 25 ++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 5719838e5a..906ba892f4 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -1691,7 +1691,9 @@ void cm_MergeStatus(cm_scache_t *dscp, /* and other stuff */ scp->parentVnode = statusp->ParentVnode; scp->parentUnique = statusp->ParentUnique; - scp->fsLockCount = statusp->lockCount; + + /* -1 is a write lock; any positive values are read locks */ + scp->fsLockCount = (afs_int32)statusp->lockCount; /* and merge in the private acl cache info, if this is more than the public * info; merge in the public stuff in any case. diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index 935153dc33..d14f398614 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -193,9 +193,11 @@ typedef struct cm_scache { have CM_FILELOCK_FLAG_CLIENTONLY set. */ - afs_uint32 fsLockCount; /* number of locks held as reported + afs_int32 fsLockCount; /* number of locks held as reported * by the file server in the most - * recent fetch status. + * recent fetch status. Updated by + * the locks known to have been acquired + * or released by this client. */ /* bulk stat progress */ diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index f45f59f602..8e4fd10078 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -4403,8 +4403,20 @@ long cm_IntSetLock(cm_scache_t * scp, cm_user_t * userp, int lockType, osi_Log0(afsd_logp, "CALL SetLock SUCCESS"); } - lock_ObtainWrite(&scp->rw); reqp->flags = reqflags; + + lock_ObtainWrite(&scp->rw); + if (code == 0) { + /* + * The file server does not return a status structure so we must + * locally track the file server lock count to the best of our + * ability. + */ + if (lockType == LockWrite) + scp->fsLockCount = -1; + else + scp->fsLockCount++; + } return code; } @@ -4454,6 +4466,16 @@ long cm_IntReleaseLock(cm_scache_t * scp, cm_user_t * userp, "CALL ReleaseLock SUCCESS"); lock_ObtainWrite(&scp->rw); + if (code == 0) { + /* + * The file server does not return a status structure so we must + * locally track the file server lock count to the best of our + * ability. + */ + scp->fsLockCount--; + if (scp->fsLockCount < 0) + scp->fsLockCount = 0; + } return (code != CM_ERROR_BADFD ? code : 0); } @@ -5421,6 +5443,7 @@ void cm_CheckLocks() if (code) { osi_Log1(afsd_logp, "CALL ExtendLock FAILURE, code 0x%x", code); + scp->fsLockCount = 0; } else { osi_Log0(afsd_logp, "CALL ExtendLock SUCCESS"); scp->lockDataVersion = scp->dataVersion;