xref: /reactos/ntoskrnl/include/internal/cc.h (revision cf4138fa)
1 #pragma once
2 
3 //
4 // Define this if you want debugging support
5 //
6 #define _CC_DEBUG_                                      0x00
7 
8 //
9 // These define the Debug Masks Supported
10 //
11 #define CC_API_DEBUG                                    0x01
12 
13 //
14 // Debug/Tracing support
15 //
16 #if _CC_DEBUG_
17 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
18 #define CCTRACE(x, ...)                                     \
19     {                                                       \
20         DbgPrintEx("%s [%.16s] - ",                         \
21                    __FUNCTION__,                            \
22                    PsGetCurrentProcess()->ImageFileName);   \
23         DbgPrintEx(__VA_ARGS__);                            \
24     }
25 #else
26 #define CCTRACE(x, ...)                                     \
27     if (x & CcRosTraceLevel)                                \
28     {                                                       \
29         DbgPrint("%s [%.16s] - ",                           \
30                  __FUNCTION__,                              \
31                  PsGetCurrentProcess()->ImageFileName);     \
32         DbgPrint(__VA_ARGS__);                              \
33     }
34 #endif
35 #else
36 #define CCTRACE(x, fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
37 #endif
38 
39 //
40 // Global Cc Data
41 //
42 extern ULONG CcRosTraceLevel;
43 extern LIST_ENTRY DirtyVacbListHead;
44 extern ULONG CcDirtyPageThreshold;
45 extern ULONG CcTotalDirtyPages;
46 extern LIST_ENTRY CcDeferredWrites;
47 extern KSPIN_LOCK CcDeferredWriteSpinLock;
48 extern ULONG CcNumberWorkerThreads;
49 extern LIST_ENTRY CcIdleWorkerThreadList;
50 extern LIST_ENTRY CcExpressWorkQueue;
51 extern LIST_ENTRY CcRegularWorkQueue;
52 extern LIST_ENTRY CcPostTickWorkQueue;
53 extern NPAGED_LOOKASIDE_LIST CcTwilightLookasideList;
54 extern LARGE_INTEGER CcIdleDelay;
55 
56 //
57 // Counters
58 //
59 extern ULONG CcLazyWritePages;
60 extern ULONG CcLazyWriteIos;
61 extern ULONG CcMapDataWait;
62 extern ULONG CcMapDataNoWait;
63 extern ULONG CcPinReadWait;
64 extern ULONG CcPinReadNoWait;
65 extern ULONG CcPinMappedDataCount;
66 extern ULONG CcDataPages;
67 extern ULONG CcDataFlushes;
68 
69 typedef struct _PF_SCENARIO_ID
70 {
71     WCHAR ScenName[30];
72     ULONG HashId;
73 } PF_SCENARIO_ID, *PPF_SCENARIO_ID;
74 
75 typedef struct _PF_LOG_ENTRY
76 {
77     ULONG FileOffset:30;
78     ULONG Type:2;
79     union
80     {
81         ULONG FileKey;
82         ULONG FileSequenceNumber;
83     };
84 } PF_LOG_ENTRY, *PPF_LOG_ENTRY;
85 
86 typedef struct _PFSN_LOG_ENTRIES
87 {
88     LIST_ENTRY TraceBuffersLink;
89     LONG NumEntries;
90     LONG MaxEntries;
91     PF_LOG_ENTRY Entries[ANYSIZE_ARRAY];
92 } PFSN_LOG_ENTRIES, *PPFSN_LOG_ENTRIES;
93 
94 typedef struct _PF_SECTION_INFO
95 {
96     ULONG FileKey;
97     ULONG FileSequenceNumber;
98     ULONG FileIdLow;
99     ULONG FileIdHigh;
100 } PF_SECTION_INFO, *PPF_SECTION_INFO;
101 
102 typedef struct _PF_TRACE_HEADER
103 {
104     ULONG Version;
105     ULONG MagicNumber;
106     ULONG Size;
107     PF_SCENARIO_ID ScenarioId;
108     ULONG ScenarioType; // PF_SCENARIO_TYPE
109     ULONG EventEntryIdxs[8];
110     ULONG NumEventEntryIdxs;
111     ULONG TraceBufferOffset;
112     ULONG NumEntries;
113     ULONG SectionInfoOffset;
114     ULONG NumSections;
115     ULONG FaultsPerPeriod[10];
116     LARGE_INTEGER LaunchTime;
117     ULONGLONG Reserved[5];
118 } PF_TRACE_HEADER, *PPF_TRACE_HEADER;
119 
120 typedef struct _PFSN_TRACE_DUMP
121 {
122     LIST_ENTRY CompletedTracesLink;
123     PF_TRACE_HEADER Trace;
124 } PFSN_TRACE_DUMP, *PPFSN_TRACE_DUMP;
125 
126 typedef struct _PFSN_TRACE_HEADER
127 {
128     ULONG Magic;
129     LIST_ENTRY ActiveTracesLink;
130     PF_SCENARIO_ID ScenarioId;
131     ULONG ScenarioType; // PF_SCENARIO_TYPE
132     ULONG EventEntryIdxs[8];
133     ULONG NumEventEntryIdxs;
134     PPFSN_LOG_ENTRIES CurrentTraceBuffer;
135     LIST_ENTRY TraceBuffersList;
136     ULONG NumTraceBuffers;
137     KSPIN_LOCK TraceBufferSpinLock;
138     KTIMER TraceTimer;
139     LARGE_INTEGER TraceTimerPeriod;
140     KDPC TraceTimerDpc;
141     KSPIN_LOCK TraceTimerSpinLock;
142     ULONG FaultsPerPeriod[10];
143     LONG LastNumFaults;
144     LONG CurPeriod;
145     LONG NumFaults;
146     LONG MaxFaults;
147     PEPROCESS Process;
148     EX_RUNDOWN_REF RefCount;
149     WORK_QUEUE_ITEM EndTraceWorkItem;
150     LONG EndTraceCalled;
151     PPFSN_TRACE_DUMP TraceDump;
152     NTSTATUS TraceDumpStatus;
153     LARGE_INTEGER LaunchTime;
154     PPF_SECTION_INFO SectionInfo;
155     ULONG SectionInfoCount;
156 } PFSN_TRACE_HEADER, *PPFSN_TRACE_HEADER;
157 
158 typedef struct _PFSN_PREFETCHER_GLOBALS
159 {
160     LIST_ENTRY ActiveTraces;
161     KSPIN_LOCK ActiveTracesLock;
162     PPFSN_TRACE_HEADER SystemWideTrace;
163     LIST_ENTRY CompletedTraces;
164     FAST_MUTEX CompletedTracesLock;
165     LONG NumCompletedTraces;
166     PKEVENT CompletedTracesEvent;
167     LONG ActivePrefetches;
168 } PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS;
169 
170 typedef struct _ROS_SHARED_CACHE_MAP
171 {
172     CSHORT NodeTypeCode;
173     CSHORT NodeByteSize;
174     ULONG OpenCount;
175     LARGE_INTEGER FileSize;
176     LIST_ENTRY BcbList;
177     LARGE_INTEGER SectionSize;
178     LARGE_INTEGER ValidDataLength;
179     PFILE_OBJECT FileObject;
180     ULONG DirtyPages;
181     LIST_ENTRY SharedCacheMapLinks;
182     ULONG Flags;
183     PVOID Section;
184     PKEVENT CreateEvent;
185     PCACHE_MANAGER_CALLBACKS Callbacks;
186     PVOID LazyWriteContext;
187     LIST_ENTRY PrivateList;
188     ULONG DirtyPageThreshold;
189     KSPIN_LOCK BcbSpinLock;
190     PRIVATE_CACHE_MAP PrivateCacheMap;
191 
192     /* ROS specific */
193     LIST_ENTRY CacheMapVacbListHead;
194     BOOLEAN PinAccess;
195     KSPIN_LOCK CacheMapLock;
196     KGUARDED_MUTEX FlushCacheLock;
197 #if DBG
198     BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
199 #endif
200 } ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP;
201 
202 #define READAHEAD_DISABLED 0x1
203 #define WRITEBEHIND_DISABLED 0x2
204 #define SHARED_CACHE_MAP_IN_CREATION 0x4
205 #define SHARED_CACHE_MAP_IN_LAZYWRITE 0x8
206 
207 typedef struct _ROS_VACB
208 {
209     /* Base address of the region where the view's data is mapped. */
210     PVOID BaseAddress;
211     /* Are the contents of the view newer than those on disk. */
212     BOOLEAN Dirty;
213     /* Page out in progress */
214     BOOLEAN PageOut;
215     ULONG MappedCount;
216     /* Entry in the list of VACBs for this shared cache map. */
217     LIST_ENTRY CacheMapVacbListEntry;
218     /* Entry in the list of VACBs which are dirty. */
219     LIST_ENTRY DirtyVacbListEntry;
220     /* Entry in the list of VACBs. */
221     LIST_ENTRY VacbLruListEntry;
222     /* Offset in the file which this view maps. */
223     LARGE_INTEGER FileOffset;
224     /* Number of references. */
225     volatile ULONG ReferenceCount;
226     /* Pointer to the shared cache map for the file which this view maps data for. */
227     PROS_SHARED_CACHE_MAP SharedCacheMap;
228     /* Pointer to the next VACB in a chain. */
229 } ROS_VACB, *PROS_VACB;
230 
231 typedef struct _INTERNAL_BCB
232 {
233     /* Lock */
234     ERESOURCE Lock;
235     PUBLIC_BCB PFCB;
236     PROS_VACB Vacb;
237     ULONG PinCount;
238     CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
239     LIST_ENTRY BcbEntry;
240 } INTERNAL_BCB, *PINTERNAL_BCB;
241 
242 typedef struct _LAZY_WRITER
243 {
244     LIST_ENTRY WorkQueue;
245     KDPC ScanDpc;
246     KTIMER ScanTimer;
247     BOOLEAN ScanActive;
248     BOOLEAN OtherWork;
249     BOOLEAN PendingTeardown;
250 } LAZY_WRITER, *PLAZY_WRITER;
251 
252 typedef struct _WORK_QUEUE_ENTRY
253 {
254     LIST_ENTRY WorkQueueLinks;
255     union
256     {
257         struct
258         {
259             FILE_OBJECT *FileObject;
260         } Read;
261         struct
262         {
263             SHARED_CACHE_MAP *SharedCacheMap;
264         } Write;
265         struct
266         {
267             KEVENT *Event;
268         } Event;
269         struct
270         {
271             unsigned long Reason;
272         } Notification;
273     } Parameters;
274     unsigned char Function;
275 } WORK_QUEUE_ENTRY, *PWORK_QUEUE_ENTRY;
276 
277 typedef enum _WORK_QUEUE_FUNCTIONS
278 {
279     ReadAhead = 1,
280     WriteBehind = 2,
281     LazyScan = 3,
282     SetDone = 4,
283 } WORK_QUEUE_FUNCTIONS, *PWORK_QUEUE_FUNCTIONS;
284 
285 extern LAZY_WRITER LazyWriter;
286 
287 #define NODE_TYPE_DEFERRED_WRITE 0x02FC
288 #define NODE_TYPE_PRIVATE_MAP    0x02FE
289 #define NODE_TYPE_SHARED_MAP     0x02FF
290 
291 CODE_SEG("INIT")
292 VOID
293 NTAPI
294 CcPfInitializePrefetcher(
295     VOID
296 );
297 
298 VOID
299 NTAPI
300 CcMdlReadComplete2(
301     IN PFILE_OBJECT FileObject,
302     IN PMDL MemoryDescriptorList
303 );
304 
305 VOID
306 NTAPI
307 CcMdlWriteComplete2(
308     IN PFILE_OBJECT FileObject,
309     IN PLARGE_INTEGER FileOffset,
310     IN PMDL MdlChain
311 );
312 
313 NTSTATUS
314 CcRosFlushVacb(
315     _In_ PROS_VACB Vacb,
316     _Out_opt_ PIO_STATUS_BLOCK Iosb
317 );
318 
319 NTSTATUS
320 CcRosGetVacb(
321     PROS_SHARED_CACHE_MAP SharedCacheMap,
322     LONGLONG FileOffset,
323     PROS_VACB *Vacb
324 );
325 
326 BOOLEAN
327 CcRosEnsureVacbResident(
328     _In_ PROS_VACB Vacb,
329     _In_ BOOLEAN Wait,
330     _In_ BOOLEAN NoRead,
331     _In_ ULONG Offset,
332     _In_ ULONG Length
333 );
334 
335 CODE_SEG("INIT")
336 VOID
337 NTAPI
338 CcInitView(VOID);
339 
340 VOID
341 NTAPI
342 CcShutdownLazyWriter(VOID);
343 
344 CODE_SEG("INIT")
345 BOOLEAN
346 CcInitializeCacheManager(VOID);
347 
348 PROS_VACB
349 CcRosLookupVacb(
350     PROS_SHARED_CACHE_MAP SharedCacheMap,
351     LONGLONG FileOffset
352 );
353 
354 VOID
355 NTAPI
356 CcInitCacheZeroPage(VOID);
357 
358 VOID
359 CcRosMarkDirtyVacb(
360     PROS_VACB Vacb);
361 
362 VOID
363 CcRosUnmarkDirtyVacb(
364     PROS_VACB Vacb,
365     BOOLEAN LockViews);
366 
367 NTSTATUS
368 CcRosFlushDirtyPages(
369     ULONG Target,
370     PULONG Count,
371     BOOLEAN Wait,
372     BOOLEAN CalledFromLazy
373 );
374 
375 VOID
376 CcRosDereferenceCache(PFILE_OBJECT FileObject);
377 
378 VOID
379 CcRosReferenceCache(PFILE_OBJECT FileObject);
380 
381 NTSTATUS
382 CcRosReleaseVacb(
383     PROS_SHARED_CACHE_MAP SharedCacheMap,
384     PROS_VACB Vacb,
385     BOOLEAN Dirty,
386     BOOLEAN Mapped
387 );
388 
389 NTSTATUS
390 CcRosRequestVacb(
391     PROS_SHARED_CACHE_MAP SharedCacheMap,
392     LONGLONG FileOffset,
393     PROS_VACB *Vacb
394 );
395 
396 NTSTATUS
397 CcRosInitializeFileCache(
398     PFILE_OBJECT FileObject,
399     PCC_FILE_SIZES FileSizes,
400     BOOLEAN PinAccess,
401     PCACHE_MANAGER_CALLBACKS CallBacks,
402     PVOID LazyWriterContext
403 );
404 
405 NTSTATUS
406 CcRosReleaseFileCache(
407     PFILE_OBJECT FileObject
408 );
409 
410 VOID
411 NTAPI
412 CcShutdownSystem(VOID);
413 
414 VOID
415 NTAPI
416 CcWorkerThread(PVOID Parameter);
417 
418 VOID
419 NTAPI
420 CcScanDpc(
421     PKDPC Dpc,
422     PVOID DeferredContext,
423     PVOID SystemArgument1,
424     PVOID SystemArgument2);
425 
426 VOID
427 CcScheduleLazyWriteScan(BOOLEAN NoDelay);
428 
429 VOID
430 CcPostDeferredWrites(VOID);
431 
432 VOID
433 CcPostWorkQueue(
434     IN PWORK_QUEUE_ENTRY WorkItem,
435     IN PLIST_ENTRY WorkQueue);
436 
437 VOID
438 CcPerformReadAhead(
439     IN PFILE_OBJECT FileObject);
440 
441 NTSTATUS
442 CcRosInternalFreeVacb(
443     IN PROS_VACB Vacb);
444 
445 FORCEINLINE
446 BOOLEAN
DoRangesIntersect(_In_ LONGLONG Offset1,_In_ LONGLONG Length1,_In_ LONGLONG Offset2,_In_ LONGLONG Length2)447 DoRangesIntersect(
448     _In_ LONGLONG Offset1,
449     _In_ LONGLONG Length1,
450     _In_ LONGLONG Offset2,
451     _In_ LONGLONG Length2)
452 {
453     if (Offset1 + Length1 <= Offset2)
454         return FALSE;
455     if (Offset2 + Length2 <= Offset1)
456         return FALSE;
457     return TRUE;
458 }
459 
460 FORCEINLINE
461 BOOLEAN
IsPointInRange(_In_ LONGLONG Offset1,_In_ LONGLONG Length1,_In_ LONGLONG Point)462 IsPointInRange(
463     _In_ LONGLONG Offset1,
464     _In_ LONGLONG Length1,
465     _In_ LONGLONG Point)
466 {
467     return DoRangesIntersect(Offset1, Length1, Point, 1);
468 }
469 
470 #define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C)
471 
472 #if DBG
473 #define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
474 #define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
475 #define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__)
476 
477 ULONG
478 CcRosVacbIncRefCount_(
479     PROS_VACB vacb,
480     PCSTR file,
481     INT line);
482 
483 ULONG
484 CcRosVacbDecRefCount_(
485     PROS_VACB vacb,
486     PCSTR file,
487     INT line);
488 
489 ULONG
490 CcRosVacbGetRefCount_(
491     PROS_VACB vacb,
492     PCSTR file,
493     INT line);
494 
495 #else
496 #define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
497 FORCEINLINE
498 ULONG
CcRosVacbDecRefCount(PROS_VACB vacb)499 CcRosVacbDecRefCount(
500     PROS_VACB vacb)
501 {
502     ULONG Refs;
503 
504     Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount);
505     if (Refs == 0)
506     {
507         CcRosInternalFreeVacb(vacb);
508     }
509     return Refs;
510 }
511 #define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
512 #endif
513 
514 BOOLEAN
515 CcRosFreeOneUnusedVacb(
516     VOID);
517