Windows: avoid deadlock TreeLock vs Fcb Resource
authorJeffrey Altman <jaltman@your-file-system.com>
Fri, 18 May 2012 20:31:19 +0000 (16:31 -0400)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 21 May 2012 14:26:01 +0000 (07:26 -0700)
Cannot call AFSPerformObjectInvalidate directly because
ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock is
held during the sequence

  AFSVerifyEntry->AFSValidateDirectoryCache->AFSVerifyDirectoryContent

and AFSPerformObjectInvalidate requires the Fcb->NPFcb->Resource
which must be held prior to the TreeLock.

Change-Id: I337f52e2927c8e5ae2d218867987625c3240a792
Reviewed-on: http://gerrit.openafs.org/7423
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>

src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp

index 763c45d..771041b 100644 (file)
@@ -1070,12 +1070,22 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
 
                             //
                             // The ObjectReferenceCount will be freed by AFSPerformObjectInvalidate
+                            // if successfully queued.  Cannot call AFSPerformObjectInvalidate directly
+                            // because ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock is
+                            // held during the sequence AFSVerifyEntry->AFSValidateDirectoryCache->
+                            // AFSVerifyDirectoryContent and AFSPerformObjectInvalidate requires the
+                            // Fcb->NPFcb->Resource which must be held prior to the TreeLock in the
+                            // lock hierarchy.
                             //
 
                             lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
 
-                            AFSPerformObjectInvalidate( pObjectInfo,
-                                                        AFS_INVALIDATE_DATA_VERSION);
+                            if ( !NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
+                                                                        AFS_INVALIDATE_DATA_VERSION)))
+                            {
+
+                                lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+                            }
                         }
                         else
                         {