Windows: Protect ObjectRefCnts with ObjectInfoLock
authorJeffrey Altman <jaltman@your-file-system.com>
Fri, 5 Oct 2012 15:36:45 +0000 (11:36 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Fri, 19 Oct 2012 14:01:56 +0000 (07:01 -0700)
The ObjectInfoCB.ObjectReferenceCount is tested to determined
when it is safe to remove an FCB from the ObjectInfoCB.  The
value must not be permitted to change while a removal is performed.

Protect AFSRemoveFcb() calls with exclusive holds of the
ObjectInfoCB.NonPagedInfo->ObjectInfoLock.  New functions:

  AFSObjectInfoIncrement()
  AFSObjectInfoDecrement()

perform all increments and decrements while holding the
ObjectInfoLock in a Shared state.

Change-Id: If89b7668ef0a891d55b039d9516620b581c79e10
Reviewed-on: http://gerrit.openafs.org/8224
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Rod Widdowson <rdw@steadingsoftware.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp
src/WINNT/afsrdr/kernel/lib/AFSClose.cpp
src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp
src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp
src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h
src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h

index 038fe55..d8a7081 100644 (file)
@@ -658,7 +658,7 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                     // The ObjectReferenceCount will be freed by AFSPerformObjectInvalidate
                     //
 
-                    InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                    AFSObjectInfoIncrement( pObjectInfo);
 
                     ClearFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
 
index 08b5a02..486b5a9 100644 (file)
@@ -394,6 +394,9 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject,
                         AFSDeleteDirEntry( pObjectInfo->ParentObjectInformation,
                                            pDirCB);
 
+                        AFSAcquireShared( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
+                                          TRUE);
+
                         if( pObjectInfo->ObjectReferenceCount <= 0)
                         {
 
@@ -413,6 +416,8 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject,
 
                             SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
                         }
+
+                        AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
                     }
 
                     AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
index 80e427d..3903396 100644 (file)
@@ -311,7 +311,7 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
                             // The ObjectReferenceCount will be freed by AFSPerformObjectInvalidate
                             //
 
-                            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
                             AFSPerformObjectInvalidate( pObjectInfo,
                                                         AFS_INVALIDATE_DATA_VERSION);
@@ -1090,13 +1090,13 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                             // lock hierarchy.
                             //
 
-                            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
                             if ( !NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
                                                                         AFS_INVALIDATE_DATA_VERSION)))
                             {
 
-                                lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+                                lCount = AFSObjectInfoDecrement( pObjectInfo);
                             }
                         }
                         else
index b860829..d55e927 100644 (file)
@@ -2225,7 +2225,12 @@ try_exit:
             if( bAllocatedFcb)
             {
 
+                AFSAcquireExcl( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
+                                TRUE);
+
                 AFSRemoveFcb( &pObjectInfo->Fcb);
+
+                AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
             }
 
             *Fcb = NULL;
@@ -2517,7 +2522,12 @@ try_exit:
             if( bAllocatedFcb)
             {
 
+                AFSAcquireExcl( &pParentObject->NonPagedInfo->ObjectInfoLock,
+                                TRUE);
+
                 AFSRemoveFcb( &pParentObject->Fcb);
+
+                AFSReleaseResource( &pParentObject->NonPagedInfo->ObjectInfoLock);
             }
 
             *Fcb = NULL;
@@ -3029,7 +3039,12 @@ try_exit:
             if( bAllocatedFcb)
             {
 
+                AFSAcquireExcl( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
+                                TRUE);
+
                 AFSRemoveFcb( &pObjectInfo->Fcb);
+
+                AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
             }
 
             *Fcb = NULL;
@@ -3461,7 +3476,12 @@ try_exit:
             if( bAllocatedFcb)
             {
 
+                AFSAcquireExcl( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
+                                TRUE);
+
                 AFSRemoveFcb( &pObjectInfo->Fcb);
+
+                AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
             }
 
             *Fcb = NULL;
@@ -3772,7 +3792,12 @@ try_exit:
                 // Need to tear down this Fcb since it is not in the tree for the worker thread
                 //
 
+                AFSAcquireExcl( &pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                                TRUE);
+
                 AFSRemoveFcb( &pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
+
+                AFSReleaseResource( &pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
             }
 
             *Fcb = NULL;
@@ -4006,7 +4031,12 @@ try_exit:
                 // Need to tear down this Fcb since it is not in the tree for the worker thread
                 //
 
+                AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                                TRUE);
+
                 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
+
+                AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
             }
 
             *Fcb = NULL;
index ccf13c0..06bd73c 100644 (file)
@@ -1367,7 +1367,7 @@ AFSProcessSetFileExtents( IN AFSSetFileExtentsCB *SetExtents )
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -1448,7 +1448,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -1853,7 +1853,7 @@ AFSFindFcbToClean(ULONG IgnoreTime, AFSFcb *LastFcb, BOOLEAN Block)
                 // A hit a very palpable hit.  Pin it
                 //
 
-                lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pCurrentObject);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -1991,7 +1991,7 @@ AFSProcessExtentFailure( PIRP Irp)
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2052,7 +2052,7 @@ AFSProcessExtentFailure( PIRP Irp)
 
         AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
 
-        lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+        lCount = AFSObjectInfoDecrement( pObjectInfo);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -2229,7 +2229,7 @@ AFSProcessReleaseFileExtents( IN PIRP Irp)
                 // Reference the node so it won't be torn down
                 //
 
-                lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pObjectInfo);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -2454,7 +2454,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
index 38d588b..83faba8 100644 (file)
@@ -262,6 +262,8 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry)
 
         pFcb->ObjectInformation = pObjectInfo;
 
+        AFSAcquireShared( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
+                          TRUE);
         //
         // Swap the allocated FCB into the ObjectInformation structure if it
         // does not already have one.
@@ -283,12 +285,16 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry)
                           &pObjectInfo->Fcb->NPFcb->Resource,
                           PsGetCurrentThread());
 
+            AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
+
             AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
                             TRUE);
 
             try_return( ntStatus = STATUS_REPARSE);
         }
 
+        AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
+
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
@@ -507,6 +513,8 @@ AFSInitVolume( IN GUID *AuthGroup,
         RtlZeroMemory( pNonPagedObject,
                        sizeof( AFSNonPagedObjectInfoCB));
 
+        ExInitializeResourceLite( &pNonPagedObject->ObjectInfoLock);
+
         ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
 
         pVolumeCB->NonPagedVcb = pNonPagedVcb;
@@ -674,7 +682,7 @@ try_exit:
             if( pNonPagedObject != NULL)
             {
 
-                ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
+                ExDeleteResourceLite( &pNonPagedObject->ObjectInfoLock);
 
                 AFSExFreePoolWithTag( pNonPagedObject, AFS_NP_OBJECT_INFO_TAG);
             }
@@ -782,7 +790,12 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
             if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
             {
 
+                AFSAcquireExcl( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                                TRUE);
+
                 AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
+
+                AFSReleaseResource( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
             }
 
             AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
@@ -826,6 +839,8 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
         if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
         {
 
+            ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
             ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
 
             AFSExFreePoolWithTag( VolumeCB->ObjectInformation.NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
index 2823940..91faa96 100644 (file)
@@ -672,7 +672,7 @@ AFSInitializeGlobalDirectoryEntries()
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -779,7 +779,7 @@ AFSInitializeGlobalDirectoryEntries()
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -976,7 +976,7 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                           FileName);
         }
 
-        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -1202,7 +1202,7 @@ try_exit:
             if( pObjectInfoCB != NULL)
             {
 
-                lCount = InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
+                lCount = AFSObjectInfoDecrement( pObjectInfoCB);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -2031,7 +2031,7 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2066,7 +2066,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2510,7 +2510,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
         if ( pCurrentObject )
         {
 
-            lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pCurrentObject);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2524,7 +2524,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
             if ( pCurrentObject)
             {
 
-                lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoDecrement( pCurrentObject);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -2550,7 +2550,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pCurrentObject);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2571,7 +2571,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
                 // Reference the node so it won't be torn down
                 //
 
-                lCount = InterlockedIncrement( &pNextObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pNextObject);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -2588,7 +2588,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
             if ( pCurrentObject )
             {
 
-                lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoDecrement( pCurrentObject);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -5922,7 +5922,7 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
             // Increment the open reference and handle on the node
             //
 
-            lCount = InterlockedIncrement( &pDirNode->ObjectInformation->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pDirNode->ObjectInformation);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -6461,6 +6461,8 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
 
         ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
 
+        ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
+
         pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
 
         pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
@@ -6469,7 +6471,7 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
 
         if( ParentObjectInfo != NULL)
         {
-            lCount = InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( ParentObjectInfo);
         }
 
         //
@@ -6535,6 +6537,40 @@ try_exit:
     return pObjectInfo;
 }
 
+LONG
+AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo)
+{
+
+    LONG lCount;
+
+    AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                      TRUE);
+
+    lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+
+    AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+    return lCount;
+}
+
+LONG
+AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo)
+{
+
+    LONG lCount;
+
+    AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                      TRUE);
+
+    lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
+
+    AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+    return lCount;
+}
+
+
+
 void
 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
 {
@@ -6605,7 +6641,7 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
     if( ObjectInfo->ParentObjectInformation != NULL)
     {
 
-        lCount = InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
+        lCount = AFSObjectInfoDecrement( ObjectInfo->ParentObjectInformation);
     }
 
     if( bAcquiredTreeLock)
@@ -6624,6 +6660,8 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
         AFSReleaseFid( &ObjectInfo->FileId);
     }
 
