xref: /reactos/ntoskrnl/include/internal/cc.h (revision 234f89c0)
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 CcDataPages;
66 extern ULONG CcDataFlushes;
67 
68 typedef struct _PF_SCENARIO_ID
69 {
70     WCHAR ScenName[30];
71     ULONG HashId;
72 } PF_SCENARIO_ID, *PPF_SCENARIO_ID;
73 
74 typedef struct _PF_LOG_ENTRY
75 {
76     ULONG FileOffset:30;
77     ULONG Type:2;
78     union
79     {
80         ULONG FileKey;
81         ULONG FileSequenceNumber;
82     };
83 } PF_LOG_ENTRY, *PPF_LOG_ENTRY;
84 
85 typedef struct _PFSN_LOG_ENTRIES
86 {
87     LIST_ENTRY TraceBuffersLink;
88     LONG NumEntries;
89     LONG MaxEntries;
90     PF_LOG_ENTRY Entries[ANYSIZE_ARRAY];
91 } PFSN_LOG_ENTRIES, *PPFSN_LOG_ENTRIES;
92 
93 typedef struct _PF_SECTION_INFO
94 {
95     ULONG FileKey;
96     ULONG FileSequenceNumber;
97     ULONG FileIdLow;
98     ULONG FileIdHigh;
99 } PF_SECTION_INFO, *PPF_SECTION_INFO;
100 
101 typedef struct _PF_TRACE_HEADER
102 {
103     ULONG Version;
104     ULONG MagicNumber;
105     ULONG Size;
106     PF_SCENARIO_ID ScenarioId;
107     ULONG ScenarioType; // PF_SCENARIO_TYPE
108     ULONG EventEntryIdxs[8];
109     ULONG NumEventEntryIdxs;
110     ULONG TraceBufferOffset;
111     ULONG NumEntries;
112     ULONG SectionInfoOffset;
113     ULONG NumSections;
114     ULONG FaultsPerPeriod[10];
115     LARGE_INTEGER LaunchTime;
116     ULONGLONG Reserved[5];
117 } PF_TRACE_HEADER, *PPF_TRACE_HEADER;
118 
119 typedef struct _PFSN_TRACE_DUMP
120 {
121     LIST_ENTRY CompletedTracesLink;
122     PF_TRACE_HEADER Trace;
123 } PFSN_TRACE_DUMP, *PPFSN_TRACE_DUMP;
124 
125 typedef struct _PFSN_TRACE_HEADER
126 {
127     ULONG Magic;
128     LIST_ENTRY ActiveTracesLink;
129     PF_SCENARIO_ID ScenarioId;
130     ULONG ScenarioType; // PF_SCENARIO_TYPE
131     ULONG EventEntryIdxs[8];
132     ULONG NumEventEntryIdxs;
133     PPFSN_LOG_ENTRIES CurrentTraceBuffer;
134     LIST_ENTRY TraceBuffersList;
135     ULONG NumTraceBuffers;
136     KSPIN_LOCK TraceBufferSpinLock;
137     KTIMER TraceTimer;
138     LARGE_INTEGER TraceTimerPeriod;
139     KDPC TraceTimerDpc;
140     KSPIN_LOCK TraceTimerSpinLock;
141     ULONG FaultsPerPeriod[10];
142     LONG LastNumFaults;
143     LONG CurPeriod;
144     LONG NumFaults;
145     LONG MaxFaults;
146     PEPROCESS Process;
147     EX_RUNDOWN_REF RefCount;
148     WORK_QUEUE_ITEM EndTraceWorkItem;
149     LONG EndTraceCalled;
150     PPFSN_TRACE_DUMP TraceDump;
151     NTSTATUS TraceDumpStatus;
152     LARGE_INTEGER LaunchTime;
153     PPF_SECTION_INFO SectionInfo;
154     ULONG SectionInfoCount;
155 } PFSN_TRACE_HEADER, *PPFSN_TRACE_HEADER;
156 
157 typedef struct _PFSN_PREFETCHER_GLOBALS
158 {
159     LIST_ENTRY ActiveTraces;
160     KSPIN_LOCK ActiveTracesLock;
161     PPFSN_TRACE_HEADER SystemWideTrace;
162     LIST_ENTRY CompletedTraces;
163     FAST_MUTEX CompletedTracesLock;
164     LONG NumCompletedTraces;
165     PKEVENT CompletedTracesEvent;
166     LONG ActivePrefetches;
167 } PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS;
168 
169 typedef struct _ROS_SHARED_CACHE_MAP
170 {
171     CSHORT NodeTypeCode;
172     CSHORT NodeByteSize;
173     ULONG OpenCount;
174     LARGE_INTEGER FileSize;
175     LARGE_INTEGER SectionSize;
176     PFILE_OBJECT FileObject;
177     ULONG DirtyPages;
178     LIST_ENTRY SharedCacheMapLinks;
179     ULONG Flags;
180     PCACHE_MANAGER_CALLBACKS Callbacks;
181     PVOID LazyWriteContext;
182     LIST_ENTRY PrivateList;
183     ULONG DirtyPageThreshold;
184     PRIVATE_CACHE_MAP PrivateCacheMap;
185 
186     /* ROS specific */
187     LIST_ENTRY CacheMapVacbListHead;
188     ULONG TimeStamp;
189     BOOLEAN PinAccess;
190     KSPIN_LOCK CacheMapLock;
191 #if DBG
192     BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
193 #endif
194 } ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP;
195 
196 #define READAHEAD_DISABLED 0x1
197 #define WRITEBEHIND_DISABLED 0x2
198 
199 typedef struct _ROS_VACB
200 {
201     /* Base address of the region where the view's data is mapped. */
202     PVOID BaseAddress;
203     /* Memory area representing the region where the view's data is mapped. */
204     struct _MEMORY_AREA* MemoryArea;
205     /* Are the contents of the view valid. */
206     BOOLEAN Valid;
207     /* Are the contents of the view newer than those on disk. */
208     BOOLEAN Dirty;
209     /* Page out in progress */
210     BOOLEAN PageOut;
211     ULONG MappedCount;
212     /* Entry in the list of VACBs for this shared cache map. */
213     LIST_ENTRY CacheMapVacbListEntry;
214     /* Entry in the list of VACBs which are dirty. */
215     LIST_ENTRY DirtyVacbListEntry;
216     /* Entry in the list of VACBs. */
217     LIST_ENTRY VacbLruListEntry;
218     /* Offset in the file which this view maps. */
219     LARGE_INTEGER FileOffset;
220     /* Number of references. */
221     volatile ULONG ReferenceCount;
222     /* How many times was it pinned? */
223     LONG PinCount;
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     BOOLEAN Dirty;
236     BOOLEAN Pinned;
237     CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
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     LazyWrite = 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 VOID
290 NTAPI
291 CcPfInitializePrefetcher(
292     VOID
293 );
294 
295 VOID
296 NTAPI
297 CcMdlReadComplete2(
298     IN PFILE_OBJECT FileObject,
299     IN PMDL MemoryDescriptorList
300 );
301 
302 VOID
303 NTAPI
304 CcMdlWriteComplete2(
305     IN PFILE_OBJECT FileObject,
306     IN PLARGE_INTEGER FileOffset,
307     IN PMDL MdlChain
308 );
309 
310 NTSTATUS
311 NTAPI
312 CcRosFlushVacb(PROS_VACB Vacb);
313 
314 NTSTATUS
315 NTAPI
316 CcRosGetVacb(
317     PROS_SHARED_CACHE_MAP SharedCacheMap,
318     LONGLONG FileOffset,
319     PLONGLONG BaseOffset,
320     PVOID *BaseAddress,
321     PBOOLEAN UptoDate,
322     PROS_VACB *Vacb
323 );
324 
325 VOID
326 NTAPI
327 CcInitView(VOID);
328 
329 VOID
330 NTAPI
331 CcShutdownLazyWriter(VOID);
332 
333 NTSTATUS
334 NTAPI
335 CcReadVirtualAddress(PROS_VACB Vacb);
336 
337 NTSTATUS
338 NTAPI
339 CcWriteVirtualAddress(PROS_VACB Vacb);
340 
341 BOOLEAN
342 NTAPI
343 CcInitializeCacheManager(VOID);
344 
345 NTSTATUS
346 NTAPI
347 CcRosUnmapVacb(
348     PROS_SHARED_CACHE_MAP SharedCacheMap,
349     LONGLONG FileOffset,
350     BOOLEAN NowDirty
351 );
352 
353 PROS_VACB
354 NTAPI
355 CcRosLookupVacb(
356     PROS_SHARED_CACHE_MAP SharedCacheMap,
357     LONGLONG FileOffset
358 );
359 
360 VOID
361 NTAPI
362 CcInitCacheZeroPage(VOID);
363 
364 NTSTATUS
365 NTAPI
366 CcRosMarkDirtyFile(
367     PROS_SHARED_CACHE_MAP SharedCacheMap,
368     LONGLONG FileOffset
369 );
370 
371 VOID
372 NTAPI
373 CcRosMarkDirtyVacb(
374     PROS_VACB Vacb);
375 
376 VOID
377 NTAPI
378 CcRosUnmarkDirtyVacb(
379     PROS_VACB Vacb,
380     BOOLEAN LockViews);
381 
382 NTSTATUS
383 NTAPI
384 CcRosFlushDirtyPages(
385     ULONG Target,
386     PULONG Count,
387     BOOLEAN Wait,
388     BOOLEAN CalledFromLazy
389 );
390 
391 VOID
392 NTAPI
393 CcRosDereferenceCache(PFILE_OBJECT FileObject);
394 
395 VOID
396 NTAPI
397 CcRosReferenceCache(PFILE_OBJECT FileObject);
398 
399 VOID
400 NTAPI
401 CcRosRemoveIfClosed(PSECTION_OBJECT_POINTERS SectionObjectPointer);
402 
403 NTSTATUS
404 NTAPI
405 CcRosReleaseVacb(
406     PROS_SHARED_CACHE_MAP SharedCacheMap,
407     PROS_VACB Vacb,
408     BOOLEAN Valid,
409     BOOLEAN Dirty,
410     BOOLEAN Mapped
411 );
412 
413 NTSTATUS
414 NTAPI
415 CcRosRequestVacb(
416     PROS_SHARED_CACHE_MAP SharedCacheMap,
417     LONGLONG FileOffset,
418     PVOID* BaseAddress,
419     PBOOLEAN UptoDate,
420     PROS_VACB *Vacb
421 );
422 
423 NTSTATUS
424 NTAPI
425 CcRosInitializeFileCache(
426     PFILE_OBJECT FileObject,
427     PCC_FILE_SIZES FileSizes,
428     BOOLEAN PinAccess,
429     PCACHE_MANAGER_CALLBACKS CallBacks,
430     PVOID LazyWriterContext
431 );
432 
433 NTSTATUS
434 NTAPI
435 CcRosReleaseFileCache(
436     PFILE_OBJECT FileObject
437 );
438 
439 VOID
440 NTAPI
441 CcShutdownSystem(VOID);
442 
443 VOID
444 NTAPI
445 CcWorkerThread(PVOID Parameter);
446 
447 VOID
448 NTAPI
449 CcScanDpc(
450     PKDPC Dpc,
451     PVOID DeferredContext,
452     PVOID SystemArgument1,
453     PVOID SystemArgument2);
454 
455 VOID
456 CcScheduleLazyWriteScan(BOOLEAN NoDelay);
457 
458 VOID
459 CcPostDeferredWrites(VOID);
460 
461 VOID
462 CcPostWorkQueue(
463     IN PWORK_QUEUE_ENTRY WorkItem,
464     IN PLIST_ENTRY WorkQueue);
465 
466 VOID
467 CcPerformReadAhead(
468     IN PFILE_OBJECT FileObject);
469 
470 NTSTATUS
471 CcRosInternalFreeVacb(
472     IN PROS_VACB Vacb);
473 
474 FORCEINLINE
475 BOOLEAN
476 DoRangesIntersect(
477     _In_ LONGLONG Offset1,
478     _In_ LONGLONG Length1,
479     _In_ LONGLONG Offset2,
480     _In_ LONGLONG Length2)
481 {
482     if (Offset1 + Length1 <= Offset2)
483         return FALSE;
484     if (Offset2 + Length2 <= Offset1)
485         return FALSE;
486     return TRUE;
487 }
488 
489 FORCEINLINE
490 BOOLEAN
491 IsPointInRange(
492     _In_ LONGLONG Offset1,
493     _In_ LONGLONG Length1,
494     _In_ LONGLONG Point)
495 {
496     return DoRangesIntersect(Offset1, Length1, Point, 1);
497 }
498 
499 #define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C)
500 
501 #if DBG
502 #define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
503 #define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
504 #define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__)
505 
506 ULONG
507 CcRosVacbIncRefCount_(
508     PROS_VACB vacb,
509     PCSTR file,
510     INT line);
511 
512 ULONG
513 CcRosVacbDecRefCount_(
514     PROS_VACB vacb,
515     PCSTR file,
516     INT line);
517 
518 ULONG
519 CcRosVacbGetRefCount_(
520     PROS_VACB vacb,
521     PCSTR file,
522     INT line);
523 
524 #else
525 #define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
526 FORCEINLINE
527 ULONG
528 CcRosVacbDecRefCount(
529     PROS_VACB vacb)
530 {
531     ULONG Refs;
532 
533     Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount);
534     if (Refs == 0)
535     {
536         CcRosInternalFreeVacb(vacb);
537     }
538     return Refs;
539 }
540 #define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
541 #endif
542