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 LARGE_INTEGER ValidDataLength; 179 PFILE_OBJECT FileObject; 180 ULONG DirtyPages; 181 LIST_ENTRY SharedCacheMapLinks; 182 ULONG Flags; 183 PVOID Section; 184 PKEVENT CreateEvent; 185 PCACHE_MANAGER_CALLBACKS Callbacks; 186 PVOID LazyWriteContext; 187 LIST_ENTRY PrivateList; 188 ULONG DirtyPageThreshold; 189 KSPIN_LOCK BcbSpinLock; 190 PRIVATE_CACHE_MAP PrivateCacheMap; 191 192 /* ROS specific */ 193 LIST_ENTRY CacheMapVacbListHead; 194 BOOLEAN PinAccess; 195 KSPIN_LOCK CacheMapLock; 196 #if DBG 197 BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */ 198 #endif 199 } ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP; 200 201 #define READAHEAD_DISABLED 0x1 202 #define WRITEBEHIND_DISABLED 0x2 203 #define SHARED_CACHE_MAP_IN_CREATION 0x4 204 #define SHARED_CACHE_MAP_IN_LAZYWRITE 0x8 205 206 typedef struct _ROS_VACB 207 { 208 /* Base address of the region where the view's data is mapped. */ 209 PVOID BaseAddress; 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 ULONG PinCount; 237 CSHORT RefCount; /* (At offset 0x34 on WinNT4) */ 238 LIST_ENTRY BcbEntry; 239 } INTERNAL_BCB, *PINTERNAL_BCB; 240 241 typedef struct _LAZY_WRITER 242 { 243 LIST_ENTRY WorkQueue; 244 KDPC ScanDpc; 245 KTIMER ScanTimer; 246 BOOLEAN ScanActive; 247 BOOLEAN OtherWork; 248 BOOLEAN PendingTeardown; 249 } LAZY_WRITER, *PLAZY_WRITER; 250 251 typedef struct _WORK_QUEUE_ENTRY 252 { 253 LIST_ENTRY WorkQueueLinks; 254 union 255 { 256 struct 257 { 258 FILE_OBJECT *FileObject; 259 } Read; 260 struct 261 { 262 SHARED_CACHE_MAP *SharedCacheMap; 263 } Write; 264 struct 265 { 266 KEVENT *Event; 267 } Event; 268 struct 269 { 270 unsigned long Reason; 271 } Notification; 272 } Parameters; 273 unsigned char Function; 274 } WORK_QUEUE_ENTRY, *PWORK_QUEUE_ENTRY; 275 276 typedef enum _WORK_QUEUE_FUNCTIONS 277 { 278 ReadAhead = 1, 279 WriteBehind = 2, 280 LazyScan = 3, 281 SetDone = 4, 282 } WORK_QUEUE_FUNCTIONS, *PWORK_QUEUE_FUNCTIONS; 283 284 extern LAZY_WRITER LazyWriter; 285 286 #define NODE_TYPE_DEFERRED_WRITE 0x02FC 287 #define NODE_TYPE_PRIVATE_MAP 0x02FE 288 #define NODE_TYPE_SHARED_MAP 0x02FF 289 290 CODE_SEG("INIT") 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 CcRosFlushVacb( 314 _In_ PROS_VACB Vacb, 315 _Out_opt_ PIO_STATUS_BLOCK Iosb 316 ); 317 318 NTSTATUS 319 CcRosGetVacb( 320 PROS_SHARED_CACHE_MAP SharedCacheMap, 321 LONGLONG FileOffset, 322 PROS_VACB *Vacb 323 ); 324 325 BOOLEAN 326 CcRosEnsureVacbResident( 327 _In_ PROS_VACB Vacb, 328 _In_ BOOLEAN Wait, 329 _In_ BOOLEAN NoRead, 330 _In_ ULONG Offset, 331 _In_ ULONG Length 332 ); 333 334 CODE_SEG("INIT") 335 VOID 336 NTAPI 337 CcInitView(VOID); 338 339 VOID 340 NTAPI 341 CcShutdownLazyWriter(VOID); 342 343 CODE_SEG("INIT") 344 BOOLEAN 345 CcInitializeCacheManager(VOID); 346 347 PROS_VACB 348 CcRosLookupVacb( 349 PROS_SHARED_CACHE_MAP SharedCacheMap, 350 LONGLONG FileOffset 351 ); 352 353 VOID 354 NTAPI 355 CcInitCacheZeroPage(VOID); 356 357 VOID 358 CcRosMarkDirtyVacb( 359 PROS_VACB Vacb); 360 361 VOID 362 CcRosUnmarkDirtyVacb( 363 PROS_VACB Vacb, 364 BOOLEAN LockViews); 365 366 NTSTATUS 367 CcRosFlushDirtyPages( 368 ULONG Target, 369 PULONG Count, 370 BOOLEAN Wait, 371 BOOLEAN CalledFromLazy 372 ); 373 374 VOID 375 CcRosDereferenceCache(PFILE_OBJECT FileObject); 376 377 VOID 378 CcRosReferenceCache(PFILE_OBJECT FileObject); 379 380 NTSTATUS 381 CcRosReleaseVacb( 382 PROS_SHARED_CACHE_MAP SharedCacheMap, 383 PROS_VACB Vacb, 384 BOOLEAN Dirty, 385 BOOLEAN Mapped 386 ); 387 388 NTSTATUS 389 CcRosRequestVacb( 390 PROS_SHARED_CACHE_MAP SharedCacheMap, 391 LONGLONG FileOffset, 392 PROS_VACB *Vacb 393 ); 394 395 NTSTATUS 396 CcRosInitializeFileCache( 397 PFILE_OBJECT FileObject, 398 PCC_FILE_SIZES FileSizes, 399 BOOLEAN PinAccess, 400 PCACHE_MANAGER_CALLBACKS CallBacks, 401 PVOID LazyWriterContext 402 ); 403 404 NTSTATUS 405 CcRosReleaseFileCache( 406 PFILE_OBJECT FileObject 407 ); 408 409 VOID 410 NTAPI 411 CcShutdownSystem(VOID); 412 413 VOID 414 NTAPI 415 CcWorkerThread(PVOID Parameter); 416 417 VOID 418 NTAPI 419 CcScanDpc( 420 PKDPC Dpc, 421 PVOID DeferredContext, 422 PVOID SystemArgument1, 423 PVOID SystemArgument2); 424 425 VOID 426 CcScheduleLazyWriteScan(BOOLEAN NoDelay); 427 428 VOID 429 CcPostDeferredWrites(VOID); 430 431 VOID 432 CcPostWorkQueue( 433 IN PWORK_QUEUE_ENTRY WorkItem, 434 IN PLIST_ENTRY WorkQueue); 435 436 VOID 437 CcPerformReadAhead( 438 IN PFILE_OBJECT FileObject); 439 440 NTSTATUS 441 CcRosInternalFreeVacb( 442 IN PROS_VACB Vacb); 443 444 FORCEINLINE 445 BOOLEAN 446 DoRangesIntersect( 447 _In_ LONGLONG Offset1, 448 _In_ LONGLONG Length1, 449 _In_ LONGLONG Offset2, 450 _In_ LONGLONG Length2) 451 { 452 if (Offset1 + Length1 <= Offset2) 453 return FALSE; 454 if (Offset2 + Length2 <= Offset1) 455 return FALSE; 456 return TRUE; 457 } 458 459 FORCEINLINE 460 BOOLEAN 461 IsPointInRange( 462 _In_ LONGLONG Offset1, 463 _In_ LONGLONG Length1, 464 _In_ LONGLONG Point) 465 { 466 return DoRangesIntersect(Offset1, Length1, Point, 1); 467 } 468 469 #define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C) 470 471 #if DBG 472 #define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__) 473 #define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__) 474 #define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__) 475 476 ULONG 477 CcRosVacbIncRefCount_( 478 PROS_VACB vacb, 479 PCSTR file, 480 INT line); 481 482 ULONG 483 CcRosVacbDecRefCount_( 484 PROS_VACB vacb, 485 PCSTR file, 486 INT line); 487 488 ULONG 489 CcRosVacbGetRefCount_( 490 PROS_VACB vacb, 491 PCSTR file, 492 INT line); 493 494 #else 495 #define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount) 496 FORCEINLINE 497 ULONG 498 CcRosVacbDecRefCount( 499 PROS_VACB vacb) 500 { 501 ULONG Refs; 502 503 Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount); 504 if (Refs == 0) 505 { 506 CcRosInternalFreeVacb(vacb); 507 } 508 return Refs; 509 } 510 #define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0) 511 #endif 512