From 2e7c203a6cc84b2d4e4c67bd47277c19315853ae Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 28 Jan 2013 21:12:10 -0500 Subject: [PATCH] Windows: More RDR Garbage Collection This patchset addresses the failure of AFSVolumeCB, AFSDirectoryCB, and AFSObjectInformationCB objects to be garbage collected by the AFSPrimaryVolumeWorker thread. The AFSPrimaryVolumeWorker thread is broken up into smaller pieces. Change-Id: I54749960be8f22313ba7ee5f9f96438be6321f25 Reviewed-on: http://gerrit.openafs.org/8995 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp | 18 +- src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp | 131 +- src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp | 115 +- .../afsrdr/kernel/lib/AFSNameSupport.cpp | 5 +- src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp | 1367 ++++++++++------- .../afsrdr/kernel/lib/Include/AFSCommon.h | 6 +- 6 files changed, 985 insertions(+), 657 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp index 5eece7bed..20f4e9ef1 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp @@ -1449,23 +1449,13 @@ AFSOpenRoot( IN PIRP Irp, // init the volume fcb // - if( VolumeCB->RootFcb == NULL) - { - - ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(), - VolumeCB); - - if( !NT_SUCCESS( ntStatus)) - { + ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(), + VolumeCB); - try_return( ntStatus); - } - } - else + if( !NT_SUCCESS( ntStatus)) { - AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource, - TRUE); + try_return( ntStatus); } lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount); diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp index 5630ba5b8..eb1b25d81 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp @@ -152,10 +152,6 @@ AFSInitFcb( IN AFSDirectoryCB *DirEntry) ExInitializeResourceLite( &pNPFcb->CcbListLock); - pFcb->Header.Resource = &pNPFcb->Resource; - - pFcb->Header.PagingIoResource = &pNPFcb->PagingResource; - // // Grab the Fcb for processing // @@ -169,6 +165,10 @@ AFSInitFcb( IN AFSDirectoryCB *DirEntry) AFSAcquireExcl( &pNPFcb->Resource, TRUE); + pFcb->Header.Resource = &pNPFcb->Resource; + + pFcb->Header.PagingIoResource = &pNPFcb->PagingResource; + pFcb->NPFcb = pNPFcb; // @@ -820,7 +820,7 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB) AFSReleaseResource( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock); } - AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation); + AFSDeleteObjectInfo( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation); ExDeleteResourceLite( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock); @@ -946,6 +946,7 @@ AFSInitRootFcb( IN ULONGLONG ProcessID, sizeof( AFSFcb)); pFcb->Header.NodeByteSize = sizeof( AFSFcb); + pFcb->Header.NodeTypeCode = AFS_ROOT_FCB; pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool, @@ -966,6 +967,7 @@ AFSInitRootFcb( IN ULONGLONG ProcessID, sizeof( AFSNonPagedFcb)); pNPFcb->Size = sizeof( AFSNonPagedFcb); + pNPFcb->Type = AFS_NON_PAGED_FCB; // @@ -978,6 +980,12 @@ AFSInitRootFcb( IN ULONGLONG ProcessID, ExInitializeResourceLite( &pNPFcb->Resource); + ExInitializeResourceLite( &pNPFcb->PagingResource); + + ExInitializeResourceLite( &pNPFcb->SectionObjectResource); + + ExInitializeResourceLite( &pNPFcb->CcbListLock); + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n", @@ -987,10 +995,6 @@ AFSInitRootFcb( IN ULONGLONG ProcessID, AFSAcquireExcl( &pNPFcb->Resource, TRUE); - ExInitializeResourceLite( &pNPFcb->PagingResource); - - ExInitializeResourceLite( &pNPFcb->CcbListLock); - pFcb->Header.Resource = &pNPFcb->Resource; pFcb->Header.PagingIoResource = &pNPFcb->PagingResource; @@ -1001,23 +1005,77 @@ AFSInitRootFcb( IN ULONGLONG ProcessID, // Save the root Fcb in the VolumeCB // - VolumeCB->ObjectInformation.Fcb = pFcb; + pFcb->ObjectInformation = &VolumeCB->ObjectInformation; VolumeCB->ObjectInformation.VolumeCB = VolumeCB; - VolumeCB->RootFcb = pFcb; + AFSAcquireShared( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock, + TRUE); + // + // Swap the allocated FCB into the ObjectInformation structure if it + // does not already have one. + // - pFcb->ObjectInformation = &VolumeCB->ObjectInformation; + if ( InterlockedCompareExchangePointer( (PVOID *)&VolumeCB->ObjectInformation.Fcb, pFcb, NULL) != NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_WARNING, + "AFSInitRootFcb Raced Fcb %p pFcb %p\n", + VolumeCB->ObjectInformation.Fcb, + pFcb); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n", + &VolumeCB->ObjectInformation.Fcb->NPFcb->Resource, + PsGetCurrentThread()); + + AFSReleaseResource( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock); + + AFSAcquireExcl( &VolumeCB->ObjectInformation.Fcb->NPFcb->Resource, + TRUE); + + try_return( ntStatus = STATUS_REPARSE); + } + + VolumeCB->RootFcb = VolumeCB->ObjectInformation.Fcb; + + AFSReleaseResource( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock); + + AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSInitRootFcb Initialized Fcb %p\n", + &VolumeCB->ObjectInformation.Fcb); try_exit: - if( !NT_SUCCESS( ntStatus)) + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_REPARSE) { if( pFcb != NULL) { - AFSRemoveRootFcb( pFcb); + if( pNPFcb != NULL) + { + + AFSReleaseResource( &pNPFcb->Resource); + + FsRtlTeardownPerStreamContexts( &pFcb->Header); + + ExDeleteResourceLite( &pNPFcb->SectionObjectResource); + + ExDeleteResourceLite( &pNPFcb->PagingResource); + + ExDeleteResourceLite( &pNPFcb->CcbListLock); + + ExDeleteResourceLite( &pNPFcb->Resource); + + AFSExFreePoolWithTag( pNPFcb, AFS_FCB_NP_ALLOCATION_TAG); + } + + AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG); } } } @@ -1030,42 +1088,67 @@ try_exit: // // Description: // -// This function performs root Fcb removal/deallocation +// This function performs root Fcb removal/deallocation from +// the provided VolumeCB object. // // Return: // -// A status is returned for the function +// None // void -AFSRemoveRootFcb( IN AFSFcb *RootFcb) +AFSRemoveRootFcb( IN AFSVolumeCB *VolumeCB) { + AFSFcb * pRootFcb; + + pRootFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)&VolumeCB->ObjectInformation.Fcb, + NULL, + (PVOID *)&VolumeCB->ObjectInformation.Fcb); + + if ( pRootFcb == NULL) + { + + return; + } + + // + // The Fcb has been disconnected from the ObjectInformation block. + // Clear it from the RootFcb convenience pointer. + // - if( RootFcb->NPFcb != NULL) + VolumeCB->RootFcb = NULL; + + if( pRootFcb->NPFcb != NULL) { // // Now the resource // - ExDeleteResourceLite( &RootFcb->NPFcb->Resource); + ExDeleteResourceLite( &pRootFcb->NPFcb->Resource); + + ExDeleteResourceLite( &pRootFcb->NPFcb->PagingResource); + + ExDeleteResourceLite( &pRootFcb->NPFcb->SectionObjectResource); - ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource); + ExDeleteResourceLite( &pRootFcb->NPFcb->CcbListLock); - ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock); + FsRtlTeardownPerStreamContexts( &pRootFcb->Header); // // The non paged region // - AFSExFreePoolWithTag( RootFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG); + AFSExFreePoolWithTag( pRootFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG); + + pRootFcb->NPFcb = NULL; } // // And the Fcb itself // - AFSExFreePoolWithTag( RootFcb, AFS_FCB_ALLOCATION_TAG); + AFSExFreePoolWithTag( pRootFcb, AFS_FCB_ALLOCATION_TAG); return; } @@ -1096,6 +1179,8 @@ AFSRemoveFcb( IN AFSFcb **ppFcb) return; } + ASSERT( pFcb->Header.NodeTypeCode != AFS_ROOT_FCB); + // // Uninitialize the file lock if it is a file // diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index 89ad4f2f7..e6533975e 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -691,7 +691,7 @@ AFSInitializeGlobalDirectoryEntries() if( pDirNode == NULL) { - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION, AFS_TRACE_LEVEL_ERROR, @@ -714,7 +714,7 @@ AFSInitializeGlobalDirectoryEntries() ExFreePool( pDirNode); - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, AFS_TRACE_LEVEL_ERROR, @@ -808,7 +808,7 @@ AFSInitializeGlobalDirectoryEntries() AFS_TRACE_LEVEL_ERROR, "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"); - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } @@ -827,7 +827,7 @@ AFSInitializeGlobalDirectoryEntries() ExFreePool( pDirNode); - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } @@ -884,7 +884,7 @@ try_exit: if( AFSGlobalDotDirEntry != NULL) { - AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation); + AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation); ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock); @@ -898,7 +898,7 @@ try_exit: if( AFSGlobalDotDotDirEntry != NULL) { - AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation); + AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation); ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock); @@ -1237,7 +1237,7 @@ try_exit: ASSERT( pObjectInfoCB->ObjectReferenceCount == 0); - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); } } } @@ -4396,7 +4396,7 @@ AFSInitializeSpecialShareNameList() if( pDirNode == NULL) { - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } @@ -4415,7 +4415,7 @@ AFSInitializeSpecialShareNameList() ExFreePool( pDirNode); - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } @@ -4489,7 +4489,7 @@ AFSInitializeSpecialShareNameList() if( pDirNode == NULL) { - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } @@ -4508,7 +4508,7 @@ AFSInitializeSpecialShareNameList() ExFreePool( pDirNode); - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } @@ -4563,7 +4563,7 @@ try_exit: pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink; - AFSDeleteObjectInfo( pDirNode->ObjectInformation); + AFSDeleteObjectInfo( &pDirNode->ObjectInformation); ExDeleteResourceLite( &pDirNode->NonPaged->Lock); @@ -6021,7 +6021,7 @@ try_exit: pObjectInfoCB, lCount); - AFSDeleteObjectInfo( pObjectInfoCB); + AFSDeleteObjectInfo( &pObjectInfoCB); } } } @@ -6744,14 +6744,17 @@ AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo) } void -AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo) +AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo) { BOOLEAN bAcquiredTreeLock = FALSE; + AFSObjectInfoCB *pObjectInfo = (*ppObjectInfo); + BOOLEAN bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE); AFSObjectInfoCB * pParentObjectInfo = NULL; + AFSFileID FileId; LONG lCount; - if ( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME)) + if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME)) { // @@ -6764,78 +6767,82 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo) return; } - ASSERT( ObjectInfo->ObjectReferenceCount == 0); + ASSERT( pObjectInfo->ObjectReferenceCount == 0); - if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock)) + (*ppObjectInfo) = NULL; + + if( !ExIsResourceAcquiredExclusiveLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock)) { - ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock)); + ASSERT( !ExIsResourceAcquiredLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock)); - AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock, + AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock, TRUE); bAcquiredTreeLock = TRUE; } - if ( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID)) + if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID)) { - pParentObjectInfo = AFSFindObjectInfo( ObjectInfo->VolumeCB, - &ObjectInfo->ParentFileId); + pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB, + &pObjectInfo->ParentFileId); } // // Remove it from the tree and list if it was inserted // - if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE)) + if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE)) { - AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead, - &ObjectInfo->TreeEntry); + AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead, + &pObjectInfo->TreeEntry); } - if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST)) + if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST)) { - if( ObjectInfo->ListEntry.fLink == NULL) + if( pObjectInfo->ListEntry.fLink == NULL) { - ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink; + pObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink; - if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL) + if( pObjectInfo->VolumeCB->ObjectInfoListTail != NULL) { - ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL; + pObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL; } } else { - ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink; + ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink; } - if( ObjectInfo->ListEntry.bLink == NULL) + if( pObjectInfo->ListEntry.bLink == NULL) { - ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink; + pObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink; - if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL) + if( pObjectInfo->VolumeCB->ObjectInfoListHead != NULL) { - ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL; + pObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL; } } else { - ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink; + ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink; } } if( pParentObjectInfo != NULL) { + ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID); + lCount = AFSObjectInfoDecrement( pParentObjectInfo, AFS_OBJECT_REFERENCE_CHILD); @@ -6844,31 +6851,39 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo) "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n", pParentObjectInfo, lCount); + + AFSReleaseObjectInfo( &pParentObjectInfo); } if( bAcquiredTreeLock) { - AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock); + AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock); } - // - // Release the fid in the service - // - - if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE)) + if( bHeldInService) { - AFSReleaseFid( &ObjectInfo->FileId); + FileId = pObjectInfo->FileId; } - ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->ObjectInfoLock); + ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock); - ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock); + ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock); - AFSExFreePoolWithTag( ObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG); + AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG); - AFSExFreePoolWithTag( ObjectInfo, AFS_OBJECT_INFO_TAG); + AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG); + + // + // Release the fid in the service + // + + if( bHeldInService) + { + + AFSReleaseFid( &FileId); + } return; } @@ -8216,7 +8231,7 @@ AFSCloseLibrary() lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation, AFS_OBJECT_REFERENCE_GLOBAL); - AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation); + AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation); ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock); @@ -8233,7 +8248,7 @@ AFSCloseLibrary() lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation, AFS_OBJECT_REFERENCE_GLOBAL); - AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation); + AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation); ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock); @@ -8257,7 +8272,7 @@ AFSCloseLibrary() lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation, AFS_OBJECT_REFERENCE_GLOBAL); - AFSDeleteObjectInfo( pDirNode->ObjectInformation); + AFSDeleteObjectInfo( &pDirNode->ObjectInformation); ExDeleteResourceLite( &pDirNode->NonPaged->Lock); diff --git a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp index 19a030144..4642a8f85 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp @@ -2514,12 +2514,11 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo, return; } -NTSTATUS +void AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo, IN AFSDirectoryCB *DirEntry) { - NTSTATUS ntStatus = STATUS_SUCCESS; LONG lCount; __Enter @@ -2594,8 +2593,6 @@ AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo, AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG); } - - return ntStatus; } NTSTATUS diff --git a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp index 4eee3a0eb..5596c8962 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp @@ -949,32 +949,817 @@ AFSIOWorkerThread( IN PVOID Context) return; } +static BOOLEAN +AFSExamineDirectory( IN AFSObjectInfoCB * pCurrentObject, + IN AFSDirectoryCB * pCurrentDirEntry) +{ + NTSTATUS ntStatus; + AFSFcb *pFcb = NULL; + AFSObjectInfoCB *pCurrentChildObject = NULL; + AFSVolumeCB * pVolumeCB = pCurrentObject->VolumeCB; + BOOLEAN bFcbBusy = FALSE; + LONG lCount; + + pCurrentChildObject = pCurrentDirEntry->ObjectInformation; + + AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineDirectory Deleting DE %wZ Object %p\n", + &pCurrentDirEntry->NameInformation.FileName, + pCurrentChildObject); + + AFSDeleteDirEntry( pCurrentObject, + pCurrentDirEntry); + + // + // Acquire ObjectInfoLock shared here so as not to deadlock + // with an invalidation call from the service during AFSCleanupFcb + // + + lCount = AFSObjectInfoIncrement( pCurrentChildObject, + AFS_OBJECT_REFERENCE_WORKER); + + AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineDirectory Increment count on object %p Cnt %d\n", + pCurrentChildObject, + lCount); + + if( lCount == 1 && + pCurrentChildObject->Fcb != NULL && + pCurrentChildObject->FileType == AFS_FILE_TYPE_FILE) + { + + // + // We must not hold pVolumeCB->ObjectInfoTree.TreeLock exclusive + // across an AFSCleanupFcb call since it can deadlock with an + // invalidation call from the service. + // + + AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); + + // + // Cannot hold a TreeLock across an AFSCleanupFcb call + // as it can deadlock with an invalidation ioctl initiated + // from the service. + // + // Dropping the TreeLock permits the + // pCurrentObject->ObjectReferenceCount to change + // + + ntStatus = AFSCleanupFcb( pCurrentChildObject->Fcb, + TRUE); + + if ( ntStatus == STATUS_RETRY) + { + + bFcbBusy = TRUE; + } + + AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, + TRUE); + } + + AFSAcquireExcl( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock, + TRUE); + + lCount = AFSObjectInfoDecrement( pCurrentChildObject, + AFS_OBJECT_REFERENCE_WORKER); + + AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineDirectory Decrement1 count on object %p Cnt %d\n", + pCurrentChildObject, + lCount); + + if( lCount == 0 && + pCurrentChildObject->Fcb != NULL && + pCurrentChildObject->Fcb->OpenReferenceCount == 0) + { + + AFSRemoveFcb( &pCurrentChildObject->Fcb); + + if( pCurrentChildObject->FileType == AFS_FILE_TYPE_DIRECTORY && + 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); + + AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG); + + AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineDirectory (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n", + pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB); + + AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG); + } + + AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock); + + AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineDirectory Deleting object %p\n", + pCurrentChildObject); + + AFSDeleteObjectInfo( &pCurrentChildObject); + } + else + { + + AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock); + } + + return bFcbBusy; +} + +// +// Called with VolumeCB->ObjectInfoTree.TreeLock held shared. +// The TreeLock will be released unless *pbReleaseVolumeLock is set to FALSE. +// + +static BOOLEAN +AFSExamineObjectInfo( IN AFSObjectInfoCB * pCurrentObject, + IN BOOLEAN bVolumeObject, + IN OUT BOOLEAN * pbReleaseVolumeLock) +{ + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension; + AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL; + AFSObjectInfoCB *pCurrentChildObject = NULL; + AFSVolumeCB * pVolumeCB = pCurrentObject->VolumeCB; + LARGE_INTEGER liCurrentTime; + BOOLEAN bFcbBusy = FALSE; + LONG lCount; + BOOLEAN bTemp; + + switch ( pCurrentObject->FileType) { + + case AFS_FILE_TYPE_DIRECTORY: + { + + if ( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN)) + { + + return FALSE; + } + + // + // If this object is deleted then remove it from the parent, if we can + // + + if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) && + pCurrentObject->ObjectReferenceCount <= 0 && + ( pCurrentObject->Fcb == NULL || + pCurrentObject->Fcb->OpenReferenceCount == 0) && + pCurrentObject->Specific.Directory.DirectoryNodeListHead == NULL && + pCurrentObject->Specific.Directory.ChildOpenReferenceCount == 0) + { + + AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); + + // + // Dropping the TreeLock permits the + // pCurrentObject->ObjectReferenceCount to change + // + + if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, + FALSE)) + { + + AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock, + TRUE); + + if ( pCurrentObject->ObjectReferenceCount <= 0) + { + + AFSRemoveFcb( &pCurrentObject->Fcb); + + 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); + + AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG); + + AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineObjectInfo (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n", + pCurrentObject->Specific.Directory.PIOCtlDirectoryCB); + + AFSExFreePoolWithTag( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG); + } + + AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); + + AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineObjectInfo Deleting deleted object %p\n", + pCurrentObject); + + AFSDeleteObjectInfo( &pCurrentObject); + } + else + { + + AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); + } + + AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); + } + else + { + + *pbReleaseVolumeLock = FALSE; + } + + return bFcbBusy; + } + + if ( pCurrentObject->Fcb != NULL && + pCurrentObject->Fcb->CcbListHead != NULL) + { + + AFSCcb *pCcb; + + for ( pCcb = pCurrentObject->Fcb->CcbListHead; + pCcb; + pCcb = (AFSCcb *)pCcb->ListEntry.fLink) + { + + if ( pCcb->NameArray) { + + AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineObjectInfo Found Object %p Fcb %p Ccb %p\n", + pCurrentObject, + pCurrentObject->Fcb, + pCcb); + } + } + + return bFcbBusy; + } + + if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0 || + ( pCurrentObject->Fcb != NULL && + pCurrentObject->Fcb->OpenReferenceCount > 0)) + { + + return bFcbBusy; + } + + if ( pCurrentObject->FileType != AFS_FILE_TYPE_DIRECTORY || + pCurrentObject->Specific.Directory.DirectoryNodeListHead != NULL) + { + + if( !AFSAcquireShared( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock, + FALSE)) + { + + return bFcbBusy; + } + + pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead; + + // + // Directory Entry Processing + // + + KeQueryTickCount( &liCurrentTime); + + while( pCurrentDirEntry != NULL) + { + + if( pCurrentDirEntry->DirOpenReferenceCount > 0) + { + + break; + } + + if ( pCurrentDirEntry->NameArrayReferenceCount > 0) + { + + break; + } + + if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL && + pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0) + { + + break; + } + + if ( liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart || + liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart < + pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart) + { + + break; + } + + if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY) + { + + if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL) + { + + break; + } + + if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0) + { + + break; + } + } + + if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE) + { + + if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL && + pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0) + { + + break; + } + } + + pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink; + } + + if( pCurrentDirEntry != NULL) + { + + AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); + + return bFcbBusy; + } + + AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); + + AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); + + // + // Now acquire the locks excl without deadlocking + // + + if( AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock, + FALSE)) + { + + if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, + FALSE)) + { + + AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); + + *pbReleaseVolumeLock = FALSE; + + return bFcbBusy; + } + + if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0) + { + + AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); + + AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); + + return bFcbBusy; + } + + KeQueryTickCount( &liCurrentTime); + + pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead; + + while( pCurrentDirEntry != NULL) + { + + if( pCurrentDirEntry->DirOpenReferenceCount > 0) + { + + break; + } + + if ( pCurrentDirEntry->NameArrayReferenceCount > 0) + { + + break; + } + + if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL && + pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0) + { + + break; + } + + if ( liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart || + liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart < + pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart) + { + + break; + } + + if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY) + { + + if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL) + { + + break; + } + + if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0) + { + + break; + } + } + + if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE) + { + + if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL && + pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0) + { + + break; + } + } + + pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink; + } + + if( pCurrentDirEntry != NULL) + { + + AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); + + AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); + + return bFcbBusy; + } + + pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead; + + while( pCurrentDirEntry != NULL) + { + + pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink; + + AFSExamineDirectory( pCurrentObject, + pCurrentDirEntry); + + pCurrentDirEntry = pNextDirEntry; + } + + // + // Clear our enumerated flag on this object so we retrieve info again on next access + // + + ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED); + + AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); + + AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); + } + else + { + + // + // Try to grab the volume lock again ... no problem if we don't + // + + if( !AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock, + FALSE)) + { + + *pbReleaseVolumeLock = FALSE; + + return bFcbBusy; + } + } + } + else if ( bVolumeObject == FALSE) + { + // + // No children + // + + AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); + + if ( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, + FALSE)) + { + + *pbReleaseVolumeLock = FALSE; + + return bFcbBusy; + } + + AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock, + TRUE); + + KeQueryTickCount( &liCurrentTime); + + if( pCurrentObject->ObjectReferenceCount <= 0 && + ( pCurrentObject->Fcb == NULL || + pCurrentObject->Fcb->OpenReferenceCount <= 0) && + liCurrentTime.QuadPart > pCurrentObject->LastAccessCount.QuadPart && + liCurrentTime.QuadPart - pCurrentObject->LastAccessCount.QuadPart > + pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart) + { + + AFSRemoveFcb( &pCurrentObject->Fcb); + + AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); + + AFSDeleteObjectInfo( &pCurrentObject); + } + else + { + + AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); + } + + AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); + } + } + break; + + case AFS_FILE_TYPE_FILE: + { + + lCount = AFSObjectInfoIncrement( pCurrentObject, + AFS_OBJECT_REFERENCE_WORKER); + + AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineObjectInfo Increment3 count on object %p Cnt %d\n", + pCurrentObject, + lCount); + + AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); + + if( pCurrentObject->Fcb != NULL) + { + + // + // Dropping the TreeLock permits the + // pCurrentObject->ObjectReferenceCount to change + // + + ntStatus = AFSCleanupFcb( pCurrentObject->Fcb, + FALSE); + + if ( ntStatus == STATUS_RETRY) + { + + bFcbBusy = TRUE; + } + } + + bTemp = AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, + FALSE); + + lCount = AFSObjectInfoDecrement( pCurrentObject, + AFS_OBJECT_REFERENCE_WORKER); + + AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineObjectInfo Decrement3 count on object %p Cnt %d\n", + pCurrentObject, + lCount); + + + if ( bTemp == FALSE) + { + + *pbReleaseVolumeLock = FALSE; + + return bFcbBusy; + } + + AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock, + TRUE); + + KeQueryTickCount( &liCurrentTime); + + if( pCurrentObject->ObjectReferenceCount <= 0 && + ( pCurrentObject->Fcb == NULL || + ( pCurrentObject->Fcb->OpenReferenceCount <= 0 && + pCurrentObject->Fcb->Specific.File.ExtentsDirtyCount <= 0)) && + liCurrentTime.QuadPart > pCurrentObject->LastAccessCount.QuadPart && + liCurrentTime.QuadPart - pCurrentObject->LastAccessCount.QuadPart > + pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart) + { + + AFSRemoveFcb( &pCurrentObject->Fcb); + + AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); + + AFSDeleteObjectInfo( &pCurrentObject); + } + else + { + + AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); + } + + AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); + } + break; + + default: + { + + AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); + + if ( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, + FALSE)) + { + + *pbReleaseVolumeLock = FALSE; + + return bFcbBusy; + } + + AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock, + TRUE); + + KeQueryTickCount( &liCurrentTime); + + if( pCurrentObject->ObjectReferenceCount <= 0 && + ( pCurrentObject->Fcb == NULL || + pCurrentObject->Fcb->OpenReferenceCount <= 0) && + liCurrentTime.QuadPart > pCurrentObject->LastAccessCount.QuadPart && + liCurrentTime.QuadPart - pCurrentObject->LastAccessCount.QuadPart > + pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart) + { + + AFSRemoveFcb( &pCurrentObject->Fcb); + + AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); + + AFSDeleteObjectInfo( &pCurrentObject); + } + else + { + + AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); + } + + AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); + } + } + + return bFcbBusy; +} + + +static BOOLEAN +AFSExamineVolume( IN AFSVolumeCB *pVolumeCB) +{ + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSObjectInfoCB *pCurrentObject = NULL, *pNextObject = NULL; + BOOLEAN bReleaseVolumeLock = FALSE; + BOOLEAN bVolumeObject = FALSE; + BOOLEAN bFcbBusy = FALSE; + LONG lCount; + + if( AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock, + FALSE)) + { + + bReleaseVolumeLock = TRUE; + + pCurrentObject = pVolumeCB->ObjectInfoListHead; + + pNextObject = NULL; + + while( pCurrentObject != NULL) + { + + if( pCurrentObject != &pVolumeCB->ObjectInformation) + { + + pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink; + + // + // If the end of the VolumeCB ObjectInfo List is reached, then + // the next ObjectInformationCB to examine is the one embedded within + // the VolumeCB itself except when the VolumeCB is the AFSGlobalRoot. + // + // bVolumeObject is used to indicate whether the embedded ObjectInfoCB + // is being examined. + // + + if( pNextObject == NULL && + pVolumeCB != AFSGlobalRoot) // Don't free up the root of the global + { + + pNextObject = &pVolumeCB->ObjectInformation; + } + + bVolumeObject = FALSE; + + if ( pNextObject) + { + + lCount = AFSObjectInfoIncrement( pNextObject, + AFS_OBJECT_REFERENCE_WORKER); + + AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineVolume Increment count on object %p Cnt %d\n", + pNextObject, + lCount); + } + } + else + { + + pNextObject = NULL; + + bVolumeObject = TRUE; + } + + bFcbBusy = AFSExamineObjectInfo( pCurrentObject, bVolumeObject, &bReleaseVolumeLock); + + if ( pNextObject) + { + + lCount = AFSObjectInfoDecrement( pNextObject, + AFS_OBJECT_REFERENCE_WORKER); + + AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSExamineVolume Decrement count on object %p Cnt %d\n", + pNextObject, + lCount); + } + + // + // If AFSExamineObjectInfo drops the VolumeLock before returning + // we must halt processing of the Volume's ObjectInfo list. + // + + if ( bReleaseVolumeLock == FALSE) + { + + break; + } + + pCurrentObject = pNextObject; + } + + if( bReleaseVolumeLock) + { + + AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); + } + } + + return bFcbBusy; +} + void AFSPrimaryVolumeWorkerThread( IN PVOID Context) { UNREFERENCED_PARAMETER(Context); - NTSTATUS ntStatus = STATUS_SUCCESS; AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&AFSGlobalRoot->NonPagedVcb->VolumeWorkerContext; - AFSDeviceExt *pControlDeviceExt = NULL; - AFSDeviceExt *pRDRDeviceExt = NULL; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension; + AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; LARGE_INTEGER DueTime; LONG TimeOut; KTIMER Timer; - AFSObjectInfoCB *pCurrentObject = NULL, *pNextObject = NULL, *pCurrentChildObject = NULL; - AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL; - BOOLEAN bReleaseVolumeLock = FALSE; AFSVolumeCB *pVolumeCB = NULL, *pNextVolume = NULL; - AFSFcb *pFcb = NULL; - LARGE_INTEGER liCurrentTime; - BOOLEAN bVolumeObject = FALSE; BOOLEAN bFcbBusy = FALSE; LONG lCount; - pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension; - - pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; - AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSPrimaryVolumeWorkerThread Initialized\n"); @@ -1076,13 +1861,15 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context) continue; } - KeQueryTickCount( &liCurrentTime); - pNextVolume = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink; AFSAcquireShared( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock, TRUE); + // + // If VolumeCB is idle, the Volume can be garbage collected + // + if( pVolumeCB->ObjectInfoListHead == NULL && pVolumeCB->DirectoryCB->DirOpenReferenceCount <= 0 && pVolumeCB->DirectoryCB->NameArrayReferenceCount <= 0 && @@ -1092,11 +1879,7 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context) pVolumeCB->ObjectInformation.ObjectReferenceCount <= 0) { - if( pVolumeCB->RootFcb != NULL) - { - - AFSRemoveRootFcb( pVolumeCB->RootFcb); - } + AFSRemoveRootFcb( pVolumeCB); AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock); @@ -1131,549 +1914,7 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context) AFSConvertToShared( pVolumeCB->VolumeLock); - if( AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock, - FALSE)) - { - - pCurrentObject = pVolumeCB->ObjectInfoListHead; - - pNextObject = NULL; - - bReleaseVolumeLock = TRUE; - - while( pCurrentObject != NULL) - { - - if( pCurrentObject != &pVolumeCB->ObjectInformation) - { - - pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink; - - if( pNextObject == NULL && - pVolumeCB != AFSGlobalRoot) // Don't free up the root of the global - { - - pNextObject = &pVolumeCB->ObjectInformation; - } - - bVolumeObject = FALSE; - } - else - { - - pNextObject = NULL; - - bVolumeObject = TRUE; - } - - if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY && - !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN)) // If we are in shutdown mode skip directories - { - - // - // If this object is deleted then remove it from the parent, if we can - // - - if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) && - pCurrentObject->ObjectReferenceCount <= 0 && - ( pCurrentObject->Fcb == NULL || - pCurrentObject->Fcb->OpenReferenceCount == 0) && - pCurrentObject->Specific.Directory.DirectoryNodeListHead == NULL && - pCurrentObject->Specific.Directory.ChildOpenReferenceCount == 0) - { - - AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); - - // - // Dropping the TreeLock permits the - // pCurrentObject->ObjectReferenceCount to change - // - - if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, - FALSE)) - { - - AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock, - TRUE); - - if ( pCurrentObject->ObjectReferenceCount <= 0) - { - - AFSRemoveFcb( &pCurrentObject->Fcb); - - 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); - - AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG); - - AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION, - AFS_TRACE_LEVEL_VERBOSE, - "AFSPrimaryVolumeWorkerThread (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n", - pCurrentObject->Specific.Directory.PIOCtlDirectoryCB); - - 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 %p\n", - pCurrentObject); - - AFSDeleteObjectInfo( pCurrentObject); - } - else - { - - AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); - } - - AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); - - pCurrentObject = pNextObject; - - continue; - } - else - { - - bReleaseVolumeLock = FALSE; - - break; - } - } - - if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0 || - ( pCurrentObject->Fcb != NULL && - pCurrentObject->Fcb->OpenReferenceCount > 0) || - pCurrentObject->Specific.Directory.DirectoryNodeListHead == NULL) - { - - pCurrentObject = pNextObject; - - continue; - } - - if( !AFSAcquireShared( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock, - FALSE)) - { - - pCurrentObject = pNextObject; - - continue; - } - - KeQueryTickCount( &liCurrentTime); - - pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead; - - while( pCurrentDirEntry != NULL) - { - - if( pCurrentDirEntry->DirOpenReferenceCount > 0 || - pCurrentDirEntry->NameArrayReferenceCount > 0 || - ( pCurrentDirEntry->ObjectInformation->Fcb != NULL && - pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0) || - liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart || - liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart < - pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart || - ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY && - ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL || - pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)) || - ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE && - pCurrentDirEntry->ObjectInformation->Fcb != NULL && - pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0)) - { - - break; - } - - pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink; - } - - if( pCurrentDirEntry != NULL) - { - - AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); - - pCurrentObject = pNextObject; - - continue; - } - - AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); - - AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); - - // - // Now acquire the locks excl - // - - if( AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock, - FALSE)) - { - - if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, - FALSE)) - { - - if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0) - { - - AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); - - AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); - - pCurrentObject = pNextObject; - - continue; - } - - KeQueryTickCount( &liCurrentTime); - - pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead; - - while( pCurrentDirEntry != NULL) - { - - if( pCurrentDirEntry->DirOpenReferenceCount > 0 || - pCurrentDirEntry->NameArrayReferenceCount > 0 || - ( pCurrentDirEntry->ObjectInformation->Fcb != NULL && - pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0) || - liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart || - liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart < - pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart || - ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY && - ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL || - pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)) || - ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE && - pCurrentDirEntry->ObjectInformation->Fcb != NULL && - pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0)) - { - - break; - } - - pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink; - } - - if( pCurrentDirEntry != NULL) - { - - AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); - - AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); - - pCurrentObject = pNextObject; - - continue; - } - - pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead; - - while( pCurrentDirEntry != NULL) - { - - pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink; - - pCurrentChildObject = pCurrentDirEntry->ObjectInformation; - - pFcb = NULL; - - AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSPrimaryVolumeWorkerThread Deleting DE %wZ Object %p\n", - &pCurrentDirEntry->NameInformation.FileName, - pCurrentChildObject); - - AFSDeleteDirEntry( pCurrentObject, - pCurrentDirEntry); - - - // - // Acquire ObjectInfoLock shared here so as not to deadlock - // with an invalidation call from the service during AFSCleanupFcb - // - - lCount = AFSObjectInfoIncrement( pCurrentChildObject, - AFS_OBJECT_REFERENCE_WORKER); - - AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSPrimaryVolumeWorkerThread Increment count on object %p Cnt %d\n", - pCurrentChildObject, - lCount); - - if( lCount == 1 && - pCurrentChildObject->Fcb != NULL && - pCurrentChildObject->FileType == AFS_FILE_TYPE_FILE) - { - - // - // We must not hold pVolumeCB->ObjectInfoTree.TreeLock exclusive - // across an AFSCleanupFcb call since it can deadlock with an - // invalidation call from the service. - // - - AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); - - // - // Cannot hold a TreeLock across an AFSCleanupFcb call - // as it can deadlock with an invalidation ioctl initiated - // from the service. - // - // Dropping the TreeLock permits the - // pCurrentObject->ObjectReferenceCount to change - // - - ntStatus = AFSCleanupFcb( pCurrentChildObject->Fcb, - TRUE); - - if ( ntStatus == STATUS_RETRY) - { - - bFcbBusy = TRUE; - } - - AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, - TRUE); - } - - lCount = AFSObjectInfoDecrement( pCurrentChildObject, - AFS_OBJECT_REFERENCE_WORKER); - - AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSPrimaryVolumeWorkerThread Decrement1 count on object %p Cnt %d\n", - pCurrentChildObject, - lCount); - - AFSAcquireExcl( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock, - TRUE); - - if( pCurrentChildObject->ObjectReferenceCount <= 0) - { - - AFSRemoveFcb( &pCurrentChildObject->Fcb); - - if( pCurrentChildObject->FileType == AFS_FILE_TYPE_DIRECTORY && - 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); - - AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG); - - AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION, - AFS_TRACE_LEVEL_VERBOSE, - "AFSPrimaryVolumeWorkerThread (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n", - pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB); - - 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 %p\n", - pCurrentChildObject); - - AFSDeleteObjectInfo( pCurrentChildObject); - } - else - { - - AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock); - } - - pCurrentDirEntry = pNextDirEntry; - - } - - pCurrentObject->Specific.Directory.DirectoryNodeListHead = NULL; - - pCurrentObject->Specific.Directory.DirectoryNodeListTail = NULL; - - pCurrentObject->Specific.Directory.ShortNameTree = NULL; - - pCurrentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL; - - pCurrentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL; - - pCurrentObject->Specific.Directory.DirectoryNodeCount = 0; - - AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT, - AFS_TRACE_LEVEL_VERBOSE, - "AFSPrimaryVolumeWorkerThread Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n", - pCurrentObject->FileId.Cell, - pCurrentObject->FileId.Volume, - pCurrentObject->FileId.Vnode, - pCurrentObject->FileId.Unique); - - // - // Clear our enumerated flag on this object so we retrieve info again on next access - // - - ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED); - - AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); - - AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); - } - else - { - - AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock); - - bReleaseVolumeLock = FALSE; - - break; - } - } - else - { - - // - // Try to grab the volume lock again ... no problem if we don't - // - - if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, - FALSE)) - { - - bReleaseVolumeLock = FALSE; - - break; - } - } - - if( pCurrentObject != &pVolumeCB->ObjectInformation) - { - - pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink; - - if( pCurrentObject == NULL && - pVolumeCB != AFSGlobalRoot) - { - - pCurrentObject = &pVolumeCB->ObjectInformation; - } - } - else - { - - pCurrentObject = NULL; - } - - continue; - } - else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE) - { - - lCount = AFSObjectInfoIncrement( pCurrentObject, - AFS_OBJECT_REFERENCE_WORKER); - - AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSPrimaryVolumeWorkerThread Increment2 count on object %p Cnt %d\n", - pCurrentObject, - lCount); - - AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); - - if( pCurrentObject->Fcb != NULL) - { - - // - // Dropping the TreeLock permits the - // pCurrentObject->ObjectReferenceCount to change - // - - ntStatus = AFSCleanupFcb( pCurrentObject->Fcb, - FALSE); - - if ( ntStatus == STATUS_RETRY) - { - - bFcbBusy = TRUE; - } - } - - lCount = AFSObjectInfoDecrement( pCurrentObject, - AFS_OBJECT_REFERENCE_WORKER); - - AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSPrimaryVolumeWorkerThread Decrement2 count on object %p Cnt %d\n", - pCurrentObject, - lCount); - - if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock, - FALSE)) - { - - bReleaseVolumeLock = FALSE; - - break; - } - - AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock, - TRUE); - - if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) && - pCurrentObject->ObjectReferenceCount <= 0) - { - - AFSRemoveFcb( &pCurrentObject->Fcb); - - AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); - - AFSDeleteObjectInfo( pCurrentObject); - } - else - { - - AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock); - } - - AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock); - - pCurrentObject = pNextObject; - - continue; - } - - pCurrentObject = pNextObject; - } - - if( bReleaseVolumeLock) - { - - AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock); - } - } + AFSExamineVolume( pVolumeCB); // // Next volume cb diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h index 030b1bd8e..0f11fdf7b 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h @@ -537,7 +537,7 @@ AFSInitRootFcb( IN ULONGLONG ProcessID, IN AFSVolumeCB *VolumeCB); void -AFSRemoveRootFcb( IN AFSFcb *RootFcb); +AFSRemoveRootFcb( IN AFSVolumeCB *VolumeCB); NTSTATUS AFSInitCcb( IN OUT AFSCcb **Ccb, @@ -586,7 +586,7 @@ AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo, IN AFSDirectoryCB *DirEntry, IN BOOLEAN InsertInEnumList); -NTSTATUS +void AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo, IN AFSDirectoryCB *DirEntry); @@ -1331,7 +1331,7 @@ AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo, IN LONG Reason); void -AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo); +AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo); AFSObjectInfoCB * AFSFindObjectInfo( IN AFSVolumeCB * VolumeCB, -- 2.39.5