ReactOS 0.4.15-dev-5884-gab5aff5
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)
 
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)
 
static BOOLEAN CcRosFreeUnusedVacb (PULONG Count)
 
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 987 of file view.c.

992{
993 PROS_SHARED_CACHE_MAP SharedCacheMap;
994 LONGLONG FlushStart, FlushEnd;
996
997 CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p FileOffset=0x%I64X Length=%lu\n",
998 SectionObjectPointers, FileOffset ? FileOffset->QuadPart : 0LL, Length);
999
1000 if (!SectionObjectPointers)
1001 {
1003 goto quit;
1004 }
1005
1006 if (!SectionObjectPointers->SharedCacheMap)
1007 {
1008 /* Forward this to Mm */
1009 MmFlushSegment(SectionObjectPointers, FileOffset, Length, IoStatus);
1010 return;
1011 }
1012
1013 SharedCacheMap = SectionObjectPointers->SharedCacheMap;
1014 ASSERT(SharedCacheMap);
1015 if (FileOffset)
1016 {
1017 FlushStart = FileOffset->QuadPart;
1018 Status = RtlLongLongAdd(FlushStart, Length, &FlushEnd);
1019 if (!NT_SUCCESS(Status))
1020 goto quit;
1021 }
1022 else
1023 {
1024 FlushStart = 0;
1025 FlushEnd = SharedCacheMap->FileSize.QuadPart;
1026 }
1027
1029 if (IoStatus)
1030 {
1031 IoStatus->Information = 0;
1032 }
1033
1034 /*
1035 * We flush the VACBs that we find here.
1036 * If there is no (dirty) VACB, it doesn't mean that there is no data to flush, so we call Mm to be sure.
1037 * This is suboptimal, but this is due to the lack of granularity of how we track dirty cache data
1038 */
1039 while (FlushStart < FlushEnd)
1040 {
1041 BOOLEAN DirtyVacb = FALSE;
1042 PROS_VACB vacb = CcRosLookupVacb(SharedCacheMap, FlushStart);
1043
1044 if (vacb != NULL)
1045 {
1046 if (vacb->Dirty)
1047 {
1048 IO_STATUS_BLOCK VacbIosb = { 0 };
1049 Status = CcRosFlushVacb(vacb, &VacbIosb);
1050 if (!NT_SUCCESS(Status))
1051 {
1052 goto quit;
1053 }
1054 DirtyVacb = TRUE;
1055
1056 if (IoStatus)
1057 IoStatus->Information += VacbIosb.Information;
1058 }
1059
1060 CcRosReleaseVacb(SharedCacheMap, vacb, FALSE, FALSE);
1061 }
1062
1063 if (!DirtyVacb)
1064 {
1065 IO_STATUS_BLOCK MmIosb;
1066 LARGE_INTEGER MmOffset;
1067
1068 MmOffset.QuadPart = FlushStart;
1069
1070 if (FlushEnd - (FlushEnd % VACB_MAPPING_GRANULARITY) <= FlushStart)
1071 {
1072 /* The whole range fits within a VACB chunk. */
1073 Status = MmFlushSegment(SectionObjectPointers, &MmOffset, FlushEnd - FlushStart, &MmIosb);
1074 }
1075 else
1076 {
1077 ULONG MmLength = VACB_MAPPING_GRANULARITY - (FlushStart % VACB_MAPPING_GRANULARITY);
1078 Status = MmFlushSegment(SectionObjectPointers, &MmOffset, MmLength, &MmIosb);
1079 }
1080
1081 if (!NT_SUCCESS(Status))
1082 goto quit;
1083
1084 if (IoStatus)
1085 IoStatus->Information += MmIosb.Information;
1086
1087 /* Update VDL */
1088 if (SharedCacheMap->ValidDataLength.QuadPart < FlushEnd)
1089 SharedCacheMap->ValidDataLength.QuadPart = FlushEnd;
1090 }
1091
1092 if (!NT_SUCCESS(RtlLongLongAdd(FlushStart, VACB_MAPPING_GRANULARITY, &FlushStart)))
1093 {
1094 /* We're at the end of file ! */
1095 break;
1096 }
1097
1098 /* Round down to next VACB start now */
1099 FlushStart -= FlushStart % VACB_MAPPING_GRANULARITY;
1100 }
1101
1102quit:
1103 if (IoStatus)
1104 {
1105 IoStatus->Status = Status;
1106 }
1107}
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:32
Status
Definition: gdiplustypes.h:25
#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:453
NTSTATUS CcRosFlushVacb(_In_ PROS_VACB Vacb, _Out_opt_ PIO_STATUS_BLOCK Iosb)
Definition: view.c:159
PROS_VACB CcRosLookupVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset)
Definition: view.c:485
#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:4841
#define STATUS_SUCCESS
Definition: shellext.h:65
LARGE_INTEGER FileSize
Definition: cc.h:175
LARGE_INTEGER ValidDataLength
Definition: cc.h:178
Definition: cc.h:207
BOOLEAN Dirty
Definition: cc.h:211
#define LL
Definition: tui.h:150
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 1336 of file view.c.

1338{
1339 PROS_SHARED_CACHE_MAP SharedCacheMap;
1340
1341 CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p\n", SectionObjectPointers);
1342
1343 if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap)
1344 {
1345 SharedCacheMap = SectionObjectPointers->SharedCacheMap;
1346 ASSERT(SharedCacheMap);
1347 return SharedCacheMap->FileObject;
1348 }
1349 return NULL;
1350}
PFILE_OBJECT FileObject
Definition: cc.h:179

◆ CcInitView()

VOID NTAPI CcInitView ( VOID  )

Definition at line 1355 of file view.c.

1357{
1358 DPRINT("CcInitView()\n");
1359
1366 NULL,
1367 NULL,
1368 0,
1369 sizeof(INTERNAL_BCB),
1370 TAG_BCB,
1371 20);
1373 NULL,
1374 NULL,
1375 0,
1376 sizeof(ROS_SHARED_CACHE_MAP),
1378 20);
1380 NULL,
1381 NULL,
1382 0,
1383 sizeof(ROS_VACB),
1384 TAG_VACB,
1385 20);
1386
1388}
#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:71
#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 682 of file view.c.

686{
688 PROS_VACB previous;
689 PLIST_ENTRY current_entry;
691 KIRQL oldIrql;
692 ULONG Refs;
693 BOOLEAN Retried;
695
696 ASSERT(SharedCacheMap);
697
698 DPRINT("CcRosCreateVacb()\n");
699
700 current = ExAllocateFromNPagedLookasideList(&VacbLookasideList);
701 current->BaseAddress = NULL;
702 current->Dirty = FALSE;
703 current->PageOut = FALSE;
704 current->FileOffset.QuadPart = ROUND_DOWN(FileOffset, VACB_MAPPING_GRANULARITY);
705 current->SharedCacheMap = SharedCacheMap;
706 current->MappedCount = 0;
707 current->ReferenceCount = 0;
708 InitializeListHead(&current->CacheMapVacbListEntry);
709 InitializeListHead(&current->DirtyVacbListEntry);
710 InitializeListHead(&current->VacbLruListEntry);
711
713
714 Retried = FALSE;
715Retry:
716 /* Map VACB in system space */
717 Status = MmMapViewInSystemSpaceEx(SharedCacheMap->Section, &current->BaseAddress, &ViewSize, &current->FileOffset, 0);
718
719 if (!NT_SUCCESS(Status))
720 {
721 ULONG Freed;
722 /* If no space left, try to prune unused VACB
723 * to recover space to map our VACB
724 * If it succeed, retry to map, otherwise
725 * just fail.
726 */
727 if (!Retried && CcRosFreeUnusedVacb(&Freed))
728 {
729 DPRINT("Prunned %d VACB, trying again\n", Freed);
730 Retried = TRUE;
731 goto Retry;
732 }
733
734 ExFreeToNPagedLookasideList(&VacbLookasideList, current);
735 return Status;
736 }
737
738#if DBG
739 if (SharedCacheMap->Trace)
740 {
741 DPRINT1("CacheMap 0x%p: new VACB: 0x%p, file offset %I64d, BaseAddress %p\n",
742 SharedCacheMap, current, current->FileOffset.QuadPart, current->BaseAddress);
743 }
744#endif
745
747
748 *Vacb = current;
749 /* There is window between the call to CcRosLookupVacb
750 * and CcRosCreateVacb. We must check if a VACB for the
751 * file offset exist. If there is a VACB, we release
752 * our newly created VACB and return the existing one.
753 */
755 current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
756 previous = NULL;
757 while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
758 {
759 current = CONTAINING_RECORD(current_entry,
760 ROS_VACB,
761 CacheMapVacbListEntry);
762 if (IsPointInRange(current->FileOffset.QuadPart,
764 FileOffset))
765 {
768#if DBG
769 if (SharedCacheMap->Trace)
770 {
771 DPRINT1("CacheMap 0x%p: deleting newly created VACB 0x%p ( found existing one 0x%p )\n",
772 SharedCacheMap,
773 (*Vacb),
774 current);
775 }
776#endif
778
779 Refs = CcRosVacbDecRefCount(*Vacb);
780 ASSERT(Refs == 0);
781
782 *Vacb = current;
783 return STATUS_SUCCESS;
784 }
785 if (current->FileOffset.QuadPart < FileOffset)
786 {
787 ASSERT(previous == NULL ||
788 previous->FileOffset.QuadPart < current->FileOffset.QuadPart);
789 previous = current;
790 }
791 if (current->FileOffset.QuadPart > FileOffset)
792 break;
793 current_entry = current_entry->Flink;
794 }
795 /* There was no existing VACB. */
796 current = *Vacb;
797 if (previous)
798 {
799 InsertHeadList(&previous->CacheMapVacbListEntry, &current->CacheMapVacbListEntry);
800 }
801 else
802 {
803 InsertHeadList(&SharedCacheMap->CacheMapVacbListHead, &current->CacheMapVacbListEntry);
804 }
806 InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
808
809 /* Reference it to allow release */
811
812 return Status;
813}
#define DPRINT1
Definition: precomp.h:8
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
#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
static BOOLEAN CcRosFreeUnusedVacb(PULONG Count)
Definition: view.c:600
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:495
FORCEINLINE BOOLEAN IsPointInRange(_In_ LONGLONG Offset1, _In_ LONGLONG Length1, _In_ LONGLONG Point)
Definition: cc.h:461
FORCEINLINE ULONG CcRosVacbDecRefCount(PROS_VACB vacb)
Definition: cc.h:498
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:4361
#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:216
LARGE_INTEGER FileOffset
Definition: cc.h:222
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
@ LockQueueMasterLock
Definition: ketypes.h:651