+    ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
     ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
 
     AFSExFreePoolWithTag( ObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
@@ -8051,7 +8089,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
                 pObjectInfo = &pVolumeCB->ObjectInformation;
 
-                lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pObjectInfo);
 
                 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
             }
@@ -8082,7 +8120,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                     // Reference the node so it won't be torn down
                     //
 
-                    lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                    lCount = AFSObjectInfoIncrement( pObjectInfo);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -8252,7 +8290,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
             pObjectInfo = pDirectoryEntry->ObjectInformation;
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             if( pVolumeCB != NULL)
             {
@@ -8312,7 +8350,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
         }
 
         if( pNameArray != NULL)
@@ -9321,7 +9359,8 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
 
         if( ObjectInfo != NULL)
         {
-            InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
+
+            AFSObjectInfoDecrement( ObjectInfo);
         }
     }
 
index 028e15f..09407fe 100644 (file)
@@ -1673,6 +1673,9 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     AFSDeleteDirEntry( pParentObjectInfo,
                                        pDirEntry);
 
+                    AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+                                      TRUE);
+
                     if( pCurrentObject->ObjectReferenceCount <= 0)
                     {
 
@@ -1690,6 +1693,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                             ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
                         }
                     }
+
+                    AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
                 }
                 else
                 {
@@ -2460,7 +2465,7 @@ AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
 
         ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
 
-        lCount = InterlockedDecrement( &DirEntry->ObjectInformation->ObjectReferenceCount);
+        lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation);
 
         if( lCount <= 0)
         {
@@ -2471,7 +2476,7 @@ AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSDeleteDirEntry Decrement count on object %08lX Cnt %d\n",
                       DirEntry->ObjectInformation,
-                      DirEntry->ObjectInformation->ObjectReferenceCount);
+                      lCount);
 
         ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
 
index 869e145..fc90bd7 100644 (file)
@@ -1066,6 +1066,9 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
 
                 pNextVolume = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
 
+                AFSAcquireShared( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock,
+                                  TRUE);
+
                 if( pVolumeCB->ObjectInfoListHead == NULL &&
                     pVolumeCB->DirectoryCB->OpenReferenceCount == 0 &&
                     pVolumeCB->VolumeReferenceCount == 1 &&
@@ -1080,11 +1083,15 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                         AFSRemoveRootFcb( pVolumeCB->RootFcb);
                     }
 
+                    AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
                     AFSRemoveVolume( pVolumeCB);
                 }
                 else
                 {
 
+                    AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
                     AFSReleaseResource( pVolumeCB->VolumeLock);
                 }
 
