From: Jeffrey Altman Date: Fri, 1 Aug 2008 14:14:50 +0000 (+0000) Subject: windows-smb-dead-vc-gc-on-head-20080801 X-Git-Tag: openafs-devel-1_5_61~923 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=ebf66eff4b0e68e06c26522ae29e33a5b6fb3298;p=packages%2Fo%2Fopenafs.git windows-smb-dead-vc-gc-on-head-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 was committed incorrectly to the 1-5 branch first. delta name on the head was modified to avoid the delta name collision.) --- diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 521606b30..c4f785c04 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -941,30 +941,32 @@ 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. - */ - vcp->refCount++; + */ + 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. */ - vcp->refCount++; /* put the refCount back */ - lock_ReleaseWrite(&smb_rctLock); - smb_CleanupDeadVC(vcp); - lock_ObtainWrite(&smb_rctLock); + 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); + } } }