]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-windows-smb-dead-vc-gc-20080627
authorJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 27 Jun 2008 20:45:11 +0000 (20:45 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 27 Jun 2008 20:45:11 +0000 (20:45 +0000)
LICENSE MIT

When an SMB virtual circuit is prematurely closed due to an error
condition by one thread it is possible that there are still several
other threads still using the VC which will determine that the VC
is dead shortly.  As a result we maintain a dead vc list to ensure
that dead vcs are not destroyed while still in use.

With the addition of locking though this causes a problem because the
locks allocated to the virtual circuit are not freed until the vc is
destroyed.

This patch reworks the cleanup routine to make the freeing of resources
the responsibility of the release routine when the refcount hits 0
and the VC is marked dead.

(cherry picked from commit 49db6afe0aeb646d712a5319a7ea1a511f66f298)

src/WINNT/afsd/smb.c

index d0287e8cb2c96140015b482bf62262609d4326c7..9a4002a9f009d09701526b551dc1ae2b998da092 100644 (file)
@@ -947,6 +947,18 @@ void smb_ReleaseVCInternal(smb_vc_t *vcp)
              */
             vcp->refCount++;
         }
+    } else if (vcp->flags & SMB_VCFLAG_ALREADYDEAD) {
+        /* The reference count is non-zero but the VC is dead.
+         * This implies that some FIDs, TIDs, etc on the VC have yet to 
+         * be cleaned up.  Add a reference that will be dropped by
+         * smb_CleanupDeadVC() and try to cleanup the VC again.
+         * Eventually the refCount will drop to zero when all of the
+         * active threads working with the VC end their task.
+         */
+        vcp->refCount++;        /* put the refCount back */
+        lock_ReleaseWrite(&smb_rctLock);
+        smb_CleanupDeadVC(vcp);
+        lock_ObtainWrite(&smb_rctLock);
     }
 }
 
@@ -1065,10 +1077,14 @@ void smb_CleanupDeadVC(smb_vc_t *vcp)
        uidpNext = vcp->usersp;
     }
 
+    lock_ObtainMutex(&vcp->mx);
+    vcp->flags &= ~SMB_VCFLAG_CLEAN_IN_PROGRESS;
+    lock_ReleaseMutex(&vcp->mx);
+
     /* The vcp is now on the deadVCsp list.  We intentionally drop the
      * reference so that the refcount can reach 0 and we can delete it */
     smb_ReleaseVCNoLock(vcp);
-    
+
     lock_ReleaseWrite(&smb_rctLock);
     osi_Log1(smb_logp, "Finished cleaning up dead vcp 0x%x", vcp);
 }