#pragma once
+//
+// Define this if you want debugging support
+//
+#define _CC_DEBUG_ 0x00
+
+//
+// These define the Debug Masks Supported
+//
+#define CC_API_DEBUG 0x01
+
+//
+// Debug/Tracing support
+//
+#if _CC_DEBUG_
+#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
+#define CCTRACE(x, ...) \
+ { \
+ DbgPrintEx("%s [%.16s] - ", \
+ __FUNCTION__, \
+ PsGetCurrentProcess()->ImageFileName); \
+ DbgPrintEx(__VA_ARGS__); \
+ }
+#else
+#define CCTRACE(x, ...) \
+ if (x & CcRosTraceLevel) \
+ { \
+ DbgPrint("%s [%.16s] - ", \
+ __FUNCTION__, \
+ PsGetCurrentProcess()->ImageFileName); \
+ DbgPrint(__VA_ARGS__); \
+ }
+#endif
+#else
+#define CCTRACE(x, fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
+#endif
+
+//
+// Global Cc Data
+//
+extern ULONG CcRosTraceLevel;
+extern LIST_ENTRY DirtyVacbListHead;
+extern ULONG CcDirtyPageThreshold;
+extern ULONG CcTotalDirtyPages;
+extern LIST_ENTRY CcDeferredWrites;
+extern KSPIN_LOCK CcDeferredWriteSpinLock;
+extern ULONG CcNumberWorkerThreads;
+extern LIST_ENTRY CcIdleWorkerThreadList;
+extern LIST_ENTRY CcExpressWorkQueue;
+extern LIST_ENTRY CcRegularWorkQueue;
+extern LIST_ENTRY CcPostTickWorkQueue;
+extern NPAGED_LOOKASIDE_LIST CcTwilightLookasideList;
+extern LARGE_INTEGER CcIdleDelay;
+
+//
+// Counters
+//
+extern ULONG CcLazyWritePages;
+extern ULONG CcLazyWriteIos;
+extern ULONG CcMapDataWait;
+extern ULONG CcMapDataNoWait;
+extern ULONG CcPinReadWait;
+extern ULONG CcPinReadNoWait;
+extern ULONG CcPinMappedDataCount;
+extern ULONG CcDataPages;
+extern ULONG CcDataFlushes;
+
typedef struct _PF_SCENARIO_ID
{
WCHAR ScenName[30];
typedef struct _ROS_SHARED_CACHE_MAP
{
- LIST_ENTRY CacheMapVacbListHead;
- ULONG TimeStamp;
- PFILE_OBJECT FileObject;
- LARGE_INTEGER SectionSize;
+ CSHORT NodeTypeCode;
+ CSHORT NodeByteSize;
+ ULONG OpenCount;
LARGE_INTEGER FileSize;
+ LIST_ENTRY BcbList;
+ LARGE_INTEGER SectionSize;
+ PFILE_OBJECT FileObject;
+ ULONG DirtyPages;
+ LIST_ENTRY SharedCacheMapLinks;
+ ULONG Flags;
PCACHE_MANAGER_CALLBACKS Callbacks;
PVOID LazyWriteContext;
+ LIST_ENTRY PrivateList;
+ ULONG DirtyPageThreshold;
+ KSPIN_LOCK BcbSpinLock;
+ PRIVATE_CACHE_MAP PrivateCacheMap;
+
+ /* ROS specific */
+ LIST_ENTRY CacheMapVacbListHead;
+ ULONG TimeStamp;
+ BOOLEAN PinAccess;
KSPIN_LOCK CacheMapLock;
- ULONG RefCount;
#if DBG
BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */
#endif
} ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP;
+#define READAHEAD_DISABLED 0x1
+#define WRITEBEHIND_DISABLED 0x2
+
typedef struct _ROS_VACB
{
/* Base address of the region where the view's data is mapped. */
/* Entry in the list of VACBs which are dirty. */
LIST_ENTRY DirtyVacbListEntry;
/* Entry in the list of VACBs. */
- LIST_ENTRY VacbListEntry;
LIST_ENTRY VacbLruListEntry;
/* Offset in the file which this view maps. */
LARGE_INTEGER FileOffset;
- /* Mutex */
- KMUTEX Mutex;
/* Number of references. */
- ULONG ReferenceCount;
+ volatile ULONG ReferenceCount;
/* Pointer to the shared cache map for the file which this view maps data for. */
PROS_SHARED_CACHE_MAP SharedCacheMap;
/* Pointer to the next VACB in a chain. */
- struct _ROS_VACB *NextInChain;
} ROS_VACB, *PROS_VACB;
typedef struct _INTERNAL_BCB
{
+ /* Lock */
+ ERESOURCE Lock;
PUBLIC_BCB PFCB;
PROS_VACB Vacb;
BOOLEAN Dirty;
+ ULONG PinCount;
CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
+ LIST_ENTRY BcbEntry;
} INTERNAL_BCB, *PINTERNAL_BCB;
+typedef struct _LAZY_WRITER
+{
+ LIST_ENTRY WorkQueue;
+ KDPC ScanDpc;
+ KTIMER ScanTimer;
+ BOOLEAN ScanActive;
+ BOOLEAN OtherWork;
+ BOOLEAN PendingTeardown;
+} LAZY_WRITER, *PLAZY_WRITER;
+
+typedef struct _WORK_QUEUE_ENTRY
+{
+ LIST_ENTRY WorkQueueLinks;
+ union
+ {
+ struct
+ {
+ FILE_OBJECT *FileObject;
+ } Read;
+ struct
+ {
+ SHARED_CACHE_MAP *SharedCacheMap;
+ } Write;
+ struct
+ {
+ KEVENT *Event;
+ } Event;
+ struct
+ {
+ unsigned long Reason;
+ } Notification;
+ } Parameters;
+ unsigned char Function;
+} WORK_QUEUE_ENTRY, *PWORK_QUEUE_ENTRY;
+
+typedef enum _WORK_QUEUE_FUNCTIONS
+{
+ ReadAhead = 1,
+ WriteBehind = 2,
+ LazyWrite = 3,
+ SetDone = 4,
+} WORK_QUEUE_FUNCTIONS, *PWORK_QUEUE_FUNCTIONS;
+
+extern LAZY_WRITER LazyWriter;
+
+#define NODE_TYPE_DEFERRED_WRITE 0x02FC
+#define NODE_TYPE_PRIVATE_MAP 0x02FE
+#define NODE_TYPE_SHARED_MAP 0x02FF
+
VOID
NTAPI
CcPfInitializePrefetcher(
NTAPI
CcRosGetVacb(
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset,
- PULONGLONG BaseOffset,
+ LONGLONG FileOffset,
+ PLONGLONG BaseOffset,
PVOID *BaseAddress,
PBOOLEAN UptoDate,
PROS_VACB *Vacb
NTAPI
CcInitView(VOID);
+VOID
+NTAPI
+CcShutdownLazyWriter(VOID);
+
NTSTATUS
NTAPI
CcReadVirtualAddress(PROS_VACB Vacb);
NTAPI
CcRosUnmapVacb(
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset,
+ LONGLONG FileOffset,
BOOLEAN NowDirty
);
NTAPI
CcRosLookupVacb(
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset
+ LONGLONG FileOffset
);
+VOID
+NTAPI
+CcInitCacheZeroPage(VOID);
+
NTSTATUS
NTAPI
-CcRosGetVacbChain(
+CcRosMarkDirtyFile(
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset,
- ULONG Length,
- PROS_VACB *Vacb
+ LONGLONG FileOffset
);
VOID
NTAPI
-CcInitCacheZeroPage(VOID);
+CcRosMarkDirtyVacb(
+ PROS_VACB Vacb);
-NTSTATUS
+VOID
NTAPI
-CcRosMarkDirtyVacb(
- PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset
-);
+CcRosUnmarkDirtyVacb(
+ PROS_VACB Vacb,
+ BOOLEAN LockViews);
NTSTATUS
NTAPI
CcRosFlushDirtyPages(
ULONG Target,
PULONG Count,
- BOOLEAN Wait
+ BOOLEAN Wait,
+ BOOLEAN CalledFromLazy
);
VOID
NTAPI
CcRosRequestVacb(
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset,
+ LONGLONG FileOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
PROS_VACB *Vacb
NTAPI
CcRosInitializeFileCache(
PFILE_OBJECT FileObject,
+ PCC_FILE_SIZES FileSizes,
+ BOOLEAN PinAccess,
PCACHE_MANAGER_CALLBACKS CallBacks,
PVOID LazyWriterContext
);
PFILE_OBJECT FileObject
);
-NTSTATUS
+VOID
+NTAPI
+CcShutdownSystem(VOID);
+
+VOID
+NTAPI
+CcWorkerThread(PVOID Parameter);
+
+VOID
NTAPI
-CcTryToInitializeFileCache(PFILE_OBJECT FileObject);
+CcScanDpc(
+ PKDPC Dpc,
+ PVOID DeferredContext,
+ PVOID SystemArgument1,
+ PVOID SystemArgument2);
+
+VOID
+CcScheduleLazyWriteScan(BOOLEAN NoDelay);
+
+VOID
+CcPostDeferredWrites(VOID);
+
+VOID
+CcPostWorkQueue(
+ IN PWORK_QUEUE_ENTRY WorkItem,
+ IN PLIST_ENTRY WorkQueue);
+
+VOID
+CcPerformReadAhead(
+ IN PFILE_OBJECT FileObject);
+
+NTSTATUS
+CcRosInternalFreeVacb(
+ IN PROS_VACB Vacb);
FORCEINLINE
BOOLEAN
DoRangesIntersect(
- _In_ ULONGLONG Offset1,
- _In_ ULONG Length1,
- _In_ ULONGLONG Offset2,
- _In_ ULONG Length2)
+ _In_ LONGLONG Offset1,
+ _In_ LONGLONG Length1,
+ _In_ LONGLONG Offset2,
+ _In_ LONGLONG Length2)
{
if (Offset1 + Length1 <= Offset2)
return FALSE;
FORCEINLINE
BOOLEAN
IsPointInRange(
- _In_ ULONGLONG Offset1,
- _In_ ULONG Length1,
- _In_ ULONGLONG Point)
+ _In_ LONGLONG Offset1,
+ _In_ LONGLONG Length1,
+ _In_ LONGLONG Point)
{
return DoRangesIntersect(Offset1, Length1, Point, 1);
}
+
+#define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C)
+
+#if DBG
+#define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
+#define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
+#define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__)
+
+ULONG
+CcRosVacbIncRefCount_(
+ PROS_VACB vacb,
+ PCSTR file,
+ INT line);
+
+ULONG
+CcRosVacbDecRefCount_(
+ PROS_VACB vacb,
+ PCSTR file,
+ INT line);
+
+ULONG
+CcRosVacbGetRefCount_(
+ PROS_VACB vacb,
+ PCSTR file,
+ INT line);
+
+#else
+#define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount)
+FORCEINLINE
+ULONG
+CcRosVacbDecRefCount(
+ PROS_VACB vacb)
+{
+ ULONG Refs;
+
+ Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount);
+ if (Refs == 0)
+ {
+ CcRosInternalFreeVacb(vacb);
+ }
+ return Refs;
+}
+#define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0)
+#endif