[NTOS:CC]

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

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

View file

@ -56,17 +56,17 @@ CcInitCacheZeroPage (
NTSTATUS 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);
} }
} }
} }

View file

@ -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(&current->BcbSegmentListEntry); RemoveEntryList(&current->BcbVacbListEntry);
RemoveEntryList(&current->CacheSegmentListEntry); RemoveEntryList(&current->VacbListEntry);
RemoveEntryList(&current->CacheSegmentLRUListEntry); RemoveEntryList(&current->VacbLruListEntry);
if (current->Dirty) if (current->Dirty)
{ {
RemoveEntryList(&current->DirtySegmentListEntry); RemoveEntryList(&current->DirtyVacbListEntry);
DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE; DirtyPageCount -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
} }
InsertHeadList(&FreeListHead, &current->BcbSegmentListEntry); InsertHeadList(&FreeListHead, &current->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);
} }
} }

View file

@ -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
{ {

View file

@ -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(&current->Mutex, FALSE); KeReleaseMutex(&current->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(&current->Mutex, FALSE); KeReleaseMutex(&current->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(&current->Bcb->BcbLock, &oldIrql); KeAcquireSpinLock(&current->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(&current->Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&current->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(&current->Bcb->BcbLock, &oldIrql); KeAcquireSpinLock(&current->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(&current->BcbSegmentListEntry); RemoveEntryList(&current->BcbVacbListEntry);
RemoveEntryList(&current->CacheSegmentListEntry); RemoveEntryList(&current->VacbListEntry);
RemoveEntryList(&current->CacheSegmentLRUListEntry); RemoveEntryList(&current->VacbLruListEntry);
InsertHeadList(&FreeList, &current->BcbSegmentListEntry); InsertHeadList(&FreeList, &current->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(&current->Mutex, KeWaitForSingleObject(&current->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(&current->Mutex, 0); KeInitializeMutex(&current->Mutex, 0);
KeWaitForSingleObject(&current->Mutex, KeWaitForSingleObject(&current->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(&current->Mutex, KeWaitForSingleObject(&current->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, &current->BcbSegmentListEntry); InsertHeadList(&previous->BcbVacbListEntry, &current->BcbVacbListEntry);
} }
else else
{ {
InsertHeadList(&Bcb->BcbSegmentListHead, &current->BcbSegmentListEntry); InsertHeadList(&Bcb->BcbVacbListHead, &current->BcbVacbListEntry);
} }
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
InsertTailList(&CacheSegmentListHead, &current->CacheSegmentListEntry); InsertTailList(&VacbListHead, &current->VacbListEntry);
InsertTailList(&CacheSegmentLRUListHead, &current->CacheSegmentLRUListEntry); InsertTailList(&VacbLruListHead, &current->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
&current->BaseAddress, &current->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(&current->CacheSegmentLRUListEntry); RemoveEntryList(&current->VacbLruListEntry);
InsertTailList(&CacheSegmentLRUListHead, &current->CacheSegmentLRUListEntry); InsertTailList(&VacbLruListHead, &current->VacbLruListEntry);
KeReleaseGuardedMutex(&ViewLock); KeReleaseGuardedMutex(&ViewLock);
CacheSegList[i] = current; VacbList[i] = current;
} }
else else
{ {
CcRosCreateCacheSegment(Bcb, CurrentOffset, &current); CcRosCreateVacb(Bcb, CurrentOffset, &current);
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, &current); Status = CcRosCreateVacb(Bcb, FileOffset, &current);
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(&current->CacheSegmentLRUListEntry); RemoveEntryList(&current->VacbLruListEntry);
InsertTailList(&CacheSegmentLRUListHead, &current->CacheSegmentLRUListEntry); InsertTailList(&VacbLruListHead, &current->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(&current->CacheSegmentListEntry); RemoveEntryList(&current->VacbListEntry);
RemoveEntryList(&current->CacheSegmentLRUListEntry); RemoveEntryList(&current->VacbLruListEntry);
if (current->Dirty) if (current->Dirty)
{ {
RemoveEntryList(&current->DirtySegmentListEntry); RemoveEntryList(&current->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, &current->BcbSegmentListEntry); InsertHeadList(&FreeList, &current->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);

View file

@ -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);
} }

View file

@ -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);
} }