pDevExt->Specific.Library.WorkerCount = 0;
KeInitializeEvent( &pDevExt->Specific.Library.WorkerQueueHasItems,
- NotificationEvent,
+ SynchronizationEvent,
FALSE);
//
pDevExt->Specific.Library.IOWorkerCount = 0;
KeInitializeEvent( &pDevExt->Specific.Library.IOWorkerQueueHasItems,
- NotificationEvent,
+ SynchronizationEvent,
FALSE);
//
pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
//
- // Loop through the workers shutting them down
+ // Loop through the workers shutting them down in two stages.
+ // First, clear AFS_WORKER_PROCESS_REQUESTS so that workers
+ // stop processing requests. Second, call AFSShutdownWorkerThread()
+ // to wake the workers and wait for them to exit.
//
pCurrentWorker = pDevExt->Specific.Library.PoolHead;
while( index < pDevExt->Specific.Library.WorkerCount)
{
+ ClearFlag( pCurrentWorker->State, AFS_WORKER_PROCESS_REQUESTS);
+
+ pCurrentWorker = pCurrentWorker->fLink;
+
+ if ( pCurrentWorker == NULL)
+ {
+
+ break;
+ }
+
+ index++;
+ }
+
+ pCurrentWorker = pDevExt->Specific.Library.PoolHead;
+
+ index = 0;
+
+ while( index < pDevExt->Specific.Library.WorkerCount)
+ {
+
ntStatus = AFSShutdownWorkerThread( pCurrentWorker);
pNextWorker = pCurrentWorker->fLink;
ExDeleteResourceLite( &pDevExt->Specific.Library.QueueLock);
//
- // Loop through the IO workers shutting them down
+ // Loop through the IO workers shutting them down in two stages.
+ // First, clear AFS_WORKER_PROCESS_REQUESTS so that workers
+ // stop processing requests. Second, call AFSShutdownIOWorkerThread()
+ // to wake the workers and wait for them to exit.
//
pCurrentWorker = pDevExt->Specific.Library.IOPoolHead;
while( index < pDevExt->Specific.Library.IOWorkerCount)
{
+ ClearFlag( pCurrentWorker->State, AFS_WORKER_PROCESS_REQUESTS);
+
+ pCurrentWorker = pCurrentWorker->fLink;
+
+ if ( pCurrentWorker == NULL)
+ {
+
+ break;
+ }
+
+ index++;
+ }
+
+ pCurrentWorker = pDevExt->Specific.Library.IOPoolHead;
+
+ index = 0;
+
+ while( index < pDevExt->Specific.Library.IOWorkerCount)
+ {
+
ntStatus = AFSShutdownIOWorkerThread( pCurrentWorker);
pNextWorker = pCurrentWorker->fLink;
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSWorkQueueContext *pWorker = &VolumeCB->VolumeWorkerContext;
+ AFSWorkQueueContext *pWorker = &VolumeCB->NonPagedVcb->VolumeWorkerContext;
HANDLE hThread;
AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
PKSTART_ROUTINE pStartRoutine = NULL;
+ LONG lCount;
__Enter
{
- if( VolumeCB == AFSGlobalRoot)
+ if ( VolumeCB != AFSGlobalRoot)
{
- pStartRoutine = AFSPrimaryVolumeWorkerThread;
+ return STATUS_INVALID_PARAMETER;
}
- else
- {
- pStartRoutine = AFSVolumeWorkerThread;
- }
+ pStartRoutine = AFSPrimaryVolumeWorkerThread;
//
// Initialize the worker thread
FALSE,
NULL);
- if( InterlockedIncrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount) > 0)
+ lCount = InterlockedIncrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount);
+
+ if( lCount > 0)
{
KeClearEvent( &pControlDeviceExt->Specific.Control.VolumeWorkerCloseEvent);
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSWorkQueueContext *pWorker = &VolumeCB->VolumeWorkerContext;
+ AFSWorkQueueContext *pWorker = &VolumeCB->NonPagedVcb->VolumeWorkerContext;
- if( pWorker->WorkerThreadObject != NULL &&
- BooleanFlagOn( pWorker->State, AFS_WORKER_INITIALIZED))
- {
+ //
+ // Clear the 'keep processing' flag
+ //
- //
- // Clear the 'keep processing' flag
- //
+ ClearFlag( pWorker->State, AFS_WORKER_PROCESS_REQUESTS);
- ClearFlag( pWorker->State, AFS_WORKER_PROCESS_REQUESTS);
+ if( pWorker->WorkerThreadObject != NULL)
+ {
+ while ( BooleanFlagOn( pWorker->State, AFS_WORKER_INITIALIZED) )
+ {
- ntStatus = KeWaitForSingleObject( pWorker->WorkerThreadObject,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ ntStatus = KeWaitForSingleObject( pWorker->WorkerThreadObject,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
ObDereferenceObject( pWorker->WorkerThreadObject);
//
// Description:
//
-// This function shusdown a worker thread in the pool
+// This function shutsdown a worker thread in the pool
//
// Return:
//
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
- if( PoolContext->WorkerThreadObject != NULL &&
- BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED))
+ if( PoolContext->WorkerThreadObject != NULL)
{
- //
- // Clear the 'keep processing' flag
- //
-
- ClearFlag( PoolContext->State, AFS_WORKER_PROCESS_REQUESTS);
+ while ( BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED) )
+ {
- //
- // Wake up the thread if it is a sleep
- //
+ //
+ // Wake up the thread if it is a sleep
+ //
- KeSetEvent( &pDeviceExt->Specific.Library.WorkerQueueHasItems,
- 0,
- FALSE);
+ KeSetEvent( &pDeviceExt->Specific.Library.WorkerQueueHasItems,
+ 0,
+ FALSE);
- ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
ObDereferenceObject( PoolContext->WorkerThreadObject);
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
- if( PoolContext->WorkerThreadObject != NULL &&
- BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED))
+ if( PoolContext->WorkerThreadObject != NULL)
{
- //
- // Clear the 'keep processing' flag
- //
-
- ClearFlag( PoolContext->State, AFS_WORKER_PROCESS_REQUESTS);
+ while ( BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED) )
+ {
- //
- // Wake up the thread if it is a sleep
- //
+ //
+ // Wake up the thread if it is a sleep
+ //
- KeSetEvent( &pDeviceExt->Specific.Library.IOWorkerQueueHasItems,
- 0,
- FALSE);
+ KeSetEvent( &pDeviceExt->Specific.Library.IOWorkerQueueHasItems,
+ 0,
+ FALSE);
- ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
ObDereferenceObject( PoolContext->WorkerThreadObject);
AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
AFSWorkItem *pWorkItem;
BOOLEAN freeWorkItem = TRUE;
- BOOLEAN exitThread = FALSE;
AFSDeviceExt *pLibraryDevExt = NULL;
+ LONG lCount;
pLibraryDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
0,
FALSE);
-
//
// Indicate we are initialized
//
SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+ ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
{
- ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
if( !NT_SUCCESS( ntStatus))
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
+
+ ntStatus = STATUS_SUCCESS;
}
else
{
pWorkItem = AFSRemoveWorkItem();
- if( pWorkItem != NULL)
+ if( pWorkItem == NULL)
+ {
+
+ ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
+ else
{
freeWorkItem = TRUE;
{
AFSReleaseExtentsWithFlush( pWorkItem->Specific.Fcb.Fcb,
- &pWorkItem->AuthGroup);
+ &pWorkItem->AuthGroup,
+ FALSE);
}
ASSERT( pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount != 0);
- InterlockedDecrement( &pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount);
+ lCount = InterlockedDecrement( &pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount);
break;
}
- case AFS_WORK_ASYNCH_READ:
+ case AFS_WORK_ENUMERATE_GLOBAL_ROOT:
{
- ASSERT( pWorkItem->Specific.AsynchIo.CallingProcess != NULL);
-
- (VOID) AFSCommonRead( pWorkItem->Specific.AsynchIo.Device,
- pWorkItem->Specific.AsynchIo.Irp,
- pWorkItem->Specific.AsynchIo.CallingProcess);
+ AFSEnumerateGlobalRoot( NULL);
break;
}
- case AFS_WORK_ASYNCH_WRITE:
+ case AFS_WORK_INVALIDATE_OBJECT:
{
- ASSERT( pWorkItem->Specific.AsynchIo.CallingProcess != NULL);
-
- (VOID) AFSCommonWrite( pWorkItem->Specific.AsynchIo.Device,
- pWorkItem->Specific.AsynchIo.Irp,
- pWorkItem->Specific.AsynchIo.CallingProcess);
- break;
- }
-
- case AFS_WORK_ENUMERATE_GLOBAL_ROOT:
- {
+ AFSPerformObjectInvalidate( pWorkItem->Specific.Invalidate.ObjectInfo,
+ pWorkItem->Specific.Invalidate.InvalidateReason);
- AFSEnumerateGlobalRoot( NULL);
+ freeWorkItem = TRUE;
break;
}
ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
}
+
+ ntStatus = STATUS_SUCCESS;
}
}
} // worker thread loop
+ ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+
+ // Wake up another worker so they too can exit
+
+ KeSetEvent( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
+ 0,
+ FALSE);
+
PsTerminateSystemThread( 0);
return;
AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
AFSWorkItem *pWorkItem;
BOOLEAN freeWorkItem = TRUE;
- BOOLEAN exitThread = FALSE;
AFSDeviceExt *pLibraryDevExt = NULL, *pRdrDevExt = NULL;
pLibraryDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+ ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
{
- ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
if( !NT_SUCCESS( ntStatus))
{
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSIOWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
+
+ ntStatus = STATUS_SUCCESS;
}
else
{
pWorkItem = AFSRemoveIOWorkItem();
- if( pWorkItem != NULL)
+ if( pWorkItem == NULL)
+ {
+
+ ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
+ else
{
freeWorkItem = TRUE;
ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
}
+
+ ntStatus = STATUS_SUCCESS;
}
}
} // worker thread loop
+ ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+
+ // Wake up another IOWorker so they too can exit
+
+ KeSetEvent( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
+ 0,
+ FALSE);
+
PsTerminateSystemThread( 0);
return;
AFSPrimaryVolumeWorkerThread( IN PVOID Context)
{
+ UNREFERENCED_PARAMETER(Context);
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&AFSGlobalRoot->VolumeWorkerContext;
+ AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&AFSGlobalRoot->NonPagedVcb->VolumeWorkerContext;
AFSDeviceExt *pControlDeviceExt = NULL;
AFSDeviceExt *pRDRDeviceExt = NULL;
- BOOLEAN exitThread = FALSE;
LARGE_INTEGER DueTime;
LONG TimeOut;
KTIMER Timer;
- BOOLEAN bFoundOpenEntry = FALSE;
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;
while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
{
- KeWaitForSingleObject( &Timer,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ if ( bFcbBusy == FALSE)
+ {
+
+ KeWaitForSingleObject( &Timer,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
+ else
+ {
+
+ bFcbBusy = FALSE;
+ }
//
// This is the primary volume worker so it will traverse the volume list
continue;
}
- if( pVolumeCB->ObjectInfoListHead == NULL &&
- pVolumeCB != AFSGlobalRoot)
+ if( pVolumeCB->ObjectInfoListHead == NULL)
{
AFSReleaseResource( pVolumeCB->VolumeLock);
pNextVolume = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
+ AFSAcquireShared( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock,
+ TRUE);
+
if( pVolumeCB->ObjectInfoListHead == NULL &&
- pVolumeCB->DirectoryCB->OpenReferenceCount == 0 &&
+ pVolumeCB->DirectoryCB->DirOpenReferenceCount <= 0 &&
pVolumeCB->VolumeReferenceCount == 1 &&
( pVolumeCB->RootFcb == NULL ||
pVolumeCB->RootFcb->OpenReferenceCount == 0) &&
- pVolumeCB->ObjectInformation.ObjectReferenceCount == 0)
+ pVolumeCB->ObjectInformation.ObjectReferenceCount <= 0)
{
if( pVolumeCB->RootFcb != NULL)
AFSRemoveRootFcb( pVolumeCB->RootFcb);
}
+ AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
AFSRemoveVolume( pVolumeCB);
}
else
{
+ AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
AFSReleaseResource( pVolumeCB->VolumeLock);
}
//
if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
- pCurrentObject->ObjectReferenceCount == 0 &&
+ pCurrentObject->ObjectReferenceCount <= 0 &&
( pCurrentObject->Fcb == NULL ||
pCurrentObject->Fcb->OpenReferenceCount == 0) &&
pCurrentObject->Specific.Directory.DirectoryNodeListHead == NULL &&
AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ //
+ // Dropping the TreeLock permits the
+ // pCurrentObject->ObjectReferenceCount to change
+ //
+
if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
FALSE))
{
- if( pCurrentObject->Fcb != NULL)
+ AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
+
+ if ( pCurrentObject->ObjectReferenceCount <= 0)
{
- //
- // Acquire and drop the Fcb resource to synchronize
- // with a potentially active AFSCleanup() which sets
- // the OpenReferenceCount to zero while holding the
- // resource.
- //
+ AFSRemoveFcb( &pCurrentObject->Fcb);
- AFSAcquireExcl( &pCurrentObject->Fcb->NPFcb->Resource,
- TRUE);
+ if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
+ {
- AFSReleaseResource( &pCurrentObject->Fcb->NPFcb->Resource);
+ AFSAcquireExcl( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- AFSRemoveFcb( pCurrentObject->Fcb);
- }
+ AFSRemoveFcb( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
- if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
- {
+ AFSReleaseResource( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
- if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
- {
+ AFSDeleteObjectInfo( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
- AFSRemoveFcb( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
- }
+ ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
- AFSDeleteObjectInfo( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
+ AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
- ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
+ AFSExFreePoolWithTag( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
+ }
- AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged);
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
- AFSExFreePool( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB);
- }
+ AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPrimaryVolumeWorkerThread Deleting deleted object %p\n",
+ pCurrentObject);
- AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPrimaryWorker Deleting deleted object %08lX\n",
- pCurrentObject);
+ AFSDeleteObjectInfo( pCurrentObject);
+ }
+ else
+ {
- AFSDeleteObjectInfo( pCurrentObject);
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+ }
AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
while( pCurrentDirEntry != NULL)
{
- if( pCurrentDirEntry->OpenReferenceCount > 0 ||
+ if( pCurrentDirEntry->DirOpenReferenceCount > 0 ||
( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0) ||
liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart ||
while( pCurrentDirEntry != NULL)
{
- if( pCurrentDirEntry->OpenReferenceCount > 0 ||
+ if( pCurrentDirEntry->DirOpenReferenceCount > 0 ||
( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0) ||
liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart ||
pCurrentChildObject = pCurrentDirEntry->ObjectInformation;
- AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+ pFcb = NULL;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSPrimaryWorker Deleting DE %wZ Object %08lX\n",
+ "AFSPrimaryVolumeWorkerThread Deleting DE %wZ Object %p\n",
&pCurrentDirEntry->NameInformation.FileName,
pCurrentChildObject);
AFSDeleteDirEntry( pCurrentObject,
pCurrentDirEntry);
- if( pCurrentChildObject->ObjectReferenceCount == 0)
+
+ //
+ // 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)
{
- if( pCurrentChildObject->Fcb != NULL)
+ //
+ // 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)
{
- if( pCurrentChildObject->FileType == AFS_FILE_TYPE_FILE)
- {
+ bFcbBusy = TRUE;
+ }
+
+ AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+ }
- AFSCleanupFcb( pCurrentChildObject->Fcb,
- TRUE);
- }
+ lCount = AFSObjectInfoDecrement( pCurrentChildObject,
+ AFS_OBJECT_REFERENCE_WORKER);
- //
- // Acquire and drop the Fcb resource to synchronize
- // with a potentially active AFSCleanup() which sets
- // the OpenReferenceCount to zero while holding the
- // resource.
- //
+ AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPrimaryVolumeWorkerThread Decrement1 count on object %p Cnt %d\n",
+ pCurrentChildObject,
+ lCount);
- AFSAcquireExcl( &pCurrentChildObject->Fcb->NPFcb->Resource,
- TRUE);
+ AFSAcquireExcl( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- AFSReleaseResource( &pCurrentChildObject->Fcb->NPFcb->Resource);
+ if( pCurrentChildObject->ObjectReferenceCount <= 0)
+ {
- AFSRemoveFcb( pCurrentChildObject->Fcb);
- }
+ AFSRemoveFcb( &pCurrentChildObject->Fcb);
if( pCurrentChildObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
{
- if( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
- {
+ AFSAcquireExcl( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+ TRUE);
+
+ AFSRemoveFcb( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
- 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);
- AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged);
+ AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
- AFSExFreePool( 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,
- "AFSPrimaryWorker Deleting object %08lX\n",
+ "AFSPrimaryVolumeWorkerThread Deleting object %p\n",
pCurrentChildObject);
AFSDeleteObjectInfo( pCurrentChildObject);
}
+ else
+ {
+
+ AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+ }
pCurrentDirEntry = pNextDirEntry;
+
}
pCurrentObject->Specific.Directory.DirectoryNodeListHead = NULL;
AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSPrimaryWorker Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
+ "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
{
break;
}
-
- AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
}
else
{
else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
{
- if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
- pCurrentObject->ObjectReferenceCount == 0 &&
- ( pCurrentObject->Fcb == NULL ||
- pCurrentObject->Fcb->OpenReferenceCount == 0))
+ 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)
{
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ //
+ // Dropping the TreeLock permits the
+ // pCurrentObject->ObjectReferenceCount to change
+ //
- if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- FALSE))
- {
+ ntStatus = AFSCleanupFcb( pCurrentObject->Fcb,
+ FALSE);
- if( pCurrentObject->Fcb != NULL)
- {
+ if ( ntStatus == STATUS_RETRY)
+ {
- AFSCleanupFcb( pCurrentObject->Fcb,
- TRUE);
+ bFcbBusy = TRUE;
+ }
+ }
- //
- // Acquire and drop the Fcb resource to synchronize
- // with a potentially active AFSCleanup() which sets
- // the OpenReferenceCount to zero while holding the
- // resource.
- //
+ lCount = AFSObjectInfoDecrement( pCurrentObject,
+ AFS_OBJECT_REFERENCE_WORKER);
- AFSAcquireExcl( &pCurrentObject->Fcb->NPFcb->Resource,
- TRUE);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPrimaryVolumeWorkerThread Decrement2 count on object %p Cnt %d\n",
+ pCurrentObject,
+ lCount);
- AFSReleaseResource( &pCurrentObject->Fcb->NPFcb->Resource);
+ if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
+ FALSE))
+ {
- AFSRemoveFcb( pCurrentObject->Fcb);
- }
+ bReleaseVolumeLock = FALSE;
- AFSDeleteObjectInfo( pCurrentObject);
+ break;
+ }
- AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
+ AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- pCurrentObject = pNextObject;
+ if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
+ pCurrentObject->ObjectReferenceCount <= 0)
+ {
- continue;
- }
- else
- {
+ AFSRemoveFcb( &pCurrentObject->Fcb);
- bReleaseVolumeLock = FALSE;
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
- break;
- }
+ AFSDeleteObjectInfo( pCurrentObject);
}
- else if( pCurrentObject->Fcb != NULL)
+ else
{
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+ }
- if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- FALSE))
- {
+ AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
- AFSCleanupFcb( pCurrentObject->Fcb,
- FALSE);
+ pCurrentObject = pNextObject;
- AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
+ continue;
+ }
- pCurrentObject = pNextObject;
-
- continue;
- }
- else
- {
-
- bReleaseVolumeLock = FALSE;
-
- break;
- }
- }
- }
-
- pCurrentObject = pNextObject;
- }
+ pCurrentObject = pNextObject;
+ }
if( bReleaseVolumeLock)
{
KeCancelTimer( &Timer);
+ ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSPrimaryVolumeWorkerThread Exiting\n");
- if( InterlockedDecrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount) == 0)
- {
-
- KeSetEvent( &pControlDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
- 0,
- FALSE);
- }
-
- PsTerminateSystemThread( 0);
-
- return;
-}
+ lCount = InterlockedDecrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount);
-void
-AFSVolumeWorkerThread( IN PVOID Context)
-{
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSVolumeCB *pVolumeCB = (AFSVolumeCB * )Context;
- AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&pVolumeCB->VolumeWorkerContext;
- AFSDeviceExt *pControlDeviceExt = NULL;
- AFSDeviceExt *pRDRDeviceExt = NULL;
- BOOLEAN exitThread = FALSE;
- LARGE_INTEGER DueTime;
- LONG TimeOut;
- KTIMER Timer;
-
- pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
-
- pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
-
- //
- // Initialize the timer for the worker thread
- //
-
- DueTime.QuadPart = -(5000);
-
- TimeOut = 5000;
-
- KeInitializeTimerEx( &Timer,
- SynchronizationTimer);
-
- KeSetTimerEx( &Timer,
- DueTime,
- TimeOut,
- NULL);
-
- //
- // Indicate that we are initialized and ready
- //
-
- KeSetEvent( &pPoolContext->WorkerThreadReady,
- 0,
- FALSE);
-
- //
- // Indicate we are initialized
- //
-
- SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
-
- while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
- {
-
- ntStatus = KeWaitForSingleObject( &Timer,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSVolumeWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
- }
- else
- {
-
- //
- // If we are in shutdown mode and the dirty flag is clear then get out now
- //
-
- if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
- {
-
- break;
- }
- }
- } // worker thread loop
-
- KeCancelTimer( &Timer);
-
- if( InterlockedDecrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount) == 0)
+ if( lCount == 0)
{
KeSetEvent( &pControlDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSDeviceExt *pDevExt = NULL;
+ LONG lCount;
pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertWorkitem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
+ "AFSInsertWorkitem Acquiring Control QueueLock lock %p EXCL %08lX\n",
&pDevExt->Specific.Library.QueueLock,
PsGetCurrentThread());
AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
TRUE);
+ lCount = InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertWorkitem Inserting work item %08lX Count %08lX\n",
+ "AFSInsertWorkitem Inserting work item %p Count %d\n",
WorkItem,
- InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount));
+ lCount);
if( pDevExt->Specific.Library.QueueTail != NULL) // queue already has nodes
{
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSDeviceExt *pDevExt = NULL;
+ LONG lCount;
pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertIOWorkitem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
+ "AFSInsertIOWorkitem Acquiring Control QueueLock lock %p EXCL %08lX\n",
&pDevExt->Specific.Library.IOQueueLock,
PsGetCurrentThread());
AFSAcquireExcl( &pDevExt->Specific.Library.IOQueueLock,
TRUE);
+ lCount = InterlockedIncrement( &pDevExt->Specific.Library.IOQueueItemCount);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertWorkitem Inserting IO work item %08lX Count %08lX\n",
+ "AFSInsertWorkitem Inserting IO work item %p Count %d\n",
WorkItem,
- InterlockedIncrement( &pDevExt->Specific.Library.IOQueueItemCount));
+ lCount);
if( pDevExt->Specific.Library.IOQueueTail != NULL) // queue already has nodes
{
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSDeviceExt *pDevExt = NULL;
+ LONG lCount;
pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertWorkitemAtHead Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
+ "AFSInsertWorkitemAtHead Acquiring Control QueueLock lock %p EXCL %08lX\n",
&pDevExt->Specific.Library.QueueLock,
PsGetCurrentThread());
pDevExt->Specific.Library.QueueHead = WorkItem;
+ lCount = InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertWorkitemAtHead Inserting work item %08lX Count %08lX\n",
+ "AFSInsertWorkitemAtHead Inserting work item %p Count %d\n",
WorkItem,
- InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount));
+ lCount);
//
// indicate that the queue has nodes
AFSRemoveWorkItem()
{
- NTSTATUS ntStatus = STATUS_SUCCESS;
AFSWorkItem *pWorkItem = NULL;
AFSDeviceExt *pDevExt = NULL;
+ LONG lCount;
pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSRemoveWorkItem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
+ "AFSRemoveWorkItem Acquiring Control QueueLock lock %p EXCL %08lX\n",
&pDevExt->Specific.Library.QueueLock,
PsGetCurrentThread());
pWorkItem = pDevExt->Specific.Library.QueueHead;
+ lCount = InterlockedDecrement( &pDevExt->Specific.Library.QueueItemCount);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSRemoveWorkItem Removing work item %08lX Count %08lX Thread %08lX\n",
+ "AFSRemoveWorkItem Removing work item %p Count %d Thread %08lX\n",
pWorkItem,
- InterlockedDecrement( &pDevExt->Specific.Library.QueueItemCount),
+ lCount,
PsGetCurrentThreadId());
pDevExt->Specific.Library.QueueHead = pDevExt->Specific.Library.QueueHead->next;
{
pDevExt->Specific.Library.QueueTail = NULL;
+ }
+ else
+ {
+
+ //
+ // Wake up another worker
+ //
- KeResetEvent(&(pDevExt->Specific.Library.WorkerQueueHasItems));
+ KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
+ 0,
+ FALSE);
}
}
- else
- {
- KeResetEvent(&(pDevExt->Specific.Library.WorkerQueueHasItems));
- }
AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
AFSRemoveIOWorkItem()
{
- NTSTATUS ntStatus = STATUS_SUCCESS;
AFSWorkItem *pWorkItem = NULL;
AFSDeviceExt *pDevExt = NULL;
+ LONG lCount;
pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSRemoveIOWorkItem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
+ "AFSRemoveIOWorkItem Acquiring Control QueueLock lock %p EXCL %08lX\n",
&pDevExt->Specific.Library.IOQueueLock,
PsGetCurrentThread());
pWorkItem = pDevExt->Specific.Library.IOQueueHead;
+ lCount = InterlockedDecrement( &pDevExt->Specific.Library.IOQueueItemCount);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSRemoveWorkItem Removing work item %08lX Count %08lX Thread %08lX\n",
+ "AFSRemoveWorkItem Removing work item %p Count %d Thread %08lX\n",
pWorkItem,
- InterlockedDecrement( &pDevExt->Specific.Library.IOQueueItemCount),
+ lCount,
PsGetCurrentThreadId());
pDevExt->Specific.Library.IOQueueHead = pDevExt->Specific.Library.IOQueueHead->next;
{
pDevExt->Specific.Library.IOQueueTail = NULL;
+ }
+ else
+ {
- KeResetEvent(&(pDevExt->Specific.Library.IOWorkerQueueHasItems));
+ //
+ // Wake up another worker
+ //
+
+ KeSetEvent( &(pDevExt->Specific.Library.IOWorkerQueueHasItems),
+ 0,
+ FALSE);
}
}
- else
- {
- KeResetEvent(&(pDevExt->Specific.Library.IOWorkerQueueHasItems));
- }
AFSReleaseResource( &pDevExt->Specific.Library.IOQueueLock);
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pDevExt = NULL;
BOOLEAN bWait = BooleanFlagOn( WorkItem->RequestFlags, AFS_SYNCHRONOUS_REQUEST);
//
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pDevExt = NULL;
BOOLEAN bWait = BooleanFlagOn( WorkItem->RequestFlags, AFS_SYNCHRONOUS_REQUEST);
//
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pDevExt = NULL;
BOOLEAN bWait = BooleanFlagOn( WorkItem->RequestFlags, AFS_SYNCHRONOUS_REQUEST);
//
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
AFSWorkItem *pWorkItem = NULL;
+ LONG lCount;
__try
{
// queue down. We'll decrement it just below.
//
- if( InterlockedIncrement( &Fcb->Specific.File.QueuedFlushCount) > 3)
+ lCount = InterlockedIncrement( &Fcb->Specific.File.QueuedFlushCount);
+
+ if( lCount > 3)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
pWorkItem->RequestType = AFS_WORK_FLUSH_FCB;
- RtlCopyMemory( &pWorkItem->AuthGroup,
- AuthGroup,
- sizeof( GUID));
+ if ( AuthGroup == NULL)
+ {
+
+ RtlZeroMemory( &pWorkItem->AuthGroup,
+ sizeof( GUID));
+
+ ntStatus = AFSRetrieveValidAuthGroup( Fcb,
+ NULL,
+ TRUE,
+ &pWorkItem->AuthGroup);
+ }
+ else
+ {
+ RtlCopyMemory( &pWorkItem->AuthGroup,
+ AuthGroup,
+ sizeof( GUID));
+ }
pWorkItem->Specific.Fcb.Fcb = Fcb;
- InterlockedIncrement( &Fcb->OpenReferenceCount);
+ lCount = InterlockedIncrement( &Fcb->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueFlushExtents Increment count on Fcb %08lX Cnt %d\n",
- Fcb,
- Fcb->OpenReferenceCount);
+ "AFSQueueFlushExtents Increment count on Fcb %p Cnt %d\n",
+ Fcb,
+ lCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueFlushExtents Workitem %08lX for FID %08lX-%08lX-%08lX-%08lX\n",
+ "AFSQueueFlushExtents Workitem %p for FID %08lX-%08lX-%08lX-%08lX\n",
pWorkItem,
Fcb->ObjectInformation->FileId.Cell,
Fcb->ObjectInformation->FileId.Volume,
// Remove the count we added above
//
- if( InterlockedDecrement( &Fcb->Specific.File.QueuedFlushCount) == 0)
+ lCount = InterlockedDecrement( &Fcb->Specific.File.QueuedFlushCount);
+
+ ASSERT( lCount >= 0);
+
+ if( lCount == 0)
{
KeSetEvent( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
if( pWorkItem != NULL)
{
- InterlockedDecrement( &Fcb->OpenReferenceCount);
+ lCount = InterlockedDecrement( &Fcb->OpenReferenceCount);
ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
}
"AFSQueueFlushExtents Failed to queue request Status %08lX\n", ntStatus);
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
"EXCEPTION - AFSQueueFlushExtents\n");
+
+ AFSDumpTraceFilesFnc();
}
return ntStatus;
}
NTSTATUS
-AFSQueueAsyncRead( IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN HANDLE CallerProcess)
+AFSQueueGlobalRootEnumeration()
{
NTSTATUS ntStatus = STATUS_SUCCESS;
__try
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncRead Queuing request for Irp %08lX\n",
- Irp);
-
pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
sizeof(AFSWorkItem),
AFS_WORK_ITEM_TAG);
AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueAsyncRead Failed to allocate work item\n");
+ "AFSQueueGlobalRootEnumeration Failed to allocate work item\n");
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
}
pWorkItem->Size = sizeof( AFSWorkItem);
- pWorkItem->RequestType = AFS_WORK_ASYNCH_READ;
-
- pWorkItem->Specific.AsynchIo.Device = DeviceObject;
-
- pWorkItem->Specific.AsynchIo.Irp = Irp;
-
- pWorkItem->Specific.AsynchIo.CallingProcess = CallerProcess;
+ pWorkItem->RequestType = AFS_WORK_ENUMERATE_GLOBAL_ROOT;
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncRead Workitem %08lX for Irp %08lX\n",
- pWorkItem,
- Irp);
+ "AFSQueueGlobalRootEnumeration Workitem %p\n",
+ pWorkItem);
ntStatus = AFSQueueWorkerRequest( pWorkItem);
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncRead Request for Irp %08lX complete Status %08lX\n",
- Irp,
+ "AFSQueueGlobalRootEnumeration Request complete Status %08lX\n",
ntStatus);
if( !NT_SUCCESS( ntStatus))
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueAsyncRead Failed to queue request Status %08lX\n", ntStatus);
+ "AFSQueueGlobalRootEnumeration Failed to queue request Status %08lX\n",
+ ntStatus);
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
- "EXCEPTION - AFSQueueAsyncRead\n");
+ "EXCEPTION - AFSQueueGlobalRootEnumeration\n");
+
+ AFSDumpTraceFilesFnc();
}
return ntStatus;
}
NTSTATUS
-AFSQueueAsyncWrite( IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN HANDLE CallerProcess)
+AFSQueueStartIos( IN PFILE_OBJECT CacheFileObject,
+ IN UCHAR FunctionCode,
+ IN ULONG RequestFlags,
+ IN AFSIoRun *IoRuns,
+ IN ULONG RunCount,
+ IN AFSGatherIo *GatherIo)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
+ AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
AFSWorkItem *pWorkItem = NULL;
__try
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncWrite Queuing request for Irp %08lX\n",
- Irp);
-
- pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
- sizeof(AFSWorkItem),
- AFS_WORK_ITEM_TAG);
- if (NULL == pWorkItem)
+ if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueAsyncWrite Failed to allocate work item\n");
+ "AFSQueueStartIos Failing request, in shutdown\n");
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
+ try_return( ntStatus = STATUS_TOO_LATE);
}
- RtlZeroMemory( pWorkItem,
- sizeof(AFSWorkItem));
-
- pWorkItem->Size = sizeof( AFSWorkItem);
-
- pWorkItem->RequestType = AFS_WORK_ASYNCH_WRITE;
-
- pWorkItem->Specific.AsynchIo.Device = DeviceObject;
-
- pWorkItem->Specific.AsynchIo.Irp = Irp;
-
- pWorkItem->Specific.AsynchIo.CallingProcess = CallerProcess;
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncWrite Workitem %08lX for Irp %08lX\n",
- pWorkItem,
- Irp);
-
- ntStatus = AFSQueueWorkerRequest( pWorkItem);
-
-try_exit:
+ //
+ // Allocate our request structure and send it to the worker
+ //
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncWrite Request for Irp %08lX complete Status %08lX\n",
- Irp,
- ntStatus);
+ pWorkItem = (AFSWorkItem *)AFSLibExAllocatePoolWithTag( NonPagedPool,
+ sizeof( AFSWorkItem),
+ AFS_WORK_ITEM_TAG);
- if( !NT_SUCCESS( ntStatus))
+ if( pWorkItem == NULL)
{
- if( pWorkItem != NULL)
- {
-
- ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
- }
-
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueAsyncWrite Failed to queue request Status %08lX\n", ntStatus);
+ "AFSQueueStartIos Failed to allocate work item\n");
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
- }
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
- {
- AFSDbgLogMsg( 0,
- 0,
- "EXCEPTION - AFSQueueAsyncWrite\n");
- }
+ RtlZeroMemory( pWorkItem,
+ sizeof( AFSWorkItem));
- return ntStatus;
-}
+ KeInitializeEvent( &pWorkItem->Event,
+ NotificationEvent,
+ FALSE);
-NTSTATUS
-AFSQueueGlobalRootEnumeration()
-{
+ pWorkItem->Size = sizeof( AFSWorkItem);
- NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSWorkItem *pWorkItem = NULL;
+ pWorkItem->ProcessID = (ULONGLONG)PsGetCurrentProcessId();
- __try
- {
+ pWorkItem->RequestType = AFS_WORK_START_IOS;
- pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
- sizeof(AFSWorkItem),
- AFS_WORK_ITEM_TAG);
- if (NULL == pWorkItem)
- {
+ pWorkItem->Specific.CacheAccess.CacheFileObject = CacheFileObject;
- AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueueGlobalRootEnumeration Failed to allocate work item\n");
+ pWorkItem->Specific.CacheAccess.FunctionCode = FunctionCode;
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
- }
+ pWorkItem->Specific.CacheAccess.RequestFlags = RequestFlags;
- RtlZeroMemory( pWorkItem,
- sizeof(AFSWorkItem));
+ pWorkItem->Specific.CacheAccess.IoRuns = IoRuns;
- pWorkItem->Size = sizeof( AFSWorkItem);
+ pWorkItem->Specific.CacheAccess.RunCount = RunCount;
- pWorkItem->RequestType = AFS_WORK_ENUMERATE_GLOBAL_ROOT;
+ pWorkItem->Specific.CacheAccess.GatherIo = GatherIo;
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueGlobalRootEnumeration Workitem %08lX\n",
+ "AFSQueueStartIos Queuing IO Workitem %p\n",
pWorkItem);
- ntStatus = AFSQueueWorkerRequest( pWorkItem);
+ ntStatus = AFSQueueIOWorkerRequest( pWorkItem);
try_exit:
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueGlobalRootEnumeration Request complete Status %08lX\n",
+ "AFSQueueStartIos Request complete Status %08lX\n",
ntStatus);
if( !NT_SUCCESS( ntStatus))
ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
}
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueueGlobalRootEnumeration Failed to queue request Status %08lX\n",
- ntStatus);
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
- "EXCEPTION - AFSQueueGlobalRootEnumeration\n");
+ "EXCEPTION - AFSQueueStartIos\n");
+
+ AFSDumpTraceFilesFnc();
}
return ntStatus;
}
NTSTATUS
-AFSQueueStartIos( IN PFILE_OBJECT CacheFileObject,
- IN UCHAR FunctionCode,
- IN ULONG RequestFlags,
- IN AFSIoRun *IoRuns,
- IN ULONG RunCount,
- IN AFSGatherIo *GatherIo)
+AFSQueueInvalidateObject( IN AFSObjectInfoCB *ObjectInfo,
+ IN ULONG InvalidateReason)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
AFSWorkItem *pWorkItem = NULL;
__try
{
- if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueueStartIos Failing request, in shutdown\n");
-
- try_return( ntStatus = STATUS_TOO_LATE);
- }
-
- //
- // Allocate our request structure and send it to the worker
- //
-
- pWorkItem = (AFSWorkItem *)AFSLibExAllocatePoolWithTag( NonPagedPool,
- sizeof( AFSWorkItem),
- AFS_WORK_ITEM_TAG);
-
- if( pWorkItem == NULL)
+ pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
+ sizeof(AFSWorkItem),
+ AFS_WORK_ITEM_TAG);
+ if (NULL == pWorkItem)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueStartIos Failed to allocate work item\n");
+ "AFSQueueInvalidateObject Failed to allocate work item\n");
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
}
RtlZeroMemory( pWorkItem,
- sizeof( AFSWorkItem));
-
- KeInitializeEvent( &pWorkItem->Event,
- NotificationEvent,
- FALSE);
+ sizeof(AFSWorkItem));
pWorkItem->Size = sizeof( AFSWorkItem);
- pWorkItem->ProcessID = (ULONGLONG)PsGetCurrentProcessId();
+ pWorkItem->RequestType = AFS_WORK_INVALIDATE_OBJECT;
- pWorkItem->RequestType = AFS_WORK_START_IOS;
+ pWorkItem->Specific.Invalidate.ObjectInfo = ObjectInfo;
- pWorkItem->Specific.CacheAccess.CacheFileObject = CacheFileObject;
-
- pWorkItem->Specific.CacheAccess.FunctionCode = FunctionCode;
-
- pWorkItem->Specific.CacheAccess.RequestFlags = RequestFlags;
-
- pWorkItem->Specific.CacheAccess.IoRuns = IoRuns;
-
- pWorkItem->Specific.CacheAccess.RunCount = RunCount;
-
- pWorkItem->Specific.CacheAccess.GatherIo = GatherIo;
+ pWorkItem->Specific.Invalidate.InvalidateReason = InvalidateReason;
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueStartIos Queuing IO Workitem %08lX\n",
+ "AFSQueueInvalidateObject Workitem %p\n",
pWorkItem);
- ntStatus = AFSQueueIOWorkerRequest( pWorkItem);
+ ntStatus = AFSQueueWorkerRequest( pWorkItem);
try_exit:
AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueStartIos Request complete Status %08lX\n",
+ "AFSQueueInvalidateObject Request complete Status %08lX\n",
ntStatus);
if( !NT_SUCCESS( ntStatus))
if( pWorkItem != NULL)
{
-
ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
}
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSQueueInvalidateObject Failed to queue request Status %08lX\n",
+ ntStatus);
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
- "EXCEPTION - AFSQueueStartIos\n");
+ "EXCEPTION - AFSQueueInvalidateObject\n");
+
+ AFSDumpTraceFilesFnc();
}
return ntStatus;