ReactOS 0.4.16-dev-91-g764881a
view.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for view.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID CcRosTraceCacheMap (PROS_SHARED_CACHE_MAP SharedCacheMap, BOOLEAN Trace)
 
NTSTATUS CcRosFlushVacb (_In_ PROS_VACB Vacb, _Out_opt_ PIO_STATUS_BLOCK Iosb)
 
static NTSTATUS CcRosDeleteFileCache (PFILE_OBJECT FileObject, PROS_SHARED_CACHE_MAP SharedCacheMap, PKIRQL OldIrql)
 
NTSTATUS CcRosFlushDirtyPages (ULONG Target, PULONG Count, BOOLEAN Wait, BOOLEAN CalledFromLazy)
 
VOID CcRosTrimCache (_In_ ULONG Target, _Out_ PULONG NrFreed)
 
NTSTATUS CcRosReleaseVacb (PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Dirty, BOOLEAN Mapped)
 
PROS_VACB CcRosLookupVacb (PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset)
 
VOID CcRosMarkDirtyVacb (PROS_VACB Vacb)
 
VOID CcRosUnmarkDirtyVacb (PROS_VACB Vacb, BOOLEAN LockViews)
 
BOOLEAN CcRosFreeOneUnusedVacb (VOID)
 
static NTSTATUS CcRosCreateVacb (PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
 
BOOLEAN CcRosEnsureVacbResident (_In_ PROS_VACB Vacb, _In_ BOOLEAN Wait, _In_ BOOLEAN NoRead, _In_ ULONG Offset, _In_ ULONG Length)
 
NTSTATUS CcRosGetVacb (PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
 
NTSTATUS CcRosRequestVacb (PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
 
NTSTATUS CcRosInternalFreeVacb (PROS_VACB Vacb)
 
VOID NTAPI CcFlushCache (IN PSECTION_OBJECT_POINTERS SectionObjectPointers, IN PLARGE_INTEGER FileOffset OPTIONAL, IN ULONG Length, OUT PIO_STATUS_BLOCK IoStatus)
 
NTSTATUS CcRosReleaseFileCache (PFILE_OBJECT FileObject)
 
NTSTATUS CcRosInitializeFileCache (PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes, BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS CallBacks, PVOID LazyWriterContext)
 
PFILE_OBJECT NTAPI CcGetFileObjectFromSectionPtrs (IN PSECTION_OBJECT_POINTERS SectionObjectPointers)
 
VOID NTAPI CcInitView (VOID)
 

Variables

LIST_ENTRY DirtyVacbListHead
 
static LIST_ENTRY VacbLruListHead
 
NPAGED_LOOKASIDE_LIST iBcbLookasideList
 
static NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList
 
static NPAGED_LOOKASIDE_LIST VacbLookasideList
 
ULONG CcDirtyPageThreshold = 0
 
ULONG CcTotalDirtyPages = 0
 
LIST_ENTRY CcDeferredWrites
 
KSPIN_LOCK CcDeferredWriteSpinLock
 
LIST_ENTRY CcCleanSharedCacheMapList
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 36 of file view.c.

Function Documentation

◆ CcFlushCache()

VOID NTAPI CcFlushCache ( IN PSECTION_OBJECT_POINTERS  SectionObjectPointers,
IN PLARGE_INTEGER FileOffset  OPTIONAL,
IN ULONG  Length,
OUT PIO_STATUS_BLOCK  IoStatus 
)

Definition at line 1102 of file view.c.

1107{
1108 PROS_SHARED_CACHE_MAP SharedCacheMap;
1109 LONGLONG FlushStart, FlushEnd;
1111
1112 CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p FileOffset=0x%I64X Length=%lu\n",
1113 SectionObjectPointers, FileOffset ? FileOffset->QuadPart : 0LL, Length);
1114
1115 if (!SectionObjectPointers)
1116 {
1118 goto quit;
1119 }
1120
1121 if (!SectionObjectPointers->SharedCacheMap)
1122 {
1123 /* Forward this to Mm */
1124 MmFlushSegment(SectionObjectPointers, FileOffset, Length, IoStatus);
1125 return;
1126 }
1127
1128 SharedCacheMap = SectionObjectPointers->SharedCacheMap;
1129 ASSERT(SharedCacheMap);
1130 if (FileOffset)
1131 {
1132 FlushStart = FileOffset->QuadPart;
1133 Status = RtlLongLongAdd(FlushStart, Length, &FlushEnd);
1134 if (!NT_SUCCESS(Status))
1135 goto quit;
1136 }
1137 else
1138 {
1139 FlushStart = 0;
1140 FlushEnd = SharedCacheMap->FileSize.QuadPart;
1141 }
1142
1144 if (IoStatus)
1145 {
1146 IoStatus->Information = 0;
1147 }
1148
1149 KeAcquireGuardedMutex(&SharedCacheMap->FlushCacheLock);
1150
1151 /*
1152 * We flush the VACBs that we find here.
1153 * If there is no (dirty) VACB, it doesn't mean that there is no data to flush, so we call Mm to be sure.
1154 * This is suboptimal, but this is due to the lack of granularity of how we track dirty cache data
1155 */
1156 while (FlushStart < FlushEnd)
1157 {
1158 BOOLEAN DirtyVacb = FALSE;
1159 PROS_VACB vacb = CcRosLookupVacb(SharedCacheMap, FlushStart);
1160
1161 if (vacb != NULL)
1162 {
1163 if (vacb->Dirty)
1164 {
1165 IO_STATUS_BLOCK VacbIosb = { 0 };
1166 Status = CcRosFlushVacb(vacb, &VacbIosb);
1167 if (!NT_SUCCESS(Status))
1168 {
1169 CcRosReleaseVacb(SharedCacheMap, vacb, FALSE, FALSE);
1170 break;
1171 }
1172 DirtyVacb = TRUE;
1173
1174 if (IoStatus)
1175 IoStatus->Information += VacbIosb.Information;
1176 }
1177
1178 CcRosReleaseVacb(SharedCacheMap, vacb, FALSE, FALSE);
1179 }
1180
1181 if (!DirtyVacb)
1182 {
1183 IO_STATUS_BLOCK MmIosb;
1184 LARGE_INTEGER MmOffset;
1185
1186 MmOffset.QuadPart = FlushStart;
1187
1188 if (FlushEnd - (FlushEnd % VACB_MAPPING_GRANULARITY) <= FlushStart)
1189 {
1190 /* The whole range fits within a VACB chunk. */
1191 Status = MmFlushSegment(SectionObjectPointers, &MmOffset, FlushEnd - FlushStart, &MmIosb);
1192 }
1193 else
1194 {
1195 ULONG MmLength = VACB_MAPPING_GRANULARITY - (FlushStart % VACB_MAPPING_GRANULARITY);
1196 Status = MmFlushSegment(SectionObjectPointers, &MmOffset, MmLength, &MmIosb);
1197 }
1198
1199 if (!NT_SUCCESS(Status))
1200 break;
1201
1202 if (IoStatus)
1203 IoStatus->Information += MmIosb.Information;
1204
1205 /* Update VDL */
1206 if (SharedCacheMap->ValidDataLength.QuadPart < FlushEnd)
1207 SharedCacheMap->ValidDataLength.QuadPart = FlushEnd;
1208 }
1209
1210 if (!NT_SUCCESS(RtlLongLongAdd(FlushStart, VACB_MAPPING_GRANULARITY, &FlushStart)))
1211 {
1212 /* We're at the end of file ! */
1213 break;
1214 }
1215
1216 /* Round down to next VACB start now */
1217 FlushStart -= FlushStart % VACB_MAPPING_GRANULARITY;
1218 }
1219
1220 KeReleaseGuardedMutex(&SharedCacheMap->FlushCacheLock);
1221
1222quit:
1223 if (IoStatus)
1224 {
1225 IoStatus->Status = Status;
1226 }
1227}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
void quit(int argc, const char *argv[])
Definition: cmds.c:1606
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define ASSERT(a)
Definition: mode.c:44
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS CcRosReleaseVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Dirty, BOOLEAN Mapped)
Definition: view.c:591
NTSTATUS CcRosFlushVacb(_In_ PROS_VACB Vacb, _Out_opt_ PIO_STATUS_BLOCK Iosb)
Definition: view.c:162
PROS_VACB CcRosLookupVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset)
Definition: view.c:623
#define CC_API_DEBUG
Definition: cc.h:11
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
NTSTATUS NTAPI MmFlushSegment(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length, _Out_opt_ PIO_STATUS_BLOCK Iosb)
Definition: section.c:4940
#define STATUS_SUCCESS
Definition: shellext.h:65
LARGE_INTEGER FileSize
Definition: cc.h:175
LARGE_INTEGER ValidDataLength
Definition: cc.h:178
KGUARDED_MUTEX FlushCacheLock
Definition: cc.h:196
Definition: cc.h:208
BOOLEAN Dirty
Definition: cc.h:212
#define LL
Definition: tui.h:167
int64_t LONGLONG
Definition: typedefs.h:68
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONGLONG QuadPart
Definition: typedefs.h:114
#define VACB_MAPPING_GRANULARITY

