Windows: Track file server lock count
authorJeffrey Altman <jaltman@your-file-system.com>
Fri, 19 Aug 2011 01:53:45 +0000 (21:53 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Tue, 23 Aug 2011 19:12:45 +0000 (12:12 -0700)
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 <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>

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

index 5719838..906ba89 100644 (file)
@@ -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.
index 935153d..d14f398 100644 (file)
@@ -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 */
index f45f59f..8e4fd10 100644 (file)
@@ -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;