xref: /reactos/ntoskrnl/include/internal/cc.h (revision c81af08f)
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     PFILE_OBJECT FileObject;
179     ULONG DirtyPages;
180     LIST_ENTRY SharedCacheMapLinks;
181     ULONG Flags;
182     PCACHE_MANAGER_CALLBACKS Callbacks;
183     PVOID LazyWriteContext;
184     LIST_ENTRY PrivateList;
185     ULONG DirtyPageThreshold;
186     KSPIN_LOCK BcbSpinLock;
187     PRIVATE_CACHE_MAP PrivateCacheMap;
188 
189     /* ROS specific */
190     LIST_ENTRY CacheMapVacbListHead;
191     BOOLEAN PinAccess;
192     KSPIN_LOCK CacheMapLock;
193 #if DBG
194     BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
195 #endif
196 } ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP;
197 
198 #define READAHEAD_DISABLED 0x1
199 #define WRITEBEHIND_DISABLED 0x2
200 
201 typedef struct _ROS_VACB
202 {
203     /* Base address of the region where the view's data is mapped. */
204     PVOID BaseAddress;
205     /* Memory area representing the region where the view's data is mapped. */
206     struct _MEMORY_AREA* MemoryArea;
207     /* Are the contents of the view valid. */
208     BOOLEAN Valid;
209     /* Are the contents of the view newer than those on disk. */
210     BOOLEAN Dirty;
211     /* Page out in progress */
212     BOOLEAN PageOut;
213     ULONG MappedCount;
214     /* Entry in the list of VACBs for this shared cache map. */
215     LIST_ENTRY CacheMapVacbListEntry;
216     /* Entry in the list of VACBs which are dirty. */
217     LIST_ENTRY DirtyVacbListEntry;
218     /* Entry in the list of VACBs. */
219     LIST_ENTRY VacbLruListEntry;
220     /* Offset in the file which this view maps. */
221     LARGE_INTEGER FileOffset;
222     /* Number of references. */
223     volatile ULONG ReferenceCount;
224     /* Pointer to the shared cache map for the file which this view maps data for. */
225     PROS_SHARED_CACHE_MAP SharedCacheMap;
226     /* Pointer to the next VACB in a chain. */
227 } ROS_VACB, *PROS_VACB;
228 
229 typedef struct _INTERNAL_BCB
230 {
231     /* Lock */
232     ERESOURCE Lock;
233     PUBLIC_BCB PFCB;
234     PROS_VACB Vacb;
235     ULONG PinCount;
236     CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
237     LIST_ENTRY BcbEntry;
238 } INTERNAL_BCB, *PINTERNAL_BCB;
239 
240 typedef struct _LAZY_WRITER
241 {
242     LIST_ENTRY WorkQueue;
243     KDPC ScanDpc;
244     KTIMER ScanTimer;
245     BOOLEAN ScanActive;
246     BOOLEAN OtherWork;
247     BOOLEAN PendingTeardown;
248 } LAZY_WRITER, *PLAZY_WRITER;
249 
250 typedef struct _WORK_QUEUE_ENTRY
251 {
252     LIST_ENTRY WorkQueueLinks;
253     union
254     {
255         struct
256         {
257             FILE_OBJECT *FileObject;
258         } Read;
259         struct
260         {
261             SHARED_CACHE_MAP *SharedCacheMap;
262         } Write;
263         struct
264         {
265             KEVENT *Event;
266         } Event;
267         struct
268         {
269             unsigned long Reason;
270         } Notification;
271     } Parameters;
272     unsigned char Function;
273 } WORK_QUEUE_ENTRY, *PWORK_QUEUE_ENTRY;
274 
275 typedef enum _WORK_QUEUE_FUNCTIONS
276 {
277     ReadAhead = 1,
278     WriteBehind = 2,
279     LazyScan = 3,
280     SetDone = 4,
281 } WORK_QUEUE_FUNCTIONS, *PWORK_QUEUE_FUNCTIONS;
282 
283 extern LAZY_WRITER LazyWriter;
284 
285 #define NODE_TYPE_DEFERRED_WRITE 0x02FC
286 #define NODE_TYPE_PRIVATE_MAP    0x02FE
287 #define NODE_TYPE_SHARED_MAP     0x02FF
288 
289 INIT_FUNCTION
290 VOID
291 NTAPI
292 CcPfInitializePrefetcher(
293     VOID
294 );
295 
296 VOID
297 NTAPI
298 CcMdlReadComplete2(
299     IN PFILE_OBJECT FileObject,
300     IN PMDL MemoryDescriptorList
301 );
302 
303 VOID
304 NTAPI
305 CcMdlWriteComplete2(
306     IN PFILE_OBJECT FileObject,
307     IN PLARGE_INTEGER FileOffset,
308     IN PMDL MdlChain
309 );
310 
311 NTSTATUS
312 NTAPI
313 CcRosFlushVacb(PROS_VACB Vacb);
314 
315 NTSTATUS
316 NTAPI
317 CcRosGetVacb(
318     PROS_SHARED_CACHE_MAP SharedCacheMap,
319     LONGLONG FileOffset,
320     PLONGLONG BaseOffset,
321     PVOID *BaseAddress,
322     PBOOLEAN UptoDate,
323     PROS_VACB *Vacb
324 );
325 
326 INIT_FUNCTION
327 VOID
328 NTAPI
329 CcInitView(VOID);
330 
331 VOID
332 NTAPI
333 CcShutdownLazyWriter(VOID);
334 
335 NTSTATUS
336 NTAPI
337 CcReadVirtualAddress(PROS_VACB Vacb);
338 
339 NTSTATUS
340 NTAPI
341 CcWriteVirtualAddress(PROS_VACB Vacb);
342 
343 INIT_FUNCTION
344 BOOLEAN
345 NTAPI
346 CcInitializeCacheManager(VOID);
347 
348 NTSTATUS
349 NTAPI
350 CcRosUnmapVacb(
351     PROS_SHARED_CACHE_MAP SharedCacheMap,
352     LONGLONG FileOffset,
353     BOOLEAN NowDirty
354 );
355 
356 PROS_VACB
357 NTAPI
358 CcRosLookupVacb(
359     PROS_SHARED_CACHE_MAP SharedCacheMap,
360     LONGLONG FileOffset
361 );
362 
363 VOID
364 NTAPI
365 CcInitCacheZeroPage(VOID);
366 
367 NTSTATUS
368 NTAPI
369 CcRosMarkDirtyFile(
370     PROS_SHARED_CACHE_MAP SharedCacheMap,
371     LONGLONG FileOffset
372 );
373 
374 VOID
375 NTAPI
376 CcRosMarkDirtyVacb(
377     PROS_VACB Vacb);
378 
379 VOID
380 NTAPI
381 CcRosUnmarkDirtyVacb(
382     PROS_VACB Vacb,
383     BOOLEAN LockViews);
384 
385 NTSTATUS
386 NTAPI
387 CcRosFlushDirtyPages(
388     ULONG Target,
389     PULONG Count,
390     BOOLEAN Wait,
391     BOOLEAN CalledFromLazy
392 );
393 
394 VOID
395 NTAPI
396 CcRosDereferenceCache(PFILE_OBJECT FileObject);
397 
398 VOID
399 NTAPI
400 CcRosReferenceCache(PFILE_OBJECT FileObject);
401 
402 VOID
403 NTAPI
404 CcRosRemoveIfClosed(PSECTION_OBJECT_POINTERS SectionObjectPointer);
405 
406 NTSTATUS
407 NTAPI
408 CcRosReleaseVacb(
409     PROS_SHARED_CACHE_MAP SharedCacheMap,
410     PROS_VACB Vacb,
411     BOOLEAN Valid,
412     BOOLEAN Dirty,
413     BOOLEAN Mapped
414 );
415 
416 NTSTATUS
417 NTAPI
418 CcRosRequestVacb(
419     PROS_SHARED_CACHE_MAP SharedCacheMap,
420     LONGLONG FileOffset,
421     PVOID* BaseAddress,
422     PBOOLEAN UptoDate,
423     PROS_VACB *Vacb
424 );
425 
426 NTSTATUS
427 NTAPI
428 CcRosInitializeFileCache(
429     PFILE_OBJECT FileObject,
430     PCC_FILE_SIZES FileSizes,
431     BOOLEAN PinAccess,
432     PCACHE_MANAGER_CALLBACKS CallBacks,
433     PVOID LazyWriterContext
434 );
435 
436 NTSTATUS
437 NTAPI
438 CcRosReleaseFileCache(
439     PFILE_OBJECT FileObject
440 );
441 
442 VOID
443 NTAPI
444 CcShutdownSystem(VOID);
445 
446 VOID
447 NTAPI
448 CcWorkerThread(PVOID Parameter);
449 
450 VOID
451 NTAPI
452 CcScanDpc(
453     PKDPC Dpc,
454     PVOID DeferredContext,
455     PVOID SystemArgument1,
456     PVOID SystemArgument2);
457 
458 VOID
459 CcScheduleLazyWriteScan(BOOLEAN NoDelay);
460 
461 VOID
462 CcPostDeferredWrites(VOID);
463 
464 VOID
465 CcPostWorkQueue(
466     IN PWORK_QUEUE_ENTRY WorkItem,
467     IN PLIST_ENTRY WorkQueue);
468 
469 VOID
470 CcPerformReadAhead(
471     IN PFILE_OBJECT FileObject);
472 
473 NTSTATUS
474 CcRosInternalFreeVacb(
475     IN PROS_VACB Vacb);
476 
477 FORCEINLINE
478 BOOLEAN
479 DoRangesIntersect(
480     _In_ LONGLONG Offset1,
481     _In_ LONGLONG Length1,
482     _In_ LONGLONG Offset2,
483     _In_ LONGLONG Length2)
484 {
485     if (Offset1 + Length1 <= Offset2)
486         return FALSE;
487     if (Offset2 + Length2 <= Offset1)
488         return FALSE;
489     return TRUE;
490 }
491 
492 FORCEINLINE
493 BOOLEAN
494 IsPointInRange(
495     _In_ LONGLONG Offset1,
496     _In_ LONGLONG Length1,
497     _In_ LONGLONG Point)
498 {
499     return DoRangesIntersect(Offset1, Length1, Point, 1);
500 }
501 
502 #define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C)
503 
504 #if DBG
505 #define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
506 #define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
507 #define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__)
508 
509 ULONG
510 CcRosVacbIncRefCount_(
511     PROS_VACB vacb,
512     PCSTR file,
513     INT line);
514 
515 ULONG
516 CcRosVacbDecRefCount_(
517     PROS_VACB vacb,
518     PCSTR file,
519     INT line);
520 
521 ULONG
522 CcRosVacbGetRefCount_(
523     PROS_VACB vacb,
524     PCSTR file,
525     INT line);
526 
527 #else
528 #define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
529 FORCEINLINE
530 ULONG
531 CcRosVacbDecRefCount(
532     PROS_VACB vacb)
533 {
534     ULONG Refs;
535 
536     Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount);
537     if (Refs == 0)
538     {
539         CcRosInternalFreeVacb(vacb);
540     }
541     return Refs;
542 }
543 #define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
544 #endif
545