◆ CcGetFileObjectFromSectionPtrs()

PFILE_OBJECT NTAPI CcGetFileObjectFromSectionPtrs ( IN PSECTION_OBJECT_POINTERS  SectionObjectPointers)

Definition at line 1457 of file view.c.

1459{
1460 PROS_SHARED_CACHE_MAP SharedCacheMap;
1461
1462 CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p\n", SectionObjectPointers);
1463
1464 if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap)
1465 {
1466 SharedCacheMap = SectionObjectPointers->SharedCacheMap;
1467 ASSERT(SharedCacheMap);
1468 return SharedCacheMap->FileObject;
1469 }
1470 return NULL;
1471}
PFILE_OBJECT FileObject
Definition: cc.h:179

◆ CcInitView()

VOID NTAPI CcInitView ( VOID  )

Definition at line 1476 of file view.c.

1478{
1479 DPRINT("CcInitView()\n");
1480
1487 NULL,
1488 NULL,
1489 0,
1490 sizeof(INTERNAL_BCB),
1491 TAG_BCB,
1492 20);
1494 NULL,
1495 NULL,
1496 0,
1497 sizeof(ROS_SHARED_CACHE_MAP),
1499 20);
1501 NULL,
1502 NULL,
1503 0,
1504 sizeof(ROS_VACB),
1505 TAG_VACB,
1506 20);
1507
1509}
#define TAG_BCB
Definition: nodetype.h:157
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
VOID NTAPI CcInitCacheZeroPage(VOID)
Definition: copy.c:56
LIST_ENTRY CcCleanSharedCacheMapList
Definition: view.c:59
static LIST_ENTRY VacbLruListHead
Definition: view.c:42
KSPIN_LOCK CcDeferredWriteSpinLock
Definition: view.c:58
LIST_ENTRY CcDeferredWrites
Definition: view.c:57
NPAGED_LOOKASIDE_LIST iBcbLookasideList
Definition: view.c:44
LIST_ENTRY DirtyVacbListHead
Definition: view.c:41
static NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList
Definition: view.c:45
static NPAGED_LOOKASIDE_LIST VacbLookasideList
Definition: view.c:46
#define DPRINT
Definition: sndvol32.h:73
#define TAG_SHARED_CACHE_MAP
Definition: tag.h:16
#define TAG_VACB
Definition: tag.h:15

Referenced by CcInitializeCacheManager().

◆ CcRosCreateVacb()

static NTSTATUS CcRosCreateVacb ( PROS_SHARED_CACHE_MAP  SharedCacheMap,
LONGLONG  FileOffset,
PROS_VACB Vacb 
)
static

Definition at line 797 of file view.c.

