Windows: Avoid race during cm_FreeServerList
authorJeffrey Altman <jaltman@your-file-system.com>
Tue, 5 Mar 2013 12:52:37 +0000 (07:52 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Mon, 11 Mar 2013 13:50:45 +0000 (06:50 -0700)
commit1b048f1f571eb02976a78a4dabafb3c677fbf9d0
tree2ba7fb2d683ad7028296b8e27c1763521f268299
parentf4373e7867abd50b3fe39716073811794fe62379
Windows: Avoid race during cm_FreeServerList

cm_FreeServerList obtains cm_serverLock exclusively and in some
circumstances will call cm_FreeServer().   cm_FreeServer() will
drop the cm_serverLock if the cm_server_t.refCount is zero in order to
avoid a lock order violation when calling cm_GCConnections() since
cm_connLock is higher in the lock hierarchy.

The call to cm_FreeServer is performed after the cm_serverRef_t
to be deleted is identified but before it is removed from the list.
There is the potential for two threads calling cm_FreeServerList()
to race and for more than one thread to attempt to delete the same
cm_serverRef_t twice.

Fix this by:

1. maintain a private copy of the cm_server_t pointer, delete the
cm_serverRef_t and update the list pointers before calling cm_FreeServer().

2. obtain and release a refcnt on the next cm_serverRef_t to ensure
that it is not deleted out from underneath the thread in case the
cm_serverLock is dropped.

Change-Id: Ia7b6eed66e9ba306c07d47027262e1a8ad1e52ac
Reviewed-on: http://gerrit.openafs.org/9391
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
src/WINNT/afsd/cm_server.c