ReactOS  0.4.15-dev-2704-gd5265b0
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 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 
1102 quit:
1103  if (IoStatus)
1104  {
1105  IoStatus->Status = Status;
1106  }
1107 }
#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:44
#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:4662
LONGLONG QuadPart
Definition: typedefs.h:114

◆ 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 }
#define CC_API_DEBUG
Definition: cc.h:11
#define ASSERT(a)
Definition: mode.c:44
#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 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 }
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 
809  /* Reference it to allow release */
811 
812  return Status;
813 }
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
static NPAGED_LOOKASIDE_LIST VacbLookasideList
Definition: view.c:46
static LIST_ENTRY VacbLruListHead
Definition: view.c:42
#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
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:458
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
#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:495
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:492
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:4185
Definition: typedefs.h:119
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 NULL
Definition: types.h:112
#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
#define DPRINT
Definition: sndvol32.h:71
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:44
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:495
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:4662
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 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_ 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:4642
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
BOOLEAN NTAPI MmArePagesResident(_In_ PEPROCESS Process, _In_ PVOID BaseAddress, _In_ ULONG Length)
Definition: section.c:4497
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:44
#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:207
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:44
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:495
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:492
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#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:119
static NTSTATUS CcRosDeleteFileCache(PFILE_OBJECT FileObject, PROS_SHARED_CACHE_MAP SharedCacheMap, PKIRQL OldIrql)
Definition: view.c:205
#define FO_TEMPORARY_FILE
Definition: iotypes.h:1791
_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:4662
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:507
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:44
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:495
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 863 of file view.c.

867 {
870  ULONG Refs;
871  KIRQL OldIrql;
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 }
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:507
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#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 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);
1281  KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
1282 
1283  FileObject->PrivateCacheMap = PrivateMap;
1284  SharedCacheMap->OpenCount++;
1285  }
1286 
1288 
1289  /* Create the section */
1290  if (Allocated)
1291  {
1292  NTSTATUS Status;
1293 
1294  ASSERT(SharedCacheMap->Section == NULL);
1295 
1297  &SharedCacheMap->Section,
1299  NULL,
1300  &SharedCacheMap->SectionSize,
1302  SEC_RESERVE,
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 }
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:381
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:44
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:4342
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:1110
_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 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 }
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:3118
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:44
#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:458
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
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:492
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:44
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:492
#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 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);
1140  KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->CacheMapLock);
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 }
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:44
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:44
FORCEINLINE ULONG CcRosVacbDecRefCount(PROS_VACB vacb)
Definition: cc.h:495
VOID CcRosMarkDirtyVacb(PROS_VACB Vacb)
Definition: view.c:528
BOOLEAN Dirty
Definition: cc.h:211
#define CcRosVacbIncRefCount(vacb)
Definition: cc.h:492
#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 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,
933  FileOffset,
934  Vacb);
935 }
NTSTATUS CcRosGetVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:863
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
#define ASSERT(a)
Definition: mode.c:44
_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:44
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:495
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