From eaad522651a81f20eac4966a55a731e0e59e39dd Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Fri, 5 Oct 2012 11:36:45 -0400 Subject: [PATCH] Windows: Protect ObjectRefCnts with ObjectInfoLock 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 Reviewed-by: Rod Widdowson Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp | 2 +- src/WINNT/afsrdr/kernel/lib/AFSClose.cpp | 5 ++ .../afsrdr/kernel/lib/AFSCommSupport.cpp | 6 +- src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp | 30 ++++++++ .../afsrdr/kernel/lib/AFSExtentsSupport.cpp | 14 ++-- src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp | 17 +++- src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp | 77 ++++++++++++++----- .../afsrdr/kernel/lib/AFSNameSupport.cpp | 9 ++- src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp | 58 ++++++++++++++ .../afsrdr/kernel/lib/Include/AFSCommon.h | 6 ++ .../afsrdr/kernel/lib/Include/AFSStructs.h | 2 + 11 files changed, 193 insertions(+), 33 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp index 038fe55d9..d8a7081a1 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp @@ -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); diff --git a/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp b/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp index 08b5a02c4..486b5a931 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp @@ -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); diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp index 80e427d3e..3903396da 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp @@ -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 diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp index b860829fc..d55e9270d 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp @@ -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; diff --git a/src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp index ccf13c07d..06bd73c79 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp @@ -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, diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp index 38d588b78..83faba82e 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp @@ -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); diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index 282394010..91faa9610 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -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); } } diff --git a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp index 028e15f41..09407fe97 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp @@ -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); diff --git a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp index 869e1456c..fc90bd7d5 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp @@ -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); diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h index ffe175434..022a6ba8f 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h @@ -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); diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h index d43407363..8e98b3146 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h @@ -178,6 +178,8 @@ typedef struct _AFS_NONPAGED_OBJECT_INFO_CB ERESOURCE DirectoryNodeHdrLock; + ERESOURCE ObjectInfoLock; + } AFSNonPagedObjectInfoCB; typedef struct _AFS_OBJECT_INFORMATION_CB -- 2.39.5