Windows: cm_buf refcnt must hold buf_globalLock
authorJeffrey Altman <jaltman@your-file-system.com>
Thu, 19 Jan 2012 20:25:44 +0000 (15:25 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 19 Jan 2012 23:49:09 +0000 (15:49 -0800)
commit22cba8e9702f3673c335bf834a9ee2c5e5fd9b6e
treeb81dfba60ee8269014dbac733626565a2e4baf92
parent201c954a36fe6ec19f96e4c8e24e6e080c3ba55a
Windows: cm_buf refcnt must hold buf_globalLock

An assertion in buf_Recycle() was being triggered when a cm_buf_t
object was supposed to be in the free buffer list but wasn't.
buf_Recycle() was racing with another thread.  The test for
refCount == 0 was performed while holding the buf_globalLock
exclusively but the InterlockedDecrement(refCount) in buf_Release()
was performed without holding buf_globalLock at all.  buf_globalLOck
must be held at least as a read lock.  Otherwise, the refCount can
reach 0 prior to the thread blocking for exclusive access to the
buf_globalLock.  This provides buf_Recycle() which is holding
buf_globalLock the opportunity to race.

The solution is to make sure that buf_Release() always holds
buf_globalLock as a read lock and then use buf_ReleaseLocked()
to perform the actual decrement and test.

Change-Id: Ieb67548a7e44fa5f06f9346f428b1edadfc80696
Reviewed-on: http://gerrit.openafs.org/6576
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>
src/WINNT/afsd/cm_buf.c