[NTOS:CC]

- Rename the CACHE_SEGMENT structure to ROS_VACB. This should eventually become NDK's VACB.
CORE-8065

svn path=/trunk/; revision=62708
This commit is contained in:
Thomas Faber 2014-04-12 09:31:07 +00:00
parent 435846f00f
commit 20cff61d07
6 changed files with 450 additions and 452 deletions

View file

@ -56,17 +56,17 @@ CcInitCacheZeroPage (
NTSTATUS
NTAPI
ReadCacheSegmentChain (
ReadVacbChain (
PBCB Bcb,
ULONG ReadOffset,
ULONG Length,
PVOID Buffer)
{
PCACHE_SEGMENT head;
PCACHE_SEGMENT current;
PCACHE_SEGMENT previous;
PROS_VACB head;
PROS_VACB current;
PROS_VACB previous;
IO_STATUS_BLOCK Iosb;
LARGE_INTEGER SegOffset;
LARGE_INTEGER VacbOffset;
NTSTATUS Status;
ULONG TempLength;
KEVENT Event;
@ -74,7 +74,7 @@ ReadCacheSegmentChain (
Mdl = _alloca(MmSizeOfMdl(NULL, MAX_RW_LENGTH));
Status = CcRosGetCacheSegmentChain(Bcb, ReadOffset, Length, &head);
Status = CcRosGetVacbChain(Bcb, ReadOffset, Length, &head);
if (!NT_SUCCESS(Status))
{
return Status;
@ -83,8 +83,7 @@ ReadCacheSegmentChain (
while (current != NULL)
{
/*
* If the current segment is valid then copy it into the
* user buffer.
* If the current VACB is valid then copy it into the user buffer.
*/
if (current->Valid)
{
@ -96,21 +95,21 @@ ReadCacheSegmentChain (
Length = Length - TempLength;
previous = current;
current = current->NextInChain;
CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, previous, TRUE, FALSE, FALSE);
}
/*
* Otherwise read in as much as we can.
*/
else
{
PCACHE_SEGMENT current2;
PROS_VACB current2;
ULONG current_size;
ULONG i;
PPFN_NUMBER MdlPages;
/*
* Count the maximum number of bytes we could read starting
* from the current segment.
* from the current VACB.
*/
current2 = current;
current_size = 0;
@ -142,11 +141,11 @@ ReadCacheSegmentChain (
/*
* Read in the information.
*/
SegOffset.QuadPart = current->FileOffset;
VacbOffset.QuadPart = current->FileOffset;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Status = IoPageRead(Bcb->FileObject,
Mdl,
&SegOffset,
&VacbOffset,
&Event,
&Iosb);
if (Status == STATUS_PENDING)
@ -164,7 +163,7 @@ ReadCacheSegmentChain (
{
previous = current;
current = current->NextInChain;
CcRosReleaseCacheSegment(Bcb, previous, FALSE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, previous, FALSE, FALSE, FALSE);
}
return Status;
}
@ -179,7 +178,7 @@ ReadCacheSegmentChain (
Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength);
Length = Length - TempLength;
CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, previous, TRUE, FALSE, FALSE);
current_size += VACB_MAPPING_GRANULARITY;
}
}
@ -189,24 +188,24 @@ ReadCacheSegmentChain (
NTSTATUS
NTAPI
ReadCacheSegment (
PCACHE_SEGMENT CacheSeg)
CcReadVirtualAddress (
PROS_VACB Vacb)
{
ULONG Size;
PMDL Mdl;
NTSTATUS Status;
LARGE_INTEGER SegOffset;
LARGE_INTEGER VacbOffset;
IO_STATUS_BLOCK IoStatus;
KEVENT Event;
SegOffset.QuadPart = CacheSeg->FileOffset;
Size = (ULONG)(CacheSeg->Bcb->AllocationSize.QuadPart - CacheSeg->FileOffset);
VacbOffset.QuadPart = Vacb->FileOffset;
Size = (ULONG)(Vacb->Bcb->AllocationSize.QuadPart - Vacb->FileOffset);
if (Size > VACB_MAPPING_GRANULARITY)
{
Size = VACB_MAPPING_GRANULARITY;
}
Mdl = IoAllocateMdl(CacheSeg->BaseAddress, Size, FALSE, FALSE, NULL);
Mdl = IoAllocateMdl(Vacb->BaseAddress, Size, FALSE, FALSE, NULL);
if (!Mdl)
{
return STATUS_INSUFFICIENT_RESOURCES;
@ -215,7 +214,7 @@ ReadCacheSegment (
MmBuildMdlForNonPagedPool(Mdl);
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Status = IoPageRead(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, &Event, &IoStatus);
Status = IoPageRead(Vacb->Bcb->FileObject, Mdl, &VacbOffset, &Event, &IoStatus);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
@ -232,7 +231,7 @@ ReadCacheSegment (
if (Size < VACB_MAPPING_GRANULARITY)
{
RtlZeroMemory((char*)CacheSeg->BaseAddress + Size,
RtlZeroMemory((char*)Vacb->BaseAddress + Size,
VACB_MAPPING_GRANULARITY - Size);
}
@ -241,19 +240,19 @@ ReadCacheSegment (
NTSTATUS
NTAPI
WriteCacheSegment (
PCACHE_SEGMENT CacheSeg)
CcWriteVirtualAddress (
PROS_VACB Vacb)
{
ULONG Size;
PMDL Mdl;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER SegOffset;
LARGE_INTEGER VacbOffset;
KEVENT Event;
CacheSeg->Dirty = FALSE;
SegOffset.QuadPart = CacheSeg->FileOffset;
Size = (ULONG)(CacheSeg->Bcb->AllocationSize.QuadPart - CacheSeg->FileOffset);
Vacb->Dirty = FALSE;
VacbOffset.QuadPart = Vacb->FileOffset;
Size = (ULONG)(Vacb->Bcb->AllocationSize.QuadPart - Vacb->FileOffset);
if (Size > VACB_MAPPING_GRANULARITY)
{
Size = VACB_MAPPING_GRANULARITY;
@ -266,11 +265,11 @@ WriteCacheSegment (
ULONG i = 0;
do
{
MmGetPfnForProcess(NULL, (PVOID)((ULONG_PTR)CacheSeg->BaseAddress + (i << PAGE_SHIFT)));
MmGetPfnForProcess(NULL, (PVOID)((ULONG_PTR)Vacb->BaseAddress + (i << PAGE_SHIFT)));
} while (++i < (Size >> PAGE_SHIFT));
}
Mdl = IoAllocateMdl(CacheSeg->BaseAddress, Size, FALSE, FALSE, NULL);
Mdl = IoAllocateMdl(Vacb->BaseAddress, Size, FALSE, FALSE, NULL);
if (!Mdl)
{
return STATUS_INSUFFICIENT_RESOURCES;
@ -278,7 +277,7 @@ WriteCacheSegment (
MmBuildMdlForNonPagedPool(Mdl);
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Status = IoSynchronousPageWrite(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, &Event, &IoStatus);
Status = IoSynchronousPageWrite(Vacb->Bcb->FileObject, Mdl, &VacbOffset, &Event, &IoStatus);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
@ -288,7 +287,7 @@ WriteCacheSegment (
if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
{
DPRINT1("IoPageWrite failed, Status %x\n", Status);
CacheSeg->Dirty = TRUE;
Vacb->Dirty = TRUE;
return Status;
}
@ -329,13 +328,13 @@ CcCopyRead (
ULONG TempLength;
NTSTATUS Status = STATUS_SUCCESS;
PVOID BaseAddress;
PCACHE_SEGMENT CacheSeg;
PROS_VACB Vacb;
BOOLEAN Valid;
ULONG ReadLength = 0;
PBCB Bcb;
KIRQL oldirql;
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
PROS_VACB current;
DPRINT("CcCopyRead(FileObject 0x%p, FileOffset %I64x, "
"Length %lu, Wait %u, Buffer 0x%p, IoStatus 0x%p)\n",
@ -350,22 +349,22 @@ CcCopyRead (
Bcb->FileSize.QuadPart);
/*
* Check for the nowait case that all the cache segments that would
* Check for the nowait case that all the cache VACBs that would
* cover this read are in memory.
*/
if (!Wait)
{
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
/* FIXME: this loop doesn't take into account areas that don't have
* a segment in the list yet */
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
* a VACB in the list yet */
current_entry = Bcb->BcbVacbListHead.Flink;
while (current_entry != &Bcb->BcbVacbListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
current = CONTAINING_RECORD(current_entry, ROS_VACB,
BcbVacbListEntry);
if (!current->Valid &&
DoSegmentsIntersect(current->FileOffset, VACB_MAPPING_GRANULARITY,
ReadOffset, Length))
DoRangesIntersect(current->FileOffset, VACB_MAPPING_GRANULARITY,
ReadOffset, Length))
{
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
IoStatus->Status = STATUS_UNSUCCESSFUL;
@ -383,32 +382,32 @@ CcCopyRead (
if (TempLength != 0)
{
TempLength = min(Length, VACB_MAPPING_GRANULARITY - TempLength);
Status = CcRosRequestCacheSegment(Bcb,
ROUND_DOWN(ReadOffset,
VACB_MAPPING_GRANULARITY),
&BaseAddress, &Valid, &CacheSeg);
Status = CcRosRequestVacb(Bcb,
ROUND_DOWN(ReadOffset,
VACB_MAPPING_GRANULARITY),
&BaseAddress, &Valid, &Vacb);
if (!NT_SUCCESS(Status))
{
IoStatus->Information = 0;
IoStatus->Status = Status;
DPRINT("CcRosRequestCacheSegment faild, Status %x\n", Status);
DPRINT("CcRosRequestVacb failed, Status %x\n", Status);
return FALSE;
}
if (!Valid)
{
Status = ReadCacheSegment(CacheSeg);
Status = CcReadVirtualAddress(Vacb);
if (!NT_SUCCESS(Status))
{
IoStatus->Information = 0;
IoStatus->Status = Status;
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
return FALSE;
}
}
RtlCopyMemory(Buffer,
(char*)BaseAddress + ReadOffset % VACB_MAPPING_GRANULARITY,
TempLength);
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
ReadLength += TempLength;
Length -= TempLength;
ReadOffset += TempLength;
@ -418,12 +417,12 @@ CcCopyRead (
while (Length > 0)
{
TempLength = min(VACB_MAPPING_GRANULARITY, Length);
Status = ReadCacheSegmentChain(Bcb, ReadOffset, TempLength, Buffer);
Status = ReadVacbChain(Bcb, ReadOffset, TempLength, Buffer);
if (!NT_SUCCESS(Status))
{
IoStatus->Information = 0;
IoStatus->Status = Status;
DPRINT("ReadCacheSegmentChain failed, Status %x\n", Status);
DPRINT("ReadVacbChain failed, Status %x\n", Status);
return FALSE;
}
@ -457,7 +456,7 @@ CcCopyWrite (
KIRQL oldirql;
PBCB Bcb;
PLIST_ENTRY current_entry;
PCACHE_SEGMENT CacheSeg;
PROS_VACB Vacb;
ULONG TempLength;
PVOID BaseAddress;
BOOLEAN Valid;
@ -474,21 +473,22 @@ CcCopyWrite (
/* testing, if the requested datas are available */
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
/* FIXME: this loop doesn't take into account areas that don't have
* a segment in the list yet */
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
* a VACB in the list yet */
current_entry = Bcb->BcbVacbListHead.Flink;
while (current_entry != &Bcb->BcbVacbListHead)
{
CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
if (!CacheSeg->Valid &&
DoSegmentsIntersect(CacheSeg->FileOffset, VACB_MAPPING_GRANULARITY,
WriteOffset, Length))
Vacb = CONTAINING_RECORD(current_entry,
ROS_VACB,
BcbVacbListEntry);
if (!Vacb->Valid &&
DoRangesIntersect(Vacb->FileOffset, VACB_MAPPING_GRANULARITY,
WriteOffset, Length))
{
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
/* datas not available */
return FALSE;
}
if (CacheSeg->FileOffset >= WriteOffset + Length)
if (Vacb->FileOffset >= WriteOffset + Length)
break;
current_entry = current_entry->Flink;
}
@ -501,15 +501,15 @@ CcCopyWrite (
ULONG ROffset;
ROffset = ROUND_DOWN(WriteOffset, VACB_MAPPING_GRANULARITY);
TempLength = min(Length, VACB_MAPPING_GRANULARITY - TempLength);
Status = CcRosRequestCacheSegment(Bcb, ROffset,
&BaseAddress, &Valid, &CacheSeg);
Status = CcRosRequestVacb(Bcb, ROffset,
&BaseAddress, &Valid, &Vacb);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
if (!Valid)
{
if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
if (!NT_SUCCESS(CcReadVirtualAddress(Vacb)))
{
return FALSE;
}
@ -517,7 +517,7 @@ CcCopyWrite (
RtlCopyMemory((char*)BaseAddress + WriteOffset % VACB_MAPPING_GRANULARITY,
Buffer,
TempLength);
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, TRUE, TRUE, FALSE);
Length -= TempLength;
WriteOffset += TempLength;
@ -528,25 +528,25 @@ CcCopyWrite (
while (Length > 0)
{
TempLength = min(VACB_MAPPING_GRANULARITY, Length);
Status = CcRosRequestCacheSegment(Bcb,
WriteOffset,
&BaseAddress,
&Valid,
&CacheSeg);
Status = CcRosRequestVacb(Bcb,
WriteOffset,
&BaseAddress,
&Valid,
&Vacb);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
if (!Valid && TempLength < VACB_MAPPING_GRANULARITY)
{
if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
if (!NT_SUCCESS(CcReadVirtualAddress(Vacb)))
{
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
return FALSE;
}
}
RtlCopyMemory(BaseAddress, Buffer, TempLength);
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, TRUE, TRUE, FALSE);
Length -= TempLength;
WriteOffset += TempLength;
@ -686,7 +686,7 @@ CcZeroData (
KIRQL oldirql;
PBCB Bcb;
PLIST_ENTRY current_entry;
PCACHE_SEGMENT CacheSeg, current, previous;
PROS_VACB Vacb, current, previous;
ULONG TempLength;
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
@ -695,21 +695,22 @@ CcZeroData (
/* testing, if the requested datas are available */
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
/* FIXME: this loop doesn't take into account areas that don't have
* a segment in the list yet */
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
* a VACB in the list yet */
current_entry = Bcb->BcbVacbListHead.Flink;
while (current_entry != &Bcb->BcbVacbListHead)
{
CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
if (!CacheSeg->Valid &&
DoSegmentsIntersect(CacheSeg->FileOffset, VACB_MAPPING_GRANULARITY,
WriteOffset.u.LowPart, Length))
Vacb = CONTAINING_RECORD(current_entry,
ROS_VACB,
BcbVacbListEntry);
if (!Vacb->Valid &&
DoRangesIntersect(Vacb->FileOffset, VACB_MAPPING_GRANULARITY,
WriteOffset.u.LowPart, Length))
{
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
/* datas not available */
return FALSE;
}
if (CacheSeg->FileOffset >= WriteOffset.u.LowPart + Length)
if (Vacb->FileOffset >= WriteOffset.u.LowPart + Length)
break;
current_entry = current_entry->Flink;
}
@ -728,13 +729,13 @@ CcZeroData (
{
CurrentLength = Length;
}
Status = CcRosGetCacheSegmentChain (Bcb, WriteOffset.u.LowPart - Offset,
Offset + CurrentLength, &CacheSeg);
Status = CcRosGetVacbChain(Bcb, WriteOffset.u.LowPart - Offset,
Offset + CurrentLength, &Vacb);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
current = CacheSeg;
current = Vacb;
while (current != NULL)
{
@ -744,11 +745,11 @@ CcZeroData (
{
if (!current->Valid)
{
/* read the segment */
Status = ReadCacheSegment(current);
/* read the block */
Status = CcReadVirtualAddress(current);
if (!NT_SUCCESS(Status))
{
DPRINT1("ReadCacheSegment failed, status %x\n",
DPRINT1("CcReadVirtualAddress failed, status %x\n",
Status);
}
}
@ -768,12 +769,12 @@ CcZeroData (
current = current->NextInChain;
}
current = CacheSeg;
current = Vacb;
while (current != NULL)
{
previous = current;
current = current->NextInChain;
CcRosReleaseCacheSegment(Bcb, previous, TRUE, TRUE, FALSE);
CcRosReleaseVacb(Bcb, previous, TRUE, TRUE, FALSE);
}
}
}

View file

@ -22,7 +22,7 @@
extern KGUARDED_MUTEX ViewLock;
extern ULONG DirtyPageCount;
NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg);
NTSTATUS CcRosInternalFreeVacb(PROS_VACB Vacb);
/* FUNCTIONS *****************************************************************/
@ -52,7 +52,7 @@ CcGetFileObjectFromBcb (
IN PVOID Bcb)
{
PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb;
return iBcb->CacheSegment->Bcb->FileObject;
return iBcb->Vacb->Bcb->FileObject;
}
/*
@ -130,7 +130,7 @@ CcSetFileSizes (
KIRQL oldirql;
PBCB Bcb;
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
PROS_VACB current;
LIST_ENTRY FreeListHead;
NTSTATUS Status;
@ -156,30 +156,30 @@ CcSetFileSizes (
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
current_entry = Bcb->BcbVacbListHead.Flink;
while (current_entry != &Bcb->BcbVacbListHead)
{
current = CONTAINING_RECORD(current_entry,
CACHE_SEGMENT,
BcbSegmentListEntry);
ROS_VACB,
BcbVacbListEntry);
current_entry = current_entry->Flink;
if (current->FileOffset >= FileSizes->AllocationSize.QuadPart)
{
if ((current->ReferenceCount == 0) || ((current->ReferenceCount == 1) && current->Dirty))
{
RemoveEntryList(&current->BcbSegmentListEntry);
RemoveEntryList(&current->CacheSegmentListEntry);
RemoveEntryList(&current->CacheSegmentLRUListEntry);
RemoveEntryList(&current->BcbVacbListEntry);
RemoveEntryList(&current->VacbListEntry);
RemoveEntryList(&current->VacbLruListEntry);
if (current->Dirty)
{
RemoveEntryList(&current->DirtySegmentListEntry);
RemoveEntryList(&current->DirtyVacbListEntry);
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
}
InsertHeadList(&FreeListHead, &current->BcbSegmentListEntry);
InsertHeadList(&FreeListHead, &current->BcbVacbListEntry);
}
else
{
DPRINT1("Anyone has referenced a cache segment behind the new size.\n");
DPRINT1("Someone has referenced a VACB behind the new size.\n");
KeBugCheck(CACHE_MANAGER);
}
}
@ -193,12 +193,12 @@ CcSetFileSizes (
current_entry = FreeListHead.Flink;
while(current_entry != &FreeListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
current = CONTAINING_RECORD(current_entry, ROS_VACB, BcbVacbListEntry);
current_entry = current_entry->Flink;
Status = CcRosInternalFreeCacheSegment(current);
Status = CcRosInternalFreeVacb(current);
if (!NT_SUCCESS(Status))
{
DPRINT1("CcRosInternalFreeCacheSegment failed, status = %x\n", Status);
DPRINT1("CcRosInternalFreeVacb failed, status = %x\n", Status);
KeBugCheck(CACHE_MANAGER);
}
}

View file

@ -35,7 +35,7 @@ CcMapData (
ULONG ReadOffset;
BOOLEAN Valid;
PBCB Bcb;
PCACHE_SEGMENT CacheSeg;
PROS_VACB Vacb;
NTSTATUS Status;
PINTERNAL_BCB iBcb;
ULONG ROffset;
@ -63,11 +63,11 @@ CcMapData (
}
ROffset = ROUND_DOWN(ReadOffset, VACB_MAPPING_GRANULARITY);
Status = CcRosRequestCacheSegment(Bcb,
ROffset,
pBuffer,
&Valid,
&CacheSeg);
Status = CcRosRequestVacb(Bcb,
ROffset,
pBuffer,
&Valid,
&Vacb);
if (!NT_SUCCESS(Status))
{
return FALSE;
@ -77,13 +77,13 @@ CcMapData (
{
if (!(Flags & MAP_WAIT))
{
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
return FALSE;
}
if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
if (!NT_SUCCESS(CcReadVirtualAddress(Vacb)))
{
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
return FALSE;
}
}
@ -92,7 +92,7 @@ CcMapData (
iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList);
if (iBcb == NULL)
{
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
return FALSE;
}
@ -101,7 +101,7 @@ CcMapData (
iBcb->PFCB.NodeByteSize = sizeof(PUBLIC_BCB);
iBcb->PFCB.MappedLength = Length;
iBcb->PFCB.MappedFileOffset = *FileOffset;
iBcb->CacheSegment = CacheSeg;
iBcb->Vacb = Vacb;
iBcb->Dirty = FALSE;
iBcb->RefCount = 1;
*pBcb = (PVOID)iBcb;
@ -165,7 +165,7 @@ CcPreparePinWrite (
/*
* FIXME: This is function is similar to CcPinRead, but doesn't
* read the data if they're not present. Instead it should just
* prepare the cache segments and zero them out if Zero == TRUE.
* prepare the VACBs and zero them out if Zero == TRUE.
*
* For now calling CcPinRead is better than returning error or
* just having UNIMPLEMENTED here.
@ -195,11 +195,11 @@ CcUnpinData (
{
PINTERNAL_BCB iBcb = Bcb;
CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb,
iBcb->CacheSegment,
TRUE,
iBcb->Dirty,
FALSE);
CcRosReleaseVacb(iBcb->Vacb->Bcb,
iBcb->Vacb,
TRUE,
iBcb->Dirty,
FALSE);
if (--iBcb->RefCount == 0)
{
ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
@ -248,20 +248,20 @@ CcUnpinRepinnedBcb (
IoStatus->Information = 0;
if (WriteThrough)
{
KeWaitForSingleObject(&iBcb->CacheSegment->Mutex,
KeWaitForSingleObject(&iBcb->Vacb->Mutex,
Executive,
KernelMode,
FALSE,
NULL);
if (iBcb->CacheSegment->Dirty)
if (iBcb->Vacb->Dirty)
{
IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment);
IoStatus->Status = CcRosFlushVacb(iBcb->Vacb);
}
else
{
IoStatus->Status = STATUS_SUCCESS;
}
KeReleaseMutex(&iBcb->CacheSegment->Mutex, FALSE);
KeReleaseMutex(&iBcb->Vacb->Mutex, FALSE);
}
else
{

View file

@ -41,9 +41,9 @@
/* GLOBALS *******************************************************************/
static LIST_ENTRY DirtySegmentListHead;
static LIST_ENTRY CacheSegmentListHead;
static LIST_ENTRY CacheSegmentLRUListHead;
static LIST_ENTRY DirtyVacbListHead;
static LIST_ENTRY VacbListHead;
static LIST_ENTRY VacbLruListHead;
static LIST_ENTRY ClosedListHead;
ULONG DirtyPageCount = 0;
@ -51,36 +51,36 @@ KGUARDED_MUTEX ViewLock;
NPAGED_LOOKASIDE_LIST iBcbLookasideList;
static NPAGED_LOOKASIDE_LIST BcbLookasideList;
static NPAGED_LOOKASIDE_LIST CacheSegLookasideList;
static NPAGED_LOOKASIDE_LIST VacbLookasideList;
#if DBG
static void CcRosCacheSegmentIncRefCount_ ( PCACHE_SEGMENT cs, const char* file, int line )
static void CcRosVacbIncRefCount_(PROS_VACB vacb, const char* file, int line)
{
++cs->ReferenceCount;
if ( cs->Bcb->Trace )
++vacb->ReferenceCount;
if (vacb->Bcb->Trace)
{
DbgPrint("(%s:%i) CacheSegment %p ++RefCount=%lu, Dirty %u, PageOut %lu\n",
file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut );
DbgPrint("(%s:%i) VACB %p ++RefCount=%lu, Dirty %u, PageOut %lu\n",
file, line, vacb, vacb->ReferenceCount, vacb->Dirty, vacb->PageOut);
}
}
static void CcRosCacheSegmentDecRefCount_ ( PCACHE_SEGMENT cs, const char* file, int line )
static void CcRosVacbDecRefCount_(PROS_VACB vacb, const char* file, int line)
{
--cs->ReferenceCount;
if ( cs->Bcb->Trace )
--vacb->ReferenceCount;
if (vacb->Bcb->Trace)
{
DbgPrint("(%s:%i) CacheSegment %p --RefCount=%lu, Dirty %u, PageOut %lu\n",
file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut );
DbgPrint("(%s:%i) VACB %p --RefCount=%lu, Dirty %u, PageOut %lu\n",
file, line, vacb, vacb->ReferenceCount, vacb->Dirty, vacb->PageOut);
}
}
#define CcRosCacheSegmentIncRefCount(cs) CcRosCacheSegmentIncRefCount_(cs,__FILE__,__LINE__)
#define CcRosCacheSegmentDecRefCount(cs) CcRosCacheSegmentDecRefCount_(cs,__FILE__,__LINE__)
#define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
#define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
#else
#define CcRosCacheSegmentIncRefCount(cs) (++((cs)->ReferenceCount))
#define CcRosCacheSegmentDecRefCount(cs) (--((cs)->ReferenceCount))
#define CcRosVacbIncRefCount(vacb) (++((vacb)->ReferenceCount))
#define CcRosVacbDecRefCount(vacb) (--((vacb)->ReferenceCount))
#endif
NTSTATUS
CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg);
CcRosInternalFreeVacb(PROS_VACB Vacb);
/* FUNCTIONS *****************************************************************/
@ -94,7 +94,7 @@ CcRosTraceCacheMap (
#if DBG
KIRQL oldirql;
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
PROS_VACB current;
if ( !Bcb )
return;
@ -108,13 +108,13 @@ CcRosTraceCacheMap (
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
current_entry = Bcb->BcbVacbListHead.Flink;
while (current_entry != &Bcb->BcbVacbListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
current = CONTAINING_RECORD(current_entry, ROS_VACB, BcbVacbListEntry);
current_entry = current_entry->Flink;
DPRINT1(" CacheSegment 0x%p enabled, RefCount %lu, Dirty %u, PageOut %lu\n",
DPRINT1(" VACB 0x%p enabled, RefCount %lu, Dirty %u, PageOut %lu\n",
current, current->ReferenceCount, current->Dirty, current->PageOut );
}
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
@ -133,24 +133,24 @@ CcRosTraceCacheMap (
NTSTATUS
NTAPI
CcRosFlushCacheSegment (
PCACHE_SEGMENT CacheSegment)
CcRosFlushVacb (
PROS_VACB Vacb)
{
NTSTATUS Status;
KIRQL oldIrql;
Status = WriteCacheSegment(CacheSegment);
Status = CcWriteVirtualAddress(Vacb);
if (NT_SUCCESS(Status))
{
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&CacheSegment->Bcb->BcbLock, &oldIrql);
KeAcquireSpinLock(&Vacb->Bcb->BcbLock, &oldIrql);
CacheSegment->Dirty = FALSE;
RemoveEntryList(&CacheSegment->DirtySegmentListEntry);
Vacb->Dirty = FALSE;
RemoveEntryList(&Vacb->DirtyVacbListEntry);
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
CcRosCacheSegmentDecRefCount(CacheSegment);
CcRosVacbDecRefCount(Vacb);
KeReleaseSpinLock(&CacheSegment->Bcb->BcbLock, oldIrql);
KeReleaseSpinLock(&Vacb->Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
}
@ -165,8 +165,7 @@ CcRosFlushDirtyPages (
BOOLEAN Wait)
{
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
ULONG PagesPerSegment;
PROS_VACB current;
BOOLEAN Locked;
NTSTATUS Status;
LARGE_INTEGER ZeroTimeout;
@ -179,25 +178,26 @@ CcRosFlushDirtyPages (
KeEnterCriticalRegion();
KeAcquireGuardedMutex(&ViewLock);
current_entry = DirtySegmentListHead.Flink;
if (current_entry == &DirtySegmentListHead)
current_entry = DirtyVacbListHead.Flink;
if (current_entry == &DirtyVacbListHead)
{
DPRINT("No Dirty pages\n");
}
while ((current_entry != &DirtySegmentListHead) && (Target > 0))
while ((current_entry != &DirtyVacbListHead) && (Target > 0))
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
DirtySegmentListEntry);
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
DirtyVacbListEntry);
current_entry = current_entry->Flink;
CcRosCacheSegmentIncRefCount(current);
CcRosVacbIncRefCount(current);
Locked = current->Bcb->Callbacks->AcquireForLazyWrite(
current->Bcb->LazyWriteContext, Wait);
if (!Locked)
{
CcRosCacheSegmentDecRefCount(current);
CcRosVacbDecRefCount(current);
continue;
}
@ -210,7 +210,7 @@ CcRosFlushDirtyPages (
{
current->Bcb->Callbacks->ReleaseFromLazyWrite(
current->Bcb->LazyWriteContext);
CcRosCacheSegmentDecRefCount(current);
CcRosVacbDecRefCount(current);
continue;
}
@ -222,34 +222,32 @@ CcRosFlushDirtyPages (
KeReleaseMutex(&current->Mutex, FALSE);
current->Bcb->Callbacks->ReleaseFromLazyWrite(
current->Bcb->LazyWriteContext);
CcRosCacheSegmentDecRefCount(current);
CcRosVacbDecRefCount(current);
continue;
}
PagesPerSegment = VACB_MAPPING_GRANULARITY / PAGE_SIZE;
KeReleaseGuardedMutex(&ViewLock);
Status = CcRosFlushCacheSegment(current);
Status = CcRosFlushVacb(current);
KeReleaseMutex(&current->Mutex, FALSE);
current->Bcb->Callbacks->ReleaseFromLazyWrite(
current->Bcb->LazyWriteContext);
KeAcquireGuardedMutex(&ViewLock);
CcRosCacheSegmentDecRefCount(current);
CcRosVacbDecRefCount(current);
if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
{
DPRINT1("CC: Failed to flush cache segment.\n");
DPRINT1("CC: Failed to flush VACB.\n");
}
else
{
(*Count) += PagesPerSegment;
Target -= PagesPerSegment;
(*Count) += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
Target -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
}
current_entry = DirtySegmentListHead.Flink;
current_entry = DirtyVacbListHead.Flink;
}
KeReleaseGuardedMutex(&ViewLock);
@ -274,8 +272,7 @@ CcRosTrimCache (
*/
{
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
ULONG PagesPerSegment;
PROS_VACB current;
ULONG PagesFreed;
KIRQL oldIrql;
LIST_ENTRY FreeList;
@ -292,17 +289,18 @@ CcRosTrimCache (
retry:
KeAcquireGuardedMutex(&ViewLock);
current_entry = CacheSegmentLRUListHead.Flink;
while (current_entry != &CacheSegmentLRUListHead)
current_entry = VacbLruListHead.Flink;
while (current_entry != &VacbLruListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
CacheSegmentLRUListEntry);
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
VacbLruListEntry);
current_entry = current_entry->Flink;
KeAcquireSpinLock(&current->Bcb->BcbLock, &oldIrql);
/* Reference the cache segment */
CcRosCacheSegmentIncRefCount(current);
/* Reference the VACB */
CcRosVacbIncRefCount(current);
/* Check if it's mapped and not dirty */
if (current->MappedCount > 0 && !current->Dirty)
@ -311,7 +309,7 @@ retry:
KeReleaseSpinLock(&current->Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
/* Page out the segment */
/* Page out the VACB */
for (i = 0; i < VACB_MAPPING_GRANULARITY / PAGE_SIZE; i++)
{
Page = (PFN_NUMBER)(MmGetPhysicalAddress((PUCHAR)current->BaseAddress + (i * PAGE_SIZE)).QuadPart >> PAGE_SHIFT);
@ -324,8 +322,8 @@ retry:
KeAcquireSpinLock(&current->Bcb->BcbLock, &oldIrql);
}
/* Dereference the cache segment */
CcRosCacheSegmentDecRefCount(current);
/* Dereference the VACB */
CcRosVacbDecRefCount(current);
/* Check if we can free this entry now */
if (current->ReferenceCount == 0)
@ -333,14 +331,13 @@ retry:
ASSERT(!current->Dirty);
ASSERT(!current->MappedCount);
RemoveEntryList(&current->BcbSegmentListEntry);
RemoveEntryList(&current->CacheSegmentListEntry);
RemoveEntryList(&current->CacheSegmentLRUListEntry);
InsertHeadList(&FreeList, &current->BcbSegmentListEntry);
RemoveEntryList(&current->BcbVacbListEntry);
RemoveEntryList(&current->VacbListEntry);
RemoveEntryList(&current->VacbLruListEntry);
InsertHeadList(&FreeList, &current->BcbVacbListEntry);
/* Calculate how many pages we freed for Mm */
PagesPerSegment = VACB_MAPPING_GRANULARITY / PAGE_SIZE;
PagesFreed = min(PagesPerSegment, Target);
PagesFreed = min(VACB_MAPPING_GRANULARITY / PAGE_SIZE, Target);
Target -= PagesFreed;
(*NrFreed) += PagesFreed;
}
@ -372,9 +369,10 @@ retry:
while (!IsListEmpty(&FreeList))
{
current_entry = RemoveHeadList(&FreeList);
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
CcRosInternalFreeCacheSegment(current);
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
BcbVacbListEntry);
CcRosInternalFreeVacb(current);
}
DPRINT("Evicted %lu cache pages\n", (*NrFreed));
@ -384,9 +382,9 @@ retry:
NTSTATUS
NTAPI
CcRosReleaseCacheSegment (
CcRosReleaseVacb (
PBCB Bcb,
PCACHE_SEGMENT CacheSeg,
PROS_VACB Vacb,
BOOLEAN Valid,
BOOLEAN Dirty,
BOOLEAN Mapped)
@ -396,71 +394,72 @@ CcRosReleaseCacheSegment (
ASSERT(Bcb);
DPRINT("CcReleaseCacheSegment(Bcb 0x%p, CacheSeg 0x%p, Valid %u)\n",
Bcb, CacheSeg, Valid);
DPRINT("CcRosReleaseVacb(Bcb 0x%p, Vacb 0x%p, Valid %u)\n",
Bcb, Vacb, Valid);
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
CacheSeg->Valid = Valid;
Vacb->Valid = Valid;
WasDirty = CacheSeg->Dirty;
CacheSeg->Dirty = CacheSeg->Dirty || Dirty;
WasDirty = Vacb->Dirty;
Vacb->Dirty = Vacb->Dirty || Dirty;
if (!WasDirty && CacheSeg->Dirty)
if (!WasDirty && Vacb->Dirty)
{
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
}
if (Mapped)
{
CacheSeg->MappedCount++;
Vacb->MappedCount++;
}
CcRosCacheSegmentDecRefCount(CacheSeg);
if (Mapped && (CacheSeg->MappedCount == 1))
CcRosVacbDecRefCount(Vacb);
if (Mapped && (Vacb->MappedCount == 1))
{
CcRosCacheSegmentIncRefCount(CacheSeg);
CcRosVacbIncRefCount(Vacb);
}
if (!WasDirty && CacheSeg->Dirty)
if (!WasDirty && Vacb->Dirty)
{
CcRosCacheSegmentIncRefCount(CacheSeg);
CcRosVacbIncRefCount(Vacb);
}
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
KeReleaseMutex(&CacheSeg->Mutex, FALSE);
KeReleaseMutex(&Vacb->Mutex, FALSE);
return STATUS_SUCCESS;
}
/* Returns with Cache Segment Lock Held! */
PCACHE_SEGMENT
/* Returns with VACB Lock Held! */
PROS_VACB
NTAPI
CcRosLookupCacheSegment (
CcRosLookupVacb (
PBCB Bcb,
ULONG FileOffset)
{
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
PROS_VACB current;
KIRQL oldIrql;
ASSERT(Bcb);
DPRINT("CcRosLookupCacheSegment(Bcb -x%p, FileOffset %lu)\n", Bcb, FileOffset);
DPRINT("CcRosLookupVacb(Bcb -x%p, FileOffset %lu)\n", Bcb, FileOffset);
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
current_entry = Bcb->BcbVacbListHead.Flink;
while (current_entry != &Bcb->BcbVacbListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
if (IsPointInSegment(current->FileOffset, VACB_MAPPING_GRANULARITY,
FileOffset))
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
BcbVacbListEntry);
if (IsPointInRange(current->FileOffset, VACB_MAPPING_GRANULARITY,
FileOffset))
{
CcRosCacheSegmentIncRefCount(current);
CcRosVacbIncRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
KeWaitForSingleObject(&current->Mutex,
@ -483,19 +482,19 @@ CcRosLookupCacheSegment (
NTSTATUS
NTAPI
CcRosMarkDirtyCacheSegment (
CcRosMarkDirtyVacb (
PBCB Bcb,
ULONG FileOffset)
{
PCACHE_SEGMENT CacheSeg;
PROS_VACB Vacb;
KIRQL oldIrql;
ASSERT(Bcb);
DPRINT("CcRosMarkDirtyCacheSegment(Bcb 0x%p, FileOffset %lu)\n", Bcb, FileOffset);
DPRINT("CcRosMarkDirtyVacb(Bcb 0x%p, FileOffset %lu)\n", Bcb, FileOffset);
CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset);
if (CacheSeg == NULL)
Vacb = CcRosLookupVacb(Bcb, FileOffset);
if (Vacb == NULL)
{
KeBugCheck(CACHE_MANAGER);
}
@ -503,47 +502,47 @@ CcRosMarkDirtyCacheSegment (
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
if (!CacheSeg->Dirty)
if (!Vacb->Dirty)
{
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
}
else
{
CcRosCacheSegmentDecRefCount(CacheSeg);
CcRosVacbDecRefCount(Vacb);
}
/* Move to the tail of the LRU list */
RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry);
InsertTailList(&CacheSegmentLRUListHead, &CacheSeg->CacheSegmentLRUListEntry);
RemoveEntryList(&Vacb->VacbLruListEntry);
InsertTailList(&VacbLruListHead, &Vacb->VacbLruListEntry);
CacheSeg->Dirty = TRUE;
Vacb->Dirty = TRUE;
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
KeReleaseMutex(&CacheSeg->Mutex, FALSE);
KeReleaseMutex(&Vacb->Mutex, FALSE);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
CcRosUnmapCacheSegment (
CcRosUnmapVacb (
PBCB Bcb,
ULONG FileOffset,
BOOLEAN NowDirty)
{
PCACHE_SEGMENT CacheSeg;
PROS_VACB Vacb;
BOOLEAN WasDirty;
KIRQL oldIrql;
ASSERT(Bcb);
DPRINT("CcRosUnmapCacheSegment(Bcb 0x%p, FileOffset %lu, NowDirty %u)\n",
DPRINT("CcRosUnmapVacb(Bcb 0x%p, FileOffset %lu, NowDirty %u)\n",
Bcb, FileOffset, NowDirty);
CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset);
if (CacheSeg == NULL)
Vacb = CcRosLookupVacb(Bcb, FileOffset);
if (Vacb == NULL)
{
return STATUS_UNSUCCESSFUL;
}
@ -551,58 +550,58 @@ CcRosUnmapCacheSegment (
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
WasDirty = CacheSeg->Dirty;
CacheSeg->Dirty = CacheSeg->Dirty || NowDirty;
WasDirty = Vacb->Dirty;
Vacb->Dirty = Vacb->Dirty || NowDirty;
CacheSeg->MappedCount--;
Vacb->MappedCount--;
if (!WasDirty && NowDirty)
{
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
}
CcRosCacheSegmentDecRefCount(CacheSeg);
CcRosVacbDecRefCount(Vacb);
if (!WasDirty && NowDirty)
{
CcRosCacheSegmentIncRefCount(CacheSeg);
CcRosVacbIncRefCount(Vacb);
}
if (CacheSeg->MappedCount == 0)
if (Vacb->MappedCount == 0)
{
CcRosCacheSegmentDecRefCount(CacheSeg);
CcRosVacbDecRefCount(Vacb);
}
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
KeReleaseMutex(&CacheSeg->Mutex, FALSE);
KeReleaseMutex(&Vacb->Mutex, FALSE);
return STATUS_SUCCESS;
}
static
NTSTATUS
CcRosCreateCacheSegment (
CcRosCreateVacb (
PBCB Bcb,
ULONG FileOffset,
PCACHE_SEGMENT* CacheSeg)
PROS_VACB *Vacb)
{
PCACHE_SEGMENT current;
PCACHE_SEGMENT previous;
PROS_VACB current;
PROS_VACB previous;
PLIST_ENTRY current_entry;
NTSTATUS Status;
KIRQL oldIrql;
ASSERT(Bcb);
DPRINT("CcRosCreateCacheSegment()\n");
DPRINT("CcRosCreateVacb()\n");
if (FileOffset >= Bcb->FileSize.u.LowPart)
{
*CacheSeg = NULL;
*Vacb = NULL;
return STATUS_INVALID_PARAMETER;
}
current = ExAllocateFromNPagedLookasideList(&CacheSegLookasideList);
current = ExAllocateFromNPagedLookasideList(&VacbLookasideList);
current->Valid = FALSE;
current->Dirty = FALSE;
current->PageOut = FALSE;
@ -611,12 +610,12 @@ CcRosCreateCacheSegment (
#if DBG
if ( Bcb->Trace )
{
DPRINT1("CacheMap 0x%p: new Cache Segment: 0x%p\n", Bcb, current );
DPRINT1("CacheMap 0x%p: new VACB: 0x%p\n", Bcb, current );
}
#endif
current->MappedCount = 0;
current->DirtySegmentListEntry.Flink = NULL;
current->DirtySegmentListEntry.Blink = NULL;
current->DirtyVacbListEntry.Flink = NULL;
current->DirtyVacbListEntry.Blink = NULL;
current->ReferenceCount = 1;
KeInitializeMutex(&current->Mutex, 0);
KeWaitForSingleObject(&current->Mutex,
@ -626,37 +625,38 @@ CcRosCreateCacheSegment (
NULL);
KeAcquireGuardedMutex(&ViewLock);
*CacheSeg = current;
/* There is window between the call to CcRosLookupCacheSegment
* and CcRosCreateCacheSegment. We must check if a segment on
* the fileoffset exist. If there exist a segment, we release
* our new created segment and return the existing one.
*Vacb = current;
/* There is window between the call to CcRosLookupVacb
* and CcRosCreateVacb. We must check if a VACB for the
* file offset exist. If there is a VACB, we release
* our newly created VACB and return the existing one.
*/
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
current_entry = Bcb->BcbSegmentListHead.Flink;
current_entry = Bcb->BcbVacbListHead.Flink;
previous = NULL;
while (current_entry != &Bcb->BcbSegmentListHead)
while (current_entry != &Bcb->BcbVacbListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
if (IsPointInSegment(current->FileOffset, VACB_MAPPING_GRANULARITY,
FileOffset))
current = CONTAINING_RECORD(current_entry,
ROS_VACB,
BcbVacbListEntry);
if (IsPointInRange(current->FileOffset, VACB_MAPPING_GRANULARITY,
FileOffset))
{
CcRosCacheSegmentIncRefCount(current);
CcRosVacbIncRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
#if DBG
if ( Bcb->Trace )
{
DPRINT1("CacheMap 0x%p: deleting newly created Cache Segment 0x%p ( found existing one 0x%p )\n",
DPRINT1("CacheMap 0x%p: deleting newly created VACB 0x%p ( found existing one 0x%p )\n",
Bcb,
(*CacheSeg),
(*Vacb),
current );
}
#endif
KeReleaseMutex(&(*CacheSeg)->Mutex, FALSE);
KeReleaseMutex(&(*Vacb)->Mutex, FALSE);
KeReleaseGuardedMutex(&ViewLock);
ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg);
*CacheSeg = current;
ExFreeToNPagedLookasideList(&VacbLookasideList, *Vacb);
*Vacb = current;
KeWaitForSingleObject(&current->Mutex,
Executive,
KernelMode,
@ -674,25 +674,25 @@ CcRosCreateCacheSegment (
break;
current_entry = current_entry->Flink;
}
/* There was no existing segment. */
current = *CacheSeg;
/* There was no existing VACB. */
current = *Vacb;
if (previous)
{
InsertHeadList(&previous->BcbSegmentListEntry, &current->BcbSegmentListEntry);
InsertHeadList(&previous->BcbVacbListEntry, &current->BcbVacbListEntry);
}
else
{
InsertHeadList(&Bcb->BcbSegmentListHead, &current->BcbSegmentListEntry);
InsertHeadList(&Bcb->BcbVacbListHead, &current->BcbVacbListEntry);
}
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
InsertTailList(&CacheSegmentListHead, &current->CacheSegmentListEntry);
InsertTailList(&CacheSegmentLRUListHead, &current->CacheSegmentLRUListEntry);
InsertTailList(&VacbListHead, &current->VacbListEntry);
InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
KeReleaseGuardedMutex(&ViewLock);
MmLockAddressSpace(MmGetKernelAddressSpace());
current->BaseAddress = NULL;
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
0, // nothing checks for cache_segment mareas, so set to 0
0, // nothing checks for VACB mareas, so set to 0
&current->BaseAddress,
VACB_MAPPING_GRANULARITY,
PAGE_READWRITE,
@ -727,49 +727,49 @@ CcRosCreateCacheSegment (
NTSTATUS
NTAPI
CcRosGetCacheSegmentChain (
CcRosGetVacbChain (
PBCB Bcb,
ULONG FileOffset,
ULONG Length,
PCACHE_SEGMENT* CacheSeg)
PROS_VACB *Vacb)
{
PCACHE_SEGMENT current;
PROS_VACB current;
ULONG i;
PCACHE_SEGMENT* CacheSegList;
PCACHE_SEGMENT Previous = NULL;
PROS_VACB *VacbList;
PROS_VACB Previous = NULL;
ASSERT(Bcb);
DPRINT("CcRosGetCacheSegmentChain()\n");
DPRINT("CcRosGetVacbChain()\n");
Length = ROUND_UP(Length, VACB_MAPPING_GRANULARITY);
CacheSegList = _alloca(sizeof(PCACHE_SEGMENT) *
(Length / VACB_MAPPING_GRANULARITY));
VacbList = _alloca(sizeof(PROS_VACB) *
(Length / VACB_MAPPING_GRANULARITY));
/*
* Look for a cache segment already mapping the same data.
* 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 = CcRosLookupCacheSegment(Bcb, CurrentOffset);
current = CcRosLookupVacb(Bcb, CurrentOffset);
if (current != NULL)
{
KeAcquireGuardedMutex(&ViewLock);
/* Move to tail of LRU list */
RemoveEntryList(&current->CacheSegmentLRUListEntry);
InsertTailList(&CacheSegmentLRUListHead, &current->CacheSegmentLRUListEntry);
RemoveEntryList(&current->VacbLruListEntry);
InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
KeReleaseGuardedMutex(&ViewLock);
CacheSegList[i] = current;
VacbList[i] = current;
}
else
{
CcRosCreateCacheSegment(Bcb, CurrentOffset, &current);
CacheSegList[i] = current;
CcRosCreateVacb(Bcb, CurrentOffset, &current);
VacbList[i] = current;
}
}
@ -777,13 +777,13 @@ CcRosGetCacheSegmentChain (
{
if (i == 0)
{
*CacheSeg = CacheSegList[i];
Previous = CacheSegList[i];
*Vacb = VacbList[i];
Previous = VacbList[i];
}
else
{
Previous->NextInChain = CacheSegList[i];
Previous = CacheSegList[i];
Previous->NextInChain = VacbList[i];
Previous = VacbList[i];
}
}
ASSERT(Previous);
@ -794,31 +794,31 @@ CcRosGetCacheSegmentChain (
NTSTATUS
NTAPI
CcRosGetCacheSegment (
CcRosGetVacb (
PBCB Bcb,
ULONG FileOffset,
PULONG BaseOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
PCACHE_SEGMENT* CacheSeg)
PROS_VACB *Vacb)
{
PCACHE_SEGMENT current;
PROS_VACB current;
NTSTATUS Status;
ASSERT(Bcb);
DPRINT("CcRosGetCacheSegment()\n");
DPRINT("CcRosGetVacb()\n");
/*
* Look for a cache segment already mapping the same data.
* Look for a VACB already mapping the same data.
*/
current = CcRosLookupCacheSegment(Bcb, FileOffset);
current = CcRosLookupVacb(Bcb, FileOffset);
if (current == NULL)
{
/*
* Otherwise create a new segment.
* Otherwise create a new VACB.
*/
Status = CcRosCreateCacheSegment(Bcb, FileOffset, &current);
Status = CcRosCreateVacb(Bcb, FileOffset, &current);
if (!NT_SUCCESS(Status))
{
return Status;
@ -828,30 +828,30 @@ CcRosGetCacheSegment (
KeAcquireGuardedMutex(&ViewLock);
/* Move to the tail of the LRU list */
RemoveEntryList(&current->CacheSegmentLRUListEntry);
InsertTailList(&CacheSegmentLRUListHead, &current->CacheSegmentLRUListEntry);
RemoveEntryList(&current->VacbLruListEntry);
InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
KeReleaseGuardedMutex(&ViewLock);
/*
* Return information about the segment to the caller.
* Return information about the VACB to the caller.
*/
*UptoDate = current->Valid;
*BaseAddress = current->BaseAddress;
DPRINT("*BaseAddress %p\n", *BaseAddress);
*CacheSeg = current;
*Vacb = current;
*BaseOffset = current->FileOffset;
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
CcRosRequestCacheSegment (
CcRosRequestVacb (
PBCB Bcb,
ULONG FileOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
PCACHE_SEGMENT* CacheSeg)
PROS_VACB *Vacb)
/*
* FUNCTION: Request a page mapping for a BCB
*/
@ -867,12 +867,12 @@ CcRosRequestCacheSegment (
KeBugCheck(CACHE_MANAGER);
}
return CcRosGetCacheSegment(Bcb,
FileOffset,
&BaseOffset,
BaseAddress,
UptoDate,
CacheSeg);
return CcRosGetVacb(Bcb,
FileOffset,
&BaseOffset,
BaseAddress,
UptoDate,
Vacb);
}
static
@ -894,28 +894,28 @@ CcFreeCachePage (
}
NTSTATUS
CcRosInternalFreeCacheSegment (
PCACHE_SEGMENT CacheSeg)
CcRosInternalFreeVacb (
PROS_VACB Vacb)
/*
* FUNCTION: Releases a cache segment associated with a BCB
* FUNCTION: Releases a VACB associated with a BCB
*/
{
DPRINT("Freeing cache segment 0x%p\n", CacheSeg);
DPRINT("Freeing VACB 0x%p\n", Vacb);
#if DBG
if ( CacheSeg->Bcb->Trace )
if (Vacb->Bcb->Trace)
{
DPRINT1("CacheMap 0x%p: deleting Cache Segment: 0x%p\n", CacheSeg->Bcb, CacheSeg );
DPRINT1("CacheMap 0x%p: deleting VACB: 0x%p\n", Vacb->Bcb, Vacb);
}
#endif
MmLockAddressSpace(MmGetKernelAddressSpace());
MmFreeMemoryArea(MmGetKernelAddressSpace(),
CacheSeg->MemoryArea,
Vacb->MemoryArea,
CcFreeCachePage,
NULL);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
ExFreeToNPagedLookasideList(&CacheSegLookasideList, CacheSeg);
ExFreeToNPagedLookasideList(&VacbLookasideList, Vacb);
return STATUS_SUCCESS;
}
@ -932,7 +932,7 @@ CcFlushCache (
{
PBCB Bcb;
LARGE_INTEGER Offset;
PCACHE_SEGMENT current;
PROS_VACB current;
NTSTATUS Status;
KIRQL oldIrql;
@ -961,12 +961,12 @@ CcFlushCache (
while (Length > 0)
{
current = CcRosLookupCacheSegment (Bcb, Offset.u.LowPart);
current = CcRosLookupVacb(Bcb, Offset.u.LowPart);
if (current != NULL)
{
if (current->Dirty)
{
Status = CcRosFlushCacheSegment(current);
Status = CcRosFlushVacb(current);
if (!NT_SUCCESS(Status) && IoStatus != NULL)
{
IoStatus->Status = Status;
@ -976,7 +976,7 @@ CcFlushCache (
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
CcRosCacheSegmentDecRefCount(current);
CcRosVacbDecRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
KeReleaseGuardedMutex(&ViewLock);
}
@ -1011,7 +1011,7 @@ CcRosDeleteFileCache (
*/
{
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
PROS_VACB current;
LIST_ENTRY FreeList;
KIRQL oldIrql;
@ -1035,23 +1035,23 @@ CcRosDeleteFileCache (
FileObject->SectionObjectPointer->SharedCacheMap = NULL;
/*
* Release all cache segments.
* Release all VACBs
*/
InitializeListHead(&FreeList);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
while (!IsListEmpty(&Bcb->BcbSegmentListHead))
while (!IsListEmpty(&Bcb->BcbVacbListHead))
{
current_entry = RemoveTailList(&Bcb->BcbSegmentListHead);
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
RemoveEntryList(&current->CacheSegmentListEntry);
RemoveEntryList(&current->CacheSegmentLRUListEntry);
current_entry = RemoveTailList(&Bcb->BcbVacbListHead);
current = CONTAINING_RECORD(current_entry, ROS_VACB, BcbVacbListEntry);
RemoveEntryList(&current->VacbListEntry);
RemoveEntryList(&current->VacbLruListEntry);
if (current->Dirty)
{
RemoveEntryList(&current->DirtySegmentListEntry);
RemoveEntryList(&current->DirtyVacbListEntry);
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
DPRINT1("Freeing dirty segment\n");
DPRINT1("Freeing dirty VACB\n");
}
InsertHeadList(&FreeList, &current->BcbSegmentListEntry);
InsertHeadList(&FreeList, &current->BcbVacbListEntry);
}
#if DBG
Bcb->Trace = FALSE;
@ -1064,8 +1064,8 @@ CcRosDeleteFileCache (
while (!IsListEmpty(&FreeList))
{
current_entry = RemoveTailList(&FreeList);
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
CcRosInternalFreeCacheSegment(current);
current = CONTAINING_RECORD(current_entry, ROS_VACB, BcbVacbListEntry);
CcRosInternalFreeVacb(current);
}
ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
KeAcquireGuardedMutex(&ViewLock);
@ -1250,7 +1250,7 @@ CcRosInitializeFileCache (
((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize;
}
KeInitializeSpinLock(&Bcb->BcbLock);
InitializeListHead(&Bcb->BcbSegmentListHead);
InitializeListHead(&Bcb->BcbVacbListHead);
FileObject->SectionObjectPointer->SharedCacheMap = Bcb;
}
if (FileObject->PrivateCacheMap == NULL)
@ -1294,9 +1294,9 @@ CcInitView (
{
DPRINT("CcInitView()\n");
InitializeListHead(&CacheSegmentListHead);
InitializeListHead(&DirtySegmentListHead);
InitializeListHead(&CacheSegmentLRUListHead);
InitializeListHead(&VacbListHead);
InitializeListHead(&DirtyVacbListHead);
InitializeListHead(&VacbLruListHead);
InitializeListHead(&ClosedListHead);
KeInitializeGuardedMutex(&ViewLock);
ExInitializeNPagedLookasideList (&iBcbLookasideList,
@ -1313,11 +1313,11 @@ CcInitView (
sizeof(BCB),
TAG_BCB,
20);
ExInitializeNPagedLookasideList (&CacheSegLookasideList,
ExInitializeNPagedLookasideList (&VacbLookasideList,
NULL,
NULL,
0,
sizeof(CACHE_SEGMENT),
sizeof(ROS_VACB),
TAG_CSEG,
20);

View file

@ -103,7 +103,7 @@ typedef struct _PFSN_PREFETCHER_GLOBALS
typedef struct _BCB
{
LIST_ENTRY BcbSegmentListHead;
LIST_ENTRY BcbVacbListHead;
LIST_ENTRY BcbRemoveListEntry;
BOOLEAN RemoveOnClose;
ULONG TimeStamp;
@ -115,49 +115,46 @@ typedef struct _BCB
KSPIN_LOCK BcbLock;
ULONG RefCount;
#if DBG
BOOLEAN Trace; /* enable extra trace output for this BCB and it's cache segments */
BOOLEAN Trace; /* enable extra trace output for this BCB and it's VACBs */
#endif
} BCB, *PBCB;
typedef struct _CACHE_SEGMENT
typedef struct _ROS_VACB
{
/* Base address of the region where the cache segment data is mapped. */
/* Base address of the region where the view's data is mapped. */
PVOID BaseAddress;
/*
* Memory area representing the region where the cache segment data is
* mapped.
*/
/* Memory area representing the region where the view's data is mapped. */
struct _MEMORY_AREA* MemoryArea;
/* Are the contents of the cache segment data valid. */
/* Are the contents of the view valid. */
BOOLEAN Valid;
/* Are the contents of the cache segment data newer than those on disk. */
/* Are the contents of the view newer than those on disk. */
BOOLEAN Dirty;
/* Page out in progress */
BOOLEAN PageOut;
ULONG MappedCount;
/* Entry in the list of segments for this BCB. */
LIST_ENTRY BcbSegmentListEntry;
/* Entry in the list of segments which are dirty. */
LIST_ENTRY DirtySegmentListEntry;
/* Entry in the list of segments. */
LIST_ENTRY CacheSegmentListEntry;
LIST_ENTRY CacheSegmentLRUListEntry;
/* Offset in the file which this cache segment maps. */
/* Entry in the list of VACBs for this BCB. */
LIST_ENTRY BcbVacbListEntry;
/* Entry in the list of VACBs which are dirty. */
LIST_ENTRY DirtyVacbListEntry;
/* Entry in the list of VACBs. */
LIST_ENTRY VacbListEntry;
LIST_ENTRY VacbLruListEntry;
/* Offset in the file which this view maps. */
ULONG FileOffset;
/* Mutex */
KMUTEX Mutex;
/* Number of references. */
ULONG ReferenceCount;
/* Pointer to the BCB for the file which this cache segment maps data for. */
/* Pointer to the BCB for the file which this view maps data for. */
PBCB Bcb;
/* Pointer to the next cache segment in a chain. */
struct _CACHE_SEGMENT* NextInChain;
} CACHE_SEGMENT, *PCACHE_SEGMENT;
/* Pointer to the next VACB in a chain. */
struct _ROS_VACB *NextInChain;
} ROS_VACB, *PROS_VACB;
typedef struct _INTERNAL_BCB
{
PUBLIC_BCB PFCB;
PCACHE_SEGMENT CacheSegment;
PROS_VACB Vacb;
BOOLEAN Dirty;
CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
} INTERNAL_BCB, *PINTERNAL_BCB;
@ -185,17 +182,17 @@ CcMdlWriteComplete2(
NTSTATUS
NTAPI
CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment);
CcRosFlushVacb(PROS_VACB Vacb);
NTSTATUS
NTAPI
CcRosGetCacheSegment(
CcRosGetVacb(
PBCB Bcb,
ULONG FileOffset,
PULONG BaseOffset,
PVOID *BaseAddress,
PBOOLEAN UptoDate,
PCACHE_SEGMENT *CacheSeg
PROS_VACB *Vacb
);
VOID
@ -204,11 +201,11 @@ CcInitView(VOID);
NTSTATUS
NTAPI
ReadCacheSegment(PCACHE_SEGMENT CacheSeg);
CcReadVirtualAddress(PROS_VACB Vacb);
NTSTATUS
NTAPI
WriteCacheSegment(PCACHE_SEGMENT CacheSeg);
CcWriteVirtualAddress(PROS_VACB Vacb);
BOOLEAN
NTAPI
@ -216,26 +213,26 @@ CcInitializeCacheManager(VOID);
NTSTATUS
NTAPI
CcRosUnmapCacheSegment(
CcRosUnmapVacb(
PBCB Bcb,
ULONG FileOffset,
BOOLEAN NowDirty
);
PCACHE_SEGMENT
PROS_VACB
NTAPI
CcRosLookupCacheSegment(
CcRosLookupVacb(
PBCB Bcb,
ULONG FileOffset
);
NTSTATUS
NTAPI
CcRosGetCacheSegmentChain(
CcRosGetVacbChain(
PBCB Bcb,
ULONG FileOffset,
ULONG Length,
PCACHE_SEGMENT* CacheSeg
PROS_VACB *Vacb
);
VOID
@ -244,7 +241,7 @@ CcInitCacheZeroPage(VOID);
NTSTATUS
NTAPI
CcRosMarkDirtyCacheSegment(
CcRosMarkDirtyVacb(
PBCB Bcb,
ULONG FileOffset
);
@ -271,9 +268,9 @@ CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer);
NTSTATUS
NTAPI
CcRosReleaseCacheSegment(
CcRosReleaseVacb(
BCB* Bcb,
CACHE_SEGMENT *CacheSeg,
PROS_VACB Vacb,
BOOLEAN Valid,
BOOLEAN Dirty,
BOOLEAN Mapped
@ -281,12 +278,12 @@ CcRosReleaseCacheSegment(
NTSTATUS
NTAPI
CcRosRequestCacheSegment(
CcRosRequestVacb(
BCB *Bcb,
ULONG FileOffset,
PVOID* BaseAddress,
PBOOLEAN UptoDate,
CACHE_SEGMENT **CacheSeg
PROS_VACB *Vacb
);
NTSTATUS
@ -309,7 +306,7 @@ CcTryToInitializeFileCache(PFILE_OBJECT FileObject);
FORCEINLINE
BOOLEAN
DoSegmentsIntersect(
DoRangesIntersect(
_In_ ULONG Offset1,
_In_ ULONG Length1,
_In_ ULONG Offset2,
@ -324,10 +321,10 @@ DoSegmentsIntersect(
FORCEINLINE
BOOLEAN
IsPointInSegment(
IsPointInRange(
_In_ ULONG Offset1,
_In_ ULONG Length1,
_In_ ULONG Point)
{
return DoSegmentsIntersect(Offset1, Length1, Point, 1);
return DoRangesIntersect(Offset1, Length1, Point, 1);
}

View file

@ -921,13 +921,13 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
IsDirectMapped = TRUE;
#ifndef NEWCC
Status = CcRosUnmapCacheSegment(Bcb, FileOffset.LowPart, Dirty);
Status = CcRosUnmapVacb(Bcb, FileOffset.LowPart, Dirty);
#else
Status = STATUS_SUCCESS;
#endif
if (!NT_SUCCESS(Status))
{
DPRINT1("CcRosUnmapCacheSegment failed, status = %x\n", Status);
DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status);
KeBugCheck(MEMORY_MANAGEMENT);
}
}
@ -1016,12 +1016,12 @@ BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
if (!(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
{
PBCB Bcb;
PCACHE_SEGMENT CacheSeg;
PROS_VACB Vacb;
Bcb = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap;
CacheSeg = CcRosLookupCacheSegment(Bcb, (ULONG)(SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset));
if (CacheSeg)
Vacb = CcRosLookupVacb(Bcb, (ULONG)(SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset));
if (Vacb)
{
CcRosReleaseCacheSegment(Bcb, CacheSeg, CacheSeg->Valid, FALSE, TRUE);
CcRosReleaseVacb(Bcb, Vacb, Vacb->Valid, FALSE, TRUE);
return TRUE;
}
}
@ -1070,7 +1070,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
ULONGLONG FileOffset;
PVOID BaseAddress;
BOOLEAN UptoDate;
PCACHE_SEGMENT CacheSeg;
PROS_VACB Vacb;
PFILE_OBJECT FileObject;
NTSTATUS Status;
ULONG_PTR RawLength;
@ -1091,7 +1091,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
/*
* If the file system is letting us go directly to the cache and the
* memory area was mapped at an offset in the file which is page aligned
* then get the related cache segment.
* then get the related VACB.
*/
if (((FileOffset % PAGE_SIZE) == 0) &&
((SegOffset + PAGE_SIZE <= RawLength) || !IsImageSection) &&
@ -1099,16 +1099,16 @@ MiReadPage(PMEMORY_AREA MemoryArea,
{
/*
* Get the related cache segment; we use a lower level interface than
* filesystems do because it is safe for us to use an offset with a
* Get the related VACB; we use a lower level interface than
* filesystems do because it is safe for us to use an offset with an
* alignment less than the file system block size.
*/
Status = CcRosGetCacheSegment(Bcb,
(ULONG)FileOffset,
&BaseOffset,
&BaseAddress,
&UptoDate,
&CacheSeg);
Status = CcRosGetVacb(Bcb,
(ULONG)FileOffset,
&BaseOffset,
&BaseAddress,
&UptoDate,
&Vacb);
if (!NT_SUCCESS(Status))
{
return(Status);
@ -1116,13 +1116,13 @@ MiReadPage(PMEMORY_AREA MemoryArea,
if (!UptoDate)
{
/*
* If the cache segment isn't up to date then call the file
* If the VACB isn't up to date then call the file
* system to read in the data.
*/
Status = ReadCacheSegment(CacheSeg);
Status = CcReadVirtualAddress(Vacb);
if (!NT_SUCCESS(Status))
{
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
return Status;
}
}
@ -1131,19 +1131,19 @@ MiReadPage(PMEMORY_AREA MemoryArea,
(void)*((volatile char*)BaseAddress + FileOffset - BaseOffset);
/*
* Retrieve the page from the cache segment that we actually want.
* Retrieve the page from the view that we actually want.
*/
(*Page) = MmGetPhysicalAddress((char*)BaseAddress +
FileOffset - BaseOffset).LowPart >> PAGE_SHIFT;
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, TRUE);
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, TRUE);
}
else
{
PEPROCESS Process;
KIRQL Irql;
PVOID PageAddr;
ULONG_PTR CacheSegOffset;
ULONG_PTR VacbOffset;
/*
* Allocate a page, this is rather complicated by the possibility
@ -1156,12 +1156,12 @@ MiReadPage(PMEMORY_AREA MemoryArea,
{
return(Status);
}
Status = CcRosGetCacheSegment(Bcb,
(ULONG)FileOffset,
&BaseOffset,
&BaseAddress,
&UptoDate,
&CacheSeg);
Status = CcRosGetVacb(Bcb,
(ULONG)FileOffset,
&BaseOffset,
&BaseAddress,
&UptoDate,
&Vacb);
if (!NT_SUCCESS(Status))
{
return(Status);
@ -1169,40 +1169,40 @@ MiReadPage(PMEMORY_AREA MemoryArea,
if (!UptoDate)
{
/*
* If the cache segment isn't up to date then call the file
* If the VACB isn't up to date then call the file
* system to read in the data.
*/
Status = ReadCacheSegment(CacheSeg);
Status = CcReadVirtualAddress(Vacb);
if (!NT_SUCCESS(Status))
{
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
return Status;
}
}
Process = PsGetCurrentProcess();
PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
CacheSegOffset = (ULONG_PTR)(BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset);
VacbOffset = (ULONG_PTR)(BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset);
Length = RawLength - SegOffset;
if (Length <= CacheSegOffset && Length <= PAGE_SIZE)
if (Length <= VacbOffset && Length <= PAGE_SIZE)
{
memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, Length);
}
else if (CacheSegOffset >= PAGE_SIZE)
else if (VacbOffset >= PAGE_SIZE)
{
memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, PAGE_SIZE);
}
else
{
memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, CacheSegOffset);
memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, VacbOffset);
MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
Status = CcRosGetCacheSegment(Bcb,
(ULONG)(FileOffset + CacheSegOffset),
&BaseOffset,
&BaseAddress,
&UptoDate,
&CacheSeg);
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
Status = CcRosGetVacb(Bcb,
(ULONG)(FileOffset + VacbOffset),
&BaseOffset,
&BaseAddress,
&UptoDate,
&Vacb);
if (!NT_SUCCESS(Status))
{
return(Status);
@ -1210,28 +1210,28 @@ MiReadPage(PMEMORY_AREA MemoryArea,
if (!UptoDate)
{
/*
* If the cache segment isn't up to date then call the file
* If the VACB isn't up to date then call the file
* system to read in the data.
*/
Status = ReadCacheSegment(CacheSeg);
Status = CcReadVirtualAddress(Vacb);
if (!NT_SUCCESS(Status))
{
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
return Status;
}
}
PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
if (Length < PAGE_SIZE)
{
memcpy((char*)PageAddr + CacheSegOffset, BaseAddress, Length - CacheSegOffset);
memcpy((char*)PageAddr + VacbOffset, BaseAddress, Length - VacbOffset);
}
else
{
memcpy((char*)PageAddr + CacheSegOffset, BaseAddress, PAGE_SIZE - CacheSegOffset);
memcpy((char*)PageAddr + VacbOffset, BaseAddress, PAGE_SIZE - VacbOffset);
}
}
MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
}
return(STATUS_SUCCESS);
}
@ -1970,7 +1970,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
}
/*
* Take an additional reference to the page or the cache segment.
* Take an additional reference to the page or the VACB.
*/
if (DirectMapped && !Context.Private)
{
@ -2066,14 +2066,14 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
KeBugCheckEx(MEMORY_MANAGEMENT, STATUS_UNSUCCESSFUL, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address);
}
#ifndef NEWCC
Status = CcRosUnmapCacheSegment(Bcb, (ULONG)FileOffset, FALSE);
Status = CcRosUnmapVacb(Bcb, (ULONG)FileOffset, FALSE);
#else
Status = STATUS_SUCCESS;
#endif
#ifndef NEWCC
if (!NT_SUCCESS(Status))
{
DPRINT1("CCRosUnmapCacheSegment failed, status = %x\n", Status);
DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status);
KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Bcb, (ULONG_PTR)FileOffset, (ULONG_PTR)Address);
}
#endif
@ -2366,7 +2366,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
ASSERT(SwapEntry == 0);
//SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset;
#ifndef NEWCC
CcRosMarkDirtyCacheSegment(Bcb, Offset.LowPart);
CcRosMarkDirtyVacb(Bcb, Offset.LowPart);
#endif
MmLockSectionSegment(Segment);
MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry);
@ -4013,7 +4013,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
#ifndef NEWCC
CcRosMarkDirtyCacheSegment(Bcb, (ULONG)(Offset.QuadPart + Segment->Image.FileOffset));
CcRosMarkDirtyVacb(Bcb, (ULONG)(Offset.QuadPart + Segment->Image.FileOffset));
#endif
ASSERT(SwapEntry == 0);
}