[NTOSKRNL] Implement CcPostDeferredWrites() that executes deferred writes.
[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 CcRegularWorkQueue;
51 extern LIST_ENTRY CcPostTickWorkQueue;
52 extern NPAGED_LOOKASIDE_LIST CcTwilightLookasideList;
53
54 typedef struct _PF_SCENARIO_ID
55 {
56 WCHAR ScenName[30];
57 ULONG HashId;
58 } PF_SCENARIO_ID, *PPF_SCENARIO_ID;
59
60 typedef struct _PF_LOG_ENTRY
61 {
62 ULONG FileOffset:30;
63 ULONG Type:2;
64 union
65 {
66 ULONG FileKey;
67 ULONG FileSequenceNumber;
68 };
69 } PF_LOG_ENTRY, *PPF_LOG_ENTRY;
70
71 typedef struct _PFSN_LOG_ENTRIES
72 {
73 LIST_ENTRY TraceBuffersLink;
74 LONG NumEntries;
75 LONG MaxEntries;
76 PF_LOG_ENTRY Entries[ANYSIZE_ARRAY];
77 } PFSN_LOG_ENTRIES, *PPFSN_LOG_ENTRIES;
78
79 typedef struct _PF_SECTION_INFO
80 {
81 ULONG FileKey;
82 ULONG FileSequenceNumber;
83 ULONG FileIdLow;
84 ULONG FileIdHigh;
85 } PF_SECTION_INFO, *PPF_SECTION_INFO;
86
87 typedef struct _PF_TRACE_HEADER
88 {
89 ULONG Version;
90 ULONG MagicNumber;
91 ULONG Size;
92 PF_SCENARIO_ID ScenarioId;
93 ULONG ScenarioType; // PF_SCENARIO_TYPE
94 ULONG EventEntryIdxs[8];
95 ULONG NumEventEntryIdxs;
96 ULONG TraceBufferOffset;
97 ULONG NumEntries;
98 ULONG SectionInfoOffset;
99 ULONG NumSections;
100 ULONG FaultsPerPeriod[10];
101 LARGE_INTEGER LaunchTime;
102 ULONGLONG Reserved[5];
103 } PF_TRACE_HEADER, *PPF_TRACE_HEADER;
104
105 typedef struct _PFSN_TRACE_DUMP
106 {
107 LIST_ENTRY CompletedTracesLink;
108 PF_TRACE_HEADER Trace;
109 } PFSN_TRACE_DUMP, *PPFSN_TRACE_DUMP;
110
111 typedef struct _PFSN_TRACE_HEADER
112 {
113 ULONG Magic;
114 LIST_ENTRY ActiveTracesLink;
115 PF_SCENARIO_ID ScenarioId;
116 ULONG ScenarioType; // PF_SCENARIO_TYPE
117 ULONG EventEntryIdxs[8];
118 ULONG NumEventEntryIdxs;
119 PPFSN_LOG_ENTRIES CurrentTraceBuffer;
120 LIST_ENTRY TraceBuffersList;
121 ULONG NumTraceBuffers;
122 KSPIN_LOCK TraceBufferSpinLock;
123 KTIMER TraceTimer;
124 LARGE_INTEGER TraceTimerPeriod;
125 KDPC TraceTimerDpc;
126 KSPIN_LOCK TraceTimerSpinLock;
127 ULONG FaultsPerPeriod[10];
128 LONG LastNumFaults;
129 LONG CurPeriod;
130 LONG NumFaults;
131 LONG MaxFaults;
132 PEPROCESS Process;
133 EX_RUNDOWN_REF RefCount;
134 WORK_QUEUE_ITEM EndTraceWorkItem;
135 LONG EndTraceCalled;
136 PPFSN_TRACE_DUMP TraceDump;
137 NTSTATUS TraceDumpStatus;
138 LARGE_INTEGER LaunchTime;
139 PPF_SECTION_INFO SectionInfo;
140 ULONG SectionInfoCount;
141 } PFSN_TRACE_HEADER, *PPFSN_TRACE_HEADER;
142
143 typedef struct _PFSN_PREFETCHER_GLOBALS
144 {
145 LIST_ENTRY ActiveTraces;
146 KSPIN_LOCK ActiveTracesLock;
147 PPFSN_TRACE_HEADER SystemWideTrace;
148 LIST_ENTRY CompletedTraces;
149 FAST_MUTEX CompletedTracesLock;
150 LONG NumCompletedTraces;
151 PKEVENT CompletedTracesEvent;
152 LONG ActivePrefetches;
153 } PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS;
154
155 typedef struct _ROS_SHARED_CACHE_MAP
156 {
157 LIST_ENTRY CacheMapVacbListHead;
158 ULONG TimeStamp;
159 PFILE_OBJECT FileObject;
160 LARGE_INTEGER SectionSize;
161 LARGE_INTEGER FileSize;
162 BOOLEAN PinAccess;
163 PCACHE_MANAGER_CALLBACKS Callbacks;
164 PVOID LazyWriteContext;
165 KSPIN_LOCK CacheMapLock;
166 ULONG OpenCount;
167 ULONG DirtyPages;
168 LIST_ENTRY SharedCacheMapLinks;
169 ULONG DirtyPageThreshold;
170 #if DBG
171 BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
172 #endif
173 } ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP;
174
175 typedef struct _ROS_VACB
176 {
177 /* Base address of the region where the view's data is mapped. */
178 PVOID BaseAddress;
179 /* Memory area representing the region where the view's data is mapped. */
180 struct _MEMORY_AREA* MemoryArea;
181 /* Are the contents of the view valid. */
182 BOOLEAN Valid;
183 /* Are the contents of the view newer than those on disk. */
184 BOOLEAN Dirty;
185 /* Page out in progress */
186 BOOLEAN PageOut;
187 ULONG MappedCount;
188 /* Entry in the list of VACBs for this shared cache map. */
189 LIST_ENTRY CacheMapVacbListEntry;
190 /* Entry in the list of VACBs which are dirty. */
191 LIST_ENTRY DirtyVacbListEntry;
192 /* Entry in the list of VACBs. */
193 LIST_ENTRY VacbLruListEntry;
194 /* Offset in the file which this view maps. */
195 LARGE_INTEGER FileOffset;
196 /* Mutex */
197 KMUTEX Mutex;
198 /* Number of references. */
199 ULONG ReferenceCount;
200 /* How many times was it pinned? */
201 _Guarded_by_(Mutex)
202 LONG PinCount;
203 /* Pointer to the shared cache map for the file which this view maps data for. */
204 PROS_SHARED_CACHE_MAP SharedCacheMap;
205 /* Pointer to the next VACB in a chain. */
206 } ROS_VACB, *PROS_VACB;
207
208 typedef struct _INTERNAL_BCB
209 {
210 /* Lock */
211 ERESOURCE Lock;
212 PUBLIC_BCB PFCB;
213 PROS_VACB Vacb;
214 BOOLEAN Dirty;
215 BOOLEAN Pinned;
216 CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
217 } INTERNAL_BCB, *PINTERNAL_BCB;
218
219 typedef struct _LAZY_WRITER
220 {
221 LIST_ENTRY WorkQueue;
222 KDPC ScanDpc;
223 KTIMER ScanTimer;
224 BOOLEAN ScanActive;
225 BOOLEAN OtherWork;
226 BOOLEAN PendingTeardown;
227 } LAZY_WRITER, *PLAZY_WRITER;
228
229 typedef struct _WORK_QUEUE_ENTRY
230 {
231 LIST_ENTRY WorkQueueLinks;
232 union
233 {
234 struct
235 {
236 FILE_OBJECT *FileObject;
237 } Read;
238 struct
239 {
240 SHARED_CACHE_MAP *SharedCacheMap;
241 } Write;
242 struct
243 {
244 KEVENT *Event;
245 } Event;
246 struct
247 {
248 unsigned long Reason;
249 } Notification;
250 } Parameters;
251 unsigned char Function;
252 } WORK_QUEUE_ENTRY, *PWORK_QUEUE_ENTRY;
253
254 extern LAZY_WRITER LazyWriter;
255
256 #define NODE_TYPE_DEFERRED_WRITE 0x02FC
257
258 VOID
259 NTAPI
260 CcPfInitializePrefetcher(
261 VOID
262 );
263
264 VOID
265 NTAPI
266 CcMdlReadComplete2(
267 IN PFILE_OBJECT FileObject,
268 IN PMDL MemoryDescriptorList
269 );
270
271 VOID
272 NTAPI
273 CcMdlWriteComplete2(
274 IN PFILE_OBJECT FileObject,
275 IN PLARGE_INTEGER FileOffset,
276 IN PMDL MdlChain
277 );
278
279 NTSTATUS
280 NTAPI
281 CcRosFlushVacb(PROS_VACB Vacb);
282
283 NTSTATUS
284 NTAPI
285 CcRosGetVacb(
286 PROS_SHARED_CACHE_MAP SharedCacheMap,
287 LONGLONG FileOffset,
288 PLONGLONG BaseOffset,
289 PVOID *BaseAddress,
290 PBOOLEAN UptoDate,
291 PROS_VACB *Vacb
292 );
293
294 VOID
295 NTAPI
296 CcInitView(VOID);
297
298 VOID
299 NTAPI
300 CcShutdownLazyWriter(VOID);
301
302 NTSTATUS
303 NTAPI
304 CcReadVirtualAddress(PROS_VACB Vacb);
305
306 NTSTATUS
307 NTAPI
308 CcWriteVirtualAddress(PROS_VACB Vacb);
309
310 BOOLEAN
311 NTAPI
312 CcInitializeCacheManager(VOID);
313
314 NTSTATUS
315 NTAPI
316 CcRosUnmapVacb(
317 PROS_SHARED_CACHE_MAP SharedCacheMap,
318 LONGLONG FileOffset,
319 BOOLEAN NowDirty
320 );
321
322 PROS_VACB
323 NTAPI
324 CcRosLookupVacb(
325 PROS_SHARED_CACHE_MAP SharedCacheMap,
326 LONGLONG FileOffset
327 );
328
329 VOID
330 NTAPI
331 CcInitCacheZeroPage(VOID);
332
333 NTSTATUS
334 NTAPI
335 CcRosMarkDirtyFile(
336 PROS_SHARED_CACHE_MAP SharedCacheMap,
337 LONGLONG FileOffset
338 );
339
340 VOID
341 NTAPI
342 CcRosMarkDirtyVacb(
343 PROS_VACB Vacb);
344
345 VOID
346 NTAPI
347 CcRosUnmarkDirtyVacb(
348 PROS_VACB Vacb,
349 BOOLEAN LockViews);
350
351 NTSTATUS
352 NTAPI
353 CcRosFlushDirtyPages(
354 ULONG Target,
355 PULONG Count,
356 BOOLEAN Wait,
357 BOOLEAN CalledFromLazy
358 );
359
360 VOID
361 NTAPI
362 CcRosDereferenceCache(PFILE_OBJECT FileObject);
363
364 VOID
365 NTAPI
366 CcRosReferenceCache(PFILE_OBJECT FileObject);
367
368 VOID
369 NTAPI
370 CcRosRemoveIfClosed(PSECTION_OBJECT_POINTERS SectionObjectPointer);
371
372 NTSTATUS
373 NTAPI
374 CcRosReleaseVacb(
375 PROS_SHARED_CACHE_MAP SharedCacheMap,
376 PROS_VACB Vacb,
377 BOOLEAN Valid,
378 BOOLEAN Dirty,
379 BOOLEAN Mapped
380 );
381
382 NTSTATUS
383 NTAPI
384 CcRosRequestVacb(
385 PROS_SHARED_CACHE_MAP SharedCacheMap,
386 LONGLONG FileOffset,
387 PVOID* BaseAddress,
388 PBOOLEAN UptoDate,
389 PROS_VACB *Vacb
390 );
391
392 NTSTATUS
393 NTAPI
394 CcRosInitializeFileCache(
395 PFILE_OBJECT FileObject,
396 PCC_FILE_SIZES FileSizes,
397 BOOLEAN PinAccess,
398 PCACHE_MANAGER_CALLBACKS CallBacks,
399 PVOID LazyWriterContext
400 );
401
402 NTSTATUS
403 NTAPI
404 CcRosReleaseFileCache(
405 PFILE_OBJECT FileObject
406 );
407
408 NTSTATUS
409 NTAPI
410 CcTryToInitializeFileCache(PFILE_OBJECT FileObject);
411
412 VOID
413 NTAPI
414 CcShutdownSystem(VOID);
415
416 VOID
417 NTAPI
418 CcWorkerThread(PVOID Parameter);
419
420 VOID
421 NTAPI
422 CcScanDpc(
423 PKDPC Dpc,
424 PVOID DeferredContext,
425 PVOID SystemArgument1,
426 PVOID SystemArgument2);
427
428 VOID
429 CcScheduleLazyWriteScan(BOOLEAN NoDelay);
430
431 VOID
432 CcPostDeferredWrites(VOID);
433
434 FORCEINLINE
435 NTSTATUS
436 CcRosAcquireVacbLock(
437 _Inout_ PROS_VACB Vacb,
438 _In_ PLARGE_INTEGER Timeout)
439 {
440 NTSTATUS Status;
441 Status = KeWaitForSingleObject(&Vacb->Mutex,
442 Executive,
443 KernelMode,
444 FALSE,
445 Timeout);
446 return Status;
447 }
448
449 FORCEINLINE
450 VOID
451 CcRosReleaseVacbLock(
452 _Inout_ PROS_VACB Vacb)
453 {
454 KeReleaseMutex(&Vacb->Mutex, FALSE);
455 }
456
457 FORCEINLINE
458 BOOLEAN
459 DoRangesIntersect(
460 _In_ LONGLONG Offset1,
461 _In_ LONGLONG Length1,
462 _In_ LONGLONG Offset2,
463 _In_ LONGLONG Length2)
464 {
465 if (Offset1 + Length1 <= Offset2)
466 return FALSE;
467 if (Offset2 + Length2 <= Offset1)
468 return FALSE;
469 return TRUE;
470 }
471
472 FORCEINLINE
473 BOOLEAN
474 IsPointInRange(
475 _In_ LONGLONG Offset1,
476 _In_ LONGLONG Length1,
477 _In_ LONGLONG Point)
478 {
479 return DoRangesIntersect(Offset1, Length1, Point, 1);
480 }
481
482 #define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C)