801{
803 PROS_VACB previous;
804 PLIST_ENTRY current_entry;
806 KIRQL oldIrql;
807 ULONG Refs;
809
810 ASSERT(SharedCacheMap);
811
812 DPRINT("CcRosCreateVacb()\n");
813
814 current = ExAllocateFromNPagedLookasideList(&VacbLookasideList);
815 if (!current)
816 {
818 }
819 current->BaseAddress = NULL;
820 current->Dirty = FALSE;
821 current->PageOut = FALSE;
822 current->FileOffset.QuadPart = ROUND_DOWN(FileOffset, VACB_MAPPING_GRANULARITY);
823 current->SharedCacheMap = SharedCacheMap;
824 current->MappedCount = 0;
825 current->ReferenceCount = 0;
826 InitializeListHead(&current->CacheMapVacbListEntry);
827 InitializeListHead(&current->DirtyVacbListEntry);
828 InitializeListHead(&current->VacbLruListEntry);
829
831
832 while (TRUE)
833 {
834 /* Map VACB in system space */
835 Status = MmMapViewInSystemSpaceEx(SharedCacheMap->Section, &current->BaseAddress, &ViewSize, &current->FileOffset, 0);
836 if (NT_SUCCESS(Status))
837 {
838 break;
839 }
840
841 /*
842 * If no space left, try to prune one unused VACB to recover space to map our VACB.
843 * If it succeeds, retry to map, otherwise just fail.
844 */
846 {
847 ExFreeToNPagedLookasideList(&VacbLookasideList, current);
848 return Status;
849 }
850 }
851
852#if DBG
853 if (SharedCacheMap->Trace)
854 {
855 DPRINT1("CacheMap 0x%p: new VACB: 0x%p, file offset %I64d, BaseAddress %p\n",
856 SharedCacheMap, current, current->FileOffset.QuadPart, current->BaseAddress);
857 }
858#endif
859
861
862 *Vacb = current;
863 /* There is window between the call to CcRosLookupVacb
864 * and CcRosCreateVacb. We must check if a VACB for the
865 * file offset exist. If there is a VACB, we release
866 * our newly created VACB and return the existing one.
867 */
869 current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
870 previous = NULL;
871 while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
872 {
873 current = CONTAINING_RECORD(current_entry,
874 ROS_VACB,
875 CacheMapVacbListEntry);
876 if (IsPointInRange(current->FileOffset.QuadPart,
878 FileOffset))
879 {
882#if DBG
883 if (SharedCacheMap->Trace)
884 {
885 DPRINT1("CacheMap 0x%p: deleting newly created VACB 0x%p ( found existing one 0x%p )\n",
886 SharedCacheMap,
887 (*Vacb),
888 current);
889 }
890#endif
892
893 Refs = CcRosVacbDecRefCount(*Vacb);
894 ASSERT(Refs == 0);
895
896 *Vacb = current;
897 return STATUS_SUCCESS;
898 }
899 if (current->FileOffset.QuadPart < FileOffset)
900 {
901 ASSERT(previous == NULL ||
902 previous->FileOffset.QuadPart < current->FileOffset.QuadPart);
903 previous = current;
904 }
905 if (current->FileOffset.QuadPart > FileOffset)
906 break;
907 current_entry = current_entry->Flink;
908 }
909 /* There was no existing VACB. */
910 current = *Vacb;
911 if (previous)
912 {
913 InsertHeadList(&previous->CacheMapVacbListEntry, &current->CacheMapVacbListEntry);
914 }
915 else
916 {
917 InsertHeadList(&SharedCacheMap->CacheMapVacbListHead, &current->CacheMapVacbListEntry);
918 }
920 InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
921
922 /* Reference it to allow release */
924
926
927 return Status;
928}
#define DPRINT1
Definition: precomp.h:8
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
struct task_struct * current
Definition: linux.c:32
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
BOOLEAN CcRosFreeOneUnusedVacb(VOID)
Definition: view.c:737
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:496
FORCEINLINE BOOLEAN IsPointInRange(_In_ LONGLONG Offset1, _In_ LONGLONG Length1, _In_ LONGLONG Point)
Definition: cc.h:462
FORCEINLINE ULONG CcRosVacbDecRefCount(PROS_VACB vacb)
Definition: cc.h:499
NTSTATUS NTAPI MmMapViewInSystemSpaceEx(_In_ PVOID Section, _Outptr_result_bytebuffer_(*ViewSize) PVOID *MappedBase, _Inout_ PSIZE_T ViewSize, _Inout_ PLARGE_INTEGER SectionOffset, _In_ ULONG_PTR Flags)
Definition: section.c:4460
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY CacheMapVacbListHead
Definition: cc.h:193
KSPIN_LOCK CacheMapLock
Definition: cc.h:195
LIST_ENTRY CacheMapVacbListEntry
Definition: cc.h:217
LARGE_INTEGER FileOffset
Definition: cc.h:223
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
@ LockQueueMasterLock
Definition: ketypes.h:663

Referenced by CcRosGetVacb().

◆ CcRosDeleteFileCache()

static NTSTATUS CcRosDeleteFileCache ( PFILE_OBJECT  FileObject,
PROS_SHARED_CACHE_MAP  SharedCacheMap,
PKIRQL  OldIrql 
)
static

Definition at line 208 of file view.c.

215{
216 PLIST_ENTRY current_entry;
217
218 ASSERT(SharedCacheMap);
219 ASSERT(SharedCacheMap == FileObject->SectionObjectPointer->SharedCacheMap);
220 ASSERT(SharedCacheMap->OpenCount == 0);
221
222 /* Remove all VACBs from the global lists */
224 current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
225 while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
226 {
227 PROS_VACB Vacb = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
228
231
232 if (Vacb->Dirty)
233 {
235 /* Mark it as dirty again so we know that we have to flush before freeing it */
236 Vacb->Dirty = TRUE;
237 }
238
239 current_entry = current_entry->Flink;
240 }
241
242 /* Make sure there is no trace anymore of this map */
243 FileObject->SectionObjectPointer->SharedCacheMap = NULL;
244 RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
245
248
249 /* Now that we're out of the locks, free everything for real */
250 while (!IsListEmpty(&SharedCacheMap->CacheMapVacbListHead))
251 {
252 PROS_VACB Vacb = CONTAINING_RECORD(RemoveHeadList(&SharedCacheMap->CacheMapVacbListHead), ROS_VACB, CacheMapVacbListEntry);
253 ULONG RefCount;
254
256
257 /* Flush to disk, if needed */
258 if (Vacb->Dirty)
259 {
262
263 Status = MmFlushSegment(FileObject->SectionObjectPointer, &Vacb->FileOffset, VACB_MAPPING_GRANULARITY, &Iosb);
264 if (!NT_SUCCESS(Status))
265 {
266 /* Complain. There's not much we can do */
267 DPRINT1("Failed to flush VACB to disk while deleting the cache entry. Status: 0x%08x\n", Status);
268 }
269 Vacb->Dirty = FALSE;
270 }
271
272 RefCount = CcRosVacbDecRefCount(Vacb);
273#if DBG // CORE-14578
274 if (RefCount != 0)
275 {
276 DPRINT1("Leaking VACB %p attached to %p (%I64d)\n", Vacb, FileObject, Vacb->FileOffset.QuadPart);
277 DPRINT1("There are: %d references left\n", RefCount);
278 DPRINT1("Map: %d\n", Vacb->MappedCount);
279 DPRINT1("Dirty: %d\n", Vacb->Dirty);
280 if (FileObject->FileName.Length != 0)
281 {
282 DPRINT1("File was: %wZ\n", &FileObject->FileName);
283 }
284 else
285 {
286 DPRINT1("No name for the file\n");
287 }
288 }
289#else
290 (void)RefCount;
291#endif
292 }
293
294 /* Release the references we own */
295 if(SharedCacheMap->Section)
296 ObDereferenceObject(SharedCacheMap->Section);
297 ObDereferenceObject(SharedCacheMap->FileObject);
298
299 ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap);
300
301 /* Acquire the lock again for our caller */
303
304 return STATUS_SUCCESS;
305}
return Iosb
Definition: create.c:4402
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
VOID CcRosUnmarkDirtyVacb(PROS_VACB Vacb, BOOLEAN LockViews)
Definition: view.c:702
LIST_ENTRY SharedCacheMapLinks
Definition: cc.h:181
ULONG OpenCount
Definition: cc.h:174
ULONG MappedCount
Definition: cc.h:215
LIST_ENTRY VacbLruListEntry
Definition: cc.h:221
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by CcRosFlushDirtyPages(), and CcRosReleaseFileCache().

◆ CcRosEnsureVacbResident()

BOOLEAN CcRosEnsureVacbResident ( _In_ PROS_VACB  Vacb,
_In_ BOOLEAN  Wait,
_In_ BOOLEAN  NoRead,
_In_ ULONG  Offset,
_In_ ULONG  Length 
)

Definition at line 931 of file view.c.

