windows-smb-dead-vc-gc-20080801

LICENSE MIT

deltas windows-smb-dead-vc-gc-20080627 and
windows-dead-vc-cleanup-take-two-20080703 attempted to
protect against an infinite recursion when cleaning up
dead smb virtual circuits.  they failed to address the
incrementing of the vc refcount in smb_ReleaseVCInternal
when it is about to call smb_CleanupDeadVC.  If the vc
is already being cleaned, then smb_ReleaseVCInternal
should not increment the refCount and should not call
smb_CleanupDeadVC.
This commit is contained in:
Jeffrey Altman 2008-08-01 14:09:50 +00:00
parent 0c20d8adb0
commit 890cbf6cae

View File

@ -1023,32 +1023,34 @@ void smb_ReleaseVCInternal(smb_vc_t *vcp)
break;
}
osi_Log3(smb_logp,"VCP not dead and %sin smb_allVCsp vcp %x ref %d",
avcp?"not ":"",vcp, vcp->refCount);
#ifdef DEBUG
GenerateMiniDump(NULL);
#endif
avcp?"":"not ",vcp, vcp->refCount);
/* This is a wrong. However, I suspect that there is an undercount
* and I don't want to release 1.4.1 in a state that will allow
* smb_vc_t objects to be deallocated while still in the
* smb_allVCsp list. The list is supposed to keep a reference
* to the smb_vc_t. Put it back.
*/
if (avcp)
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
* be cleaned up. If we were not called by smb_CleanupDeadVC(),
* 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.
*/
if (!(vcp->flags & SMB_VCFLAG_CLEAN_IN_PROGRESS)) {
vcp->refCount++; /* put the refCount back */
lock_ReleaseWrite(&smb_rctLock);
smb_CleanupDeadVC(vcp);
lock_ObtainWrite(&smb_rctLock);
}
}
}
void smb_ReleaseVCNoLock(smb_vc_t *vcp)
{