/*++ Copyright (c) 1994 Microsoft Corporation Module Name: scavengr.h Abstract: This module defines data structures related to scavenging in the RDBSS Author: Balan Sethu Raman [SethuR] 9-Sep-1995 Revision History: Notes: The dormant file limit must be made configurable on a per server basis --*/ #ifndef _SCAVENGR_H_ #define _SCAVENGR_H_ // currently, only a single scavengermutex is across all scavenging operations // for all underlying deviceobjects extern KMUTEX RxScavengerMutex; // An instance of this data structure is embedded as part of those data structures // that are scavenged, i.e., FCB, RX_CONTEXT, etc. #define RX_SCAVENGER_ENTRY_TYPE_MARKER (0x0001) #define RX_SCAVENGER_ENTRY_TYPE_FCB (0x0002) #define RX_SCAVENGER_OP_PURGE (0x0001) #define RX_SCAVENGER_OP_CLOSE (0x0002) #define RX_SCAVENGER_INITIATED_OPERATION (0x0001) typedef enum _RX_SCAVENGER_ENTRY_STATE { RX_SCAVENGING_INACTIVE, RX_SCAVENGING_PENDING, RX_SCAVENGING_IN_PROGRESS, RX_SCAVENGING_AWAITING_RESPONSE } RX_SCAVENGER_ENTRY_STATE, *PRX_SCAVENGER_ENTRY_STATE; typedef struct _RX_SCAVENGER_ENTRY { // List of related items to be scavenged LIST_ENTRY List; UCHAR Type; UCHAR Operation; UCHAR State; UCHAR Flags; struct _RX_SCAVENGER_ENTRY *pContinuationEntry; } RX_SCAVENGER_ENTRY, *PRX_SCAVENGER_ENTRY; #define RxInitializeScavengerEntry(pScavengerEntry) \ (pScavengerEntry)->State = 0; \ (pScavengerEntry)->Flags = 0; \ (pScavengerEntry)->Type = 0; \ (pScavengerEntry)->Operation = 0; \ InitializeListHead(&(pScavengerEntry)->List); \ (pScavengerEntry)->pContinuationEntry = NULL #define RX_SCAVENGER_MUTEX_ACQUIRED (1) typedef enum _RDBSS_SCAVENGER_STATE { RDBSS_SCAVENGER_INACTIVE, RDBSS_SCAVENGER_DORMANT, RDBSS_SCAVENGER_ACTIVE, RDBSS_SCAVENGER_SUSPENDED } RDBSS_SCAVENGER_STATE, *PRDBSS_SCAVENGER_STATE; typedef struct _RDBSS_SCAVENGER { RDBSS_SCAVENGER_STATE State; LONG MaximumNumberOfDormantFiles; LONG NumberOfDormantFiles; ULONG SrvCallsToBeFinalized; ULONG NetRootsToBeFinalized; ULONG VNetRootsToBeFinalized; ULONG FcbsToBeFinalized; ULONG SrvOpensToBeFinalized; ULONG FobxsToBeFinalized; LIST_ENTRY SrvCallFinalizationList; LIST_ENTRY NetRootFinalizationList; LIST_ENTRY VNetRootFinalizationList; LIST_ENTRY FcbFinalizationList; LIST_ENTRY SrvOpenFinalizationList; LIST_ENTRY FobxFinalizationList; LIST_ENTRY ClosePendingFobxsList; RX_WORK_ITEM WorkItem; KEVENT SyncEvent; PETHREAD CurrentScavengerThread; PNET_ROOT CurrentNetRootForClosePendingProcessing; PFCB CurrentFcbForClosePendingProcessing; KEVENT ClosePendingProcessingSyncEvent; } RDBSS_SCAVENGER, *PRDBSS_SCAVENGER; #if 0 //this is not used anywhere typedef struct _RX_FCB_SCAVENGER_ { ULONG State; ULONG OperationsCompleted; PRX_SCAVENGER_ENTRY pLastActiveMarkerEntry; LIST_ENTRY OperationsPendingList; LIST_ENTRY OperationsInProgressList; LIST_ENTRY OperationsAwaitingResponseList; } RX_FCB_SCAVENGER, *PRX_FCB_SCAVENGER; #define RxInitializeFcbScavenger(pFcbScavenger) \ (pFcbScavenger)->pLastActiveMarkerEntry = NULL; \ (pFcbScavenger)->OperationsCompleted = 0; \ (pFcbScavenger)->State = 0; \ InitializeListHead(&(pFcbScavenger)->OperationsPendingList); \ InitializeListHead(&(pFcbScavenger)->OperationsInProgressList); \ InitializeListHead(&(pFcbScavenger)->OperationsAwaitingResponseList) #endif #define RxInitializeRdbssScavenger(pScavenger) \ (pScavenger)->State = RDBSS_SCAVENGER_INACTIVE; \ (pScavenger)->SrvCallsToBeFinalized = 0; \ (pScavenger)->NetRootsToBeFinalized = 0; \ (pScavenger)->VNetRootsToBeFinalized = 0; \ (pScavenger)->FcbsToBeFinalized = 0; \ (pScavenger)->SrvOpensToBeFinalized = 0; \ (pScavenger)->FobxsToBeFinalized = 0; \ (pScavenger)->NumberOfDormantFiles = 0; \ (pScavenger)->MaximumNumberOfDormantFiles = 50; \ (pScavenger)->CurrentFcbForClosePendingProcessing = NULL; \ (pScavenger)->CurrentNetRootForClosePendingProcessing = NULL; \ KeInitializeEvent(&((pScavenger)->SyncEvent),NotificationEvent,FALSE); \ KeInitializeEvent(&((pScavenger)->ClosePendingProcessingSyncEvent),NotificationEvent,FALSE); \ InitializeListHead(&(pScavenger)->SrvCallFinalizationList); \ InitializeListHead(&(pScavenger)->NetRootFinalizationList); \ InitializeListHead(&(pScavenger)->VNetRootFinalizationList); \ InitializeListHead(&(pScavenger)->SrvOpenFinalizationList); \ InitializeListHead(&(pScavenger)->FcbFinalizationList); \ InitializeListHead(&(pScavenger)->FobxFinalizationList); \ InitializeListHead(&(pScavenger)->ClosePendingFobxsList) #define RxAcquireScavengerMutex() \ KeWaitForSingleObject(&RxScavengerMutex,Executive,KernelMode,FALSE,NULL) #define RxReleaseScavengerMutex() \ KeReleaseMutex(&RxScavengerMutex,FALSE) extern NTSTATUS RxMarkFcbForScavengingAtCleanup(PFCB pFcb); extern NTSTATUS RxMarkFcbForScavengingAtClose(PFCB pFcb); extern VOID RxUpdateScavengerOnCloseCompletion(PFCB pFcb); extern VOID RxMarkFobxOnCleanup(PFOBX pFobx, BOOLEAN *pNeedPurge); extern VOID RxMarkFobxOnClose(PFOBX pFobx); extern NTSTATUS RxPurgeRelatedFobxs(PNET_ROOT pNetRoot,PRX_CONTEXT pRxContext,BOOLEAN AttemptFinalization,PFCB PurgingFcb); #define DONT_ATTEMPT_FINALIZE_ON_PURGE FALSE #define ATTEMPT_FINALIZE_ON_PURGE TRUE // // the purge_sync context is used to synchronize contexts that are attempting to purge... // notatbly creates and dirctrls. these are planted in various structures because various minirdrs // require different granularity of purge operations typedef struct _PURGE_SYNCHRONIZATION_CONTEXT { LIST_ENTRY ContextsAwaitingPurgeCompletion; // the list of purge requests active for this netroot. BOOLEAN PurgeInProgress; } PURGE_SYNCHRONIZATION_CONTEXT, *PPURGE_SYNCHRONIZATION_CONTEXT; VOID RxInitializePurgeSyncronizationContext ( PPURGE_SYNCHRONIZATION_CONTEXT PurgeSyncronizationContext ); extern NTSTATUS RxScavengeRelatedFcbs(PRX_CONTEXT pRxContext); extern BOOLEAN RxScavengeRelatedFobxs(PFCB pFcb); extern VOID RxScavengeFobxsForNetRoot( struct _NET_ROOT *pNetRoot, PFCB PurgingFcb); extern VOID RxpMarkInstanceForScavengedFinalization( PVOID pInstance); extern VOID RxpUndoScavengerFinalizationMarking( PVOID pInstance); extern VOID RxTerminateScavenging( PRX_CONTEXT pRxContext); extern BOOLEAN RxScavengeVNetRoots( PRDBSS_DEVICE_OBJECT RxDeviceObject); extern VOID RxSynchronizeWithScavenger( PRX_CONTEXT RxContext); #endif // _SCAVENGR_H_