[NTOSKRNL] Add the CcPinMappedDataCount counter
[reactos.git] / ntoskrnl / include / internal / cc.h
index 439ffa3..8a5fb73 100644 (file)
@@ -1,5 +1,71 @@
 #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];
@@ -101,67 +167,127 @@ typedef struct _PFSN_PREFETCHER_GLOBALS
     LONG ActivePrefetches;
 } PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS;
 
-typedef struct _BCB
+typedef struct _ROS_SHARED_CACHE_MAP
 {
-    LIST_ENTRY BcbSegmentListHead;
-    LIST_ENTRY BcbRemoveListEntry;
-    BOOLEAN RemoveOnClose;
-    ULONG TimeStamp;
-    PFILE_OBJECT FileObject;
-    LARGE_INTEGER AllocationSize;
+    CSHORT NodeTypeCode;
+    CSHORT NodeByteSize;
+    ULONG OpenCount;
     LARGE_INTEGER FileSize;
+    LIST_ENTRY BcbList;
+    LARGE_INTEGER SectionSize;
+    PFILE_OBJECT FileObject;
+    ULONG DirtyPages;
+    LIST_ENTRY SharedCacheMapLinks;
+    ULONG Flags;
     PCACHE_MANAGER_CALLBACKS Callbacks;
     PVOID LazyWriteContext;
-    KSPIN_LOCK BcbLock;
-    ULONG RefCount;
+    LIST_ENTRY PrivateList;
+    ULONG DirtyPageThreshold;
+    KSPIN_LOCK BcbSpinLock;
+    PRIVATE_CACHE_MAP PrivateCacheMap;
+
+    /* ROS specific */
+    LIST_ENTRY CacheMapVacbListHead;
+    ULONG TimeStamp;
+    BOOLEAN PinAccess;
+    KSPIN_LOCK CacheMapLock;
 #if DBG
-       BOOLEAN Trace; /* enable extra trace output for this BCB and it's cache segments */
+    BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
 #endif
-} BCB, *PBCB;
+} ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP;
 
-typedef struct _CACHE_SEGMENT
+#define READAHEAD_DISABLED 0x1
+#define WRITEBEHIND_DISABLED 0x2
+
+typedef struct _ROS_VACB
 {
-    /* Base address of the region where the cache segment data is mapped. */
+    /* Base address of the region where the view's data is mapped. */
     PVOID BaseAddress;
-    /*
-     * Memory area representing the region where the cache segment data is
-     * mapped.
-     */
+    /* Memory area representing the region where the view's data is mapped. */
     struct _MEMORY_AREA* MemoryArea;
-    /* Are the contents of the cache segment data valid. */
+    /* Are the contents of the view valid. */
     BOOLEAN Valid;
-    /* Are the contents of the cache segment data newer than those on disk. */
+    /* 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 segments for this BCB. */
-    LIST_ENTRY BcbSegmentListEntry;
-    /* Entry in the list of segments which are dirty. */
-    LIST_ENTRY DirtySegmentListEntry;
-    /* Entry in the list of segments. */
-    LIST_ENTRY CacheSegmentListEntry;
-    LIST_ENTRY CacheSegmentLRUListEntry;
-    /* Offset in the file which this cache segment maps. */
-    ULONG FileOffset;
-    /* Mutex */
-    KMUTEX Mutex;
+    /* 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. */
-    ULONG ReferenceCount;
-    /* Pointer to the BCB for the file which this cache segment maps data for. */
-    PBCB Bcb;
-    /* Pointer to the next cache segment in a chain. */
-    struct _CACHE_SEGMENT* NextInChain;
-} CACHE_SEGMENT, *PCACHE_SEGMENT;
+    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;
-    PCACHE_SEGMENT CacheSegment;
+    PROS_VACB Vacb;
     BOOLEAN Dirty;
+    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,
+    LazyWrite = 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
+
 VOID
 NTAPI
 CcPfInitializePrefetcher(
@@ -185,30 +311,34 @@ CcMdlWriteComplete2(
 
 NTSTATUS
 NTAPI
-CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment);
+CcRosFlushVacb(PROS_VACB Vacb);
 
 NTSTATUS
 NTAPI
-CcRosGetCacheSegment(
-    PBCB Bcb,
-    ULONG FileOffset,
-    PULONG BaseOffset,
+CcRosGetVacb(
+    PROS_SHARED_CACHE_MAP SharedCacheMap,
+    LONGLONG FileOffset,
+    PLONGLONG BaseOffset,
     PVOID *BaseAddress,
     PBOOLEAN UptoDate,
-    PCACHE_SEGMENT *CacheSeg
+    PROS_VACB *Vacb
 );
 
 VOID
 NTAPI
 CcInitView(VOID);
 
+VOID
+NTAPI
+CcShutdownLazyWriter(VOID);
+
 NTSTATUS
 NTAPI
-ReadCacheSegment(PCACHE_SEGMENT CacheSeg);
+CcReadVirtualAddress(PROS_VACB Vacb);
 
 NTSTATUS
 NTAPI
-WriteCacheSegment(PCACHE_SEGMENT CacheSeg);
+CcWriteVirtualAddress(PROS_VACB Vacb);
 
 BOOLEAN
 NTAPI
@@ -216,45 +346,48 @@ CcInitializeCacheManager(VOID);
 
 NTSTATUS
 NTAPI
-CcRosUnmapCacheSegment(
-    PBCB Bcb,
-    ULONG FileOffset,
+CcRosUnmapVacb(
+    PROS_SHARED_CACHE_MAP SharedCacheMap,
+    LONGLONG FileOffset,
     BOOLEAN NowDirty
 );
 
-PCACHE_SEGMENT
+PROS_VACB
 NTAPI
-CcRosLookupCacheSegment(
-    PBCB Bcb,
-    ULONG FileOffset
+CcRosLookupVacb(
+    PROS_SHARED_CACHE_MAP SharedCacheMap,
+    LONGLONG FileOffset
 );
 
+VOID
+NTAPI
+CcInitCacheZeroPage(VOID);
+
 NTSTATUS
 NTAPI
-CcRosGetCacheSegmentChain(
-    PBCB Bcb,
-    ULONG FileOffset,
-    ULONG Length,
-    PCACHE_SEGMENT* CacheSeg
+CcRosMarkDirtyFile(
+    PROS_SHARED_CACHE_MAP SharedCacheMap,
+    LONGLONG FileOffset
 );
 
 VOID
 NTAPI
-CcInitCacheZeroPage(VOID);
+CcRosMarkDirtyVacb(
+    PROS_VACB Vacb);
 
-NTSTATUS
+VOID
 NTAPI
-CcRosMarkDirtyCacheSegment(
-    PBCB Bcb,
-    ULONG FileOffset
-);
+CcRosUnmarkDirtyVacb(
+    PROS_VACB Vacb,
+    BOOLEAN LockViews);
 
 NTSTATUS
 NTAPI
 CcRosFlushDirtyPages(
     ULONG Target,
     PULONG Count,
-    BOOLEAN Wait
+    BOOLEAN Wait,
+    BOOLEAN CalledFromLazy
 );
 
 VOID
@@ -267,13 +400,13 @@ CcRosReferenceCache(PFILE_OBJECT FileObject);
 
 VOID
 NTAPI
-CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer);
+CcRosRemoveIfClosed(PSECTION_OBJECT_POINTERS SectionObjectPointer);
 
 NTSTATUS
 NTAPI
-CcRosReleaseCacheSegment(
-    BCB* Bcb,
-    CACHE_SEGMENT *CacheSeg,
+CcRosReleaseVacb(
+    PROS_SHARED_CACHE_MAP SharedCacheMap,
+    PROS_VACB Vacb,
     BOOLEAN Valid,
     BOOLEAN Dirty,
     BOOLEAN Mapped
@@ -281,18 +414,20 @@ CcRosReleaseCacheSegment(
 
 NTSTATUS
 NTAPI
-CcRosRequestCacheSegment(
-    BCB *Bcb,
-    ULONG FileOffset,
+CcRosRequestVacb(
+    PROS_SHARED_CACHE_MAP SharedCacheMap,
+    LONGLONG FileOffset,
     PVOID* BaseAddress,
     PBOOLEAN UptoDate,
-    CACHE_SEGMENT **CacheSeg
+    PROS_VACB *Vacb
 );
 
 NTSTATUS
 NTAPI
 CcRosInitializeFileCache(
     PFILE_OBJECT FileObject,
+    PCC_FILE_SIZES FileSizes,
+    BOOLEAN PinAccess,
     PCACHE_MANAGER_CALLBACKS CallBacks,
     PVOID LazyWriterContext
 );
@@ -303,17 +438,48 @@ CcRosReleaseFileCache(
     PFILE_OBJECT FileObject
 );
 
-NTSTATUS
+VOID
+NTAPI
+CcShutdownSystem(VOID);
+
+VOID
+NTAPI
+CcWorkerThread(PVOID Parameter);
+
+VOID
 NTAPI
-CcTryToInitializeFileCache(PFILE_OBJECT FileObject);
+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
-DoSegmentsIntersect(
-    _In_ ULONG Offset1,
-    _In_ ULONG Length1,
-    _In_ ULONG Offset2,
-    _In_ ULONG Length2)
+DoRangesIntersect(
+    _In_ LONGLONG Offset1,
+    _In_ LONGLONG Length1,
+    _In_ LONGLONG Offset2,
+    _In_ LONGLONG Length2)
 {
     if (Offset1 + Length1 <= Offset2)
         return FALSE;
@@ -324,10 +490,54 @@ DoSegmentsIntersect(
 
 FORCEINLINE
 BOOLEAN
-IsPointInSegment(
-    _In_ ULONG Offset1,
-    _In_ ULONG Length1,
-    _In_ ULONG Point)
+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)
 {
-    return DoSegmentsIntersect(Offset1, Length1, Point, 1);
+    ULONG Refs;
+
+    Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount);
+    if (Refs == 0)
+    {
+        CcRosInternalFreeVacb(vacb);
+    }
+    return Refs;
 }
+#define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
+#endif