938{
940
942
943#if 0
944 if ((Vacb->FileOffset.QuadPart + Offset) > Vacb->SharedCacheMap->SectionSize.QuadPart)
945 {
946 DPRINT1("Vacb read beyond the file size!\n");
947 return FALSE;
948 }
949#endif
950
951 BaseAddress = (PVOID)((ULONG_PTR)Vacb->BaseAddress + Offset);
952
953 /* Check if the pages are resident */
955 {
956 if (!Wait)
957 {
958 return FALSE;
959 }
960
961 if (!NoRead)
962 {
963 PROS_SHARED_CACHE_MAP SharedCacheMap = Vacb->SharedCacheMap;
964 NTSTATUS Status = MmMakeDataSectionResident(SharedCacheMap->FileObject->SectionObjectPointer,
965 Vacb->FileOffset.QuadPart + Offset,
966 Length,
967 &SharedCacheMap->ValidDataLength);
968 if (!NT_SUCCESS(Status))
970 }
971 }
972
973 return TRUE;
974}
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
BOOLEAN NTAPI MmArePagesResident(_In_ PEPROCESS Process, _In_ PVOID BaseAddress, _In_ ULONG Length)
Definition: section.c:4775
NTSTATUS NTAPI MmMakeDataSectionResident(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_ LONGLONG Offset, _In_ ULONG Length, _In_ PLARGE_INTEGER ValidDataLength)
Definition: section.c:4920
#define ExRaiseStatus
Definition: ntoskrnl.h:114
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170

Referenced by CcCopyRead(), CcCopyWrite(), CcMapData(), CcPerformReadAhead(), CcpPinData(), and CcZeroData().

◆ CcRosFlushDirtyPages()

NTSTATUS CcRosFlushDirtyPages ( ULONG  Target,
PULONG  Count,
BOOLEAN  Wait,
BOOLEAN  CalledFromLazy 
)

Definition at line 308 of file view.c.

313{
314 PLIST_ENTRY current_entry;
317 BOOLEAN FlushAll = (Target == MAXULONG);
318
319 DPRINT("CcRosFlushDirtyPages(Target %lu)\n", Target);
320
321 (*Count) = 0;
322
325
326 current_entry = DirtyVacbListHead.Flink;
327 if (current_entry == &DirtyVacbListHead)
328 {
329 DPRINT("No Dirty pages\n");
330 }
331
332 while (((current_entry != &DirtyVacbListHead) && (Target > 0)) || FlushAll)
333 {
334 PROS_SHARED_CACHE_MAP SharedCacheMap;
337
338 if (current_entry == &DirtyVacbListHead)
339 {
340 ASSERT(FlushAll);
342 break;
343 current_entry = DirtyVacbListHead.Flink;
344 }
345
346 current = CONTAINING_RECORD(current_entry,
347 ROS_VACB,
348 DirtyVacbListEntry);
349 current_entry = current_entry->Flink;
350
352
353 SharedCacheMap = current->SharedCacheMap;
354
355 /* When performing lazy write, don't handle temporary files */
356 if (CalledFromLazy && BooleanFlagOn(SharedCacheMap->FileObject->Flags, FO_TEMPORARY_FILE))
357 {
359 continue;
360 }
361
362 /* Don't attempt to lazy write the files that asked not to */
363 if (CalledFromLazy && BooleanFlagOn(SharedCacheMap->Flags, WRITEBEHIND_DISABLED))
364 {
366 continue;
367 }
368
369 ASSERT(current->Dirty);
370
371 /* Do not lazy-write the same file concurrently. Fastfat ASSERTS on that */
372 if (SharedCacheMap->Flags & SHARED_CACHE_MAP_IN_LAZYWRITE)
373 {
375 continue;
376 }
377
378 SharedCacheMap->Flags |= SHARED_CACHE_MAP_IN_LAZYWRITE;
379
380 /* Keep a ref on the shared cache map */
381 SharedCacheMap->OpenCount++;
382
384
385 Locked = SharedCacheMap->Callbacks->AcquireForLazyWrite(SharedCacheMap->LazyWriteContext, Wait);
386 if (!Locked)
387 {
388 DPRINT("Not locked!");
389 ASSERT(!Wait);
392 SharedCacheMap->Flags &= ~SHARED_CACHE_MAP_IN_LAZYWRITE;
393
394 if (--SharedCacheMap->OpenCount == 0)
395 CcRosDeleteFileCache(SharedCacheMap->FileObject, SharedCacheMap, &OldIrql);
396
397 continue;
398 }
399
402
403 SharedCacheMap->Callbacks->ReleaseFromLazyWrite(SharedCacheMap->LazyWriteContext);
404
405 /* We release the VACB before acquiring the lock again, because
406 * CcRosVacbDecRefCount might free the VACB, as CcRosFlushVacb dropped a
407 * Refcount. Freeing must be done outside of the lock.
408 * The refcount is decremented atomically. So this is OK. */
411
412 SharedCacheMap->Flags &= ~SHARED_CACHE_MAP_IN_LAZYWRITE;
413
414 if (--SharedCacheMap->OpenCount == 0)
415 CcRosDeleteFileCache(SharedCacheMap->FileObject, SharedCacheMap, &OldIrql);
416
419 {
420 DPRINT1("CC: Failed to flush VACB.\n");
421 }
422 else
423 {
424 ULONG PagesFreed;
425
426 /* How many pages did we free? */
427 PagesFreed = Iosb.Information / PAGE_SIZE;
428 (*Count) += PagesFreed;
429
430 if (!Wait)
431 {
432 /* Make sure we don't overflow target! */
433 if (Target < PagesFreed)
434 {
435 /* If we would have, jump to zero directly */
436 Target = 0;
437 }
438 else
439 {
440 Target -= PagesFreed;
441 }
442 }
443 }
444
445 current_entry = DirtyVacbListHead.Flink;
446 }
447
450
451 DPRINT("CcRosFlushDirtyPages() finished\n");
452 return STATUS_SUCCESS;
453}
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
static NTSTATUS CcRosDeleteFileCache(PFILE_OBJECT FileObject, PROS_SHARED_CACHE_MAP SharedCacheMap, PKIRQL OldIrql)
Definition: view.c:208
#define WRITEBEHIND_DISABLED
Definition: cc.h:203
#define SHARED_CACHE_MAP_IN_LAZYWRITE
Definition: cc.h:205
#define STATUS_END_OF_FILE
Definition: shellext.h:67
PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite
Definition: cctypes.h:39
PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite
Definition: cctypes.h:40
PCACHE_MANAGER_CALLBACKS Callbacks
Definition: cc.h:185
PVOID LazyWriteContext
Definition: cc.h:186
#define MAXULONG
Definition: typedefs.h:251
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
#define FO_TEMPORARY_FILE
Definition: iotypes.h:1791

Referenced by CcRosTrimCache(), CcWriteBehind(), and NtSetSystemPowerState().

◆ CcRosFlushVacb()

NTSTATUS CcRosFlushVacb ( _In_ PROS_VACB  Vacb,
_Out_opt_ PIO_STATUS_BLOCK  Iosb 
)

Definition at line 162 of file view.c.

165{
167 BOOLEAN HaveLock = FALSE;
168 PROS_SHARED_CACHE_MAP SharedCacheMap = Vacb->SharedCacheMap;
169
171
172 /* Lock for flush, if we are not already the top-level */
174 {
175 Status = FsRtlAcquireFileForCcFlushEx(Vacb->SharedCacheMap->FileObject);
176 if (!NT_SUCCESS(Status))
177 goto quit;
178 HaveLock = TRUE;
179 }
180
181 Status = MmFlushSegment(SharedCacheMap->FileObject->SectionObjectPointer,
182 &Vacb->FileOffset,
184 Iosb);
185
186 if (HaveLock)
187 {
188 FsRtlReleaseFileForCcFlush(Vacb->SharedCacheMap->FileObject);
189 }
190
191quit:
192 if (!NT_SUCCESS(Status))
193 CcRosMarkDirtyVacb(Vacb);
194 else
195 {
196 /* Update VDL */
197 if (SharedCacheMap->ValidDataLength.QuadPart < (Vacb->FileOffset.QuadPart + VACB_MAPPING_GRANULARITY))
198 {
199 SharedCacheMap->ValidDataLength.QuadPart = Vacb->FileOffset.QuadPart + VACB_MAPPING_GRANULARITY;
200 }
201 }
202
203 return Status;
204}
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
VOID CcRosMarkDirtyVacb(PROS_VACB Vacb)
Definition: view.c:666
NTSTATUS NTAPI FsRtlAcquireFileForCcFlushEx(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1692
VOID NTAPI FsRtlReleaseFileForCcFlush(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1765
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843

Referenced by CcFlushCache(), and CcRosFlushDirtyPages().

◆ CcRosFreeOneUnusedVacb()

BOOLEAN CcRosFreeOneUnusedVacb ( VOID  )

Definition at line 737 of file view.c.

739{
740 KIRQL oldIrql;
741 PLIST_ENTRY current_entry;
742 PROS_VACB to_free = NULL;
743
745
746 /* Browse all the available VACB */
747 current_entry = VacbLruListHead.Flink;
748 while ((current_entry != &VacbLruListHead) && (to_free == NULL))
749 {
750 ULONG Refs;
752
753 current = CONTAINING_RECORD(current_entry,
754 ROS_VACB,
755 VacbLruListEntry);
756
757 KeAcquireSpinLockAtDpcLevel(&current->SharedCacheMap->CacheMapLock);
758
759 /* Only deal with unused VACB, we will free them */
761 if (Refs < 2)
762 {
763 ASSERT(!current->Dirty);
764 ASSERT(!current->MappedCount);
765 ASSERT(Refs == 1);
766
767 /* Reset it, this is the one we want to free */
768 RemoveEntryList(&current->CacheMapVacbListEntry);
769 InitializeListHead(&current->CacheMapVacbListEntry);
770 RemoveEntryList(&current->VacbLruListEntry);
771 InitializeListHead(&current->VacbLruListEntry);
772
773 to_free = current;
774 }
775
776 KeReleaseSpinLockFromDpcLevel(&current->SharedCacheMap->CacheMapLock);
777
778 current_entry = current_entry->Flink;
779 }
780
782
783 /* And now, free the VACB that we found, if any. */
784 if (to_free == NULL)
785 {
786 return FALSE;
787 }
788
789 /* This must be its last ref */
790 NT_VERIFY(CcRosVacbDecRefCount(to_free) == 0);
791
792 return TRUE;
793}
#define CcRosVacbGetRefCount(vacb)
Definition: cc.h:511
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3301

Referenced by CcRosCreateVacb(), and CcWriteBehind().

◆ CcRosGetVacb()

NTSTATUS CcRosGetVacb ( PROS_SHARED_CACHE_MAP  SharedCacheMap,
LONGLONG  FileOffset,
PROS_VACB Vacb 
)

Definition at line 978 of file view.c.

982{
985 ULONG Refs;
987
988 ASSERT(SharedCacheMap);
989
990 DPRINT("CcRosGetVacb()\n");
991
992 /*
993 * Look for a VACB already mapping the same data.
994 */
995 current = CcRosLookupVacb(SharedCacheMap, FileOffset);
996 if (current == NULL)
997 {
998 /*
999 * Otherwise create a new VACB.
1000 */
1001 Status = CcRosCreateVacb(SharedCacheMap, FileOffset, &current);
1002 if (!NT_SUCCESS(Status))
1003 {
1004 return Status;
1005 }
1006 }
1007
1009
1011
1012 /* Move to the tail of the LRU list */
1013 RemoveEntryList(&current->VacbLruListEntry);
1014 InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
1015
1017
1018 /*
1019 * Return the VACB to the caller.
1020 */
1021 *Vacb = current;
1022
1023 ASSERT(Refs > 1);
1024
1025 return STATUS_SUCCESS;
1026}
static NTSTATUS CcRosCreateVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:797

Referenced by CcCopyRead(), CcCopyWrite(), CcMapData(), CcpPinData(), CcRosRequestVacb(), and CcZeroData().

◆ CcRosInitializeFileCache()

NTSTATUS CcRosInitializeFileCache ( PFILE_OBJECT  FileObject,
PCC_FILE_SIZES  FileSizes,
BOOLEAN  PinAccess,
PCACHE_MANAGER_CALLBACKS  CallBacks,
PVOID  LazyWriterContext 
)

Definition at line 1286 of file view.c.

1295{
1296 KIRQL OldIrql;
1298 PROS_SHARED_CACHE_MAP SharedCacheMap;
1299
1300 DPRINT("CcRosInitializeFileCache(FileObject 0x%p)\n", FileObject);
1301
1303
1304 Allocated = FALSE;
1305 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
1306 if (SharedCacheMap == NULL)
1307 {
1308 Allocated = TRUE;
1309 SharedCacheMap = ExAllocateFromNPagedLookasideList(&SharedCacheMapLookasideList);
1310 if (SharedCacheMap == NULL)
1311 {
1313 }
1314 RtlZeroMemory(SharedCacheMap, sizeof(*SharedCacheMap));
1315 SharedCacheMap->NodeTypeCode = NODE_TYPE_SHARED_MAP;
1316 SharedCacheMap->NodeByteSize = sizeof(*SharedCacheMap);
1317 SharedCacheMap->FileObject = FileObject;
1318 SharedCacheMap->Callbacks = CallBacks;
1319 SharedCacheMap->LazyWriteContext = LazyWriterContext;
1320 SharedCacheMap->SectionSize = FileSizes->AllocationSize;
1321 SharedCacheMap->FileSize = FileSizes->FileSize;
1322 SharedCacheMap->ValidDataLength = FileSizes->ValidDataLength;
1323 SharedCacheMap->PinAccess = PinAccess;
1324 SharedCacheMap->DirtyPageThreshold = 0;
1325 SharedCacheMap->DirtyPages = 0;
1326 InitializeListHead(&SharedCacheMap->PrivateList);
1327 KeInitializeSpinLock(&SharedCacheMap->CacheMapLock);
1328 InitializeListHead(&SharedCacheMap->CacheMapVacbListHead);
1329 InitializeListHead(&SharedCacheMap->BcbList);
1330 KeInitializeGuardedMutex(&SharedCacheMap->FlushCacheLock);
1331
1332 SharedCacheMap->Flags = SHARED_CACHE_MAP_IN_CREATION;
1333
1336 NULL,
1337 KernelMode);
1338
1339 FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap;
1340
1341 //CcRosTraceCacheMap(SharedCacheMap, TRUE);
1342 }
1343 else if (SharedCacheMap->Flags & SHARED_CACHE_MAP_IN_CREATION)
1344 {
1345 /* The shared cache map is being created somewhere else. Wait for that to happen */
1346 KEVENT Waiter;
1347 PKEVENT PreviousWaiter = SharedCacheMap->CreateEvent;
1348
1350 SharedCacheMap->CreateEvent = &Waiter;
1351
1353
1355
1356 if (PreviousWaiter)
1357 KeSetEvent(PreviousWaiter, IO_NO_INCREMENT, FALSE);
1358
1360 }
1361
1362 if (FileObject->PrivateCacheMap == NULL)
1363 {
1364 PPRIVATE_CACHE_MAP PrivateMap;
1365
1366 /* Allocate the private cache map for this handle */
1367 if (SharedCacheMap->PrivateCacheMap.NodeTypeCode != 0)
1368 {
1370 }
1371 else
1372 {
1373 PrivateMap = &SharedCacheMap->PrivateCacheMap;
1374 }
1375
1376 if (PrivateMap == NULL)
1377 {
1378 /* If we also allocated the shared cache map for this file, kill it */
1379 if (Allocated)
1380 {
1381 RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
1382
1383 FileObject->SectionObjectPointer->SharedCacheMap = NULL;
1385 ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap);
1386 }
1387
1390 }
1391
1392 /* Initialize it */
1393 RtlZeroMemory(PrivateMap, sizeof(PRIVATE_CACHE_MAP));
1394 PrivateMap->NodeTypeCode = NODE_TYPE_PRIVATE_MAP;
1395 PrivateMap->ReadAheadMask = PAGE_SIZE - 1;
1396 PrivateMap->FileObject = FileObject;
1398
1399 /* Link it to the file */
1400 KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
1401 InsertTailList(&SharedCacheMap->PrivateList, &PrivateMap->PrivateLinks);
1403
1404 FileObject->PrivateCacheMap = PrivateMap;
1405 SharedCacheMap->OpenCount++;
1406 }
1407
1409
1410 /* Create the section */
1411 if (Allocated)
1412 {
1414
1415 ASSERT(SharedCacheMap->Section == NULL);
1416
1418 &SharedCacheMap->Section,
1420 NULL,
1421 &SharedCacheMap->SectionSize,
1424 NULL,
1425 FileObject);
1426
1428
1429 if (!NT_SUCCESS(Status))
1430 {
1432 return Status;
1433 }
1434
1436
1438 SharedCacheMap->Flags &= ~SHARED_CACHE_MAP_IN_CREATION;
1439
1440 if (SharedCacheMap->CreateEvent)
1441 {
1442 KeSetEvent(SharedCacheMap->CreateEvent, IO_NO_INCREMENT, FALSE);
1443 SharedCacheMap->CreateEvent = NULL;
1444 }
1445
1447 }
1448
1449 return STATUS_SUCCESS;
1450}
static CC_FILE_SIZES FileSizes
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define NonPagedPool
Definition: env_spec_w32.h:307
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
Definition: fatprocs.h:311
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define KernelMode
Definition: asm.h:34
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define SEC_RESERVE
Definition: nt_native.h:1323
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
@ NotificationEvent
NTSTATUS CcRosReleaseFileCache(PFILE_OBJECT FileObject)
Definition: view.c:1230
#define NODE_TYPE_PRIVATE_MAP
Definition: cc.h:288
#define SHARED_CACHE_MAP_IN_CREATION
Definition: cc.h:204
#define NODE_TYPE_SHARED_MAP
Definition: cc.h:289
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
NTSTATUS NTAPI MmCreateSection(OUT PVOID *Section, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
Definition: section.c:4620
LARGE_INTEGER FileSize
Definition: cctypes.h:16
LARGE_INTEGER ValidDataLength
Definition: cctypes.h:17
LARGE_INTEGER AllocationSize
Definition: cctypes.h:15
PFILE_OBJECT FileObject
Definition: cctypes.h:76
ULONG ReadAheadMask
Definition: cctypes.h:75
KSPIN_LOCK ReadAheadSpinLock
Definition: cctypes.h:83
CSHORT NodeTypeCode
Definition: cctypes.h:71
LIST_ENTRY PrivateLinks
Definition: cctypes.h:84
PRIVATE_CACHE_MAP PrivateCacheMap
Definition: cc.h:190
PKEVENT CreateEvent
Definition: cc.h:184
CSHORT NodeTypeCode
Definition: cc.h:172
ULONG DirtyPageThreshold
Definition: cc.h:188
ULONG DirtyPages
Definition: cc.h:180
LIST_ENTRY PrivateList
Definition: cc.h:187
LARGE_INTEGER SectionSize
Definition: cc.h:177
CSHORT NodeByteSize
Definition: cc.h:173
BOOLEAN PinAccess
Definition: cc.h:194
LIST_ENTRY BcbList
Definition: cc.h:176
#define TAG_PRIVATE_CACHE_MAP
Definition: tag.h:17
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ Executive
Definition: ketypes.h:415

Referenced by CcInitializeCacheMap().

◆ CcRosInternalFreeVacb()

NTSTATUS CcRosInternalFreeVacb ( PROS_VACB  Vacb)

Definition at line 1053 of file view.c.

1058{
1060
1061 DPRINT("Freeing VACB 0x%p\n", Vacb);
1062#if DBG
1063 if (Vacb->SharedCacheMap->Trace)
1064 {
1065 DPRINT1("CacheMap 0x%p: deleting VACB: 0x%p\n", Vacb->SharedCacheMap, Vacb);
1066 }
1067#endif
1068
1069 if (Vacb->ReferenceCount != 0)
1070 {
1071 DPRINT1("Invalid free: %ld\n", Vacb->ReferenceCount);
1072 if (Vacb->SharedCacheMap->FileObject && Vacb->SharedCacheMap->FileObject->FileName.Length)
1073 {
1074 DPRINT1("For file: %wZ\n", &Vacb->SharedCacheMap->FileObject->FileName);
1075 }
1076 }
1077
1078 ASSERT(Vacb->ReferenceCount == 0);
1082
1083 /* Delete the mapping */
1085 if (!NT_SUCCESS(Status))
1086 {
1087 DPRINT1("Failed to unmap VACB from System address space! Status 0x%08X\n", Status);
1088 ASSERT(FALSE);
1089 /* Proceed with the deĺetion anyway */
1090 }
1091
1092 RtlFillMemory(Vacb, sizeof(*Vacb), 0xfd);
1093 ExFreeToNPagedLookasideList(&VacbLookasideList, Vacb);
1094 return STATUS_SUCCESS;
1095}
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:2761
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
PROS_SHARED_CACHE_MAP SharedCacheMap
Definition: cc.h:227
PVOID BaseAddress
Definition: cc.h:210
volatile ULONG ReferenceCount
Definition: cc.h:225
LIST_ENTRY DirtyVacbListEntry
Definition: cc.h:219

◆ CcRosLookupVacb()

PROS_VACB CcRosLookupVacb ( PROS_SHARED_CACHE_MAP  SharedCacheMap,
LONGLONG  FileOffset 
)

Definition at line 623 of file view.c.

626{
627 PLIST_ENTRY current_entry;
629 KIRQL oldIrql;
630
631 ASSERT(SharedCacheMap);
632
633 DPRINT("CcRosLookupVacb(SharedCacheMap 0x%p, FileOffset %I64u)\n",
634 SharedCacheMap, FileOffset);
635
638
639 current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
640 while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
641 {
642 current = CONTAINING_RECORD(current_entry,
643 ROS_VACB,
644 CacheMapVacbListEntry);
645 if (IsPointInRange(current->FileOffset.QuadPart,
647 FileOffset))
648 {
652 return current;
653 }
654 if (current->FileOffset.QuadPart > FileOffset)
655 break;
656 current_entry = current_entry->Flink;
657 }
658
661
662 return NULL;
663}

Referenced by CcFlushCache(), and CcRosGetVacb().

◆ CcRosMarkDirtyVacb()

VOID CcRosMarkDirtyVacb ( PROS_VACB  Vacb)

Definition at line 666 of file view.c.

668{
669 KIRQL oldIrql;
670 PROS_SHARED_CACHE_MAP SharedCacheMap;
671
672 SharedCacheMap = Vacb->SharedCacheMap;
673
676
677 ASSERT(!Vacb->Dirty);
678
680 /* FIXME: There is no reason to account for the whole VACB. */
684
685 /* Move to the tail of the LRU list */
688
689 Vacb->Dirty = TRUE;
690
692
693 /* Schedule a lazy writer run to now that we have dirty VACB */
695 {
697 }
699}
VOID CcScheduleLazyWriteScan(IN BOOLEAN NoDelay)
Definition: lazywrite.c:210
LAZY_WRITER LazyWriter
Definition: lazywrite.c:37
ULONG CcTotalDirtyPages
Definition: view.c:56
BOOLEAN ScanActive
Definition: cc.h:247

Referenced by CcRosFlushVacb(), CcRosReleaseVacb(), and CcSetDirtyPinnedData().

◆ CcRosReleaseFileCache()

NTSTATUS CcRosReleaseFileCache ( PFILE_OBJECT  FileObject)

Definition at line 1230 of file view.c.

1236{
1237 KIRQL OldIrql;
1238 PPRIVATE_CACHE_MAP PrivateMap;
1239 PROS_SHARED_CACHE_MAP SharedCacheMap;
1240
1242
1243 if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
1244 {
1245 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
1246
1247 /* Closing the handle, so kill the private cache map
1248 * Before you event try to remove it from FO, always
1249 * lock the master lock, to be sure not to race
1250 * with a potential read ahead ongoing!
1251 */
1252 PrivateMap = FileObject->PrivateCacheMap;
1253 FileObject->PrivateCacheMap = NULL;
1254
1255 if (PrivateMap != NULL)
1256 {
1257 /* Remove it from the file */
1258 KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
1259 RemoveEntryList(&PrivateMap->PrivateLinks);
1261
1262 /* And free it. */
1263 if (PrivateMap != &SharedCacheMap->PrivateCacheMap)
1264 {
1266 }
1267 else
1268 {
1269 PrivateMap->NodeTypeCode = 0;
1270 }
1271
1272 ASSERT(SharedCacheMap->OpenCount > 0);
1273
1274 SharedCacheMap->OpenCount--;
1275 if (SharedCacheMap->OpenCount == 0)
1276 {
1277 CcRosDeleteFileCache(FileObject, SharedCacheMap, &OldIrql);
1278 }
1279 }
1280 }
1282 return STATUS_SUCCESS;
1283}
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109

Referenced by CcRosInitializeFileCache(), and CcUninitializeCacheMap().

◆ CcRosReleaseVacb()

NTSTATUS CcRosReleaseVacb ( PROS_SHARED_CACHE_MAP  SharedCacheMap,
PROS_VACB  Vacb,
BOOLEAN  Dirty,
BOOLEAN  Mapped 
)

Definition at line 591 of file view.c.

596{
597 ULONG Refs;
598 ASSERT(SharedCacheMap);
599
600 DPRINT("CcRosReleaseVacb(SharedCacheMap 0x%p, Vacb 0x%p)\n", SharedCacheMap, Vacb);
601
602 if (Dirty && !Vacb->Dirty)
603 {
604 CcRosMarkDirtyVacb(Vacb);
605 }
606
607 if (Mapped)
608 {
609 if (InterlockedIncrement((PLONG)&Vacb->MappedCount) == 1)
610 {
612 }
613 }
614
615 Refs = CcRosVacbDecRefCount(Vacb);
616 ASSERT(Refs > 0);
617
618 return STATUS_SUCCESS;
619}
#define InterlockedIncrement
Definition: armddk.h:53
int32_t * PLONG
Definition: typedefs.h:58

Referenced by CcCopyRead(), CcCopyWrite(), CcFlushCache(), CcMapData(), CcpDereferenceBcb(), CcPerformReadAhead(), CcpGetAppropriateBcb(), CcpPinData(), CcUnpinRepinnedBcb(), and CcZeroData().

◆ CcRosRequestVacb()

NTSTATUS CcRosRequestVacb ( PROS_SHARED_CACHE_MAP  SharedCacheMap,
LONGLONG  FileOffset,
PROS_VACB Vacb 
)

Definition at line 1029 of file view.c.

1036{
1037
1038 ASSERT(SharedCacheMap);
1039
1041 {
1042 DPRINT1("Bad fileoffset %I64x should be multiple of %x",
1044 KeBugCheck(CACHE_MANAGER);
1045 }
1046
1047 return CcRosGetVacb(SharedCacheMap,
1048 FileOffset,
1049 Vacb);
1050}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1430
NTSTATUS CcRosGetVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:978

Referenced by CcPerformReadAhead().

◆ CcRosTraceCacheMap()

VOID CcRosTraceCacheMap ( PROS_SHARED_CACHE_MAP  SharedCacheMap,
BOOLEAN  Trace 
)

Definition at line 116 of file view.c.

119{
120#if DBG
121 KIRQL oldirql;
122 PLIST_ENTRY current_entry;
124
125 if (!SharedCacheMap)
126 return;
127
128 SharedCacheMap->Trace = Trace;
129
130 if (Trace)
131 {
132 DPRINT1("Enabling Tracing for CacheMap 0x%p:\n", SharedCacheMap);
133
136
137 current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
138 while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
139 {
140 current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
141 current_entry = current_entry->Flink;
142
143 DPRINT1(" VACB 0x%p enabled, RefCount %lu, Dirty %u, PageOut %lu, BaseAddress %p, FileOffset %I64d\n",
144 current, current->ReferenceCount, current->Dirty, current->PageOut, current->BaseAddress, current->FileOffset.QuadPart);
145 }
146
149 }
150 else
151 {
152 DPRINT1("Disabling Tracing for CacheMap 0x%p:\n", SharedCacheMap);
153 }
154
155#else
156 UNREFERENCED_PARAMETER(SharedCacheMap);
158#endif
159}
#define Trace(x)
Definition: inflate.c:42
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317

◆ CcRosTrimCache()

VOID CcRosTrimCache ( _In_ ULONG  Target,
_Out_ PULONG  NrFreed 
)

Definition at line 456 of file view.c.

466{
467 PLIST_ENTRY current_entry;
469 ULONG PagesFreed;
470 KIRQL oldIrql;
471 LIST_ENTRY FreeList;
472 BOOLEAN FlushedPages = FALSE;
473
474 DPRINT("CcRosTrimCache(Target %lu)\n", Target);
475
476 InitializeListHead(&FreeList);
477
478 *NrFreed = 0;
479
480retry:
482
483 current_entry = VacbLruListHead.Flink;
484 while (current_entry != &VacbLruListHead)
485 {
486 ULONG Refs;
487
488 current = CONTAINING_RECORD(current_entry,
489 ROS_VACB,
490 VacbLruListEntry);
491
492 KeAcquireSpinLockAtDpcLevel(&current->SharedCacheMap->CacheMapLock);
493
494 /* Reference the VACB */
496
497 /* Check if it's mapped and not dirty */
498 if (InterlockedCompareExchange((PLONG)&current->MappedCount, 0, 0) > 0 && !current->Dirty)
499 {
500 /* This code is never executed. It is left for reference only. */
501#if 1
502 DPRINT1("MmPageOutPhysicalAddress unexpectedly called\n");
503 ASSERT(FALSE);
504#else
505 ULONG i;
507
508 /* We have to break these locks to call MmPageOutPhysicalAddress */
509 KeReleaseSpinLockFromDpcLevel(&current->SharedCacheMap->CacheMapLock);
511
512 /* Page out the VACB */
513 for (i = 0; i < VACB_MAPPING_GRANULARITY / PAGE_SIZE; i++)
514 {
516
518 }
519
520 /* Reacquire the locks */
522 KeAcquireSpinLockAtDpcLevel(&current->SharedCacheMap->CacheMapLock);
523#endif
524 }
525
526 /* Only keep iterating though the loop while the lock is held */
527 current_entry = current_entry->Flink;
528
529 /* Dereference the VACB */
531
532 /* Check if we can free this entry now */
533 if (Refs < 2)
534 {
535 ASSERT(!current->Dirty);
536 ASSERT(!current->MappedCount);
537 ASSERT(Refs == 1);
538
539 RemoveEntryList(&current->CacheMapVacbListEntry);
540 RemoveEntryList(&current->VacbLruListEntry);
541 InitializeListHead(&current->VacbLruListEntry);
542 InsertHeadList(&FreeList, &current->CacheMapVacbListEntry);
543
544 /* Calculate how many pages we freed for Mm */
546 Target -= PagesFreed;
547 (*NrFreed) += PagesFreed;
548 }
549
550 KeReleaseSpinLockFromDpcLevel(&current->SharedCacheMap->CacheMapLock);
551 }
552
554
555 /* Try flushing pages if we haven't met our target */
556 if ((Target > 0) && !FlushedPages)
557 {
558 /* Flush dirty pages to disk */
559 CcRosFlushDirtyPages(Target, &PagesFreed, FALSE, FALSE);
560 FlushedPages = TRUE;
561
562 /* We can only swap as many pages as we flushed */
563 if (PagesFreed < Target) Target = PagesFreed;
564
565 /* Check if we flushed anything */
566 if (PagesFreed != 0)
567 {
568 /* Try again after flushing dirty pages */
569 DPRINT("Flushed %lu dirty cache pages to disk\n", PagesFreed);
570 goto retry;
571 }
572 }
573
574 while (!IsListEmpty(&FreeList))
575 {
576 ULONG Refs;
577
578 current_entry = RemoveHeadList(&FreeList);
579 current = CONTAINING_RECORD(current_entry,
580 ROS_VACB,
581 CacheMapVacbListEntry);
582 InitializeListHead(&current->CacheMapVacbListEntry);
584 ASSERT(Refs == 0);
585 }
586
587 DPRINT("Evicted %lu cache pages\n", (*NrFreed));
588}
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define min(a, b)
Definition: monoChain.cc:55
NTSTATUS CcRosFlushDirtyPages(ULONG Target, PULONG Count, BOOLEAN Wait, BOOLEAN CalledFromLazy)
Definition: view.c:308
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
NTSTATUS NTAPI MmPageOutPhysicalAddress(PFN_NUMBER Page)
Definition: rmap.c:51
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:685
ULONG PFN_NUMBER
Definition: ke.h:9
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by MiBalancerThread().

◆ CcRosUnmarkDirtyVacb()

VOID CcRosUnmarkDirtyVacb ( PROS_VACB  Vacb,
BOOLEAN  LockViews 
)

Definition at line 702 of file view.c.

705{
706 KIRQL oldIrql;
707 PROS_SHARED_CACHE_MAP SharedCacheMap;
708
709 SharedCacheMap = Vacb->SharedCacheMap;
710
711 if (LockViews)
712 {
715 }
716
717 ASSERT(Vacb->Dirty);
718
719 Vacb->Dirty = FALSE;
720
723
726
728
729 if (LockViews)
730 {
733 }
734}

Referenced by CcPurgeCacheSection(), CcRosDeleteFileCache(), and CcRosFlushVacb().

Variable Documentation

◆ CcCleanSharedCacheMapList

LIST_ENTRY CcCleanSharedCacheMapList

Definition at line 59 of file view.c.

Referenced by CcInitView(), and CcRosInitializeFileCache().

◆ CcDeferredWrites

LIST_ENTRY CcDeferredWrites

◆ CcDeferredWriteSpinLock

KSPIN_LOCK CcDeferredWriteSpinLock

Definition at line 58 of file view.c.

Referenced by CcCanIWrite(), CcDeferWrite(), CcInitView(), and CcPostDeferredWrites().

◆ CcDirtyPageThreshold

ULONG CcDirtyPageThreshold = 0

Definition at line 55 of file view.c.

Referenced by CcCanIWrite(), and CcInitializeCacheManager().

◆ CcTotalDirtyPages

ULONG CcTotalDirtyPages = 0

◆ DirtyVacbListHead

LIST_ENTRY DirtyVacbListHead

Definition at line 41 of file view.c.

Referenced by CcInitView(), CcIsThereDirtyData(), CcRosFlushDirtyPages(), and CcRosMarkDirtyVacb().

◆ iBcbLookasideList

NPAGED_LOOKASIDE_LIST iBcbLookasideList

Definition at line 44 of file view.c.

Referenced by CcInitView(), CcpDereferenceBcb(), CcpGetAppropriateBcb(), and CcUnpinRepinnedBcb().

◆ SharedCacheMapLookasideList

NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList
static

Definition at line 45 of file view.c.

Referenced by CcInitView(), CcRosDeleteFileCache(), and CcRosInitializeFileCache().

◆ VacbLookasideList

NPAGED_LOOKASIDE_LIST VacbLookasideList
static

Definition at line 46 of file view.c.

Referenced by CcInitView(), CcRosCreateVacb(), and CcRosInternalFreeVacb().

◆ VacbLruListHead

LIST_ENTRY VacbLruListHead
static