mirror of
https://github.com/reactos/reactos.git
synced 2025-05-11 13:27:47 +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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ReadCacheSegmentChain (
|
ReadVacbChain (
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG ReadOffset,
|
ULONG ReadOffset,
|
||||||
ULONG Length,
|
ULONG Length,
|
||||||
PVOID Buffer)
|
PVOID Buffer)
|
||||||
{
|
{
|
||||||
PCACHE_SEGMENT head;
|
PROS_VACB head;
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
PCACHE_SEGMENT previous;
|
PROS_VACB previous;
|
||||||
IO_STATUS_BLOCK Iosb;
|
IO_STATUS_BLOCK Iosb;
|
||||||
LARGE_INTEGER SegOffset;
|
LARGE_INTEGER VacbOffset;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG TempLength;
|
ULONG TempLength;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
|
@ -74,7 +74,7 @@ ReadCacheSegmentChain (
|
||||||
|
|
||||||
Mdl = _alloca(MmSizeOfMdl(NULL, MAX_RW_LENGTH));
|
Mdl = _alloca(MmSizeOfMdl(NULL, MAX_RW_LENGTH));
|
||||||
|
|
||||||
Status = CcRosGetCacheSegmentChain(Bcb, ReadOffset, Length, &head);
|
Status = CcRosGetVacbChain(Bcb, ReadOffset, Length, &head);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -83,8 +83,7 @@ ReadCacheSegmentChain (
|
||||||
while (current != NULL)
|
while (current != NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If the current segment is valid then copy it into the
|
* If the current VACB is valid then copy it into the user buffer.
|
||||||
* user buffer.
|
|
||||||
*/
|
*/
|
||||||
if (current->Valid)
|
if (current->Valid)
|
||||||
{
|
{
|
||||||
|
@ -96,21 +95,21 @@ ReadCacheSegmentChain (
|
||||||
Length = Length - TempLength;
|
Length = Length - TempLength;
|
||||||
previous = current;
|
previous = current;
|
||||||
current = current->NextInChain;
|
current = current->NextInChain;
|
||||||
CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, previous, TRUE, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Otherwise read in as much as we can.
|
* Otherwise read in as much as we can.
|
||||||
*/
|
*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PCACHE_SEGMENT current2;
|
PROS_VACB current2;
|
||||||
ULONG current_size;
|
ULONG current_size;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PPFN_NUMBER MdlPages;
|
PPFN_NUMBER MdlPages;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Count the maximum number of bytes we could read starting
|
* Count the maximum number of bytes we could read starting
|
||||||
* from the current segment.
|
* from the current VACB.
|
||||||
*/
|
*/
|
||||||
current2 = current;
|
current2 = current;
|
||||||
current_size = 0;
|
current_size = 0;
|
||||||
|
@ -142,11 +141,11 @@ ReadCacheSegmentChain (
|
||||||
/*
|
/*
|
||||||
* Read in the information.
|
* Read in the information.
|
||||||
*/
|
*/
|
||||||
SegOffset.QuadPart = current->FileOffset;
|
VacbOffset.QuadPart = current->FileOffset;
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
Status = IoPageRead(Bcb->FileObject,
|
Status = IoPageRead(Bcb->FileObject,
|
||||||
Mdl,
|
Mdl,
|
||||||
&SegOffset,
|
&VacbOffset,
|
||||||
&Event,
|
&Event,
|
||||||
&Iosb);
|
&Iosb);
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
|
@ -164,7 +163,7 @@ ReadCacheSegmentChain (
|
||||||
{
|
{
|
||||||
previous = current;
|
previous = current;
|
||||||
current = current->NextInChain;
|
current = current->NextInChain;
|
||||||
CcRosReleaseCacheSegment(Bcb, previous, FALSE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, previous, FALSE, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +178,7 @@ ReadCacheSegmentChain (
|
||||||
Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength);
|
Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength);
|
||||||
|
|
||||||
Length = Length - TempLength;
|
Length = Length - TempLength;
|
||||||
CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, previous, TRUE, FALSE, FALSE);
|
||||||
current_size += VACB_MAPPING_GRANULARITY;
|
current_size += VACB_MAPPING_GRANULARITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,24 +188,24 @@ ReadCacheSegmentChain (
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ReadCacheSegment (
|
CcReadVirtualAddress (
|
||||||
PCACHE_SEGMENT CacheSeg)
|
PROS_VACB Vacb)
|
||||||
{
|
{
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
LARGE_INTEGER SegOffset;
|
LARGE_INTEGER VacbOffset;
|
||||||
IO_STATUS_BLOCK IoStatus;
|
IO_STATUS_BLOCK IoStatus;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
|
|
||||||
SegOffset.QuadPart = CacheSeg->FileOffset;
|
VacbOffset.QuadPart = Vacb->FileOffset;
|
||||||
Size = (ULONG)(CacheSeg->Bcb->AllocationSize.QuadPart - CacheSeg->FileOffset);
|
Size = (ULONG)(Vacb->Bcb->AllocationSize.QuadPart - Vacb->FileOffset);
|
||||||
if (Size > VACB_MAPPING_GRANULARITY)
|
if (Size > VACB_MAPPING_GRANULARITY)
|
||||||
{
|
{
|
||||||
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)
|
if (!Mdl)
|
||||||
{
|
{
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
@ -215,7 +214,7 @@ ReadCacheSegment (
|
||||||
MmBuildMdlForNonPagedPool(Mdl);
|
MmBuildMdlForNonPagedPool(Mdl);
|
||||||
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
|
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
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)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
@ -232,7 +231,7 @@ ReadCacheSegment (
|
||||||
|
|
||||||
if (Size < VACB_MAPPING_GRANULARITY)
|
if (Size < VACB_MAPPING_GRANULARITY)
|
||||||
{
|
{
|
||||||
RtlZeroMemory((char*)CacheSeg->BaseAddress + Size,
|
RtlZeroMemory((char*)Vacb->BaseAddress + Size,
|
||||||
VACB_MAPPING_GRANULARITY - Size);
|
VACB_MAPPING_GRANULARITY - Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,19 +240,19 @@ ReadCacheSegment (
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
WriteCacheSegment (
|
CcWriteVirtualAddress (
|
||||||
PCACHE_SEGMENT CacheSeg)
|
PROS_VACB Vacb)
|
||||||
{
|
{
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
IO_STATUS_BLOCK IoStatus;
|
IO_STATUS_BLOCK IoStatus;
|
||||||
LARGE_INTEGER SegOffset;
|
LARGE_INTEGER VacbOffset;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
|
|
||||||
CacheSeg->Dirty = FALSE;
|
Vacb->Dirty = FALSE;
|
||||||
SegOffset.QuadPart = CacheSeg->FileOffset;
|
VacbOffset.QuadPart = Vacb->FileOffset;
|
||||||
Size = (ULONG)(CacheSeg->Bcb->AllocationSize.QuadPart - CacheSeg->FileOffset);
|
Size = (ULONG)(Vacb->Bcb->AllocationSize.QuadPart - Vacb->FileOffset);
|
||||||
if (Size > VACB_MAPPING_GRANULARITY)
|
if (Size > VACB_MAPPING_GRANULARITY)
|
||||||
{
|
{
|
||||||
Size = VACB_MAPPING_GRANULARITY;
|
Size = VACB_MAPPING_GRANULARITY;
|
||||||
|
@ -266,11 +265,11 @@ WriteCacheSegment (
|
||||||
ULONG i = 0;
|
ULONG i = 0;
|
||||||
do
|
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));
|
} while (++i < (Size >> PAGE_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
Mdl = IoAllocateMdl(CacheSeg->BaseAddress, Size, FALSE, FALSE, NULL);
|
Mdl = IoAllocateMdl(Vacb->BaseAddress, Size, FALSE, FALSE, NULL);
|
||||||
if (!Mdl)
|
if (!Mdl)
|
||||||
{
|
{
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
@ -278,7 +277,7 @@ WriteCacheSegment (
|
||||||
MmBuildMdlForNonPagedPool(Mdl);
|
MmBuildMdlForNonPagedPool(Mdl);
|
||||||
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
|
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
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)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
@ -288,7 +287,7 @@ WriteCacheSegment (
|
||||||
if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
|
if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
|
||||||
{
|
{
|
||||||
DPRINT1("IoPageWrite failed, Status %x\n", Status);
|
DPRINT1("IoPageWrite failed, Status %x\n", Status);
|
||||||
CacheSeg->Dirty = TRUE;
|
Vacb->Dirty = TRUE;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,13 +328,13 @@ CcCopyRead (
|
||||||
ULONG TempLength;
|
ULONG TempLength;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PROS_VACB Vacb;
|
||||||
BOOLEAN Valid;
|
BOOLEAN Valid;
|
||||||
ULONG ReadLength = 0;
|
ULONG ReadLength = 0;
|
||||||
PBCB Bcb;
|
PBCB Bcb;
|
||||||
KIRQL oldirql;
|
KIRQL oldirql;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
|
|
||||||
DPRINT("CcCopyRead(FileObject 0x%p, FileOffset %I64x, "
|
DPRINT("CcCopyRead(FileObject 0x%p, FileOffset %I64x, "
|
||||||
"Length %lu, Wait %u, Buffer 0x%p, IoStatus 0x%p)\n",
|
"Length %lu, Wait %u, Buffer 0x%p, IoStatus 0x%p)\n",
|
||||||
|
@ -350,21 +349,21 @@ CcCopyRead (
|
||||||
Bcb->FileSize.QuadPart);
|
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.
|
* cover this read are in memory.
|
||||||
*/
|
*/
|
||||||
if (!Wait)
|
if (!Wait)
|
||||||
{
|
{
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
||||||
/* FIXME: this loop doesn't take into account areas that don't have
|
/* FIXME: this loop doesn't take into account areas that don't have
|
||||||
* a segment in the list yet */
|
* a VACB in the list yet */
|
||||||
current_entry = Bcb->BcbSegmentListHead.Flink;
|
current_entry = Bcb->BcbVacbListHead.Flink;
|
||||||
while (current_entry != &Bcb->BcbSegmentListHead)
|
while (current_entry != &Bcb->BcbVacbListHead)
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
current = CONTAINING_RECORD(current_entry, ROS_VACB,
|
||||||
BcbSegmentListEntry);
|
BcbVacbListEntry);
|
||||||
if (!current->Valid &&
|
if (!current->Valid &&
|
||||||
DoSegmentsIntersect(current->FileOffset, VACB_MAPPING_GRANULARITY,
|
DoRangesIntersect(current->FileOffset, VACB_MAPPING_GRANULARITY,
|
||||||
ReadOffset, Length))
|
ReadOffset, Length))
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
||||||
|
@ -383,32 +382,32 @@ CcCopyRead (
|
||||||
if (TempLength != 0)
|
if (TempLength != 0)
|
||||||
{
|
{
|
||||||
TempLength = min(Length, VACB_MAPPING_GRANULARITY - TempLength);
|
TempLength = min(Length, VACB_MAPPING_GRANULARITY - TempLength);
|
||||||
Status = CcRosRequestCacheSegment(Bcb,
|
Status = CcRosRequestVacb(Bcb,
|
||||||
ROUND_DOWN(ReadOffset,
|
ROUND_DOWN(ReadOffset,
|
||||||
VACB_MAPPING_GRANULARITY),
|
VACB_MAPPING_GRANULARITY),
|
||||||
&BaseAddress, &Valid, &CacheSeg);
|
&BaseAddress, &Valid, &Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
IoStatus->Information = 0;
|
IoStatus->Information = 0;
|
||||||
IoStatus->Status = Status;
|
IoStatus->Status = Status;
|
||||||
DPRINT("CcRosRequestCacheSegment faild, Status %x\n", Status);
|
DPRINT("CcRosRequestVacb failed, Status %x\n", Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!Valid)
|
if (!Valid)
|
||||||
{
|
{
|
||||||
Status = ReadCacheSegment(CacheSeg);
|
Status = CcReadVirtualAddress(Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
IoStatus->Information = 0;
|
IoStatus->Information = 0;
|
||||||
IoStatus->Status = Status;
|
IoStatus->Status = Status;
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RtlCopyMemory(Buffer,
|
RtlCopyMemory(Buffer,
|
||||||
(char*)BaseAddress + ReadOffset % VACB_MAPPING_GRANULARITY,
|
(char*)BaseAddress + ReadOffset % VACB_MAPPING_GRANULARITY,
|
||||||
TempLength);
|
TempLength);
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
|
||||||
ReadLength += TempLength;
|
ReadLength += TempLength;
|
||||||
Length -= TempLength;
|
Length -= TempLength;
|
||||||
ReadOffset += TempLength;
|
ReadOffset += TempLength;
|
||||||
|
@ -418,12 +417,12 @@ CcCopyRead (
|
||||||
while (Length > 0)
|
while (Length > 0)
|
||||||
{
|
{
|
||||||
TempLength = min(VACB_MAPPING_GRANULARITY, Length);
|
TempLength = min(VACB_MAPPING_GRANULARITY, Length);
|
||||||
Status = ReadCacheSegmentChain(Bcb, ReadOffset, TempLength, Buffer);
|
Status = ReadVacbChain(Bcb, ReadOffset, TempLength, Buffer);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
IoStatus->Information = 0;
|
IoStatus->Information = 0;
|
||||||
IoStatus->Status = Status;
|
IoStatus->Status = Status;
|
||||||
DPRINT("ReadCacheSegmentChain failed, Status %x\n", Status);
|
DPRINT("ReadVacbChain failed, Status %x\n", Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +456,7 @@ CcCopyWrite (
|
||||||
KIRQL oldirql;
|
KIRQL oldirql;
|
||||||
PBCB Bcb;
|
PBCB Bcb;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PROS_VACB Vacb;
|
||||||
ULONG TempLength;
|
ULONG TempLength;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
BOOLEAN Valid;
|
BOOLEAN Valid;
|
||||||
|
@ -474,21 +473,22 @@ CcCopyWrite (
|
||||||
/* testing, if the requested datas are available */
|
/* testing, if the requested datas are available */
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
||||||
/* FIXME: this loop doesn't take into account areas that don't have
|
/* FIXME: this loop doesn't take into account areas that don't have
|
||||||
* a segment in the list yet */
|
* a VACB in the list yet */
|
||||||
current_entry = Bcb->BcbSegmentListHead.Flink;
|
current_entry = Bcb->BcbVacbListHead.Flink;
|
||||||
while (current_entry != &Bcb->BcbSegmentListHead)
|
while (current_entry != &Bcb->BcbVacbListHead)
|
||||||
{
|
{
|
||||||
CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
Vacb = CONTAINING_RECORD(current_entry,
|
||||||
BcbSegmentListEntry);
|
ROS_VACB,
|
||||||
if (!CacheSeg->Valid &&
|
BcbVacbListEntry);
|
||||||
DoSegmentsIntersect(CacheSeg->FileOffset, VACB_MAPPING_GRANULARITY,
|
if (!Vacb->Valid &&
|
||||||
|
DoRangesIntersect(Vacb->FileOffset, VACB_MAPPING_GRANULARITY,
|
||||||
WriteOffset, Length))
|
WriteOffset, Length))
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
||||||
/* datas not available */
|
/* datas not available */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (CacheSeg->FileOffset >= WriteOffset + Length)
|
if (Vacb->FileOffset >= WriteOffset + Length)
|
||||||
break;
|
break;
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
}
|
}
|
||||||
|
@ -501,15 +501,15 @@ CcCopyWrite (
|
||||||
ULONG ROffset;
|
ULONG ROffset;
|
||||||
ROffset = ROUND_DOWN(WriteOffset, VACB_MAPPING_GRANULARITY);
|
ROffset = ROUND_DOWN(WriteOffset, VACB_MAPPING_GRANULARITY);
|
||||||
TempLength = min(Length, VACB_MAPPING_GRANULARITY - TempLength);
|
TempLength = min(Length, VACB_MAPPING_GRANULARITY - TempLength);
|
||||||
Status = CcRosRequestCacheSegment(Bcb, ROffset,
|
Status = CcRosRequestVacb(Bcb, ROffset,
|
||||||
&BaseAddress, &Valid, &CacheSeg);
|
&BaseAddress, &Valid, &Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!Valid)
|
if (!Valid)
|
||||||
{
|
{
|
||||||
if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
|
if (!NT_SUCCESS(CcReadVirtualAddress(Vacb)))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -517,7 +517,7 @@ CcCopyWrite (
|
||||||
RtlCopyMemory((char*)BaseAddress + WriteOffset % VACB_MAPPING_GRANULARITY,
|
RtlCopyMemory((char*)BaseAddress + WriteOffset % VACB_MAPPING_GRANULARITY,
|
||||||
Buffer,
|
Buffer,
|
||||||
TempLength);
|
TempLength);
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, TRUE, TRUE, FALSE);
|
||||||
|
|
||||||
Length -= TempLength;
|
Length -= TempLength;
|
||||||
WriteOffset += TempLength;
|
WriteOffset += TempLength;
|
||||||
|
@ -528,25 +528,25 @@ CcCopyWrite (
|
||||||
while (Length > 0)
|
while (Length > 0)
|
||||||
{
|
{
|
||||||
TempLength = min(VACB_MAPPING_GRANULARITY, Length);
|
TempLength = min(VACB_MAPPING_GRANULARITY, Length);
|
||||||
Status = CcRosRequestCacheSegment(Bcb,
|
Status = CcRosRequestVacb(Bcb,
|
||||||
WriteOffset,
|
WriteOffset,
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&Valid,
|
&Valid,
|
||||||
&CacheSeg);
|
&Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!Valid && TempLength < VACB_MAPPING_GRANULARITY)
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RtlCopyMemory(BaseAddress, Buffer, TempLength);
|
RtlCopyMemory(BaseAddress, Buffer, TempLength);
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, TRUE, TRUE, FALSE);
|
||||||
Length -= TempLength;
|
Length -= TempLength;
|
||||||
WriteOffset += TempLength;
|
WriteOffset += TempLength;
|
||||||
|
|
||||||
|
@ -686,7 +686,7 @@ CcZeroData (
|
||||||
KIRQL oldirql;
|
KIRQL oldirql;
|
||||||
PBCB Bcb;
|
PBCB Bcb;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT CacheSeg, current, previous;
|
PROS_VACB Vacb, current, previous;
|
||||||
ULONG TempLength;
|
ULONG TempLength;
|
||||||
|
|
||||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
|
@ -695,21 +695,22 @@ CcZeroData (
|
||||||
/* testing, if the requested datas are available */
|
/* testing, if the requested datas are available */
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
||||||
/* FIXME: this loop doesn't take into account areas that don't have
|
/* FIXME: this loop doesn't take into account areas that don't have
|
||||||
* a segment in the list yet */
|
* a VACB in the list yet */
|
||||||
current_entry = Bcb->BcbSegmentListHead.Flink;
|
current_entry = Bcb->BcbVacbListHead.Flink;
|
||||||
while (current_entry != &Bcb->BcbSegmentListHead)
|
while (current_entry != &Bcb->BcbVacbListHead)
|
||||||
{
|
{
|
||||||
CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
Vacb = CONTAINING_RECORD(current_entry,
|
||||||
BcbSegmentListEntry);
|
ROS_VACB,
|
||||||
if (!CacheSeg->Valid &&
|
BcbVacbListEntry);
|
||||||
DoSegmentsIntersect(CacheSeg->FileOffset, VACB_MAPPING_GRANULARITY,
|
if (!Vacb->Valid &&
|
||||||
|
DoRangesIntersect(Vacb->FileOffset, VACB_MAPPING_GRANULARITY,
|
||||||
WriteOffset.u.LowPart, Length))
|
WriteOffset.u.LowPart, Length))
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
||||||
/* datas not available */
|
/* datas not available */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (CacheSeg->FileOffset >= WriteOffset.u.LowPart + Length)
|
if (Vacb->FileOffset >= WriteOffset.u.LowPart + Length)
|
||||||
break;
|
break;
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
}
|
}
|
||||||
|
@ -728,13 +729,13 @@ CcZeroData (
|
||||||
{
|
{
|
||||||
CurrentLength = Length;
|
CurrentLength = Length;
|
||||||
}
|
}
|
||||||
Status = CcRosGetCacheSegmentChain (Bcb, WriteOffset.u.LowPart - Offset,
|
Status = CcRosGetVacbChain(Bcb, WriteOffset.u.LowPart - Offset,
|
||||||
Offset + CurrentLength, &CacheSeg);
|
Offset + CurrentLength, &Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
current = CacheSeg;
|
current = Vacb;
|
||||||
|
|
||||||
while (current != NULL)
|
while (current != NULL)
|
||||||
{
|
{
|
||||||
|
@ -744,11 +745,11 @@ CcZeroData (
|
||||||
{
|
{
|
||||||
if (!current->Valid)
|
if (!current->Valid)
|
||||||
{
|
{
|
||||||
/* read the segment */
|
/* read the block */
|
||||||
Status = ReadCacheSegment(current);
|
Status = CcReadVirtualAddress(current);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("ReadCacheSegment failed, status %x\n",
|
DPRINT1("CcReadVirtualAddress failed, status %x\n",
|
||||||
Status);
|
Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -768,12 +769,12 @@ CcZeroData (
|
||||||
current = current->NextInChain;
|
current = current->NextInChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = CacheSeg;
|
current = Vacb;
|
||||||
while (current != NULL)
|
while (current != NULL)
|
||||||
{
|
{
|
||||||
previous = current;
|
previous = current;
|
||||||
current = current->NextInChain;
|
current = current->NextInChain;
|
||||||
CcRosReleaseCacheSegment(Bcb, previous, TRUE, TRUE, FALSE);
|
CcRosReleaseVacb(Bcb, previous, TRUE, TRUE, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
extern KGUARDED_MUTEX ViewLock;
|
extern KGUARDED_MUTEX ViewLock;
|
||||||
extern ULONG DirtyPageCount;
|
extern ULONG DirtyPageCount;
|
||||||
|
|
||||||
NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg);
|
NTSTATUS CcRosInternalFreeVacb(PROS_VACB Vacb);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ CcGetFileObjectFromBcb (
|
||||||
IN PVOID Bcb)
|
IN PVOID Bcb)
|
||||||
{
|
{
|
||||||
PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb;
|
PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb;
|
||||||
return iBcb->CacheSegment->Bcb->FileObject;
|
return iBcb->Vacb->Bcb->FileObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -130,7 +130,7 @@ CcSetFileSizes (
|
||||||
KIRQL oldirql;
|
KIRQL oldirql;
|
||||||
PBCB Bcb;
|
PBCB Bcb;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
LIST_ENTRY FreeListHead;
|
LIST_ENTRY FreeListHead;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -156,30 +156,30 @@ CcSetFileSizes (
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
||||||
|
|
||||||
current_entry = Bcb->BcbSegmentListHead.Flink;
|
current_entry = Bcb->BcbVacbListHead.Flink;
|
||||||
while (current_entry != &Bcb->BcbSegmentListHead)
|
while (current_entry != &Bcb->BcbVacbListHead)
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
CACHE_SEGMENT,
|
ROS_VACB,
|
||||||
BcbSegmentListEntry);
|
BcbVacbListEntry);
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
if (current->FileOffset >= FileSizes->AllocationSize.QuadPart)
|
if (current->FileOffset >= FileSizes->AllocationSize.QuadPart)
|
||||||
{
|
{
|
||||||
if ((current->ReferenceCount == 0) || ((current->ReferenceCount == 1) && current->Dirty))
|
if ((current->ReferenceCount == 0) || ((current->ReferenceCount == 1) && current->Dirty))
|
||||||
{
|
{
|
||||||
RemoveEntryList(¤t->BcbSegmentListEntry);
|
RemoveEntryList(¤t->BcbVacbListEntry);
|
||||||
RemoveEntryList(¤t->CacheSegmentListEntry);
|
RemoveEntryList(¤t->VacbListEntry);
|
||||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
RemoveEntryList(¤t->VacbLruListEntry);
|
||||||
if (current->Dirty)
|
if (current->Dirty)
|
||||||
{
|
{
|
||||||
RemoveEntryList(¤t->DirtySegmentListEntry);
|
RemoveEntryList(¤t->DirtyVacbListEntry);
|
||||||
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
}
|
}
|
||||||
InsertHeadList(&FreeListHead, ¤t->BcbSegmentListEntry);
|
InsertHeadList(&FreeListHead, ¤t->BcbVacbListEntry);
|
||||||
}
|
}
|
||||||
else
|
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);
|
KeBugCheck(CACHE_MANAGER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,12 +193,12 @@ CcSetFileSizes (
|
||||||
current_entry = FreeListHead.Flink;
|
current_entry = FreeListHead.Flink;
|
||||||
while(current_entry != &FreeListHead)
|
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;
|
current_entry = current_entry->Flink;
|
||||||
Status = CcRosInternalFreeCacheSegment(current);
|
Status = CcRosInternalFreeVacb(current);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("CcRosInternalFreeCacheSegment failed, status = %x\n", Status);
|
DPRINT1("CcRosInternalFreeVacb failed, status = %x\n", Status);
|
||||||
KeBugCheck(CACHE_MANAGER);
|
KeBugCheck(CACHE_MANAGER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ CcMapData (
|
||||||
ULONG ReadOffset;
|
ULONG ReadOffset;
|
||||||
BOOLEAN Valid;
|
BOOLEAN Valid;
|
||||||
PBCB Bcb;
|
PBCB Bcb;
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PROS_VACB Vacb;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PINTERNAL_BCB iBcb;
|
PINTERNAL_BCB iBcb;
|
||||||
ULONG ROffset;
|
ULONG ROffset;
|
||||||
|
@ -63,11 +63,11 @@ CcMapData (
|
||||||
}
|
}
|
||||||
|
|
||||||
ROffset = ROUND_DOWN(ReadOffset, VACB_MAPPING_GRANULARITY);
|
ROffset = ROUND_DOWN(ReadOffset, VACB_MAPPING_GRANULARITY);
|
||||||
Status = CcRosRequestCacheSegment(Bcb,
|
Status = CcRosRequestVacb(Bcb,
|
||||||
ROffset,
|
ROffset,
|
||||||
pBuffer,
|
pBuffer,
|
||||||
&Valid,
|
&Valid,
|
||||||
&CacheSeg);
|
&Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -77,13 +77,13 @@ CcMapData (
|
||||||
{
|
{
|
||||||
if (!(Flags & MAP_WAIT))
|
if (!(Flags & MAP_WAIT))
|
||||||
{
|
{
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
|
||||||
return 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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ CcMapData (
|
||||||
iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList);
|
iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList);
|
||||||
if (iBcb == NULL)
|
if (iBcb == NULL)
|
||||||
{
|
{
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ CcMapData (
|
||||||
iBcb->PFCB.NodeByteSize = sizeof(PUBLIC_BCB);
|
iBcb->PFCB.NodeByteSize = sizeof(PUBLIC_BCB);
|
||||||
iBcb->PFCB.MappedLength = Length;
|
iBcb->PFCB.MappedLength = Length;
|
||||||
iBcb->PFCB.MappedFileOffset = *FileOffset;
|
iBcb->PFCB.MappedFileOffset = *FileOffset;
|
||||||
iBcb->CacheSegment = CacheSeg;
|
iBcb->Vacb = Vacb;
|
||||||
iBcb->Dirty = FALSE;
|
iBcb->Dirty = FALSE;
|
||||||
iBcb->RefCount = 1;
|
iBcb->RefCount = 1;
|
||||||
*pBcb = (PVOID)iBcb;
|
*pBcb = (PVOID)iBcb;
|
||||||
|
@ -165,7 +165,7 @@ CcPreparePinWrite (
|
||||||
/*
|
/*
|
||||||
* FIXME: This is function is similar to CcPinRead, but doesn't
|
* FIXME: This is function is similar to CcPinRead, but doesn't
|
||||||
* read the data if they're not present. Instead it should just
|
* 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
|
* For now calling CcPinRead is better than returning error or
|
||||||
* just having UNIMPLEMENTED here.
|
* just having UNIMPLEMENTED here.
|
||||||
|
@ -195,8 +195,8 @@ CcUnpinData (
|
||||||
{
|
{
|
||||||
PINTERNAL_BCB iBcb = Bcb;
|
PINTERNAL_BCB iBcb = Bcb;
|
||||||
|
|
||||||
CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb,
|
CcRosReleaseVacb(iBcb->Vacb->Bcb,
|
||||||
iBcb->CacheSegment,
|
iBcb->Vacb,
|
||||||
TRUE,
|
TRUE,
|
||||||
iBcb->Dirty,
|
iBcb->Dirty,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
@ -248,20 +248,20 @@ CcUnpinRepinnedBcb (
|
||||||
IoStatus->Information = 0;
|
IoStatus->Information = 0;
|
||||||
if (WriteThrough)
|
if (WriteThrough)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&iBcb->CacheSegment->Mutex,
|
KeWaitForSingleObject(&iBcb->Vacb->Mutex,
|
||||||
Executive,
|
Executive,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
if (iBcb->CacheSegment->Dirty)
|
if (iBcb->Vacb->Dirty)
|
||||||
{
|
{
|
||||||
IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment);
|
IoStatus->Status = CcRosFlushVacb(iBcb->Vacb);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IoStatus->Status = STATUS_SUCCESS;
|
IoStatus->Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
KeReleaseMutex(&iBcb->CacheSegment->Mutex, FALSE);
|
KeReleaseMutex(&iBcb->Vacb->Mutex, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,9 +41,9 @@
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
static LIST_ENTRY DirtySegmentListHead;
|
static LIST_ENTRY DirtyVacbListHead;
|
||||||
static LIST_ENTRY CacheSegmentListHead;
|
static LIST_ENTRY VacbListHead;
|
||||||
static LIST_ENTRY CacheSegmentLRUListHead;
|
static LIST_ENTRY VacbLruListHead;
|
||||||
static LIST_ENTRY ClosedListHead;
|
static LIST_ENTRY ClosedListHead;
|
||||||
ULONG DirtyPageCount = 0;
|
ULONG DirtyPageCount = 0;
|
||||||
|
|
||||||
|
@ -51,36 +51,36 @@ KGUARDED_MUTEX ViewLock;
|
||||||
|
|
||||||
NPAGED_LOOKASIDE_LIST iBcbLookasideList;
|
NPAGED_LOOKASIDE_LIST iBcbLookasideList;
|
||||||
static NPAGED_LOOKASIDE_LIST BcbLookasideList;
|
static NPAGED_LOOKASIDE_LIST BcbLookasideList;
|
||||||
static NPAGED_LOOKASIDE_LIST CacheSegLookasideList;
|
static NPAGED_LOOKASIDE_LIST VacbLookasideList;
|
||||||
|
|
||||||
#if DBG
|
#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;
|
++vacb->ReferenceCount;
|
||||||
if ( cs->Bcb->Trace )
|
if (vacb->Bcb->Trace)
|
||||||
{
|
{
|
||||||
DbgPrint("(%s:%i) CacheSegment %p ++RefCount=%lu, Dirty %u, PageOut %lu\n",
|
DbgPrint("(%s:%i) VACB %p ++RefCount=%lu, Dirty %u, PageOut %lu\n",
|
||||||
file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut );
|
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;
|
--vacb->ReferenceCount;
|
||||||
if ( cs->Bcb->Trace )
|
if (vacb->Bcb->Trace)
|
||||||
{
|
{
|
||||||
DbgPrint("(%s:%i) CacheSegment %p --RefCount=%lu, Dirty %u, PageOut %lu\n",
|
DbgPrint("(%s:%i) VACB %p --RefCount=%lu, Dirty %u, PageOut %lu\n",
|
||||||
file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut );
|
file, line, vacb, vacb->ReferenceCount, vacb->Dirty, vacb->PageOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#define CcRosCacheSegmentIncRefCount(cs) CcRosCacheSegmentIncRefCount_(cs,__FILE__,__LINE__)
|
#define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__)
|
||||||
#define CcRosCacheSegmentDecRefCount(cs) CcRosCacheSegmentDecRefCount_(cs,__FILE__,__LINE__)
|
#define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__)
|
||||||
#else
|
#else
|
||||||
#define CcRosCacheSegmentIncRefCount(cs) (++((cs)->ReferenceCount))
|
#define CcRosVacbIncRefCount(vacb) (++((vacb)->ReferenceCount))
|
||||||
#define CcRosCacheSegmentDecRefCount(cs) (--((cs)->ReferenceCount))
|
#define CcRosVacbDecRefCount(vacb) (--((vacb)->ReferenceCount))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg);
|
CcRosInternalFreeVacb(PROS_VACB Vacb);
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
@ -94,7 +94,7 @@ CcRosTraceCacheMap (
|
||||||
#if DBG
|
#if DBG
|
||||||
KIRQL oldirql;
|
KIRQL oldirql;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
|
|
||||||
if ( !Bcb )
|
if ( !Bcb )
|
||||||
return;
|
return;
|
||||||
|
@ -108,13 +108,13 @@ CcRosTraceCacheMap (
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
||||||
|
|
||||||
current_entry = Bcb->BcbSegmentListHead.Flink;
|
current_entry = Bcb->BcbVacbListHead.Flink;
|
||||||
while (current_entry != &Bcb->BcbSegmentListHead)
|
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;
|
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 );
|
current, current->ReferenceCount, current->Dirty, current->PageOut );
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
||||||
|
@ -133,24 +133,24 @@ CcRosTraceCacheMap (
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosFlushCacheSegment (
|
CcRosFlushVacb (
|
||||||
PCACHE_SEGMENT CacheSegment)
|
PROS_VACB Vacb)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
Status = WriteCacheSegment(CacheSegment);
|
Status = CcWriteVirtualAddress(Vacb);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
KeAcquireSpinLock(&CacheSegment->Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(&Vacb->Bcb->BcbLock, &oldIrql);
|
||||||
|
|
||||||
CacheSegment->Dirty = FALSE;
|
Vacb->Dirty = FALSE;
|
||||||
RemoveEntryList(&CacheSegment->DirtySegmentListEntry);
|
RemoveEntryList(&Vacb->DirtyVacbListEntry);
|
||||||
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
CcRosCacheSegmentDecRefCount(CacheSegment);
|
CcRosVacbDecRefCount(Vacb);
|
||||||
|
|
||||||
KeReleaseSpinLock(&CacheSegment->Bcb->BcbLock, oldIrql);
|
KeReleaseSpinLock(&Vacb->Bcb->BcbLock, oldIrql);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,8 +165,7 @@ CcRosFlushDirtyPages (
|
||||||
BOOLEAN Wait)
|
BOOLEAN Wait)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
ULONG PagesPerSegment;
|
|
||||||
BOOLEAN Locked;
|
BOOLEAN Locked;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
LARGE_INTEGER ZeroTimeout;
|
LARGE_INTEGER ZeroTimeout;
|
||||||
|
@ -179,25 +178,26 @@ CcRosFlushDirtyPages (
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
current_entry = DirtySegmentListHead.Flink;
|
current_entry = DirtyVacbListHead.Flink;
|
||||||
if (current_entry == &DirtySegmentListHead)
|
if (current_entry == &DirtyVacbListHead)
|
||||||
{
|
{
|
||||||
DPRINT("No Dirty pages\n");
|
DPRINT("No Dirty pages\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((current_entry != &DirtySegmentListHead) && (Target > 0))
|
while ((current_entry != &DirtyVacbListHead) && (Target > 0))
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
DirtySegmentListEntry);
|
ROS_VACB,
|
||||||
|
DirtyVacbListEntry);
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
|
|
||||||
CcRosCacheSegmentIncRefCount(current);
|
CcRosVacbIncRefCount(current);
|
||||||
|
|
||||||
Locked = current->Bcb->Callbacks->AcquireForLazyWrite(
|
Locked = current->Bcb->Callbacks->AcquireForLazyWrite(
|
||||||
current->Bcb->LazyWriteContext, Wait);
|
current->Bcb->LazyWriteContext, Wait);
|
||||||
if (!Locked)
|
if (!Locked)
|
||||||
{
|
{
|
||||||
CcRosCacheSegmentDecRefCount(current);
|
CcRosVacbDecRefCount(current);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ CcRosFlushDirtyPages (
|
||||||
{
|
{
|
||||||
current->Bcb->Callbacks->ReleaseFromLazyWrite(
|
current->Bcb->Callbacks->ReleaseFromLazyWrite(
|
||||||
current->Bcb->LazyWriteContext);
|
current->Bcb->LazyWriteContext);
|
||||||
CcRosCacheSegmentDecRefCount(current);
|
CcRosVacbDecRefCount(current);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,34 +222,32 @@ CcRosFlushDirtyPages (
|
||||||
KeReleaseMutex(¤t->Mutex, FALSE);
|
KeReleaseMutex(¤t->Mutex, FALSE);
|
||||||
current->Bcb->Callbacks->ReleaseFromLazyWrite(
|
current->Bcb->Callbacks->ReleaseFromLazyWrite(
|
||||||
current->Bcb->LazyWriteContext);
|
current->Bcb->LazyWriteContext);
|
||||||
CcRosCacheSegmentDecRefCount(current);
|
CcRosVacbDecRefCount(current);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
PagesPerSegment = VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
|
||||||
|
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
Status = CcRosFlushCacheSegment(current);
|
Status = CcRosFlushVacb(current);
|
||||||
|
|
||||||
KeReleaseMutex(¤t->Mutex, FALSE);
|
KeReleaseMutex(¤t->Mutex, FALSE);
|
||||||
current->Bcb->Callbacks->ReleaseFromLazyWrite(
|
current->Bcb->Callbacks->ReleaseFromLazyWrite(
|
||||||
current->Bcb->LazyWriteContext);
|
current->Bcb->LazyWriteContext);
|
||||||
|
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
CcRosCacheSegmentDecRefCount(current);
|
CcRosVacbDecRefCount(current);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
|
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
|
else
|
||||||
{
|
{
|
||||||
(*Count) += PagesPerSegment;
|
(*Count) += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
Target -= PagesPerSegment;
|
Target -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_entry = DirtySegmentListHead.Flink;
|
current_entry = DirtyVacbListHead.Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
|
@ -274,8 +272,7 @@ CcRosTrimCache (
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
ULONG PagesPerSegment;
|
|
||||||
ULONG PagesFreed;
|
ULONG PagesFreed;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
LIST_ENTRY FreeList;
|
LIST_ENTRY FreeList;
|
||||||
|
@ -292,17 +289,18 @@ CcRosTrimCache (
|
||||||
retry:
|
retry:
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
current_entry = CacheSegmentLRUListHead.Flink;
|
current_entry = VacbLruListHead.Flink;
|
||||||
while (current_entry != &CacheSegmentLRUListHead)
|
while (current_entry != &VacbLruListHead)
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
CacheSegmentLRUListEntry);
|
ROS_VACB,
|
||||||
|
VacbLruListEntry);
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
|
|
||||||
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
||||||
|
|
||||||
/* Reference the cache segment */
|
/* Reference the VACB */
|
||||||
CcRosCacheSegmentIncRefCount(current);
|
CcRosVacbIncRefCount(current);
|
||||||
|
|
||||||
/* Check if it's mapped and not dirty */
|
/* Check if it's mapped and not dirty */
|
||||||
if (current->MappedCount > 0 && !current->Dirty)
|
if (current->MappedCount > 0 && !current->Dirty)
|
||||||
|
@ -311,7 +309,7 @@ retry:
|
||||||
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
/* Page out the segment */
|
/* Page out the VACB */
|
||||||
for (i = 0; i < VACB_MAPPING_GRANULARITY / PAGE_SIZE; i++)
|
for (i = 0; i < VACB_MAPPING_GRANULARITY / PAGE_SIZE; i++)
|
||||||
{
|
{
|
||||||
Page = (PFN_NUMBER)(MmGetPhysicalAddress((PUCHAR)current->BaseAddress + (i * PAGE_SIZE)).QuadPart >> PAGE_SHIFT);
|
Page = (PFN_NUMBER)(MmGetPhysicalAddress((PUCHAR)current->BaseAddress + (i * PAGE_SIZE)).QuadPart >> PAGE_SHIFT);
|
||||||
|
@ -324,8 +322,8 @@ retry:
|
||||||
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dereference the cache segment */
|
/* Dereference the VACB */
|
||||||
CcRosCacheSegmentDecRefCount(current);
|
CcRosVacbDecRefCount(current);
|
||||||
|
|
||||||
/* Check if we can free this entry now */
|
/* Check if we can free this entry now */
|
||||||
if (current->ReferenceCount == 0)
|
if (current->ReferenceCount == 0)
|
||||||
|
@ -333,14 +331,13 @@ retry:
|
||||||
ASSERT(!current->Dirty);
|
ASSERT(!current->Dirty);
|
||||||
ASSERT(!current->MappedCount);
|
ASSERT(!current->MappedCount);
|
||||||
|
|
||||||
RemoveEntryList(¤t->BcbSegmentListEntry);
|
RemoveEntryList(¤t->BcbVacbListEntry);
|
||||||
RemoveEntryList(¤t->CacheSegmentListEntry);
|
RemoveEntryList(¤t->VacbListEntry);
|
||||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
RemoveEntryList(¤t->VacbLruListEntry);
|
||||||
InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry);
|
InsertHeadList(&FreeList, ¤t->BcbVacbListEntry);
|
||||||
|
|
||||||
/* Calculate how many pages we freed for Mm */
|
/* Calculate how many pages we freed for Mm */
|
||||||
PagesPerSegment = VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
PagesFreed = min(VACB_MAPPING_GRANULARITY / PAGE_SIZE, Target);
|
||||||
PagesFreed = min(PagesPerSegment, Target);
|
|
||||||
Target -= PagesFreed;
|
Target -= PagesFreed;
|
||||||
(*NrFreed) += PagesFreed;
|
(*NrFreed) += PagesFreed;
|
||||||
}
|
}
|
||||||
|
@ -372,9 +369,10 @@ retry:
|
||||||
while (!IsListEmpty(&FreeList))
|
while (!IsListEmpty(&FreeList))
|
||||||
{
|
{
|
||||||
current_entry = RemoveHeadList(&FreeList);
|
current_entry = RemoveHeadList(&FreeList);
|
||||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
BcbSegmentListEntry);
|
ROS_VACB,
|
||||||
CcRosInternalFreeCacheSegment(current);
|
BcbVacbListEntry);
|
||||||
|
CcRosInternalFreeVacb(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Evicted %lu cache pages\n", (*NrFreed));
|
DPRINT("Evicted %lu cache pages\n", (*NrFreed));
|
||||||
|
@ -384,9 +382,9 @@ retry:
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosReleaseCacheSegment (
|
CcRosReleaseVacb (
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
PCACHE_SEGMENT CacheSeg,
|
PROS_VACB Vacb,
|
||||||
BOOLEAN Valid,
|
BOOLEAN Valid,
|
||||||
BOOLEAN Dirty,
|
BOOLEAN Dirty,
|
||||||
BOOLEAN Mapped)
|
BOOLEAN Mapped)
|
||||||
|
@ -396,71 +394,72 @@ CcRosReleaseCacheSegment (
|
||||||
|
|
||||||
ASSERT(Bcb);
|
ASSERT(Bcb);
|
||||||
|
|
||||||
DPRINT("CcReleaseCacheSegment(Bcb 0x%p, CacheSeg 0x%p, Valid %u)\n",
|
DPRINT("CcRosReleaseVacb(Bcb 0x%p, Vacb 0x%p, Valid %u)\n",
|
||||||
Bcb, CacheSeg, Valid);
|
Bcb, Vacb, Valid);
|
||||||
|
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
||||||
|
|
||||||
CacheSeg->Valid = Valid;
|
Vacb->Valid = Valid;
|
||||||
|
|
||||||
WasDirty = CacheSeg->Dirty;
|
WasDirty = Vacb->Dirty;
|
||||||
CacheSeg->Dirty = CacheSeg->Dirty || 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;
|
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Mapped)
|
if (Mapped)
|
||||||
{
|
{
|
||||||
CacheSeg->MappedCount++;
|
Vacb->MappedCount++;
|
||||||
}
|
}
|
||||||
CcRosCacheSegmentDecRefCount(CacheSeg);
|
CcRosVacbDecRefCount(Vacb);
|
||||||
if (Mapped && (CacheSeg->MappedCount == 1))
|
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);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
KeReleaseMutex(&CacheSeg->Mutex, FALSE);
|
KeReleaseMutex(&Vacb->Mutex, FALSE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns with Cache Segment Lock Held! */
|
/* Returns with VACB Lock Held! */
|
||||||
PCACHE_SEGMENT
|
PROS_VACB
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosLookupCacheSegment (
|
CcRosLookupVacb (
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset)
|
ULONG FileOffset)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
ASSERT(Bcb);
|
ASSERT(Bcb);
|
||||||
|
|
||||||
DPRINT("CcRosLookupCacheSegment(Bcb -x%p, FileOffset %lu)\n", Bcb, FileOffset);
|
DPRINT("CcRosLookupVacb(Bcb -x%p, FileOffset %lu)\n", Bcb, FileOffset);
|
||||||
|
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
||||||
|
|
||||||
current_entry = Bcb->BcbSegmentListHead.Flink;
|
current_entry = Bcb->BcbVacbListHead.Flink;
|
||||||
while (current_entry != &Bcb->BcbSegmentListHead)
|
while (current_entry != &Bcb->BcbVacbListHead)
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
BcbSegmentListEntry);
|
ROS_VACB,
|
||||||
if (IsPointInSegment(current->FileOffset, VACB_MAPPING_GRANULARITY,
|
BcbVacbListEntry);
|
||||||
|
if (IsPointInRange(current->FileOffset, VACB_MAPPING_GRANULARITY,
|
||||||
FileOffset))
|
FileOffset))
|
||||||
{
|
{
|
||||||
CcRosCacheSegmentIncRefCount(current);
|
CcRosVacbIncRefCount(current);
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
KeWaitForSingleObject(¤t->Mutex,
|
KeWaitForSingleObject(¤t->Mutex,
|
||||||
|
@ -483,19 +482,19 @@ CcRosLookupCacheSegment (
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosMarkDirtyCacheSegment (
|
CcRosMarkDirtyVacb (
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset)
|
ULONG FileOffset)
|
||||||
{
|
{
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PROS_VACB Vacb;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
ASSERT(Bcb);
|
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);
|
Vacb = CcRosLookupVacb(Bcb, FileOffset);
|
||||||
if (CacheSeg == NULL)
|
if (Vacb == NULL)
|
||||||
{
|
{
|
||||||
KeBugCheck(CACHE_MANAGER);
|
KeBugCheck(CACHE_MANAGER);
|
||||||
}
|
}
|
||||||
|
@ -503,47 +502,47 @@ CcRosMarkDirtyCacheSegment (
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
||||||
|
|
||||||
if (!CacheSeg->Dirty)
|
if (!Vacb->Dirty)
|
||||||
{
|
{
|
||||||
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
|
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
|
||||||
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CcRosCacheSegmentDecRefCount(CacheSeg);
|
CcRosVacbDecRefCount(Vacb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move to the tail of the LRU list */
|
/* Move to the tail of the LRU list */
|
||||||
RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry);
|
RemoveEntryList(&Vacb->VacbLruListEntry);
|
||||||
InsertTailList(&CacheSegmentLRUListHead, &CacheSeg->CacheSegmentLRUListEntry);
|
InsertTailList(&VacbLruListHead, &Vacb->VacbLruListEntry);
|
||||||
|
|
||||||
CacheSeg->Dirty = TRUE;
|
Vacb->Dirty = TRUE;
|
||||||
|
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
KeReleaseMutex(&CacheSeg->Mutex, FALSE);
|
KeReleaseMutex(&Vacb->Mutex, FALSE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosUnmapCacheSegment (
|
CcRosUnmapVacb (
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
BOOLEAN NowDirty)
|
BOOLEAN NowDirty)
|
||||||
{
|
{
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PROS_VACB Vacb;
|
||||||
BOOLEAN WasDirty;
|
BOOLEAN WasDirty;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
ASSERT(Bcb);
|
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);
|
Bcb, FileOffset, NowDirty);
|
||||||
|
|
||||||
CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset);
|
Vacb = CcRosLookupVacb(Bcb, FileOffset);
|
||||||
if (CacheSeg == NULL)
|
if (Vacb == NULL)
|
||||||
{
|
{
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
@ -551,58 +550,58 @@ CcRosUnmapCacheSegment (
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
||||||
|
|
||||||
WasDirty = CacheSeg->Dirty;
|
WasDirty = Vacb->Dirty;
|
||||||
CacheSeg->Dirty = CacheSeg->Dirty || NowDirty;
|
Vacb->Dirty = Vacb->Dirty || NowDirty;
|
||||||
|
|
||||||
CacheSeg->MappedCount--;
|
Vacb->MappedCount--;
|
||||||
|
|
||||||
if (!WasDirty && NowDirty)
|
if (!WasDirty && NowDirty)
|
||||||
{
|
{
|
||||||
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
|
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
|
||||||
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
DirtyPageCount += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CcRosCacheSegmentDecRefCount(CacheSeg);
|
CcRosVacbDecRefCount(Vacb);
|
||||||
if (!WasDirty && NowDirty)
|
if (!WasDirty && NowDirty)
|
||||||
{
|
{
|
||||||
CcRosCacheSegmentIncRefCount(CacheSeg);
|
CcRosVacbIncRefCount(Vacb);
|
||||||
}
|
}
|
||||||
if (CacheSeg->MappedCount == 0)
|
if (Vacb->MappedCount == 0)
|
||||||
{
|
{
|
||||||
CcRosCacheSegmentDecRefCount(CacheSeg);
|
CcRosVacbDecRefCount(Vacb);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
KeReleaseMutex(&CacheSeg->Mutex, FALSE);
|
KeReleaseMutex(&Vacb->Mutex, FALSE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CcRosCreateCacheSegment (
|
CcRosCreateVacb (
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
PCACHE_SEGMENT* CacheSeg)
|
PROS_VACB *Vacb)
|
||||||
{
|
{
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
PCACHE_SEGMENT previous;
|
PROS_VACB previous;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
ASSERT(Bcb);
|
ASSERT(Bcb);
|
||||||
|
|
||||||
DPRINT("CcRosCreateCacheSegment()\n");
|
DPRINT("CcRosCreateVacb()\n");
|
||||||
|
|
||||||
if (FileOffset >= Bcb->FileSize.u.LowPart)
|
if (FileOffset >= Bcb->FileSize.u.LowPart)
|
||||||
{
|
{
|
||||||
*CacheSeg = NULL;
|
*Vacb = NULL;
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = ExAllocateFromNPagedLookasideList(&CacheSegLookasideList);
|
current = ExAllocateFromNPagedLookasideList(&VacbLookasideList);
|
||||||
current->Valid = FALSE;
|
current->Valid = FALSE;
|
||||||
current->Dirty = FALSE;
|
current->Dirty = FALSE;
|
||||||
current->PageOut = FALSE;
|
current->PageOut = FALSE;
|
||||||
|
@ -611,12 +610,12 @@ CcRosCreateCacheSegment (
|
||||||
#if DBG
|
#if DBG
|
||||||
if ( Bcb->Trace )
|
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
|
#endif
|
||||||
current->MappedCount = 0;
|
current->MappedCount = 0;
|
||||||
current->DirtySegmentListEntry.Flink = NULL;
|
current->DirtyVacbListEntry.Flink = NULL;
|
||||||
current->DirtySegmentListEntry.Blink = NULL;
|
current->DirtyVacbListEntry.Blink = NULL;
|
||||||
current->ReferenceCount = 1;
|
current->ReferenceCount = 1;
|
||||||
KeInitializeMutex(¤t->Mutex, 0);
|
KeInitializeMutex(¤t->Mutex, 0);
|
||||||
KeWaitForSingleObject(¤t->Mutex,
|
KeWaitForSingleObject(¤t->Mutex,
|
||||||
|
@ -626,37 +625,38 @@ CcRosCreateCacheSegment (
|
||||||
NULL);
|
NULL);
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
*CacheSeg = current;
|
*Vacb = current;
|
||||||
/* There is window between the call to CcRosLookupCacheSegment
|
/* There is window between the call to CcRosLookupVacb
|
||||||
* and CcRosCreateCacheSegment. We must check if a segment on
|
* and CcRosCreateVacb. We must check if a VACB for the
|
||||||
* the fileoffset exist. If there exist a segment, we release
|
* file offset exist. If there is a VACB, we release
|
||||||
* our new created segment and return the existing one.
|
* our newly created VACB and return the existing one.
|
||||||
*/
|
*/
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
||||||
current_entry = Bcb->BcbSegmentListHead.Flink;
|
current_entry = Bcb->BcbVacbListHead.Flink;
|
||||||
previous = NULL;
|
previous = NULL;
|
||||||
while (current_entry != &Bcb->BcbSegmentListHead)
|
while (current_entry != &Bcb->BcbVacbListHead)
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
BcbSegmentListEntry);
|
ROS_VACB,
|
||||||
if (IsPointInSegment(current->FileOffset, VACB_MAPPING_GRANULARITY,
|
BcbVacbListEntry);
|
||||||
|
if (IsPointInRange(current->FileOffset, VACB_MAPPING_GRANULARITY,
|
||||||
FileOffset))
|
FileOffset))
|
||||||
{
|
{
|
||||||
CcRosCacheSegmentIncRefCount(current);
|
CcRosVacbIncRefCount(current);
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
||||||
#if DBG
|
#if DBG
|
||||||
if ( Bcb->Trace )
|
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,
|
Bcb,
|
||||||
(*CacheSeg),
|
(*Vacb),
|
||||||
current );
|
current );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
KeReleaseMutex(&(*CacheSeg)->Mutex, FALSE);
|
KeReleaseMutex(&(*Vacb)->Mutex, FALSE);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg);
|
ExFreeToNPagedLookasideList(&VacbLookasideList, *Vacb);
|
||||||
*CacheSeg = current;
|
*Vacb = current;
|
||||||
KeWaitForSingleObject(¤t->Mutex,
|
KeWaitForSingleObject(¤t->Mutex,
|
||||||
Executive,
|
Executive,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
|
@ -674,25 +674,25 @@ CcRosCreateCacheSegment (
|
||||||
break;
|
break;
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
}
|
}
|
||||||
/* There was no existing segment. */
|
/* There was no existing VACB. */
|
||||||
current = *CacheSeg;
|
current = *Vacb;
|
||||||
if (previous)
|
if (previous)
|
||||||
{
|
{
|
||||||
InsertHeadList(&previous->BcbSegmentListEntry, ¤t->BcbSegmentListEntry);
|
InsertHeadList(&previous->BcbVacbListEntry, ¤t->BcbVacbListEntry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InsertHeadList(&Bcb->BcbSegmentListHead, ¤t->BcbSegmentListEntry);
|
InsertHeadList(&Bcb->BcbVacbListHead, ¤t->BcbVacbListEntry);
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
||||||
InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry);
|
InsertTailList(&VacbListHead, ¤t->VacbListEntry);
|
||||||
InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry);
|
InsertTailList(&VacbLruListHead, ¤t->VacbLruListEntry);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
MmLockAddressSpace(MmGetKernelAddressSpace());
|
||||||
current->BaseAddress = NULL;
|
current->BaseAddress = NULL;
|
||||||
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
|
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,
|
¤t->BaseAddress,
|
||||||
VACB_MAPPING_GRANULARITY,
|
VACB_MAPPING_GRANULARITY,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
|
@ -727,49 +727,49 @@ CcRosCreateCacheSegment (
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosGetCacheSegmentChain (
|
CcRosGetVacbChain (
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
ULONG Length,
|
ULONG Length,
|
||||||
PCACHE_SEGMENT* CacheSeg)
|
PROS_VACB *Vacb)
|
||||||
{
|
{
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PCACHE_SEGMENT* CacheSegList;
|
PROS_VACB *VacbList;
|
||||||
PCACHE_SEGMENT Previous = NULL;
|
PROS_VACB Previous = NULL;
|
||||||
|
|
||||||
ASSERT(Bcb);
|
ASSERT(Bcb);
|
||||||
|
|
||||||
DPRINT("CcRosGetCacheSegmentChain()\n");
|
DPRINT("CcRosGetVacbChain()\n");
|
||||||
|
|
||||||
Length = ROUND_UP(Length, VACB_MAPPING_GRANULARITY);
|
Length = ROUND_UP(Length, VACB_MAPPING_GRANULARITY);
|
||||||
|
|
||||||
CacheSegList = _alloca(sizeof(PCACHE_SEGMENT) *
|
VacbList = _alloca(sizeof(PROS_VACB) *
|
||||||
(Length / VACB_MAPPING_GRANULARITY));
|
(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++)
|
for (i = 0; i < (Length / VACB_MAPPING_GRANULARITY); i++)
|
||||||
{
|
{
|
||||||
ULONG CurrentOffset = FileOffset + (i * VACB_MAPPING_GRANULARITY);
|
ULONG CurrentOffset = FileOffset + (i * VACB_MAPPING_GRANULARITY);
|
||||||
current = CcRosLookupCacheSegment(Bcb, CurrentOffset);
|
current = CcRosLookupVacb(Bcb, CurrentOffset);
|
||||||
if (current != NULL)
|
if (current != NULL)
|
||||||
{
|
{
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
/* Move to tail of LRU list */
|
/* Move to tail of LRU list */
|
||||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
RemoveEntryList(¤t->VacbLruListEntry);
|
||||||
InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry);
|
InsertTailList(&VacbLruListHead, ¤t->VacbLruListEntry);
|
||||||
|
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
CacheSegList[i] = current;
|
VacbList[i] = current;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CcRosCreateCacheSegment(Bcb, CurrentOffset, ¤t);
|
CcRosCreateVacb(Bcb, CurrentOffset, ¤t);
|
||||||
CacheSegList[i] = current;
|
VacbList[i] = current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,13 +777,13 @@ CcRosGetCacheSegmentChain (
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
*CacheSeg = CacheSegList[i];
|
*Vacb = VacbList[i];
|
||||||
Previous = CacheSegList[i];
|
Previous = VacbList[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Previous->NextInChain = CacheSegList[i];
|
Previous->NextInChain = VacbList[i];
|
||||||
Previous = CacheSegList[i];
|
Previous = VacbList[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT(Previous);
|
ASSERT(Previous);
|
||||||
|
@ -794,31 +794,31 @@ CcRosGetCacheSegmentChain (
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosGetCacheSegment (
|
CcRosGetVacb (
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
PULONG BaseOffset,
|
PULONG BaseOffset,
|
||||||
PVOID* BaseAddress,
|
PVOID* BaseAddress,
|
||||||
PBOOLEAN UptoDate,
|
PBOOLEAN UptoDate,
|
||||||
PCACHE_SEGMENT* CacheSeg)
|
PROS_VACB *Vacb)
|
||||||
{
|
{
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
ASSERT(Bcb);
|
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)
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -828,30 +828,30 @@ CcRosGetCacheSegment (
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
/* Move to the tail of the LRU list */
|
/* Move to the tail of the LRU list */
|
||||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
RemoveEntryList(¤t->VacbLruListEntry);
|
||||||
InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry);
|
InsertTailList(&VacbLruListHead, ¤t->VacbLruListEntry);
|
||||||
|
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return information about the segment to the caller.
|
* Return information about the VACB to the caller.
|
||||||
*/
|
*/
|
||||||
*UptoDate = current->Valid;
|
*UptoDate = current->Valid;
|
||||||
*BaseAddress = current->BaseAddress;
|
*BaseAddress = current->BaseAddress;
|
||||||
DPRINT("*BaseAddress %p\n", *BaseAddress);
|
DPRINT("*BaseAddress %p\n", *BaseAddress);
|
||||||
*CacheSeg = current;
|
*Vacb = current;
|
||||||
*BaseOffset = current->FileOffset;
|
*BaseOffset = current->FileOffset;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosRequestCacheSegment (
|
CcRosRequestVacb (
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
PVOID* BaseAddress,
|
PVOID* BaseAddress,
|
||||||
PBOOLEAN UptoDate,
|
PBOOLEAN UptoDate,
|
||||||
PCACHE_SEGMENT* CacheSeg)
|
PROS_VACB *Vacb)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Request a page mapping for a BCB
|
* FUNCTION: Request a page mapping for a BCB
|
||||||
*/
|
*/
|
||||||
|
@ -867,12 +867,12 @@ CcRosRequestCacheSegment (
|
||||||
KeBugCheck(CACHE_MANAGER);
|
KeBugCheck(CACHE_MANAGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CcRosGetCacheSegment(Bcb,
|
return CcRosGetVacb(Bcb,
|
||||||
FileOffset,
|
FileOffset,
|
||||||
&BaseOffset,
|
&BaseOffset,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
UptoDate,
|
UptoDate,
|
||||||
CacheSeg);
|
Vacb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -894,28 +894,28 @@ CcFreeCachePage (
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CcRosInternalFreeCacheSegment (
|
CcRosInternalFreeVacb (
|
||||||
PCACHE_SEGMENT CacheSeg)
|
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 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
|
#endif
|
||||||
|
|
||||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
MmLockAddressSpace(MmGetKernelAddressSpace());
|
||||||
MmFreeMemoryArea(MmGetKernelAddressSpace(),
|
MmFreeMemoryArea(MmGetKernelAddressSpace(),
|
||||||
CacheSeg->MemoryArea,
|
Vacb->MemoryArea,
|
||||||
CcFreeCachePage,
|
CcFreeCachePage,
|
||||||
NULL);
|
NULL);
|
||||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||||
|
|
||||||
ExFreeToNPagedLookasideList(&CacheSegLookasideList, CacheSeg);
|
ExFreeToNPagedLookasideList(&VacbLookasideList, Vacb);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,7 +932,7 @@ CcFlushCache (
|
||||||
{
|
{
|
||||||
PBCB Bcb;
|
PBCB Bcb;
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
@ -961,12 +961,12 @@ CcFlushCache (
|
||||||
|
|
||||||
while (Length > 0)
|
while (Length > 0)
|
||||||
{
|
{
|
||||||
current = CcRosLookupCacheSegment (Bcb, Offset.u.LowPart);
|
current = CcRosLookupVacb(Bcb, Offset.u.LowPart);
|
||||||
if (current != NULL)
|
if (current != NULL)
|
||||||
{
|
{
|
||||||
if (current->Dirty)
|
if (current->Dirty)
|
||||||
{
|
{
|
||||||
Status = CcRosFlushCacheSegment(current);
|
Status = CcRosFlushVacb(current);
|
||||||
if (!NT_SUCCESS(Status) && IoStatus != NULL)
|
if (!NT_SUCCESS(Status) && IoStatus != NULL)
|
||||||
{
|
{
|
||||||
IoStatus->Status = Status;
|
IoStatus->Status = Status;
|
||||||
|
@ -976,7 +976,7 @@ CcFlushCache (
|
||||||
|
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
||||||
CcRosCacheSegmentDecRefCount(current);
|
CcRosVacbDecRefCount(current);
|
||||||
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
}
|
}
|
||||||
|
@ -1011,7 +1011,7 @@ CcRosDeleteFileCache (
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT current;
|
PROS_VACB current;
|
||||||
LIST_ENTRY FreeList;
|
LIST_ENTRY FreeList;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
@ -1035,23 +1035,23 @@ CcRosDeleteFileCache (
|
||||||
FileObject->SectionObjectPointer->SharedCacheMap = NULL;
|
FileObject->SectionObjectPointer->SharedCacheMap = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release all cache segments.
|
* Release all VACBs
|
||||||
*/
|
*/
|
||||||
InitializeListHead(&FreeList);
|
InitializeListHead(&FreeList);
|
||||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
|
||||||
while (!IsListEmpty(&Bcb->BcbSegmentListHead))
|
while (!IsListEmpty(&Bcb->BcbVacbListHead))
|
||||||
{
|
{
|
||||||
current_entry = RemoveTailList(&Bcb->BcbSegmentListHead);
|
current_entry = RemoveTailList(&Bcb->BcbVacbListHead);
|
||||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
|
current = CONTAINING_RECORD(current_entry, ROS_VACB, BcbVacbListEntry);
|
||||||
RemoveEntryList(¤t->CacheSegmentListEntry);
|
RemoveEntryList(¤t->VacbListEntry);
|
||||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
RemoveEntryList(¤t->VacbLruListEntry);
|
||||||
if (current->Dirty)
|
if (current->Dirty)
|
||||||
{
|
{
|
||||||
RemoveEntryList(¤t->DirtySegmentListEntry);
|
RemoveEntryList(¤t->DirtyVacbListEntry);
|
||||||
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
|
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
|
#if DBG
|
||||||
Bcb->Trace = FALSE;
|
Bcb->Trace = FALSE;
|
||||||
|
@ -1064,8 +1064,8 @@ CcRosDeleteFileCache (
|
||||||
while (!IsListEmpty(&FreeList))
|
while (!IsListEmpty(&FreeList))
|
||||||
{
|
{
|
||||||
current_entry = RemoveTailList(&FreeList);
|
current_entry = RemoveTailList(&FreeList);
|
||||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
|
current = CONTAINING_RECORD(current_entry, ROS_VACB, BcbVacbListEntry);
|
||||||
CcRosInternalFreeCacheSegment(current);
|
CcRosInternalFreeVacb(current);
|
||||||
}
|
}
|
||||||
ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
|
ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
|
||||||
KeAcquireGuardedMutex(&ViewLock);
|
KeAcquireGuardedMutex(&ViewLock);
|
||||||
|
@ -1250,7 +1250,7 @@ CcRosInitializeFileCache (
|
||||||
((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize;
|
((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize;
|
||||||
}
|
}
|
||||||
KeInitializeSpinLock(&Bcb->BcbLock);
|
KeInitializeSpinLock(&Bcb->BcbLock);
|
||||||
InitializeListHead(&Bcb->BcbSegmentListHead);
|
InitializeListHead(&Bcb->BcbVacbListHead);
|
||||||
FileObject->SectionObjectPointer->SharedCacheMap = Bcb;
|
FileObject->SectionObjectPointer->SharedCacheMap = Bcb;
|
||||||
}
|
}
|
||||||
if (FileObject->PrivateCacheMap == NULL)
|
if (FileObject->PrivateCacheMap == NULL)
|
||||||
|
@ -1294,9 +1294,9 @@ CcInitView (
|
||||||
{
|
{
|
||||||
DPRINT("CcInitView()\n");
|
DPRINT("CcInitView()\n");
|
||||||
|
|
||||||
InitializeListHead(&CacheSegmentListHead);
|
InitializeListHead(&VacbListHead);
|
||||||
InitializeListHead(&DirtySegmentListHead);
|
InitializeListHead(&DirtyVacbListHead);
|
||||||
InitializeListHead(&CacheSegmentLRUListHead);
|
InitializeListHead(&VacbLruListHead);
|
||||||
InitializeListHead(&ClosedListHead);
|
InitializeListHead(&ClosedListHead);
|
||||||
KeInitializeGuardedMutex(&ViewLock);
|
KeInitializeGuardedMutex(&ViewLock);
|
||||||
ExInitializeNPagedLookasideList (&iBcbLookasideList,
|
ExInitializeNPagedLookasideList (&iBcbLookasideList,
|
||||||
|
@ -1313,11 +1313,11 @@ CcInitView (
|
||||||
sizeof(BCB),
|
sizeof(BCB),
|
||||||
TAG_BCB,
|
TAG_BCB,
|
||||||
20);
|
20);
|
||||||
ExInitializeNPagedLookasideList (&CacheSegLookasideList,
|
ExInitializeNPagedLookasideList (&VacbLookasideList,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
sizeof(CACHE_SEGMENT),
|
sizeof(ROS_VACB),
|
||||||
TAG_CSEG,
|
TAG_CSEG,
|
||||||
20);
|
20);
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ typedef struct _PFSN_PREFETCHER_GLOBALS
|
||||||
|
|
||||||
typedef struct _BCB
|
typedef struct _BCB
|
||||||
{
|
{
|
||||||
LIST_ENTRY BcbSegmentListHead;
|
LIST_ENTRY BcbVacbListHead;
|
||||||
LIST_ENTRY BcbRemoveListEntry;
|
LIST_ENTRY BcbRemoveListEntry;
|
||||||
BOOLEAN RemoveOnClose;
|
BOOLEAN RemoveOnClose;
|
||||||
ULONG TimeStamp;
|
ULONG TimeStamp;
|
||||||
|
@ -115,49 +115,46 @@ typedef struct _BCB
|
||||||
KSPIN_LOCK BcbLock;
|
KSPIN_LOCK BcbLock;
|
||||||
ULONG RefCount;
|
ULONG RefCount;
|
||||||
#if DBG
|
#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
|
#endif
|
||||||
} BCB, *PBCB;
|
} 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;
|
PVOID BaseAddress;
|
||||||
/*
|
/* Memory area representing the region where the view's data is mapped. */
|
||||||
* Memory area representing the region where the cache segment data is
|
|
||||||
* mapped.
|
|
||||||
*/
|
|
||||||
struct _MEMORY_AREA* MemoryArea;
|
struct _MEMORY_AREA* MemoryArea;
|
||||||
/* Are the contents of the cache segment data valid. */
|
/* Are the contents of the view valid. */
|
||||||
BOOLEAN 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;
|
BOOLEAN Dirty;
|
||||||
/* Page out in progress */
|
/* Page out in progress */
|
||||||
BOOLEAN PageOut;
|
BOOLEAN PageOut;
|
||||||
ULONG MappedCount;
|
ULONG MappedCount;
|
||||||
/* Entry in the list of segments for this BCB. */
|
/* Entry in the list of VACBs for this BCB. */
|
||||||
LIST_ENTRY BcbSegmentListEntry;
|
LIST_ENTRY BcbVacbListEntry;
|
||||||
/* Entry in the list of segments which are dirty. */
|
/* Entry in the list of VACBs which are dirty. */
|
||||||
LIST_ENTRY DirtySegmentListEntry;
|
LIST_ENTRY DirtyVacbListEntry;
|
||||||
/* Entry in the list of segments. */
|
/* Entry in the list of VACBs. */
|
||||||
LIST_ENTRY CacheSegmentListEntry;
|
LIST_ENTRY VacbListEntry;
|
||||||
LIST_ENTRY CacheSegmentLRUListEntry;
|
LIST_ENTRY VacbLruListEntry;
|
||||||
/* Offset in the file which this cache segment maps. */
|
/* Offset in the file which this view maps. */
|
||||||
ULONG FileOffset;
|
ULONG FileOffset;
|
||||||
/* Mutex */
|
/* Mutex */
|
||||||
KMUTEX Mutex;
|
KMUTEX Mutex;
|
||||||
/* Number of references. */
|
/* Number of references. */
|
||||||
ULONG ReferenceCount;
|
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;
|
PBCB Bcb;
|
||||||
/* Pointer to the next cache segment in a chain. */
|
/* Pointer to the next VACB in a chain. */
|
||||||
struct _CACHE_SEGMENT* NextInChain;
|
struct _ROS_VACB *NextInChain;
|
||||||
} CACHE_SEGMENT, *PCACHE_SEGMENT;
|
} ROS_VACB, *PROS_VACB;
|
||||||
|
|
||||||
typedef struct _INTERNAL_BCB
|
typedef struct _INTERNAL_BCB
|
||||||
{
|
{
|
||||||
PUBLIC_BCB PFCB;
|
PUBLIC_BCB PFCB;
|
||||||
PCACHE_SEGMENT CacheSegment;
|
PROS_VACB Vacb;
|
||||||
BOOLEAN Dirty;
|
BOOLEAN Dirty;
|
||||||
CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
|
CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
|
||||||
} INTERNAL_BCB, *PINTERNAL_BCB;
|
} INTERNAL_BCB, *PINTERNAL_BCB;
|
||||||
|
@ -185,17 +182,17 @@ CcMdlWriteComplete2(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment);
|
CcRosFlushVacb(PROS_VACB Vacb);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosGetCacheSegment(
|
CcRosGetVacb(
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
PULONG BaseOffset,
|
PULONG BaseOffset,
|
||||||
PVOID *BaseAddress,
|
PVOID *BaseAddress,
|
||||||
PBOOLEAN UptoDate,
|
PBOOLEAN UptoDate,
|
||||||
PCACHE_SEGMENT *CacheSeg
|
PROS_VACB *Vacb
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -204,11 +201,11 @@ CcInitView(VOID);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ReadCacheSegment(PCACHE_SEGMENT CacheSeg);
|
CcReadVirtualAddress(PROS_VACB Vacb);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
WriteCacheSegment(PCACHE_SEGMENT CacheSeg);
|
CcWriteVirtualAddress(PROS_VACB Vacb);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -216,26 +213,26 @@ CcInitializeCacheManager(VOID);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosUnmapCacheSegment(
|
CcRosUnmapVacb(
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
BOOLEAN NowDirty
|
BOOLEAN NowDirty
|
||||||
);
|
);
|
||||||
|
|
||||||
PCACHE_SEGMENT
|
PROS_VACB
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosLookupCacheSegment(
|
CcRosLookupVacb(
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset
|
ULONG FileOffset
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosGetCacheSegmentChain(
|
CcRosGetVacbChain(
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
ULONG Length,
|
ULONG Length,
|
||||||
PCACHE_SEGMENT* CacheSeg
|
PROS_VACB *Vacb
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -244,7 +241,7 @@ CcInitCacheZeroPage(VOID);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosMarkDirtyCacheSegment(
|
CcRosMarkDirtyVacb(
|
||||||
PBCB Bcb,
|
PBCB Bcb,
|
||||||
ULONG FileOffset
|
ULONG FileOffset
|
||||||
);
|
);
|
||||||
|
@ -271,9 +268,9 @@ CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosReleaseCacheSegment(
|
CcRosReleaseVacb(
|
||||||
BCB* Bcb,
|
BCB* Bcb,
|
||||||
CACHE_SEGMENT *CacheSeg,
|
PROS_VACB Vacb,
|
||||||
BOOLEAN Valid,
|
BOOLEAN Valid,
|
||||||
BOOLEAN Dirty,
|
BOOLEAN Dirty,
|
||||||
BOOLEAN Mapped
|
BOOLEAN Mapped
|
||||||
|
@ -281,12 +278,12 @@ CcRosReleaseCacheSegment(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRosRequestCacheSegment(
|
CcRosRequestVacb(
|
||||||
BCB *Bcb,
|
BCB *Bcb,
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
PVOID* BaseAddress,
|
PVOID* BaseAddress,
|
||||||
PBOOLEAN UptoDate,
|
PBOOLEAN UptoDate,
|
||||||
CACHE_SEGMENT **CacheSeg
|
PROS_VACB *Vacb
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -309,7 +306,7 @@ CcTryToInitializeFileCache(PFILE_OBJECT FileObject);
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
DoSegmentsIntersect(
|
DoRangesIntersect(
|
||||||
_In_ ULONG Offset1,
|
_In_ ULONG Offset1,
|
||||||
_In_ ULONG Length1,
|
_In_ ULONG Length1,
|
||||||
_In_ ULONG Offset2,
|
_In_ ULONG Offset2,
|
||||||
|
@ -324,10 +321,10 @@ DoSegmentsIntersect(
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
IsPointInSegment(
|
IsPointInRange(
|
||||||
_In_ ULONG Offset1,
|
_In_ ULONG Offset1,
|
||||||
_In_ ULONG Length1,
|
_In_ ULONG Length1,
|
||||||
_In_ ULONG Point)
|
_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;
|
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
IsDirectMapped = TRUE;
|
IsDirectMapped = TRUE;
|
||||||
#ifndef NEWCC
|
#ifndef NEWCC
|
||||||
Status = CcRosUnmapCacheSegment(Bcb, FileOffset.LowPart, Dirty);
|
Status = CcRosUnmapVacb(Bcb, FileOffset.LowPart, Dirty);
|
||||||
#else
|
#else
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("CcRosUnmapCacheSegment failed, status = %x\n", Status);
|
DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status);
|
||||||
KeBugCheck(MEMORY_MANAGEMENT);
|
KeBugCheck(MEMORY_MANAGEMENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1016,12 +1016,12 @@ BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
|
||||||
if (!(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
|
if (!(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
|
||||||
{
|
{
|
||||||
PBCB Bcb;
|
PBCB Bcb;
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PROS_VACB Vacb;
|
||||||
Bcb = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap;
|
Bcb = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
CacheSeg = CcRosLookupCacheSegment(Bcb, (ULONG)(SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset));
|
Vacb = CcRosLookupVacb(Bcb, (ULONG)(SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset));
|
||||||
if (CacheSeg)
|
if (Vacb)
|
||||||
{
|
{
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, CacheSeg->Valid, FALSE, TRUE);
|
CcRosReleaseVacb(Bcb, Vacb, Vacb->Valid, FALSE, TRUE);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1070,7 +1070,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
ULONGLONG FileOffset;
|
ULONGLONG FileOffset;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
BOOLEAN UptoDate;
|
BOOLEAN UptoDate;
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PROS_VACB Vacb;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG_PTR RawLength;
|
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
|
* 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
|
* 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) &&
|
if (((FileOffset % PAGE_SIZE) == 0) &&
|
||||||
((SegOffset + PAGE_SIZE <= RawLength) || !IsImageSection) &&
|
((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
|
* Get the related VACB; we use a lower level interface than
|
||||||
* filesystems do because it is safe for us to use an offset with a
|
* filesystems do because it is safe for us to use an offset with an
|
||||||
* alignment less than the file system block size.
|
* alignment less than the file system block size.
|
||||||
*/
|
*/
|
||||||
Status = CcRosGetCacheSegment(Bcb,
|
Status = CcRosGetVacb(Bcb,
|
||||||
(ULONG)FileOffset,
|
(ULONG)FileOffset,
|
||||||
&BaseOffset,
|
&BaseOffset,
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&UptoDate,
|
&UptoDate,
|
||||||
&CacheSeg);
|
&Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
|
@ -1116,13 +1116,13 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
if (!UptoDate)
|
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.
|
* system to read in the data.
|
||||||
*/
|
*/
|
||||||
Status = ReadCacheSegment(CacheSeg);
|
Status = CcReadVirtualAddress(Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1131,19 +1131,19 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
(void)*((volatile char*)BaseAddress + FileOffset - BaseOffset);
|
(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 +
|
(*Page) = MmGetPhysicalAddress((char*)BaseAddress +
|
||||||
FileOffset - BaseOffset).LowPart >> PAGE_SHIFT;
|
FileOffset - BaseOffset).LowPart >> PAGE_SHIFT;
|
||||||
|
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, TRUE);
|
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
KIRQL Irql;
|
KIRQL Irql;
|
||||||
PVOID PageAddr;
|
PVOID PageAddr;
|
||||||
ULONG_PTR CacheSegOffset;
|
ULONG_PTR VacbOffset;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a page, this is rather complicated by the possibility
|
* Allocate a page, this is rather complicated by the possibility
|
||||||
|
@ -1156,12 +1156,12 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
Status = CcRosGetCacheSegment(Bcb,
|
Status = CcRosGetVacb(Bcb,
|
||||||
(ULONG)FileOffset,
|
(ULONG)FileOffset,
|
||||||
&BaseOffset,
|
&BaseOffset,
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&UptoDate,
|
&UptoDate,
|
||||||
&CacheSeg);
|
&Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
|
@ -1169,40 +1169,40 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
if (!UptoDate)
|
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.
|
* system to read in the data.
|
||||||
*/
|
*/
|
||||||
Status = ReadCacheSegment(CacheSeg);
|
Status = CcReadVirtualAddress(Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process = PsGetCurrentProcess();
|
Process = PsGetCurrentProcess();
|
||||||
PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
|
PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
|
||||||
CacheSegOffset = (ULONG_PTR)(BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset);
|
VacbOffset = (ULONG_PTR)(BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset);
|
||||||
Length = RawLength - SegOffset;
|
Length = RawLength - SegOffset;
|
||||||
if (Length <= CacheSegOffset && Length <= PAGE_SIZE)
|
if (Length <= VacbOffset && Length <= PAGE_SIZE)
|
||||||
{
|
{
|
||||||
memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, Length);
|
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);
|
memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, PAGE_SIZE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, CacheSegOffset);
|
memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, VacbOffset);
|
||||||
MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
|
MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
|
||||||
Status = CcRosGetCacheSegment(Bcb,
|
Status = CcRosGetVacb(Bcb,
|
||||||
(ULONG)(FileOffset + CacheSegOffset),
|
(ULONG)(FileOffset + VacbOffset),
|
||||||
&BaseOffset,
|
&BaseOffset,
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&UptoDate,
|
&UptoDate,
|
||||||
&CacheSeg);
|
&Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
|
@ -1210,28 +1210,28 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
if (!UptoDate)
|
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.
|
* system to read in the data.
|
||||||
*/
|
*/
|
||||||
Status = ReadCacheSegment(CacheSeg);
|
Status = CcReadVirtualAddress(Vacb);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, FALSE, FALSE, FALSE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
|
PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
|
||||||
if (Length < PAGE_SIZE)
|
if (Length < PAGE_SIZE)
|
||||||
{
|
{
|
||||||
memcpy((char*)PageAddr + CacheSegOffset, BaseAddress, Length - CacheSegOffset);
|
memcpy((char*)PageAddr + VacbOffset, BaseAddress, Length - VacbOffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy((char*)PageAddr + CacheSegOffset, BaseAddress, PAGE_SIZE - CacheSegOffset);
|
memcpy((char*)PageAddr + VacbOffset, BaseAddress, PAGE_SIZE - VacbOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
|
MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
|
CcRosReleaseVacb(Bcb, Vacb, TRUE, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
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)
|
if (DirectMapped && !Context.Private)
|
||||||
{
|
{
|
||||||
|
@ -2066,14 +2066,14 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
|
||||||
KeBugCheckEx(MEMORY_MANAGEMENT, STATUS_UNSUCCESSFUL, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address);
|
KeBugCheckEx(MEMORY_MANAGEMENT, STATUS_UNSUCCESSFUL, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address);
|
||||||
}
|
}
|
||||||
#ifndef NEWCC
|
#ifndef NEWCC
|
||||||
Status = CcRosUnmapCacheSegment(Bcb, (ULONG)FileOffset, FALSE);
|
Status = CcRosUnmapVacb(Bcb, (ULONG)FileOffset, FALSE);
|
||||||
#else
|
#else
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
#ifndef NEWCC
|
#ifndef NEWCC
|
||||||
if (!NT_SUCCESS(Status))
|
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);
|
KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Bcb, (ULONG_PTR)FileOffset, (ULONG_PTR)Address);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2366,7 +2366,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
|
||||||
ASSERT(SwapEntry == 0);
|
ASSERT(SwapEntry == 0);
|
||||||
//SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset;
|
//SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset;
|
||||||
#ifndef NEWCC
|
#ifndef NEWCC
|
||||||
CcRosMarkDirtyCacheSegment(Bcb, Offset.LowPart);
|
CcRosMarkDirtyVacb(Bcb, Offset.LowPart);
|
||||||
#endif
|
#endif
|
||||||
MmLockSectionSegment(Segment);
|
MmLockSectionSegment(Segment);
|
||||||
MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry);
|
MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry);
|
||||||
|
@ -4013,7 +4013,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
|
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
|
||||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
#ifndef NEWCC
|
#ifndef NEWCC
|
||||||
CcRosMarkDirtyCacheSegment(Bcb, (ULONG)(Offset.QuadPart + Segment->Image.FileOffset));
|
CcRosMarkDirtyVacb(Bcb, (ULONG)(Offset.QuadPart + Segment->Image.FileOffset));
|
||||||
#endif
|
#endif
|
||||||
ASSERT(SwapEntry == 0);
|
ASSERT(SwapEntry == 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue