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"
42 // Function: AFSInitializeWorkerPool
46 // This function initializes the worker thread pool
50 // A status is returned for the function
54 AFSInitializeWorkerPool()
57 NTSTATUS ntStatus = STATUS_SUCCESS;
58 AFSWorkQueueContext *pCurrentWorker = NULL, *pLastWorker = NULL;
59 AFSDeviceExt *pDevExt = NULL;
64 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
67 // Initialize the worker threads.
70 pDevExt->Specific.Library.WorkerCount = 0;
72 KeInitializeEvent( &pDevExt->Specific.Library.WorkerQueueHasItems,
77 // Initialize the queue resource
80 ExInitializeResourceLite( &pDevExt->Specific.Library.QueueLock);
82 while( pDevExt->Specific.Library.WorkerCount < AFS_WORKER_COUNT)
85 pCurrentWorker = (AFSWorkQueueContext *)AFSLibExAllocatePoolWithTag( NonPagedPool,
86 sizeof( AFSWorkQueueContext),
89 if( pCurrentWorker == NULL)
92 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
93 AFS_TRACE_LEVEL_ERROR,
94 "AFSInitializeWorkerPool Failed to allocate worker context\n");
96 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
101 RtlZeroMemory( pCurrentWorker,
102 sizeof( AFSWorkQueueContext));
104 ntStatus = AFSInitWorkerThread( pCurrentWorker,
105 (PKSTART_ROUTINE)AFSWorkerThread);
107 if( !NT_SUCCESS( ntStatus))
110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
111 AFS_TRACE_LEVEL_ERROR,
112 "AFSInitializeWorkerPool Failed to initialize worker thread Status %08lX\n", ntStatus);
114 ExFreePool( pCurrentWorker);
119 if( pDevExt->Specific.Library.PoolHead == NULL)
122 pDevExt->Specific.Library.PoolHead = pCurrentWorker;
127 pLastWorker->fLink = pCurrentWorker;
130 pLastWorker = pCurrentWorker;
132 pDevExt->Specific.Library.WorkerCount++;
136 // If there was a failure but there is at least one worker, then go with it.
139 if( !NT_SUCCESS( ntStatus) &&
140 pDevExt->Specific.Library.WorkerCount == 0)
143 try_return( ntStatus);
146 ntStatus = STATUS_SUCCESS;
149 // Now our IO Worker queue
152 pDevExt->Specific.Library.IOWorkerCount = 0;
154 KeInitializeEvent( &pDevExt->Specific.Library.IOWorkerQueueHasItems,
155 SynchronizationEvent,
159 // Initialize the queue resource
162 ExInitializeResourceLite( &pDevExt->Specific.Library.IOQueueLock);
164 while( pDevExt->Specific.Library.IOWorkerCount < AFS_IO_WORKER_COUNT)
167 pCurrentWorker = (AFSWorkQueueContext *)AFSLibExAllocatePoolWithTag( NonPagedPool,
168 sizeof( AFSWorkQueueContext),
171 if( pCurrentWorker == NULL)
174 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
175 AFS_TRACE_LEVEL_ERROR,
176 "AFSInitializeWorkerPool Failed to allocate IO worker context\n");
178 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
183 RtlZeroMemory( pCurrentWorker,
184 sizeof( AFSWorkQueueContext));
186 ntStatus = AFSInitWorkerThread( pCurrentWorker,
187 (PKSTART_ROUTINE)AFSIOWorkerThread);
189 if( !NT_SUCCESS( ntStatus))
192 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
193 AFS_TRACE_LEVEL_ERROR,
194 "AFSInitializeWorkerPool Failed to initialize IO worker thread Status %08lX\n", ntStatus);
196 ExFreePool( pCurrentWorker);
201 if( pDevExt->Specific.Library.IOPoolHead == NULL)
204 pDevExt->Specific.Library.IOPoolHead = pCurrentWorker;
209 pLastWorker->fLink = pCurrentWorker;
212 pLastWorker = pCurrentWorker;
214 pDevExt->Specific.Library.IOWorkerCount++;
218 // If there was a failure but there is at least one worker, then go with it.
221 if( !NT_SUCCESS( ntStatus) &&
222 pDevExt->Specific.Library.IOWorkerCount == 0)
225 try_return( ntStatus);
230 if( !NT_SUCCESS( ntStatus))
234 // Failed to initialize the pool so tear it down
237 AFSRemoveWorkerPool();
245 // Function: AFSRemoveWorkerPool
249 // This function tears down the worker thread pool
253 // A status is returned for the function
257 AFSRemoveWorkerPool()
260 NTSTATUS ntStatus = STATUS_SUCCESS;
262 AFSWorkQueueContext *pCurrentWorker = NULL, *pNextWorker = NULL;
263 AFSDeviceExt *pDevExt = NULL;
265 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
268 // Loop through the workers shutting them down in two stages.
269 // First, clear AFS_WORKER_PROCESS_REQUESTS so that workers
270 // stop processing requests. Second, call AFSShutdownWorkerThread()
271 // to wake the workers and wait for them to exit.
274 pCurrentWorker = pDevExt->Specific.Library.PoolHead;
276 while( index < pDevExt->Specific.Library.WorkerCount)
279 ClearFlag( pCurrentWorker->State, AFS_WORKER_PROCESS_REQUESTS);
281 pCurrentWorker = pCurrentWorker->fLink;
283 if ( pCurrentWorker == NULL)
292 pCurrentWorker = pDevExt->Specific.Library.PoolHead;
296 while( index < pDevExt->Specific.Library.WorkerCount)
299 ntStatus = AFSShutdownWorkerThread( pCurrentWorker);
301 pNextWorker = pCurrentWorker->fLink;
303 ExFreePool( pCurrentWorker);
305 pCurrentWorker = pNextWorker;
307 if( pCurrentWorker == NULL)
316 pDevExt->Specific.Library.PoolHead = NULL;
318 ExDeleteResourceLite( &pDevExt->Specific.Library.QueueLock);
321 // Loop through the IO workers shutting them down in two stages.
322 // First, clear AFS_WORKER_PROCESS_REQUESTS so that workers
323 // stop processing requests. Second, call AFSShutdownWorkerThread()
324 // to wake the workers and wait for them to exit.
327 pCurrentWorker = pDevExt->Specific.Library.IOPoolHead;
331 while( index < pDevExt->Specific.Library.IOWorkerCount)
334 ClearFlag( pCurrentWorker->State, AFS_WORKER_PROCESS_REQUESTS);
336 pCurrentWorker = pCurrentWorker->fLink;
338 if ( pCurrentWorker == NULL)
347 pCurrentWorker = pDevExt->Specific.Library.IOPoolHead;
351 while( index < pDevExt->Specific.Library.IOWorkerCount)
354 ntStatus = AFSShutdownIOWorkerThread( pCurrentWorker);
356 pNextWorker = pCurrentWorker->fLink;
358 ExFreePool( pCurrentWorker);
360 pCurrentWorker = pNextWorker;
362 if( pCurrentWorker == NULL)
371 pDevExt->Specific.Library.IOPoolHead = NULL;
373 ExDeleteResourceLite( &pDevExt->Specific.Library.IOQueueLock);
379 AFSInitVolumeWorker( IN AFSVolumeCB *VolumeCB)
382 NTSTATUS ntStatus = STATUS_SUCCESS;
383 AFSWorkQueueContext *pWorker = &VolumeCB->VolumeWorkerContext;
385 AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
386 PKSTART_ROUTINE pStartRoutine = NULL;
392 if( VolumeCB == AFSGlobalRoot)
395 pStartRoutine = AFSPrimaryVolumeWorkerThread;
400 pStartRoutine = AFSVolumeWorkerThread;
404 // Initialize the worker thread
407 KeInitializeEvent( &pWorker->WorkerThreadReady,
412 // Set the worker to process requests
415 pWorker->State = AFS_WORKER_PROCESS_REQUESTS;
421 ntStatus = PsCreateSystemThread( &hThread,
429 if( NT_SUCCESS( ntStatus))
432 ObReferenceObjectByHandle( hThread,
433 GENERIC_READ | GENERIC_WRITE,
436 (PVOID *)&pWorker->WorkerThreadObject,
439 ntStatus = KeWaitForSingleObject( &pWorker->WorkerThreadReady,
445 lCount = InterlockedIncrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount);
450 KeClearEvent( &pControlDeviceExt->Specific.Control.VolumeWorkerCloseEvent);
461 // Function: AFSInitWorkerThread
465 // This function initializes a worker thread in the pool
469 // A status is returned for the function
473 AFSInitWorkerThread( IN AFSWorkQueueContext *PoolContext,
474 IN PKSTART_ROUTINE WorkerRoutine)
477 NTSTATUS ntStatus = STATUS_SUCCESS;
481 // INitialize the worker signal thread
484 KeInitializeEvent( &PoolContext->WorkerThreadReady,
489 // Set the worker to process requests
492 PoolContext->State = AFS_WORKER_PROCESS_REQUESTS;
498 ntStatus = PsCreateSystemThread( &Handle,
504 (void *)PoolContext);
506 if( NT_SUCCESS( ntStatus))
509 ObReferenceObjectByHandle( Handle,
510 GENERIC_READ | GENERIC_WRITE,
513 (PVOID *)&PoolContext->WorkerThreadObject,
516 ntStatus = KeWaitForSingleObject( &PoolContext->WorkerThreadReady,
529 AFSShutdownVolumeWorker( IN AFSVolumeCB *VolumeCB)
532 NTSTATUS ntStatus = STATUS_SUCCESS;
533 AFSWorkQueueContext *pWorker = &VolumeCB->VolumeWorkerContext;
535 if( pWorker->WorkerThreadObject != NULL &&
536 BooleanFlagOn( pWorker->State, AFS_WORKER_INITIALIZED))
540 // Clear the 'keep processing' flag
543 ClearFlag( pWorker->State, AFS_WORKER_PROCESS_REQUESTS);
545 ntStatus = KeWaitForSingleObject( pWorker->WorkerThreadObject,
551 ObDereferenceObject( pWorker->WorkerThreadObject);
553 pWorker->WorkerThreadObject = NULL;
560 // Function: AFSShutdownWorkerThread
564 // This function shutsdown a worker thread in the pool
568 // A status is returned for the function
572 AFSShutdownWorkerThread( IN AFSWorkQueueContext *PoolContext)
575 NTSTATUS ntStatus = STATUS_SUCCESS;
576 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
578 if( PoolContext->WorkerThreadObject != NULL &&
579 BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED))
583 // Wake up the thread if it is a sleep
586 KeSetEvent( &pDeviceExt->Specific.Library.WorkerQueueHasItems,
590 ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
596 ObDereferenceObject( PoolContext->WorkerThreadObject);
598 PoolContext->WorkerThreadObject = NULL;
605 // Function: AFSShutdownIOWorkerThread
609 // This function shutsdown an IO worker thread in the pool
613 // A status is returned for the function
617 AFSShutdownIOWorkerThread( IN AFSWorkQueueContext *PoolContext)
620 NTSTATUS ntStatus = STATUS_SUCCESS;
621 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
623 if( PoolContext->WorkerThreadObject != NULL &&
624 BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED))
628 // Wake up the thread if it is a sleep
631 KeSetEvent( &pDeviceExt->Specific.Library.IOWorkerQueueHasItems,
635 ntStatus = KeWaitForSingleObject( PoolContext->WorkerThreadObject,
641 ObDereferenceObject( PoolContext->WorkerThreadObject);
643 PoolContext->WorkerThreadObject = NULL;
650 // Function: AFSWorkerThread
654 // This is the worker thread entry point.
658 // A status is returned for the function
662 AFSWorkerThread( IN PVOID Context)
665 NTSTATUS ntStatus = STATUS_SUCCESS;
666 AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
667 AFSWorkItem *pWorkItem;
668 BOOLEAN freeWorkItem = TRUE;
669 AFSDeviceExt *pLibraryDevExt = NULL;
672 pLibraryDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
675 // Indicate that we are initialized and ready
678 KeSetEvent( &pPoolContext->WorkerThreadReady,
683 // Indicate we are initialized
686 SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
688 ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
694 while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
697 if( !NT_SUCCESS( ntStatus))
700 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
701 AFS_TRACE_LEVEL_ERROR,
702 "AFSWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
704 ntStatus = STATUS_SUCCESS;
709 pWorkItem = AFSRemoveWorkItem();
711 if( pWorkItem == NULL)
714 ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
726 // Switch on the type of work item to process
729 switch( pWorkItem->RequestType)
732 case AFS_WORK_FLUSH_FCB:
735 ntStatus = AFSFlushExtents( pWorkItem->Specific.Fcb.Fcb,
736 &pWorkItem->AuthGroup);
738 if( !NT_SUCCESS( ntStatus))
741 AFSReleaseExtentsWithFlush( pWorkItem->Specific.Fcb.Fcb,
742 &pWorkItem->AuthGroup);
745 ASSERT( pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount != 0);
747 lCount = InterlockedDecrement( &pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount);
752 case AFS_WORK_ASYNCH_READ:
755 ASSERT( pWorkItem->Specific.AsynchIo.CallingProcess != NULL);
757 (VOID) AFSCommonRead( pWorkItem->Specific.AsynchIo.Device,
758 pWorkItem->Specific.AsynchIo.Irp,
759 pWorkItem->Specific.AsynchIo.CallingProcess);
764 case AFS_WORK_ASYNCH_WRITE:
767 ASSERT( pWorkItem->Specific.AsynchIo.CallingProcess != NULL);
769 (VOID) AFSCommonWrite( pWorkItem->Specific.AsynchIo.Device,
770 pWorkItem->Specific.AsynchIo.Irp,
771 pWorkItem->Specific.AsynchIo.CallingProcess);
775 case AFS_WORK_ENUMERATE_GLOBAL_ROOT:
778 AFSEnumerateGlobalRoot( NULL);
783 case AFS_WORK_INVALIDATE_OBJECT:
786 AFSPerformObjectInvalidate( pWorkItem->Specific.Invalidate.ObjectInfo,
787 pWorkItem->Specific.Invalidate.InvalidateReason);
794 case AFS_WORK_START_IOS:
804 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
805 AFS_TRACE_LEVEL_ERROR,
806 "AFSWorkerThread Unknown request type %d\n", pWorkItem->RequestType);
814 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
817 ntStatus = STATUS_SUCCESS;
820 } // worker thread loop
822 ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
824 // Wake up another worker so they too can exit
826 KeSetEvent( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
830 PsTerminateSystemThread( 0);
836 AFSIOWorkerThread( IN PVOID Context)
839 NTSTATUS ntStatus = STATUS_SUCCESS;
840 AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
841 AFSWorkItem *pWorkItem;
842 BOOLEAN freeWorkItem = TRUE;
843 AFSDeviceExt *pLibraryDevExt = NULL, *pRdrDevExt = NULL;
845 pLibraryDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
848 // Indicate that we are initialized and ready
851 KeSetEvent( &pPoolContext->WorkerThreadReady,
857 // Indicate we are initialized
860 SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
862 ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
868 while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
871 if( !NT_SUCCESS( ntStatus))
874 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
875 AFS_TRACE_LEVEL_ERROR,
876 "AFSIOWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
878 ntStatus = STATUS_SUCCESS;
883 pWorkItem = AFSRemoveIOWorkItem();
885 if( pWorkItem == NULL)
888 ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
900 // Switch on the type of work item to process
903 switch( pWorkItem->RequestType)
906 case AFS_WORK_START_IOS:
909 pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
912 // The final status is in the gather io
915 ntStatus = AFSStartIos( pWorkItem->Specific.CacheAccess.CacheFileObject,
916 pWorkItem->Specific.CacheAccess.FunctionCode,
917 pWorkItem->Specific.CacheAccess.RequestFlags,
918 pWorkItem->Specific.CacheAccess.IoRuns,
919 pWorkItem->Specific.CacheAccess.RunCount,
920 pWorkItem->Specific.CacheAccess.GatherIo);
923 // Regardless of the status we we do the complete - there may
925 // Decrement the count - setting the event if we were told
926 // to. This may trigger completion.
929 AFSCompleteIo( pWorkItem->Specific.CacheAccess.GatherIo, ntStatus );
938 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
939 AFS_TRACE_LEVEL_ERROR,
940 "AFSWorkerThread Unknown request type %d\n", pWorkItem->RequestType);
948 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
951 ntStatus = STATUS_SUCCESS;
954 } // worker thread loop
956 ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
958 // Wake up another IOWorker so they too can exit
960 KeSetEvent( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
964 PsTerminateSystemThread( 0);
970 AFSPrimaryVolumeWorkerThread( IN PVOID Context)
973 NTSTATUS ntStatus = STATUS_SUCCESS;
974 AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&AFSGlobalRoot->VolumeWorkerContext;
975 AFSDeviceExt *pControlDeviceExt = NULL;
976 AFSDeviceExt *pRDRDeviceExt = NULL;
977 LARGE_INTEGER DueTime;
980 BOOLEAN bFoundOpenEntry = FALSE;
981 AFSObjectInfoCB *pCurrentObject = NULL, *pNextObject = NULL, *pCurrentChildObject = NULL;
982 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
983 BOOLEAN bReleaseVolumeLock = FALSE;
984 AFSVolumeCB *pVolumeCB = NULL, *pNextVolume = NULL;
987 LARGE_INTEGER liCurrentTime;
988 BOOLEAN bVolumeObject = FALSE;
991 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
993 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
995 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
996 AFS_TRACE_LEVEL_VERBOSE,
997 "AFSPrimaryVolumeWorkerThread Initialized\n");
1000 // Initialize the timer for the worker thread
1003 DueTime.QuadPart = -(5000);
1007 KeInitializeTimerEx( &Timer,
1008 SynchronizationTimer);
1010 KeSetTimerEx( &Timer,
1016 // Indicate that we are initialized and ready
1019 KeSetEvent( &pPoolContext->WorkerThreadReady,
1024 // Indicate we are initialized
1027 SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
1029 while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
1032 KeWaitForSingleObject( &Timer,
1039 // This is the primary volume worker so it will traverse the volume list
1040 // looking for cleanup or volumes requiring private workers
1043 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
1046 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
1048 while( pVolumeCB != NULL)
1051 if( pVolumeCB == AFSGlobalRoot ||
1052 !AFSAcquireExcl( pVolumeCB->VolumeLock,
1056 pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
1061 if( pVolumeCB->ObjectInfoListHead == NULL)
1064 AFSReleaseResource( pVolumeCB->VolumeLock);
1066 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1068 AFSAcquireExcl( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock,
1071 AFSAcquireExcl( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
1074 if( !AFSAcquireExcl( pVolumeCB->VolumeLock,
1078 AFSConvertToShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1080 AFSReleaseResource( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock);
1082 pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
1087 KeQueryTickCount( &liCurrentTime);
1089 pNextVolume = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
1091 if( pVolumeCB->ObjectInfoListHead == NULL &&
1092 pVolumeCB->DirectoryCB->OpenReferenceCount == 0 &&
1093 pVolumeCB->VolumeReferenceCount == 1 &&
1094 ( pVolumeCB->RootFcb == NULL ||
1095 pVolumeCB->RootFcb->OpenReferenceCount == 0) &&
1096 pVolumeCB->ObjectInformation.ObjectReferenceCount <= 0)
1099 if( pVolumeCB->RootFcb != NULL)
1102 AFSRemoveRootFcb( pVolumeCB->RootFcb);
1105 AFSRemoveVolume( pVolumeCB);
1110 AFSReleaseResource( pVolumeCB->VolumeLock);
1113 AFSConvertToShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1115 AFSReleaseResource( pRDRDeviceExt->Specific.RDR.VolumeTree.TreeLock);
1117 pVolumeCB = pNextVolume;
1123 // Don't need this lock anymore now that we have a volume cb to work with
1126 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1129 // For now we only need the volume lock shared
1132 AFSConvertToShared( pVolumeCB->VolumeLock);
1134 if( AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1138 pCurrentObject = pVolumeCB->ObjectInfoListHead;
1142 bReleaseVolumeLock = TRUE;
1144 while( pCurrentObject != NULL)
1147 if( pCurrentObject != &pVolumeCB->ObjectInformation)
1150 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
1152 if( pNextObject == NULL &&
1153 pVolumeCB != AFSGlobalRoot) // Don't free up the root of the global
1156 pNextObject = &pVolumeCB->ObjectInformation;
1159 bVolumeObject = FALSE;
1166 bVolumeObject = TRUE;
1169 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1170 !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN)) // If we are in shutdown mode skip directories
1174 // If this object is deleted then remove it from the parent, if we can
1177 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1178 pCurrentObject->ObjectReferenceCount <= 0 &&
1179 ( pCurrentObject->Fcb == NULL ||
1180 pCurrentObject->Fcb->OpenReferenceCount == 0) &&
1181 pCurrentObject->Specific.Directory.DirectoryNodeListHead == NULL &&
1182 pCurrentObject->Specific.Directory.ChildOpenReferenceCount == 0)
1185 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1188 // Dropping the TreeLock permits the
1189 // pCurrentObject->ObjectReferenceCount to change
1192 if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1196 if ( pCurrentObject->ObjectReferenceCount <= 0)
1199 if( pCurrentObject->Fcb != NULL)
1202 AFSRemoveFcb( &pCurrentObject->Fcb);
1205 if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
1208 if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
1211 AFSRemoveFcb( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
1214 AFSDeleteObjectInfo( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
1216 ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
1218 AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged);
1220 AFSExFreePool( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB);
1223 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1224 AFS_TRACE_LEVEL_VERBOSE,
1225 "AFSPrimaryVolumeWorkerThread Deleting deleted object %08lX\n",
1228 AFSDeleteObjectInfo( pCurrentObject);
1231 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1233 pCurrentObject = pNextObject;
1240 bReleaseVolumeLock = FALSE;
1246 if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0 ||
1247 ( pCurrentObject->Fcb != NULL &&
1248 pCurrentObject->Fcb->OpenReferenceCount > 0) ||
1249 pCurrentObject->Specific.Directory.DirectoryNodeListHead == NULL)
1252 pCurrentObject = pNextObject;
1257 if( !AFSAcquireShared( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1261 pCurrentObject = pNextObject;
1266 KeQueryTickCount( &liCurrentTime);
1268 pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
1270 while( pCurrentDirEntry != NULL)
1273 if( pCurrentDirEntry->OpenReferenceCount > 0 ||
1274 ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
1275 pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0) ||
1276 liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart ||
1277 liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart <
1278 pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart ||
1279 ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1280 ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL ||
1281 pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)) ||
1282 ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
1283 pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
1284 pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0))
1290 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
1293 if( pCurrentDirEntry != NULL)
1296 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1298 pCurrentObject = pNextObject;
1303 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1305 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1308 // Now acquire the locks excl
1311 if( AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1315 if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1319 if( pCurrentObject->Specific.Directory.ChildOpenReferenceCount > 0)
1322 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1324 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1326 pCurrentObject = pNextObject;
1331 KeQueryTickCount( &liCurrentTime);
1333 pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
1335 while( pCurrentDirEntry != NULL)
1338 if( pCurrentDirEntry->OpenReferenceCount > 0 ||
1339 ( pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
1340 pCurrentDirEntry->ObjectInformation->Fcb->OpenReferenceCount > 0) ||
1341 liCurrentTime.QuadPart <= pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart ||
1342 liCurrentTime.QuadPart - pCurrentDirEntry->ObjectInformation->LastAccessCount.QuadPart <
1343 pControlDeviceExt->Specific.Control.ObjectLifeTimeCount.QuadPart ||
1344 ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1345 ( pCurrentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL ||
1346 pCurrentDirEntry->ObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)) ||
1347 ( pCurrentDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
1348 pCurrentDirEntry->ObjectInformation->Fcb != NULL &&
1349 pCurrentDirEntry->ObjectInformation->Fcb->Specific.File.ExtentsDirtyCount > 0))
1355 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
1358 if( pCurrentDirEntry != NULL)
1361 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1363 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1365 pCurrentObject = pNextObject;
1370 pCurrentDirEntry = pCurrentObject->Specific.Directory.DirectoryNodeListHead;
1372 while( pCurrentDirEntry != NULL)
1375 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
1377 pCurrentChildObject = pCurrentDirEntry->ObjectInformation;
1381 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1382 AFS_TRACE_LEVEL_VERBOSE,
1383 "AFSPrimaryVolumeWorkerThread Deleting DE %wZ Object %08lX\n",
1384 &pCurrentDirEntry->NameInformation.FileName,
1385 pCurrentChildObject);
1387 AFSDeleteDirEntry( pCurrentObject,
1390 if( pCurrentChildObject->ObjectReferenceCount <= 0 &&
1391 pCurrentChildObject->Fcb != NULL &&
1392 pCurrentChildObject->FileType == AFS_FILE_TYPE_FILE)
1396 // We must not hold pVolumeCB->ObjectInfoTree.TreeLock exclusive
1397 // across an AFSCleanupFcb call since it can deadlock with an
1398 // invalidation call from the service.
1401 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1404 // Dropping the TreeLock permits the
1405 // pCurrentObject->ObjectReferenceCount to change
1408 AFSCleanupFcb( pCurrentChildObject->Fcb,
1411 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1415 if( pCurrentChildObject->ObjectReferenceCount <= 0 &&
1416 ( pCurrentChildObject->Fcb == NULL ||
1417 pCurrentChildObject->Fcb->OpenReferenceCount == 0 &&
1418 pCurrentChildObject->Fcb->Specific.File.ExtentCount == 0))
1421 if( pCurrentChildObject->Fcb != NULL)
1424 AFSRemoveFcb( &pCurrentChildObject->Fcb);
1427 if( pCurrentChildObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1428 pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
1431 if( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
1434 AFSRemoveFcb( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
1437 AFSDeleteObjectInfo( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
1439 ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
1441 AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged);
1443 AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB);
1446 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1447 AFS_TRACE_LEVEL_VERBOSE,
1448 "AFSPrimaryVolumeWorkerThread Deleting object %08lX\n",
1449 pCurrentChildObject);
1451 AFSDeleteObjectInfo( pCurrentChildObject);
1454 pCurrentDirEntry = pNextDirEntry;
1458 pCurrentObject->Specific.Directory.DirectoryNodeListHead = NULL;
1460 pCurrentObject->Specific.Directory.DirectoryNodeListTail = NULL;
1462 pCurrentObject->Specific.Directory.ShortNameTree = NULL;
1464 pCurrentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
1466 pCurrentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
1468 pCurrentObject->Specific.Directory.DirectoryNodeCount = 0;
1470 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
1471 AFS_TRACE_LEVEL_VERBOSE,
1472 "AFSPrimaryVolumeWorkerThread Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
1473 pCurrentObject->FileId.Cell,
1474 pCurrentObject->FileId.Volume,
1475 pCurrentObject->FileId.Vnode,
1476 pCurrentObject->FileId.Unique);
1479 // Clear our enumerated flag on this object so we retrieve info again on next access
1482 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1484 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1486 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1491 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1493 bReleaseVolumeLock = FALSE;
1502 // Try to grab the volume lock again ... no problem if we don't
1505 if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1509 bReleaseVolumeLock = FALSE;
1515 if( pCurrentObject != &pVolumeCB->ObjectInformation)
1518 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
1520 if( pCurrentObject == NULL &&
1521 pVolumeCB != AFSGlobalRoot)
1524 pCurrentObject = &pVolumeCB->ObjectInformation;
1530 pCurrentObject = NULL;
1535 else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
1538 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1540 if( pCurrentObject->Fcb != NULL)
1544 // Dropping the TreeLock permits the
1545 // pCurrentObject->ObjectReferenceCount to change
1548 AFSCleanupFcb( pCurrentObject->Fcb,
1552 if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
1556 bReleaseVolumeLock = FALSE;
1561 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1562 pCurrentObject->ObjectReferenceCount <= 0 &&
1563 ( pCurrentObject->Fcb == NULL ||
1564 pCurrentObject->Fcb->OpenReferenceCount == 0 &&
1565 pCurrentObject->Fcb->Specific.File.ExtentCount == 0))
1568 if( pCurrentObject->Fcb != NULL)
1571 AFSRemoveFcb( &pCurrentObject->Fcb);
1574 AFSDeleteObjectInfo( pCurrentObject);
1577 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
1579 pCurrentObject = pNextObject;
1584 pCurrentObject = pNextObject;
1587 if( bReleaseVolumeLock)
1590 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1598 AFSReleaseResource( pVolumeCB->VolumeLock);
1600 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
1603 pVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
1606 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
1608 } // worker thread loop
1610 KeCancelTimer( &Timer);
1612 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1613 AFS_TRACE_LEVEL_VERBOSE,
1614 "AFSPrimaryVolumeWorkerThread Exiting\n");
1616 lCount = InterlockedDecrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount);
1621 KeSetEvent( &pControlDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
1626 PsTerminateSystemThread( 0);
1632 AFSVolumeWorkerThread( IN PVOID Context)
1635 NTSTATUS ntStatus = STATUS_SUCCESS;
1636 AFSVolumeCB *pVolumeCB = (AFSVolumeCB * )Context;
1637 AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&pVolumeCB->VolumeWorkerContext;
1638 AFSDeviceExt *pControlDeviceExt = NULL;
1639 AFSDeviceExt *pRDRDeviceExt = NULL;
1640 BOOLEAN exitThread = FALSE;
1641 LARGE_INTEGER DueTime;
1646 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
1648 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1651 // Initialize the timer for the worker thread
1654 DueTime.QuadPart = -(5000);
1658 KeInitializeTimerEx( &Timer,
1659 SynchronizationTimer);
1661 KeSetTimerEx( &Timer,
1667 // Indicate that we are initialized and ready
1670 KeSetEvent( &pPoolContext->WorkerThreadReady,
1675 // Indicate we are initialized
1678 SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
1680 while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
1683 ntStatus = KeWaitForSingleObject( &Timer,
1689 if( !NT_SUCCESS( ntStatus))
1692 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1693 AFS_TRACE_LEVEL_ERROR,
1694 "AFSVolumeWorkerThread Wait for queue items failed Status %08lX\n", ntStatus);
1700 // If we are in shutdown mode and the dirty flag is clear then get out now
1703 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
1709 } // worker thread loop
1711 KeCancelTimer( &Timer);
1713 lCount = InterlockedDecrement( &pControlDeviceExt->Specific.Control.VolumeWorkerThreadCount);
1718 KeSetEvent( &pControlDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
1723 PsTerminateSystemThread( 0);
1729 AFSInsertWorkitem( IN AFSWorkItem *WorkItem)
1732 NTSTATUS ntStatus = STATUS_SUCCESS;
1733 AFSDeviceExt *pDevExt = NULL;
1736 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
1738 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1739 AFS_TRACE_LEVEL_VERBOSE,
1740 "AFSInsertWorkitem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
1741 &pDevExt->Specific.Library.QueueLock,
1742 PsGetCurrentThread());
1744 AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
1747 lCount = InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount);
1749 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
1750 AFS_TRACE_LEVEL_VERBOSE,
1751 "AFSInsertWorkitem Inserting work item %08lX Count %08lX\n",
1755 if( pDevExt->Specific.Library.QueueTail != NULL) // queue already has nodes
1758 pDevExt->Specific.Library.QueueTail->next = WorkItem;
1763 pDevExt->Specific.Library.QueueHead = WorkItem;
1766 WorkItem->next = NULL;
1767 pDevExt->Specific.Library.QueueTail = WorkItem;
1769 // indicate that the queue has nodes
1770 KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
1774 AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
1780 AFSInsertIOWorkitem( IN AFSWorkItem *WorkItem)
1783 NTSTATUS ntStatus = STATUS_SUCCESS;
1784 AFSDeviceExt *pDevExt = NULL;
1787 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
1789 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1790 AFS_TRACE_LEVEL_VERBOSE,
1791 "AFSInsertIOWorkitem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
1792 &pDevExt->Specific.Library.IOQueueLock,
1793 PsGetCurrentThread());
1795 AFSAcquireExcl( &pDevExt->Specific.Library.IOQueueLock,
1798 lCount = InterlockedIncrement( &pDevExt->Specific.Library.IOQueueItemCount);
1800 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
1801 AFS_TRACE_LEVEL_VERBOSE,
1802 "AFSInsertWorkitem Inserting IO work item %08lX Count %08lX\n",
1806 if( pDevExt->Specific.Library.IOQueueTail != NULL) // queue already has nodes
1809 pDevExt->Specific.Library.IOQueueTail->next = WorkItem;
1814 pDevExt->Specific.Library.IOQueueHead = WorkItem;
1817 WorkItem->next = NULL;
1818 pDevExt->Specific.Library.IOQueueTail = WorkItem;
1820 // indicate that the queue has nodes
1821 KeSetEvent( &(pDevExt->Specific.Library.IOWorkerQueueHasItems),
1825 AFSReleaseResource( &pDevExt->Specific.Library.IOQueueLock);
1831 AFSInsertWorkitemAtHead( IN AFSWorkItem *WorkItem)
1834 NTSTATUS ntStatus = STATUS_SUCCESS;
1835 AFSDeviceExt *pDevExt = NULL;
1838 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
1840 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1841 AFS_TRACE_LEVEL_VERBOSE,
1842 "AFSInsertWorkitemAtHead Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
1843 &pDevExt->Specific.Library.QueueLock,
1844 PsGetCurrentThread());
1846 AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
1849 WorkItem->next = pDevExt->Specific.Library.QueueHead;
1851 pDevExt->Specific.Library.QueueHead = WorkItem;
1853 lCount = InterlockedIncrement( &pDevExt->Specific.Library.QueueItemCount);
1855 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
1856 AFS_TRACE_LEVEL_VERBOSE,
1857 "AFSInsertWorkitemAtHead Inserting work item %08lX Count %08lX\n",
1862 // indicate that the queue has nodes
1865 KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
1869 AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
1878 NTSTATUS ntStatus = STATUS_SUCCESS;
1879 AFSWorkItem *pWorkItem = NULL;
1880 AFSDeviceExt *pDevExt = NULL;
1883 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
1885 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1886 AFS_TRACE_LEVEL_VERBOSE,
1887 "AFSRemoveWorkItem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
1888 &pDevExt->Specific.Library.QueueLock,
1889 PsGetCurrentThread());
1891 AFSAcquireExcl( &pDevExt->Specific.Library.QueueLock,
1894 if( pDevExt->Specific.Library.QueueHead != NULL) // queue has nodes
1897 pWorkItem = pDevExt->Specific.Library.QueueHead;
1899 lCount = InterlockedDecrement( &pDevExt->Specific.Library.QueueItemCount);
1901 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
1902 AFS_TRACE_LEVEL_VERBOSE,
1903 "AFSRemoveWorkItem Removing work item %08lX Count %08lX Thread %08lX\n",
1906 PsGetCurrentThreadId());
1908 pDevExt->Specific.Library.QueueHead = pDevExt->Specific.Library.QueueHead->next;
1910 if( pDevExt->Specific.Library.QueueHead == NULL) // if queue just became empty
1913 pDevExt->Specific.Library.QueueTail = NULL;
1919 // Wake up another worker
1922 KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
1928 AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
1934 AFSRemoveIOWorkItem()
1937 NTSTATUS ntStatus = STATUS_SUCCESS;
1938 AFSWorkItem *pWorkItem = NULL;
1939 AFSDeviceExt *pDevExt = NULL;
1942 pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
1944 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1945 AFS_TRACE_LEVEL_VERBOSE,
1946 "AFSRemoveIOWorkItem Acquiring Control QueueLock lock %08lX EXCL %08lX\n",
1947 &pDevExt->Specific.Library.IOQueueLock,
1948 PsGetCurrentThread());
1950 AFSAcquireExcl( &pDevExt->Specific.Library.IOQueueLock,
1953 if( pDevExt->Specific.Library.IOQueueHead != NULL) // queue has nodes
1956 pWorkItem = pDevExt->Specific.Library.IOQueueHead;
1958 lCount = InterlockedDecrement( &pDevExt->Specific.Library.IOQueueItemCount);
1960 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
1961 AFS_TRACE_LEVEL_VERBOSE,
1962 "AFSRemoveWorkItem Removing work item %08lX Count %08lX Thread %08lX\n",
1965 PsGetCurrentThreadId());
1967 pDevExt->Specific.Library.IOQueueHead = pDevExt->Specific.Library.IOQueueHead->next;
1969 if( pDevExt->Specific.Library.IOQueueHead == NULL) // if queue just became empty
1972 pDevExt->Specific.Library.IOQueueTail = NULL;
1978 // Wake up another worker
1981 KeSetEvent( &(pDevExt->Specific.Library.IOWorkerQueueHasItems),
1987 AFSReleaseResource( &pDevExt->Specific.Library.IOQueueLock);
1993 AFSQueueWorkerRequest( IN AFSWorkItem *WorkItem)
1996 NTSTATUS ntStatus = STATUS_SUCCESS;
1997 AFSDeviceExt *pDevExt = NULL;
1998 BOOLEAN bWait = BooleanFlagOn( WorkItem->RequestFlags, AFS_SYNCHRONOUS_REQUEST);
2001 // Submit the work item to the worker
2004 ntStatus = AFSInsertWorkitem( WorkItem);
2010 // Sync request so block on the work item event
2013 ntStatus = KeWaitForSingleObject( &WorkItem->Event,
2024 AFSQueueIOWorkerRequest( IN AFSWorkItem *WorkItem)
2027 NTSTATUS ntStatus = STATUS_SUCCESS;
2028 AFSDeviceExt *pDevExt = NULL;
2029 BOOLEAN bWait = BooleanFlagOn( WorkItem->RequestFlags, AFS_SYNCHRONOUS_REQUEST);
2032 // Submit the work item to the worker
2035 ntStatus = AFSInsertIOWorkitem( WorkItem);
2041 // Sync request so block on the work item event
2044 ntStatus = KeWaitForSingleObject( &WorkItem->Event,
2055 AFSQueueWorkerRequestAtHead( IN AFSWorkItem *WorkItem)
2058 NTSTATUS ntStatus = STATUS_SUCCESS;
2059 AFSDeviceExt *pDevExt = NULL;
2060 BOOLEAN bWait = BooleanFlagOn( WorkItem->RequestFlags, AFS_SYNCHRONOUS_REQUEST);
2063 // Submit the work item to the worker
2066 ntStatus = AFSInsertWorkitemAtHead( WorkItem);
2072 // Sync request so block on the work item event
2075 ntStatus = KeWaitForSingleObject( &WorkItem->Event,
2086 AFSQueueFlushExtents( IN AFSFcb *Fcb,
2090 NTSTATUS ntStatus = STATUS_SUCCESS;
2091 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2092 AFSWorkItem *pWorkItem = NULL;
2098 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2099 AFS_TRACE_LEVEL_VERBOSE,
2100 "AFSQueueFlushExtents Queuing request for FID %08lX-%08lX-%08lX-%08lX\n",
2101 Fcb->ObjectInformation->FileId.Cell,
2102 Fcb->ObjectInformation->FileId.Volume,
2103 Fcb->ObjectInformation->FileId.Vnode,
2104 Fcb->ObjectInformation->FileId.Unique);
2107 // Increment our flush count here just to keep the number of items in the
2108 // queue down. We'll decrement it just below.
2111 lCount = InterlockedIncrement( &Fcb->Specific.File.QueuedFlushCount);
2116 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2117 AFS_TRACE_LEVEL_VERBOSE,
2118 "AFSQueueFlushExtents Max queued items for FID %08lX-%08lX-%08lX-%08lX\n",
2119 Fcb->ObjectInformation->FileId.Cell,
2120 Fcb->ObjectInformation->FileId.Volume,
2121 Fcb->ObjectInformation->FileId.Vnode,
2122 Fcb->ObjectInformation->FileId.Unique);
2124 try_return( ntStatus);
2127 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
2130 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2131 AFS_TRACE_LEVEL_ERROR,
2132 "AFSQueueFlushExtents Failing request, in shutdown\n");
2134 try_return( ntStatus = STATUS_TOO_LATE);
2138 // Allocate our request structure and send it to the worker
2141 pWorkItem = (AFSWorkItem *)AFSLibExAllocatePoolWithTag( NonPagedPool,
2142 sizeof( AFSWorkItem),
2145 if( pWorkItem == NULL)
2148 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2149 AFS_TRACE_LEVEL_ERROR,
2150 "AFSQueueFlushExtents Failed to allocate work item\n");
2152 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2155 RtlZeroMemory( pWorkItem,
2156 sizeof( AFSWorkItem));
2158 pWorkItem->Size = sizeof( AFSWorkItem);
2160 pWorkItem->ProcessID = (ULONGLONG)PsGetCurrentProcessId();
2162 pWorkItem->RequestType = AFS_WORK_FLUSH_FCB;
2164 if ( AuthGroup == NULL)
2167 RtlZeroMemory( &pWorkItem->AuthGroup,
2170 ntStatus = AFSRetrieveValidAuthGroup( Fcb,
2173 &pWorkItem->AuthGroup);
2177 RtlCopyMemory( &pWorkItem->AuthGroup,
2182 pWorkItem->Specific.Fcb.Fcb = Fcb;
2184 lCount = InterlockedIncrement( &Fcb->OpenReferenceCount);
2186 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2187 AFS_TRACE_LEVEL_VERBOSE,
2188 "AFSQueueFlushExtents Increment count on Fcb %08lX Cnt %d\n",
2192 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2193 AFS_TRACE_LEVEL_VERBOSE,
2194 "AFSQueueFlushExtents Workitem %08lX for FID %08lX-%08lX-%08lX-%08lX\n",
2196 Fcb->ObjectInformation->FileId.Cell,
2197 Fcb->ObjectInformation->FileId.Volume,
2198 Fcb->ObjectInformation->FileId.Vnode,
2199 Fcb->ObjectInformation->FileId.Unique);
2201 ntStatus = AFSQueueWorkerRequest( pWorkItem);
2205 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2206 AFS_TRACE_LEVEL_VERBOSE,
2207 "AFSQueueFlushExtents Request complete Status %08lX FID %08lX-%08lX-%08lX-%08lX\n",
2208 Fcb->ObjectInformation->FileId.Cell,
2209 Fcb->ObjectInformation->FileId.Volume,
2210 Fcb->ObjectInformation->FileId.Vnode,
2211 Fcb->ObjectInformation->FileId.Unique,
2215 // Remove the count we added above
2218 lCount = InterlockedDecrement( &Fcb->Specific.File.QueuedFlushCount);
2223 KeSetEvent( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
2228 if( !NT_SUCCESS( ntStatus))
2231 if( pWorkItem != NULL)
2234 lCount = InterlockedDecrement( &Fcb->OpenReferenceCount);
2236 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2239 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2240 AFS_TRACE_LEVEL_ERROR,
2241 "AFSQueueFlushExtents Failed to queue request Status %08lX\n", ntStatus);
2244 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2249 "EXCEPTION - AFSQueueFlushExtents\n");
2251 AFSDumpTraceFilesFnc();
2258 AFSQueueAsyncRead( IN PDEVICE_OBJECT DeviceObject,
2260 IN HANDLE CallerProcess)
2263 NTSTATUS ntStatus = STATUS_SUCCESS;
2264 AFSWorkItem *pWorkItem = NULL;
2269 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2270 AFS_TRACE_LEVEL_VERBOSE,
2271 "AFSQueueAsyncRead Queuing request for Irp %08lX\n",
2274 pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
2275 sizeof(AFSWorkItem),
2277 if (NULL == pWorkItem)
2280 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2281 AFS_TRACE_LEVEL_ERROR,
2282 "AFSQueueAsyncRead Failed to allocate work item\n");
2284 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
2287 RtlZeroMemory( pWorkItem,
2288 sizeof(AFSWorkItem));
2290 pWorkItem->Size = sizeof( AFSWorkItem);
2292 pWorkItem->RequestType = AFS_WORK_ASYNCH_READ;
2294 pWorkItem->Specific.AsynchIo.Device = DeviceObject;
2296 pWorkItem->Specific.AsynchIo.Irp = Irp;
2298 pWorkItem->Specific.AsynchIo.CallingProcess = CallerProcess;
2300 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2301 AFS_TRACE_LEVEL_VERBOSE,
2302 "AFSQueueAsyncRead Workitem %08lX for Irp %08lX\n",
2306 ntStatus = AFSQueueWorkerRequest( pWorkItem);
2310 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2311 AFS_TRACE_LEVEL_VERBOSE,
2312 "AFSQueueAsyncRead Request for Irp %08lX complete Status %08lX\n",
2316 if( !NT_SUCCESS( ntStatus))
2319 if( pWorkItem != NULL)
2322 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2325 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2326 AFS_TRACE_LEVEL_ERROR,
2327 "AFSQueueAsyncRead Failed to queue request Status %08lX\n", ntStatus);
2330 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2335 "EXCEPTION - AFSQueueAsyncRead\n");
2337 AFSDumpTraceFilesFnc();
2344 AFSQueueAsyncWrite( IN PDEVICE_OBJECT DeviceObject,
2346 IN HANDLE CallerProcess)
2349 NTSTATUS ntStatus = STATUS_SUCCESS;
2350 AFSWorkItem *pWorkItem = NULL;
2355 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2356 AFS_TRACE_LEVEL_VERBOSE,
2357 "AFSQueueAsyncWrite Queuing request for Irp %08lX\n",
2360 pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
2361 sizeof(AFSWorkItem),
2363 if (NULL == pWorkItem)
2366 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2367 AFS_TRACE_LEVEL_ERROR,
2368 "AFSQueueAsyncWrite Failed to allocate work item\n");
2370 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
2373 RtlZeroMemory( pWorkItem,
2374 sizeof(AFSWorkItem));
2376 pWorkItem->Size = sizeof( AFSWorkItem);
2378 pWorkItem->RequestType = AFS_WORK_ASYNCH_WRITE;
2380 pWorkItem->Specific.AsynchIo.Device = DeviceObject;
2382 pWorkItem->Specific.AsynchIo.Irp = Irp;
2384 pWorkItem->Specific.AsynchIo.CallingProcess = CallerProcess;
2386 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2387 AFS_TRACE_LEVEL_VERBOSE,
2388 "AFSQueueAsyncWrite Workitem %08lX for Irp %08lX\n",
2392 ntStatus = AFSQueueWorkerRequest( pWorkItem);
2396 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2397 AFS_TRACE_LEVEL_VERBOSE,
2398 "AFSQueueAsyncWrite Request for Irp %08lX complete Status %08lX\n",
2402 if( !NT_SUCCESS( ntStatus))
2405 if( pWorkItem != NULL)
2408 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2411 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2412 AFS_TRACE_LEVEL_ERROR,
2413 "AFSQueueAsyncWrite Failed to queue request Status %08lX\n", ntStatus);
2416 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2421 "EXCEPTION - AFSQueueAsyncWrite\n");
2423 AFSDumpTraceFilesFnc();
2430 AFSQueueGlobalRootEnumeration()
2433 NTSTATUS ntStatus = STATUS_SUCCESS;
2434 AFSWorkItem *pWorkItem = NULL;
2439 pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
2440 sizeof(AFSWorkItem),
2442 if (NULL == pWorkItem)
2445 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2446 AFS_TRACE_LEVEL_ERROR,
2447 "AFSQueueGlobalRootEnumeration Failed to allocate work item\n");
2449 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
2452 RtlZeroMemory( pWorkItem,
2453 sizeof(AFSWorkItem));
2455 pWorkItem->Size = sizeof( AFSWorkItem);
2457 pWorkItem->RequestType = AFS_WORK_ENUMERATE_GLOBAL_ROOT;
2459 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2460 AFS_TRACE_LEVEL_VERBOSE,
2461 "AFSQueueGlobalRootEnumeration Workitem %08lX\n",
2464 ntStatus = AFSQueueWorkerRequest( pWorkItem);
2468 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2469 AFS_TRACE_LEVEL_VERBOSE,
2470 "AFSQueueGlobalRootEnumeration Request complete Status %08lX\n",
2473 if( !NT_SUCCESS( ntStatus))
2476 if( pWorkItem != NULL)
2479 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2482 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2483 AFS_TRACE_LEVEL_ERROR,
2484 "AFSQueueGlobalRootEnumeration Failed to queue request Status %08lX\n",
2488 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2493 "EXCEPTION - AFSQueueGlobalRootEnumeration\n");
2495 AFSDumpTraceFilesFnc();
2502 AFSQueueStartIos( IN PFILE_OBJECT CacheFileObject,
2503 IN UCHAR FunctionCode,
2504 IN ULONG RequestFlags,
2505 IN AFSIoRun *IoRuns,
2507 IN AFSGatherIo *GatherIo)
2510 NTSTATUS ntStatus = STATUS_SUCCESS;
2511 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2512 AFSWorkItem *pWorkItem = NULL;
2517 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
2520 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2521 AFS_TRACE_LEVEL_ERROR,
2522 "AFSQueueStartIos Failing request, in shutdown\n");
2524 try_return( ntStatus = STATUS_TOO_LATE);
2528 // Allocate our request structure and send it to the worker
2531 pWorkItem = (AFSWorkItem *)AFSLibExAllocatePoolWithTag( NonPagedPool,
2532 sizeof( AFSWorkItem),
2535 if( pWorkItem == NULL)
2538 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2539 AFS_TRACE_LEVEL_ERROR,
2540 "AFSQueueStartIos Failed to allocate work item\n");
2542 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2545 RtlZeroMemory( pWorkItem,
2546 sizeof( AFSWorkItem));
2548 KeInitializeEvent( &pWorkItem->Event,
2552 pWorkItem->Size = sizeof( AFSWorkItem);
2554 pWorkItem->ProcessID = (ULONGLONG)PsGetCurrentProcessId();
2556 pWorkItem->RequestType = AFS_WORK_START_IOS;
2558 pWorkItem->Specific.CacheAccess.CacheFileObject = CacheFileObject;
2560 pWorkItem->Specific.CacheAccess.FunctionCode = FunctionCode;
2562 pWorkItem->Specific.CacheAccess.RequestFlags = RequestFlags;
2564 pWorkItem->Specific.CacheAccess.IoRuns = IoRuns;
2566 pWorkItem->Specific.CacheAccess.RunCount = RunCount;
2568 pWorkItem->Specific.CacheAccess.GatherIo = GatherIo;
2570 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2571 AFS_TRACE_LEVEL_VERBOSE,
2572 "AFSQueueStartIos Queuing IO Workitem %08lX\n",
2575 ntStatus = AFSQueueIOWorkerRequest( pWorkItem);
2579 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2580 AFS_TRACE_LEVEL_VERBOSE,
2581 "AFSQueueStartIos Request complete Status %08lX\n",
2584 if( !NT_SUCCESS( ntStatus))
2587 if( pWorkItem != NULL)
2590 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2594 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2599 "EXCEPTION - AFSQueueStartIos\n");
2601 AFSDumpTraceFilesFnc();
2608 AFSQueueInvalidateObject( IN AFSObjectInfoCB *ObjectInfo,
2609 IN ULONG InvalidateReason)
2612 NTSTATUS ntStatus = STATUS_SUCCESS;
2613 AFSWorkItem *pWorkItem = NULL;
2618 pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
2619 sizeof(AFSWorkItem),
2621 if (NULL == pWorkItem)
2624 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2625 AFS_TRACE_LEVEL_ERROR,
2626 "AFSQueueInvalidateObject Failed to allocate work item\n");
2628 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
2631 RtlZeroMemory( pWorkItem,
2632 sizeof(AFSWorkItem));
2634 pWorkItem->Size = sizeof( AFSWorkItem);
2636 pWorkItem->RequestType = AFS_WORK_INVALIDATE_OBJECT;
2638 pWorkItem->Specific.Invalidate.ObjectInfo = ObjectInfo;
2640 pWorkItem->Specific.Invalidate.InvalidateReason = InvalidateReason;
2642 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2643 AFS_TRACE_LEVEL_VERBOSE,
2644 "AFSQueueInvalidateObject Workitem %08lX\n",
2647 ntStatus = AFSQueueWorkerRequest( pWorkItem);
2651 AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
2652 AFS_TRACE_LEVEL_VERBOSE,
2653 "AFSQueueInvalidateObject Request complete Status %08lX\n",
2656 if( !NT_SUCCESS( ntStatus))
2659 if( pWorkItem != NULL)
2661 ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
2664 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2665 AFS_TRACE_LEVEL_ERROR,
2666 "AFSQueueInvalidateObject Failed to queue request Status %08lX\n",
2670 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
2675 "EXCEPTION - AFSQueueInvalidateObject\n");
2677 AFSDumpTraceFilesFnc();