xref: /reactos/ntoskrnl/include/internal/cc.h (revision 19b18ce2)
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     /* Mutex */
221     KMUTEX Mutex;
222     /* Number of references. */
223     volatile ULONG ReferenceCount;
224     /* How many times was it pinned? */
225     _Guarded_by_(Mutex)
226     LONG PinCount;
227     /* Pointer to the shared cache map for the file which this view maps data for. */
228     PROS_SHARED_CACHE_MAP SharedCacheMap;
229     /* Pointer to the next VACB in a chain. */
230 } ROS_VACB, *PROS_VACB;
231 
232 typedef struct _INTERNAL_BCB
233 {
234     /* Lock */
235     ERESOURCE Lock;
236     PUBLIC_BCB PFCB;
237     PROS_VACB Vacb;
238     BOOLEAN Dirty;
239     BOOLEAN Pinned;
240     CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
241 } INTERNAL_BCB, *PINTERNAL_BCB;
242 
243 typedef struct _LAZY_WRITER
244 {
245     LIST_ENTRY WorkQueue;
246     KDPC ScanDpc;
247     KTIMER ScanTimer;
248     BOOLEAN ScanActive;
249     BOOLEAN OtherWork;
250     BOOLEAN PendingTeardown;
251 } LAZY_WRITER, *PLAZY_WRITER;
252 
253 typedef struct _WORK_QUEUE_ENTRY
254 {
255     LIST_ENTRY WorkQueueLinks;
256     union
257     {
258         struct
259         {
260             FILE_OBJECT *FileObject;
261         } Read;
262         struct
263         {
264             SHARED_CACHE_MAP *SharedCacheMap;
265         } Write;
266         struct
267         {
268             KEVENT *Event;
269         } Event;
270         struct
271         {
272             unsigned long Reason;
273         } Notification;
274     } Parameters;
275     unsigned char Function;
276 } WORK_QUEUE_ENTRY, *PWORK_QUEUE_ENTRY;
277 
278 typedef enum _WORK_QUEUE_FUNCTIONS
279 {
280     ReadAhead = 1,
281     WriteBehind = 2,
282     LazyWrite = 3,
283     SetDone = 4,
284 } WORK_QUEUE_FUNCTIONS, *PWORK_QUEUE_FUNCTIONS;
285 
286 extern LAZY_WRITER LazyWriter;
287 
288 #define NODE_TYPE_DEFERRED_WRITE 0x02FC
289 #define NODE_TYPE_PRIVATE_MAP    0x02FE
290 #define NODE_TYPE_SHARED_MAP     0x02FF
291 
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 NTAPI
315 CcRosFlushVacb(PROS_VACB Vacb);
316 
317 NTSTATUS
318 NTAPI
319 CcRosGetVacb(
320     PROS_SHARED_CACHE_MAP SharedCacheMap,
321     LONGLONG FileOffset,
322     PLONGLONG BaseOffset,
323     PVOID *BaseAddress,
324     PBOOLEAN UptoDate,
325     PROS_VACB *Vacb
326 );
327 
328 VOID
329 NTAPI
330 CcInitView(VOID);
331 
332 VOID
333 NTAPI
334 CcShutdownLazyWriter(VOID);
335 
336 NTSTATUS
337 NTAPI
338 CcReadVirtualAddress(PROS_VACB Vacb);
339 
340 NTSTATUS
341 NTAPI
342 CcWriteVirtualAddress(PROS_VACB Vacb);
343 
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 FORCEINLINE
474 NTSTATUS
475 CcRosAcquireVacbLock(
476     _Inout_ PROS_VACB Vacb,
477     _In_ PLARGE_INTEGER Timeout)
478 {
479     NTSTATUS Status;
480     Status = KeWaitForSingleObject(&Vacb->Mutex,
481                                    Executive,
482                                    KernelMode,
483                                    FALSE,
484                                    Timeout);
485     return Status;
486 }
487 
488 FORCEINLINE
489 VOID
490 CcRosReleaseVacbLock(
491     _Inout_ PROS_VACB Vacb)
492 {
493     KeReleaseMutex(&Vacb->Mutex, FALSE);
494 }
495 
496 FORCEINLINE
497 BOOLEAN
498 DoRangesIntersect(
499     _In_ LONGLONG Offset1,
500     _In_ LONGLONG Length1,
501     _In_ LONGLONG Offset2,
502     _In_ LONGLONG Length2)
503 {
504     if (Offset1 + Length1 <= Offset2)
505         return FALSE;
506     if (Offset2 + Length2 <= Offset1)
507         return FALSE;
508     return TRUE;
509 }
510 
511 FORCEINLINE
512 BOOLEAN
513 IsPointInRange(
514     _In_ LONGLONG Offset1,
515     _In_ LONGLONG Length1,
516     _In_ LONGLONG Point)
517 {
518     return DoRangesIntersect(Offset1, Length1, Point, 1);
519 }
520 
521 #define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C)
522 
523 #if DBG
524 #define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
525 #define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
526 #define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__)
527 
528 ULONG
529 CcRosVacbIncRefCount_(
530     PROS_VACB vacb,
531     PCSTR file,
532     INT line);
533 
534 ULONG
535 CcRosVacbDecRefCount_(
536     PROS_VACB vacb,
537     PCSTR file,
538     INT line);
539 
540 ULONG
541 CcRosVacbGetRefCount_(
542     PROS_VACB vacb,
543     PCSTR file,
544     INT line);
545 
546 #else
547 #define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
548 #define CcRosVacbDecRefCount(vacb) InterlockedDecrement((PLONG)&(vacb)->ReferenceCount)
549 #define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
550 #endif
551