Reactos
at master 516 lines 12 kB view raw
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// 42extern ULONG CcRosTraceLevel; 43extern LIST_ENTRY DirtyVacbListHead; 44extern ULONG CcDirtyPageThreshold; 45extern ULONG CcTotalDirtyPages; 46extern LIST_ENTRY CcDeferredWrites; 47extern KSPIN_LOCK CcDeferredWriteSpinLock; 48extern ULONG CcNumberWorkerThreads; 49extern LIST_ENTRY CcIdleWorkerThreadList; 50extern LIST_ENTRY CcExpressWorkQueue; 51extern LIST_ENTRY CcRegularWorkQueue; 52extern LIST_ENTRY CcPostTickWorkQueue; 53extern NPAGED_LOOKASIDE_LIST CcTwilightLookasideList; 54extern LARGE_INTEGER CcIdleDelay; 55 56// 57// Counters 58// 59extern ULONG CcLazyWritePages; 60extern ULONG CcLazyWriteIos; 61extern ULONG CcMapDataWait; 62extern ULONG CcMapDataNoWait; 63extern ULONG CcPinReadWait; 64extern ULONG CcPinReadNoWait; 65extern ULONG CcPinMappedDataCount; 66extern ULONG CcDataPages; 67extern ULONG CcDataFlushes; 68 69typedef struct _PF_SCENARIO_ID 70{ 71 WCHAR ScenName[30]; 72 ULONG HashId; 73} PF_SCENARIO_ID, *PPF_SCENARIO_ID; 74 75typedef 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 86typedef 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 94typedef 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 102typedef 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 120typedef struct _PFSN_TRACE_DUMP 121{ 122 LIST_ENTRY CompletedTracesLink; 123 PF_TRACE_HEADER Trace; 124} PFSN_TRACE_DUMP, *PPFSN_TRACE_DUMP; 125 126typedef 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 158typedef 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 170typedef 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 KGUARDED_MUTEX FlushCacheLock; 197#if DBG 198 BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */ 199#endif 200} ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP; 201 202#define READAHEAD_DISABLED 0x1 203#define WRITEBEHIND_DISABLED 0x2 204#define SHARED_CACHE_MAP_IN_CREATION 0x4 205#define SHARED_CACHE_MAP_IN_LAZYWRITE 0x8 206 207typedef struct _ROS_VACB 208{ 209 /* Base address of the region where the view's data is mapped. */ 210 PVOID BaseAddress; 211 /* Are the contents of the view newer than those on disk. */ 212 BOOLEAN Dirty; 213 /* Page out in progress */ 214 BOOLEAN PageOut; 215 ULONG MappedCount; 216 /* Entry in the list of VACBs for this shared cache map. */ 217 LIST_ENTRY CacheMapVacbListEntry; 218 /* Entry in the list of VACBs which are dirty. */ 219 LIST_ENTRY DirtyVacbListEntry; 220 /* Entry in the list of VACBs. */ 221 LIST_ENTRY VacbLruListEntry; 222 /* Offset in the file which this view maps. */ 223 LARGE_INTEGER FileOffset; 224 /* Number of references. */ 225 volatile ULONG ReferenceCount; 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 231typedef struct _INTERNAL_BCB 232{ 233 /* Lock */ 234 ERESOURCE Lock; 235 PUBLIC_BCB PFCB; 236 PROS_VACB Vacb; 237 ULONG PinCount; 238 CSHORT RefCount; /* (At offset 0x34 on WinNT4) */ 239 LIST_ENTRY BcbEntry; 240} INTERNAL_BCB, *PINTERNAL_BCB; 241 242typedef 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 252typedef 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 277typedef 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 285extern 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 291CODE_SEG("INIT") 292VOID 293NTAPI 294CcPfInitializePrefetcher( 295 VOID 296); 297 298VOID 299NTAPI 300CcMdlReadComplete2( 301 IN PFILE_OBJECT FileObject, 302 IN PMDL MemoryDescriptorList 303); 304 305VOID 306NTAPI 307CcMdlWriteComplete2( 308 IN PFILE_OBJECT FileObject, 309 IN PLARGE_INTEGER FileOffset, 310 IN PMDL MdlChain 311); 312 313NTSTATUS 314CcRosFlushVacb( 315 _In_ PROS_VACB Vacb, 316 _Out_opt_ PIO_STATUS_BLOCK Iosb 317); 318 319NTSTATUS 320CcRosGetVacb( 321 PROS_SHARED_CACHE_MAP SharedCacheMap, 322 LONGLONG FileOffset, 323 PROS_VACB *Vacb 324); 325 326BOOLEAN 327CcRosEnsureVacbResident( 328 _In_ PROS_VACB Vacb, 329 _In_ BOOLEAN Wait, 330 _In_ BOOLEAN NoRead, 331 _In_ ULONG Offset, 332 _In_ ULONG Length 333); 334 335CODE_SEG("INIT") 336VOID 337NTAPI 338CcInitView(VOID); 339 340VOID 341NTAPI 342CcShutdownLazyWriter(VOID); 343 344CODE_SEG("INIT") 345BOOLEAN 346CcInitializeCacheManager(VOID); 347 348PROS_VACB 349CcRosLookupVacb( 350 PROS_SHARED_CACHE_MAP SharedCacheMap, 351 LONGLONG FileOffset 352); 353 354VOID 355NTAPI 356CcInitCacheZeroPage(VOID); 357 358VOID 359CcRosMarkDirtyVacb( 360 PROS_VACB Vacb); 361 362VOID 363CcRosUnmarkDirtyVacb( 364 PROS_VACB Vacb, 365 BOOLEAN LockViews); 366 367NTSTATUS 368CcRosFlushDirtyPages( 369 ULONG Target, 370 PULONG Count, 371 BOOLEAN Wait, 372 BOOLEAN CalledFromLazy 373); 374 375VOID 376CcRosDereferenceCache(PFILE_OBJECT FileObject); 377 378VOID 379CcRosReferenceCache(PFILE_OBJECT FileObject); 380 381NTSTATUS 382CcRosReleaseVacb( 383 PROS_SHARED_CACHE_MAP SharedCacheMap, 384 PROS_VACB Vacb, 385 BOOLEAN Dirty, 386 BOOLEAN Mapped 387); 388 389NTSTATUS 390CcRosRequestVacb( 391 PROS_SHARED_CACHE_MAP SharedCacheMap, 392 LONGLONG FileOffset, 393 PROS_VACB *Vacb 394); 395 396NTSTATUS 397CcRosInitializeFileCache( 398 PFILE_OBJECT FileObject, 399 PCC_FILE_SIZES FileSizes, 400 BOOLEAN PinAccess, 401 PCACHE_MANAGER_CALLBACKS CallBacks, 402 PVOID LazyWriterContext 403); 404 405NTSTATUS 406CcRosReleaseFileCache( 407 PFILE_OBJECT FileObject 408); 409 410VOID 411NTAPI 412CcShutdownSystem(VOID); 413 414VOID 415NTAPI 416CcWorkerThread(PVOID Parameter); 417 418VOID 419NTAPI 420CcScanDpc( 421 PKDPC Dpc, 422 PVOID DeferredContext, 423 PVOID SystemArgument1, 424 PVOID SystemArgument2); 425 426VOID 427CcScheduleLazyWriteScan(BOOLEAN NoDelay); 428 429VOID 430CcPostDeferredWrites(VOID); 431 432VOID 433CcPostWorkQueue( 434 IN PWORK_QUEUE_ENTRY WorkItem, 435 IN PLIST_ENTRY WorkQueue); 436 437VOID 438CcPerformReadAhead( 439 IN PFILE_OBJECT FileObject); 440 441NTSTATUS 442CcRosInternalFreeVacb( 443 IN PROS_VACB Vacb); 444 445FORCEINLINE 446BOOLEAN 447DoRangesIntersect( 448 _In_ LONGLONG Offset1, 449 _In_ LONGLONG Length1, 450 _In_ LONGLONG Offset2, 451 _In_ LONGLONG Length2) 452{ 453 if (Offset1 + Length1 <= Offset2) 454 return FALSE; 455 if (Offset2 + Length2 <= Offset1) 456 return FALSE; 457 return TRUE; 458} 459 460FORCEINLINE 461BOOLEAN 462IsPointInRange( 463 _In_ LONGLONG Offset1, 464 _In_ LONGLONG Length1, 465 _In_ LONGLONG Point) 466{ 467 return DoRangesIntersect(Offset1, Length1, Point, 1); 468} 469 470#define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C) 471 472#if DBG 473#define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__) 474#define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__) 475#define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__) 476 477ULONG 478CcRosVacbIncRefCount_( 479 PROS_VACB vacb, 480 PCSTR file, 481 INT line); 482 483ULONG 484CcRosVacbDecRefCount_( 485 PROS_VACB vacb, 486 PCSTR file, 487 INT line); 488 489ULONG 490CcRosVacbGetRefCount_( 491 PROS_VACB vacb, 492 PCSTR file, 493 INT line); 494 495#else 496#define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount) 497FORCEINLINE 498ULONG 499CcRosVacbDecRefCount( 500 PROS_VACB vacb) 501{ 502 ULONG Refs; 503 504 Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount); 505 if (Refs == 0) 506 { 507 CcRosInternalFreeVacb(vacb); 508 } 509 return Refs; 510} 511#define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0) 512#endif 513 514BOOLEAN 515CcRosFreeOneUnusedVacb( 516 VOID);