/*
* Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
- * notice,
- * this list of conditions and the following disclaimer in the
- * documentation
- * and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
* nor the names of their contributors may be used to endorse or promote
* products derived from this software without specific prior written
#include "AFSCommon.h"
+static
+VOID
+AFSPostedDeferredWrite( IN PVOID Context1,
+ IN PVOID Context2);
+
//
// Function: AFSInitializeWorkerPool
//
// Initialize the worker threads.
//
- pDevExt->Specific.Library.WorkerCount = 0;
-
- KeInitializeEvent( &pDevExt->Specific.Library.WorkerQueueHasItems,
- SynchronizationEvent,
- FALSE);
-
- //
- // Initialize the queue resource
- //
-
- ExInitializeResourceLite( &pDevExt->Specific.Library.QueueLock);
-
while( pDevExt->Specific.Library.WorkerCount < AFS_WORKER_COUNT)
{
if( pCurrentWorker == NULL)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeWorkerPool Failed to allocate worker context\n");
+ "AFSInitializeWorkerPool Failed to allocate worker context\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
if( !NT_SUCCESS( ntStatus))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeWorkerPool Failed to initialize worker thread Status %08lX\n", ntStatus);
+ "AFSInitializeWorkerPool Failed to initialize worker thread Status %08lX\n",
+ ntStatus));
ExFreePool( pCurrentWorker);
// Now our IO Worker queue
//
- pDevExt->Specific.Library.IOWorkerCount = 0;
-
- KeInitializeEvent( &pDevExt->Specific.Library.IOWorkerQueueHasItems,
- SynchronizationEvent,
- FALSE);
-
- //
- // Initialize the queue resource
- //
-
- ExInitializeResourceLite( &pDevExt->Specific.Library.IOQueueLock);
-
while( pDevExt->Specific.Library.IOWorkerCount < AFS_IO_WORKER_COUNT)
{
if( pCurrentWorker == NULL)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeWorkerPool Failed to allocate IO worker context\n");
+ "AFSInitializeWorkerPool Failed to allocate IO worker context\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
if( !NT_SUCCESS( ntStatus))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeWorkerPool Failed to initialize IO worker thread Status %08lX\n", ntStatus);
+ "AFSInitializeWorkerPool Failed to initialize IO worker thread Status %08lX\n",
+ ntStatus));
ExFreePool( pCurrentWorker);
pDevExt->Specific.Library.PoolHead = NULL;
- ExDeleteResourceLite( &pDevExt->Specific.Library.QueueLock);
-
//
// 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 AFSShutdownWorkerThread()
+ // stop processing requests. Second, call AFSShutdownIOWorkerThread()
// to wake the workers and wait for them to exit.
//
pDevExt->Specific.Library.IOPoolHead = NULL;
- ExDeleteResourceLite( &pDevExt->Specific.Library.IOQueueLock);
-
return ntStatus;
}
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSWorkQueueContext *pWorker = &VolumeCB->VolumeWorkerContext;
+ AFSWorkQueueContext *pWorker = &VolumeCB->NonPagedVcb->VolumeWorkerContext;
HANDLE hThread;
AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
PKSTART_ROUTINE pStartRoutine = NULL;
__Enter
{
- if( VolumeCB == AFSGlobalRoot)
+ if ( VolumeCB != AFSGlobalRoot)
{
- pStartRoutine = AFSPrimaryVolumeWorkerThread;
+ return STATUS_INVALID_PARAMETER;
}
- else
- {
- pStartRoutine = AFSVolumeWorkerThread;
- }
+ pStartRoutine = AFSPrimaryVolumeWorkerThread;
//
// Initialize the worker thread
{
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);
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
+ AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
- if( PoolContext->WorkerThreadObject != NULL &&
- BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED))
+ if( PoolContext->WorkerThreadObject != NULL)
{
- //
- // Wake up the thread if it is a sleep
- //
+ while ( BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED) )
+ {
- KeSetEvent( &pDeviceExt->Specific.Library.WorkerQueueHasItems,
- 0,
- FALSE);
+ //
+ // Wake up the thread if it is a sleep
+ //
- ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ KeSetEvent( &pControlDeviceExt->Specific.Control.WorkerQueueHasItems,
+ 0,
+ FALSE);
+
+ ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
ObDereferenceObject( PoolContext->WorkerThreadObject);
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
+ AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
- if( PoolContext->WorkerThreadObject != NULL &&
- BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED))
+ if( PoolContext->WorkerThreadObject != NULL)
{
- //
- // Wake up the thread if it is a sleep
- //
+ while ( BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED) )
+ {
- KeSetEvent( &pDeviceExt->Specific.Library.IOWorkerQueueHasItems,
- 0,
- FALSE);
+ //
+ // Wake up the thread if it is a sleep
+ //
- ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ KeSetEvent( &pControlDeviceExt->Specific.Control.IOWorkerQueueHasItems,
+ 0,
+ FALSE);
+
+ ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
ObDereferenceObject( PoolContext->WorkerThreadObject);
AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
AFSWorkItem *pWorkItem;
BOOLEAN freeWorkItem = TRUE;
- AFSDeviceExt *pLibraryDevExt = NULL;
+ AFSDeviceExt *pControlDevExt = NULL;
LONG lCount;
- pLibraryDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
+ pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
//
// Indicate that we are initialized and ready
SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
- ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
+ ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.WorkerQueueHasItems,
Executive,
KernelMode,
FALSE,
if( !NT_SUCCESS( ntStatus))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
+ "AFSWorkerThread Wait for queue items failed Status %08lX\n",
+ ntStatus));
ntStatus = STATUS_SUCCESS;
}
if( pWorkItem == NULL)
{
- ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
+ ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.WorkerQueueHasItems,
Executive,
KernelMode,
FALSE,
{
AFSReleaseExtentsWithFlush( pWorkItem->Specific.Fcb.Fcb,
- &pWorkItem->AuthGroup);
+ &pWorkItem->AuthGroup,
+ FALSE);
}
ASSERT( pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount != 0);
break;
}
- case AFS_WORK_ASYNCH_READ:
- {
-
- ASSERT( pWorkItem->Specific.AsynchIo.CallingProcess != NULL);
-
- (VOID) AFSCommonRead( pWorkItem->Specific.AsynchIo.Device,
- pWorkItem->Specific.AsynchIo.Irp,
- pWorkItem->Specific.AsynchIo.CallingProcess);
-
- break;
- }
-
- case AFS_WORK_ASYNCH_WRITE:
- {
-
- 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:
{
default:
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSWorkerThread Unknown request type %d\n", pWorkItem->RequestType);
+ "AFSWorkerThread Unknown request type %d\n",
+ pWorkItem->RequestType));
break;
}
// Wake up another worker so they too can exit
- KeSetEvent( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
+ KeSetEvent( &pControlDevExt->Specific.Control.WorkerQueueHasItems,
0,
FALSE);
AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
AFSWorkItem *pWorkItem;
BOOLEAN freeWorkItem = TRUE;
- AFSDeviceExt *pLibraryDevExt = NULL, *pRdrDevExt = NULL;
+ AFSDeviceExt *pControlDevExt = NULL, *pRdrDevExt = NULL;
- pLibraryDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
+ pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
//
// Indicate that we are initialized and ready
SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
- ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
+ ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.IOWorkerQueueHasItems,
Executive,
KernelMode,
FALSE,
if( !NT_SUCCESS( ntStatus))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSIOWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
+ "AFSIOWorkerThread Wait for queue items failed Status %08lX\n",
+ ntStatus));
ntStatus = STATUS_SUCCESS;
}
if( pWorkItem == NULL)
{
- ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
+ ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.IOWorkerQueueHasItems,
Executive,
KernelMode,
FALSE,
break;
}
+ case AFS_WORK_DEFERRED_WRITE:
+ {
+
+ ntStatus = AFSCommonWrite( pWorkItem->Specific.AsynchIo.Device,
+ pWorkItem->Specific.AsynchIo.Irp,
+ pWorkItem->Specific.AsynchIo.CallingProcess,
+ TRUE);
+
+ freeWorkItem = TRUE;
+
+ break;
+ }
+
default:
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSWorkerThread Unknown request type %d\n", pWorkItem->RequestType);
+ "AFSIOWorkerThread Unknown request type %d\n",
+ pWorkItem->RequestType));
break;
}
// Wake up another IOWorker so they too can exit
- KeSetEvent( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
+ KeSetEvent( &pControlDevExt->Specific.Control.IOWorkerQueueHasItems,
0,
FALSE);
return;
}
-void
-AFSPrimaryVolumeWorkerThread( IN PVOID Context)
-{
+//
+// Called with VolumeCB->ObjectInfoTree.TreeLock held exclusive.
+// pCurrentObject->ObjectReferenceCount is incremented by the caller.
+//
+// The *pbReleaseVolumeLock is set to FALSE if the TreeLock is dropped
+// before returning.
+//
+// pCurrentObject must either be destroyed or the reference count
+// decremented before returning.
+//
+static void
+AFSExamineObjectInfo( IN AFSObjectInfoCB * pCurrentObject,
+ IN BOOLEAN bVolumeObject,
+ IN OUT BOOLEAN * pbReleaseVolumeLock)
+{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&AFSGlobalRoot->VolumeWorkerContext;
- AFSDeviceExt *pControlDeviceExt = NULL;
- AFSDeviceExt *pRDRDeviceExt = NULL;
- LARGE_INTEGER DueTime;
- LONG TimeOut;
- KTIMER Timer;
- BOOLEAN bFoundOpenEntry = FALSE;
- AFSObjectInfoCB *pCurrentObject = NULL, *pNextObject = NULL, *pCurrentChildObject = NULL;
+ AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
+ AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
- BOOLEAN bReleaseVolumeLock = FALSE;
- AFSVolumeCB *pVolumeCB = NULL, *pNextVolume = NULL;
- AFSFcb *pFcb = NULL;
- LONG lFileType;
+ AFSObjectInfoCB *pCurrentChildObject = NULL;
+ AFSVolumeCB * pVolumeCB = pCurrentObject->VolumeCB;
LARGE_INTEGER liCurrentTime;
- BOOLEAN bVolumeObject = FALSE;
LONG lCount;
+ BOOLEAN bTemp;
- pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
-
- pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPrimaryVolumeWorkerThread Initialized\n");
-
- //
- // Initialize the timer for the worker thread
- //
-
- DueTime.QuadPart = -(5000);
-
- TimeOut = 5000;
-
- KeInitializeTimerEx( &Timer,
- SynchronizationTimer);
+ __Enter
+ {
- KeSetTimerEx( &Timer,
- DueTime,
- TimeOut,
- NULL);
+ ASSERT( ExIsResourceAcquiredExclusiveLite( pVolumeCB->ObjectInfoTree.TreeLock));
- //
- // Indicate that we are initialized and ready
- //
+ switch ( pCurrentObject->FileType)
+ {
- KeSetEvent( &pPoolContext->WorkerThreadReady,
- 0,
- FALSE);
+ case AFS_FILE_TYPE_DIRECTORY:
+ {
- //
- // Indicate we are initialized
- //
+ if ( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
+ {
- SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+ try_return( ntStatus);
+ }
- while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
- {
+ //
+ // If this object is deleted then remove it from the parent, if we can
+ //
- KeWaitForSingleObject( &Timer,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED))
+ {
- //
- // This is the primary volume worker so it will traverse the volume list
- // looking for cleanup or volumes requiring private workers
- //
+ if ( pCurrentObject->ObjectReferenceCount == 1 &&
+ ( pCurrentObject->Fcb == NULL ||
+ pCurrentObject->Fcb->OpenReferenceCount == 0) &&
+ pCurrentObject->Specific.Directory.DirectoryNodeListHead == NULL &&
+ pCurrentObject->Specific.Directory.ChildOpenReferenceCount == 0)
+ {
- AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
- TRUE);
+ AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
+ if ( pCurrentObject->Fcb != NULL)
+ {
- while( pVolumeCB != NULL)
- {
+ AFSRemoveFcb( &pCurrentObject->Fcb);
+ }
- if( pVolumeCB == AFSGlobalRoot ||
- !AFSAcquireExcl( pVolumeCB->VolumeLock,
- FALSE))
- {
+ if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
+ {
- pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
+ AFSAcquireExcl( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- continue;
- }
+ AFSRemoveFcb( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
- if( pVolumeCB->ObjectInfoListHead == NULL)
- {
+ AFSReleaseResource( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
- AFSReleaseResource( pVolumeCB->VolumeLock);
+ lCount = AFSObjectInfoDecrement( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation,
+ AFS_OBJECT_REFERENCE_PIOCTL);
- AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
+ AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineObjectInfo Decrement count on object %p Cnt %d\n",
+ pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation,
+ lCount));
- AFSAcquireExcl( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock,
- TRUE);
+ ASSERT( lCount == 0);
- AFSAcquireExcl( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
- TRUE);
+ if ( lCount == 0)
+ {
- if( !AFSAcquireExcl( pVolumeCB->VolumeLock,
- FALSE))
- {
+ AFSDeleteObjectInfo( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
+ }
- AFSConvertToShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
+ ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
- AFSReleaseResource( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock);
+ AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
- pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
+ AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineObjectInfo (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n",
+ pCurrentObject->Specific.Directory.PIOCtlDirectoryCB));
- continue;
- }
+ AFSExFreePoolWithTag( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
- KeQueryTickCount( &liCurrentTime);
+ pCurrentObject->Specific.Directory.PIOCtlDirectoryCB = NULL;
+ }
- pNextVolume = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
- if( pVolumeCB->ObjectInfoListHead == NULL &&
- pVolumeCB->DirectoryCB->OpenReferenceCount == 0 &&
- pVolumeCB->VolumeReferenceCount == 1 &&
- ( pVolumeCB->RootFcb == NULL ||
- pVolumeCB->RootFcb->OpenReferenceCount == 0) &&
- pVolumeCB->ObjectInformation.ObjectReferenceCount <= 0)
- {
+ lCount = AFSObjectInfoDecrement( pCurrentObject,
+ AFS_OBJECT_REFERENCE_WORKER);
- if( pVolumeCB->RootFcb != NULL)
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineObjectInfo Decrement1 count on object %p Cnt %d\n",
+ pCurrentObject,
+ lCount));
- AFSRemoveRootFcb( pVolumeCB->RootFcb);
- }
+ AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineObjectInfo Deleting deleted object %p\n",
+ pCurrentObject));
- AFSRemoveVolume( pVolumeCB);
- }
- else
- {
+ //
+ // The CurrentReferenceCount must be zero or we would not
+ // have gotten this far. It is safe to delete the ObjectInfoCB.
+ //
- AFSReleaseResource( pVolumeCB->VolumeLock);
+ AFSDeleteObjectInfo( &pCurrentObject);
}
- AFSConvertToShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
-
- AFSReleaseResource( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock);
-
- pVolumeCB = pNextVolume;
+ //
+ // Finished processing the AFS_OBJECT_FLAGS_DELETED case.
+ //
- continue;
+ try_return( ntStatus);
}
//
- // Don't need this lock anymore now that we have a volume cb to work with
+ // pCurrentObject not marked Deleted.
//
- AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
-
- //
- // For now we only need the volume lock shared
- //
+ if ( pCurrentObject->Fcb != NULL &&
+ pCurrentObject->Fcb->CcbListHead != NULL)
+ {
- AFSConvertToShared( pVolumeCB->VolumeLock);
+ try_return( ntStatus);
+ }
- if( AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
- FALSE))
+ if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0 ||
+ ( pCurrentObject->Fcb != NULL &&
+ pCurrentObject->Fcb->OpenReferenceCount > 0))
{
- pCurrentObject = pVolumeCB->ObjectInfoListHead;
+ try_return( ntStatus);
+ }
- pNextObject = NULL;
+ if ( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
+ pCurrentObject->Specific.Directory.DirectoryNodeListHead != NULL)
+ {
- bReleaseVolumeLock = TRUE;
+ //
+ // Directory Entry Processing
+ //
+ // First pass is performed with the TreeLock held shared.
+ // If we detect any objects in use, we give up quickly without
+ // making any changes and without blocking other threads.
+ // The second pass is performed with the TreeLock held exclusive
+ // so deletions can take place.
+ //
- while( pCurrentObject != NULL)
+ if( !AFSAcquireShared( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ FALSE))
{
- if( pCurrentObject != &pVolumeCB->ObjectInformation)
- {
+ try_return( ntStatus);
+ }
- pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
+ KeQueryTickCount( &liCurrentTime);
- if( pNextObject == NULL &&
- pVolumeCB != AFSGlobalRoot) // Don't free up the root of the global
- {
+ pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
- pNextObject = &pVolumeCB->ObjectInformation;
- }
+ while( pCurrentDirEntry != NULL)
+ {
- bVolumeObject = FALSE;
- }
- else
+ if( pCurrentDirEntry->DirOpenReferenceCount > 0 ||
+ pCurrentDirEntry->NameArrayReferenceCount > 0)
{
- pNextObject = NULL;
+ AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
- bVolumeObject = TRUE;
+ try_return( ntStatus);
}
- if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
- !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN)) // If we are in shutdown mode skip directories
+ if ( pCurrentDirEntry->ObjectInformation != NULL)
{
- //
- // 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)
+ if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
+ pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0)
{
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
- //
- // Dropping the TreeLock permits the
- // pCurrentObject->ObjectReferenceCount to change
- //
+ try_return( ntStatus);
+ }
- if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- FALSE))
- {
+ if ( liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart ||
+ liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart <
+ pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart)
+ {
- if ( pCurrentObject->ObjectReferenceCount <= 0)
- {
+ AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
- if( pCurrentObject->Fcb != NULL)
- {
+ try_return( ntStatus);
+ }
- AFSRemoveFcb( &pCurrentObject->Fcb);
- }
+ if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
+ {
- if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
- {
+ if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
+ {
- if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
- {
+ break;
+ }
- AFSRemoveFcb( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
- }
+ if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)
+ {
- AFSDeleteObjectInfo( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
+ break;
+ }
+ }
- ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
+ if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE)
+ {
- AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged);
+ if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
+ pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0)
+ {
- AFSExFreePool( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB);
- }
+ break;
+ }
+ }
+ }
- AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPrimaryVolumeWorkerThread Deleting deleted object %08lX\n",
- pCurrentObject);
+ pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
+ }
- AFSDeleteObjectInfo( pCurrentObject);
- }
+ AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
- AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
+ if( pCurrentDirEntry != NULL)
+ {
- pCurrentObject = pNextObject;
+ try_return( ntStatus);
+ }
- continue;
- }
- else
- {
+ //
+ // Attempt the second pass with the TreeLock held exclusive.
+ // The the TreeLock cannot be obtained without blocking it means that
+ // the directory is in active use, so do nothing.
+ //
- bReleaseVolumeLock = FALSE;
+ if( AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ FALSE))
+ {
- break;
- }
- }
+ if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0)
+ {
- if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0 ||
- ( pCurrentObject->Fcb != NULL &&
- pCurrentObject->Fcb->OpenReferenceCount > 0) ||
- pCurrentObject->Specific.Directory.DirectoryNodeListHead == NULL)
- {
+ AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
- pCurrentObject = pNextObject;
+ try_return( ntStatus);
+ }
- continue;
- }
+ KeQueryTickCount( &liCurrentTime);
- if( !AFSAcquireShared( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
- FALSE))
- {
+ pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
- pCurrentObject = pNextObject;
+ while( pCurrentDirEntry != NULL)
+ {
- continue;
+ if( pCurrentDirEntry->DirOpenReferenceCount > 0)
+ {
+
+ break;
}
- KeQueryTickCount( &liCurrentTime);
+ if ( pCurrentDirEntry->NameArrayReferenceCount > 0)
+ {
- pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
+ break;
+ }
- while( pCurrentDirEntry != NULL)
+ if ( pCurrentDirEntry->ObjectInformation != NULL)
{
- if( pCurrentDirEntry->OpenReferenceCount > 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))
+ if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
+ pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0)
{
break;
}
- pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
- }
-
- if( pCurrentDirEntry != NULL)
- {
-
- AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ if ( liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart ||
+ liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart <
+ pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart)
+ {
- pCurrentObject = pNextObject;
+ break;
+ }
- continue;
- }
+ if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
+ {
- AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
+ {
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ break;
+ }
- //
- // Now acquire the locks excl
- //
+ if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)
+ {
- if( AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
- FALSE))
- {
+ break;
+ }
+ }
- if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- FALSE))
+ if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE)
{
- if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0)
+ if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
+ pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0)
{
- AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
- AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
-
- pCurrentObject = pNextObject;
-
- continue;
+ break;
}
+ }
+ }
- KeQueryTickCount( &liCurrentTime);
+ pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
+ }
- pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
+ if( pCurrentDirEntry != NULL)
+ {
- while( pCurrentDirEntry != NULL)
- {
+ //
+ // At least one entry in the directory is actively in use.
+ // Drop the lock and exit without removing anything.
+ //
- if( pCurrentDirEntry->OpenReferenceCount > 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;
- }
+ AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
- if( pCurrentDirEntry != NULL)
- {
+ try_return( ntStatus);
+ }
- AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ //
+ // Third pass, process each directory entry and remove what we can.
+ // The VolumeCB TreeLock and the ObjectInfo TreeLock are still held exclusive.
+ //
- AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
+ pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
- pCurrentObject = pNextObject;
+ while( pCurrentDirEntry != NULL)
+ {
- continue;
- }
+ pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
- pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
+ //
+ // Delete the DirectoryCB which in turn removes the DIRENTRY reference
+ // count from the associated ObjectInfoCB. The reference count held above
+ // may now be the only one left.
+ //
- while( pCurrentDirEntry != NULL)
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineObjectInfo Deleting DE %wZ Object %p\n",
+ &pCurrentDirEntry->NameInformation.FileName,
+ pCurrentDirEntry->ObjectInformation));
- pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
+ AFSDeleteDirEntry( pCurrentObject,
+ &pCurrentDirEntry);
- pCurrentChildObject = pCurrentDirEntry->ObjectInformation;
+ pCurrentDirEntry = pNextDirEntry;
+ }
- pFcb = NULL;
+ //
+ // Clear our enumerated flag on this object so we retrieve info again on next access
+ //
- AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPrimaryVolumeWorkerThread Deleting DE %wZ Object %08lX\n",
- &pCurrentDirEntry->NameInformation.FileName,
- pCurrentChildObject);
+ ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
- AFSDeleteDirEntry( pCurrentObject,
- pCurrentDirEntry);
+ AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+ }
+ else if ( bVolumeObject == FALSE)
+ {
+ //
+ // No children
+ //
- if( pCurrentChildObject->ObjectReferenceCount <= 0)
- {
+ if( pCurrentObject->ObjectReferenceCount > 1 ||
+ pCurrentObject->Fcb != NULL &&
+ pCurrentObject->Fcb->OpenReferenceCount > 0)
+ {
- if( pCurrentChildObject->Fcb != NULL)
- {
+ try_return( ntStatus);
+ }
- pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)&pCurrentChildObject->Fcb, NULL, (PVOID)pCurrentChildObject->Fcb);
+ AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- lFileType = pCurrentChildObject->FileType;
- }
+ KeQueryTickCount( &liCurrentTime);
- if( pCurrentChildObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
- pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
- {
+ if( pCurrentObject->ObjectReferenceCount == 1 &&
+ ( pCurrentObject->Fcb == NULL ||
+ pCurrentObject->Fcb->OpenReferenceCount == 0) &&
+ liCurrentTime.QuadPart > pCurrentObject->LastAccessCount.QuadPart &&
+ liCurrentTime.QuadPart - pCurrentObject->LastAccessCount.QuadPart >
+ pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart)
+ {
- if( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
- {
+ AFSRemoveFcb( &pCurrentObject->Fcb);
- AFSRemoveFcb( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
- }
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
- AFSDeleteObjectInfo( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
+ lCount = AFSObjectInfoDecrement( pCurrentObject,
+ AFS_OBJECT_REFERENCE_WORKER);
- ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
+ AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineObjectInfo Decrement4 count on object %p Cnt %d\n",
+ pCurrentObject,
+ lCount));
- AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged);
+ //
+ // The Volume TreeLock is held exclusive. Therefore, the ObjectReferenceCount
+ // cannot change. It is therefore safe to delete the ObjectInfoCB
+ //
- AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB);
- }
+ AFSDeleteObjectInfo( &pCurrentObject);
+ }
+ else
+ {
- AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPrimaryVolumeWorkerThread Deleting object %08lX\n",
- pCurrentChildObject);
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+ }
+ }
- AFSDeleteObjectInfo( pCurrentChildObject);
- }
+ break;
+ }
- pCurrentDirEntry = pNextDirEntry;
+ case AFS_FILE_TYPE_FILE:
+ {
- if ( pFcb != NULL)
- {
+ if( pCurrentObject->ObjectReferenceCount > 1 ||
+ pCurrentObject->Fcb != NULL &&
+ pCurrentObject->Fcb->OpenReferenceCount > 0)
+ {
- if( lFileType == 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.
- //
+ try_return( ntStatus);
+ }
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ if( pCurrentObject->Fcb != NULL)
+ {
- //
- // Dropping the TreeLock permits the
- // pCurrentObject->ObjectReferenceCount to change
- //
+ AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
- AFSCleanupFcb( pFcb,
- TRUE);
+ //
+ // Dropping the VolumeCB TreeLock permits the
+ // pCurrentObject->ObjectReferenceCount to change.
+ // But it cannot be held across the AFSCleanupFcb
+ // call.
+ //
- AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
- }
+ ntStatus = AFSCleanupFcb( pCurrentObject->Fcb,
+ FALSE);
- AFSRemoveFcb( &pFcb);
- }
- }
+ if (!AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
+ FALSE))
+ {
- pCurrentObject->Specific.Directory.DirectoryNodeListHead = NULL;
+ *pbReleaseVolumeLock = FALSE;
+ }
- pCurrentObject->Specific.Directory.DirectoryNodeListTail = NULL;
+ if ( ntStatus == STATUS_RETRY ||
+ *pbReleaseVolumeLock == FALSE)
+ {
- pCurrentObject->Specific.Directory.ShortNameTree = NULL;
+ //
+ // The Fcb is in use.
+ //
- pCurrentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
+ try_return( ntStatus);
+ }
+ }
- pCurrentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
+ //
+ // VolumeCB is held exclusive
+ //
- pCurrentObject->Specific.Directory.DirectoryNodeCount = 0;
+ AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- 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);
+ KeQueryTickCount( &liCurrentTime);
- //
- // Clear our enumerated flag on this object so we retrieve info again on next access
- //
+ if( pCurrentObject->ObjectReferenceCount == 1 &&
+ ( 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)
+ {
- ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
+ AFSRemoveFcb( &pCurrentObject->Fcb);
- AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
- AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
- }
- else
- {
+ lCount = AFSObjectInfoDecrement( pCurrentObject,
+ AFS_OBJECT_REFERENCE_WORKER);
- AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineObjectInfo Decrement5 count on object %p Cnt %d\n",
+ pCurrentObject,
+ lCount));
- bReleaseVolumeLock = FALSE;
+ //
+ // The VolumeCB TreeLock is held exclusive so the
+ // ObjectReferenceCount cannot change.
+ //
- break;
- }
- }
- else
- {
+ AFSDeleteObjectInfo( &pCurrentObject);
+ }
+ else
+ {
- //
- // Try to grab the volume lock again ... no problem if we don't
- //
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+ }
- if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- FALSE))
- {
+ break;
+ }
- bReleaseVolumeLock = FALSE;
+ default:
+ {
- break;
- }
- }
+ AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- if( pCurrentObject != &pVolumeCB->ObjectInformation)
- {
+ KeQueryTickCount( &liCurrentTime);
- pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
+ if( pCurrentObject->ObjectReferenceCount == 1 &&
+ ( pCurrentObject->Fcb == NULL ||
+ pCurrentObject->Fcb->OpenReferenceCount == 0) &&
+ liCurrentTime.QuadPart > pCurrentObject->LastAccessCount.QuadPart &&
+ liCurrentTime.QuadPart - pCurrentObject->LastAccessCount.QuadPart >
+ pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart)
+ {
- if( pCurrentObject == NULL &&
- pVolumeCB != AFSGlobalRoot)
- {
+ AFSRemoveFcb( &pCurrentObject->Fcb);
- pCurrentObject = &pVolumeCB->ObjectInformation;
- }
- }
- else
- {
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
- pCurrentObject = NULL;
- }
+ lCount = AFSObjectInfoDecrement( pCurrentObject,
+ AFS_OBJECT_REFERENCE_WORKER);
- continue;
- }
- else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineObjectInfo Decrement6 count on object %p Cnt %d\n",
+ pCurrentObject,
+ lCount));
- if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
- pCurrentObject->ObjectReferenceCount <= 0 &&
- ( pCurrentObject->Fcb == NULL ||
- pCurrentObject->Fcb->OpenReferenceCount == 0))
- {
+ //
+ // The VolumeCB TreeLock is held exclusive so the
+ // ObjectReferenceCount cannot change.
+ //
- pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)&pCurrentObject->Fcb, NULL, (PVOID)pCurrentObject->Fcb);
+ AFSDeleteObjectInfo( &pCurrentObject);
+ }
+ else
+ {
- if( pFcb != NULL)
- {
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+ }
+ }
+ }
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ try_exit:
- //
- // Dropping the TreeLock permits the
- // pCurrentObject->ObjectReferenceCount to change
- //
+ if ( pCurrentObject != NULL)
+ {
- AFSCleanupFcb( pFcb,
- TRUE);
+ lCount = AFSObjectInfoDecrement( pCurrentObject,
+ AFS_OBJECT_REFERENCE_WORKER);
- AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
+ AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineObjectInfo Decrement count on object %p Cnt %d\n",
+ pCurrentObject,
+ lCount));
+ }
+ }
+}
- AFSRemoveFcb( &pFcb);
- }
+//
+// Called with VolumeCB->VolumeLock held shared.
+//
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+static void
+AFSExamineVolume( IN AFSVolumeCB *pVolumeCB)
+{
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ AFSObjectInfoCB *pCurrentObject = NULL, *pNextObject = NULL;
+ BOOLEAN bReleaseVolumeTreeLock = FALSE;
+ BOOLEAN bVolumeObject = FALSE;
+ LONG lCount;
- if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- FALSE))
- {
+ //
+ // The Volume ObjectInfoTree TreeLock must be held exclusive to
+ // prevent other threads from obtaining a reference to an ObjectInfoCB
+ // via AFSFindObjectInfo() while it is being deleted. This is
+ // annoying but the alternative is to hold the TreeLock shared during
+ // garbage collection and exclusive during find operations.
+ //
- AFSDeleteObjectInfo( pCurrentObject);
+ if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
+ TRUE))
+ {
- AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
+ bReleaseVolumeTreeLock = TRUE;
- pCurrentObject = pNextObject;
+ pCurrentObject = pVolumeCB->ObjectInfoListHead;
- continue;
- }
- else
- {
+ lCount = AFSObjectInfoIncrement( pCurrentObject,
+ AFS_OBJECT_REFERENCE_WORKER);
- bReleaseVolumeLock = FALSE;
+ AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineVolume Increment count on object %p Cnt %d\n",
+ pCurrentObject,
+ lCount));
- break;
- }
- }
- else if( pCurrentObject->Fcb != NULL)
- {
+ pNextObject = NULL;
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ while( pCurrentObject != NULL &&
+ bReleaseVolumeTreeLock == TRUE)
+ {
- //
- // Dropping the TreeLock permits the
- // pCurrentObject->ObjectReferenceCount to change
- //
+ if( pCurrentObject != &pVolumeCB->ObjectInformation)
+ {
- AFSCleanupFcb( pCurrentObject->Fcb,
- FALSE);
+ pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
- AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
- }
- }
+ //
+ // 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
+ {
- pCurrentObject = pNextObject;
+ pNextObject = &pVolumeCB->ObjectInformation;
}
- if( bReleaseVolumeLock)
+ bVolumeObject = FALSE;
+
+ if ( pNextObject)
{
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ lCount = AFSObjectInfoIncrement( pNextObject,
+ AFS_OBJECT_REFERENCE_WORKER);
+
+ AFSDbgTrace(( 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;
+ }
+ AFSExamineObjectInfo( pCurrentObject, bVolumeObject, &bReleaseVolumeTreeLock);
+
+ if ( bReleaseVolumeTreeLock == TRUE &&
+ ( ExGetExclusiveWaiterCount( pVolumeCB->ObjectInfoTree.TreeLock) > 0 ||
+ ExGetSharedWaiterCount( pVolumeCB->ObjectInfoTree.TreeLock) > 0))
+ {
+
+ AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+
+ bReleaseVolumeTreeLock = FALSE;
+ }
//
- // Next volume cb
+ // The CurrentObject is either destroyed or the reference count has been
+ // dropped by AFSExamineObjectInfo().
//
- AFSReleaseResource( pVolumeCB->VolumeLock);
+ if ( bReleaseVolumeTreeLock == FALSE)
+ {
- AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
- TRUE);
+ //
+ // Try to obtain the Volume's ObjectInfoTree.TreeLock after dropping
+ // other locks and continue.
+ //
- pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
- }
+ bReleaseVolumeTreeLock = AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+ }
- AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
+ pCurrentObject = pNextObject;
- } // worker thread loop
+ pNextObject = NULL;
+ }
- KeCancelTimer( &Timer);
+ if ( pCurrentObject != NULL)
+ {
- AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPrimaryVolumeWorkerThread Exiting\n");
+ lCount = AFSObjectInfoDecrement( pCurrentObject,
+ AFS_OBJECT_REFERENCE_WORKER);
- lCount = InterlockedDecrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount);
+ AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSExamineVolume Decrement count on object %p Cnt %d\n",
+ pCurrentObject,
+ lCount));
+ }
- if( lCount == 0)
- {
+ if( bReleaseVolumeTreeLock)
+ {
- KeSetEvent( &pControlDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
- 0,
- FALSE);
+ AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ }
}
-
- PsTerminateSystemThread( 0);
-
- return;
}
void
-AFSVolumeWorkerThread( IN PVOID Context)
+AFSPrimaryVolumeWorkerThread( 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;
+ UNREFERENCED_PARAMETER(Context);
+ AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&AFSGlobalRoot->NonPagedVcb->VolumeWorkerContext;
+ AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
+ AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
LARGE_INTEGER DueTime;
LONG TimeOut;
KTIMER Timer;
+ AFSVolumeCB *pVolumeCB = NULL, *pNextVolume = NULL;
LONG lCount;
- pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
-
- pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+ AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPrimaryVolumeWorkerThread Initialized\n"));
//
// Initialize the timer for the worker thread
KeInitializeTimerEx( &Timer,
SynchronizationTimer);
- KeSetTimerEx( &Timer,
- DueTime,
- TimeOut,
- NULL);
+ 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))
+ {
+
+ KeWaitForSingleObject( &Timer,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ //
+ // This is the primary volume worker so it will traverse the volume list
+ // looking for cleanup or volumes requiring private workers
+ //
+
+ AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
+ TRUE);
+
+ pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
+
+ while( pVolumeCB != NULL)
+ {
+
+ if( pVolumeCB == AFSGlobalRoot ||
+ !AFSAcquireExcl( pVolumeCB->VolumeLock,
+ FALSE))
+ {
+
+ pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
+
+ continue;
+ }
+
+ if( pVolumeCB->ObjectInfoListHead == NULL)
+ {
+
+ AFSReleaseResource( pVolumeCB->VolumeLock);
+
+ AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
+
+ AFSAcquireExcl( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock,
+ TRUE);
+
+ AFSAcquireExcl( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
+ TRUE);
+
+ if( !AFSAcquireExcl( pVolumeCB->VolumeLock,
+ FALSE))
+ {
+
+ AFSConvertToShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
+
+ AFSReleaseResource( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock);
+
+ pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
+
+ continue;
+ }
+
+ pNextVolume = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
+
+ AFSAcquireExcl( &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 &&
+ pVolumeCB->VolumeReferenceCount == 0 &&
+ ( pVolumeCB->RootFcb == NULL ||
+ pVolumeCB->RootFcb->OpenReferenceCount == 0) &&
+ pVolumeCB->ObjectInformation.ObjectReferenceCount <= 0)
+ {
+
+ AFSRemoveRootFcb( pVolumeCB);
+
+ AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
+ AFSRemoveVolume( pVolumeCB);
+ }
+ else
+ {
+
+ AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
+ AFSReleaseResource( pVolumeCB->VolumeLock);
+ }
+
+ AFSConvertToShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
- //
- // Indicate that we are initialized and ready
- //
+ AFSReleaseResource( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock);
- KeSetEvent( &pPoolContext->WorkerThreadReady,
- 0,
- FALSE);
+ pVolumeCB = pNextVolume;
- //
- // Indicate we are initialized
- //
+ continue;
+ }
- SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+ //
+ // Don't need this lock anymore now that we have a volume cb to work with
+ //
- while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
- {
+ AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
- ntStatus = KeWaitForSingleObject( &Timer,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ //
+ // For now we only need the volume lock shared
+ //
- if( !NT_SUCCESS( ntStatus))
- {
+ AFSConvertToShared( pVolumeCB->VolumeLock);
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSVolumeWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
- }
- else
- {
+ AFSExamineVolume( pVolumeCB);
//
- // If we are in shutdown mode and the dirty flag is clear then get out now
+ // Next volume cb
//
- if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
- {
+ AFSReleaseResource( pVolumeCB->VolumeLock);
- break;
- }
+ AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
+ TRUE);
+
+ pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
}
+
+ AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
+
} // worker thread loop
KeCancelTimer( &Timer);
+ ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPrimaryVolumeWorkerThread Exiting\n"));
+
lCount = InterlockedDecrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount);
if( lCount == 0)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pDevExt = NULL;
+ AFSDeviceExt *pControlDevExt = NULL;
LONG lCount;
- pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
+ pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
- AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertWorkitem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
- &pDevExt->Specific.Library.QueueLock,
- PsGetCurrentThread());
+ "AFSInsertWorkitem Acquiring Control QueueLock lock %p EXCL %08lX\n",
+ &pControlDevExt->Specific.Control.QueueLock,
+ PsGetCurrentThread()));
- AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
+ AFSAcquireExcl( &pControlDevExt->Specific.Control.QueueLock,
TRUE);
- lCount = InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount);
+ lCount = InterlockedIncrement( &pControlDevExt->Specific.Control.QueueItemCount);
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( 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,
- lCount);
+ lCount));
- if( pDevExt->Specific.Library.QueueTail != NULL) // queue already has nodes
+ if( pControlDevExt->Specific.Control.QueueTail != NULL) // queue already has nodes
{
- pDevExt->Specific.Library.QueueTail->next = WorkItem;
+ pControlDevExt->Specific.Control.QueueTail->next = WorkItem;
}
else // first node
{
- pDevExt->Specific.Library.QueueHead = WorkItem;
+ pControlDevExt->Specific.Control.QueueHead = WorkItem;
}
WorkItem->next = NULL;
- pDevExt->Specific.Library.QueueTail = WorkItem;
+ pControlDevExt->Specific.Control.QueueTail = WorkItem;
// indicate that the queue has nodes
- KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
+ KeSetEvent( &(pControlDevExt->Specific.Control.WorkerQueueHasItems),
0,
FALSE);
- AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
+ AFSReleaseResource( &pControlDevExt->Specific.Control.QueueLock);
return ntStatus;
}
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pDevExt = NULL;
+ AFSDeviceExt *pControlDevExt = NULL;
LONG lCount;
- pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
+ pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
- AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertIOWorkitem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
- &pDevExt->Specific.Library.IOQueueLock,
- PsGetCurrentThread());
+ "AFSInsertIOWorkitem Acquiring Control QueueLock lock %p EXCL %08lX\n",
+ &pControlDevExt->Specific.Control.IOQueueLock,
+ PsGetCurrentThread()));
- AFSAcquireExcl( &pDevExt->Specific.Library.IOQueueLock,
+ AFSAcquireExcl( &pControlDevExt->Specific.Control.IOQueueLock,
TRUE);
- lCount = InterlockedIncrement( &pDevExt->Specific.Library.IOQueueItemCount);
+ lCount = InterlockedIncrement( &pControlDevExt->Specific.Control.IOQueueItemCount);
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( 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,
- lCount);
+ lCount));
- if( pDevExt->Specific.Library.IOQueueTail != NULL) // queue already has nodes
+ if( pControlDevExt->Specific.Control.IOQueueTail != NULL) // queue already has nodes
{
- pDevExt->Specific.Library.IOQueueTail->next = WorkItem;
+ pControlDevExt->Specific.Control.IOQueueTail->next = WorkItem;
}
else // first node
{
- pDevExt->Specific.Library.IOQueueHead = WorkItem;
+ pControlDevExt->Specific.Control.IOQueueHead = WorkItem;
}
WorkItem->next = NULL;
- pDevExt->Specific.Library.IOQueueTail = WorkItem;
+ pControlDevExt->Specific.Control.IOQueueTail = WorkItem;
// indicate that the queue has nodes
- KeSetEvent( &(pDevExt->Specific.Library.IOWorkerQueueHasItems),
+ KeSetEvent( &(pControlDevExt->Specific.Control.IOWorkerQueueHasItems),
0,
FALSE);
- AFSReleaseResource( &pDevExt->Specific.Library.IOQueueLock);
+ AFSReleaseResource( &pControlDevExt->Specific.Control.IOQueueLock);
return ntStatus;
}
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pDevExt = NULL;
+ AFSDeviceExt *pControlDevExt = NULL;
LONG lCount;
- pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
+ pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
- AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSInsertWorkitemAtHead Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
- &pDevExt->Specific.Library.QueueLock,
- PsGetCurrentThread());
+ "AFSInsertWorkitemAtHead Acquiring Control QueueLock lock %p EXCL %08lX\n",
+ &pControlDevExt->Specific.Control.QueueLock,
+ PsGetCurrentThread()));
- AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
+ AFSAcquireExcl( &pControlDevExt->Specific.Control.QueueLock,
TRUE);
- WorkItem->next = pDevExt->Specific.Library.QueueHead;
+ WorkItem->next = pControlDevExt->Specific.Control.QueueHead;
- pDevExt->Specific.Library.QueueHead = WorkItem;
+ pControlDevExt->Specific.Control.QueueHead = WorkItem;
- lCount = InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount);
+ lCount = InterlockedIncrement( &pControlDevExt->Specific.Control.QueueItemCount);
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( 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,
- lCount);
+ lCount));
//
// indicate that the queue has nodes
//
- KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
+ KeSetEvent( &(pControlDevExt->Specific.Control.WorkerQueueHasItems),
0,
FALSE);
- AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
+ AFSReleaseResource( &pControlDevExt->Specific.Control.QueueLock);
return ntStatus;
}
AFSRemoveWorkItem()
{
- NTSTATUS ntStatus = STATUS_SUCCESS;
AFSWorkItem *pWorkItem = NULL;
- AFSDeviceExt *pDevExt = NULL;
+ AFSDeviceExt *pControlDevExt = NULL;
LONG lCount;
- pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
+ pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
- AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSRemoveWorkItem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
- &pDevExt->Specific.Library.QueueLock,
- PsGetCurrentThread());
+ "AFSRemoveWorkItem Acquiring Control QueueLock lock %p EXCL %08lX\n",
+ &pControlDevExt->Specific.Control.QueueLock,
+ PsGetCurrentThread()));
- AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
+ AFSAcquireExcl( &pControlDevExt->Specific.Control.QueueLock,
TRUE);
- if( pDevExt->Specific.Library.QueueHead != NULL) // queue has nodes
+ if( pControlDevExt->Specific.Control.QueueHead != NULL) // queue has nodes
{
- pWorkItem = pDevExt->Specific.Library.QueueHead;
+ pWorkItem = pControlDevExt->Specific.Control.QueueHead;
- lCount = InterlockedDecrement( &pDevExt->Specific.Library.QueueItemCount);
+ lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.QueueItemCount);
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( 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,
lCount,
- PsGetCurrentThreadId());
+ PsGetCurrentThreadId()));
- pDevExt->Specific.Library.QueueHead = pDevExt->Specific.Library.QueueHead->next;
+ pControlDevExt->Specific.Control.QueueHead = pControlDevExt->Specific.Control.QueueHead->next;
- if( pDevExt->Specific.Library.QueueHead == NULL) // if queue just became empty
+ if( pControlDevExt->Specific.Control.QueueHead == NULL) // if queue just became empty
{
- pDevExt->Specific.Library.QueueTail = NULL;
+ pControlDevExt->Specific.Control.QueueTail = NULL;
}
else
{
// Wake up another worker
//
- KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
+ KeSetEvent( &(pControlDevExt->Specific.Control.WorkerQueueHasItems),
0,
FALSE);
}
}
- AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
+ AFSReleaseResource( &pControlDevExt->Specific.Control.QueueLock);
return pWorkItem;
}
AFSRemoveIOWorkItem()
{
- NTSTATUS ntStatus = STATUS_SUCCESS;
AFSWorkItem *pWorkItem = NULL;
- AFSDeviceExt *pDevExt = NULL;
+ AFSDeviceExt *pControlDevExt = NULL;
LONG lCount;
- pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
+ pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
- AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSRemoveIOWorkItem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
- &pDevExt->Specific.Library.IOQueueLock,
- PsGetCurrentThread());
+ "AFSRemoveIOWorkItem Acquiring Control QueueLock lock %p EXCL %08lX\n",
+ &pControlDevExt->Specific.Control.IOQueueLock,
+ PsGetCurrentThread()));
- AFSAcquireExcl( &pDevExt->Specific.Library.IOQueueLock,
+ AFSAcquireExcl( &pControlDevExt->Specific.Control.IOQueueLock,
TRUE);
- if( pDevExt->Specific.Library.IOQueueHead != NULL) // queue has nodes
+ if( pControlDevExt->Specific.Control.IOQueueHead != NULL) // queue has nodes
{
- pWorkItem = pDevExt->Specific.Library.IOQueueHead;
+ pWorkItem = pControlDevExt->Specific.Control.IOQueueHead;
- lCount = InterlockedDecrement( &pDevExt->Specific.Library.IOQueueItemCount);
+ lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.IOQueueItemCount);
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( 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,
lCount,
- PsGetCurrentThreadId());
+ PsGetCurrentThreadId()));
- pDevExt->Specific.Library.IOQueueHead = pDevExt->Specific.Library.IOQueueHead->next;
+ pControlDevExt->Specific.Control.IOQueueHead = pControlDevExt->Specific.Control.IOQueueHead->next;
- if( pDevExt->Specific.Library.IOQueueHead == NULL) // if queue just became empty
+ if( pControlDevExt->Specific.Control.IOQueueHead == NULL) // if queue just became empty
{
- pDevExt->Specific.Library.IOQueueTail = NULL;
+ pControlDevExt->Specific.Control.IOQueueTail = NULL;
}
else
{
// Wake up another worker
//
- KeSetEvent( &(pDevExt->Specific.Library.IOWorkerQueueHasItems),
+ KeSetEvent( &(pControlDevExt->Specific.Control.IOWorkerQueueHasItems),
0,
FALSE);
}
}
- AFSReleaseResource( &pDevExt->Specific.Library.IOQueueLock);
+ AFSReleaseResource( &pControlDevExt->Specific.Control.IOQueueLock);
return pWorkItem;
}
{
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);
//
__try
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSQueueFlushExtents Queuing request for FID %08lX-%08lX-%08lX-%08lX\n",
Fcb->ObjectInformation->FileId.Cell,
Fcb->ObjectInformation->FileId.Volume,
Fcb->ObjectInformation->FileId.Vnode,
- Fcb->ObjectInformation->FileId.Unique);
+ Fcb->ObjectInformation->FileId.Unique));
//
// Increment our flush count here just to keep the number of items in the
if( lCount > 3)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSQueueFlushExtents Max queued items for FID %08lX-%08lX-%08lX-%08lX\n",
Fcb->ObjectInformation->FileId.Cell,
Fcb->ObjectInformation->FileId.Volume,
Fcb->ObjectInformation->FileId.Vnode,
- Fcb->ObjectInformation->FileId.Unique);
+ Fcb->ObjectInformation->FileId.Unique));
try_return( ntStatus);
}
if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueFlushExtents Failing request, in shutdown\n");
+ "AFSQueueFlushExtents 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);
+ pWorkItem = (AFSWorkItem *)AFSExAllocatePoolWithTag( NonPagedPool,
+ sizeof( AFSWorkItem),
+ AFS_WORK_ITEM_TAG);
if( pWorkItem == NULL)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueFlushExtents Failed to allocate work item\n");
+ "AFSQueueFlushExtents Failed to allocate work item\n"));
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
lCount = InterlockedIncrement( &Fcb->OpenReferenceCount);
- AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueFlushExtents Increment count on Fcb %08lX Cnt %d\n",
+ "AFSQueueFlushExtents Increment count on Fcb %p Cnt %d\n",
Fcb,
- lCount);
+ lCount));
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( 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,
Fcb->ObjectInformation->FileId.Vnode,
- Fcb->ObjectInformation->FileId.Unique);
+ Fcb->ObjectInformation->FileId.Unique));
ntStatus = AFSQueueWorkerRequest( pWorkItem);
try_exit:
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSQueueFlushExtents Request complete Status %08lX FID %08lX-%08lX-%08lX-%08lX\n",
Fcb->ObjectInformation->FileId.Cell,
Fcb->ObjectInformation->FileId.Volume,
Fcb->ObjectInformation->FileId.Vnode,
Fcb->ObjectInformation->FileId.Unique,
- ntStatus);
+ ntStatus));
//
// Remove the count we added above
lCount = InterlockedDecrement( &Fcb->Specific.File.QueuedFlushCount);
+ ASSERT( lCount >= 0);
+
if( lCount == 0)
{
ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
}
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueFlushExtents Failed to queue request Status %08lX\n", ntStatus);
+ "AFSQueueFlushExtents Failed to queue request Status %08lX\n",
+ ntStatus));
}
}
__except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
- AFSDbgLogMsg( 0,
+ AFSDbgTrace(( 0,
0,
- "EXCEPTION - AFSQueueFlushExtents\n");
+ "EXCEPTION - AFSQueueFlushExtents\n"));
AFSDumpTraceFilesFnc();
}
}
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);
+ pWorkItem = (AFSWorkItem *) AFSExAllocatePoolWithTag( NonPagedPool,
+ sizeof(AFSWorkItem),
+ AFS_WORK_ITEM_TAG);
if (NULL == pWorkItem)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFSDbgTrace(( 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,
+ AFSDbgTrace(( 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);
try_exit:
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncRead Request for Irp %08lX complete Status %08lX\n",
- Irp,
- ntStatus);
+ "AFSQueueGlobalRootEnumeration Request complete Status %08lX\n",
+ ntStatus));
if( !NT_SUCCESS( ntStatus))
{
ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
}
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( 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( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
- AFSDbgLogMsg( 0,
+ AFSDbgTrace(( 0,
0,
- "EXCEPTION - AFSQueueAsyncRead\n");
+ "EXCEPTION - AFSQueueGlobalRootEnumeration\n"));
AFSDumpTraceFilesFnc();
}
}
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);
+ if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
+ {
- pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
- sizeof(AFSWorkItem),
- AFS_WORK_ITEM_TAG);
- if (NULL == pWorkItem)
+ AFSDbgTrace(( 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 *)AFSExAllocatePoolWithTag( NonPagedPool,
+ sizeof( AFSWorkItem),
+ AFS_WORK_ITEM_TAG);
+
+ if( pWorkItem == NULL)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueAsyncWrite Failed to allocate work item\n");
+ "AFSQueueStartIos Failed to allocate work item\n"));
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory( pWorkItem,
- sizeof(AFSWorkItem));
+ sizeof( AFSWorkItem));
+
+ KeInitializeEvent( &pWorkItem->Event,
+ NotificationEvent,
+ FALSE);
pWorkItem->Size = sizeof( AFSWorkItem);
- pWorkItem->RequestType = AFS_WORK_ASYNCH_WRITE;
+ pWorkItem->ProcessID = (ULONGLONG)PsGetCurrentProcessId();
- pWorkItem->Specific.AsynchIo.Device = DeviceObject;
+ pWorkItem->RequestType = AFS_WORK_START_IOS;
- pWorkItem->Specific.AsynchIo.Irp = Irp;
+ pWorkItem->Specific.CacheAccess.CacheFileObject = CacheFileObject;
+
+ pWorkItem->Specific.CacheAccess.FunctionCode = FunctionCode;
- pWorkItem->Specific.AsynchIo.CallingProcess = CallerProcess;
+ pWorkItem->Specific.CacheAccess.RequestFlags = RequestFlags;
+
+ pWorkItem->Specific.CacheAccess.IoRuns = IoRuns;
+
+ pWorkItem->Specific.CacheAccess.RunCount = RunCount;
+
+ pWorkItem->Specific.CacheAccess.GatherIo = GatherIo;
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncWrite Workitem %08lX for Irp %08lX\n",
- pWorkItem,
- Irp);
+ "AFSQueueStartIos Queuing IO Workitem %p\n",
+ pWorkItem));
- ntStatus = AFSQueueWorkerRequest( pWorkItem);
+ ntStatus = AFSQueueIOWorkerRequest( pWorkItem);
try_exit:
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncWrite Request for Irp %08lX complete Status %08lX\n",
- Irp,
- ntStatus);
+ "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,
- "AFSQueueAsyncWrite Failed to queue request Status %08lX\n", ntStatus);
}
}
__except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
- AFSDbgLogMsg( 0,
+ AFSDbgTrace(( 0,
0,
- "EXCEPTION - AFSQueueAsyncWrite\n");
+ "EXCEPTION - AFSQueueStartIos\n"));
AFSDumpTraceFilesFnc();
}
}
NTSTATUS
-AFSQueueGlobalRootEnumeration()
+AFSQueueInvalidateObject( IN AFSObjectInfoCB *ObjectInfo,
+ IN ULONG InvalidateReason)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
__try
{
- pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
- sizeof(AFSWorkItem),
- AFS_WORK_ITEM_TAG);
+ pWorkItem = (AFSWorkItem *) AFSExAllocatePoolWithTag( NonPagedPool,
+ sizeof(AFSWorkItem),
+ AFS_WORK_ITEM_TAG);
if (NULL == pWorkItem)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueGlobalRootEnumeration Failed to allocate work item\n");
+ "AFSQueueInvalidateObject Failed to allocate work item\n"));
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
}
pWorkItem->Size = sizeof( AFSWorkItem);
- pWorkItem->RequestType = AFS_WORK_ENUMERATE_GLOBAL_ROOT;
+ pWorkItem->RequestType = AFS_WORK_INVALIDATE_OBJECT;
+
+ pWorkItem->Specific.Invalidate.ObjectInfo = ObjectInfo;
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ pWorkItem->Specific.Invalidate.InvalidateReason = InvalidateReason;
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueGlobalRootEnumeration Workitem %08lX\n",
- pWorkItem);
+ "AFSQueueInvalidateObject Workitem %p\n",
+ pWorkItem));
ntStatus = AFSQueueWorkerRequest( pWorkItem);
try_exit:
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueGlobalRootEnumeration Request complete Status %08lX\n",
- ntStatus);
+ "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,
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueGlobalRootEnumeration Failed to queue request Status %08lX\n",
- ntStatus);
+ "AFSQueueInvalidateObject Failed to queue request Status %08lX\n",
+ ntStatus));
}
}
__except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
- AFSDbgLogMsg( 0,
+ AFSDbgTrace(( 0,
0,
- "EXCEPTION - AFSQueueGlobalRootEnumeration\n");
+ "EXCEPTION - AFSQueueInvalidateObject\n"));
AFSDumpTraceFilesFnc();
}
}
NTSTATUS
-AFSQueueStartIos( IN PFILE_OBJECT CacheFileObject,
- IN UCHAR FunctionCode,
- IN ULONG RequestFlags,
- IN AFSIoRun *IoRuns,
- IN ULONG RunCount,
- IN AFSGatherIo *GatherIo)
+AFSDeferWrite( IN PDEVICE_OBJECT DeviceObject,
+ IN PFILE_OBJECT FileObject,
+ IN HANDLE CallingUser,
+ IN PIRP Irp,
+ IN ULONG BytesToWrite,
+ IN BOOLEAN bRetrying)
{
-
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
AFSWorkItem *pWorkItem = NULL;
__try
{
- if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
+ //
+ // Pin the user buffer (first time round only - AFSLockSystemBuffer is
+ // idempotent)
+ //
+
+ if ( NULL == AFSLockSystemBuffer( Irp, BytesToWrite ))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueStartIos Failing request, in shutdown\n");
+ "%s Could not pin user memory item\n",
+ __FUNCTION__));
- try_return( ntStatus = STATUS_TOO_LATE);
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
}
- //
- // Allocate our request structure and send it to the worker
- //
-
- pWorkItem = (AFSWorkItem *)AFSLibExAllocatePoolWithTag( NonPagedPool,
- sizeof( AFSWorkItem),
- AFS_WORK_ITEM_TAG);
+ pWorkItem = (AFSWorkItem *) AFSExAllocatePoolWithTag( NonPagedPool,
+ sizeof(AFSWorkItem),
+ AFS_WORK_ITEM_TAG);
- if( pWorkItem == NULL)
+ if (NULL == pWorkItem)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSQueueStartIos Failed to allocate work item\n");
+ "%s Failed to allocate work item\n",
+ __FUNCTION__));
- 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_START_IOS;
-
- 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->RequestType = AFS_WORK_DEFERRED_WRITE;
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueStartIos Queuing IO Workitem %08lX\n",
- pWorkItem);
+ pWorkItem->Specific.AsynchIo.CallingProcess = CallingUser;
- ntStatus = AFSQueueIOWorkerRequest( pWorkItem);
+ pWorkItem->Specific.AsynchIo.Device = DeviceObject;
-try_exit:
+ pWorkItem->Specific.AsynchIo.Irp = Irp;
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING | AFS_SUBSYSTEM_WORKER_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueStartIos Request complete Status %08lX\n",
- ntStatus);
+ "%s Workitem %p\n",
+ __FUNCTION__,
+ pWorkItem));
- if( !NT_SUCCESS( ntStatus))
- {
+ CcDeferWrite( FileObject, AFSPostedDeferredWrite, pWorkItem, NULL, BytesToWrite, bRetrying);
- if( pWorkItem != NULL)
- {
+ IoMarkIrpPending(Irp);
- ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
- }
- }
+ ntStatus = STATUS_PENDING;
}
__except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
- AFSDbgLogMsg( 0,
+ AFSDbgTrace(( 0,
0,
- "EXCEPTION - AFSQueueStartIos\n");
+ "EXCEPTION - %s \n",
+ __FUNCTION__));
- AFSDumpTraceFilesFnc();
+ ntStatus = GetExceptionCode();
}
- return ntStatus;
-}
-
-NTSTATUS
-AFSQueueInvalidateObject( IN AFSObjectInfoCB *ObjectInfo,
- IN ULONG InvalidateReason)
-{
+try_exit:
- NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSWorkItem *pWorkItem = NULL;
+ AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "%s complete Status %08lX\n",
+ __FUNCTION__,
+ ntStatus));
- __try
+ if( !NT_SUCCESS( ntStatus))
{
- pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
- sizeof(AFSWorkItem),
- AFS_WORK_ITEM_TAG);
- if (NULL == pWorkItem)
+ if( pWorkItem != NULL)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueueInvalidateObject Failed to allocate work item\n");
-
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
+ ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
}
- RtlZeroMemory( pWorkItem,
- sizeof(AFSWorkItem));
-
- pWorkItem->Size = sizeof( AFSWorkItem);
-
- pWorkItem->RequestType = AFS_WORK_INVALIDATE_OBJECT;
-
- pWorkItem->Specific.Invalidate.ObjectInfo = ObjectInfo;
-
- pWorkItem->Specific.Invalidate.InvalidateReason = InvalidateReason;
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueInvalidateObject Workitem %08lX\n",
- pWorkItem);
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "%s Failed to queue request Status %08lX\n",
+ __FUNCTION__,
+ ntStatus));
+ }
- ntStatus = AFSQueueWorkerRequest( pWorkItem);
+ return ntStatus;
+}
-try_exit:
+static
+VOID
+AFSPostedDeferredWrite( IN PVOID Context1,
+ IN PVOID Context2)
+{
+ UNREFERENCED_PARAMETER( Context2);
+ NTSTATUS ntStatus;
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueInvalidateObject Request complete Status %08lX\n",
- ntStatus);
+ AFSWorkItem *pWorkItem = (AFSWorkItem *) Context1;
- if( !NT_SUCCESS( ntStatus))
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING | AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "%s Workitem %p\n",
+ __FUNCTION__,
+ pWorkItem));
- if( pWorkItem != NULL)
- {
- ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
- }
+ ntStatus = AFSQueueIOWorkerRequest( pWorkItem);
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueueInvalidateObject Failed to queue request Status %08lX\n",
- ntStatus);
- }
- }
- __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+ if (!NT_SUCCESS( ntStatus))
{
- AFSDbgLogMsg( 0,
- 0,
- "EXCEPTION - AFSQueueInvalidateObject\n");
+ AFSCompleteRequest( pWorkItem->Specific.AsynchIo.Irp, ntStatus);
- AFSDumpTraceFilesFnc();
- }
+ ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
- return ntStatus;
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING | AFS_SUBSYSTEM_WORKER_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "%s (%p) Failed to queue request Status %08lX\n",
+ __FUNCTION__,
+ pWorkItem->Specific.AsynchIo.Irp,
+ ntStatus));
+ }
}