Referenced by CcRosGetVacb().

◆ CcRosDeleteFileCache()

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

Definition at line 205 of file view.c.

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

823{
825
827
828#if 0
829 if ((Vacb->FileOffset.QuadPart + Offset) > Vacb->SharedCacheMap->SectionSize.QuadPart)
830 {
831 DPRINT1("Vacb read beyond the file size!\n");
832 return FALSE;
833 }
834#endif
835
836 BaseAddress = (PVOID)((ULONG_PTR)Vacb->BaseAddress + Offset);
837
838 /* Check if the pages are resident */
840 {
841 if (!Wait)
842 {
843 return FALSE;
844 }
845
846 if (!NoRead)
847 {
848 PROS_SHARED_CACHE_MAP SharedCacheMap = Vacb->SharedCacheMap;
849 NTSTATUS Status = MmMakeDataSectionResident(SharedCacheMap->FileObject->SectionObjectPointer,
850 Vacb->FileOffset.QuadPart + Offset,
851 Length,
852 &SharedCacheMap->ValidDataLength);
853 if (!NT_SUCCESS(Status))
855 }
856 }
857
858 return TRUE;
859}
_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:4676
NTSTATUS NTAPI MmMakeDataSectionResident(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_ LONGLONG Offset, _In_ ULONG Length, _In_ PLARGE_INTEGER ValidDataLength)
Definition: section.c:4821
#define ExRaiseStatus
Definition: ntoskrnl.h:108
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 305 of file view.c.

310{
311 PLIST_ENTRY current_entry;
314 BOOLEAN FlushAll = (Target == MAXULONG);
315
316 DPRINT("CcRosFlushDirtyPages(Target %lu)\n", Target);
317
318 (*Count) = 0;
319
322
323 current_entry = DirtyVacbListHead.Flink;
324 if (current_entry == &DirtyVacbListHead)
325 {
326 DPRINT("No Dirty pages\n");
327 }
328
329 while (((current_entry != &DirtyVacbListHead) && (Target > 0)) || FlushAll)
330 {
331 PROS_SHARED_CACHE_MAP SharedCacheMap;
334
335 if (current_entry == &DirtyVacbListHead)
336 {
337 ASSERT(FlushAll);
339 break;
340 current_entry = DirtyVacbListHead.Flink;
341 }
342
343 current = CONTAINING_RECORD(current_entry,
344 ROS_VACB,
345 DirtyVacbListEntry);
346 current_entry = current_entry->Flink;
347
349
350 SharedCacheMap = current->SharedCacheMap;
351
352 /* When performing lazy write, don't handle temporary files */
353 if (CalledFromLazy && BooleanFlagOn(SharedCacheMap->FileObject->Flags, FO_TEMPORARY_FILE))
354 {
356 continue;
357 }
358
359 /* Don't attempt to lazy write the files that asked not to */
360 if (CalledFromLazy && BooleanFlagOn(SharedCacheMap->Flags, WRITEBEHIND_DISABLED))
361 {
363 continue;
364 }
365
366 ASSERT(current->Dirty);
367
368 /* Do not lazy-write the same file concurrently. Fastfat ASSERTS on that */
369 if (SharedCacheMap->Flags & SHARED_CACHE_MAP_IN_LAZYWRITE)
370 {
372 continue;
373 }
374
375 SharedCacheMap->Flags |= SHARED_CACHE_MAP_IN_LAZYWRITE;
376
377 /* Keep a ref on the shared cache map */
378 SharedCacheMap->OpenCount++;
379
381
382 Locked = SharedCacheMap->Callbacks->AcquireForLazyWrite(SharedCacheMap->LazyWriteContext, Wait);
383 if (!Locked)
384 {
385 DPRINT("Not locked!");
386 ASSERT(!Wait);
389 SharedCacheMap->Flags &= ~SHARED_CACHE_MAP_IN_LAZYWRITE;
390
391 if (--SharedCacheMap->OpenCount == 0)
392 CcRosDeleteFileCache(SharedCacheMap->FileObject, SharedCacheMap, &OldIrql);
393
394 continue;
395 }
396
399
400 SharedCacheMap->Callbacks->ReleaseFromLazyWrite(SharedCacheMap->LazyWriteContext);
401
402 /* We release the VACB before acquiring the lock again, because
403 * CcRosVacbDecRefCount might free the VACB, as CcRosFlushVacb dropped a
404 * Refcount. Freeing must be done outside of the lock.
405 * The refcount is decremented atomically. So this is OK. */
408
409 SharedCacheMap->Flags &= ~SHARED_CACHE_MAP_IN_LAZYWRITE;
410
411 if (--SharedCacheMap->OpenCount == 0)
412 CcRosDeleteFileCache(SharedCacheMap->FileObject, SharedCacheMap, &OldIrql);
413
416 {
417 DPRINT1("CC: Failed to flush VACB.\n");
418 }
419 else
420 {
421 ULONG PagesFreed;
422
423 /* How many pages did we free? */
424 PagesFreed = Iosb.Information / PAGE_SIZE;
425 (*Count) += PagesFreed;
426
427 if (!Wait)
428 {
429 /* Make sure we don't overflow target! */
430 if (Target < PagesFreed)
431 {
432 /* If we would have, jump to zero directly */
433 Target = 0;
434 }
435 else
436 {
437 Target -= PagesFreed;
438 }
439 }
440 }
441
442 current_entry = DirtyVacbListHead.Flink;
443 }
444
447
448 DPRINT("CcRosFlushDirtyPages() finished\n");
449 return STATUS_SUCCESS;
450}
#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:205
#define WRITEBEHIND_DISABLED
Definition: cc.h:202
#define SHARED_CACHE_MAP_IN_LAZYWRITE
Definition: cc.h:204
#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 CcWriteBehind(), and NtSetSystemPowerState().

◆ CcRosFlushVacb()

NTSTATUS CcRosFlushVacb ( _In_ PROS_VACB  Vacb,
_Out_opt_ PIO_STATUS_BLOCK  Iosb 
)

Definition at line 159 of file view.c.

162{
164 BOOLEAN HaveLock = FALSE;
165 PROS_SHARED_CACHE_MAP SharedCacheMap = Vacb->SharedCacheMap;
166
168
169 /* Lock for flush, if we are not already the top-level */
171 {
172 Status = FsRtlAcquireFileForCcFlushEx(Vacb->SharedCacheMap->FileObject);
173 if (!NT_SUCCESS(Status))
174 goto quit;
175 HaveLock = TRUE;
176 }
177
178 Status = MmFlushSegment(SharedCacheMap->FileObject->SectionObjectPointer,
179 &Vacb->FileOffset,
181 Iosb);
182
183 if (HaveLock)
184 {
185 FsRtlReleaseFileForCcFlush(Vacb->SharedCacheMap->FileObject);
186 }
187
188quit:
189 if (!NT_SUCCESS(Status))
190 CcRosMarkDirtyVacb(Vacb);
191 else
192 {
193 /* Update VDL */
194 if (SharedCacheMap->ValidDataLength.QuadPart < (Vacb->FileOffset.QuadPart + VACB_MAPPING_GRANULARITY))
195 {
196 SharedCacheMap->ValidDataLength.QuadPart = Vacb->FileOffset.QuadPart + VACB_MAPPING_GRANULARITY;
197 }
198 }
199
200 return Status;
201}
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
VOID CcRosMarkDirtyVacb(PROS_VACB Vacb)
Definition: view.c:528
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().

◆ CcRosFreeUnusedVacb()

static BOOLEAN CcRosFreeUnusedVacb ( PULONG  Count)
static

Definition at line 600 of file view.c.

602{
603 ULONG cFreed;
604 BOOLEAN Freed;
605 KIRQL oldIrql;
607 LIST_ENTRY FreeList;
608 PLIST_ENTRY current_entry;
609
610 cFreed = 0;
611 Freed = FALSE;
612 InitializeListHead(&FreeList);
613
615
616 /* Browse all the available VACB */
617 current_entry = VacbLruListHead.Flink;
618 while (current_entry != &VacbLruListHead)
619 {
620 ULONG Refs;
621
622 current = CONTAINING_RECORD(current_entry,
623 ROS_VACB,
624 VacbLruListEntry);
625 current_entry = current_entry->Flink;
626
627 KeAcquireSpinLockAtDpcLevel(&current->SharedCacheMap->CacheMapLock);
628
629 /* Only deal with unused VACB, we will free them */
631 if (Refs < 2)
632 {
633 ASSERT(!current->Dirty);
634 ASSERT(!current->MappedCount);
635 ASSERT(Refs == 1);
636
637 /* Reset and move to free list */
638 RemoveEntryList(&current->CacheMapVacbListEntry);
639 RemoveEntryList(&current->VacbLruListEntry);
640 InitializeListHead(&current->VacbLruListEntry);
641 InsertHeadList(&FreeList, &current->CacheMapVacbListEntry);
642 }
643
644 KeReleaseSpinLockFromDpcLevel(&current->SharedCacheMap->CacheMapLock);
645
646 }
647
649
650 /* And now, free any of the found VACB, that'll free memory! */
651 while (!IsListEmpty(&FreeList))
652 {
653 ULONG Refs;
654
655 current_entry = RemoveHeadList(&FreeList);
656 current = CONTAINING_RECORD(current_entry,
657 ROS_VACB,
658 CacheMapVacbListEntry);
659 InitializeListHead(&current->CacheMapVacbListEntry);
661 ASSERT(Refs == 0);
662 ++cFreed;
663 }
664
665 /* If we freed at least one VACB, return success */
666 if (cFreed != 0)
667 {
668 Freed = TRUE;
669 }
670
671 /* If caller asked for free count, return it */
672 if (Count != NULL)
673 {
674 *Count = cFreed;
675 }
676
677 return Freed;
678}
int Count
Definition: noreturn.cpp:7
#define CcRosVacbGetRefCount(vacb)
Definition: cc.h:510

Referenced by CcRosCreateVacb().

◆ CcRosGetVacb()

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

Definition at line 863 of file view.c.

867{
870 ULONG Refs;
872
873 ASSERT(SharedCacheMap);
874
875 DPRINT("CcRosGetVacb()\n");
876
877 /*
878 * Look for a VACB already mapping the same data.
879 */
880 current = CcRosLookupVacb(SharedCacheMap, FileOffset);
881 if (current == NULL)
882 {
883 /*
884 * Otherwise create a new VACB.
885 */
886 Status = CcRosCreateVacb(SharedCacheMap, FileOffset, &current);
887 if (!NT_SUCCESS(Status))
888 {
889 return Status;
890 }
891 }
892
894
896
897 /* Move to the tail of the LRU list */
898 RemoveEntryList(&current->VacbLruListEntry);
899 InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
900
902
903 /*
904 * Return the VACB to the caller.
905 */
906 *Vacb = current;
907
908 ASSERT(Refs > 1);
909
910 return STATUS_SUCCESS;
911}
static NTSTATUS CcRosCreateVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:682

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 1166 of file view.c.

1175{
1176 KIRQL OldIrql;
1178 PROS_SHARED_CACHE_MAP SharedCacheMap;
1179
1180 DPRINT("CcRosInitializeFileCache(FileObject 0x%p)\n", FileObject);
1181
1183
1184 Allocated = FALSE;
1185 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
1186 if (SharedCacheMap == NULL)
1187 {
1188 Allocated = TRUE;
1189 SharedCacheMap = ExAllocateFromNPagedLookasideList(&SharedCacheMapLookasideList);
1190 if (SharedCacheMap == NULL)
1191 {
1193 }
1194 RtlZeroMemory(SharedCacheMap, sizeof(*SharedCacheMap));
1195 SharedCacheMap->NodeTypeCode = NODE_TYPE_SHARED_MAP;
1196 SharedCacheMap->NodeByteSize = sizeof(*SharedCacheMap);
1197 SharedCacheMap->FileObject = FileObject;
1198 SharedCacheMap->Callbacks = CallBacks;
1199 SharedCacheMap->LazyWriteContext = LazyWriterContext;
1200 SharedCacheMap->SectionSize = FileSizes->AllocationSize;
1201 SharedCacheMap->FileSize = FileSizes->FileSize;
1202 SharedCacheMap->ValidDataLength = FileSizes->ValidDataLength;
1203 SharedCacheMap->PinAccess = PinAccess;
1204 SharedCacheMap->DirtyPageThreshold = 0;
1205 SharedCacheMap->DirtyPages = 0;
1206 InitializeListHead(&SharedCacheMap->PrivateList);
1207 KeInitializeSpinLock(&SharedCacheMap->CacheMapLock);
1208 InitializeListHead(&SharedCacheMap->CacheMapVacbListHead);
1209 InitializeListHead(&SharedCacheMap->BcbList);
1210
1211 SharedCacheMap->Flags = SHARED_CACHE_MAP_IN_CREATION;
1212
1215 NULL,
1216 KernelMode);
1217
1218 FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap;
1219
1220 //CcRosTraceCacheMap(SharedCacheMap, TRUE);
1221 }
1222 else if (SharedCacheMap->Flags & SHARED_CACHE_MAP_IN_CREATION)
1223 {
1224 /* The shared cache map is being created somewhere else. Wait for that to happen */
1225 KEVENT Waiter;
1226 PKEVENT PreviousWaiter = SharedCacheMap->CreateEvent;
1227
1229 SharedCacheMap->CreateEvent = &Waiter;
1230
1232
1234
1235 if (PreviousWaiter)
1236 KeSetEvent(PreviousWaiter, IO_NO_INCREMENT, FALSE);
1237
1239 }
1240
1241 if (FileObject->PrivateCacheMap == NULL)
1242 {
1243 PPRIVATE_CACHE_MAP PrivateMap;
1244
1245 /* Allocate the private cache map for this handle */
1246 if (SharedCacheMap->PrivateCacheMap.NodeTypeCode != 0)
1247 {
1249 }
1250 else
1251 {
1252 PrivateMap = &SharedCacheMap->PrivateCacheMap;
1253 }
1254
1255 if (PrivateMap == NULL)
1256 {
1257 /* If we also allocated the shared cache map for this file, kill it */
1258 if (Allocated)
1259 {
1260 RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
1261
1262 FileObject->SectionObjectPointer->SharedCacheMap = NULL;
1264 ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap);
1265 }
1266
1269 }
1270
1271 /* Initialize it */
1272 RtlZeroMemory(PrivateMap, sizeof(PRIVATE_CACHE_MAP));
1273 PrivateMap->NodeTypeCode = NODE_TYPE_PRIVATE_MAP;
1274 PrivateMap->ReadAheadMask = PAGE_SIZE - 1;
1275 PrivateMap->FileObject = FileObject;
1277
1278 /* Link it to the file */
1279 KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
1280 InsertTailList(&SharedCacheMap->PrivateList, &PrivateMap->PrivateLinks);
1282
1283 FileObject->PrivateCacheMap = PrivateMap;
1284 SharedCacheMap->OpenCount++;
1285 }
1286
1288
1289 /* Create the section */
1290 if (Allocated)
1291 {
1293
1294 ASSERT(SharedCacheMap->Section == NULL);
1295
1297 &SharedCacheMap->Section,
1299 NULL,
1300 &SharedCacheMap->SectionSize,
1303 NULL,
1304 FileObject);
1305
1307
1308 if (!NT_SUCCESS(Status))
1309 {
1311 return Status;
1312 }
1313
1315
1317 SharedCacheMap->Flags &= ~SHARED_CACHE_MAP_IN_CREATION;
1318
1319 if (SharedCacheMap->CreateEvent)
1320 {
1321 KeSetEvent(SharedCacheMap->CreateEvent, IO_NO_INCREMENT, FALSE);
1322 SharedCacheMap->CreateEvent = NULL;
1323 }
1324
1326 }
1327
1328 return STATUS_SUCCESS;
1329}
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:310
#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:1110
#define NODE_TYPE_PRIVATE_MAP
Definition: cc.h:287
#define SHARED_CACHE_MAP_IN_CREATION
Definition: cc.h:203
#define NODE_TYPE_SHARED_MAP
Definition: cc.h:288
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:4521
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 STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ Executive
Definition: ketypes.h:403

Referenced by CcInitializeCacheMap().

◆ CcRosInternalFreeVacb()

NTSTATUS CcRosInternalFreeVacb ( PROS_VACB  Vacb)

Definition at line 938 of file view.c.

943{
945
946 DPRINT("Freeing VACB 0x%p\n", Vacb);
947#if DBG
948 if (Vacb->SharedCacheMap->Trace)
949 {
950 DPRINT1("CacheMap 0x%p: deleting VACB: 0x%p\n", Vacb->SharedCacheMap, Vacb);
951 }
952#endif
953
954 if (Vacb->ReferenceCount != 0)
955 {
956 DPRINT1("Invalid free: %ld\n", Vacb->ReferenceCount);
957 if (Vacb->SharedCacheMap->FileObject && Vacb->SharedCacheMap->FileObject->FileName.Length)
958 {
959 DPRINT1("For file: %wZ\n", &Vacb->SharedCacheMap->FileObject->FileName);
960 }
961 }
962
963 ASSERT(Vacb->ReferenceCount == 0);
967
968 /* Delete the mapping */
970 if (!NT_SUCCESS(Status))
971 {
972 DPRINT1("Failed to unmap VACB from System address space! Status 0x%08X\n", Status);
973 ASSERT(FALSE);
974 /* Proceed with the deĺetion anyway */
975 }
976
977 RtlFillMemory(Vacb, sizeof(*Vacb), 0xfd);
978 ExFreeToNPagedLookasideList(&VacbLookasideList, Vacb);
979 return STATUS_SUCCESS;
980}
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:3128
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
PROS_SHARED_CACHE_MAP SharedCacheMap
Definition: cc.h:226
PVOID BaseAddress
Definition: cc.h:209
volatile ULONG ReferenceCount
Definition: cc.h:224
LIST_ENTRY DirtyVacbListEntry
Definition: cc.h:218

◆ CcRosLookupVacb()

PROS_VACB CcRosLookupVacb ( PROS_SHARED_CACHE_MAP  SharedCacheMap,
LONGLONG  FileOffset 
)

Definition at line 485 of file view.c.

488{
489 PLIST_ENTRY current_entry;
491 KIRQL oldIrql;
492
493 ASSERT(SharedCacheMap);
494
495 DPRINT("CcRosLookupVacb(SharedCacheMap 0x%p, FileOffset %I64u)\n",
496 SharedCacheMap, FileOffset);
497
500
501 current_entry = SharedCacheMap->CacheMapVacbListHead.Flink;
502 while (current_entry != &SharedCacheMap->CacheMapVacbListHead)
503 {
504 current = CONTAINING_RECORD(current_entry,
505 ROS_VACB,
506 CacheMapVacbListEntry);
507 if (IsPointInRange(current->FileOffset.QuadPart,
509 FileOffset))
510 {
514 return current;
515 }
516 if (current->FileOffset.QuadPart > FileOffset)
517 break;
518 current_entry = current_entry->Flink;
519 }
520
523
524 return NULL;
525}

Referenced by CcFlushCache(), and CcRosGetVacb().

◆ CcRosMarkDirtyVacb()

VOID CcRosMarkDirtyVacb ( PROS_VACB  Vacb)

Definition at line 528 of file view.c.

530{
531 KIRQL oldIrql;
532 PROS_SHARED_CACHE_MAP SharedCacheMap;
533
534 SharedCacheMap = Vacb->SharedCacheMap;
535
538
539 ASSERT(!Vacb->Dirty);
540
542 /* FIXME: There is no reason to account for the whole VACB. */
546
547 /* Move to the tail of the LRU list */
550
551 Vacb->Dirty = TRUE;
552
554
555 /* Schedule a lazy writer run to now that we have dirty VACB */
557 {
559 }
561}
VOID CcScheduleLazyWriteScan(IN BOOLEAN NoDelay)
Definition: lazywrite.c:200
LAZY_WRITER LazyWriter
Definition: lazywrite.c:37
ULONG CcTotalDirtyPages
Definition: view.c:56
BOOLEAN ScanActive
Definition: cc.h:246

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

◆ CcRosReleaseFileCache()

NTSTATUS CcRosReleaseFileCache ( PFILE_OBJECT  FileObject)

Definition at line 1110 of file view.c.

1116{
1117 KIRQL OldIrql;
1118 PPRIVATE_CACHE_MAP PrivateMap;
1119 PROS_SHARED_CACHE_MAP SharedCacheMap;
1120
1122
1123 if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
1124 {
1125 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
1126
1127 /* Closing the handle, so kill the private cache map
1128 * Before you event try to remove it from FO, always
1129 * lock the master lock, to be sure not to race
1130 * with a potential read ahead ongoing!
1131 */
1132 PrivateMap = FileObject->PrivateCacheMap;
1133 FileObject->PrivateCacheMap = NULL;
1134
1135 if (PrivateMap != NULL)
1136 {
1137 /* Remove it from the file */
1138 KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
1139 RemoveEntryList(&PrivateMap->PrivateLinks);
1141
1142 /* And free it. */
1143 if (PrivateMap != &SharedCacheMap->PrivateCacheMap)
1144 {
1146 }
1147 else
1148 {
1149 PrivateMap->NodeTypeCode = 0;
1150 }
1151
1152 ASSERT(SharedCacheMap->OpenCount > 0);
1153
1154 SharedCacheMap->OpenCount--;
1155 if (SharedCacheMap->OpenCount == 0)
1156 {
1157 CcRosDeleteFileCache(FileObject, SharedCacheMap, &OldIrql);
1158 }
1159 }
1160 }
1162 return STATUS_SUCCESS;
1163}
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by CcRosInitializeFileCache(), and CcUninitializeCacheMap().

◆ CcRosReleaseVacb()

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

Definition at line 453 of file view.c.

458{
459 ULONG Refs;
460 ASSERT(SharedCacheMap);
461
462 DPRINT("CcRosReleaseVacb(SharedCacheMap 0x%p, Vacb 0x%p)\n", SharedCacheMap, Vacb);
463
464 if (Dirty && !Vacb->Dirty)
465 {
466 CcRosMarkDirtyVacb(Vacb);
467 }
468
469 if (Mapped)
470 {
471 if (InterlockedIncrement((PLONG)&Vacb->MappedCount) == 1)
472 {
474 }
475 }
476
477 Refs = CcRosVacbDecRefCount(Vacb);
478 ASSERT(Refs > 0);
479
480 return STATUS_SUCCESS;
481}
#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 914 of file view.c.

921{
922
923 ASSERT(SharedCacheMap);
924
926 {
927 DPRINT1("Bad fileoffset %I64x should be multiple of %x",
929 KeBugCheck(CACHE_MANAGER);
930 }
931
932 return CcRosGetVacb(SharedCacheMap,
934 Vacb);
935}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
NTSTATUS CcRosGetVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:863

Referenced by CcPerformReadAhead().

◆ CcRosTraceCacheMap()

VOID CcRosTraceCacheMap ( PROS_SHARED_CACHE_MAP  SharedCacheMap,
BOOLEAN  Trace 
)

Definition at line 113 of file view.c.

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

◆ CcRosUnmarkDirtyVacb()

VOID CcRosUnmarkDirtyVacb ( PROS_VACB  Vacb,
BOOLEAN  LockViews 
)

Definition at line 564 of file view.c.

567{
568 KIRQL oldIrql;
569 PROS_SHARED_CACHE_MAP SharedCacheMap;
570
571 SharedCacheMap = Vacb->SharedCacheMap;
572
573 if (LockViews)
574 {
577 }
578
579 ASSERT(Vacb->Dirty);
580
581 Vacb->Dirty = FALSE;
582
585
588
590
591 if (LockViews)
592 {
595 }
596}

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