reactos/ntoskrnl/include/internal/cc.h
2021-06-22 10:33:45 +02:00

511 lines
11 KiB
C

#pragma once
//
// Define this if you want debugging support
//
#define _CC_DEBUG_ 0x00
//
// These define the Debug Masks Supported
//
#define CC_API_DEBUG 0x01
//
// Debug/Tracing support
//
#if _CC_DEBUG_
#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
#define CCTRACE(x, ...) \
{ \
DbgPrintEx("%s [%.16s] - ", \
__FUNCTION__, \
PsGetCurrentProcess()->ImageFileName); \
DbgPrintEx(__VA_ARGS__); \
}
#else
#define CCTRACE(x, ...) \
if (x & CcRosTraceLevel) \
{ \
DbgPrint("%s [%.16s] - ", \
__FUNCTION__, \
PsGetCurrentProcess()->ImageFileName); \
DbgPrint(__VA_ARGS__); \
}
#endif
#else
#define CCTRACE(x, fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
#endif
//
// Global Cc Data
//
extern ULONG CcRosTraceLevel;
extern LIST_ENTRY DirtyVacbListHead;
extern ULONG CcDirtyPageThreshold;
extern ULONG CcTotalDirtyPages;
extern LIST_ENTRY CcDeferredWrites;
extern KSPIN_LOCK CcDeferredWriteSpinLock;
extern ULONG CcNumberWorkerThreads;
extern LIST_ENTRY CcIdleWorkerThreadList;
extern LIST_ENTRY CcExpressWorkQueue;
extern LIST_ENTRY CcRegularWorkQueue;
extern LIST_ENTRY CcPostTickWorkQueue;
extern NPAGED_LOOKASIDE_LIST CcTwilightLookasideList;
extern LARGE_INTEGER CcIdleDelay;
//
// Counters
//
extern ULONG CcLazyWritePages;
extern ULONG CcLazyWriteIos;
extern ULONG CcMapDataWait;
extern ULONG CcMapDataNoWait;
extern ULONG CcPinReadWait;
extern ULONG CcPinReadNoWait;
extern ULONG CcPinMappedDataCount;
extern ULONG CcDataPages;
extern ULONG CcDataFlushes;
typedef struct _PF_SCENARIO_ID
{
WCHAR ScenName[30];
ULONG HashId;
} PF_SCENARIO_ID, *PPF_SCENARIO_ID;
typedef struct _PF_LOG_ENTRY
{
ULONG FileOffset:30;
ULONG Type:2;
union
{
ULONG FileKey;
ULONG FileSequenceNumber;
};
} PF_LOG_ENTRY, *PPF_LOG_ENTRY;
typedef struct _PFSN_LOG_ENTRIES
{
LIST_ENTRY TraceBuffersLink;
LONG NumEntries;
LONG MaxEntries;
PF_LOG_ENTRY Entries[ANYSIZE_ARRAY];
} PFSN_LOG_ENTRIES, *PPFSN_LOG_ENTRIES;
typedef struct _PF_SECTION_INFO
{
ULONG FileKey;
ULONG FileSequenceNumber;
ULONG FileIdLow;
ULONG FileIdHigh;
} PF_SECTION_INFO, *PPF_SECTION_INFO;
typedef struct _PF_TRACE_HEADER
{
ULONG Version;
ULONG MagicNumber;
ULONG Size;
PF_SCENARIO_ID ScenarioId;
ULONG ScenarioType; // PF_SCENARIO_TYPE
ULONG EventEntryIdxs[8];
ULONG NumEventEntryIdxs;
ULONG TraceBufferOffset;
ULONG NumEntries;
ULONG SectionInfoOffset;
ULONG NumSections;
ULONG FaultsPerPeriod[10];
LARGE_INTEGER LaunchTime;
ULONGLONG Reserved[5];
} PF_TRACE_HEADER, *PPF_TRACE_HEADER;
typedef struct _PFSN_TRACE_DUMP
{
LIST_ENTRY CompletedTracesLink;
PF_TRACE_HEADER Trace;
} PFSN_TRACE_DUMP, *PPFSN_TRACE_DUMP;
typedef struct _PFSN_TRACE_HEADER
{
ULONG Magic;
LIST_ENTRY ActiveTracesLink;
PF_SCENARIO_ID ScenarioId;
ULONG ScenarioType; // PF_SCENARIO_TYPE
ULONG EventEntryIdxs[8];
ULONG NumEventEntryIdxs;
PPFSN_LOG_ENTRIES CurrentTraceBuffer;
LIST_ENTRY TraceBuffersList;
ULONG NumTraceBuffers;
KSPIN_LOCK TraceBufferSpinLock;
KTIMER TraceTimer;
LARGE_INTEGER TraceTimerPeriod;
KDPC TraceTimerDpc;
KSPIN_LOCK TraceTimerSpinLock;
ULONG FaultsPerPeriod[10];
LONG LastNumFaults;
LONG CurPeriod;
LONG NumFaults;
LONG MaxFaults;
PEPROCESS Process;
EX_RUNDOWN_REF RefCount;
WORK_QUEUE_ITEM EndTraceWorkItem;
LONG EndTraceCalled;
PPFSN_TRACE_DUMP TraceDump;
NTSTATUS TraceDumpStatus;
LARGE_INTEGER LaunchTime;
PPF_SECTION_INFO SectionInfo;
ULONG SectionInfoCount;
} PFSN_TRACE_HEADER, *PPFSN_TRACE_HEADER;
typedef struct _PFSN_PREFETCHER_GLOBALS
{
LIST_ENTRY ActiveTraces;
KSPIN_LOCK ActiveTracesLock;
PPFSN_TRACE_HEADER SystemWideTrace;
LIST_ENTRY CompletedTraces;
FAST_MUTEX CompletedTracesLock;
LONG NumCompletedTraces;
PKEVENT CompletedTracesEvent;
LONG ActivePrefetches;
} PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS;
typedef struct _ROS_SHARED_CACHE_MAP
{
CSHORT NodeTypeCode;
CSHORT NodeByteSize;
ULONG OpenCount;
LARGE_INTEGER FileSize;
LIST_ENTRY BcbList;
LARGE_INTEGER SectionSize;
LARGE_INTEGER ValidDataLength;
PFILE_OBJECT FileObject;
ULONG DirtyPages;
LIST_ENTRY SharedCacheMapLinks;
ULONG Flags;
PVOID Section;
PKEVENT CreateEvent;
PCACHE_MANAGER_CALLBACKS Callbacks;
PVOID LazyWriteContext;
LIST_ENTRY PrivateList;
ULONG DirtyPageThreshold;
KSPIN_LOCK BcbSpinLock;
PRIVATE_CACHE_MAP PrivateCacheMap;
/* ROS specific */
LIST_ENTRY CacheMapVacbListHead;
BOOLEAN PinAccess;
KSPIN_LOCK CacheMapLock;
#if DBG
BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
#endif
} ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP;
#define READAHEAD_DISABLED 0x1
#define WRITEBEHIND_DISABLED 0x2
#define SHARED_CACHE_MAP_IN_CREATION 0x4
#define SHARED_CACHE_MAP_IN_LAZYWRITE 0x8
typedef struct _ROS_VACB
{
/* Base address of the region where the view's data is mapped. */
PVOID BaseAddress;
/* Are the contents of the view newer than those on disk. */
BOOLEAN Dirty;
/* Page out in progress */
BOOLEAN PageOut;
ULONG MappedCount;
/* Entry in the list of VACBs for this shared cache map. */
LIST_ENTRY CacheMapVacbListEntry;
/* Entry in the list of VACBs which are dirty. */
LIST_ENTRY DirtyVacbListEntry;
/* Entry in the list of VACBs. */
LIST_ENTRY VacbLruListEntry;
/* Offset in the file which this view maps. */
LARGE_INTEGER FileOffset;
/* Number of references. */
volatile ULONG ReferenceCount;
/* Pointer to the shared cache map for the file which this view maps data for. */
PROS_SHARED_CACHE_MAP SharedCacheMap;
/* Pointer to the next VACB in a chain. */
} ROS_VACB, *PROS_VACB;
typedef struct _INTERNAL_BCB
{
/* Lock */
ERESOURCE Lock;
PUBLIC_BCB PFCB;
PROS_VACB Vacb;
ULONG PinCount;
CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
LIST_ENTRY BcbEntry;
} INTERNAL_BCB, *PINTERNAL_BCB;
typedef struct _LAZY_WRITER
{
LIST_ENTRY WorkQueue;
KDPC ScanDpc;
KTIMER ScanTimer;
BOOLEAN ScanActive;
BOOLEAN OtherWork;
BOOLEAN PendingTeardown;
} LAZY_WRITER, *PLAZY_WRITER;
typedef struct _WORK_QUEUE_ENTRY
{
LIST_ENTRY WorkQueueLinks;
union
{
struct
{
FILE_OBJECT *FileObject;
} Read;
struct
{
SHARED_CACHE_MAP *SharedCacheMap;
} Write;
struct
{
KEVENT *Event;
} Event;
struct
{
unsigned long Reason;
} Notification;
} Parameters;
unsigned char Function;
} WORK_QUEUE_ENTRY, *PWORK_QUEUE_ENTRY;
typedef enum _WORK_QUEUE_FUNCTIONS
{
ReadAhead = 1,
WriteBehind = 2,
LazyScan = 3,
SetDone = 4,
} WORK_QUEUE_FUNCTIONS, *PWORK_QUEUE_FUNCTIONS;
extern LAZY_WRITER LazyWriter;
#define NODE_TYPE_DEFERRED_WRITE 0x02FC
#define NODE_TYPE_PRIVATE_MAP 0x02FE
#define NODE_TYPE_SHARED_MAP 0x02FF
CODE_SEG("INIT")
VOID
NTAPI
CcPfInitializePrefetcher(
VOID
);
VOID
NTAPI
CcMdlReadComplete2(
IN PFILE_OBJECT FileObject,
IN PMDL MemoryDescriptorList
);
VOID
NTAPI
CcMdlWriteComplete2(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PMDL MdlChain
);
NTSTATUS
CcRosFlushVacb(
_In_ PROS_VACB Vacb,
_Out_opt_ PIO_STATUS_BLOCK Iosb
);
NTSTATUS
CcRosGetVacb(
PROS_SHARED_CACHE_MAP SharedCacheMap,
LONGLONG FileOffset,
PROS_VACB *Vacb
);
BOOLEAN
CcRosEnsureVacbResident(
_In_ PROS_VACB Vacb,
_In_ BOOLEAN Wait,
_In_ BOOLEAN NoRead,
_In_ ULONG Offset,
_In_ ULONG Length
);
CODE_SEG("INIT")
VOID
NTAPI
CcInitView(VOID);
VOID
NTAPI
CcShutdownLazyWriter(VOID);
CODE_SEG("INIT")
BOOLEAN
CcInitializeCacheManager(VOID);
PROS_VACB
CcRosLookupVacb(
PROS_SHARED_CACHE_MAP SharedCacheMap,
LONGLONG FileOffset
);
VOID
NTAPI
CcInitCacheZeroPage(VOID);
VOID
CcRosMarkDirtyVacb(
PROS_VACB Vacb);
VOID
CcRosUnmarkDirtyVacb(
PROS_VACB Vacb,
BOOLEAN LockViews);
NTSTATUS
CcRosFlushDirtyPages(
ULONG Target,
PULONG Count,
BOOLEAN Wait,
BOOLEAN CalledFromLazy
);
VOID
CcRosDereferenceCache(PFILE_OBJECT FileObject);
VOID
CcRosReferenceCache(PFILE_OBJECT FileObject);
NTSTATUS
CcRosReleaseVacb(
PROS_SHARED_CACHE_MAP SharedCacheMap,
PROS_VACB Vacb,
BOOLEAN Dirty,
BOOLEAN Mapped
);
NTSTATUS
CcRosRequestVacb(
PROS_SHARED_CACHE_MAP SharedCacheMap,
LONGLONG FileOffset,
PROS_VACB *Vacb
);
NTSTATUS
CcRosInitializeFileCache(
PFILE_OBJECT FileObject,
PCC_FILE_SIZES FileSizes,
BOOLEAN PinAccess,
PCACHE_MANAGER_CALLBACKS CallBacks,
PVOID LazyWriterContext
);
NTSTATUS
CcRosReleaseFileCache(
PFILE_OBJECT FileObject
);
VOID
NTAPI
CcShutdownSystem(VOID);
VOID
NTAPI
CcWorkerThread(PVOID Parameter);
VOID
NTAPI
CcScanDpc(
PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2);
VOID
CcScheduleLazyWriteScan(BOOLEAN NoDelay);
VOID
CcPostDeferredWrites(VOID);
VOID
CcPostWorkQueue(
IN PWORK_QUEUE_ENTRY WorkItem,
IN PLIST_ENTRY WorkQueue);
VOID
CcPerformReadAhead(
IN PFILE_OBJECT FileObject);
NTSTATUS
CcRosInternalFreeVacb(
IN PROS_VACB Vacb);
FORCEINLINE
BOOLEAN
DoRangesIntersect(
_In_ LONGLONG Offset1,
_In_ LONGLONG Length1,
_In_ LONGLONG Offset2,
_In_ LONGLONG Length2)
{
if (Offset1 + Length1 <= Offset2)
return FALSE;
if (Offset2 + Length2 <= Offset1)
return FALSE;
return TRUE;
}
FORCEINLINE
BOOLEAN
IsPointInRange(
_In_ LONGLONG Offset1,
_In_ LONGLONG Length1,
_In_ LONGLONG Point)
{
return DoRangesIntersect(Offset1, Length1, Point, 1);
}
#define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C)
#if DBG
#define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
#define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
#define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__)
ULONG
CcRosVacbIncRefCount_(
PROS_VACB vacb,
PCSTR file,
INT line);
ULONG
CcRosVacbDecRefCount_(
PROS_VACB vacb,
PCSTR file,
INT line);
ULONG
CcRosVacbGetRefCount_(
PROS_VACB vacb,
PCSTR file,
INT line);
#else
#define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
FORCEINLINE
ULONG
CcRosVacbDecRefCount(
PROS_VACB vacb)
{
ULONG Refs;
Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount);
if (Refs == 0)
{
CcRosInternalFreeVacb(vacb);
}
return Refs;
}
#define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
#endif