Windows: Correct lock error codes and log file server lockCount
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 12 Oct 2009 12:28:54 +0000 (08:28 -0400)
committerJeffrey Altman <jaltman|account-1000011@unknown>
Mon, 12 Oct 2009 14:27:29 +0000 (07:27 -0700)
The error codes that should be returned when a lock request
fails are:

  STATUS_LOCK_NOT_GRANTED for an explicit lock request
  STATUS_SHARING_VIOLATION when a CreateFile fails due to a previous lock

Correct the service to ensure that these values are in fact returned.

Also, add 'fsLockCount' field to cm_scache_t and dump its value
as part of the "fs memdump" output.  This permits some ability to
identify what the file server thinks the lock count is.

LICENSE MIT

Reviewed-on: http://gerrit.openafs.org/646
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>

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

index 07881b3..8c373da 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef CM_MEMMAP_H
 #define CM_MEMMAP_H 1
 
-#define CM_CONFIG_DATA_VERSION  6
+#define CM_CONFIG_DATA_VERSION  7
 #define CM_CONFIG_DATA_MAGIC            ('A' | 'F'<<8 | 'S'<<16 | CM_CONFIG_DATA_VERSION<<24)
 
 typedef struct cm_config_data {
index fca77ef..c86453f 100644 (file)
@@ -235,6 +235,7 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags)
     scp->exclusiveLocks = 0;
     scp->sharedLocks = 0;
     scp->lockDataVersion = CM_SCACHE_VERSION_BAD;
+    scp->fsLockCount = 0;
 
     /* not locked, but there can be no references to this guy
      * while we hold the global refcount lock.
@@ -794,7 +795,8 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
         scp->group=0;
         scp->dataVersion=cm_data.fakeDirVersion;
         scp->bufDataVersionLow=cm_data.fakeDirVersion;
-        scp->lockDataVersion=-1; /* no lock yet */
+        scp->lockDataVersion=CM_SCACHE_VERSION_BAD; /* no lock yet */
+        scp->fsLockCount=0;
         lock_ReleaseWrite(&scp->rw);
         lock_ReleaseWrite(&cm_scacheLock);
        *outScpp = scp;
@@ -1542,6 +1544,7 @@ void cm_MergeStatus(cm_scache_t *dscp,
         statusp->Group = 0;
         statusp->SyncCounter = 0;
         statusp->dataVersionHigh = (afs_uint32)(cm_data.fakeDirVersion >> 32);
+        statusp->lockCount = 0;
         statusp->errorCode = 0;
     }
 #endif /* AFS_FREELANCE_CLIENT */
@@ -1565,6 +1568,7 @@ void cm_MergeStatus(cm_scache_t *dscp,
        scp->anyAccess = 0;
        scp->dataVersion = CM_SCACHE_VERSION_BAD;
         scp->bufDataVersionLow = CM_SCACHE_VERSION_BAD;
+        scp->fsLockCount = 0;
 
        if (dscp) {
             scp->parentVnode = dscp->fid.vnode;
@@ -1666,7 +1670,8 @@ void cm_MergeStatus(cm_scache_t *dscp,
     /* and other stuff */
     scp->parentVnode = statusp->ParentVnode;
     scp->parentUnique = statusp->ParentUnique;
-        
+    scp->fsLockCount = 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.
      */
@@ -1958,10 +1963,10 @@ int cm_DumpSCache(FILE *outputFile, char *cookie, int lock)
   
     for (scp = cm_data.allSCachesp; scp; scp = scp->allNextp) 
     {
-        sprintf(output, "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) type=%d dv=%I64d len=0x%I64x mp='%s' Locks (server=0x%x shared=%d excl=%d clnt=%d) flags=0x%x cb=0x%x refCount=%u\r\n", 
+        sprintf(output, "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) type=%d dv=%I64d len=0x%I64x mp='%s' Locks (server=0x%x shared=%u excl=%u clnt=%u) lockCount=%d flags=0x%x cb=0x%x refCount=%u\r\n",
                 cookie, scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique, 
                 scp->fileType, scp->dataVersion, scp->length.QuadPart, scp->mountPointStringp, 
-                scp->serverLock, scp->sharedLocks, scp->exclusiveLocks, scp->clientLocks, 
+                scp->serverLock, scp->sharedLocks, scp->exclusiveLocks, scp->clientLocks, scp->fsLockCount,
                 scp->flags, (unsigned long)scp->cbExpires, scp->refCount);
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
 
index df5ca40..79046f9 100644 (file)
@@ -189,6 +189,11 @@ typedef struct cm_scache {
     afs_uint32   clientLocks;   /* number of locks on ::fileLocks that
                                    have CM_FILELOCK_FLAG_CLIENTONLY
                                    set. */
+
+    afs_uint32   fsLockCount;   /* number of locks held as reported
+                                 * by the file server in the most
+                                 * recent fetch status.
+                                 */
        
     /* bulk stat progress */
     osi_hyper_t bulkStatProgress;      /* track bulk stats of large dirs */
index 927b184..addbe23 100644 (file)
@@ -4701,6 +4701,10 @@ long cm_Lock(cm_scache_t *scp, unsigned char sLockType,
                  "cm_Lock Rejecting lock (code = 0x%x)", code);
     }
 
+    /* Convert from would block to lock not granted */
+    if (code == CM_ERROR_WOULDBLOCK)
+        code = CM_ERROR_LOCK_NOT_GRANTED;
+
     return code;
 }
 
index 3b19838..39acf88 100644 (file)
@@ -6454,7 +6454,7 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                            userp, &req, &lockp);
        }
 
-        if (code == CM_ERROR_WOULDBLOCK && Timeout != 0) {
+        if (code == CM_ERROR_LOCK_NOT_GRANTED && Timeout != 0) {
             smb_waitingLock_t * wLock;
 
             /* Put on waiting list */
@@ -7894,7 +7894,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
            smb_CloseFID(vcp, fidp, NULL, 0);
            smb_ReleaseFID(fidp);
             free(realPathp);
-            return code;
+            return CM_ERROR_SHARING_VIOLATION;
         }
     }