/* GLOBALS *******************************************************************/
static LIST_ENTRY DirtyVacbListHead;
-static LIST_ENTRY VacbListHead;
static LIST_ENTRY VacbLruListHead;
ULONG DirtyPageCount = 0;
continue;
}
- Status = KeWaitForSingleObject(¤t->Mutex,
- Executive,
- KernelMode,
- FALSE,
- Wait ? NULL : &ZeroTimeout);
+ Status = CcRosAcquireVacbLock(current,
+ Wait ? NULL : &ZeroTimeout);
if (Status != STATUS_SUCCESS)
{
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
/* One reference is added above */
if (current->ReferenceCount > 2)
{
- KeReleaseMutex(¤t->Mutex, FALSE);
+ CcRosReleaseVacbLock(current);
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
current->SharedCacheMap->LazyWriteContext);
CcRosVacbDecRefCount(current);
Status = CcRosFlushVacb(current);
- KeReleaseMutex(¤t->Mutex, FALSE);
+ CcRosReleaseVacbLock(current);
current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
current->SharedCacheMap->LazyWriteContext);
KeAcquireGuardedMutex(&ViewLock);
CcRosVacbDecRefCount(current);
- if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
+ if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE) &&
+ (Status != STATUS_MEDIA_WRITE_PROTECTED))
{
DPRINT1("CC: Failed to flush VACB.\n");
}
ASSERT(!current->MappedCount);
RemoveEntryList(¤t->CacheMapVacbListEntry);
- RemoveEntryList(¤t->VacbListEntry);
RemoveEntryList(¤t->VacbLruListEntry);
InsertHeadList(&FreeList, ¤t->CacheMapVacbListEntry);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
- KeReleaseMutex(&Vacb->Mutex, FALSE);
+ if (InterlockedCompareExchange(&Vacb->PinCount, 0, 0) == 0)
+ {
+ CcRosReleaseVacbLock(Vacb);
+ }
return STATUS_SUCCESS;
}
NTAPI
CcRosLookupVacb (
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset)
+ LONGLONG FileOffset)
{
PLIST_ENTRY current_entry;
PROS_VACB current;
ASSERT(SharedCacheMap);
- DPRINT("CcRosLookupVacb(SharedCacheMap 0x%p, FileOffset %lu)\n",
+ DPRINT("CcRosLookupVacb(SharedCacheMap 0x%p, FileOffset %I64u)\n",
SharedCacheMap, FileOffset);
KeAcquireGuardedMutex(&ViewLock);
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
CacheMapVacbListEntry);
- if (IsPointInRange(current->FileOffset, VACB_MAPPING_GRANULARITY,
+ if (IsPointInRange(current->FileOffset.QuadPart,
+ VACB_MAPPING_GRANULARITY,
FileOffset))
{
CcRosVacbIncRefCount(current);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
- KeWaitForSingleObject(¤t->Mutex,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ if (InterlockedCompareExchange(¤t->PinCount, 0, 0) == 0)
+ {
+ CcRosAcquireVacbLock(current, NULL);
+ }
return current;
}
- if (current->FileOffset > FileOffset)
+ if (current->FileOffset.QuadPart > FileOffset)
break;
current_entry = current_entry->Flink;
}
NTAPI
CcRosMarkDirtyVacb (
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset)
+ LONGLONG FileOffset)
{
PROS_VACB Vacb;
KIRQL oldIrql;
ASSERT(SharedCacheMap);
- DPRINT("CcRosMarkDirtyVacb(SharedCacheMap 0x%p, FileOffset %lu)\n",
+ DPRINT("CcRosMarkDirtyVacb(SharedCacheMap 0x%p, FileOffset %I64u)\n",
SharedCacheMap, FileOffset);
Vacb = CcRosLookupVacb(SharedCacheMap, FileOffset);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
- KeReleaseMutex(&Vacb->Mutex, FALSE);
+ CcRosReleaseVacbLock(Vacb);
return STATUS_SUCCESS;
}
NTAPI
CcRosUnmapVacb (
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset,
+ LONGLONG FileOffset,
BOOLEAN NowDirty)
{
PROS_VACB Vacb;
ASSERT(SharedCacheMap);
- DPRINT("CcRosUnmapVacb(SharedCacheMap 0x%p, FileOffset %lu, NowDirty %u)\n",
+ DPRINT("CcRosUnmapVacb(SharedCacheMap 0x%p, FileOffset %I64u, NowDirty %u)\n",
SharedCacheMap, FileOffset, NowDirty);
Vacb = CcRosLookupVacb(SharedCacheMap, FileOffset);
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
- KeReleaseMutex(&Vacb->Mutex, FALSE);
+ CcRosReleaseVacbLock(Vacb);
+
+ return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+CcRosMapVacb(
+ PROS_VACB Vacb)
+{
+ ULONG i;
+ NTSTATUS Status;
+ ULONG_PTR NumberOfPages;
+
+ /* Create a memory area. */
+ MmLockAddressSpace(MmGetKernelAddressSpace());
+ Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
+ 0, // nothing checks for VACB mareas, so set to 0
+ &Vacb->BaseAddress,
+ VACB_MAPPING_GRANULARITY,
+ PAGE_READWRITE,
+ (PMEMORY_AREA*)&Vacb->MemoryArea,
+ 0,
+ PAGE_SIZE);
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheck(CACHE_MANAGER);
+ }
+
+ ASSERT(((ULONG_PTR)Vacb->BaseAddress % PAGE_SIZE) == 0);
+ ASSERT((ULONG_PTR)Vacb->BaseAddress > (ULONG_PTR)MmSystemRangeStart);
+
+ /* Create a virtual mapping for this memory area */
+ NumberOfPages = BYTES_TO_PAGES(VACB_MAPPING_GRANULARITY);
+ for (i = 0; i < NumberOfPages; i++)
+ {
+ PFN_NUMBER PageFrameNumber;
+
+ Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &PageFrameNumber);
+ if (PageFrameNumber == 0)
+ {
+ DPRINT1("Unable to allocate page\n");
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+
+ Status = MmCreateVirtualMapping(NULL,
+ (PVOID)((ULONG_PTR)Vacb->BaseAddress + (i * PAGE_SIZE)),
+ PAGE_READWRITE,
+ &PageFrameNumber,
+ 1);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Unable to create virtual mapping\n");
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+ }
return STATUS_SUCCESS;
}
NTSTATUS
CcRosCreateVacb (
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset,
+ LONGLONG FileOffset,
PROS_VACB *Vacb)
{
PROS_VACB current;
DPRINT("CcRosCreateVacb()\n");
- if (FileOffset >= SharedCacheMap->FileSize.u.LowPart)
+ if (FileOffset >= SharedCacheMap->FileSize.QuadPart)
{
*Vacb = NULL;
return STATUS_INVALID_PARAMETER;
}
current = ExAllocateFromNPagedLookasideList(&VacbLookasideList);
+ current->BaseAddress = NULL;
current->Valid = FALSE;
current->Dirty = FALSE;
current->PageOut = FALSE;
- current->FileOffset = ROUND_DOWN(FileOffset, VACB_MAPPING_GRANULARITY);
+ current->FileOffset.QuadPart = ROUND_DOWN(FileOffset, VACB_MAPPING_GRANULARITY);
current->SharedCacheMap = SharedCacheMap;
#if DBG
if (SharedCacheMap->Trace)
current->DirtyVacbListEntry.Flink = NULL;
current->DirtyVacbListEntry.Blink = NULL;
current->ReferenceCount = 1;
+ current->PinCount = 0;
KeInitializeMutex(¤t->Mutex, 0);
- KeWaitForSingleObject(¤t->Mutex,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ CcRosAcquireVacbLock(current, NULL);
KeAcquireGuardedMutex(&ViewLock);
*Vacb = current;
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
CacheMapVacbListEntry);
- if (IsPointInRange(current->FileOffset, VACB_MAPPING_GRANULARITY,
+ if (IsPointInRange(current->FileOffset.QuadPart,
+ VACB_MAPPING_GRANULARITY,
FileOffset))
{
CcRosVacbIncRefCount(current);
current);
}
#endif
- KeReleaseMutex(&(*Vacb)->Mutex, FALSE);
+ CcRosReleaseVacbLock(*Vacb);
KeReleaseGuardedMutex(&ViewLock);
ExFreeToNPagedLookasideList(&VacbLookasideList, *Vacb);
*Vacb = current;
- KeWaitForSingleObject(¤t->Mutex,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ if (InterlockedCompareExchange(¤t->PinCount, 0, 0) == 0)
+ {
+ CcRosAcquireVacbLock(current, NULL);
+ }
return STATUS_SUCCESS;
}
- if (current->FileOffset < FileOffset)
+ if (current->FileOffset.QuadPart < FileOffset)
{
ASSERT(previous == NULL ||
- previous->FileOffset < current->FileOffset);
+ previous->FileOffset.QuadPart < current->FileOffset.QuadPart);
previous = current;
}
- if (current->FileOffset > FileOffset)
+ if (current->FileOffset.QuadPart > FileOffset)
break;
current_entry = current_entry->Flink;
}
InsertHeadList(&SharedCacheMap->CacheMapVacbListHead, ¤t->CacheMapVacbListEntry);
}
KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
- InsertTailList(&VacbListHead, ¤t->VacbListEntry);
InsertTailList(&VacbLruListHead, ¤t->VacbLruListEntry);
KeReleaseGuardedMutex(&ViewLock);
- MmLockAddressSpace(MmGetKernelAddressSpace());
- current->BaseAddress = NULL;
- Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
- 0, // nothing checks for VACB mareas, so set to 0
- ¤t->BaseAddress,
- VACB_MAPPING_GRANULARITY,
- PAGE_READWRITE,
- (PMEMORY_AREA*)¤t->MemoryArea,
- FALSE,
- 0,
- PAGE_SIZE);
- MmUnlockAddressSpace(MmGetKernelAddressSpace());
- if (!NT_SUCCESS(Status))
- {
- KeBugCheck(CACHE_MANAGER);
- }
-
- /* Create a virtual mapping for this memory area */
MI_SET_USAGE(MI_USAGE_CACHE);
#if MI_TRACE_PFNS
- PWCHAR pos = NULL;
- ULONG len = 0;
if ((SharedCacheMap->FileObject) && (SharedCacheMap->FileObject->FileName.Buffer))
{
+ PWCHAR pos = NULL;
+ ULONG len = 0;
pos = wcsrchr(SharedCacheMap->FileObject->FileName.Buffer, '\\');
len = wcslen(pos) * sizeof(WCHAR);
if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos);
}
#endif
- MmMapMemoryArea(current->BaseAddress, VACB_MAPPING_GRANULARITY,
- MC_CACHE, PAGE_READWRITE);
+ Status = CcRosMapVacb(current);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-CcRosGetVacbChain (
- PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset,
- ULONG Length,
- PROS_VACB *Vacb)
-{
- PROS_VACB current;
- ULONG i;
- PROS_VACB *VacbList;
- PROS_VACB Previous = NULL;
-
- ASSERT(SharedCacheMap);
-
- DPRINT("CcRosGetVacbChain()\n");
-
- Length = ROUND_UP(Length, VACB_MAPPING_GRANULARITY);
-
- VacbList = _alloca(sizeof(PROS_VACB) *
- (Length / VACB_MAPPING_GRANULARITY));
-
- /*
- * Look for a VACB already mapping the same data.
- */
- for (i = 0; i < (Length / VACB_MAPPING_GRANULARITY); i++)
- {
- ULONG CurrentOffset = FileOffset + (i * VACB_MAPPING_GRANULARITY);
- current = CcRosLookupVacb(SharedCacheMap, CurrentOffset);
- if (current != NULL)
- {
- KeAcquireGuardedMutex(&ViewLock);
-
- /* Move to tail of LRU list */
- RemoveEntryList(¤t->VacbLruListEntry);
- InsertTailList(&VacbLruListHead, ¤t->VacbLruListEntry);
-
- KeReleaseGuardedMutex(&ViewLock);
-
- VacbList[i] = current;
- }
- else
- {
- CcRosCreateVacb(SharedCacheMap, CurrentOffset, ¤t);
- VacbList[i] = current;
- }
- }
-
- for (i = 0; i < Length / VACB_MAPPING_GRANULARITY; i++)
- {
- if (i == 0)
- {
- *Vacb = VacbList[i];
- Previous = VacbList[i];
- }
- else
- {
- Previous->NextInChain = VacbList[i];
- Previous = VacbList[i];
- }
- }
- ASSERT(Previous);
- Previous->NextInChain = NULL;
-
- return STATUS_SUCCESS;
+ return Status;
}
NTSTATUS
NTAPI
CcRosGetVacb (
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset,
- PULONG BaseOffset,
+ LONGLONG FileOffset,
+ PLONGLONG BaseOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
PROS_VACB *Vacb)
*BaseAddress = current->BaseAddress;
DPRINT("*BaseAddress %p\n", *BaseAddress);
*Vacb = current;
- *BaseOffset = current->FileOffset;
+ *BaseOffset = current->FileOffset.QuadPart;
return STATUS_SUCCESS;
}
NTAPI
CcRosRequestVacb (
PROS_SHARED_CACHE_MAP SharedCacheMap,
- ULONG FileOffset,
+ LONGLONG FileOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
PROS_VACB *Vacb)
* FUNCTION: Request a page mapping for a shared cache map
*/
{
- ULONG BaseOffset;
+ LONGLONG BaseOffset;
ASSERT(SharedCacheMap);
if (FileOffset % VACB_MAPPING_GRANULARITY != 0)
{
- DPRINT1("Bad fileoffset %x should be multiple of %x",
+ DPRINT1("Bad fileoffset %I64x should be multiple of %x",
FileOffset, VACB_MAPPING_GRANULARITY);
KeBugCheck(CACHE_MANAGER);
}
{
PROS_SHARED_CACHE_MAP SharedCacheMap;
LARGE_INTEGER Offset;
+ LONGLONG RemainingLength;
PROS_VACB current;
NTSTATUS Status;
KIRQL oldIrql;
+ CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p FileOffset=%p Length=%lu\n",
+ SectionObjectPointers, FileOffset, Length);
+
DPRINT("CcFlushCache(SectionObjectPointers 0x%p, FileOffset 0x%p, Length %lu, IoStatus 0x%p)\n",
SectionObjectPointers, FileOffset, Length, IoStatus);
if (FileOffset)
{
Offset = *FileOffset;
+ RemainingLength = Length;
}
else
{
- Offset.QuadPart = (LONGLONG)0;
- Length = SharedCacheMap->FileSize.u.LowPart;
+ Offset.QuadPart = 0;
+ RemainingLength = SharedCacheMap->FileSize.QuadPart;
}
if (IoStatus)
IoStatus->Information = 0;
}
- while (Length > 0)
+ while (RemainingLength > 0)
{
- current = CcRosLookupVacb(SharedCacheMap, Offset.u.LowPart);
+ current = CcRosLookupVacb(SharedCacheMap, Offset.QuadPart);
if (current != NULL)
{
if (current->Dirty)
IoStatus->Status = Status;
}
}
- KeReleaseMutex(¤t->Mutex, FALSE);
+
+ if (InterlockedCompareExchange(¤t->PinCount, 0, 0) == 0)
+ {
+ CcRosReleaseVacbLock(current);
+ }
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
}
Offset.QuadPart += VACB_MAPPING_GRANULARITY;
- if (Length > VACB_MAPPING_GRANULARITY)
- {
- Length -= VACB_MAPPING_GRANULARITY;
- }
- else
- {
- Length = 0;
- }
+ RemainingLength -= min(RemainingLength, VACB_MAPPING_GRANULARITY);
}
}
else
{
current_entry = RemoveTailList(&SharedCacheMap->CacheMapVacbListHead);
current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
- RemoveEntryList(¤t->VacbListEntry);
RemoveEntryList(¤t->VacbLruListEntry);
if (current->Dirty)
{
NTAPI
CcRosInitializeFileCache (
PFILE_OBJECT FileObject,
+ PCC_FILE_SIZES FileSizes,
+ BOOLEAN PinAccess,
PCACHE_MANAGER_CALLBACKS CallBacks,
PVOID LazyWriterContext)
/*
if (SharedCacheMap == NULL)
{
KeReleaseGuardedMutex(&ViewLock);
- return STATUS_UNSUCCESSFUL;
+ return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(SharedCacheMap, sizeof(*SharedCacheMap));
ObReferenceObjectByPointer(FileObject,
SharedCacheMap->FileObject = FileObject;
SharedCacheMap->Callbacks = CallBacks;
SharedCacheMap->LazyWriteContext = LazyWriterContext;
- if (FileObject->FsContext)
- {
- SharedCacheMap->AllocationSize =
- ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->AllocationSize;
- SharedCacheMap->FileSize =
- ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize;
- }
+ SharedCacheMap->SectionSize = FileSizes->AllocationSize;
+ SharedCacheMap->FileSize = FileSizes->FileSize;
+ SharedCacheMap->PinAccess = PinAccess;
KeInitializeSpinLock(&SharedCacheMap->CacheMapLock);
InitializeListHead(&SharedCacheMap->CacheMapVacbListHead);
FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap;
IN PSECTION_OBJECT_POINTERS SectionObjectPointers)
{
PROS_SHARED_CACHE_MAP SharedCacheMap;
+
+ CCTRACE(CC_API_DEBUG, "SectionObjectPointers=%p\n", SectionObjectPointers);
+
if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap)
{
SharedCacheMap = SectionObjectPointers->SharedCacheMap;
{
DPRINT("CcInitView()\n");
- InitializeListHead(&VacbListHead);
InitializeListHead(&DirtyVacbListHead);
InitializeListHead(&VacbLruListHead);
KeInitializeGuardedMutex(&ViewLock);
- ExInitializeNPagedLookasideList (&iBcbLookasideList,
- NULL,
- NULL,
- 0,
- sizeof(INTERNAL_BCB),
- TAG_IBCB,
- 20);
- ExInitializeNPagedLookasideList (&SharedCacheMapLookasideList,
- NULL,
- NULL,
- 0,
- sizeof(ROS_SHARED_CACHE_MAP),
- TAG_BCB,
- 20);
- ExInitializeNPagedLookasideList (&VacbLookasideList,
- NULL,
- NULL,
- 0,
- sizeof(ROS_VACB),
- TAG_CSEG,
- 20);
+ ExInitializeNPagedLookasideList(&iBcbLookasideList,
+ NULL,
+ NULL,
+ 0,
+ sizeof(INTERNAL_BCB),
+ TAG_BCB,
+ 20);
+ ExInitializeNPagedLookasideList(&SharedCacheMapLookasideList,
+ NULL,
+ NULL,
+ 0,
+ sizeof(ROS_SHARED_CACHE_MAP),
+ TAG_SHARED_CACHE_MAP,
+ 20);
+ ExInitializeNPagedLookasideList(&VacbLookasideList,
+ NULL,
+ NULL,
+ 0,
+ sizeof(ROS_VACB),
+ TAG_VACB,
+ 20);
MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache);
CcInitCacheZeroPage();
-
}
/* EOF */