[NTOSKRNL] Implement write behind in Cc
[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 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 ULONG TimeStamp;
192 BOOLEAN PinAccess;
193 KSPIN_LOCK CacheMapLock;
194 #if DBG
195 BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
196 #endif
197 } ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP;
198
199 #define READAHEAD_DISABLED 0x1
200 #define WRITEBEHIND_DISABLED 0x2
201
202 typedef struct _ROS_VACB
203 {
204 /* Base address of the region where the view's data is mapped. */
205 PVOID BaseAddress;
206 /* Memory area representing the region where the view's data is mapped. */
207 struct _MEMORY_AREA* MemoryArea;
208 /* Are the contents of the view valid. */
209 BOOLEAN Valid;
210 /* Are the contents of the view newer than those on disk. */
211 BOOLEAN Dirty;
212 /* Page out in progress */
213 BOOLEAN PageOut;
214 ULONG MappedCount;
215 /* Entry in the list of VACBs for this shared cache map. */
216 LIST_ENTRY CacheMapVacbListEntry;
217 /* Entry in the list of VACBs which are dirty. */
218 LIST_ENTRY DirtyVacbListEntry;
219 /* Entry in the list of VACBs. */
220 LIST_ENTRY VacbLruListEntry;
221 /* Offset in the file which this view maps. */
222 LARGE_INTEGER FileOffset;
223 /* Number of references. */
224 volatile ULONG ReferenceCount;
225 /* Pointer to the shared cache map for the file which this view maps data for. */
226 PROS_SHARED_CACHE_MAP SharedCacheMap;
227 /* Pointer to the next VACB in a chain. */
228 } ROS_VACB, *PROS_VACB;
229
230 typedef struct _INTERNAL_BCB
231 {
232 /* Lock */
233 ERESOURCE Lock;
234 PUBLIC_BCB PFCB;
235 PROS_VACB Vacb;
236 BOOLEAN Dirty;
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 VOID
292 NTAPI
293 CcPfInitializePrefetcher(
294 VOID
295 );
296
297 VOID
298 NTAPI
299 CcMdlReadComplete2(
300 IN PFILE_OBJECT FileObject,
301 IN PMDL MemoryDescriptorList
302 );
303
304 VOID
305 NTAPI
306 CcMdlWriteComplete2(
307 IN PFILE_OBJECT FileObject,
308 IN PLARGE_INTEGER FileOffset,
309 IN PMDL MdlChain
310 );
311
312 NTSTATUS
313 NTAPI
314 CcRosFlushVacb(PROS_VACB Vacb);
315
316 NTSTATUS
317 NTAPI
318 CcRosGetVacb(
319 PROS_SHARED_CACHE_MAP SharedCacheMap,
320 LONGLONG FileOffset,
321 PLONGLONG BaseOffset,
322 PVOID *BaseAddress,
323 PBOOLEAN UptoDate,
324 PROS_VACB *Vacb
325 );
326
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 BOOLEAN
344 NTAPI
345 CcInitializeCacheManager(VOID);
346
347 NTSTATUS
348 NTAPI
349 CcRosUnmapVacb(
350 PROS_SHARED_CACHE_MAP SharedCacheMap,
351 LONGLONG FileOffset,
352 BOOLEAN NowDirty
353 );
354
355 PROS_VACB
356 NTAPI
357 CcRosLookupVacb(
358 PROS_SHARED_CACHE_MAP SharedCacheMap,
359 LONGLONG FileOffset
360 );
361
362 VOID
363 NTAPI
364 CcInitCacheZeroPage(VOID);
365
366 NTSTATUS
367 NTAPI
368 CcRosMarkDirtyFile(
369 PROS_SHARED_CACHE_MAP SharedCacheMap,
370 LONGLONG FileOffset
371 );
372
373 VOID
374 NTAPI
375 CcRosMarkDirtyVacb(
376 PROS_VACB Vacb);
377
378 VOID
379 NTAPI
380 CcRosUnmarkDirtyVacb(
381 PROS_VACB Vacb,
382 BOOLEAN LockViews);
383
384 NTSTATUS
385 NTAPI
386 CcRosFlushDirtyPages(
387 ULONG Target,
388 PULONG Count,
389 BOOLEAN Wait,
390 BOOLEAN CalledFromLazy
391 );
392
393 VOID
394 NTAPI
395 CcRosDereferenceCache(PFILE_OBJECT FileObject);
396
397 VOID
398 NTAPI
399 CcRosReferenceCache(PFILE_OBJECT FileObject);
400
401 VOID
402 NTAPI
403 CcRosRemoveIfClosed(PSECTION_OBJECT_POINTERS SectionObjectPointer);
404
405 NTSTATUS
406 NTAPI
407 CcRosReleaseVacb(
408 PROS_SHARED_CACHE_MAP SharedCacheMap,
409 PROS_VACB Vacb,
410 BOOLEAN Valid,
411 BOOLEAN Dirty,
412 BOOLEAN Mapped
413 );
414
415 NTSTATUS
416 NTAPI
417 CcRosRequestVacb(
418 PROS_SHARED_CACHE_MAP SharedCacheMap,
419 LONGLONG FileOffset,
420 PVOID* BaseAddress,
421 PBOOLEAN UptoDate,
422 PROS_VACB *Vacb
423 );
424
425 NTSTATUS
426 NTAPI
427 CcRosInitializeFileCache(
428 PFILE_OBJECT FileObject,
429 PCC_FILE_SIZES FileSizes,
430 BOOLEAN PinAccess,
431 PCACHE_MANAGER_CALLBACKS CallBacks,
432 PVOID LazyWriterContext
433 );
434
435 NTSTATUS
436 NTAPI
437 CcRosReleaseFileCache(
438 PFILE_OBJECT FileObject
439 );
440
441 VOID
442 NTAPI
443 CcShutdownSystem(VOID);
444
445 VOID
446 NTAPI
447 CcWorkerThread(PVOID Parameter);
448
449 VOID
450 NTAPI
451 CcScanDpc(
452 PKDPC Dpc,
453 PVOID DeferredContext,
454 PVOID SystemArgument1,
455 PVOID SystemArgument2);
456
457 VOID
458 CcScheduleLazyWriteScan(BOOLEAN NoDelay);
459
460 VOID
461 CcPostDeferredWrites(VOID);
462
463 VOID
464 CcPostWorkQueue(
465 IN PWORK_QUEUE_ENTRY WorkItem,
466 IN PLIST_ENTRY WorkQueue);
467
468 VOID
469 CcPerformReadAhead(
470 IN PFILE_OBJECT FileObject);
471
472 NTSTATUS
473 CcRosInternalFreeVacb(
474 IN PROS_VACB Vacb);
475
476 FORCEINLINE
477 BOOLEAN
478 DoRangesIntersect(
479 _In_ LONGLONG Offset1,
480 _In_ LONGLONG Length1,
481 _In_ LONGLONG Offset2,
482 _In_ LONGLONG Length2)
483 {
484 if (Offset1 + Length1 <= Offset2)
485 return FALSE;
486 if (Offset2 + Length2 <= Offset1)
487 return FALSE;
488 return TRUE;
489 }
490
491 FORCEINLINE
492 BOOLEAN
493 IsPointInRange(
494 _In_ LONGLONG Offset1,
495 _In_ LONGLONG Length1,
496 _In_ LONGLONG Point)
497 {
498 return DoRangesIntersect(Offset1, Length1, Point, 1);
499 }
500
501 #define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C)
502
503 #if DBG
504 #define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
505 #define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
506 #define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__)
507
508 ULONG
509 CcRosVacbIncRefCount_(
510 PROS_VACB vacb,
511 PCSTR file,
512 INT line);
513
514 ULONG
515 CcRosVacbDecRefCount_(
516 PROS_VACB vacb,
517 PCSTR file,
518 INT line);
519
520 ULONG
521 CcRosVacbGetRefCount_(
522 PROS_VACB vacb,
523 PCSTR file,
524 INT line);
525
526 #else
527 #define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
528 FORCEINLINE
529 ULONG
530 CcRosVacbDecRefCount(
531 PROS_VACB vacb)
532 {
533 ULONG Refs;
534
535 Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount);
536 if (Refs == 0)
537 {
538 CcRosInternalFreeVacb(vacb);
539 }
540 return Refs;
541 }
542 #define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
543 #endif