windows-smb-dead-vc-gc-20080627
[openafs.git] / src / WINNT / afsd / smb.c
index f073b81..0aa88bb 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);
 }