mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[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:
parent
435846f00f
commit
20cff61d07
6 changed files with 450 additions and 452 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(¤t->BcbSegmentListEntry);
|
||||
RemoveEntryList(¤t->CacheSegmentListEntry);
|
||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
||||
RemoveEntryList(¤t->BcbVacbListEntry);
|
||||
RemoveEntryList(¤t->VacbListEntry);
|
||||
RemoveEntryList(¤t->VacbLruListEntry);
|
||||
if (current->Dirty)
|
||||
{
|
||||
RemoveEntryList(¤t->DirtySegmentListEntry);
|
||||
RemoveEntryList(¤t->DirtyVacbListEntry);
|
||||
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||
}
|
||||
InsertHeadList(&FreeListHead, ¤t->BcbSegmentListEntry);
|
||||
InsertHeadList(&FreeListHead, ¤t->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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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(¤t->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(¤t->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(¤t->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(¤t->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(¤t->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(¤t->BcbSegmentListEntry);
|
||||
RemoveEntryList(¤t->CacheSegmentListEntry);
|
||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
||||
InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry);
|
||||
RemoveEntryList(¤t->BcbVacbListEntry);
|
||||
RemoveEntryList(¤t->VacbListEntry);
|
||||
RemoveEntryList(¤t->VacbLruListEntry);
|
||||
InsertHeadList(&FreeList, ¤t->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(¤t->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(¤t->Mutex, 0);
|
||||
KeWaitForSingleObject(¤t->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(¤t->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, ¤t->BcbSegmentListEntry);
|
||||
InsertHeadList(&previous->BcbVacbListEntry, ¤t->BcbVacbListEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertHeadList(&Bcb->BcbSegmentListHead, ¤t->BcbSegmentListEntry);
|
||||
InsertHeadList(&Bcb->BcbVacbListHead, ¤t->BcbVacbListEntry);
|
||||
}
|
||||
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
||||
InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry);
|
||||
InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry);
|
||||
InsertTailList(&VacbListHead, ¤t->VacbListEntry);
|
||||
InsertTailList(&VacbLruListHead, ¤t->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
|
||||
¤t->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(¤t->CacheSegmentLRUListEntry);
|
||||
InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry);
|
||||
RemoveEntryList(¤t->VacbLruListEntry);
|
||||
InsertTailList(&VacbLruListHead, ¤t->VacbLruListEntry);
|
||||
|
||||
KeReleaseGuardedMutex(&ViewLock);
|
||||
|
||||
CacheSegList[i] = current;
|
||||
VacbList[i] = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
CcRosCreateCacheSegment(Bcb, CurrentOffset, ¤t);
|
||||
CacheSegList[i] = current;
|
||||
CcRosCreateVacb(Bcb, CurrentOffset, ¤t);
|
||||
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, ¤t);
|
||||
Status = CcRosCreateVacb(Bcb, FileOffset, ¤t);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
|
@ -828,30 +828,30 @@ CcRosGetCacheSegment (
|
|||
KeAcquireGuardedMutex(&ViewLock);
|
||||
|
||||
/* Move to the tail of the LRU list */
|
||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
||||
InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry);
|
||||
RemoveEntryList(¤t->VacbLruListEntry);
|
||||
InsertTailList(&VacbLruListHead, ¤t->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(¤t->CacheSegmentListEntry);
|
||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
||||
current_entry = RemoveTailList(&Bcb->BcbVacbListHead);
|
||||
current = CONTAINING_RECORD(current_entry, ROS_VACB, BcbVacbListEntry);
|
||||
RemoveEntryList(¤t->VacbListEntry);
|
||||
RemoveEntryList(¤t->VacbLruListEntry);
|
||||
if (current->Dirty)
|
||||
{
|
||||
RemoveEntryList(¤t->DirtySegmentListEntry);
|
||||
RemoveEntryList(¤t->DirtyVacbListEntry);
|
||||
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||
DPRINT1("Freeing dirty segment\n");
|
||||
DPRINT1("Freeing dirty VACB\n");
|
||||
}
|
||||
InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry);
|
||||
InsertHeadList(&FreeList, ¤t->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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue