2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSWorker.cpp
39 #include "AFSCommon.h"
43 AFSPostedDeferredWrite( IN PVOID Context1,
47 // Function: AFSInitializeWorkerPool
51 // This function initializes the worker thread pool
55 // A status is returned for the function
59 AFSInitializeWorkerPool()
62 NTSTATUS ntStatus = STATUS_SUCCESS;
63 AFSWorkQueueContext *pCurrentWorker = NULL, *pLastWorker = NULL;
64 AFSDeviceExt *pDevExt = NULL;
69 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
72 // Initialize the worker threads.
75 pDevExt->Specific.Library.WorkerCount = 0;
77 KeInitializeEvent( &pDevExt->Specific.Library.WorkerQueueHasItems,
82 // Initialize the queue resource
85 ExInitializeResourceLite( &pDevExt->Specific.Library.QueueLock);
87 while( pDevExt->Specific.Library.WorkerCount < AFS_WORKER_COUNT)
90 pCurrentWorker = (AFSWorkQueueContext *)AFSLibExAllocatePoolWithTag( NonPagedPool,
91 sizeof( AFSWorkQueueContext),
94 if( pCurrentWorker == NULL)
97 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
98 AFS_TRACE_LEVEL_ERROR,
99 "AFSInitializeWorkerPool Failed to allocate worker context\n");
101 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
106 RtlZeroMemory( pCurrentWorker,
107 sizeof( AFSWorkQueueContext));
109 ntStatus = AFSInitWorkerThread( pCurrentWorker,
110 (PKSTART_ROUTINE)AFSWorkerThread);
112 if( !NT_SUCCESS( ntStatus))
115 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
116 AFS_TRACE_LEVEL_ERROR,
117 "AFSInitializeWorkerPool Failed to initialize worker thread Status %08lX\n", ntStatus);
119 ExFreePool( pCurrentWorker);
124 if( pDevExt->Specific.Library.PoolHead == NULL)
127 pDevExt->Specific.Library.PoolHead = pCurrentWorker;
132 pLastWorker->fLink = pCurrentWorker;
135 pLastWorker = pCurrentWorker;
137 pDevExt->Specific.Library.WorkerCount++;
141 // If there was a failure but there is at least one worker, then go with it.
144 if( !NT_SUCCESS( ntStatus) &&
145 pDevExt->Specific.Library.WorkerCount == 0)
148 try_return( ntStatus);
151 ntStatus = STATUS_SUCCESS;
154 // Now our IO Worker queue
157 pDevExt->Specific.Library.IOWorkerCount = 0;
159 KeInitializeEvent( &pDevExt->Specific.Library.IOWorkerQueueHasItems,
160 SynchronizationEvent,
164 // Initialize the queue resource
167 ExInitializeResourceLite( &pDevExt->Specific.Library.IOQueueLock);
169 while( pDevExt->Specific.Library.IOWorkerCount < AFS_IO_WORKER_COUNT)
172 pCurrentWorker = (AFSWorkQueueContext *)AFSLibExAllocatePoolWithTag( NonPagedPool,
173 sizeof( AFSWorkQueueContext),
176 if( pCurrentWorker == NULL)
179 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
180 AFS_TRACE_LEVEL_ERROR,
181 "AFSInitializeWorkerPool Failed to allocate IO worker context\n");
183 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
188 RtlZeroMemory( pCurrentWorker,
189 sizeof( AFSWorkQueueContext));
191 ntStatus = AFSInitWorkerThread( pCurrentWorker,
192 (PKSTART_ROUTINE)AFSIOWorkerThread);
194 if( !NT_SUCCESS( ntStatus))
197 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
198 AFS_TRACE_LEVEL_ERROR,
199 "AFSInitializeWorkerPool Failed to initialize IO worker thread Status %08lX\n", ntStatus);
201 ExFreePool( pCurrentWorker);
206 if( pDevExt->Specific.Library.IOPoolHead == NULL)
209 pDevExt->Specific.Library.IOPoolHead = pCurrentWorker;
214 pLastWorker->fLink = pCurrentWorker;
217 pLastWorker = pCurrentWorker;
219 pDevExt->Specific.Library.IOWorkerCount++;
223 // If there was a failure but there is at least one worker, then go with it.
226 if( !NT_SUCCESS( ntStatus) &&
227 pDevExt->Specific.Library.IOWorkerCount == 0)
230 try_return( ntStatus);
235 if( !NT_SUCCESS( ntStatus))
239 // Failed to initialize the pool so tear it down
242 AFSRemoveWorkerPool();
250 // Function: AFSRemoveWorkerPool
254 // This function tears down the worker thread pool
258 // A status is returned for the function
262 AFSRemoveWorkerPool()
265 NTSTATUS ntStatus = STATUS_SUCCESS;
267 AFSWorkQueueContext *pCurrentWorker = NULL, *pNextWorker = NULL;
268 AFSDeviceExt *pDevExt = NULL;
270 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
273 // Loop through the workers shutting them down in two stages.
274 // First, clear AFS_WORKER_PROCESS_REQUESTS so that workers
275 // stop processing requests. Second, call AFSShutdownWorkerThread()
276 // to wake the workers and wait for them to exit.
279 pCurrentWorker = pDevExt->Specific.Library.PoolHead;
281 while( index < pDevExt->Specific.Library.WorkerCount)
284 ClearFlag( pCurrentWorker->State, AFS_WORKER_PROCESS_REQUESTS);
286 pCurrentWorker = pCurrentWorker->fLink;
288 if ( pCurrentWorker == NULL)
297 pCurrentWorker = pDevExt->Specific.Library.PoolHead;
301 while( index < pDevExt->Specific.Library.WorkerCount)
304 ntStatus = AFSShutdownWorkerThread( pCurrentWorker);
306 pNextWorker = pCurrentWorker->fLink;
308 ExFreePool( pCurrentWorker);
310 pCurrentWorker = pNextWorker;
312 if( pCurrentWorker == NULL)
321 pDevExt->Specific.Library.PoolHead = NULL;
323 ExDeleteResourceLite( &pDevExt->Specific.Library.QueueLock);
326 // Loop through the IO workers shutting them down in two stages.
327 // First, clear AFS_WORKER_PROCESS_REQUESTS so that workers
328 // stop processing requests. Second, call AFSShutdownIOWorkerThread()
329 // to wake the workers and wait for them to exit.
332 pCurrentWorker = pDevExt->Specific.Library.IOPoolHead;
336 while( index < pDevExt->Specific.Library.IOWorkerCount)
339 ClearFlag( pCurrentWorker->State, AFS_WORKER_PROCESS_REQUESTS);
341 pCurrentWorker = pCurrentWorker->fLink;
343 if ( pCurrentWorker == NULL)
352 pCurrentWorker = pDevExt->Specific.Library.IOPoolHead;
356 while( index < pDevExt->Specific.Library.IOWorkerCount)
359 ntStatus = AFSShutdownIOWorkerThread( pCurrentWorker);
361 pNextWorker = pCurrentWorker->fLink;
363 ExFreePool( pCurrentWorker);
365 pCurrentWorker = pNextWorker;
367 if( pCurrentWorker == NULL)
376 pDevExt->Specific.Library.IOPoolHead = NULL;
378 ExDeleteResourceLite( &pDevExt->Specific.Library.IOQueueLock);
384 AFSInitVolumeWorker( IN AFSVolumeCB *VolumeCB)
387 NTSTATUS ntStatus = STATUS_SUCCESS;
388 AFSWorkQueueContext *pWorker = &VolumeCB->NonPagedVcb->VolumeWorkerContext;
390 AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
391 PKSTART_ROUTINE pStartRoutine = NULL;
397 if ( VolumeCB != AFSGlobalRoot)
400 return STATUS_INVALID_PARAMETER;
403 pStartRoutine = AFSPrimaryVolumeWorkerThread;
406 // Initialize the worker thread
409 KeInitializeEvent( &pWorker->WorkerThreadReady,
414 // Set the worker to process requests
417 pWorker->State = AFS_WORKER_PROCESS_REQUESTS;
423 ntStatus = PsCreateSystemThread( &hThread,
431 if( NT_SUCCESS( ntStatus))
434 ObReferenceObjectByHandle( hThread,
435 GENERIC_READ | GENERIC_WRITE,
438 (PVOID *)&pWorker->WorkerThreadObject,
441 ntStatus = KeWaitForSingleObject( &pWorker->WorkerThreadReady,
447 lCount = InterlockedIncrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount);
452 KeClearEvent( &pControlDeviceExt->Specific.Control.VolumeWorkerCloseEvent);
463 // Function: AFSInitWorkerThread
467 // This function initializes a worker thread in the pool
471 // A status is returned for the function
475 AFSInitWorkerThread( IN AFSWorkQueueContext *PoolContext,
476 IN PKSTART_ROUTINE WorkerRoutine)
479 NTSTATUS ntStatus = STATUS_SUCCESS;
483 // INitialize the worker signal thread
486 KeInitializeEvent( &PoolContext->WorkerThreadReady,
491 // Set the worker to process requests
494 PoolContext->State = AFS_WORKER_PROCESS_REQUESTS;
500 ntStatus = PsCreateSystemThread( &Handle,
506 (void *)PoolContext);
508 if( NT_SUCCESS( ntStatus))
511 ObReferenceObjectByHandle( Handle,
512 GENERIC_READ | GENERIC_WRITE,
515 (PVOID *)&PoolContext->WorkerThreadObject,
518 ntStatus = KeWaitForSingleObject( &PoolContext->WorkerThreadReady,
531 AFSShutdownVolumeWorker( IN AFSVolumeCB *VolumeCB)
534 NTSTATUS ntStatus = STATUS_SUCCESS;
535 AFSWorkQueueContext *pWorker = &VolumeCB->NonPagedVcb->VolumeWorkerContext;
538 // Clear the 'keep processing' flag
541 ClearFlag( pWorker->State, AFS_WORKER_PROCESS_REQUESTS);
543 if( pWorker->WorkerThreadObject != NULL)
545 while ( BooleanFlagOn( pWorker->State, AFS_WORKER_INITIALIZED) )
548 ntStatus = KeWaitForSingleObject( pWorker->WorkerThreadObject,
555 ObDereferenceObject( pWorker->WorkerThreadObject);
557 pWorker->WorkerThreadObject = NULL;
564 // Function: AFSShutdownWorkerThread
568 // This function shutsdown a worker thread in the pool
572 // A status is returned for the function
576 AFSShutdownWorkerThread( IN AFSWorkQueueContext *PoolContext)
579 NTSTATUS ntStatus = STATUS_SUCCESS;
580 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
582 if( PoolContext->WorkerThreadObject != NULL)
585 while ( BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED) )
589 // Wake up the thread if it is a sleep
592 KeSetEvent( &pDeviceExt->Specific.Library.WorkerQueueHasItems,
596 ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
603 ObDereferenceObject( PoolContext->WorkerThreadObject);
605 PoolContext->WorkerThreadObject = NULL;
612 // Function: AFSShutdownIOWorkerThread
616 // This function shutsdown an IO worker thread in the pool
620 // A status is returned for the function
624 AFSShutdownIOWorkerThread( IN AFSWorkQueueContext *PoolContext)
627 NTSTATUS ntStatus = STATUS_SUCCESS;
628 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
630 if( PoolContext->WorkerThreadObject != NULL)
633 while ( BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED) )
637 // Wake up the thread if it is a sleep
640 KeSetEvent( &pDeviceExt->Specific.Library.IOWorkerQueueHasItems,
644 ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
651 ObDereferenceObject( PoolContext->WorkerThreadObject);
653 PoolContext->WorkerThreadObject = NULL;
660 // Function: AFSWorkerThread
664 // This is the worker thread entry point.
668 // A status is returned for the function
672 AFSWorkerThread( IN PVOID Context)
675 NTSTATUS ntStatus = STATUS_SUCCESS;
676 AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
677 AFSWorkItem *pWorkItem;
678 BOOLEAN freeWorkItem = TRUE;
679 AFSDeviceExt *pLibraryDevExt = NULL;
682 pLibraryDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
685 // Indicate that we are initialized and ready
688 KeSetEvent( &pPoolContext->WorkerThreadReady,
693 // Indicate we are initialized
696 SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
698 ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
704 while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
707 if( !NT_SUCCESS( ntStatus))
710 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
711 AFS_TRACE_LEVEL_ERROR,
712 "AFSWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
714 ntStatus = STATUS_SUCCESS;
719 pWorkItem = AFSRemoveWorkItem();
721 if( pWorkItem == NULL)
724 ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
736 // Switch on the type of work item to process
739 switch( pWorkItem->RequestType)
742 case AFS_WORK_FLUSH_FCB:
745 ntStatus = AFSFlushExtents( pWorkItem->Specific.Fcb.Fcb,
746 &pWorkItem->AuthGroup);
748 if( !NT_SUCCESS( ntStatus))
751 AFSReleaseExtentsWithFlush( pWorkItem->Specific.Fcb.Fcb,
752 &pWorkItem->AuthGroup,
756 ASSERT( pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount != 0);
758 lCount = InterlockedDecrement( &pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount);
763 case AFS_WORK_ENUMERATE_GLOBAL_ROOT:
766 AFSEnumerateGlobalRoot( NULL);
771 case AFS_WORK_INVALIDATE_OBJECT:
774 AFSPerformObjectInvalidate( pWorkItem->Specific.Invalidate.ObjectInfo,
775 pWorkItem->Specific.Invalidate.InvalidateReason);
782 case AFS_WORK_START_IOS:
792 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
793 AFS_TRACE_LEVEL_ERROR,
794 "AFSWorkerThread Unknown request type %d\n", pWorkItem->RequestType);
802 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
805 ntStatus = STATUS_SUCCESS;
808 } // worker thread loop
810 ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
812 // Wake up another worker so they too can exit
814 KeSetEvent( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
818 PsTerminateSystemThread( 0);
824 AFSIOWorkerThread( IN PVOID Context)
827 NTSTATUS ntStatus = STATUS_SUCCESS;
828 AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
829 AFSWorkItem *pWorkItem;
830 BOOLEAN freeWorkItem = TRUE;
831 AFSDeviceExt *pLibraryDevExt = NULL, *pRdrDevExt = NULL;
833 pLibraryDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
836 // Indicate that we are initialized and ready
839 KeSetEvent( &pPoolContext->WorkerThreadReady,
845 // Indicate we are initialized
848 SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
850 ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
856 while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
859 if( !NT_SUCCESS( ntStatus))
862 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
863 AFS_TRACE_LEVEL_ERROR,
864 "AFSIOWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
866 ntStatus = STATUS_SUCCESS;
871 pWorkItem = AFSRemoveIOWorkItem();
873 if( pWorkItem == NULL)
876 ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
888 // Switch on the type of work item to process
891 switch( pWorkItem->RequestType)
894 case AFS_WORK_START_IOS:
897 pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
900 // The final status is in the gather io
903 ntStatus = AFSStartIos( pWorkItem->Specific.CacheAccess.CacheFileObject,
904 pWorkItem->Specific.CacheAccess.FunctionCode,
905 pWorkItem->Specific.CacheAccess.RequestFlags,
906 pWorkItem->Specific.CacheAccess.IoRuns,
907 pWorkItem->Specific.CacheAccess.RunCount,
908 pWorkItem->Specific.CacheAccess.GatherIo);
911 // Regardless of the status we we do the complete - there may
913 // Decrement the count - setting the event if we were told
914 // to. This may trigger completion.
917 AFSCompleteIo( pWorkItem->Specific.CacheAccess.GatherIo, ntStatus );
924 case AFS_WORK_DEFERRED_WRITE:
927 ntStatus = AFSCommonWrite( pWorkItem->Specific.AsynchIo.Device,
928 pWorkItem->Specific.AsynchIo.Irp,
929 pWorkItem->Specific.AsynchIo.CallingProcess,
939 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
940 AFS_TRACE_LEVEL_ERROR,
941 "AFSIOWorkerThread Unknown request type %d\n", pWorkItem->RequestType);
949 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
952 ntStatus = STATUS_SUCCESS;
955 } // worker thread loop
957 ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
959 // Wake up another IOWorker so they too can exit
961 KeSetEvent( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
965 PsTerminateSystemThread( 0);
971 AFSExamineDirectory( IN AFSObjectInfoCB * pCurrentObject,
972 IN AFSDirectoryCB * pCurrentDirEntry)
976 AFSObjectInfoCB *pCurrentChildObject = NULL;
977 AFSVolumeCB * pVolumeCB = pCurrentObject->VolumeCB;
978 BOOLEAN bFcbBusy = FALSE;
981 pCurrentChildObject = pCurrentDirEntry->ObjectInformation;
983 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
984 AFS_TRACE_LEVEL_VERBOSE,
985 "AFSExamineDirectory Deleting DE %wZ Object %p\n",
986 &pCurrentDirEntry->NameInformation.FileName,
987 pCurrentChildObject);
989 AFSDeleteDirEntry( pCurrentObject,
993 // Acquire ObjectInfoLock shared here so as not to deadlock
994 // with an invalidation call from the service during AFSCleanupFcb
997 lCount = AFSObjectInfoIncrement( pCurrentChildObject,
998 AFS_OBJECT_REFERENCE_WORKER);
1000 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1001 AFS_TRACE_LEVEL_VERBOSE,
1002 "AFSExamineDirectory Increment count on object %p Cnt %d\n",
1003 pCurrentChildObject,
1007 pCurrentChildObject->Fcb != NULL &&
1008 pCurrentChildObject->FileType == AFS_FILE_TYPE_FILE)
1012 // We must not hold pVolumeCB->ObjectInfoTree.TreeLock exclusive
1013 // across an AFSCleanupFcb call since it can deadlock with an
1014 // invalidation call from the service.
1017 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1020 // Cannot hold a TreeLock across an AFSCleanupFcb call
1021 // as it can deadlock with an invalidation ioctl initiated
1022 // from the service.
1024 // Dropping the TreeLock permits the
1025 // pCurrentObject->ObjectReferenceCount to change
1028 ntStatus = AFSCleanupFcb( pCurrentChildObject->Fcb,
1031 if ( ntStatus == STATUS_RETRY)
1037 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1041 AFSAcquireExcl( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock,
1044 lCount = AFSObjectInfoDecrement( pCurrentChildObject,
1045 AFS_OBJECT_REFERENCE_WORKER);
1047 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1048 AFS_TRACE_LEVEL_VERBOSE,
1049 "AFSExamineDirectory Decrement1 count on object %p Cnt %d\n",
1050 pCurrentChildObject,
1054 pCurrentChildObject->Fcb != NULL &&
1055 pCurrentChildObject->Fcb->OpenReferenceCount == 0)
1058 AFSRemoveFcb( &pCurrentChildObject->Fcb);
1060 if( pCurrentChildObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1061 pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
1064 AFSAcquireExcl( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
1067 AFSRemoveFcb( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
1069 AFSReleaseResource( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
1071 AFSDeleteObjectInfo( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
1073 ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
1075 AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
1077 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1078 AFS_TRACE_LEVEL_VERBOSE,
1079 "AFSExamineDirectory (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n",
1080 pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB);
1082 AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
1085 AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
1087 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1088 AFS_TRACE_LEVEL_VERBOSE,
1089 "AFSExamineDirectory Deleting object %p\n",
1090 pCurrentChildObject);
1092 AFSDeleteObjectInfo( &pCurrentChildObject);
1097 AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
1104 // Called with VolumeCB->ObjectInfoTree.TreeLock held shared.
1105 // The TreeLock will be released unless *pbReleaseVolumeLock is set to FALSE.
1109 AFSExamineObjectInfo( IN AFSObjectInfoCB * pCurrentObject,
1110 IN BOOLEAN bVolumeObject,
1111 IN OUT BOOLEAN * pbReleaseVolumeLock)
1113 NTSTATUS ntStatus = STATUS_SUCCESS;
1114 AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
1115 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1116 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
1117 AFSObjectInfoCB *pCurrentChildObject = NULL;
1118 AFSVolumeCB * pVolumeCB = pCurrentObject->VolumeCB;
1119 LARGE_INTEGER liCurrentTime;
1120 BOOLEAN bFcbBusy = FALSE;
1124 switch ( pCurrentObject->FileType) {
1126 case AFS_FILE_TYPE_DIRECTORY:
1129 if ( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
1136 // If this object is deleted then remove it from the parent, if we can
1139 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1140 pCurrentObject->ObjectReferenceCount <= 0 &&
1141 ( pCurrentObject->Fcb == NULL ||
1142 pCurrentObject->Fcb->OpenReferenceCount == 0) &&
1143 pCurrentObject->Specific.Directory.DirectoryNodeListHead == NULL &&
1144 pCurrentObject->Specific.Directory.ChildOpenReferenceCount == 0)
1147 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1150 // Dropping the TreeLock permits the
1151 // pCurrentObject->ObjectReferenceCount to change
1154 if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1158 AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1161 if ( pCurrentObject->ObjectReferenceCount <= 0)
1164 AFSRemoveFcb( &pCurrentObject->Fcb);
1166 if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
1169 AFSAcquireExcl( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
1172 AFSRemoveFcb( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
1174 AFSReleaseResource( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
1176 AFSDeleteObjectInfo( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
1178 ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
1180 AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
1182 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1183 AFS_TRACE_LEVEL_VERBOSE,
1184 "AFSExamineObjectInfo (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n",
1185 pCurrentObject->Specific.Directory.PIOCtlDirectoryCB);
1187 AFSExFreePoolWithTag( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
1190 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1192 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1193 AFS_TRACE_LEVEL_VERBOSE,
1194 "AFSExamineObjectInfo Deleting deleted object %p\n",
1197 AFSDeleteObjectInfo( &pCurrentObject);
1202 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1205 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1210 *pbReleaseVolumeLock = FALSE;
1216 if ( pCurrentObject->Fcb != NULL &&
1217 pCurrentObject->Fcb->CcbListHead != NULL)
1222 for ( pCcb = pCurrentObject->Fcb->CcbListHead;
1224 pCcb = (AFSCcb *)pCcb->ListEntry.fLink)
1227 if ( pCcb->NameArray) {
1229 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1230 AFS_TRACE_LEVEL_VERBOSE,
1231 "AFSExamineObjectInfo Found Object %p Fcb %p Ccb %p\n",
1233 pCurrentObject->Fcb,
1241 if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0 ||
1242 ( pCurrentObject->Fcb != NULL &&
1243 pCurrentObject->Fcb->OpenReferenceCount > 0))
1249 if ( pCurrentObject->FileType != AFS_FILE_TYPE_DIRECTORY ||
1250 pCurrentObject->Specific.Directory.DirectoryNodeListHead != NULL)
1253 if( !AFSAcquireShared( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1260 pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
1263 // Directory Entry Processing
1266 KeQueryTickCount( &liCurrentTime);
1268 while( pCurrentDirEntry != NULL)
1271 if( pCurrentDirEntry->DirOpenReferenceCount > 0)
1277 if ( pCurrentDirEntry->NameArrayReferenceCount > 0)
1283 if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
1284 pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0)
1290 if ( liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart ||
1291 liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart <
1292 pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart)
1298 if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
1301 if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
1307 if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)
1314 if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE)
1317 if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
1318 pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0)
1325 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
1328 if( pCurrentDirEntry != NULL)
1331 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1336 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1338 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1341 // Now acquire the locks excl without deadlocking
1344 if( AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1348 if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1352 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1354 *pbReleaseVolumeLock = FALSE;
1359 if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0)
1362 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1364 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1369 KeQueryTickCount( &liCurrentTime);
1371 pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
1373 while( pCurrentDirEntry != NULL)
1376 if( pCurrentDirEntry->DirOpenReferenceCount > 0)
1382 if ( pCurrentDirEntry->NameArrayReferenceCount > 0)
1388 if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
1389 pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0)
1395 if ( liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart ||
1396 liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart <
1397 pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart)
1403 if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
1406 if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
1412 if ( pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)
1419 if ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE)
1422 if ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
1423 pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0)
1430 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
1433 if( pCurrentDirEntry != NULL)
1436 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1438 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1443 pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
1445 while( pCurrentDirEntry != NULL)
1448 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
1450 AFSExamineDirectory( pCurrentObject,
1453 pCurrentDirEntry = pNextDirEntry;
1457 // Clear our enumerated flag on this object so we retrieve info again on next access
1460 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1462 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1464 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1470 // Try to grab the volume lock again ... no problem if we don't
1473 if( !AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1477 *pbReleaseVolumeLock = FALSE;
1483 else if ( bVolumeObject == FALSE)
1489 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1491 if ( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1495 *pbReleaseVolumeLock = FALSE;
1500 AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1503 KeQueryTickCount( &liCurrentTime);
1505 if( pCurrentObject->ObjectReferenceCount <= 0 &&
1506 ( pCurrentObject->Fcb == NULL ||
1507 pCurrentObject->Fcb->OpenReferenceCount <= 0) &&
1508 liCurrentTime.QuadPart > pCurrentObject->LastAccessCount.QuadPart &&
1509 liCurrentTime.QuadPart - pCurrentObject->LastAccessCount.QuadPart >
1510 pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart)
1513 AFSRemoveFcb( &pCurrentObject->Fcb);
1515 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1517 AFSDeleteObjectInfo( &pCurrentObject);
1522 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1525 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1530 case AFS_FILE_TYPE_FILE:
1533 lCount = AFSObjectInfoIncrement( pCurrentObject,
1534 AFS_OBJECT_REFERENCE_WORKER);
1536 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1537 AFS_TRACE_LEVEL_VERBOSE,
1538 "AFSExamineObjectInfo Increment3 count on object %p Cnt %d\n",
1542 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1544 if( pCurrentObject->Fcb != NULL)
1548 // Dropping the TreeLock permits the
1549 // pCurrentObject->ObjectReferenceCount to change
1552 ntStatus = AFSCleanupFcb( pCurrentObject->Fcb,
1555 if ( ntStatus == STATUS_RETRY)
1562 bTemp = AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1565 lCount = AFSObjectInfoDecrement( pCurrentObject,
1566 AFS_OBJECT_REFERENCE_WORKER);
1568 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1569 AFS_TRACE_LEVEL_VERBOSE,
1570 "AFSExamineObjectInfo Decrement3 count on object %p Cnt %d\n",
1575 if ( bTemp == FALSE)
1578 *pbReleaseVolumeLock = FALSE;
1583 AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1586 KeQueryTickCount( &liCurrentTime);
1588 if( pCurrentObject->ObjectReferenceCount <= 0 &&
1589 ( pCurrentObject->Fcb == NULL ||
1590 ( pCurrentObject->Fcb->OpenReferenceCount <= 0 &&
1591 pCurrentObject->Fcb->Specific.File.ExtentsDirtyCount <= 0)) &&
1592 liCurrentTime.QuadPart > pCurrentObject->LastAccessCount.QuadPart &&
1593 liCurrentTime.QuadPart - pCurrentObject->LastAccessCount.QuadPart >
1594 pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart)
1597 AFSRemoveFcb( &pCurrentObject->Fcb);
1599 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1601 AFSDeleteObjectInfo( &pCurrentObject);
1606 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1609 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1616 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1618 if ( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1622 *pbReleaseVolumeLock = FALSE;
1627 AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1630 KeQueryTickCount( &liCurrentTime);
1632 if( pCurrentObject->ObjectReferenceCount <= 0 &&
1633 ( pCurrentObject->Fcb == NULL ||
1634 pCurrentObject->Fcb->OpenReferenceCount <= 0) &&
1635 liCurrentTime.QuadPart > pCurrentObject->LastAccessCount.QuadPart &&
1636 liCurrentTime.QuadPart - pCurrentObject->LastAccessCount.QuadPart >
1637 pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart)
1640 AFSRemoveFcb( &pCurrentObject->Fcb);
1642 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1644 AFSDeleteObjectInfo( &pCurrentObject);
1649 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1652 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1661 AFSExamineVolume( IN AFSVolumeCB *pVolumeCB)
1663 NTSTATUS ntStatus = STATUS_SUCCESS;
1664 AFSObjectInfoCB *pCurrentObject = NULL, *pNextObject = NULL;
1665 BOOLEAN bReleaseVolumeLock = FALSE;
1666 BOOLEAN bVolumeObject = FALSE;
1667 BOOLEAN bFcbBusy = FALSE;
1670 if( AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1674 bReleaseVolumeLock = TRUE;
1676 pCurrentObject = pVolumeCB->ObjectInfoListHead;
1680 while( pCurrentObject != NULL)
1683 if( pCurrentObject != &pVolumeCB->ObjectInformation)
1686 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
1689 // If the end of the VolumeCB ObjectInfo List is reached, then
1690 // the next ObjectInformationCB to examine is the one embedded within
1691 // the VolumeCB itself except when the VolumeCB is the AFSGlobalRoot.
1693 // bVolumeObject is used to indicate whether the embedded ObjectInfoCB
1694 // is being examined.
1697 if( pNextObject == NULL &&
1698 pVolumeCB != AFSGlobalRoot) // Don't free up the root of the global
1701 pNextObject = &pVolumeCB->ObjectInformation;
1704 bVolumeObject = FALSE;
1709 lCount = AFSObjectInfoIncrement( pNextObject,
1710 AFS_OBJECT_REFERENCE_WORKER);
1712 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1713 AFS_TRACE_LEVEL_VERBOSE,
1714 "AFSExamineVolume Increment count on object %p Cnt %d\n",
1724 bVolumeObject = TRUE;
1727 bFcbBusy = AFSExamineObjectInfo( pCurrentObject, bVolumeObject, &bReleaseVolumeLock);
1732 lCount = AFSObjectInfoDecrement( pNextObject,
1733 AFS_OBJECT_REFERENCE_WORKER);
1735 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1736 AFS_TRACE_LEVEL_VERBOSE,
1737 "AFSExamineVolume Decrement count on object %p Cnt %d\n",
1743 // If AFSExamineObjectInfo drops the VolumeLock before returning
1744 // we must halt processing of the Volume's ObjectInfo list.
1747 if ( bReleaseVolumeLock == FALSE)
1753 pCurrentObject = pNextObject;
1756 if( bReleaseVolumeLock)
1759 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1767 AFSPrimaryVolumeWorkerThread( IN PVOID Context)
1770 UNREFERENCED_PARAMETER(Context);
1771 AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&AFSGlobalRoot->NonPagedVcb->VolumeWorkerContext;
1772 AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
1773 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1774 LARGE_INTEGER DueTime;
1777 AFSVolumeCB *pVolumeCB = NULL, *pNextVolume = NULL;
1778 BOOLEAN bFcbBusy = FALSE;
1781 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1782 AFS_TRACE_LEVEL_VERBOSE,
1783 "AFSPrimaryVolumeWorkerThread Initialized\n");
1786 // Initialize the timer for the worker thread
1789 DueTime.QuadPart = -(5000);
1793 KeInitializeTimerEx( &Timer,
1794 SynchronizationTimer);
1796 KeSetTimerEx( &Timer,
1802 // Indicate that we are initialized and ready
1805 KeSetEvent( &pPoolContext->WorkerThreadReady,
1810 // Indicate we are initialized
1813 SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
1815 while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
1818 if ( bFcbBusy == FALSE)
1821 KeWaitForSingleObject( &Timer,
1834 // This is the primary volume worker so it will traverse the volume list
1835 // looking for cleanup or volumes requiring private workers
1838 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
1841 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
1843 while( pVolumeCB != NULL)
1846 if( pVolumeCB == AFSGlobalRoot ||
1847 !AFSAcquireExcl( pVolumeCB->VolumeLock,
1851 pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
1856 if( pVolumeCB->ObjectInfoListHead == NULL)
1859 AFSReleaseResource( pVolumeCB->VolumeLock);
1861 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1863 AFSAcquireExcl( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock,
1866 AFSAcquireExcl( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
1869 if( !AFSAcquireExcl( pVolumeCB->VolumeLock,
1873 AFSConvertToShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1875 AFSReleaseResource( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock);
1877 pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
1882 pNextVolume = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
1884 AFSAcquireShared( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock,
1888 // If VolumeCB is idle, the Volume can be garbage collected
1891 if( pVolumeCB->ObjectInfoListHead == NULL &&
1892 pVolumeCB->DirectoryCB->DirOpenReferenceCount <= 0 &&
1893 pVolumeCB->DirectoryCB->NameArrayReferenceCount <= 0 &&
1894 pVolumeCB->VolumeReferenceCount == 0 &&
1895 ( pVolumeCB->RootFcb == NULL ||
1896 pVolumeCB->RootFcb->OpenReferenceCount == 0) &&
1897 pVolumeCB->ObjectInformation.ObjectReferenceCount <= 0)
1900 AFSRemoveRootFcb( pVolumeCB);
1902 AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
1904 AFSRemoveVolume( pVolumeCB);
1909 AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
1911 AFSReleaseResource( pVolumeCB->VolumeLock);
1914 AFSConvertToShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1916 AFSReleaseResource( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock);
1918 pVolumeCB = pNextVolume;
1924 // Don't need this lock anymore now that we have a volume cb to work with
1927 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1930 // For now we only need the volume lock shared
1933 AFSConvertToShared( pVolumeCB->VolumeLock);
1935 AFSExamineVolume( pVolumeCB);
1941 AFSReleaseResource( pVolumeCB->VolumeLock);
1943 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
1946 pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
1949 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1951 } // worker thread loop
1953 KeCancelTimer( &Timer);
1955 ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
1957 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1958 AFS_TRACE_LEVEL_VERBOSE,
1959 "AFSPrimaryVolumeWorkerThread Exiting\n");
1961 lCount = InterlockedDecrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount);
1966 KeSetEvent( &pControlDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
1971 PsTerminateSystemThread( 0);
1977 AFSInsertWorkitem( IN AFSWorkItem *WorkItem)
1980 NTSTATUS ntStatus = STATUS_SUCCESS;
1981 AFSDeviceExt *pDevExt = NULL;
1984 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
1986 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1987 AFS_TRACE_LEVEL_VERBOSE,
1988 "AFSInsertWorkitem Acquiring Control QueueLock lock %p EXCL %08lX\n",
1989 &pDevExt->Specific.Library.QueueLock,
1990 PsGetCurrentThread());
1992 AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
1995 lCount = InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount);
1997 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
1998 AFS_TRACE_LEVEL_VERBOSE,
1999 "AFSInsertWorkitem Inserting work item %p Count %d\n",
2003 if( pDevExt->Specific.Library.QueueTail != NULL) // queue already has nodes
2006 pDevExt->Specific.Library.QueueTail->next = WorkItem;
2011 pDevExt->Specific.Library.QueueHead = WorkItem;
2014 WorkItem->next = NULL;
2015 pDevExt->Specific.Library.QueueTail = WorkItem;
2017 // indicate that the queue has nodes
2018 KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
2022 AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
2028 AFSInsertIOWorkitem( IN AFSWorkItem *WorkItem)
2031 NTSTATUS ntStatus = STATUS_SUCCESS;
2032 AFSDeviceExt *pDevExt = NULL;
2035 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
2037 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2038 AFS_TRACE_LEVEL_VERBOSE,
2039 "AFSInsertIOWorkitem Acquiring Control QueueLock lock %p EXCL %08lX\n",
2040 &pDevExt->Specific.Library.IOQueueLock,
2041 PsGetCurrentThread());
2043 AFSAcquireExcl( &pDevExt->Specific.Library.IOQueueLock,
2046 lCount = InterlockedIncrement( &pDevExt->Specific.Library.IOQueueItemCount);
2048 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2049 AFS_TRACE_LEVEL_VERBOSE,
2050 "AFSInsertWorkitem Inserting IO work item %p Count %d\n",
2054 if( pDevExt->Specific.Library.IOQueueTail != NULL) // queue already has nodes
2057 pDevExt->Specific.Library.IOQueueTail->next = WorkItem;
2062 pDevExt->Specific.Library.IOQueueHead = WorkItem;
2065 WorkItem->next = NULL;
2066 pDevExt->Specific.Library.IOQueueTail = WorkItem;
2068 // indicate that the queue has nodes
2069 KeSetEvent( &(pDevExt->Specific.Library.IOWorkerQueueHasItems),
2073 AFSReleaseResource( &pDevExt->Specific.Library.IOQueueLock);
2079 AFSInsertWorkitemAtHead( IN AFSWorkItem *WorkItem)
2082 NTSTATUS ntStatus = STATUS_SUCCESS;
2083 AFSDeviceExt *pDevExt = NULL;
2086 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
2088 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2089 AFS_TRACE_LEVEL_VERBOSE,
2090 "AFSInsertWorkitemAtHead Acquiring Control QueueLock lock %p EXCL %08lX\n",
2091 &pDevExt->Specific.Library.QueueLock,
2092 PsGetCurrentThread());
2094 AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
2097 WorkItem->next = pDevExt->Specific.Library.QueueHead;
2099 pDevExt->Specific.Library.QueueHead = WorkItem;
2101 lCount = InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount);
2103 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2104 AFS_TRACE_LEVEL_VERBOSE,
2105 "AFSInsertWorkitemAtHead Inserting work item %p Count %d\n",
2110 // indicate that the queue has nodes
2113 KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
2117 AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
2126 AFSWorkItem *pWorkItem = NULL;
2127 AFSDeviceExt *pDevExt = NULL;
2130 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
2132 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2133 AFS_TRACE_LEVEL_VERBOSE,
2134 "AFSRemoveWorkItem Acquiring Control QueueLock lock %p EXCL %08lX\n",
2135 &pDevExt->Specific.Library.QueueLock,
2136 PsGetCurrentThread());
2138 AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
2141 if( pDevExt->Specific.Library.QueueHead != NULL) // queue has nodes
2144 pWorkItem = pDevExt->Specific.Library.QueueHead;
2146 lCount = InterlockedDecrement( &pDevExt->Specific.Library.QueueItemCount);
2148 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2149 AFS_TRACE_LEVEL_VERBOSE,
2150 "AFSRemoveWorkItem Removing work item %p Count %d Thread %08lX\n",
2153 PsGetCurrentThreadId());
2155 pDevExt->Specific.Library.QueueHead = pDevExt->Specific.Library.QueueHead->next;
2157 if( pDevExt->Specific.Library.QueueHead == NULL) // if queue just became empty
2160 pDevExt->Specific.Library.QueueTail = NULL;
2166 // Wake up another worker
2169 KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
2175 AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
2181 AFSRemoveIOWorkItem()
2184 AFSWorkItem *pWorkItem = NULL;
2185 AFSDeviceExt *pDevExt = NULL;
2188 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
2190 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2191 AFS_TRACE_LEVEL_VERBOSE,
2192 "AFSRemoveIOWorkItem Acquiring Control QueueLock lock %p EXCL %08lX\n",
2193 &pDevExt->Specific.Library.IOQueueLock,
2194 PsGetCurrentThread());
2196 AFSAcquireExcl( &pDevExt->Specific.Library.IOQueueLock,
2199 if( pDevExt->Specific.Library.IOQueueHead != NULL) // queue has nodes
2202 pWorkItem = pDevExt->Specific.Library.IOQueueHead;
2204 lCount = InterlockedDecrement( &pDevExt->Specific.Library.IOQueueItemCount);
2206 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2207 AFS_TRACE_LEVEL_VERBOSE,
2208 "AFSRemoveWorkItem Removing work item %p Count %d Thread %08lX\n",
2211 PsGetCurrentThreadId());
2213 pDevExt->Specific.Library.IOQueueHead = pDevExt->Specific.Library.IOQueueHead->next;
2215 if( pDevExt->Specific.Library.IOQueueHead == NULL) // if queue just became empty
2218 pDevExt->Specific.Library.IOQueueTail = NULL;
2224 // Wake up another worker
2227 KeSetEvent( &(pDevExt->Specific.Library.IOWorkerQueueHasItems),
2233 AFSReleaseResource( &pDevExt->Specific.Library.IOQueueLock);
2239 AFSQueueWorkerRequest( IN AFSWorkItem *WorkItem)
2242 NTSTATUS ntStatus = STATUS_SUCCESS;
2243 BOOLEAN bWait = BooleanFlagOn( WorkItem->RequestFlags, AFS_SYNCHRONOUS_REQUEST);
2246 // Submit the work item to the worker
2249 ntStatus = AFSInsertWorkitem( WorkItem);
2255 // Sync request so block on the work item event
2258 ntStatus = KeWaitForSingleObject( &WorkItem->Event,
2269 AFSQueueIOWorkerRequest( IN AFSWorkItem *WorkItem)
2272 NTSTATUS ntStatus = STATUS_SUCCESS;
2273 BOOLEAN bWait = BooleanFlagOn( WorkItem->RequestFlags, AFS_SYNCHRONOUS_REQUEST);
2276 // Submit the work item to the worker
2279 ntStatus = AFSInsertIOWorkitem( WorkItem);
2285 // Sync request so block on the work item event
2288 ntStatus = KeWaitForSingleObject( &WorkItem->Event,
2299 AFSQueueWorkerRequestAtHead( IN AFSWorkItem *WorkItem)
2302 NTSTATUS ntStatus = STATUS_SUCCESS;
2303 BOOLEAN bWait = BooleanFlagOn( WorkItem->RequestFlags, AFS_SYNCHRONOUS_REQUEST);
2306 // Submit the work item to the worker
2309 ntStatus = AFSInsertWorkitemAtHead( WorkItem);
2315 // Sync request so block on the work item event
2318 ntStatus = KeWaitForSingleObject( &WorkItem->Event,
2329 AFSQueueFlushExtents( IN AFSFcb *Fcb,
2333 NTSTATUS ntStatus = STATUS_SUCCESS;
2334 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2335 AFSWorkItem *pWorkItem = NULL;
2341 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2342 AFS_TRACE_LEVEL_VERBOSE,
2343 "AFSQueueFlushExtents Queuing request for FID %08lX-%08lX-%08lX-%08lX\n",
2344 Fcb->ObjectInformation->FileId.Cell,
2345 Fcb->ObjectInformation->FileId.Volume,
2346 Fcb->ObjectInformation->FileId.Vnode,
2347 Fcb->ObjectInformation->FileId.Unique);
2350 // Increment our flush count here just to keep the number of items in the
2351 // queue down. We'll decrement it just below.
2354 lCount = InterlockedIncrement( &Fcb->Specific.File.QueuedFlushCount);
2359 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2360 AFS_TRACE_LEVEL_VERBOSE,
2361 "AFSQueueFlushExtents Max queued items for FID %08lX-%08lX-%08lX-%08lX\n",
2362 Fcb->ObjectInformation->FileId.Cell,
2363 Fcb->ObjectInformation->FileId.Volume,
2364 Fcb->ObjectInformation->FileId.Vnode,
2365 Fcb->ObjectInformation->FileId.Unique);
2367 try_return( ntStatus);
2370 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
2373 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2374 AFS_TRACE_LEVEL_ERROR,
2375 "AFSQueueFlushExtents Failing request, in shutdown\n");
2377 try_return( ntStatus = STATUS_TOO_LATE);
2381 // Allocate our request structure and send it to the worker
2384 pWorkItem = (AFSWorkItem *)AFSLibExAllocatePoolWithTag( NonPagedPool,
2385 sizeof( AFSWorkItem),
2388 if( pWorkItem == NULL)
2391 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2392 AFS_TRACE_LEVEL_ERROR,
2393 "AFSQueueFlushExtents Failed to allocate work item\n");
2395 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2398 RtlZeroMemory( pWorkItem,
2399 sizeof( AFSWorkItem));
2401 pWorkItem->Size = sizeof( AFSWorkItem);
2403 pWorkItem->ProcessID = (ULONGLONG)PsGetCurrentProcessId();
2405 pWorkItem->RequestType = AFS_WORK_FLUSH_FCB;
2407 if ( AuthGroup == NULL)
2410 RtlZeroMemory( &pWorkItem->AuthGroup,
2413 ntStatus = AFSRetrieveValidAuthGroup( Fcb,
2416 &pWorkItem->AuthGroup);
2420 RtlCopyMemory( &pWorkItem->AuthGroup,
2425 pWorkItem->Specific.Fcb.Fcb = Fcb;
2427 lCount = InterlockedIncrement( &Fcb->OpenReferenceCount);
2429 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2430 AFS_TRACE_LEVEL_VERBOSE,
2431 "AFSQueueFlushExtents Increment count on Fcb %p Cnt %d\n",
2435 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2436 AFS_TRACE_LEVEL_VERBOSE,
2437 "AFSQueueFlushExtents Workitem %p for FID %08lX-%08lX-%08lX-%08lX\n",
2439 Fcb->ObjectInformation->FileId.Cell,
2440 Fcb->ObjectInformation->FileId.Volume,
2441 Fcb->ObjectInformation->FileId.Vnode,
2442 Fcb->ObjectInformation->FileId.Unique);
2444 ntStatus = AFSQueueWorkerRequest( pWorkItem);
2448 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2449 AFS_TRACE_LEVEL_VERBOSE,
2450 "AFSQueueFlushExtents Request complete Status %08lX FID %08lX-%08lX-%08lX-%08lX\n",
2451 Fcb->ObjectInformation->FileId.Cell,
2452 Fcb->ObjectInformation->FileId.Volume,
2453 Fcb->ObjectInformation->FileId.Vnode,
2454 Fcb->ObjectInformation->FileId.Unique,
2458 // Remove the count we added above
2461 lCount = InterlockedDecrement( &Fcb->Specific.File.QueuedFlushCount);
2463 ASSERT( lCount >= 0);
2468 KeSetEvent( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
2473 if( !NT_SUCCESS( ntStatus))
2476 if( pWorkItem != NULL)
2479 lCount = InterlockedDecrement( &Fcb->OpenReferenceCount);
2481 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2484 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2485 AFS_TRACE_LEVEL_ERROR,
2486 "AFSQueueFlushExtents Failed to queue request Status %08lX\n", ntStatus);
2489 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2494 "EXCEPTION - AFSQueueFlushExtents\n");
2496 AFSDumpTraceFilesFnc();
2503 AFSQueueGlobalRootEnumeration()
2506 NTSTATUS ntStatus = STATUS_SUCCESS;
2507 AFSWorkItem *pWorkItem = NULL;
2512 pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
2513 sizeof(AFSWorkItem),
2515 if (NULL == pWorkItem)
2518 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2519 AFS_TRACE_LEVEL_ERROR,
2520 "AFSQueueGlobalRootEnumeration Failed to allocate work item\n");
2522 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
2525 RtlZeroMemory( pWorkItem,
2526 sizeof(AFSWorkItem));
2528 pWorkItem->Size = sizeof( AFSWorkItem);
2530 pWorkItem->RequestType = AFS_WORK_ENUMERATE_GLOBAL_ROOT;
2532 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2533 AFS_TRACE_LEVEL_VERBOSE,
2534 "AFSQueueGlobalRootEnumeration Workitem %p\n",
2537 ntStatus = AFSQueueWorkerRequest( pWorkItem);
2541 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2542 AFS_TRACE_LEVEL_VERBOSE,
2543 "AFSQueueGlobalRootEnumeration Request complete Status %08lX\n",
2546 if( !NT_SUCCESS( ntStatus))
2549 if( pWorkItem != NULL)
2552 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2555 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2556 AFS_TRACE_LEVEL_ERROR,
2557 "AFSQueueGlobalRootEnumeration Failed to queue request Status %08lX\n",
2561 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2566 "EXCEPTION - AFSQueueGlobalRootEnumeration\n");
2568 AFSDumpTraceFilesFnc();
2575 AFSQueueStartIos( IN PFILE_OBJECT CacheFileObject,
2576 IN UCHAR FunctionCode,
2577 IN ULONG RequestFlags,
2578 IN AFSIoRun *IoRuns,
2580 IN AFSGatherIo *GatherIo)
2583 NTSTATUS ntStatus = STATUS_SUCCESS;
2584 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2585 AFSWorkItem *pWorkItem = NULL;
2590 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
2593 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2594 AFS_TRACE_LEVEL_ERROR,
2595 "AFSQueueStartIos Failing request, in shutdown\n");
2597 try_return( ntStatus = STATUS_TOO_LATE);
2601 // Allocate our request structure and send it to the worker
2604 pWorkItem = (AFSWorkItem *)AFSLibExAllocatePoolWithTag( NonPagedPool,
2605 sizeof( AFSWorkItem),
2608 if( pWorkItem == NULL)
2611 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2612 AFS_TRACE_LEVEL_ERROR,
2613 "AFSQueueStartIos Failed to allocate work item\n");
2615 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2618 RtlZeroMemory( pWorkItem,
2619 sizeof( AFSWorkItem));
2621 KeInitializeEvent( &pWorkItem->Event,
2625 pWorkItem->Size = sizeof( AFSWorkItem);
2627 pWorkItem->ProcessID = (ULONGLONG)PsGetCurrentProcessId();
2629 pWorkItem->RequestType = AFS_WORK_START_IOS;
2631 pWorkItem->Specific.CacheAccess.CacheFileObject = CacheFileObject;
2633 pWorkItem->Specific.CacheAccess.FunctionCode = FunctionCode;
2635 pWorkItem->Specific.CacheAccess.RequestFlags = RequestFlags;
2637 pWorkItem->Specific.CacheAccess.IoRuns = IoRuns;
2639 pWorkItem->Specific.CacheAccess.RunCount = RunCount;
2641 pWorkItem->Specific.CacheAccess.GatherIo = GatherIo;
2643 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2644 AFS_TRACE_LEVEL_VERBOSE,
2645 "AFSQueueStartIos Queuing IO Workitem %p\n",
2648 ntStatus = AFSQueueIOWorkerRequest( pWorkItem);
2652 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2653 AFS_TRACE_LEVEL_VERBOSE,
2654 "AFSQueueStartIos Request complete Status %08lX\n",
2657 if( !NT_SUCCESS( ntStatus))
2660 if( pWorkItem != NULL)
2663 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2667 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2672 "EXCEPTION - AFSQueueStartIos\n");
2674 AFSDumpTraceFilesFnc();
2681 AFSQueueInvalidateObject( IN AFSObjectInfoCB *ObjectInfo,
2682 IN ULONG InvalidateReason)
2685 NTSTATUS ntStatus = STATUS_SUCCESS;
2686 AFSWorkItem *pWorkItem = NULL;
2691 pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
2692 sizeof(AFSWorkItem),
2694 if (NULL == pWorkItem)
2697 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2698 AFS_TRACE_LEVEL_ERROR,
2699 "AFSQueueInvalidateObject Failed to allocate work item\n");
2701 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
2704 RtlZeroMemory( pWorkItem,
2705 sizeof(AFSWorkItem));
2707 pWorkItem->Size = sizeof( AFSWorkItem);
2709 pWorkItem->RequestType = AFS_WORK_INVALIDATE_OBJECT;
2711 pWorkItem->Specific.Invalidate.ObjectInfo = ObjectInfo;
2713 pWorkItem->Specific.Invalidate.InvalidateReason = InvalidateReason;
2715 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2716 AFS_TRACE_LEVEL_VERBOSE,
2717 "AFSQueueInvalidateObject Workitem %p\n",
2720 ntStatus = AFSQueueWorkerRequest( pWorkItem);
2724 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2725 AFS_TRACE_LEVEL_VERBOSE,
2726 "AFSQueueInvalidateObject Request complete Status %08lX\n",
2729 if( !NT_SUCCESS( ntStatus))
2732 if( pWorkItem != NULL)
2734 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2737 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2738 AFS_TRACE_LEVEL_ERROR,
2739 "AFSQueueInvalidateObject Failed to queue request Status %08lX\n",
2743 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2748 "EXCEPTION - AFSQueueInvalidateObject\n");
2750 AFSDumpTraceFilesFnc();
2757 AFSDeferWrite( IN PDEVICE_OBJECT DeviceObject,
2758 IN PFILE_OBJECT FileObject,
2759 IN HANDLE CallingUser,
2761 IN ULONG BytesToWrite,
2762 IN BOOLEAN bRetrying)
2764 NTSTATUS ntStatus = STATUS_SUCCESS;
2765 AFSWorkItem *pWorkItem = NULL;
2771 // Pin the user buffer (first time round only - AFSLockSystemBuffer is
2775 if ( NULL == AFSLockSystemBuffer( Irp, BytesToWrite ))
2778 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2779 AFS_TRACE_LEVEL_ERROR,
2780 "%s Could not pin user memory item\n",
2783 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
2786 pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
2787 sizeof(AFSWorkItem),
2790 if (NULL == pWorkItem)
2793 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2794 AFS_TRACE_LEVEL_ERROR,
2795 "%s Failed to allocate work item\n",
2798 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
2801 RtlZeroMemory( pWorkItem,
2802 sizeof(AFSWorkItem));
2804 pWorkItem->Size = sizeof( AFSWorkItem);
2806 pWorkItem->RequestType = AFS_WORK_DEFERRED_WRITE;
2808 pWorkItem->Specific.AsynchIo.CallingProcess = CallingUser;
2810 pWorkItem->Specific.AsynchIo.Device = DeviceObject;
2812 pWorkItem->Specific.AsynchIo.Irp = Irp;
2814 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING | AFS_SUBSYSTEM_WORKER_PROCESSING,
2815 AFS_TRACE_LEVEL_VERBOSE,
2820 CcDeferWrite( FileObject, AFSPostedDeferredWrite, pWorkItem, NULL, BytesToWrite, bRetrying);
2822 IoMarkIrpPending(Irp);
2824 ntStatus = STATUS_PENDING;
2826 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2831 "EXCEPTION - %s \n",
2834 ntStatus = GetExceptionCode();
2839 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2840 AFS_TRACE_LEVEL_VERBOSE,
2841 "%s complete Status %08lX\n",
2845 if( !NT_SUCCESS( ntStatus))
2848 if( pWorkItem != NULL)
2851 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2854 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2855 AFS_TRACE_LEVEL_ERROR,
2856 "%s Failed to queue request Status %08lX\n",
2866 AFSPostedDeferredWrite( IN PVOID Context1,
2869 UNREFERENCED_PARAMETER( Context2);
2872 AFSWorkItem *pWorkItem = (AFSWorkItem *) Context1;
2874 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING | AFS_SUBSYSTEM_WORKER_PROCESSING,
2875 AFS_TRACE_LEVEL_ERROR,
2880 ntStatus = AFSQueueIOWorkerRequest( pWorkItem);
2882 if (!NT_SUCCESS( ntStatus))
2885 AFSCompleteRequest( pWorkItem->Specific.AsynchIo.Irp, ntStatus);
2887 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2889 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING | AFS_SUBSYSTEM_WORKER_PROCESSING,
2890 AFS_TRACE_LEVEL_ERROR,
2891 "%s (%p) Failed to queue request Status %08lX\n",
2893 pWorkItem->Specific.AsynchIo.Irp,