Windows: Avoid deadlock on VolumeCB->VolumeLock
authorJeffrey Altman <jaltman@your-file-system.com>
Thu, 24 May 2012 08:57:19 +0000 (04:57 -0400)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 31 May 2012 23:35:01 +0000 (16:35 -0700)
commit06a602bfd40661ef89b3d6b39dd8574015a15b92
treed0d3087947fd29a31e1b2a9e8992d59cda4da7df
parent02018d729f3d1b1177ee271d566b8acba488a515
Windows: Avoid deadlock on VolumeCB->VolumeLock

AFSPrimaryVolumeWorkerThread() holds VolumeCB->VolumeLock SHARED
across the call to AFSCleanupFcb() -> CcPurgeCacheSection().
If a filter driver such as Sophos (savonaccessfilter.sys ->
savonaccesscontrol.sys) triggers an AFSCreate() in response to
the cache section being purged that will force the evaluation of
the file path by AFSLocateNameEntry().  If the path contains a
mount point that requires validation, AFSBuildMountPointTarget()
is called which in turn required the VolumeCB->VolumeLock EXCL.

AFSBuildMountPointTarget() only requires the VolumeCB->VolumeLock
if the VolumeCB->RootFcb == NULL.  That should only be true if
the VolumeCB was allocated by AFSInitVolume() or under very rare
race conditions.

This patchset refactors AFSInitVolume() to ensure that it holds
an extra VolumeCB->VolumeReferenceCount reference.  This reference
is used to assist in the refactoring of AFSBuildRootVolume() and
AFSBuildMountPointTarget() to avoid races with volume root object
invalidation as well as permitting the VolumeCB->VolumeLock to
be ignored in the common case.

Avoiding the acquisition of VolumeCB->VolumeLock during mount
point target evaluation has the additional benefit of reducing
lock contention during path evaluation.

FIXES 130812

Change-Id: Id9b0dcc2bfd91277d522f3724893b60ce4d947f5
Reviewed-on: http://gerrit.openafs.org/7474
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Peter Scott <pscott@kerneldrivers.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>
src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp