ReactOS  0.4.15-dev-2155-g06f57e1
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, _In_ 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 1006 of file view.c.

1011 {
1012  PROS_SHARED_CACHE_MAP SharedCacheMap;
1013  LONGLONG FlushStart, FlushEnd;
1014  NTSTATUS Status;
1015 
1016  CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p FileOffset=0x%I64X Length=%lu\n",
1017  SectionObjectPointers, FileOffset ? FileOffset->QuadPart : 0LL, Length);
1018 
1019  if (!SectionObjectPointers)
1020  {
1022  goto quit;
1023  }
1024 
1025  if (!SectionObjectPointers->SharedCacheMap)
1026  {
1027  /* Forward this to Mm */
1028  MmFlushSegment(SectionObjectPointers, FileOffset, Length, IoStatus);
1029  return;
1030  }
1031 
1032  SharedCacheMap = SectionObjectPointers->SharedCacheMap;
1033  ASSERT(SharedCacheMap);
1034  if (FileOffset)
1035  {
1036  FlushStart = FileOffset->QuadPart;
1037  Status = RtlLongLongAdd(FlushStart, Length, &FlushEnd);
1038  if (!NT_SUCCESS(Status))
1039  goto quit;
1040  }
1041  else
1042  {
1043  FlushStart = 0;
1044  FlushEnd = SharedCacheMap->FileSize.QuadPart;
1045  }
1046 
1048  if (IoStatus)
1049  {
1050  IoStatus->Information = 0;
1051  }
1052 
1053  /*
1054  * We flush the VACBs that we find here.
1055  * If there is no (dirty) VACB, it doesn't mean that there is no data to flush, so we call Mm to be sure.
1056  * This is suboptimal, but this is due to the lack of granularity of how we track dirty cache data
1057  */
1058  while (FlushStart < FlushEnd)
1059  {
1060  BOOLEAN DirtyVacb = FALSE;
1061  PROS_VACB vacb = CcRosLookupVacb(SharedCacheMap, FlushStart);
1062 
1063  if (vacb != NULL)
1064  {
1065  if (vacb->Dirty)
1066  {
1067  IO_STATUS_BLOCK VacbIosb;
1068  Status = CcRosFlushVacb(vacb, &VacbIosb);
1069  if (!NT_SUCCESS(Status))
1070  {
1071  goto quit;
1072  }
1073  DirtyVacb = TRUE;
1074 
1075  if (IoStatus)
1076  IoStatus->Information += VacbIosb.Information;
1077  }
1078 
1079  CcRosReleaseVacb(SharedCacheMap, vacb, FALSE, FALSE);
1080  }
1081 
1082  if (!DirtyVacb)
1083  {
1084  IO_STATUS_BLOCK MmIosb;
1085  LARGE_INTEGER MmOffset;
1086 
1087  MmOffset.QuadPart = FlushStart;
1088 
1089  if (FlushEnd - (FlushEnd % VACB_MAPPING_GRANULARITY) <= FlushStart)
1090  {
1091  /* The whole range fits within a VACB chunk. */
1092  Status = MmFlushSegment(SectionObjectPointers, &MmOffset, FlushEnd - FlushStart, &MmIosb);
1093  }
1094  else
1095  {
1096  ULONG MmLength = VACB_MAPPING_GRANULARITY - (FlushStart % VACB_MAPPING_GRANULARITY);
1097  Status = MmFlushSegment(SectionObjectPointers, &MmOffset, MmLength, &MmIosb);
1098  }
1099 
1100  if (!NT_SUCCESS(Status))
1101  goto quit;
1102 
1103  if (IoStatus)
1104  IoStatus->Information += MmIosb.Information;
1105 
1106  /* Update VDL */
1107  if (SharedCacheMap->ValidDataLength.QuadPart < FlushEnd)
1108  SharedCacheMap->ValidDataLength.QuadPart = FlushEnd;
1109  }
1110 
1111  if (!NT_SUCCESS(RtlLongLongAdd(FlushStart, VACB_MAPPING_GRANULARITY, &FlushStart)))
1112  {
1113  /* We're at the end of file ! */
1114  break;
1115  }
1116 
1117  /* Round down to next VACB start now */
1118  FlushStart -= FlushStart % VACB_MAPPING_GRANULARITY;
1119  }
1120 
1121 quit:
1122  if (IoStatus)
1123  {
1124  IoStatus->Status = Status;
1125  }
1126 }
#define LL
Definition: tui.h:84
Definition: cc.h:206
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
void quit(int argc, const char *argv[])
Definition: cmds.c:1606
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
int64_t LONGLONG
Definition: typedefs.h:68
#define CC_API_DEBUG
Definition: cc.h:11
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
BOOLEAN Dirty
Definition: cc.h:211
NTSTATUS CcRosFlushVacb(_In_ PROS_VACB Vacb, _In_ PIO_STATUS_BLOCK Iosb)
Definition: view.c:159
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define NULL
Definition: types.h:112
#define VACB_MAPPING_GRANULARITY
LARGE_INTEGER FileSize
Definition: cc.h:175
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:155
unsigned int ULONG
Definition: retypes.h:1
LARGE_INTEGER ValidDataLength
Definition: cc.h:178
NTSTATUS CcRosReleaseVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Dirty, BOOLEAN Mapped)
Definition: view.c:453
PROS_VACB CcRosLookupVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset)
Definition: view.c:485
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS NTAPI MmFlushSegment(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length, _In_opt_ PIO_STATUS_BLOCK Iosb)
Definition: section.c:4748
LONGLONG QuadPart
Definition: typedefs.h:114

◆ CcGetFileObjectFromSectionPtrs()

PFILE_OBJECT NTAPI CcGetFileObjectFromSectionPtrs ( IN PSECTION_OBJECT_POINTERS  SectionObjectPointers)

Definition at line 1355 of file view.c.

1357 {
1358  PROS_SHARED_CACHE_MAP SharedCacheMap;
1359 
1360  CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p\n", SectionObjectPointers);
1361 
1362  if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap)
1363  {
1364  SharedCacheMap = SectionObjectPointers->SharedCacheMap;
1365  ASSERT(SharedCacheMap);
1366  return SharedCacheMap->FileObject;
1367  }
1368  return NULL;
1369 }
#define CC_API_DEBUG
Definition: cc.h:11
#define ASSERT(a)
Definition: mode.c:45
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
#define NULL
Definition: types.h:112
PFILE_OBJECT FileObject
Definition: cc.h:179

◆ CcInitView()

VOID NTAPI CcInitView ( VOID  )

Definition at line 1374 of file view.c.

1376 {
1377  DPRINT("CcInitView()\n");
1378 
1385  NULL,
1386  NULL,
1387  0,
1388  sizeof(INTERNAL_BCB),
1389  TAG_BCB,
1390  20);
1392  NULL,
1393  NULL,
1394  0,
1395  sizeof(ROS_SHARED_CACHE_MAP),
1397  20);
1399  NULL,
1400  NULL,
1401  0,
1402  sizeof(ROS_VACB),
1403  TAG_VACB,
1404  20);
1405 
1407 }
Definition: cc.h:206
#define TAG_VACB
Definition: tag.h:5
static NPAGED_LOOKASIDE_LIST VacbLookasideList
Definition: view.c:46
#define TAG_BCB
Definition: nodetype.h:157
static LIST_ENTRY VacbLruListHead
Definition: view.c:42
#define TAG_SHARED_CACHE_MAP
Definition: tag.h:6
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
LIST_ENTRY CcCleanSharedCacheMapList
Definition: view.c:59
VOID NTAPI CcInitCacheZeroPage(VOID)
Definition: copy.c:56
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
static NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList
Definition: view.c:45
LIST_ENTRY CcDeferredWrites
Definition: view.c:57
KSPIN_LOCK CcDeferredWriteSpinLock
Definition: view.c:58
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NPAGED_LOOKASIDE_LIST iBcbLookasideList
Definition: view.c:44
#define NULL
Definition: types.h:112
#define DPRINT
Definition: sndvol32.h:71
LIST_ENTRY DirtyVacbListHead
Definition: view.c:41

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;
715 Retry:
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  */
754  KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
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 
810 #if MI_TRACE_PFNS
811  if ((SharedCacheMap->FileObject) && (SharedCacheMap->FileObject->FileName.Buffer))
812  {
813  PWCHAR pos;
814  ULONG len = 0;
815  pos = wcsrchr(SharedCacheMap->FileObject->FileName.Buffer, '\\');
816  if (pos)
817  {
818  len = wcslen(pos) * sizeof(WCHAR);
820  }
821  else
822  {
823  snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%wZ", &SharedCacheMap->FileObject->FileName);
824  }
825  }
826 #endif
827 
828  /* Reference it to allow release */
830 
831  return Status;
832 }
Definition: cc.h:206
#define TRUE
Definition: types.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
LONG NTSTATUS
Definition: precomp.h:26
#define snprintf
Definition: wintirpc.h:48
static NPAGED_LOOKASIDE_LIST VacbLookasideList
Definition: view.c:46
static LIST_ENTRY VacbLruListHead
Definition: view.c:42
uint16_t * PWCHAR
Definition: typedefs.h:56
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
static BOOLEAN CcRosFreeUnusedVacb(PULONG Count)
Definition: view.c:600
LIST_ENTRY CacheMapVacbListEntry
Definition: cc.h:216
unsigned char BOOLEAN
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
#define MI_SET_USAGE(x)
Definition: mm.h:250
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LIST_ENTRY CacheMapVacbListHead
Definition: cc.h:193
Status
Definition: gdiplustypes.h:24
FORCEINLINE BOOLEAN IsPointInRange(_In_ LONGLONG Offset1, _In_ LONGLONG Length1, _In_ LONGLONG Point)
Definition: cc.h:455
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
FORCEINLINE ULONG CcRosVacbDecRefCount(PROS_VACB vacb)
Definition: cc.h:492
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:489
GLenum GLsizei len
Definition: glext.h:6722
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:4196
Definition: typedefs.h:119
#define wcsrchr
Definition: compat.h:16
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:30
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
LARGE_INTEGER FileOffset
Definition: cc.h:222
#define VACB_MAPPING_GRANULARITY
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
KSPIN_LOCK CacheMapLock
Definition: cc.h:195
PFILE_OBJECT FileObject
Definition: cc.h:179
#define DPRINT
Definition: sndvol32.h:71
CHAR MI_PFN_CURRENT_PROCESS_NAME[16]
Definition: pfnlist.c:64
struct task_struct * current
Definition: linux.c:32
LONGLONG QuadPart
Definition: typedefs.h:114

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 */
220  KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
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 }
Definition: cc.h:206
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
ULONG OpenCount
Definition: cc.h:174
#define TRUE
Definition: types.h:120
LIST_ENTRY SharedCacheMapLinks
Definition: cc.h:181
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FALSE
Definition: types.h:117
LIST_ENTRY CacheMapVacbListEntry
Definition: cc.h:216
ULONG MappedCount
Definition: cc.h:214
VOID CcRosUnmarkDirtyVacb(PROS_VACB Vacb, BOOLEAN LockViews)
Definition: view.c:564
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
LIST_ENTRY CacheMapVacbListHead
Definition: cc.h:193
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
static NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList
Definition: view.c:45
#define ASSERT(a)
Definition: mode.c:45
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
#define ObDereferenceObject
Definition: obfuncs.h:203
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
FORCEINLINE ULONG CcRosVacbDecRefCount(PROS_VACB vacb)
Definition: cc.h:492
BOOLEAN Dirty
Definition: cc.h:211
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: typedefs.h:119
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
LARGE_INTEGER FileOffset
Definition: cc.h:222
#define VACB_MAPPING_GRANULARITY
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
KSPIN_LOCK CacheMapLock
Definition: cc.h:195
PFILE_OBJECT FileObject
Definition: cc.h:179
NTSTATUS NTAPI MmFlushSegment(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length, _In_opt_ PIO_STATUS_BLOCK Iosb)
Definition: section.c:4748
LIST_ENTRY VacbLruListEntry
Definition: cc.h:220
LONGLONG QuadPart
Definition: typedefs.h:114

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

842 {
844 
846 
847 #if 0
848  if ((Vacb->FileOffset.QuadPart + Offset) > Vacb->SharedCacheMap->SectionSize.QuadPart)
849  {
850  DPRINT1("Vacb read beyond the file size!\n");
851  return FALSE;
852  }
853 #endif
854 
855  BaseAddress = (PVOID)((ULONG_PTR)Vacb->BaseAddress + Offset);
856 
857  /* Check if the pages are resident */
859  {
860  if (!Wait)
861  {
862  return FALSE;
863  }
864 
865  if (!NoRead)
866  {
867  PROS_SHARED_CACHE_MAP SharedCacheMap = Vacb->SharedCacheMap;
868  NTSTATUS Status = MmMakeDataSectionResident(SharedCacheMap->FileObject->SectionObjectPointer,
869  Vacb->FileOffset.QuadPart + Offset,
870  Length,
871  &SharedCacheMap->ValidDataLength);
872  if (!NT_SUCCESS(Status))
874  }
875  }
876 
877  return TRUE;
878 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI MmMakeDataSectionResident(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_ LONGLONG Offset, _In_ ULONG Length, _In_ PLARGE_INTEGER ValidDataLength)
Definition: section.c:4728
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
BOOLEAN NTAPI MmArePagesResident(_In_ PEPROCESS Process, _In_ PVOID BaseAddress, _In_ ULONG Length)
Definition: section.c:4508
LONG NTSTATUS
Definition: precomp.h:26
#define ExRaiseStatus
Definition: ntoskrnl.h:104
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
void * PVOID
Definition: retypes.h:9
Status
Definition: gdiplustypes.h:24
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define VACB_MAPPING_GRANULARITY
LARGE_INTEGER ValidDataLength
Definition: cc.h:178
PFILE_OBJECT FileObject
Definition: cc.h:179

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;
313  KIRQL OldIrql;
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;
333  BOOLEAN Locked;
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 
414  if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE) &&
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 }
Definition: cc.h:206
ULONG OpenCount
Definition: cc.h:174
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define SHARED_CACHE_MAP_IN_LAZYWRITE
Definition: cc.h:204
#define STATUS_END_OF_FILE
Definition: shellext.h:67
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:217
unsigned char BOOLEAN
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
PCACHE_MANAGER_CALLBACKS Callbacks
Definition: cc.h:185
#define WRITEBEHIND_DISABLED
Definition: cc.h:202
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:45
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite
Definition: cctypes.h:39
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
FORCEINLINE ULONG CcRosVacbDecRefCount(PROS_VACB vacb)
Definition: cc.h:492
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:489
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:119
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
NTSTATUS CcRosFlushVacb(_In_ PROS_VACB Vacb, _In_ PIO_STATUS_BLOCK Iosb)
Definition: view.c:159
#define MAXULONG
Definition: typedefs.h:251
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
static NTSTATUS CcRosDeleteFileCache(PFILE_OBJECT FileObject, PROS_SHARED_CACHE_MAP SharedCacheMap, PKIRQL OldIrql)
Definition: view.c:205
#define FO_TEMPORARY_FILE
Definition: iotypes.h:1788
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
#define DPRINT1
Definition: precomp.h:8
PVOID LazyWriteContext
Definition: cc.h:186
PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite
Definition: cctypes.h:40
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
PFILE_OBJECT FileObject
Definition: cc.h:179
#define DPRINT
Definition: sndvol32.h:71
LIST_ENTRY DirtyVacbListHead
Definition: view.c:41
struct task_struct * current
Definition: linux.c:32

Referenced by CcWriteBehind(), and NtSetSystemPowerState().

◆ CcRosFlushVacb()

NTSTATUS CcRosFlushVacb ( _In_ PROS_VACB  Vacb,
_In_ 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 
167  CcRosUnmarkDirtyVacb(Vacb, TRUE);
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 
188 quit:
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 TRUE
Definition: types.h:120
void quit(int argc, const char *argv[])
Definition: cmds.c:1606
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
VOID CcRosUnmarkDirtyVacb(PROS_VACB Vacb, BOOLEAN LockViews)
Definition: view.c:564
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
VOID CcRosMarkDirtyVacb(PROS_VACB Vacb)
Definition: view.c:528
#define VACB_MAPPING_GRANULARITY
NTSTATUS NTAPI FsRtlAcquireFileForCcFlushEx(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1692
VOID NTAPI FsRtlReleaseFileForCcFlush(IN PFILE_OBJECT FileObject)
Definition: fastio.c:1765
LARGE_INTEGER ValidDataLength
Definition: cc.h:178
PFILE_OBJECT FileObject
Definition: cc.h:179
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
NTSTATUS NTAPI MmFlushSegment(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER Offset, _In_ ULONG Length, _In_opt_ PIO_STATUS_BLOCK Iosb)
Definition: section.c:4748
LONGLONG QuadPart
Definition: typedefs.h:114

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;
608  PLIST_ENTRY current_entry;
609 
610  cFreed = 0;
611  Freed = FALSE;
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 }
Definition: cc.h:206
#define TRUE
Definition: types.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
static LIST_ENTRY VacbLruListHead
Definition: view.c:42
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define CcRosVacbGetRefCount(vacb)
Definition: cc.h:504
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
int Count
Definition: noreturn.cpp:7
#define ASSERT(a)
Definition: mode.c:45
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
FORCEINLINE ULONG CcRosVacbDecRefCount(PROS_VACB vacb)
Definition: cc.h:492
MmuFreePage * FreeList
Definition: mmuobject.c:60
Definition: typedefs.h:119
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
struct task_struct * current
Definition: linux.c:32

Referenced by CcRosCreateVacb().

◆ CcRosGetVacb()

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

Definition at line 882 of file view.c.

886 {
889  ULONG Refs;
890  KIRQL OldIrql;
891 
892  ASSERT(SharedCacheMap);
893 
894  DPRINT("CcRosGetVacb()\n");
895 
896  /*
897  * Look for a VACB already mapping the same data.
898  */
899  current = CcRosLookupVacb(SharedCacheMap, FileOffset);
900  if (current == NULL)
901  {
902  /*
903  * Otherwise create a new VACB.
904  */
905  Status = CcRosCreateVacb(SharedCacheMap, FileOffset, &current);
906  if (!NT_SUCCESS(Status))
907  {
908  return Status;
909  }
910  }
911 
913 
915 
916  /* Move to the tail of the LRU list */
917  RemoveEntryList(&current->VacbLruListEntry);
918  InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
919 
921 
922  /*
923  * Return the VACB to the caller.
924  */
925  *Vacb = current;
926 
927  ASSERT(Refs > 1);
928 
929  return STATUS_SUCCESS;
930 }
Definition: cc.h:206
LONG NTSTATUS
Definition: precomp.h:26
static LIST_ENTRY VacbLruListHead
Definition: view.c:42
#define InsertTailList(ListHead, Entry)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define CcRosVacbGetRefCount(vacb)
Definition: cc.h:504
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
static NTSTATUS CcRosCreateVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:682
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
PROS_VACB CcRosLookupVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset)
Definition: view.c:485
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
struct task_struct * current
Definition: linux.c:32

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

1194 {
1195  KIRQL OldIrql;
1197  PROS_SHARED_CACHE_MAP SharedCacheMap;
1198 
1199  DPRINT("CcRosInitializeFileCache(FileObject 0x%p)\n", FileObject);
1200 
1202 
1203  Allocated = FALSE;
1204  SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
1205  if (SharedCacheMap == NULL)
1206  {
1207  Allocated = TRUE;
1208  SharedCacheMap = ExAllocateFromNPagedLookasideList(&SharedCacheMapLookasideList);
1209  if (SharedCacheMap == NULL)
1210  {
1212  }
1213  RtlZeroMemory(SharedCacheMap, sizeof(*SharedCacheMap));
1214  SharedCacheMap->NodeTypeCode = NODE_TYPE_SHARED_MAP;
1215  SharedCacheMap->NodeByteSize = sizeof(*SharedCacheMap);
1216  SharedCacheMap->FileObject = FileObject;
1217  SharedCacheMap->Callbacks = CallBacks;
1218  SharedCacheMap->LazyWriteContext = LazyWriterContext;
1219  SharedCacheMap->SectionSize = FileSizes->AllocationSize;
1220  SharedCacheMap->FileSize = FileSizes->FileSize;
1221  SharedCacheMap->ValidDataLength = FileSizes->ValidDataLength;
1222  SharedCacheMap->PinAccess = PinAccess;
1223  SharedCacheMap->DirtyPageThreshold = 0;
1224  SharedCacheMap->DirtyPages = 0;
1225  InitializeListHead(&SharedCacheMap->PrivateList);
1226  KeInitializeSpinLock(&SharedCacheMap->CacheMapLock);
1227  InitializeListHead(&SharedCacheMap->CacheMapVacbListHead);
1228  InitializeListHead(&SharedCacheMap->BcbList);
1229 
1230  SharedCacheMap->Flags = SHARED_CACHE_MAP_IN_CREATION;
1231 
1234  NULL,
1235  KernelMode);
1236 
1237  FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap;
1238 
1239  //CcRosTraceCacheMap(SharedCacheMap, TRUE);
1240  }
1241  else if (SharedCacheMap->Flags & SHARED_CACHE_MAP_IN_CREATION)
1242  {
1243  /* The shared cache map is being created somewhere else. Wait for that to happen */
1244  KEVENT Waiter;
1245  PKEVENT PreviousWaiter = SharedCacheMap->CreateEvent;
1246 
1248  SharedCacheMap->CreateEvent = &Waiter;
1249 
1251 
1253 
1254  if (PreviousWaiter)
1255  KeSetEvent(PreviousWaiter, IO_NO_INCREMENT, FALSE);
1256 
1258  }
1259 
1260  if (FileObject->PrivateCacheMap == NULL)
1261  {
1262  PPRIVATE_CACHE_MAP PrivateMap;
1263 
1264  /* Allocate the private cache map for this handle */
1265  if (SharedCacheMap->PrivateCacheMap.NodeTypeCode != 0)
1266  {
1268  }
1269  else
1270  {
1271  PrivateMap = &SharedCacheMap->PrivateCacheMap;
1272  }
1273 
1274  if (PrivateMap == NULL)
1275  {
1276  /* If we also allocated the shared cache map for this file, kill it */
1277  if (Allocated)
1278  {
1279  RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
1280 
1281  FileObject->SectionObjectPointer->SharedCacheMap = NULL;
1283  ExFreeToNPagedLookasideList(&SharedCacheMapLookasideList, SharedCacheMap);
1284  }
1285 
1288  }
1289 
1290  /* Initialize it */
1291  RtlZeroMemory(PrivateMap, sizeof(PRIVATE_CACHE_MAP));
1292  PrivateMap->NodeTypeCode = NODE_TYPE_PRIVATE_MAP;
1293  PrivateMap->ReadAheadMask = PAGE_SIZE - 1;
1294  PrivateMap->FileObject = FileObject;
1296 
1297  /* Link it to the file */
1298  KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
1299  InsertTailList(&SharedCacheMap->PrivateList, &PrivateMap->PrivateLinks);
1300  KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
1301 
1302  FileObject->PrivateCacheMap = PrivateMap;
1303  SharedCacheMap->OpenCount++;
1304  }
1305 
1307 
1308  /* Create the section */
1309  if (Allocated)
1310  {
1311  NTSTATUS Status;
1312 
1313  ASSERT(SharedCacheMap->Section == NULL);
1314 
1316  &SharedCacheMap->Section,
1318  NULL,
1319  &SharedCacheMap->SectionSize,
1321  SEC_RESERVE,
1322  NULL,
1323  FileObject);
1324 
1326 
1327  if (!NT_SUCCESS(Status))
1328  {
1330  return Status;
1331  }
1332 
1334 
1336  SharedCacheMap->Flags &= ~SHARED_CACHE_MAP_IN_CREATION;
1337 
1338  if (SharedCacheMap->CreateEvent)
1339  {
1340  KeSetEvent(SharedCacheMap->CreateEvent, IO_NO_INCREMENT, FALSE);
1341  SharedCacheMap->CreateEvent = NULL;
1342  }
1343 
1345  }
1346 
1347  return STATUS_SUCCESS;
1348 }
BOOLEAN PinAccess
Definition: cc.h:194
LIST_ENTRY PrivateList
Definition: cc.h:187
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
ULONG OpenCount
Definition: cc.h:174
LARGE_INTEGER SectionSize
Definition: cc.h:177
#define SHARED_CACHE_MAP_IN_CREATION
Definition: cc.h:203
#define TRUE
Definition: types.h:120
LIST_ENTRY SharedCacheMapLinks
Definition: cc.h:181
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
LONG NTSTATUS
Definition: precomp.h:26
LIST_ENTRY BcbList
Definition: cc.h:176
static CC_FILE_SIZES FileSizes
#define InsertTailList(ListHead, Entry)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
ULONG ReadAheadMask
Definition: cctypes.h:75
LARGE_INTEGER FileSize
Definition: cctypes.h:16
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define FALSE
Definition: types.h:117
#define SEC_RESERVE
Definition: nt_native.h:1323
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
unsigned char BOOLEAN
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
Definition: fatprocs.h:306
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:383
PCACHE_MANAGER_CALLBACKS Callbacks
Definition: cc.h:185
LIST_ENTRY CcCleanSharedCacheMapList
Definition: view.c:59
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
LIST_ENTRY CacheMapVacbListHead
Definition: cc.h:193
KSPIN_LOCK ReadAheadSpinLock
Definition: cctypes.h:83
Status
Definition: gdiplustypes.h:24
static NPAGED_LOOKASIDE_LIST SharedCacheMapLookasideList
Definition: view.c:45
#define ASSERT(a)
Definition: mode.c:45
LIST_ENTRY PrivateLinks
Definition: cctypes.h:84
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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:4353
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
#define ObDereferenceObject
Definition: obfuncs.h:203
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
CSHORT NodeTypeCode
Definition: cc.h:172
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS CcRosReleaseFileCache(PFILE_OBJECT FileObject)
Definition: view.c:1129
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
LARGE_INTEGER ValidDataLength
Definition: cctypes.h:17
#define PAGE_SIZE
Definition: env_spec_w32.h:49
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
PFILE_OBJECT FileObject
Definition: cctypes.h:76
CSHORT NodeByteSize
Definition: cc.h:173
#define NODE_TYPE_PRIVATE_MAP
Definition: cc.h:287
PRIVATE_CACHE_MAP PrivateCacheMap
Definition: cc.h:190
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
LARGE_INTEGER AllocationSize
Definition: cctypes.h:15
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
PVOID LazyWriteContext
Definition: cc.h:186
LARGE_INTEGER FileSize
Definition: cc.h:175
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
LARGE_INTEGER ValidDataLength
Definition: cc.h:178
#define TAG_PRIVATE_CACHE_MAP
Definition: tag.h:7
PKEVENT CreateEvent
Definition: cc.h:184
#define STATUS_SUCCESS
Definition: shellext.h:65
KSPIN_LOCK CacheMapLock
Definition: cc.h:195
CSHORT NodeTypeCode
Definition: cctypes.h:71
PFILE_OBJECT FileObject
Definition: cc.h:179
#define DPRINT
Definition: sndvol32.h:71
ULONG DirtyPageThreshold
Definition: cc.h:188
#define NODE_TYPE_SHARED_MAP
Definition: cc.h:288
ULONG DirtyPages
Definition: cc.h:180
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by CcInitializeCacheMap().

◆ CcRosInternalFreeVacb()

NTSTATUS CcRosInternalFreeVacb ( PROS_VACB  Vacb)

Definition at line 957 of file view.c.

962 {
964 
965  DPRINT("Freeing VACB 0x%p\n", Vacb);
966 #if DBG
967  if (Vacb->SharedCacheMap->Trace)
968  {
969  DPRINT1("CacheMap 0x%p: deleting VACB: 0x%p\n", Vacb->SharedCacheMap, Vacb);
970  }
971 #endif
972 
973  if (Vacb->ReferenceCount != 0)
974  {
975  DPRINT1("Invalid free: %ld\n", Vacb->ReferenceCount);
976  if (Vacb->SharedCacheMap->FileObject && Vacb->SharedCacheMap->FileObject->FileName.Length)
977  {
978  DPRINT1("For file: %wZ\n", &Vacb->SharedCacheMap->FileObject->FileName);
979  }
980  }
981 
982  ASSERT(Vacb->ReferenceCount == 0);
986 
987  /* Delete the mapping */
989  if (!NT_SUCCESS(Status))
990  {
991  DPRINT1("Failed to unmap VACB from System address space! Status 0x%08X\n", Status);
992  ASSERT(FALSE);
993  /* Proceed with the deĺetion anyway */
994  }
995 
996  RtlFillMemory(Vacb, sizeof(*Vacb), 0xfd);
997  ExFreeToNPagedLookasideList(&VacbLookasideList, Vacb);
998  return STATUS_SUCCESS;
999 }
PVOID BaseAddress
Definition: cc.h:209
LONG NTSTATUS
Definition: precomp.h:26
static NPAGED_LOOKASIDE_LIST VacbLookasideList
Definition: view.c:46
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:3117
LIST_ENTRY CacheMapVacbListEntry
Definition: cc.h:216
PROS_SHARED_CACHE_MAP SharedCacheMap
Definition: cc.h:226
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
volatile ULONG ReferenceCount
Definition: cc.h:224
#define DPRINT1
Definition: precomp.h:8
LIST_ENTRY DirtyVacbListEntry
Definition: cc.h:218
#define STATUS_SUCCESS
Definition: shellext.h:65
PFILE_OBJECT FileObject
Definition: cc.h:179
#define DPRINT
Definition: sndvol32.h:71
LIST_ENTRY VacbLruListEntry
Definition: cc.h:220

◆ 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 
499  KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
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 }
Definition: cc.h:206
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
UCHAR KIRQL
Definition: env_spec_w32.h:591
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LIST_ENTRY CacheMapVacbListHead
Definition: cc.h:193
FORCEINLINE BOOLEAN IsPointInRange(_In_ LONGLONG Offset1, _In_ LONGLONG Length1, _In_ LONGLONG Point)
Definition: cc.h:455
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:45
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:489
Definition: typedefs.h:119
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define NULL
Definition: types.h:112
#define VACB_MAPPING_GRANULARITY
KSPIN_LOCK CacheMapLock
Definition: cc.h:195
#define DPRINT
Definition: sndvol32.h:71
struct task_struct * current
Definition: linux.c:32

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 
537  KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
538 
539  ASSERT(!Vacb->Dirty);
540 
542  /* FIXME: There is no reason to account for the whole VACB. */
545  CcRosVacbIncRefCount(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 */
556  if (!LazyWriter.ScanActive)
557  {
559  }
561 }
#define TRUE
Definition: types.h:120
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
static LIST_ENTRY VacbLruListHead
Definition: view.c:42
#define InsertTailList(ListHead, Entry)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
LAZY_WRITER LazyWriter
Definition: lazywrite.c:37
#define FALSE
Definition: types.h:117
PROS_SHARED_CACHE_MAP SharedCacheMap
Definition: cc.h:226
#define ASSERT(a)
Definition: mode.c:45
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
BOOLEAN ScanActive
Definition: cc.h:246
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
BOOLEAN Dirty
Definition: cc.h:211
ULONG CcTotalDirtyPages
Definition: view.c:56
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:489
#define PAGE_SIZE
Definition: env_spec_w32.h:49
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
VOID CcScheduleLazyWriteScan(IN BOOLEAN NoDelay)
Definition: lazywrite.c:200
#define VACB_MAPPING_GRANULARITY
LIST_ENTRY DirtyVacbListEntry
Definition: cc.h:218
KSPIN_LOCK CacheMapLock
Definition: cc.h:195
LIST_ENTRY DirtyVacbListHead
Definition: view.c:41
ULONG DirtyPages
Definition: cc.h:180
LIST_ENTRY VacbLruListEntry
Definition: cc.h:220

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

◆ CcRosReleaseFileCache()

NTSTATUS CcRosReleaseFileCache ( PFILE_OBJECT  FileObject)

Definition at line 1129 of file view.c.

1135 {
1136  KIRQL OldIrql;
1137  PPRIVATE_CACHE_MAP PrivateMap;
1138  PROS_SHARED_CACHE_MAP SharedCacheMap;
1139 
1141 
1142  if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
1143  {
1144  SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
1145 
1146  /* Closing the handle, so kill the private cache map
1147  * Before you event try to remove it from FO, always
1148  * lock the master lock, to be sure not to race
1149  * with a potential read ahead ongoing!
1150  */
1151  PrivateMap = FileObject->PrivateCacheMap;
1152  FileObject->PrivateCacheMap = NULL;
1153 
1154  if (PrivateMap != NULL)
1155  {
1156  /* Remove it from the file */
1157  KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
1158  RemoveEntryList(&PrivateMap->PrivateLinks);
1159  KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
1160 
1161  /* And free it. */
1162  if (PrivateMap != &SharedCacheMap->PrivateCacheMap)
1163  {
1165  }
1166  else
1167  {
1168  PrivateMap->NodeTypeCode = 0;
1169  }
1170 
1171  ASSERT(SharedCacheMap->OpenCount > 0);
1172 
1173  SharedCacheMap->OpenCount--;
1174  if (SharedCacheMap->OpenCount == 0)
1175  {
1176  CcRosDeleteFileCache(FileObject, SharedCacheMap, &OldIrql);
1177  }
1178  }
1179  }
1181  return STATUS_SUCCESS;
1182 }
ULONG OpenCount
Definition: cc.h:174
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define ASSERT(a)
Definition: mode.c:45
LIST_ENTRY PrivateLinks
Definition: cctypes.h:84
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
PRIVATE_CACHE_MAP PrivateCacheMap
Definition: cc.h:190
static NTSTATUS CcRosDeleteFileCache(PFILE_OBJECT FileObject, PROS_SHARED_CACHE_MAP SharedCacheMap, PKIRQL OldIrql)
Definition: view.c:205
#define NULL
Definition: types.h:112
#define TAG_PRIVATE_CACHE_MAP
Definition: tag.h:7
#define STATUS_SUCCESS
Definition: shellext.h:65
KSPIN_LOCK CacheMapLock
Definition: cc.h:195
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
CSHORT NodeTypeCode
Definition: cctypes.h:71

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  {
473  CcRosVacbIncRefCount(Vacb);
474  }
475  }
476 
477  Refs = CcRosVacbDecRefCount(Vacb);
478  ASSERT(Refs > 0);
479 
480  return STATUS_SUCCESS;
481 }
ULONG MappedCount
Definition: cc.h:214
#define ASSERT(a)
Definition: mode.c:45
FORCEINLINE ULONG CcRosVacbDecRefCount(PROS_VACB vacb)
Definition: cc.h:492
VOID CcRosMarkDirtyVacb(PROS_VACB Vacb)
Definition: view.c:528
BOOLEAN Dirty
Definition: cc.h:211
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:489
#define InterlockedIncrement
Definition: armddk.h:53
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
signed int * PLONG
Definition: retypes.h:5

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

940 {
941 
942  ASSERT(SharedCacheMap);
943 
945  {
946  DPRINT1("Bad fileoffset %I64x should be multiple of %x",
948  KeBugCheck(CACHE_MANAGER);
949  }
950 
951  return CcRosGetVacb(SharedCacheMap,
952  FileOffset,
953  Vacb);
954 }
NTSTATUS CcRosGetVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:882
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
#define ASSERT(a)
Definition: mode.c:45
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define DPRINT1
Definition: precomp.h:8
#define VACB_MAPPING_GRANULARITY

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 
132  KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
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 }
Definition: cc.h:206
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
UCHAR KIRQL
Definition: env_spec_w32.h:591
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LIST_ENTRY CacheMapVacbListHead
Definition: cc.h:193
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define Trace(x)
Definition: inflate.c:42
Definition: typedefs.h:119
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define DPRINT1
Definition: precomp.h:8
KSPIN_LOCK CacheMapLock
Definition: cc.h:195
struct task_struct * current
Definition: linux.c:32

◆ 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  {
576  KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->CacheMapLock);
577  }
578 
579  ASSERT(Vacb->Dirty);
580 
581  Vacb->Dirty = FALSE;
582 
585 
588 
589  CcRosVacbDecRefCount(Vacb);
590 
591  if (LockViews)
592  {
595  }
596 }
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
PROS_SHARED_CACHE_MAP SharedCacheMap
Definition: cc.h:226
#define ASSERT(a)
Definition: mode.c:45
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
FORCEINLINE ULONG CcRosVacbDecRefCount(PROS_VACB vacb)
Definition: cc.h:492
BOOLEAN Dirty
Definition: cc.h:211
ULONG CcTotalDirtyPages
Definition: view.c:56
#define PAGE_SIZE
Definition: env_spec_w32.h:49
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define VACB_MAPPING_GRANULARITY
LIST_ENTRY DirtyVacbListEntry
Definition: cc.h:218
KSPIN_LOCK CacheMapLock
Definition: cc.h:195
ULONG DirtyPages
Definition: cc.h:180

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