[NTOSKRNL] When allocating a new BCB, save it in a list
[reactos.git] / ntoskrnl / include / internal / cc.h
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 LIST_ENTRY BcbList;
176 LARGE_INTEGER SectionSize;
177 PFILE_OBJECT FileObject;
178 ULONG DirtyPages;
179 LIST_ENTRY SharedCacheMapLinks;
180 ULONG Flags;
181 PCACHE_MANAGER_CALLBACKS Callbacks;
182 PVOID LazyWriteContext;
183 LIST_ENTRY PrivateList;
184 ULONG DirtyPageThreshold;
185 KSPIN_LOCK BcbSpinLock;
186 PRIVATE_CACHE_MAP PrivateCacheMap;
187
188 /* ROS specific */
189 LIST_ENTRY CacheMapVacbListHead;
190 ULONG TimeStamp;
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 /* How many times was it pinned? */
225 LONG PinCount;
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 BOOLEAN Dirty;
238 BOOLEAN Pinned;
239 CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
240 LIST_ENTRY BcbEntry;
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 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