mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
[FORMATTING]
* Addendum to r56262. svn path=/trunk/; revision=56273
This commit is contained in:
parent
4d61c55638
commit
aabb4465a0
13 changed files with 1259 additions and 1151 deletions
411
reactos/ntoskrnl/cache/cachesub.c
vendored
411
reactos/ntoskrnl/cache/cachesub.c
vendored
|
@ -19,10 +19,10 @@
|
|||
|
||||
typedef struct _WORK_QUEUE_WITH_READ_AHEAD
|
||||
{
|
||||
WORK_QUEUE_ITEM WorkItem;
|
||||
PFILE_OBJECT FileObject;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG Length;
|
||||
WORK_QUEUE_ITEM WorkItem;
|
||||
PFILE_OBJECT FileObject;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG Length;
|
||||
} WORK_QUEUE_WITH_READ_AHEAD, *PWORK_QUEUE_WITH_READ_AHEAD;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
@ -37,52 +37,54 @@ CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject,
|
|||
IN ULONG Granularity)
|
||||
{
|
||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
if (Map)
|
||||
{
|
||||
Map->ReadAheadGranularity = Granularity;
|
||||
}
|
||||
if (Map)
|
||||
{
|
||||
Map->ReadAheadGranularity = Granularity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcpReadAhead(PVOID Context)
|
||||
{
|
||||
LARGE_INTEGER Offset;
|
||||
PWORK_QUEUE_WITH_READ_AHEAD WorkItem = (PWORK_QUEUE_WITH_READ_AHEAD)Context;
|
||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)WorkItem->FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
DPRINT1("Reading ahead %08x%08x:%x %wZ\n",
|
||||
WorkItem->FileOffset.HighPart,
|
||||
WorkItem->FileOffset.LowPart,
|
||||
WorkItem->Length,
|
||||
&WorkItem->FileObject->FileName);
|
||||
Offset.HighPart = WorkItem->FileOffset.HighPart;
|
||||
Offset.LowPart = PAGE_ROUND_DOWN(WorkItem->FileOffset.LowPart);
|
||||
if (Map)
|
||||
{
|
||||
PLIST_ENTRY ListEntry;
|
||||
volatile char *chptr;
|
||||
PNOCC_BCB Bcb;
|
||||
for (ListEntry = Map->AssociatedBcb.Flink;
|
||||
ListEntry != &Map->AssociatedBcb;
|
||||
ListEntry = ListEntry->Flink)
|
||||
{
|
||||
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
||||
if ((Offset.QuadPart + WorkItem->Length < Bcb->FileOffset.QuadPart) ||
|
||||
(Bcb->FileOffset.QuadPart + Bcb->Length < Offset.QuadPart))
|
||||
continue;
|
||||
for (chptr = Bcb->BaseAddress, Offset = Bcb->FileOffset;
|
||||
chptr < ((PCHAR)Bcb->BaseAddress) + Bcb->Length &&
|
||||
Offset.QuadPart <
|
||||
WorkItem->FileOffset.QuadPart + WorkItem->Length;
|
||||
chptr += PAGE_SIZE, Offset.QuadPart += PAGE_SIZE)
|
||||
{
|
||||
*chptr ^= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
ObDereferenceObject(WorkItem->FileObject);
|
||||
ExFreePool(WorkItem);
|
||||
DPRINT("Done\n");
|
||||
LARGE_INTEGER Offset;
|
||||
PWORK_QUEUE_WITH_READ_AHEAD WorkItem = (PWORK_QUEUE_WITH_READ_AHEAD)Context;
|
||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)WorkItem->FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
|
||||
DPRINT1("Reading ahead %08x%08x:%x %wZ\n",
|
||||
WorkItem->FileOffset.HighPart,
|
||||
WorkItem->FileOffset.LowPart,
|
||||
WorkItem->Length,
|
||||
&WorkItem->FileObject->FileName);
|
||||
|
||||
Offset.HighPart = WorkItem->FileOffset.HighPart;
|
||||
Offset.LowPart = PAGE_ROUND_DOWN(WorkItem->FileOffset.LowPart);
|
||||
if (Map)
|
||||
{
|
||||
PLIST_ENTRY ListEntry;
|
||||
volatile char *chptr;
|
||||
PNOCC_BCB Bcb;
|
||||
for (ListEntry = Map->AssociatedBcb.Flink;
|
||||
ListEntry != &Map->AssociatedBcb;
|
||||
ListEntry = ListEntry->Flink)
|
||||
{
|
||||
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
||||
if ((Offset.QuadPart + WorkItem->Length < Bcb->FileOffset.QuadPart) ||
|
||||
(Bcb->FileOffset.QuadPart + Bcb->Length < Offset.QuadPart))
|
||||
continue;
|
||||
for (chptr = Bcb->BaseAddress, Offset = Bcb->FileOffset;
|
||||
chptr < ((PCHAR)Bcb->BaseAddress) + Bcb->Length &&
|
||||
Offset.QuadPart <
|
||||
WorkItem->FileOffset.QuadPart + WorkItem->Length;
|
||||
chptr += PAGE_SIZE, Offset.QuadPart += PAGE_SIZE)
|
||||
{
|
||||
*chptr ^= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
ObDereferenceObject(WorkItem->FileObject);
|
||||
ExFreePool(WorkItem);
|
||||
DPRINT("Done\n");
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -91,30 +93,36 @@ CcScheduleReadAhead(IN PFILE_OBJECT FileObject,
|
|||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length)
|
||||
{
|
||||
PWORK_QUEUE_WITH_READ_AHEAD WorkItem;
|
||||
DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
|
||||
FileOffset->HighPart,
|
||||
FileOffset->LowPart,
|
||||
Length,
|
||||
&FileObject->FileName);
|
||||
WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem));
|
||||
if (!WorkItem) KeBugCheck(0);
|
||||
ObReferenceObject(FileObject);
|
||||
WorkItem->FileObject = FileObject;
|
||||
WorkItem->FileOffset = *FileOffset;
|
||||
WorkItem->Length = Length;
|
||||
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpReadAhead, WorkItem);
|
||||
ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
|
||||
DPRINT("Done\n");
|
||||
PWORK_QUEUE_WITH_READ_AHEAD WorkItem;
|
||||
|
||||
DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
|
||||
FileOffset->HighPart,
|
||||
FileOffset->LowPart,
|
||||
Length,
|
||||
&FileObject->FileName);
|
||||
|
||||
WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem));
|
||||
if (!WorkItem) KeBugCheck(0);
|
||||
ObReferenceObject(FileObject);
|
||||
WorkItem->FileObject = FileObject;
|
||||
WorkItem->FileOffset = *FileOffset;
|
||||
WorkItem->Length = Length;
|
||||
|
||||
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem),
|
||||
(PWORKER_THREAD_ROUTINE)CcpReadAhead,
|
||||
WorkItem);
|
||||
|
||||
ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
|
||||
DPRINT("Done\n");
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcSetDirtyPinnedData(IN PVOID BcbVoid,
|
||||
IN OPTIONAL PLARGE_INTEGER Lsn)
|
||||
{
|
||||
PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid;
|
||||
Bcb->Dirty = TRUE;
|
||||
PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid;
|
||||
Bcb->Dirty = TRUE;
|
||||
}
|
||||
|
||||
LARGE_INTEGER
|
||||
|
@ -128,81 +136,85 @@ CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
|||
return Result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
_CcpFlushCache(IN PNOCC_CACHE_MAP Map,
|
||||
IN OPTIONAL PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
|
||||
BOOLEAN Delete,
|
||||
const char *File,
|
||||
int Line)
|
||||
IN OPTIONAL PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
|
||||
BOOLEAN Delete,
|
||||
const char *File,
|
||||
int Line)
|
||||
{
|
||||
PNOCC_BCB Bcb = NULL;
|
||||
LARGE_INTEGER LowerBound, UpperBound;
|
||||
PLIST_ENTRY ListEntry;
|
||||
IO_STATUS_BLOCK IOSB;
|
||||
LARGE_INTEGER LowerBound, UpperBound;
|
||||
PLIST_ENTRY ListEntry;
|
||||
IO_STATUS_BLOCK IOSB;
|
||||
|
||||
RtlZeroMemory(&IOSB, sizeof(IO_STATUS_BLOCK));
|
||||
RtlZeroMemory(&IOSB, sizeof(IO_STATUS_BLOCK));
|
||||
|
||||
DPRINT("CcFlushCache (while file) (%s:%d)\n", File, Line);
|
||||
DPRINT("CcFlushCache (while file) (%s:%d)\n", File, Line);
|
||||
|
||||
if (FileOffset && Length)
|
||||
{
|
||||
LowerBound.QuadPart = FileOffset->QuadPart;
|
||||
UpperBound.QuadPart = LowerBound.QuadPart + Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
LowerBound.QuadPart = 0;
|
||||
UpperBound.QuadPart = 0x7fffffffffffffffull;
|
||||
}
|
||||
if (FileOffset && Length)
|
||||
{
|
||||
LowerBound.QuadPart = FileOffset->QuadPart;
|
||||
UpperBound.QuadPart = LowerBound.QuadPart + Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
LowerBound.QuadPart = 0;
|
||||
UpperBound.QuadPart = 0x7fffffffffffffffull;
|
||||
}
|
||||
|
||||
CcpLock();
|
||||
ListEntry = Map->AssociatedBcb.Flink;
|
||||
CcpLock();
|
||||
ListEntry = Map->AssociatedBcb.Flink;
|
||||
|
||||
while (ListEntry != &Map->AssociatedBcb)
|
||||
{
|
||||
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
||||
CcpReferenceCache((ULONG)(Bcb - CcCacheSections));
|
||||
while (ListEntry != &Map->AssociatedBcb)
|
||||
{
|
||||
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
||||
CcpReferenceCache((ULONG)(Bcb - CcCacheSections));
|
||||
|
||||
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
|
||||
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
|
||||
{
|
||||
DPRINT
|
||||
("Bcb #%x (@%08x%08x)\n",
|
||||
Bcb - CcCacheSections,
|
||||
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
|
||||
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
|
||||
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
|
||||
{
|
||||
DPRINT("Bcb #%x (@%08x%08x)\n",
|
||||
Bcb - CcCacheSections,
|
||||
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
|
||||
|
||||
Bcb->RefCount++;
|
||||
CcpUnlock();
|
||||
MiFlushMappedSection(Bcb->BaseAddress, &Bcb->FileOffset, &Map->FileSizes.FileSize, Bcb->Dirty);
|
||||
CcpLock();
|
||||
Bcb->RefCount--;
|
||||
Bcb->RefCount++;
|
||||
CcpUnlock();
|
||||
MiFlushMappedSection(Bcb->BaseAddress,
|
||||
&Bcb->FileOffset,
|
||||
&Map->FileSizes.FileSize,
|
||||
Bcb->Dirty);
|
||||
CcpLock();
|
||||
Bcb->RefCount--;
|
||||
|
||||
Bcb->Dirty = FALSE;
|
||||
|
||||
ListEntry = ListEntry->Flink;
|
||||
if (Delete && Bcb->RefCount < 2)
|
||||
{
|
||||
Bcb->RefCount = 1;
|
||||
CcpDereferenceCache((ULONG)(Bcb - CcCacheSections), FALSE);
|
||||
}
|
||||
else
|
||||
CcpUnpinData(Bcb, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ListEntry = ListEntry->Flink;
|
||||
CcpUnpinData(Bcb, TRUE);
|
||||
}
|
||||
Bcb->Dirty = FALSE;
|
||||
|
||||
ListEntry = ListEntry->Flink;
|
||||
if (Delete && Bcb->RefCount < 2)
|
||||
{
|
||||
Bcb->RefCount = 1;
|
||||
CcpDereferenceCache((ULONG)(Bcb - CcCacheSections), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
CcpUnpinData(Bcb, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ListEntry = ListEntry->Flink;
|
||||
CcpUnpinData(Bcb, TRUE);
|
||||
}
|
||||
|
||||
DPRINT("End loop\n");
|
||||
}
|
||||
CcpUnlock();
|
||||
|
||||
DPRINT("End loop\n");
|
||||
}
|
||||
CcpUnlock();
|
||||
|
||||
if (IoStatus) *IoStatus = IOSB;
|
||||
}
|
||||
|
||||
|
@ -215,25 +227,24 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
|||
{
|
||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
||||
|
||||
// Not cached
|
||||
if (!Map)
|
||||
{
|
||||
if (IoStatus)
|
||||
{
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
IoStatus->Information = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Not cached */
|
||||
if (!Map)
|
||||
{
|
||||
if (IoStatus)
|
||||
{
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
IoStatus->Information = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CcpFlushCache(Map, FileOffset, Length, IoStatus, TRUE);
|
||||
CcpFlushCache(Map, FileOffset, Length, IoStatus, TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CcFlushImageSection
|
||||
(PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||
MMFLUSH_TYPE FlushType)
|
||||
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||
MMFLUSH_TYPE FlushType)
|
||||
{
|
||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
||||
PNOCC_BCB Bcb;
|
||||
|
@ -241,93 +252,91 @@ CcFlushImageSection
|
|||
IO_STATUS_BLOCK IOSB;
|
||||
BOOLEAN Result = TRUE;
|
||||
|
||||
if (!Map) return TRUE;
|
||||
|
||||
if (!Map) return TRUE;
|
||||
|
||||
for (Entry = Map->AssociatedBcb.Flink;
|
||||
Entry != &Map->AssociatedBcb;
|
||||
Entry = Entry->Flink)
|
||||
Entry != &Map->AssociatedBcb;
|
||||
Entry = Entry->Flink)
|
||||
{
|
||||
Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
|
||||
Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
|
||||
|
||||
if (!Bcb->Dirty) continue;
|
||||
if (!Bcb->Dirty) continue;
|
||||
|
||||
switch (FlushType)
|
||||
{
|
||||
case MmFlushForDelete:
|
||||
CcPurgeCacheSection
|
||||
(SectionObjectPointer,
|
||||
&Bcb->FileOffset,
|
||||
Bcb->Length,
|
||||
FALSE);
|
||||
break;
|
||||
case MmFlushForWrite:
|
||||
CcFlushCache
|
||||
(SectionObjectPointer,
|
||||
&Bcb->FileOffset,
|
||||
Bcb->Length,
|
||||
&IOSB);
|
||||
break;
|
||||
}
|
||||
switch (FlushType)
|
||||
{
|
||||
case MmFlushForDelete:
|
||||
CcPurgeCacheSection(SectionObjectPointer,
|
||||
&Bcb->FileOffset,
|
||||
Bcb->Length,
|
||||
FALSE);
|
||||
break;
|
||||
case MmFlushForWrite:
|
||||
CcFlushCache(SectionObjectPointer,
|
||||
&Bcb->FileOffset,
|
||||
Bcb->Length,
|
||||
&IOSB);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Always succeeds for us
|
||||
/* Always succeeds for us */
|
||||
PVOID
|
||||
NTAPI
|
||||
CcRemapBcb(IN PVOID Bcb)
|
||||
{
|
||||
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
|
||||
CcpLock();
|
||||
ASSERT(RtlTestBit(CcCacheBitmap, Number));
|
||||
CcpReferenceCache(Number);
|
||||
CcpUnlock();
|
||||
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
|
||||
CcpLock();
|
||||
ASSERT(RtlTestBit(CcCacheBitmap, Number));
|
||||
CcpReferenceCache(Number);
|
||||
CcpUnlock();
|
||||
return Bcb;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcShutdownSystem()
|
||||
CcShutdownSystem(VOID)
|
||||
{
|
||||
ULONG i, Result;
|
||||
NTSTATUS Status;
|
||||
ULONG i, Result;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1("CC: Shutdown\n");
|
||||
DPRINT1("CC: Shutdown\n");
|
||||
|
||||
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
|
||||
{
|
||||
PNOCC_BCB Bcb = &CcCacheSections[i];
|
||||
if (Bcb->SectionObject)
|
||||
{
|
||||
DPRINT1
|
||||
("Evicting #%02x %08x%08x %wZ\n",
|
||||
i,
|
||||
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart,
|
||||
&MmGetFileObjectForSection
|
||||
((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName);
|
||||
CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE);
|
||||
Bcb->Dirty = FALSE;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
|
||||
{
|
||||
PNOCC_BCB Bcb = &CcCacheSections[i];
|
||||
if (Bcb->SectionObject)
|
||||
{
|
||||
DPRINT1("Evicting #%02x %08x%08x %wZ\n",
|
||||
i,
|
||||
Bcb->FileOffset.u.HighPart,
|
||||
Bcb->FileOffset.u.LowPart,
|
||||
&MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName);
|
||||
|
||||
// Evict all section pages
|
||||
Status = MiRosTrimCache(~0, 0, &Result);
|
||||
CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE);
|
||||
Bcb->Dirty = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT1("Done (Evicted %d, Status %x)\n", Result, Status);
|
||||
/* Evict all section pages */
|
||||
Status = MiRosTrimCache(~0, 0, &Result);
|
||||
|
||||
DPRINT1("Done (Evicted %d, Status %x)\n", Result, Status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcRepinBcb(IN PVOID Bcb)
|
||||
{
|
||||
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
|
||||
CcpLock();
|
||||
ASSERT(RtlTestBit(CcCacheBitmap, Number));
|
||||
DPRINT("CcRepinBcb(#%x)\n", Number);
|
||||
CcpReferenceCache(Number);
|
||||
CcpUnlock();
|
||||
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
|
||||
CcpLock();
|
||||
ASSERT(RtlTestBit(CcCacheBitmap, Number));
|
||||
DPRINT("CcRepinBcb(#%x)\n", Number);
|
||||
CcpReferenceCache(Number);
|
||||
CcpUnlock();
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -340,13 +349,13 @@ CcUnpinRepinnedBcb(IN PVOID Bcb,
|
|||
|
||||
if (WriteThrough)
|
||||
{
|
||||
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
|
||||
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
|
||||
|
||||
CcpFlushCache
|
||||
(RealBcb->Map,
|
||||
&RealBcb->FileOffset,
|
||||
RealBcb->Length,
|
||||
IoStatus, RealBcb->Dirty);
|
||||
CcpFlushCache(RealBcb->Map,
|
||||
&RealBcb->FileOffset,
|
||||
RealBcb->Length,
|
||||
IoStatus,
|
||||
RealBcb->Dirty);
|
||||
}
|
||||
|
||||
CcUnpinData(Bcb);
|
||||
|
|
202
reactos/ntoskrnl/cache/copysup.c
vendored
202
reactos/ntoskrnl/cache/copysup.c
vendored
|
@ -52,61 +52,63 @@ CcCopyRead(IN PFILE_OBJECT FileObject,
|
|||
PVOID Bcb;
|
||||
PCHAR BufferTarget = (PCHAR)Buffer;
|
||||
LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
|
||||
|
||||
DPRINT
|
||||
("CcCopyRead(%x,%x,%d,%d,%x)\n",
|
||||
FileObject,
|
||||
FileOffset->LowPart,
|
||||
Length,
|
||||
Wait,
|
||||
Buffer);
|
||||
|
||||
|
||||
DPRINT("CcCopyRead(%x,%x,%d,%d,%x)\n",
|
||||
FileObject,
|
||||
FileOffset->LowPart,
|
||||
Length,
|
||||
Wait,
|
||||
Buffer);
|
||||
|
||||
CacheOffset.QuadPart = FileOffset->QuadPart;
|
||||
EndOfExtent.QuadPart = FileOffset->QuadPart + Length;
|
||||
|
||||
while (CacheOffset.QuadPart < EndOfExtent.QuadPart)
|
||||
{
|
||||
NextOffset.QuadPart = CacheOffset.QuadPart;
|
||||
NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
|
||||
ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
|
||||
if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
|
||||
{
|
||||
ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
|
||||
}
|
||||
|
||||
DPRINT("Reading %d bytes in this go (at %08x%08x)\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
|
||||
|
||||
if (!CcPinRead
|
||||
(FileObject,
|
||||
&CacheOffset,
|
||||
ReadLen,
|
||||
Wait ? PIN_WAIT : PIN_IF_BCB,
|
||||
&Bcb,
|
||||
(PVOID*)&ReadBuffer))
|
||||
{
|
||||
IoStatus->Status = STATUS_UNSUCCESSFUL;
|
||||
IoStatus->Information = 0;
|
||||
DPRINT("Failed CcCopyRead\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DPRINT("Copying %d bytes at %08x%08x\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
|
||||
RtlCopyMemory
|
||||
(BufferTarget,
|
||||
ReadBuffer,
|
||||
ReadLen);
|
||||
|
||||
BufferTarget += ReadLen;
|
||||
|
||||
CacheOffset = NextOffset;
|
||||
CcUnpinData(Bcb);
|
||||
NextOffset.QuadPart = CacheOffset.QuadPart;
|
||||
NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
|
||||
ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
|
||||
if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
|
||||
{
|
||||
ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
|
||||
}
|
||||
|
||||
DPRINT("Reading %d bytes in this go (at %08x%08x)\n",
|
||||
ReadLen,
|
||||
CacheOffset.HighPart,
|
||||
CacheOffset.LowPart);
|
||||
|
||||
if (!CcPinRead(FileObject,
|
||||
&CacheOffset,
|
||||
ReadLen,
|
||||
Wait ? PIN_WAIT : PIN_IF_BCB,
|
||||
&Bcb,
|
||||
(PVOID*)&ReadBuffer))
|
||||
{
|
||||
IoStatus->Status = STATUS_UNSUCCESSFUL;
|
||||
IoStatus->Information = 0;
|
||||
DPRINT("Failed CcCopyRead\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DPRINT("Copying %d bytes at %08x%08x\n",
|
||||
ReadLen,
|
||||
CacheOffset.HighPart,
|
||||
CacheOffset.LowPart);
|
||||
|
||||
RtlCopyMemory(BufferTarget, ReadBuffer, ReadLen);
|
||||
|
||||
BufferTarget += ReadLen;
|
||||
|
||||
CacheOffset = NextOffset;
|
||||
CcUnpinData(Bcb);
|
||||
}
|
||||
|
||||
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
IoStatus->Information = Length;
|
||||
|
||||
|
||||
DPRINT("Done with CcCopyRead\n");
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -131,58 +133,72 @@ CcCopyWrite(IN PFILE_OBJECT FileObject,
|
|||
IN BOOLEAN Wait,
|
||||
IN PVOID Buffer)
|
||||
{
|
||||
INT Count = 0;
|
||||
BOOLEAN Result;
|
||||
PNOCC_BCB Bcb;
|
||||
PVOID WriteBuf;
|
||||
ULONG WriteLen;
|
||||
LARGE_INTEGER CurrentOffset = *FileOffset;
|
||||
LARGE_INTEGER EndOffset;
|
||||
LARGE_INTEGER NextOffset;
|
||||
INT Count = 0;
|
||||
BOOLEAN Result;
|
||||
PNOCC_BCB Bcb;
|
||||
PVOID WriteBuf;
|
||||
ULONG WriteLen;
|
||||
LARGE_INTEGER CurrentOffset = *FileOffset;
|
||||
LARGE_INTEGER EndOffset;
|
||||
LARGE_INTEGER NextOffset;
|
||||
|
||||
EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
|
||||
EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
|
||||
|
||||
DPRINT
|
||||
("CcCopyWrite(%x,%x,%d,%d,%x)\n",
|
||||
FileObject,
|
||||
FileOffset->LowPart,
|
||||
Length,
|
||||
Wait,
|
||||
Buffer);
|
||||
DPRINT("CcCopyWrite(%x,%x,%d,%d,%x)\n",
|
||||
FileObject,
|
||||
FileOffset->LowPart,
|
||||
Length,
|
||||
Wait,
|
||||
Buffer);
|
||||
|
||||
while (CurrentOffset.QuadPart < EndOffset.QuadPart)
|
||||
{
|
||||
NextOffset.HighPart = CurrentOffset.HighPart;
|
||||
NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
|
||||
DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
|
||||
WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
|
||||
DPRINT("Copying %x bytes from %08x%08x\n",
|
||||
WriteLen,
|
||||
CurrentOffset.u.HighPart, CurrentOffset.u.LowPart);
|
||||
DPRINT("CcPreparePinWrite\n");
|
||||
Result = CcPreparePinWrite
|
||||
(FileObject, &CurrentOffset, WriteLen, FALSE, Wait ? PIN_WAIT : PIN_IF_BCB,
|
||||
(PVOID *)&Bcb, &WriteBuf);
|
||||
DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
|
||||
if (!Result)
|
||||
{
|
||||
DPRINT1("CcPreparePinWrite Failed?\n");
|
||||
if (Wait) RtlRaiseStatus(STATUS_NOT_MAPPED_DATA); else return FALSE;
|
||||
}
|
||||
DPRINT("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n", Bcb - CcCacheSections, WriteBuf, Bcb->BaseAddress);
|
||||
|
||||
//MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
|
||||
RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
|
||||
Count += WriteLen;
|
||||
Length -= WriteLen;
|
||||
CurrentOffset = NextOffset;
|
||||
Bcb->Dirty = TRUE;
|
||||
CcUnpinData(Bcb);
|
||||
}
|
||||
while (CurrentOffset.QuadPart < EndOffset.QuadPart)
|
||||
{
|
||||
NextOffset.HighPart = CurrentOffset.HighPart;
|
||||
NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
|
||||
DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
|
||||
WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
|
||||
|
||||
DPRINT("Done with CcCopyWrite\n");
|
||||
DPRINT("Copying %x bytes from %08x%08x\n",
|
||||
WriteLen,
|
||||
CurrentOffset.u.HighPart,
|
||||
CurrentOffset.u.LowPart);
|
||||
|
||||
return TRUE;
|
||||
DPRINT("CcPreparePinWrite\n");
|
||||
|
||||
Result = CcPreparePinWrite(FileObject,
|
||||
&CurrentOffset,
|
||||
WriteLen,
|
||||
FALSE,
|
||||
Wait ? PIN_WAIT : PIN_IF_BCB,
|
||||
(PVOID *)&Bcb, &WriteBuf);
|
||||
|
||||
DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
|
||||
if (!Result)
|
||||
{
|
||||
DPRINT1("CcPreparePinWrite Failed?\n");
|
||||
if (Wait)
|
||||
RtlRaiseStatus(STATUS_NOT_MAPPED_DATA);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DPRINT("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n",
|
||||
Bcb - CcCacheSections,
|
||||
WriteBuf,
|
||||
Bcb->BaseAddress);
|
||||
|
||||
//MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
|
||||
RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
|
||||
Count += WriteLen;
|
||||
Length -= WriteLen;
|
||||
CurrentOffset = NextOffset;
|
||||
Bcb->Dirty = TRUE;
|
||||
CcUnpinData(Bcb);
|
||||
}
|
||||
|
||||
DPRINT("Done with CcCopyWrite\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
631
reactos/ntoskrnl/cache/fssup.c
vendored
631
reactos/ntoskrnl/cache/fssup.c
vendored
|
@ -27,9 +27,9 @@ HANDLE CcUnmapThreadHandle, CcLazyWriteThreadHandle;
|
|||
CLIENT_ID CcUnmapThreadId, CcLazyWriteThreadId;
|
||||
FAST_MUTEX GlobalPageOperation;
|
||||
|
||||
/*
|
||||
/*
|
||||
|
||||
A note about private cache maps.
|
||||
A note about private cache maps.
|
||||
|
||||
CcInitializeCacheMap and CcUninitializeCacheMap are not meant to be paired,
|
||||
although they can work that way.
|
||||
|
@ -40,7 +40,7 @@ and real filesystems is this:
|
|||
CcInitializeCacheMap means:
|
||||
|
||||
Make the indicated FILE_OBJECT have a private cache map if it doesn't already
|
||||
and make it have a shared cache map if it doesn't already.
|
||||
and make it have a shared cache map if it doesn't already.
|
||||
|
||||
CcUninitializeCacheMap means:
|
||||
|
||||
|
@ -52,7 +52,7 @@ flusing all cached information.
|
|||
Using these simple semantics, filesystems can do all the things they actually
|
||||
do:
|
||||
|
||||
- Copy out the shared cache map pointer from a newly initialized file object
|
||||
- Copy out the shared cache map pointer from a newly initialized file object
|
||||
and store it in the fcb cache.
|
||||
- Copy it back into any file object and call CcInitializeCacheMap to make
|
||||
that file object be associated with the caching of all the other siblings.
|
||||
|
@ -68,9 +68,9 @@ what shared cache map it associates with.
|
|||
*/
|
||||
typedef struct _NOCC_PRIVATE_CACHE_MAP
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
PFILE_OBJECT FileObject;
|
||||
PNOCC_CACHE_MAP Map;
|
||||
LIST_ENTRY ListEntry;
|
||||
PFILE_OBJECT FileObject;
|
||||
PNOCC_CACHE_MAP Map;
|
||||
} NOCC_PRIVATE_CACHE_MAP, *PNOCC_PRIVATE_CACHE_MAP;
|
||||
|
||||
LIST_ENTRY CcpAllSharedCacheMaps;
|
||||
|
@ -81,25 +81,28 @@ BOOLEAN
|
|||
NTAPI
|
||||
CcInitializeCacheManager(VOID)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
DPRINT("Initialize\n");
|
||||
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
|
||||
{
|
||||
KeInitializeEvent(&CcCacheSections[i].ExclusiveWait, SynchronizationEvent, FALSE);
|
||||
InitializeListHead(&CcCacheSections[i].ThisFileList);
|
||||
}
|
||||
DPRINT("Initialize\n");
|
||||
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
|
||||
{
|
||||
KeInitializeEvent(&CcCacheSections[i].ExclusiveWait,
|
||||
SynchronizationEvent,
|
||||
FALSE);
|
||||
|
||||
InitializeListHead(&CcpAllSharedCacheMaps);
|
||||
InitializeListHead(&CcCacheSections[i].ThisFileList);
|
||||
}
|
||||
|
||||
KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
|
||||
KeInitializeEvent(&CcFinalizeEvent, SynchronizationEvent, FALSE);
|
||||
KeInitializeEvent(&CcpLazyWriteEvent, SynchronizationEvent, FALSE);
|
||||
InitializeListHead(&CcpAllSharedCacheMaps);
|
||||
|
||||
CcCacheBitmap->Buffer = ((PULONG)&CcCacheBitmap[1]);
|
||||
CcCacheBitmap->SizeOfBitMap = ROUND_UP(CACHE_NUM_SECTIONS, 32);
|
||||
DPRINT1("Cache has %d entries\n", CcCacheBitmap->SizeOfBitMap);
|
||||
ExInitializeFastMutex(&CcMutex);
|
||||
KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
|
||||
KeInitializeEvent(&CcFinalizeEvent, SynchronizationEvent, FALSE);
|
||||
KeInitializeEvent(&CcpLazyWriteEvent, SynchronizationEvent, FALSE);
|
||||
|
||||
CcCacheBitmap->Buffer = ((PULONG)&CcCacheBitmap[1]);
|
||||
CcCacheBitmap->SizeOfBitMap = ROUND_UP(CACHE_NUM_SECTIONS, 32);
|
||||
DPRINT1("Cache has %d entries\n", CcCacheBitmap->SizeOfBitMap);
|
||||
ExInitializeFastMutex(&CcMutex);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -125,16 +128,16 @@ BOOLEAN
|
|||
NTAPI
|
||||
CcpAcquireFileLock(PNOCC_CACHE_MAP Map)
|
||||
{
|
||||
DPRINT("Calling AcquireForLazyWrite: %x\n", Map->LazyContext);
|
||||
return Map->Callbacks.AcquireForLazyWrite(Map->LazyContext, TRUE);
|
||||
DPRINT("Calling AcquireForLazyWrite: %x\n", Map->LazyContext);
|
||||
return Map->Callbacks.AcquireForLazyWrite(Map->LazyContext, TRUE);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcpReleaseFileLock(PNOCC_CACHE_MAP Map)
|
||||
{
|
||||
DPRINT("Releasing Lazy Write %x\n", Map->LazyContext);
|
||||
Map->Callbacks.ReleaseFromLazyWrite(Map->LazyContext);
|
||||
DPRINT("Releasing Lazy Write %x\n", Map->LazyContext);
|
||||
Map->Callbacks.ReleaseFromLazyWrite(Map->LazyContext);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -150,37 +153,41 @@ a stream file object and a sibling file object in the file object struct
|
|||
itself.
|
||||
|
||||
*/
|
||||
// Must have CcpLock()
|
||||
|
||||
/* Must have CcpLock() */
|
||||
PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject)
|
||||
{
|
||||
PLIST_ENTRY Entry, Private;
|
||||
for (Entry = CcpAllSharedCacheMaps.Flink;
|
||||
Entry != &CcpAllSharedCacheMaps;
|
||||
Entry = Entry->Flink)
|
||||
{
|
||||
// 'Identical' test for other stream file object
|
||||
PNOCC_CACHE_MAP Map = CONTAINING_RECORD(Entry, NOCC_CACHE_MAP, Entry);
|
||||
for (Private = Map->PrivateCacheMaps.Flink;
|
||||
Private != &Map->PrivateCacheMaps;
|
||||
Private = Private->Flink)
|
||||
{
|
||||
PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private, NOCC_PRIVATE_CACHE_MAP, ListEntry);
|
||||
if (PrivateMap->FileObject->Flags & FO_STREAM_FILE &&
|
||||
PrivateMap->FileObject->DeviceObject == FileObject->DeviceObject &&
|
||||
PrivateMap->FileObject->Vpb == FileObject->Vpb &&
|
||||
PrivateMap->FileObject->FsContext == FileObject->FsContext &&
|
||||
PrivateMap->FileObject->FsContext2 == FileObject->FsContext2 &&
|
||||
1)
|
||||
{
|
||||
return PrivateMap->FileObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
PLIST_ENTRY Entry, Private;
|
||||
for (Entry = CcpAllSharedCacheMaps.Flink;
|
||||
Entry != &CcpAllSharedCacheMaps;
|
||||
Entry = Entry->Flink)
|
||||
{
|
||||
/* 'Identical' test for other stream file object */
|
||||
PNOCC_CACHE_MAP Map = CONTAINING_RECORD(Entry, NOCC_CACHE_MAP, Entry);
|
||||
for (Private = Map->PrivateCacheMaps.Flink;
|
||||
Private != &Map->PrivateCacheMaps;
|
||||
Private = Private->Flink)
|
||||
{
|
||||
PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private,
|
||||
NOCC_PRIVATE_CACHE_MAP,
|
||||
ListEntry);
|
||||
|
||||
if (PrivateMap->FileObject->Flags & FO_STREAM_FILE &&
|
||||
PrivateMap->FileObject->DeviceObject == FileObject->DeviceObject &&
|
||||
PrivateMap->FileObject->Vpb == FileObject->Vpb &&
|
||||
PrivateMap->FileObject->FsContext == FileObject->FsContext &&
|
||||
PrivateMap->FileObject->FsContext2 == FileObject->FsContext2 &&
|
||||
1)
|
||||
{
|
||||
return PrivateMap->FileObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Thanks: http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html
|
||||
|
||||
/* Thanks: http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html */
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
|
||||
|
@ -189,55 +196,64 @@ CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
|
|||
IN PCACHE_MANAGER_CALLBACKS Callbacks,
|
||||
IN PVOID LazyWriteContext)
|
||||
{
|
||||
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
|
||||
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
|
||||
|
||||
CcpLock();
|
||||
/* We don't have a shared cache map. First find out if we have a sibling
|
||||
stream file object we can take it from. */
|
||||
if (!Map && FileObject->Flags & FO_STREAM_FILE)
|
||||
{
|
||||
PFILE_OBJECT IdenticalStreamFileObject =
|
||||
CcpFindOtherStreamFileObject(FileObject);
|
||||
if (IdenticalStreamFileObject)
|
||||
Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
|
||||
if (Map)
|
||||
{
|
||||
DPRINT1
|
||||
("Linking SFO %x to previous SFO %x through cache map %x #\n",
|
||||
FileObject, IdenticalStreamFileObject, Map);
|
||||
}
|
||||
}
|
||||
if (!Map && FileObject->Flags & FO_STREAM_FILE)
|
||||
{
|
||||
PFILE_OBJECT IdenticalStreamFileObject = CcpFindOtherStreamFileObject(FileObject);
|
||||
if (IdenticalStreamFileObject)
|
||||
Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
|
||||
if (Map)
|
||||
{
|
||||
DPRINT1("Linking SFO %x to previous SFO %x through cache map %x #\n",
|
||||
FileObject,
|
||||
IdenticalStreamFileObject,
|
||||
Map);
|
||||
}
|
||||
}
|
||||
/* We still don't have a shared cache map. We need to create one. */
|
||||
if (!Map)
|
||||
{
|
||||
DPRINT("Initializing file object for (%p) %wZ\n", FileObject, &FileObject->FileName);
|
||||
Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
|
||||
FileObject->SectionObjectPointer->SharedCacheMap = Map;
|
||||
Map->FileSizes = *FileSizes;
|
||||
Map->LazyContext = LazyWriteContext;
|
||||
Map->ReadAheadGranularity = PAGE_SIZE;
|
||||
RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));
|
||||
// For now ...
|
||||
DPRINT("FileSizes->ValidDataLength %08x%08x\n", FileSizes->ValidDataLength.HighPart, FileSizes->ValidDataLength.LowPart);
|
||||
InitializeListHead(&Map->AssociatedBcb);
|
||||
InitializeListHead(&Map->PrivateCacheMaps);
|
||||
InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry);
|
||||
DPRINT("New Map %x\n", Map);
|
||||
DPRINT("Initializing file object for (%p) %wZ\n",
|
||||
FileObject,
|
||||
&FileObject->FileName);
|
||||
|
||||
Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
|
||||
FileObject->SectionObjectPointer->SharedCacheMap = Map;
|
||||
Map->FileSizes = *FileSizes;
|
||||
Map->LazyContext = LazyWriteContext;
|
||||
Map->ReadAheadGranularity = PAGE_SIZE;
|
||||
RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));
|
||||
|
||||
/* For now ... */
|
||||
DPRINT("FileSizes->ValidDataLength %08x%08x\n",
|
||||
FileSizes->ValidDataLength.HighPart,
|
||||
FileSizes->ValidDataLength.LowPart);
|
||||
|
||||
InitializeListHead(&Map->AssociatedBcb);
|
||||
InitializeListHead(&Map->PrivateCacheMaps);
|
||||
InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry);
|
||||
DPRINT("New Map %x\n", Map);
|
||||
}
|
||||
/* We don't have a private cache map. Link it with the shared cache map
|
||||
to serve as a held reference. When the list in the shared cache map
|
||||
is empty, we know we can delete it. */
|
||||
if (!PrivateCacheMap)
|
||||
{
|
||||
PrivateCacheMap = ExAllocatePool(NonPagedPool, sizeof(*PrivateCacheMap));
|
||||
FileObject->PrivateCacheMap = PrivateCacheMap;
|
||||
PrivateCacheMap->FileObject = FileObject;
|
||||
ObReferenceObject(PrivateCacheMap->FileObject);
|
||||
}
|
||||
if (!PrivateCacheMap)
|
||||
{
|
||||
PrivateCacheMap = ExAllocatePool(NonPagedPool,
|
||||
sizeof(*PrivateCacheMap));
|
||||
|
||||
PrivateCacheMap->Map = Map;
|
||||
InsertTailList(&Map->PrivateCacheMaps, &PrivateCacheMap->ListEntry);
|
||||
FileObject->PrivateCacheMap = PrivateCacheMap;
|
||||
PrivateCacheMap->FileObject = FileObject;
|
||||
ObReferenceObject(PrivateCacheMap->FileObject);
|
||||
}
|
||||
|
||||
PrivateCacheMap->Map = Map;
|
||||
InsertTailList(&Map->PrivateCacheMaps, &PrivateCacheMap->ListEntry);
|
||||
|
||||
CcpUnlock();
|
||||
}
|
||||
|
@ -254,12 +270,14 @@ ULONG
|
|||
NTAPI
|
||||
CcpCountCacheSections(IN PNOCC_CACHE_MAP Map)
|
||||
{
|
||||
PLIST_ENTRY Entry;
|
||||
ULONG Count;
|
||||
PLIST_ENTRY Entry;
|
||||
ULONG Count;
|
||||
|
||||
for (Count = 0, Entry = Map->AssociatedBcb.Flink; Entry != &Map->AssociatedBcb; Entry = Entry->Flink, Count++);
|
||||
for (Count = 0, Entry = Map->AssociatedBcb.Flink;
|
||||
Entry != &Map->AssociatedBcb;
|
||||
Entry = Entry->Flink, Count++);
|
||||
|
||||
return Count;
|
||||
return Count;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
|
@ -268,59 +286,63 @@ CcUninitializeCacheMap(IN PFILE_OBJECT FileObject,
|
|||
IN OPTIONAL PLARGE_INTEGER TruncateSize,
|
||||
IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
|
||||
{
|
||||
BOOLEAN LastMap = FALSE;
|
||||
BOOLEAN LastMap = FALSE;
|
||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
|
||||
|
||||
DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n", &FileObject->FileName, FileObject->SectionObjectPointer);
|
||||
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
|
||||
|
||||
DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n",
|
||||
&FileObject->FileName,
|
||||
FileObject->SectionObjectPointer);
|
||||
|
||||
ASSERT(UninitializeEvent == NULL);
|
||||
|
||||
/* It may not be strictly necessary to flush here, but we do just for
|
||||
/* It may not be strictly necessary to flush here, but we do just for
|
||||
kicks. */
|
||||
if (Map)
|
||||
CcpFlushCache(Map, NULL, 0, NULL, FALSE);
|
||||
if (Map)
|
||||
CcpFlushCache(Map, NULL, 0, NULL, FALSE);
|
||||
|
||||
CcpLock();
|
||||
CcpLock();
|
||||
/* We have a private cache map, so we've been initialized and haven't been
|
||||
* uninitialized. */
|
||||
if (PrivateCacheMap)
|
||||
{
|
||||
ASSERT(!Map || Map == PrivateCacheMap->Map);
|
||||
ASSERT(PrivateCacheMap->FileObject == FileObject);
|
||||
if (PrivateCacheMap)
|
||||
{
|
||||
ASSERT(!Map || Map == PrivateCacheMap->Map);
|
||||
ASSERT(PrivateCacheMap->FileObject == FileObject);
|
||||
|
||||
RemoveEntryList(&PrivateCacheMap->ListEntry);
|
||||
RemoveEntryList(&PrivateCacheMap->ListEntry);
|
||||
/* That was the last private cache map. It's time to delete all
|
||||
cache stripes and all aspects of caching on the file. */
|
||||
if (IsListEmpty(&PrivateCacheMap->Map->PrivateCacheMaps))
|
||||
{
|
||||
if (IsListEmpty(&PrivateCacheMap->Map->PrivateCacheMaps))
|
||||
{
|
||||
/* Get rid of all the cache stripes. */
|
||||
while (!IsListEmpty(&PrivateCacheMap->Map->AssociatedBcb))
|
||||
{
|
||||
PNOCC_BCB Bcb = CONTAINING_RECORD(PrivateCacheMap->Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
|
||||
DPRINT("Evicting cache stripe #%x\n", Bcb - CcCacheSections);
|
||||
Bcb->RefCount = 1;
|
||||
CcpDereferenceCache(Bcb - CcCacheSections, TRUE);
|
||||
}
|
||||
RemoveEntryList(&PrivateCacheMap->Map->Entry);
|
||||
ExFreePool(PrivateCacheMap->Map);
|
||||
FileObject->SectionObjectPointer->SharedCacheMap = NULL;
|
||||
LastMap = TRUE;
|
||||
}
|
||||
ObDereferenceObject(PrivateCacheMap->FileObject);
|
||||
FileObject->PrivateCacheMap = NULL;
|
||||
ExFreePool(PrivateCacheMap);
|
||||
}
|
||||
CcpUnlock();
|
||||
while (!IsListEmpty(&PrivateCacheMap->Map->AssociatedBcb))
|
||||
{
|
||||
PNOCC_BCB Bcb = CONTAINING_RECORD(PrivateCacheMap->Map->AssociatedBcb.Flink,
|
||||
NOCC_BCB,
|
||||
ThisFileList);
|
||||
|
||||
DPRINT("Uninit complete\n");
|
||||
DPRINT("Evicting cache stripe #%x\n", Bcb - CcCacheSections);
|
||||
Bcb->RefCount = 1;
|
||||
CcpDereferenceCache(Bcb - CcCacheSections, TRUE);
|
||||
}
|
||||
RemoveEntryList(&PrivateCacheMap->Map->Entry);
|
||||
ExFreePool(PrivateCacheMap->Map);
|
||||
FileObject->SectionObjectPointer->SharedCacheMap = NULL;
|
||||
LastMap = TRUE;
|
||||
}
|
||||
ObDereferenceObject(PrivateCacheMap->FileObject);
|
||||
FileObject->PrivateCacheMap = NULL;
|
||||
ExFreePool(PrivateCacheMap);
|
||||
}
|
||||
CcpUnlock();
|
||||
|
||||
/* The return from CcUninitializeCacheMap means that 'caching was stopped'.
|
||||
*/
|
||||
DPRINT("Uninit complete\n");
|
||||
|
||||
/* The return from CcUninitializeCacheMap means that 'caching was stopped'. */
|
||||
return LastMap;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
CcSetFileSizes is used to tell the cache manager that the file changed
|
||||
size. In our case, we use the internal Mm method MmExtendCacheSection
|
||||
|
@ -338,20 +360,19 @@ CcSetFileSizes(IN PFILE_OBJECT FileObject,
|
|||
|
||||
if (!Map) return;
|
||||
Map->FileSizes = *FileSizes;
|
||||
Bcb = Map->AssociatedBcb.Flink == &Map->AssociatedBcb ?
|
||||
NULL : CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
|
||||
if (!Bcb) return;
|
||||
MmExtendCacheSection(Bcb->SectionObject, &FileSizes->FileSize, FALSE);
|
||||
DPRINT("FileSizes->FileSize %x\n", FileSizes->FileSize.LowPart);
|
||||
DPRINT("FileSizes->AllocationSize %x\n", FileSizes->AllocationSize.LowPart);
|
||||
Bcb = Map->AssociatedBcb.Flink == &Map->AssociatedBcb ?
|
||||
NULL : CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
|
||||
if (!Bcb) return;
|
||||
MmExtendCacheSection(Bcb->SectionObject, &FileSizes->FileSize, FALSE);
|
||||
DPRINT("FileSizes->FileSize %x\n", FileSizes->FileSize.LowPart);
|
||||
DPRINT("FileSizes->AllocationSize %x\n", FileSizes->AllocationSize.LowPart);
|
||||
DPRINT("FileSizes->ValidDataLength %x\n", FileSizes->ValidDataLength.LowPart);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CcGetFileSizes
|
||||
(IN PFILE_OBJECT FileObject,
|
||||
IN PCC_FILE_SIZES FileSizes)
|
||||
CcGetFileSizes(IN PFILE_OBJECT FileObject,
|
||||
IN PCC_FILE_SIZES FileSizes)
|
||||
{
|
||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
if (!Map) return FALSE;
|
||||
|
@ -366,10 +387,10 @@ CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
|||
IN ULONG Length,
|
||||
IN BOOLEAN UninitializeCacheMaps)
|
||||
{
|
||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
||||
if (!Map) return TRUE;
|
||||
CcpFlushCache(Map, NULL, 0, NULL, TRUE);
|
||||
return TRUE;
|
||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
||||
if (!Map) return TRUE;
|
||||
CcpFlushCache(Map, NULL, 0, NULL, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -380,12 +401,12 @@ CcSetDirtyPageThreshold(IN PFILE_OBJECT FileObject,
|
|||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
|
||||
This could be implemented much more intelligently by mapping instances
|
||||
of a CoW zero page into the affected regions. We just RtlZeroMemory
|
||||
for now.
|
||||
for now.
|
||||
|
||||
*/
|
||||
BOOLEAN
|
||||
|
@ -396,156 +417,212 @@ CcZeroData(IN PFILE_OBJECT FileObject,
|
|||
IN BOOLEAN Wait)
|
||||
{
|
||||
PNOCC_BCB Bcb = NULL;
|
||||
PLIST_ENTRY ListEntry = NULL;
|
||||
LARGE_INTEGER LowerBound = *StartOffset;
|
||||
LARGE_INTEGER UpperBound = *EndOffset;
|
||||
LARGE_INTEGER Target, End;
|
||||
PVOID PinnedBcb, PinnedBuffer;
|
||||
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
PLIST_ENTRY ListEntry = NULL;
|
||||
LARGE_INTEGER LowerBound = *StartOffset;
|
||||
LARGE_INTEGER UpperBound = *EndOffset;
|
||||
LARGE_INTEGER Target, End;
|
||||
PVOID PinnedBcb, PinnedBuffer;
|
||||
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
|
||||
DPRINT
|
||||
("S %08x%08x E %08x%08x\n",
|
||||
StartOffset->u.HighPart, StartOffset->u.LowPart,
|
||||
EndOffset->u.HighPart, EndOffset->u.LowPart);
|
||||
DPRINT("S %08x%08x E %08x%08x\n",
|
||||
StartOffset->u.HighPart,
|
||||
StartOffset->u.LowPart,
|
||||
EndOffset->u.HighPart,
|
||||
EndOffset->u.LowPart);
|
||||
|
||||
if (!Map)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK IOSB;
|
||||
PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
|
||||
ULONG ToWrite;
|
||||
if (!Map)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK IOSB;
|
||||
PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
|
||||
ULONG ToWrite;
|
||||
|
||||
if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
|
||||
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
|
||||
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
|
||||
if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
|
||||
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
|
||||
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
|
||||
|
||||
Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
|
||||
End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);
|
||||
Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
|
||||
End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);
|
||||
|
||||
// Handle leading page
|
||||
if (LowerBound.QuadPart != Target.QuadPart)
|
||||
{
|
||||
ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart, (PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
|
||||
DPRINT("Zero last half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
|
||||
Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, TRUE, &IOSB);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite);
|
||||
RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite);
|
||||
Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE,UpperBound.QuadPart-Target.QuadPart), &IOSB);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
Target.QuadPart += PAGE_SIZE;
|
||||
}
|
||||
// Handle leading page
|
||||
if (LowerBound.QuadPart != Target.QuadPart)
|
||||
{
|
||||
ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart,
|
||||
(PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
|
||||
|
||||
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
|
||||
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
|
||||
|
||||
while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
|
||||
{
|
||||
DPRINT("Zero full page %08x%08x\n", Target.u.HighPart, Target.u.LowPart);
|
||||
Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, PAGE_SIZE, &IOSB);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
Target.QuadPart += PAGE_SIZE;
|
||||
}
|
||||
DPRINT("Zero last half %08x%08x %x\n",
|
||||
Target.u.HighPart,
|
||||
Target.u.LowPart,
|
||||
ToWrite);
|
||||
|
||||
if (UpperBound.QuadPart > Target.QuadPart)
|
||||
{
|
||||
ToWrite = UpperBound.QuadPart - Target.QuadPart;
|
||||
DPRINT("Zero first half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
|
||||
Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, TRUE, &IOSB);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite);
|
||||
RtlZeroMemory(ZeroBuf, ToWrite);
|
||||
Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE, UpperBound.QuadPart-Target.QuadPart), &IOSB);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
Target.QuadPart += PAGE_SIZE;
|
||||
}
|
||||
Status = MiSimpleRead(FileObject,
|
||||
&Target,
|
||||
ZeroBuf,
|
||||
PAGE_SIZE,
|
||||
TRUE,
|
||||
&IOSB);
|
||||
|
||||
ExFreePool(ZeroBuf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CcpLock();
|
||||
ListEntry = Map->AssociatedBcb.Flink;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
|
||||
while (ListEntry != &Map->AssociatedBcb)
|
||||
{
|
||||
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
||||
CcpReferenceCache(Bcb - CcCacheSections);
|
||||
DPRINT1("RtlZeroMemory(%x,%x)\n",
|
||||
ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
|
||||
ToWrite);
|
||||
|
||||
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
|
||||
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
|
||||
{
|
||||
DPRINT
|
||||
("Bcb #%x (@%08x%08x)\n",
|
||||
Bcb - CcCacheSections,
|
||||
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
|
||||
RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
|
||||
ToWrite);
|
||||
|
||||
Target.QuadPart = MAX(Bcb->FileOffset.QuadPart, LowerBound.QuadPart);
|
||||
End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart, UpperBound.QuadPart);
|
||||
End.QuadPart = MIN(End.QuadPart, Bcb->FileOffset.QuadPart + Bcb->Length);
|
||||
CcpUnlock();
|
||||
Status = MiSimpleWrite(FileObject,
|
||||
&Target,
|
||||
ZeroBuf,
|
||||
MIN(PAGE_SIZE,
|
||||
UpperBound.QuadPart-Target.QuadPart),
|
||||
&IOSB);
|
||||
|
||||
if (!CcPreparePinWrite
|
||||
(FileObject,
|
||||
&Target,
|
||||
End.QuadPart - Target.QuadPart,
|
||||
TRUE,
|
||||
Wait,
|
||||
&PinnedBcb,
|
||||
&PinnedBuffer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
Target.QuadPart += PAGE_SIZE;
|
||||
}
|
||||
|
||||
ASSERT(PinnedBcb == Bcb);
|
||||
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
|
||||
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
|
||||
|
||||
CcpLock();
|
||||
ListEntry = ListEntry->Flink;
|
||||
// Return from pin state
|
||||
CcpUnpinData(PinnedBcb, TRUE);
|
||||
}
|
||||
while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
|
||||
{
|
||||
DPRINT("Zero full page %08x%08x\n",
|
||||
Target.u.HighPart,
|
||||
Target.u.LowPart);
|
||||
|
||||
CcpUnpinData(Bcb, TRUE);
|
||||
}
|
||||
Status = MiSimpleWrite(FileObject,
|
||||
&Target,
|
||||
ZeroBuf,
|
||||
PAGE_SIZE,
|
||||
&IOSB);
|
||||
|
||||
CcpUnlock();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
Target.QuadPart += PAGE_SIZE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
if (UpperBound.QuadPart > Target.QuadPart)
|
||||
{
|
||||
ToWrite = UpperBound.QuadPart - Target.QuadPart;
|
||||
DPRINT("Zero first half %08x%08x %x\n",
|
||||
Target.u.HighPart,
|
||||
Target.u.LowPart,
|
||||
ToWrite);
|
||||
|
||||
Status = MiSimpleRead(FileObject,
|
||||
&Target,
|
||||
ZeroBuf,
|
||||
PAGE_SIZE,
|
||||
TRUE,
|
||||
&IOSB);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite);
|
||||
RtlZeroMemory(ZeroBuf, ToWrite);
|
||||
Status = MiSimpleWrite(FileObject,
|
||||
&Target,
|
||||
ZeroBuf,
|
||||
MIN(PAGE_SIZE,
|
||||
UpperBound.QuadPart-Target.QuadPart),
|
||||
&IOSB);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ZeroBuf);
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
Target.QuadPart += PAGE_SIZE;
|
||||
}
|
||||
|
||||
ExFreePool(ZeroBuf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CcpLock();
|
||||
ListEntry = Map->AssociatedBcb.Flink;
|
||||
|
||||
while (ListEntry != &Map->AssociatedBcb)
|
||||
{
|
||||
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
||||
CcpReferenceCache(Bcb - CcCacheSections);
|
||||
|
||||
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
|
||||
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
|
||||
{
|
||||
DPRINT("Bcb #%x (@%08x%08x)\n",
|
||||
Bcb - CcCacheSections,
|
||||
Bcb->FileOffset.u.HighPart,
|
||||
Bcb->FileOffset.u.LowPart);
|
||||
|
||||
Target.QuadPart = MAX(Bcb->FileOffset.QuadPart,
|
||||
LowerBound.QuadPart);
|
||||
|
||||
End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart,
|
||||
UpperBound.QuadPart);
|
||||
|
||||
End.QuadPart = MIN(End.QuadPart,
|
||||
Bcb->FileOffset.QuadPart + Bcb->Length);
|
||||
|
||||
CcpUnlock();
|
||||
|
||||
if (!CcPreparePinWrite(FileObject,
|
||||
&Target,
|
||||
End.QuadPart - Target.QuadPart,
|
||||
TRUE,
|
||||
Wait,
|
||||
&PinnedBcb,
|
||||
&PinnedBuffer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ASSERT(PinnedBcb == Bcb);
|
||||
|
||||
CcpLock();
|
||||
ListEntry = ListEntry->Flink;
|
||||
/* Return from pin state */
|
||||
CcpUnpinData(PinnedBcb, TRUE);
|
||||
}
|
||||
|
||||
CcpUnpinData(Bcb, TRUE);
|
||||
}
|
||||
|
||||
CcpUnlock();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PFILE_OBJECT
|
||||
NTAPI
|
||||
CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
|
||||
{
|
||||
PFILE_OBJECT Result = NULL;
|
||||
PNOCC_CACHE_MAP Map = SectionObjectPointer->SharedCacheMap;
|
||||
CcpLock();
|
||||
if (!IsListEmpty(&Map->AssociatedBcb))
|
||||
{
|
||||
PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
|
||||
Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject);
|
||||
}
|
||||
CcpUnlock();
|
||||
PFILE_OBJECT Result = NULL;
|
||||
PNOCC_CACHE_MAP Map = SectionObjectPointer->SharedCacheMap;
|
||||
CcpLock();
|
||||
if (!IsListEmpty(&Map->AssociatedBcb))
|
||||
{
|
||||
PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink,
|
||||
NOCC_BCB,
|
||||
ThisFileList);
|
||||
|
||||
Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject);
|
||||
}
|
||||
CcpUnlock();
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -553,9 +630,9 @@ PFILE_OBJECT
|
|||
NTAPI
|
||||
CcGetFileObjectFromBcb(PVOID Bcb)
|
||||
{
|
||||
PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
|
||||
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
|
||||
return MmGetFileObjectForSection((PROS_SECTION_OBJECT)RealBcb->SectionObject);
|
||||
PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
|
||||
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
|
||||
return MmGetFileObjectForSection((PROS_SECTION_OBJECT)RealBcb->SectionObject);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
2
reactos/ntoskrnl/cache/lazyrite.c
vendored
2
reactos/ntoskrnl/cache/lazyrite.c
vendored
|
@ -22,7 +22,7 @@ KEVENT CcpLazyWriteEvent;
|
|||
VOID NTAPI
|
||||
CcpLazyWriteThread(PVOID Unused)
|
||||
{
|
||||
/* Not implemented */
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
|
8
reactos/ntoskrnl/cache/logsup.c
vendored
8
reactos/ntoskrnl/cache/logsup.c
vendored
|
@ -33,10 +33,10 @@ CcSetLogHandleForFile(IN PFILE_OBJECT FileObject,
|
|||
IN PVOID LogHandle,
|
||||
IN PFLUSH_TO_LSN FlushToLsnRoutine)
|
||||
{
|
||||
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
if (!Map) return;
|
||||
Map->LogHandle = LogHandle;
|
||||
Map->FlushToLsn = FlushToLsnRoutine;
|
||||
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
if (!Map) return;
|
||||
Map->LogHandle = LogHandle;
|
||||
Map->FlushToLsn = FlushToLsnRoutine;
|
||||
}
|
||||
|
||||
LARGE_INTEGER
|
||||
|
|
102
reactos/ntoskrnl/cache/mdlsup.c
vendored
102
reactos/ntoskrnl/cache/mdlsup.c
vendored
|
@ -16,55 +16,47 @@
|
|||
/* GLOBALS ********************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
|
||||
PMDL
|
||||
NTAPI
|
||||
CcpBuildCacheMdl
|
||||
(PFILE_OBJECT FileObject,
|
||||
PLARGE_INTEGER FileOffset,
|
||||
ULONG Length,
|
||||
PIO_STATUS_BLOCK IOSB)
|
||||
CcpBuildCacheMdl(PFILE_OBJECT FileObject,
|
||||
PLARGE_INTEGER FileOffset,
|
||||
ULONG Length,
|
||||
PIO_STATUS_BLOCK IOSB)
|
||||
{
|
||||
PMDL Mdl;
|
||||
PVOID Bcb, Buffer;
|
||||
PMDL Mdl;
|
||||
PVOID Bcb, Buffer;
|
||||
|
||||
BOOLEAN Result = CcMapData
|
||||
(FileObject,
|
||||
FileOffset,
|
||||
Length,
|
||||
PIN_WAIT,
|
||||
&Bcb,
|
||||
&Buffer);
|
||||
BOOLEAN Result = CcMapData(FileObject,
|
||||
FileOffset,
|
||||
Length,
|
||||
PIN_WAIT,
|
||||
&Bcb,
|
||||
&Buffer);
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
IOSB->Information = 0;
|
||||
IOSB->Status = STATUS_UNSUCCESSFUL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IOSB->Information = Length;
|
||||
IOSB->Status = STATUS_SUCCESS;
|
||||
|
||||
Mdl = IoAllocateMdl
|
||||
(Buffer,
|
||||
Length,
|
||||
FALSE,
|
||||
FALSE,
|
||||
NULL);
|
||||
if (!Result)
|
||||
{
|
||||
IOSB->Information = 0;
|
||||
IOSB->Status = STATUS_UNSUCCESSFUL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!Mdl)
|
||||
{
|
||||
IOSB->Information = 0;
|
||||
IOSB->Status = STATUS_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
IOSB->Information = Length;
|
||||
IOSB->Status = STATUS_SUCCESS;
|
||||
|
||||
IOSB->Information = Length;
|
||||
IOSB->Status = STATUS_SUCCESS;
|
||||
Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
|
||||
|
||||
return Mdl;
|
||||
if (!Mdl)
|
||||
{
|
||||
IOSB->Information = 0;
|
||||
IOSB->Status = STATUS_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IOSB->Information = Length;
|
||||
IOSB->Status = STATUS_SUCCESS;
|
||||
|
||||
return Mdl;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -75,29 +67,25 @@ CcMdlRead(IN PFILE_OBJECT FileObject,
|
|||
OUT PMDL *MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
*MdlChain = CcpBuildCacheMdl
|
||||
(FileObject,
|
||||
FileOffset,
|
||||
Length,
|
||||
IoStatus);
|
||||
*MdlChain = CcpBuildCacheMdl(FileObject, FileOffset, Length, IoStatus);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcMdlReadComplete(IN PFILE_OBJECT FileObject,
|
||||
IN PMDL MdlChain)
|
||||
{
|
||||
IoFreeMdl(MdlChain);
|
||||
IoFreeMdl(MdlChain);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcMdlReadComplete2(IN PMDL MdlChain,
|
||||
IN PFILE_OBJECT FileObject)
|
||||
IN PFILE_OBJECT FileObject)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
|
||||
|
@ -106,11 +94,7 @@ CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
|
|||
OUT PMDL *MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
*MdlChain = CcpBuildCacheMdl
|
||||
(FileObject,
|
||||
FileOffset,
|
||||
Length,
|
||||
IoStatus);
|
||||
*MdlChain = CcpBuildCacheMdl(FileObject, FileOffset, Length, IoStatus);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -119,7 +103,7 @@ CcMdlWriteComplete(IN PFILE_OBJECT FileObject,
|
|||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain)
|
||||
{
|
||||
IoFreeMdl(MdlChain);
|
||||
IoFreeMdl(MdlChain);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -128,7 +112,7 @@ CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
|
|||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -136,8 +120,8 @@ NTAPI
|
|||
CcMdlWriteAbort(IN PFILE_OBJECT FileObject,
|
||||
IN PMDL MdlChain)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
IoFreeMdl(MdlChain);
|
||||
ASSERT(FALSE);
|
||||
IoFreeMdl(MdlChain);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
100
reactos/ntoskrnl/cache/newcc.h
vendored
100
reactos/ntoskrnl/cache/newcc.h
vendored
|
@ -5,19 +5,19 @@ typedef struct _NOCC_BCB
|
|||
/* Public part */
|
||||
PUBLIC_BCB Bcb;
|
||||
|
||||
struct _NOCC_CACHE_MAP *Map;
|
||||
struct _NOCC_CACHE_MAP *Map;
|
||||
PROS_SECTION_OBJECT SectionObject;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG Length;
|
||||
PVOID BaseAddress;
|
||||
BOOLEAN Dirty;
|
||||
PVOID OwnerPointer;
|
||||
|
||||
|
||||
/* Reference counts */
|
||||
ULONG RefCount;
|
||||
|
||||
|
||||
LIST_ENTRY ThisFileList;
|
||||
|
||||
|
||||
KEVENT ExclusiveWait;
|
||||
ULONG ExclusiveWaiter;
|
||||
BOOLEAN Exclusive;
|
||||
|
@ -25,39 +25,33 @@ typedef struct _NOCC_BCB
|
|||
|
||||
typedef struct _NOCC_CACHE_MAP
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
LIST_ENTRY Entry;
|
||||
LIST_ENTRY AssociatedBcb;
|
||||
LIST_ENTRY PrivateCacheMaps;
|
||||
LIST_ENTRY PrivateCacheMaps;
|
||||
ULONG NumberOfMaps;
|
||||
ULONG RefCount;
|
||||
CC_FILE_SIZES FileSizes;
|
||||
CACHE_MANAGER_CALLBACKS Callbacks;
|
||||
PVOID LazyContext;
|
||||
PVOID LogHandle;
|
||||
PFLUSH_TO_LSN FlushToLsn;
|
||||
ULONG ReadAheadGranularity;
|
||||
CACHE_MANAGER_CALLBACKS Callbacks;
|
||||
PVOID LazyContext;
|
||||
PVOID LogHandle;
|
||||
PFLUSH_TO_LSN FlushToLsn;
|
||||
ULONG ReadAheadGranularity;
|
||||
} NOCC_CACHE_MAP, *PNOCC_CACHE_MAP;
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcPfInitializePrefetcher(
|
||||
VOID
|
||||
);
|
||||
CcPfInitializePrefetcher(VOID);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcMdlReadComplete2(
|
||||
IN PMDL MemoryDescriptorList,
|
||||
IN PFILE_OBJECT FileObject
|
||||
);
|
||||
CcMdlReadComplete2(IN PMDL MemoryDescriptorList,
|
||||
IN PFILE_OBJECT FileObject);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcMdlWriteComplete2(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain
|
||||
);
|
||||
CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
|
@ -65,7 +59,8 @@ CcInitView(VOID);
|
|||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CcpUnpinData(PNOCC_BCB Bcb, BOOLEAN ActuallyRelease);
|
||||
CcpUnpinData(PNOCC_BCB Bcb,
|
||||
BOOLEAN ActuallyRelease);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
|
@ -82,24 +77,25 @@ CcInitCacheZeroPage(VOID);
|
|||
/* Called by section.c */
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer, MMFLUSH_TYPE FlushType);
|
||||
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||
MMFLUSH_TYPE FlushType);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
_CcpFlushCache
|
||||
(IN PNOCC_CACHE_MAP Map,
|
||||
IN OPTIONAL PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
|
||||
BOOLEAN Delete,
|
||||
const char *File,
|
||||
int Line);
|
||||
_CcpFlushCache(IN PNOCC_CACHE_MAP Map,
|
||||
IN OPTIONAL PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
|
||||
BOOLEAN Delete,
|
||||
const char *File,
|
||||
int Line);
|
||||
|
||||
#define CcpFlushCache(M,F,L,I,D) _CcpFlushCache(M,F,L,I,D,__FILE__,__LINE__)
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CcGetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
|
||||
CcGetFileSizes(PFILE_OBJECT FileObject,
|
||||
PCC_FILE_SIZES FileSizes);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
|
@ -125,13 +121,13 @@ CcpReleaseFileLock(PNOCC_CACHE_MAP Map);
|
|||
/* Private data */
|
||||
|
||||
#define CACHE_SINGLE_FILE_MAX (16)
|
||||
#define CACHE_OVERALL_SIZE (32 * 1024 * 1024)
|
||||
#define CACHE_STRIPE VACB_MAPPING_GRANULARITY
|
||||
#define CACHE_SHIFT 18
|
||||
#define CACHE_NUM_SECTIONS (CACHE_OVERALL_SIZE / CACHE_STRIPE)
|
||||
#define CACHE_ROUND_UP(x) (((x) + (CACHE_STRIPE-1)) & ~(CACHE_STRIPE-1))
|
||||
#define CACHE_ROUND_DOWN(x) ((x) & ~(CACHE_STRIPE-1))
|
||||
#define INVALID_CACHE ((ULONG)~0)
|
||||
#define CACHE_OVERALL_SIZE (32 * 1024 * 1024)
|
||||
#define CACHE_STRIPE VACB_MAPPING_GRANULARITY
|
||||
#define CACHE_SHIFT 18
|
||||
#define CACHE_NUM_SECTIONS (CACHE_OVERALL_SIZE / CACHE_STRIPE)
|
||||
#define CACHE_ROUND_UP(x) (((x) + (CACHE_STRIPE-1)) & ~(CACHE_STRIPE-1))
|
||||
#define CACHE_ROUND_DOWN(x) ((x) & ~(CACHE_STRIPE-1))
|
||||
#define INVALID_CACHE ((ULONG)~0)
|
||||
|
||||
extern NOCC_BCB CcCacheSections[CACHE_NUM_SECTIONS];
|
||||
extern PRTL_BITMAP CcCacheBitmap;
|
||||
|
@ -149,20 +145,20 @@ extern VOID _CcpUnlock(const char *file, int line);
|
|||
|
||||
extern VOID CcpReferenceCache(ULONG Sector);
|
||||
extern VOID CcpDereferenceCache(ULONG Sector, BOOLEAN Immediate);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CcpMapData
|
||||
(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG Flags,
|
||||
OUT PVOID *BcbResult,
|
||||
OUT PVOID *Buffer);
|
||||
CcpMapData(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG Flags,
|
||||
OUT PVOID *BcbResult,
|
||||
OUT PVOID *Buffer);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CcpPinMappedData(IN PNOCC_CACHE_MAP Map,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG Flags,
|
||||
IN OUT PVOID *Bcb);
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG Flags,
|
||||
IN OUT PVOID *Bcb);
|
||||
|
|
910
reactos/ntoskrnl/cache/pinsup.c
vendored
910
reactos/ntoskrnl/cache/pinsup.c
vendored
File diff suppressed because it is too large
Load diff
12
reactos/ntoskrnl/cache/section/fault.c
vendored
12
reactos/ntoskrnl/cache/section/fault.c
vendored
|
@ -51,9 +51,9 @@ action atomically, or place a wait entry and return a continuation to the
|
|||
caller. This lends itself to code that has a simple, structured form,
|
||||
doesn't make assumptions about lock taking and breaking, and provides an
|
||||
obvious, graphic seperation between code that may block and code that isn't
|
||||
allowed to. This file contains the non-blocking half.
|
||||
allowed to. This file contains the non-blocking half.
|
||||
|
||||
In order to request a blocking operation to happen outside locks, place a
|
||||
In order to request a blocking operation to happen outside locks, place a
|
||||
function pointer in the provided MM_REQUIRED_RESOURCES struct and return
|
||||
STATUS_MORE_PROCESSING_REQUIRED. The function indicated will receive the
|
||||
provided struct and take action outside of any mm related locks and at
|
||||
|
@ -89,7 +89,7 @@ extern PMMWSL MmWorkingSetList;
|
|||
Multiple stage handling of a not-present fault in a data section.
|
||||
|
||||
Required->State is used to accumulate flags that indicate the next action
|
||||
the handler should take.
|
||||
the handler should take.
|
||||
|
||||
State & 2 is currently used to indicate that the page acquired by a previous
|
||||
callout is a global page to the section and should be placed in the section
|
||||
|
@ -351,7 +351,7 @@ MiCowCacheSectionPage(PMMSUPPORT AddressSpace,
|
|||
Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
|
||||
{
|
||||
#if 0
|
||||
if (Region->Protect == PAGE_READWRITE ||
|
||||
if (Region->Protect == PAGE_READWRITE ||
|
||||
Region->Protect == PAGE_EXECUTE_READWRITE)
|
||||
#endif
|
||||
{
|
||||
|
@ -513,7 +513,7 @@ MM_WAIT_ENTRY from a page table.
|
|||
|
||||
In the ultimate form of this code, there is a single system wide fault handler
|
||||
for each of access fault and not present and each memory area contains a
|
||||
function pointer that indicates the active fault handler. Since the mm code
|
||||
function pointer that indicates the active fault handler. Since the mm code
|
||||
in reactos is currently fragmented, I didn't bring this change to trunk.
|
||||
|
||||
*/
|
||||
|
@ -669,7 +669,7 @@ MmpSectionAccessFaultInner(KPROCESSOR_MODE Mode,
|
|||
|
||||
/*
|
||||
|
||||
This is the outer fault handler mentioned in the description of
|
||||
This is the outer fault handler mentioned in the description of
|
||||
MmpSectionAccsesFaultInner. It increments a fault depth count in the current
|
||||
thread.
|
||||
|
||||
|
|
6
reactos/ntoskrnl/cache/section/io.c
vendored
6
reactos/ntoskrnl/cache/section/io.c
vendored
|
@ -64,11 +64,11 @@ MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject)
|
|||
return IoGetRelatedDeviceObject(FileObject);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
|
||||
Note:
|
||||
This completion function is really required. Paging io completion does almost
|
||||
nothing, including freeing the mdls.
|
||||
nothing, including freeing the mdls.
|
||||
|
||||
*/
|
||||
NTSTATUS
|
||||
|
@ -282,7 +282,7 @@ FAST_MUTEX MiWriteMutex;
|
|||
/*
|
||||
|
||||
Function which uses MiSimpleWrite to write back a single page to a file.
|
||||
The page in question does not need to be mapped. This function could be
|
||||
The page in question does not need to be mapped. This function could be
|
||||
made a bit more efficient by avoiding the copy and making a system space
|
||||
mdl.
|
||||
|
||||
|
|
6
reactos/ntoskrnl/cache/section/reqtools.c
vendored
6
reactos/ntoskrnl/cache/section/reqtools.c
vendored
|
@ -44,7 +44,7 @@
|
|||
|
||||
/*
|
||||
This file contains functions used by fault.c to do blocking resource
|
||||
acquisition. To call one of these functions, fill out your
|
||||
acquisition. To call one of these functions, fill out your
|
||||
MM_REQUIRED_RESOURCES with a pointer to the desired function and configure
|
||||
the other members as below.
|
||||
*/
|
||||
|
@ -64,7 +64,7 @@ MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages);
|
|||
|
||||
/*
|
||||
|
||||
Blocking function to acquire zeroed pages from the balancer.
|
||||
Blocking function to acquire zeroed pages from the balancer.
|
||||
|
||||
Upon entry:
|
||||
|
||||
|
@ -110,7 +110,7 @@ MiGetOnePage(PMMSUPPORT AddressSpace,
|
|||
|
||||
/*
|
||||
|
||||
Blocking function to read (part of) a page from a file.
|
||||
Blocking function to read (part of) a page from a file.
|
||||
|
||||
Upon entry:
|
||||
|
||||
|
|
10
reactos/ntoskrnl/cache/section/sptab.c
vendored
10
reactos/ntoskrnl/cache/section/sptab.c
vendored
|
@ -26,8 +26,8 @@
|
|||
/*
|
||||
|
||||
This file implements the section page table. It relies on rtl generic table
|
||||
functionality to provide access to 256-page chunks. Calls to
|
||||
MiSetPageEntrySectionSegment and MiGetPageEntrySectionSegment must be
|
||||
functionality to provide access to 256-page chunks. Calls to
|
||||
MiSetPageEntrySectionSegment and MiGetPageEntrySectionSegment must be
|
||||
synchronized by holding the segment lock.
|
||||
|
||||
Each page table entry is a ULONG as in x86.
|
||||
|
@ -46,7 +46,7 @@ These functions, in addition to maintaining the segment page table also
|
|||
automatically maintain the segment rmap by calling MmSetSectionAssociation
|
||||
and MmDeleteSectionAssociation. Segment rmaps are discussed in rmap.c. The
|
||||
upshot is that it is impossible to have a page properly registered in a segment
|
||||
page table and not also found in a segment rmap that can be found from the
|
||||
page table and not also found in a segment rmap that can be found from the
|
||||
paging machinery.
|
||||
|
||||
*/
|
||||
|
@ -310,10 +310,10 @@ MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment,
|
|||
DPRINT("Done\n");
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
|
||||
Retrieves the MM_SECTION_SEGMENT and fills in the LARGE_INTEGER Offset given
|
||||
by the caller that corresponds to the page specified. This uses
|
||||
by the caller that corresponds to the page specified. This uses
|
||||
MmGetSegmentRmap to find the rmap belonging to the segment itself, and uses
|
||||
the result as a pointer to a 256-entry page table structure. The rmap also
|
||||
includes 8 bits of offset information indication one of 256 page entries that
|
||||
|
|
10
reactos/ntoskrnl/cache/section/swapout.c
vendored
10
reactos/ntoskrnl/cache/section/swapout.c
vendored
|
@ -77,7 +77,7 @@ FAST_MUTEX MiGlobalPageOperation;
|
|||
|
||||
MmWithdrawSectionPage removes a page entry from the section segment, replacing
|
||||
it with a wait entry. The caller must replace the wait entry with a 0, when
|
||||
any required writing is done. The wait entry must remain until the page is
|
||||
any required writing is done. The wait entry must remain until the page is
|
||||
written to protect against cases where a fault brings a stale copy of the page
|
||||
back before writing is complete.
|
||||
|
||||
|
@ -147,7 +147,7 @@ MmWithdrawSectionPage(PMM_SECTION_SEGMENT Segment,
|
|||
/*
|
||||
|
||||
This function determines whether the segment holds the very last reference to
|
||||
the page being considered and if so, writes it back or discards it as
|
||||
the page being considered and if so, writes it back or discards it as
|
||||
approriate. One small niggle here is that we might be holding the last
|
||||
reference to the section segment associated with this page. That happens
|
||||
when the segment is destroyed at the same time that an active swap operation
|
||||
|
@ -265,7 +265,7 @@ MmFinalizeSectionPageOut(PMM_SECTION_SEGMENT Segment,
|
|||
The slightly misnamed MmPageOutCacheSection removes a page from an address
|
||||
space in the manner of fault handlers found in fault.c. In the ultimate form
|
||||
of the code, this is one of the function pointers stored in a memory area
|
||||
to control how pages in that memory area are managed.
|
||||
to control how pages in that memory area are managed.
|
||||
|
||||
Also misleading is the call to MmReleasePageMemoryConsumer, which releases
|
||||
the reference held by this address space only. After all address spaces
|
||||
|
@ -319,7 +319,7 @@ MmPageOutCacheSection(PMMSUPPORT AddressSpace,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
|
||||
This function is called by rmap when spare pages are needed by the blancer.
|
||||
It attempts first to release the page from every address space in which it
|
||||
|
@ -332,7 +332,7 @@ the page mapped.
|
|||
|
||||
This code is like the other fault handlers, in that MmPageOutCacheSection has
|
||||
the option of returning either STATUS_SUCCESS + 1 to wait for a wait entry
|
||||
to disppear or to use the blocking callout facility by returning
|
||||
to disppear or to use the blocking callout facility by returning
|
||||
STATUS_MORE_PROCESSING_REQUIRED and placing a pointer to a function from
|
||||
reqtools.c in the MM_REQUIRED_RESOURCES struct.
|
||||
|
||||
|
|
Loading…
Reference in a new issue