@@ -1171,6 +1178,9 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                                 FALSE))
                             {
 
+                                AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+                                                TRUE);
+
                                 if ( pCurrentObject->ObjectReferenceCount <= 0 &&
                                      ( pCurrentObject->Fcb == NULL ||
                                        pCurrentObject->Fcb->OpenReferenceCount == 0 &&
@@ -1182,8 +1192,13 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                     if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
                                     {
 
+                                        AFSAcquireExcl( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                                                        TRUE);
+
                                         AFSRemoveFcb( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
 
+                                        AFSReleaseResource( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
+
                                         AFSDeleteObjectInfo( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
 
                                         ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
@@ -1193,6 +1208,8 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                         AFSExFreePoolWithTag( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
                                     }
 
+                                    AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+
                                     AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                                                   AFS_TRACE_LEVEL_VERBOSE,
                                                   "AFSPrimaryVolumeWorkerThread Deleting deleted object %08lX\n",
@@ -1200,6 +1217,11 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
 
                                     AFSDeleteObjectInfo( pCurrentObject);
                                 }
+                                else
+                                {
+
+                                    AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+                                }
 
                                 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
 
@@ -1360,6 +1382,15 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                     AFSDeleteDirEntry( pCurrentObject,
                                                        pCurrentDirEntry);
 
+
+                                    //
+                                    // Acquire ObjectInfoLock shared here so as not to deadlock
+                                    // with an invalidation call from the service during AFSCleanupFcb
+                                    //
+
+                                    AFSAcquireShared( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock,
+                                                      TRUE);
+
                                     if( pCurrentChildObject->ObjectReferenceCount <= 0 &&
                                         pCurrentChildObject->Fcb != NULL &&
                                         pCurrentChildObject->FileType == AFS_FILE_TYPE_FILE)
@@ -1385,6 +1416,11 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                                         TRUE);
                                     }
 
+                                    AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+
+                                    AFSAcquireExcl( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock,
+                                                    TRUE);
+
                                     if( pCurrentChildObject->ObjectReferenceCount <= 0 &&
                                         ( pCurrentChildObject->Fcb == NULL ||
                                           pCurrentChildObject->Fcb->OpenReferenceCount == 0 &&
@@ -1397,8 +1433,13 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                             pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
                                         {
 
+                                            AFSAcquireExcl( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                                                            TRUE);
+
                                             AFSRemoveFcb( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
 
+                                            AFSReleaseResource( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
+
                                             AFSDeleteObjectInfo( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
 
                                             ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
@@ -1408,6 +1449,8 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                             AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
                                         }
 
+                                        AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+
                                         AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                                                       AFS_TRACE_LEVEL_VERBOSE,
                                                       "AFSPrimaryVolumeWorkerThread Deleting object %08lX\n",
@@ -1415,6 +1458,11 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
 
                                         AFSDeleteObjectInfo( pCurrentChildObject);
                                     }
+                                    else
+                                    {
+
+                                        AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+                                    }
 
                                     pCurrentDirEntry = pNextDirEntry;
 
@@ -1523,6 +1571,9 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                             break;
                         }
 
+                        AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+                                        TRUE);
+
                         if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
                             pCurrentObject->ObjectReferenceCount <= 0 &&
                             ( pCurrentObject->Fcb == NULL ||
@@ -1532,8 +1583,15 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
 
                             AFSRemoveFcb( &pCurrentObject->Fcb);
 
+                            AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+
                             AFSDeleteObjectInfo( pCurrentObject);
                         }
+                        else
+                        {
+
+                            AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+                        }
 
                         AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
 
index ffe1754..022a6ba 100644 (file)
@@ -1298,6 +1298,12 @@ AFSObjectInfoCB *
 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
                        IN ULONGLONG HashIndex);
 
+LONG
+AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo);
+
+LONG
+AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo);
+
 void
 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo);
 
index d434073..8e98b31 100644 (file)
@@ -178,6 +178,8 @@ typedef struct _AFS_NONPAGED_OBJECT_INFO_CB
 
     ERESOURCE           DirectoryNodeHdrLock;
 
+    ERESOURCE           ObjectInfoLock;
+
 } AFSNonPagedObjectInfoCB;
 
 typedef struct _AFS_OBJECT_INFORMATION_CB