mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +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
|
typedef struct _WORK_QUEUE_WITH_READ_AHEAD
|
||||||
{
|
{
|
||||||
WORK_QUEUE_ITEM WorkItem;
|
WORK_QUEUE_ITEM WorkItem;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
LARGE_INTEGER FileOffset;
|
LARGE_INTEGER FileOffset;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
} WORK_QUEUE_WITH_READ_AHEAD, *PWORK_QUEUE_WITH_READ_AHEAD;
|
} WORK_QUEUE_WITH_READ_AHEAD, *PWORK_QUEUE_WITH_READ_AHEAD;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
@ -37,52 +37,54 @@ CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject,
|
||||||
IN ULONG Granularity)
|
IN ULONG Granularity)
|
||||||
{
|
{
|
||||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
if (Map)
|
if (Map)
|
||||||
{
|
{
|
||||||
Map->ReadAheadGranularity = Granularity;
|
Map->ReadAheadGranularity = Granularity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcpReadAhead(PVOID Context)
|
CcpReadAhead(PVOID Context)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER Offset;
|
LARGE_INTEGER Offset;
|
||||||
PWORK_QUEUE_WITH_READ_AHEAD WorkItem = (PWORK_QUEUE_WITH_READ_AHEAD)Context;
|
PWORK_QUEUE_WITH_READ_AHEAD WorkItem = (PWORK_QUEUE_WITH_READ_AHEAD)Context;
|
||||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)WorkItem->FileObject->SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)WorkItem->FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
DPRINT1("Reading ahead %08x%08x:%x %wZ\n",
|
|
||||||
WorkItem->FileOffset.HighPart,
|
DPRINT1("Reading ahead %08x%08x:%x %wZ\n",
|
||||||
WorkItem->FileOffset.LowPart,
|
WorkItem->FileOffset.HighPart,
|
||||||
WorkItem->Length,
|
WorkItem->FileOffset.LowPart,
|
||||||
&WorkItem->FileObject->FileName);
|
WorkItem->Length,
|
||||||
Offset.HighPart = WorkItem->FileOffset.HighPart;
|
&WorkItem->FileObject->FileName);
|
||||||
Offset.LowPart = PAGE_ROUND_DOWN(WorkItem->FileOffset.LowPart);
|
|
||||||
if (Map)
|
Offset.HighPart = WorkItem->FileOffset.HighPart;
|
||||||
{
|
Offset.LowPart = PAGE_ROUND_DOWN(WorkItem->FileOffset.LowPart);
|
||||||
PLIST_ENTRY ListEntry;
|
if (Map)
|
||||||
volatile char *chptr;
|
{
|
||||||
PNOCC_BCB Bcb;
|
PLIST_ENTRY ListEntry;
|
||||||
for (ListEntry = Map->AssociatedBcb.Flink;
|
volatile char *chptr;
|
||||||
ListEntry != &Map->AssociatedBcb;
|
PNOCC_BCB Bcb;
|
||||||
ListEntry = ListEntry->Flink)
|
for (ListEntry = Map->AssociatedBcb.Flink;
|
||||||
{
|
ListEntry != &Map->AssociatedBcb;
|
||||||
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
ListEntry = ListEntry->Flink)
|
||||||
if ((Offset.QuadPart + WorkItem->Length < Bcb->FileOffset.QuadPart) ||
|
{
|
||||||
(Bcb->FileOffset.QuadPart + Bcb->Length < Offset.QuadPart))
|
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
||||||
continue;
|
if ((Offset.QuadPart + WorkItem->Length < Bcb->FileOffset.QuadPart) ||
|
||||||
for (chptr = Bcb->BaseAddress, Offset = Bcb->FileOffset;
|
(Bcb->FileOffset.QuadPart + Bcb->Length < Offset.QuadPart))
|
||||||
chptr < ((PCHAR)Bcb->BaseAddress) + Bcb->Length &&
|
continue;
|
||||||
Offset.QuadPart <
|
for (chptr = Bcb->BaseAddress, Offset = Bcb->FileOffset;
|
||||||
WorkItem->FileOffset.QuadPart + WorkItem->Length;
|
chptr < ((PCHAR)Bcb->BaseAddress) + Bcb->Length &&
|
||||||
chptr += PAGE_SIZE, Offset.QuadPart += PAGE_SIZE)
|
Offset.QuadPart <
|
||||||
{
|
WorkItem->FileOffset.QuadPart + WorkItem->Length;
|
||||||
*chptr ^= 0;
|
chptr += PAGE_SIZE, Offset.QuadPart += PAGE_SIZE)
|
||||||
}
|
{
|
||||||
}
|
*chptr ^= 0;
|
||||||
}
|
}
|
||||||
ObDereferenceObject(WorkItem->FileObject);
|
}
|
||||||
ExFreePool(WorkItem);
|
}
|
||||||
DPRINT("Done\n");
|
ObDereferenceObject(WorkItem->FileObject);
|
||||||
|
ExFreePool(WorkItem);
|
||||||
|
DPRINT("Done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -91,30 +93,36 @@ CcScheduleReadAhead(IN PFILE_OBJECT FileObject,
|
||||||
IN PLARGE_INTEGER FileOffset,
|
IN PLARGE_INTEGER FileOffset,
|
||||||
IN ULONG Length)
|
IN ULONG Length)
|
||||||
{
|
{
|
||||||
PWORK_QUEUE_WITH_READ_AHEAD WorkItem;
|
PWORK_QUEUE_WITH_READ_AHEAD WorkItem;
|
||||||
DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
|
|
||||||
FileOffset->HighPart,
|
DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
|
||||||
FileOffset->LowPart,
|
FileOffset->HighPart,
|
||||||
Length,
|
FileOffset->LowPart,
|
||||||
&FileObject->FileName);
|
Length,
|
||||||
WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem));
|
&FileObject->FileName);
|
||||||
if (!WorkItem) KeBugCheck(0);
|
|
||||||
ObReferenceObject(FileObject);
|
WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem));
|
||||||
WorkItem->FileObject = FileObject;
|
if (!WorkItem) KeBugCheck(0);
|
||||||
WorkItem->FileOffset = *FileOffset;
|
ObReferenceObject(FileObject);
|
||||||
WorkItem->Length = Length;
|
WorkItem->FileObject = FileObject;
|
||||||
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpReadAhead, WorkItem);
|
WorkItem->FileOffset = *FileOffset;
|
||||||
ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
|
WorkItem->Length = Length;
|
||||||
DPRINT("Done\n");
|
|
||||||
|
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem),
|
||||||
|
(PWORKER_THREAD_ROUTINE)CcpReadAhead,
|
||||||
|
WorkItem);
|
||||||
|
|
||||||
|
ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
|
||||||
|
DPRINT("Done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcSetDirtyPinnedData(IN PVOID BcbVoid,
|
CcSetDirtyPinnedData(IN PVOID BcbVoid,
|
||||||
IN OPTIONAL PLARGE_INTEGER Lsn)
|
IN OPTIONAL PLARGE_INTEGER Lsn)
|
||||||
{
|
{
|
||||||
PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid;
|
PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid;
|
||||||
Bcb->Dirty = TRUE;
|
Bcb->Dirty = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LARGE_INTEGER
|
LARGE_INTEGER
|
||||||
|
@ -128,81 +136,85 @@ CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
_CcpFlushCache(IN PNOCC_CACHE_MAP Map,
|
_CcpFlushCache(IN PNOCC_CACHE_MAP Map,
|
||||||
IN OPTIONAL PLARGE_INTEGER FileOffset,
|
IN OPTIONAL PLARGE_INTEGER FileOffset,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
|
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
|
||||||
BOOLEAN Delete,
|
BOOLEAN Delete,
|
||||||
const char *File,
|
const char *File,
|
||||||
int Line)
|
int Line)
|
||||||
{
|
{
|
||||||
PNOCC_BCB Bcb = NULL;
|
PNOCC_BCB Bcb = NULL;
|
||||||
LARGE_INTEGER LowerBound, UpperBound;
|
LARGE_INTEGER LowerBound, UpperBound;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
IO_STATUS_BLOCK IOSB;
|
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)
|
if (FileOffset && Length)
|
||||||
{
|
{
|
||||||
LowerBound.QuadPart = FileOffset->QuadPart;
|
LowerBound.QuadPart = FileOffset->QuadPart;
|
||||||
UpperBound.QuadPart = LowerBound.QuadPart + Length;
|
UpperBound.QuadPart = LowerBound.QuadPart + Length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LowerBound.QuadPart = 0;
|
LowerBound.QuadPart = 0;
|
||||||
UpperBound.QuadPart = 0x7fffffffffffffffull;
|
UpperBound.QuadPart = 0x7fffffffffffffffull;
|
||||||
}
|
}
|
||||||
|
|
||||||
CcpLock();
|
CcpLock();
|
||||||
ListEntry = Map->AssociatedBcb.Flink;
|
ListEntry = Map->AssociatedBcb.Flink;
|
||||||
|
|
||||||
while (ListEntry != &Map->AssociatedBcb)
|
while (ListEntry != &Map->AssociatedBcb)
|
||||||
{
|
{
|
||||||
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
||||||
CcpReferenceCache((ULONG)(Bcb - CcCacheSections));
|
CcpReferenceCache((ULONG)(Bcb - CcCacheSections));
|
||||||
|
|
||||||
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
|
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
|
||||||
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
|
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
|
||||||
{
|
{
|
||||||
DPRINT
|
DPRINT("Bcb #%x (@%08x%08x)\n",
|
||||||
("Bcb #%x (@%08x%08x)\n",
|
Bcb - CcCacheSections,
|
||||||
Bcb - CcCacheSections,
|
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
|
||||||
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
|
|
||||||
|
|
||||||
Bcb->RefCount++;
|
Bcb->RefCount++;
|
||||||
CcpUnlock();
|
CcpUnlock();
|
||||||
MiFlushMappedSection(Bcb->BaseAddress, &Bcb->FileOffset, &Map->FileSizes.FileSize, Bcb->Dirty);
|
MiFlushMappedSection(Bcb->BaseAddress,
|
||||||
CcpLock();
|
&Bcb->FileOffset,
|
||||||
Bcb->RefCount--;
|
&Map->FileSizes.FileSize,
|
||||||
|
Bcb->Dirty);
|
||||||
|
CcpLock();
|
||||||
|
Bcb->RefCount--;
|
||||||
|
|
||||||
Bcb->Dirty = FALSE;
|
Bcb->Dirty = FALSE;
|
||||||
|
|
||||||
ListEntry = ListEntry->Flink;
|
ListEntry = ListEntry->Flink;
|
||||||
if (Delete && Bcb->RefCount < 2)
|
if (Delete && Bcb->RefCount < 2)
|
||||||
{
|
{
|
||||||
Bcb->RefCount = 1;
|
Bcb->RefCount = 1;
|
||||||
CcpDereferenceCache((ULONG)(Bcb - CcCacheSections), FALSE);
|
CcpDereferenceCache((ULONG)(Bcb - CcCacheSections), FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CcpUnpinData(Bcb, TRUE);
|
{
|
||||||
}
|
CcpUnpinData(Bcb, TRUE);
|
||||||
else
|
}
|
||||||
{
|
}
|
||||||
ListEntry = ListEntry->Flink;
|
else
|
||||||
CcpUnpinData(Bcb, TRUE);
|
{
|
||||||
}
|
ListEntry = ListEntry->Flink;
|
||||||
|
CcpUnpinData(Bcb, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("End loop\n");
|
||||||
|
}
|
||||||
|
CcpUnlock();
|
||||||
|
|
||||||
DPRINT("End loop\n");
|
|
||||||
}
|
|
||||||
CcpUnlock();
|
|
||||||
|
|
||||||
if (IoStatus) *IoStatus = IOSB;
|
if (IoStatus) *IoStatus = IOSB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,25 +227,24 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
{
|
{
|
||||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
||||||
|
|
||||||
// Not cached
|
/* Not cached */
|
||||||
if (!Map)
|
if (!Map)
|
||||||
{
|
{
|
||||||
if (IoStatus)
|
if (IoStatus)
|
||||||
{
|
{
|
||||||
IoStatus->Status = STATUS_SUCCESS;
|
IoStatus->Status = STATUS_SUCCESS;
|
||||||
IoStatus->Information = 0;
|
IoStatus->Information = 0;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CcpFlushCache(Map, FileOffset, Length, IoStatus, TRUE);
|
CcpFlushCache(Map, FileOffset, Length, IoStatus, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcFlushImageSection
|
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
(PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
MMFLUSH_TYPE FlushType)
|
||||||
MMFLUSH_TYPE FlushType)
|
|
||||||
{
|
{
|
||||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
||||||
PNOCC_BCB Bcb;
|
PNOCC_BCB Bcb;
|
||||||
|
@ -241,93 +252,91 @@ CcFlushImageSection
|
||||||
IO_STATUS_BLOCK IOSB;
|
IO_STATUS_BLOCK IOSB;
|
||||||
BOOLEAN Result = TRUE;
|
BOOLEAN Result = TRUE;
|
||||||
|
|
||||||
if (!Map) return TRUE;
|
if (!Map) return TRUE;
|
||||||
|
|
||||||
for (Entry = Map->AssociatedBcb.Flink;
|
for (Entry = Map->AssociatedBcb.Flink;
|
||||||
Entry != &Map->AssociatedBcb;
|
Entry != &Map->AssociatedBcb;
|
||||||
Entry = Entry->Flink)
|
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)
|
switch (FlushType)
|
||||||
{
|
{
|
||||||
case MmFlushForDelete:
|
case MmFlushForDelete:
|
||||||
CcPurgeCacheSection
|
CcPurgeCacheSection(SectionObjectPointer,
|
||||||
(SectionObjectPointer,
|
&Bcb->FileOffset,
|
||||||
&Bcb->FileOffset,
|
Bcb->Length,
|
||||||
Bcb->Length,
|
FALSE);
|
||||||
FALSE);
|
break;
|
||||||
break;
|
case MmFlushForWrite:
|
||||||
case MmFlushForWrite:
|
CcFlushCache(SectionObjectPointer,
|
||||||
CcFlushCache
|
&Bcb->FileOffset,
|
||||||
(SectionObjectPointer,
|
Bcb->Length,
|
||||||
&Bcb->FileOffset,
|
&IOSB);
|
||||||
Bcb->Length,
|
break;
|
||||||
&IOSB);
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always succeeds for us
|
/* Always succeeds for us */
|
||||||
PVOID
|
PVOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRemapBcb(IN PVOID Bcb)
|
CcRemapBcb(IN PVOID Bcb)
|
||||||
{
|
{
|
||||||
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
|
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
|
||||||
CcpLock();
|
CcpLock();
|
||||||
ASSERT(RtlTestBit(CcCacheBitmap, Number));
|
ASSERT(RtlTestBit(CcCacheBitmap, Number));
|
||||||
CcpReferenceCache(Number);
|
CcpReferenceCache(Number);
|
||||||
CcpUnlock();
|
CcpUnlock();
|
||||||
return Bcb;
|
return Bcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcShutdownSystem()
|
CcShutdownSystem(VOID)
|
||||||
{
|
{
|
||||||
ULONG i, Result;
|
ULONG i, Result;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT1("CC: Shutdown\n");
|
DPRINT1("CC: Shutdown\n");
|
||||||
|
|
||||||
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
|
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
|
||||||
{
|
{
|
||||||
PNOCC_BCB Bcb = &CcCacheSections[i];
|
PNOCC_BCB Bcb = &CcCacheSections[i];
|
||||||
if (Bcb->SectionObject)
|
if (Bcb->SectionObject)
|
||||||
{
|
{
|
||||||
DPRINT1
|
DPRINT1("Evicting #%02x %08x%08x %wZ\n",
|
||||||
("Evicting #%02x %08x%08x %wZ\n",
|
i,
|
||||||
i,
|
Bcb->FileOffset.u.HighPart,
|
||||||
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart,
|
Bcb->FileOffset.u.LowPart,
|
||||||
&MmGetFileObjectForSection
|
&MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName);
|
||||||
((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName);
|
|
||||||
CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE);
|
|
||||||
Bcb->Dirty = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evict all section pages
|
CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE);
|
||||||
Status = MiRosTrimCache(~0, 0, &Result);
|
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
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcRepinBcb(IN PVOID Bcb)
|
CcRepinBcb(IN PVOID Bcb)
|
||||||
{
|
{
|
||||||
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
|
ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
|
||||||
CcpLock();
|
CcpLock();
|
||||||
ASSERT(RtlTestBit(CcCacheBitmap, Number));
|
ASSERT(RtlTestBit(CcCacheBitmap, Number));
|
||||||
DPRINT("CcRepinBcb(#%x)\n", Number);
|
DPRINT("CcRepinBcb(#%x)\n", Number);
|
||||||
CcpReferenceCache(Number);
|
CcpReferenceCache(Number);
|
||||||
CcpUnlock();
|
CcpUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -340,13 +349,13 @@ CcUnpinRepinnedBcb(IN PVOID Bcb,
|
||||||
|
|
||||||
if (WriteThrough)
|
if (WriteThrough)
|
||||||
{
|
{
|
||||||
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
|
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
|
||||||
|
|
||||||
CcpFlushCache
|
CcpFlushCache(RealBcb->Map,
|
||||||
(RealBcb->Map,
|
&RealBcb->FileOffset,
|
||||||
&RealBcb->FileOffset,
|
RealBcb->Length,
|
||||||
RealBcb->Length,
|
IoStatus,
|
||||||
IoStatus, RealBcb->Dirty);
|
RealBcb->Dirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
CcUnpinData(Bcb);
|
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;
|
PVOID Bcb;
|
||||||
PCHAR BufferTarget = (PCHAR)Buffer;
|
PCHAR BufferTarget = (PCHAR)Buffer;
|
||||||
LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
|
LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
|
||||||
|
|
||||||
DPRINT
|
DPRINT("CcCopyRead(%x,%x,%d,%d,%x)\n",
|
||||||
("CcCopyRead(%x,%x,%d,%d,%x)\n",
|
FileObject,
|
||||||
FileObject,
|
FileOffset->LowPart,
|
||||||
FileOffset->LowPart,
|
Length,
|
||||||
Length,
|
Wait,
|
||||||
Wait,
|
Buffer);
|
||||||
Buffer);
|
|
||||||
|
|
||||||
CacheOffset.QuadPart = FileOffset->QuadPart;
|
CacheOffset.QuadPart = FileOffset->QuadPart;
|
||||||
EndOfExtent.QuadPart = FileOffset->QuadPart + Length;
|
EndOfExtent.QuadPart = FileOffset->QuadPart + Length;
|
||||||
|
|
||||||
while (CacheOffset.QuadPart < EndOfExtent.QuadPart)
|
while (CacheOffset.QuadPart < EndOfExtent.QuadPart)
|
||||||
{
|
{
|
||||||
NextOffset.QuadPart = CacheOffset.QuadPart;
|
NextOffset.QuadPart = CacheOffset.QuadPart;
|
||||||
NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
|
NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
|
||||||
ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
|
ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
|
||||||
if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
|
if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
|
||||||
{
|
{
|
||||||
ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
|
ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Reading %d bytes in this go (at %08x%08x)\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
|
DPRINT("Reading %d bytes in this go (at %08x%08x)\n",
|
||||||
|
ReadLen,
|
||||||
if (!CcPinRead
|
CacheOffset.HighPart,
|
||||||
(FileObject,
|
CacheOffset.LowPart);
|
||||||
&CacheOffset,
|
|
||||||
ReadLen,
|
if (!CcPinRead(FileObject,
|
||||||
Wait ? PIN_WAIT : PIN_IF_BCB,
|
&CacheOffset,
|
||||||
&Bcb,
|
ReadLen,
|
||||||
(PVOID*)&ReadBuffer))
|
Wait ? PIN_WAIT : PIN_IF_BCB,
|
||||||
{
|
&Bcb,
|
||||||
IoStatus->Status = STATUS_UNSUCCESSFUL;
|
(PVOID*)&ReadBuffer))
|
||||||
IoStatus->Information = 0;
|
{
|
||||||
DPRINT("Failed CcCopyRead\n");
|
IoStatus->Status = STATUS_UNSUCCESSFUL;
|
||||||
return FALSE;
|
IoStatus->Information = 0;
|
||||||
}
|
DPRINT("Failed CcCopyRead\n");
|
||||||
|
return FALSE;
|
||||||
DPRINT("Copying %d bytes at %08x%08x\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
|
}
|
||||||
RtlCopyMemory
|
|
||||||
(BufferTarget,
|
DPRINT("Copying %d bytes at %08x%08x\n",
|
||||||
ReadBuffer,
|
ReadLen,
|
||||||
ReadLen);
|
CacheOffset.HighPart,
|
||||||
|
CacheOffset.LowPart);
|
||||||
BufferTarget += ReadLen;
|
|
||||||
|
RtlCopyMemory(BufferTarget, ReadBuffer, ReadLen);
|
||||||
CacheOffset = NextOffset;
|
|
||||||
CcUnpinData(Bcb);
|
BufferTarget += ReadLen;
|
||||||
|
|
||||||
|
CacheOffset = NextOffset;
|
||||||
|
CcUnpinData(Bcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
IoStatus->Status = STATUS_SUCCESS;
|
IoStatus->Status = STATUS_SUCCESS;
|
||||||
IoStatus->Information = Length;
|
IoStatus->Information = Length;
|
||||||
|
|
||||||
DPRINT("Done with CcCopyRead\n");
|
DPRINT("Done with CcCopyRead\n");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,58 +133,72 @@ CcCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
IN BOOLEAN Wait,
|
IN BOOLEAN Wait,
|
||||||
IN PVOID Buffer)
|
IN PVOID Buffer)
|
||||||
{
|
{
|
||||||
INT Count = 0;
|
INT Count = 0;
|
||||||
BOOLEAN Result;
|
BOOLEAN Result;
|
||||||
PNOCC_BCB Bcb;
|
PNOCC_BCB Bcb;
|
||||||
PVOID WriteBuf;
|
PVOID WriteBuf;
|
||||||
ULONG WriteLen;
|
ULONG WriteLen;
|
||||||
LARGE_INTEGER CurrentOffset = *FileOffset;
|
LARGE_INTEGER CurrentOffset = *FileOffset;
|
||||||
LARGE_INTEGER EndOffset;
|
LARGE_INTEGER EndOffset;
|
||||||
LARGE_INTEGER NextOffset;
|
LARGE_INTEGER NextOffset;
|
||||||
|
|
||||||
EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
|
EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
|
||||||
|
|
||||||
DPRINT
|
DPRINT("CcCopyWrite(%x,%x,%d,%d,%x)\n",
|
||||||
("CcCopyWrite(%x,%x,%d,%d,%x)\n",
|
FileObject,
|
||||||
FileObject,
|
FileOffset->LowPart,
|
||||||
FileOffset->LowPart,
|
Length,
|
||||||
Length,
|
Wait,
|
||||||
Wait,
|
Buffer);
|
||||||
Buffer);
|
|
||||||
|
|
||||||
while (CurrentOffset.QuadPart < EndOffset.QuadPart)
|
while (CurrentOffset.QuadPart < EndOffset.QuadPart)
|
||||||
{
|
{
|
||||||
NextOffset.HighPart = CurrentOffset.HighPart;
|
NextOffset.HighPart = CurrentOffset.HighPart;
|
||||||
NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
|
NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
|
||||||
DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
|
DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
|
||||||
WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
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;
|
CLIENT_ID CcUnmapThreadId, CcLazyWriteThreadId;
|
||||||
FAST_MUTEX GlobalPageOperation;
|
FAST_MUTEX GlobalPageOperation;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
A note about private cache maps.
|
A note about private cache maps.
|
||||||
|
|
||||||
CcInitializeCacheMap and CcUninitializeCacheMap are not meant to be paired,
|
CcInitializeCacheMap and CcUninitializeCacheMap are not meant to be paired,
|
||||||
although they can work that way.
|
although they can work that way.
|
||||||
|
@ -40,7 +40,7 @@ and real filesystems is this:
|
||||||
CcInitializeCacheMap means:
|
CcInitializeCacheMap means:
|
||||||
|
|
||||||
Make the indicated FILE_OBJECT have a private cache map if it doesn't already
|
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:
|
CcUninitializeCacheMap means:
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ flusing all cached information.
|
||||||
Using these simple semantics, filesystems can do all the things they actually
|
Using these simple semantics, filesystems can do all the things they actually
|
||||||
do:
|
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.
|
and store it in the fcb cache.
|
||||||
- Copy it back into any file object and call CcInitializeCacheMap to make
|
- 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.
|
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
|
typedef struct _NOCC_PRIVATE_CACHE_MAP
|
||||||
{
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PNOCC_CACHE_MAP Map;
|
PNOCC_CACHE_MAP Map;
|
||||||
} NOCC_PRIVATE_CACHE_MAP, *PNOCC_PRIVATE_CACHE_MAP;
|
} NOCC_PRIVATE_CACHE_MAP, *PNOCC_PRIVATE_CACHE_MAP;
|
||||||
|
|
||||||
LIST_ENTRY CcpAllSharedCacheMaps;
|
LIST_ENTRY CcpAllSharedCacheMaps;
|
||||||
|
@ -81,25 +81,28 @@ BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcInitializeCacheManager(VOID)
|
CcInitializeCacheManager(VOID)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DPRINT("Initialize\n");
|
DPRINT("Initialize\n");
|
||||||
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
|
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
|
||||||
{
|
{
|
||||||
KeInitializeEvent(&CcCacheSections[i].ExclusiveWait, SynchronizationEvent, FALSE);
|
KeInitializeEvent(&CcCacheSections[i].ExclusiveWait,
|
||||||
InitializeListHead(&CcCacheSections[i].ThisFileList);
|
SynchronizationEvent,
|
||||||
}
|
FALSE);
|
||||||
|
|
||||||
InitializeListHead(&CcpAllSharedCacheMaps);
|
InitializeListHead(&CcCacheSections[i].ThisFileList);
|
||||||
|
}
|
||||||
|
|
||||||
KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
|
InitializeListHead(&CcpAllSharedCacheMaps);
|
||||||
KeInitializeEvent(&CcFinalizeEvent, SynchronizationEvent, FALSE);
|
|
||||||
KeInitializeEvent(&CcpLazyWriteEvent, SynchronizationEvent, FALSE);
|
|
||||||
|
|
||||||
CcCacheBitmap->Buffer = ((PULONG)&CcCacheBitmap[1]);
|
KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
|
||||||
CcCacheBitmap->SizeOfBitMap = ROUND_UP(CACHE_NUM_SECTIONS, 32);
|
KeInitializeEvent(&CcFinalizeEvent, SynchronizationEvent, FALSE);
|
||||||
DPRINT1("Cache has %d entries\n", CcCacheBitmap->SizeOfBitMap);
|
KeInitializeEvent(&CcpLazyWriteEvent, SynchronizationEvent, FALSE);
|
||||||
ExInitializeFastMutex(&CcMutex);
|
|
||||||
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -125,16 +128,16 @@ BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcpAcquireFileLock(PNOCC_CACHE_MAP Map)
|
CcpAcquireFileLock(PNOCC_CACHE_MAP Map)
|
||||||
{
|
{
|
||||||
DPRINT("Calling AcquireForLazyWrite: %x\n", Map->LazyContext);
|
DPRINT("Calling AcquireForLazyWrite: %x\n", Map->LazyContext);
|
||||||
return Map->Callbacks.AcquireForLazyWrite(Map->LazyContext, TRUE);
|
return Map->Callbacks.AcquireForLazyWrite(Map->LazyContext, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcpReleaseFileLock(PNOCC_CACHE_MAP Map)
|
CcpReleaseFileLock(PNOCC_CACHE_MAP Map)
|
||||||
{
|
{
|
||||||
DPRINT("Releasing Lazy Write %x\n", Map->LazyContext);
|
DPRINT("Releasing Lazy Write %x\n", Map->LazyContext);
|
||||||
Map->Callbacks.ReleaseFromLazyWrite(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.
|
itself.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
// Must have CcpLock()
|
|
||||||
|
/* Must have CcpLock() */
|
||||||
PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject)
|
PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY Entry, Private;
|
PLIST_ENTRY Entry, Private;
|
||||||
for (Entry = CcpAllSharedCacheMaps.Flink;
|
for (Entry = CcpAllSharedCacheMaps.Flink;
|
||||||
Entry != &CcpAllSharedCacheMaps;
|
Entry != &CcpAllSharedCacheMaps;
|
||||||
Entry = Entry->Flink)
|
Entry = Entry->Flink)
|
||||||
{
|
{
|
||||||
// 'Identical' test for other stream file object
|
/* 'Identical' test for other stream file object */
|
||||||
PNOCC_CACHE_MAP Map = CONTAINING_RECORD(Entry, NOCC_CACHE_MAP, Entry);
|
PNOCC_CACHE_MAP Map = CONTAINING_RECORD(Entry, NOCC_CACHE_MAP, Entry);
|
||||||
for (Private = Map->PrivateCacheMaps.Flink;
|
for (Private = Map->PrivateCacheMaps.Flink;
|
||||||
Private != &Map->PrivateCacheMaps;
|
Private != &Map->PrivateCacheMaps;
|
||||||
Private = Private->Flink)
|
Private = Private->Flink)
|
||||||
{
|
{
|
||||||
PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private, NOCC_PRIVATE_CACHE_MAP, ListEntry);
|
PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private,
|
||||||
if (PrivateMap->FileObject->Flags & FO_STREAM_FILE &&
|
NOCC_PRIVATE_CACHE_MAP,
|
||||||
PrivateMap->FileObject->DeviceObject == FileObject->DeviceObject &&
|
ListEntry);
|
||||||
PrivateMap->FileObject->Vpb == FileObject->Vpb &&
|
|
||||||
PrivateMap->FileObject->FsContext == FileObject->FsContext &&
|
if (PrivateMap->FileObject->Flags & FO_STREAM_FILE &&
|
||||||
PrivateMap->FileObject->FsContext2 == FileObject->FsContext2 &&
|
PrivateMap->FileObject->DeviceObject == FileObject->DeviceObject &&
|
||||||
1)
|
PrivateMap->FileObject->Vpb == FileObject->Vpb &&
|
||||||
{
|
PrivateMap->FileObject->FsContext == FileObject->FsContext &&
|
||||||
return PrivateMap->FileObject;
|
PrivateMap->FileObject->FsContext2 == FileObject->FsContext2 &&
|
||||||
}
|
1)
|
||||||
}
|
{
|
||||||
}
|
return PrivateMap->FileObject;
|
||||||
return 0;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
|
CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
|
||||||
|
@ -189,55 +196,64 @@ CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
|
||||||
IN PCACHE_MANAGER_CALLBACKS Callbacks,
|
IN PCACHE_MANAGER_CALLBACKS Callbacks,
|
||||||
IN PVOID LazyWriteContext)
|
IN PVOID LazyWriteContext)
|
||||||
{
|
{
|
||||||
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
|
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
|
||||||
|
|
||||||
CcpLock();
|
CcpLock();
|
||||||
/* We don't have a shared cache map. First find out if we have a sibling
|
/* We don't have a shared cache map. First find out if we have a sibling
|
||||||
stream file object we can take it from. */
|
stream file object we can take it from. */
|
||||||
if (!Map && FileObject->Flags & FO_STREAM_FILE)
|
if (!Map && FileObject->Flags & FO_STREAM_FILE)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT IdenticalStreamFileObject =
|
PFILE_OBJECT IdenticalStreamFileObject = CcpFindOtherStreamFileObject(FileObject);
|
||||||
CcpFindOtherStreamFileObject(FileObject);
|
if (IdenticalStreamFileObject)
|
||||||
if (IdenticalStreamFileObject)
|
Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
|
if (Map)
|
||||||
if (Map)
|
{
|
||||||
{
|
DPRINT1("Linking SFO %x to previous SFO %x through cache map %x #\n",
|
||||||
DPRINT1
|
FileObject,
|
||||||
("Linking SFO %x to previous SFO %x through cache map %x #\n",
|
IdenticalStreamFileObject,
|
||||||
FileObject, IdenticalStreamFileObject, Map);
|
Map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* We still don't have a shared cache map. We need to create one. */
|
/* We still don't have a shared cache map. We need to create one. */
|
||||||
if (!Map)
|
if (!Map)
|
||||||
{
|
{
|
||||||
DPRINT("Initializing file object for (%p) %wZ\n", FileObject, &FileObject->FileName);
|
DPRINT("Initializing file object for (%p) %wZ\n",
|
||||||
Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
|
FileObject,
|
||||||
FileObject->SectionObjectPointer->SharedCacheMap = Map;
|
&FileObject->FileName);
|
||||||
Map->FileSizes = *FileSizes;
|
|
||||||
Map->LazyContext = LazyWriteContext;
|
Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
|
||||||
Map->ReadAheadGranularity = PAGE_SIZE;
|
FileObject->SectionObjectPointer->SharedCacheMap = Map;
|
||||||
RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));
|
Map->FileSizes = *FileSizes;
|
||||||
// For now ...
|
Map->LazyContext = LazyWriteContext;
|
||||||
DPRINT("FileSizes->ValidDataLength %08x%08x\n", FileSizes->ValidDataLength.HighPart, FileSizes->ValidDataLength.LowPart);
|
Map->ReadAheadGranularity = PAGE_SIZE;
|
||||||
InitializeListHead(&Map->AssociatedBcb);
|
RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));
|
||||||
InitializeListHead(&Map->PrivateCacheMaps);
|
|
||||||
InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry);
|
/* For now ... */
|
||||||
DPRINT("New Map %x\n", Map);
|
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
|
/* 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
|
to serve as a held reference. When the list in the shared cache map
|
||||||
is empty, we know we can delete it. */
|
is empty, we know we can delete it. */
|
||||||
if (!PrivateCacheMap)
|
if (!PrivateCacheMap)
|
||||||
{
|
{
|
||||||
PrivateCacheMap = ExAllocatePool(NonPagedPool, sizeof(*PrivateCacheMap));
|
PrivateCacheMap = ExAllocatePool(NonPagedPool,
|
||||||
FileObject->PrivateCacheMap = PrivateCacheMap;
|
sizeof(*PrivateCacheMap));
|
||||||
PrivateCacheMap->FileObject = FileObject;
|
|
||||||
ObReferenceObject(PrivateCacheMap->FileObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivateCacheMap->Map = Map;
|
FileObject->PrivateCacheMap = PrivateCacheMap;
|
||||||
InsertTailList(&Map->PrivateCacheMaps, &PrivateCacheMap->ListEntry);
|
PrivateCacheMap->FileObject = FileObject;
|
||||||
|
ObReferenceObject(PrivateCacheMap->FileObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrivateCacheMap->Map = Map;
|
||||||
|
InsertTailList(&Map->PrivateCacheMaps, &PrivateCacheMap->ListEntry);
|
||||||
|
|
||||||
CcpUnlock();
|
CcpUnlock();
|
||||||
}
|
}
|
||||||
|
@ -254,12 +270,14 @@ ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
CcpCountCacheSections(IN PNOCC_CACHE_MAP Map)
|
CcpCountCacheSections(IN PNOCC_CACHE_MAP Map)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
ULONG Count;
|
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
|
BOOLEAN
|
||||||
|
@ -268,59 +286,63 @@ CcUninitializeCacheMap(IN PFILE_OBJECT FileObject,
|
||||||
IN OPTIONAL PLARGE_INTEGER TruncateSize,
|
IN OPTIONAL PLARGE_INTEGER TruncateSize,
|
||||||
IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
|
IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
|
||||||
{
|
{
|
||||||
BOOLEAN LastMap = FALSE;
|
BOOLEAN LastMap = FALSE;
|
||||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
|
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
|
||||||
|
|
||||||
DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n", &FileObject->FileName, FileObject->SectionObjectPointer);
|
DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n",
|
||||||
|
&FileObject->FileName,
|
||||||
|
FileObject->SectionObjectPointer);
|
||||||
|
|
||||||
ASSERT(UninitializeEvent == NULL);
|
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. */
|
kicks. */
|
||||||
if (Map)
|
if (Map)
|
||||||
CcpFlushCache(Map, NULL, 0, NULL, FALSE);
|
CcpFlushCache(Map, NULL, 0, NULL, FALSE);
|
||||||
|
|
||||||
CcpLock();
|
CcpLock();
|
||||||
/* We have a private cache map, so we've been initialized and haven't been
|
/* We have a private cache map, so we've been initialized and haven't been
|
||||||
* uninitialized. */
|
* uninitialized. */
|
||||||
if (PrivateCacheMap)
|
if (PrivateCacheMap)
|
||||||
{
|
{
|
||||||
ASSERT(!Map || Map == PrivateCacheMap->Map);
|
ASSERT(!Map || Map == PrivateCacheMap->Map);
|
||||||
ASSERT(PrivateCacheMap->FileObject == FileObject);
|
ASSERT(PrivateCacheMap->FileObject == FileObject);
|
||||||
|
|
||||||
RemoveEntryList(&PrivateCacheMap->ListEntry);
|
RemoveEntryList(&PrivateCacheMap->ListEntry);
|
||||||
/* That was the last private cache map. It's time to delete all
|
/* That was the last private cache map. It's time to delete all
|
||||||
cache stripes and all aspects of caching on the file. */
|
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. */
|
/* Get rid of all the cache stripes. */
|
||||||
while (!IsListEmpty(&PrivateCacheMap->Map->AssociatedBcb))
|
while (!IsListEmpty(&PrivateCacheMap->Map->AssociatedBcb))
|
||||||
{
|
{
|
||||||
PNOCC_BCB Bcb = CONTAINING_RECORD(PrivateCacheMap->Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
|
PNOCC_BCB Bcb = CONTAINING_RECORD(PrivateCacheMap->Map->AssociatedBcb.Flink,
|
||||||
DPRINT("Evicting cache stripe #%x\n", Bcb - CcCacheSections);
|
NOCC_BCB,
|
||||||
Bcb->RefCount = 1;
|
ThisFileList);
|
||||||
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();
|
|
||||||
|
|
||||||
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;
|
return LastMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
CcSetFileSizes is used to tell the cache manager that the file changed
|
CcSetFileSizes is used to tell the cache manager that the file changed
|
||||||
size. In our case, we use the internal Mm method MmExtendCacheSection
|
size. In our case, we use the internal Mm method MmExtendCacheSection
|
||||||
|
@ -338,20 +360,19 @@ CcSetFileSizes(IN PFILE_OBJECT FileObject,
|
||||||
|
|
||||||
if (!Map) return;
|
if (!Map) return;
|
||||||
Map->FileSizes = *FileSizes;
|
Map->FileSizes = *FileSizes;
|
||||||
Bcb = Map->AssociatedBcb.Flink == &Map->AssociatedBcb ?
|
Bcb = Map->AssociatedBcb.Flink == &Map->AssociatedBcb ?
|
||||||
NULL : CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
|
NULL : CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
|
||||||
if (!Bcb) return;
|
if (!Bcb) return;
|
||||||
MmExtendCacheSection(Bcb->SectionObject, &FileSizes->FileSize, FALSE);
|
MmExtendCacheSection(Bcb->SectionObject, &FileSizes->FileSize, FALSE);
|
||||||
DPRINT("FileSizes->FileSize %x\n", FileSizes->FileSize.LowPart);
|
DPRINT("FileSizes->FileSize %x\n", FileSizes->FileSize.LowPart);
|
||||||
DPRINT("FileSizes->AllocationSize %x\n", FileSizes->AllocationSize.LowPart);
|
DPRINT("FileSizes->AllocationSize %x\n", FileSizes->AllocationSize.LowPart);
|
||||||
DPRINT("FileSizes->ValidDataLength %x\n", FileSizes->ValidDataLength.LowPart);
|
DPRINT("FileSizes->ValidDataLength %x\n", FileSizes->ValidDataLength.LowPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcGetFileSizes
|
CcGetFileSizes(IN PFILE_OBJECT FileObject,
|
||||||
(IN PFILE_OBJECT FileObject,
|
IN PCC_FILE_SIZES FileSizes)
|
||||||
IN PCC_FILE_SIZES FileSizes)
|
|
||||||
{
|
{
|
||||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
if (!Map) return FALSE;
|
if (!Map) return FALSE;
|
||||||
|
@ -366,10 +387,10 @@ CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
IN BOOLEAN UninitializeCacheMaps)
|
IN BOOLEAN UninitializeCacheMaps)
|
||||||
{
|
{
|
||||||
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
|
||||||
if (!Map) return TRUE;
|
if (!Map) return TRUE;
|
||||||
CcpFlushCache(Map, NULL, 0, NULL, TRUE);
|
CcpFlushCache(Map, NULL, 0, NULL, TRUE);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -380,12 +401,12 @@ CcSetDirtyPageThreshold(IN PFILE_OBJECT FileObject,
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
while (TRUE);
|
while (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This could be implemented much more intelligently by mapping instances
|
This could be implemented much more intelligently by mapping instances
|
||||||
of a CoW zero page into the affected regions. We just RtlZeroMemory
|
of a CoW zero page into the affected regions. We just RtlZeroMemory
|
||||||
for now.
|
for now.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
@ -396,156 +417,212 @@ CcZeroData(IN PFILE_OBJECT FileObject,
|
||||||
IN BOOLEAN Wait)
|
IN BOOLEAN Wait)
|
||||||
{
|
{
|
||||||
PNOCC_BCB Bcb = NULL;
|
PNOCC_BCB Bcb = NULL;
|
||||||
PLIST_ENTRY ListEntry = NULL;
|
PLIST_ENTRY ListEntry = NULL;
|
||||||
LARGE_INTEGER LowerBound = *StartOffset;
|
LARGE_INTEGER LowerBound = *StartOffset;
|
||||||
LARGE_INTEGER UpperBound = *EndOffset;
|
LARGE_INTEGER UpperBound = *EndOffset;
|
||||||
LARGE_INTEGER Target, End;
|
LARGE_INTEGER Target, End;
|
||||||
PVOID PinnedBcb, PinnedBuffer;
|
PVOID PinnedBcb, PinnedBuffer;
|
||||||
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
|
|
||||||
DPRINT
|
DPRINT("S %08x%08x E %08x%08x\n",
|
||||||
("S %08x%08x E %08x%08x\n",
|
StartOffset->u.HighPart,
|
||||||
StartOffset->u.HighPart, StartOffset->u.LowPart,
|
StartOffset->u.LowPart,
|
||||||
EndOffset->u.HighPart, EndOffset->u.LowPart);
|
EndOffset->u.HighPart,
|
||||||
|
EndOffset->u.LowPart);
|
||||||
|
|
||||||
if (!Map)
|
if (!Map)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
IO_STATUS_BLOCK IOSB;
|
IO_STATUS_BLOCK IOSB;
|
||||||
PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
|
PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
|
||||||
ULONG ToWrite;
|
ULONG ToWrite;
|
||||||
|
|
||||||
if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
|
if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
|
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
|
||||||
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
|
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
|
||||||
|
|
||||||
Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
|
Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
|
||||||
End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);
|
End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);
|
||||||
|
|
||||||
// Handle leading page
|
// Handle leading page
|
||||||
if (LowerBound.QuadPart != Target.QuadPart)
|
if (LowerBound.QuadPart != Target.QuadPart)
|
||||||
{
|
{
|
||||||
ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart, (PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
|
ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart,
|
||||||
DPRINT("Zero last half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
|
(PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
|
DPRINT("Zero last half %08x%08x %x\n",
|
||||||
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
|
Target.u.HighPart,
|
||||||
|
Target.u.LowPart,
|
||||||
while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
|
ToWrite);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UpperBound.QuadPart > Target.QuadPart)
|
Status = MiSimpleRead(FileObject,
|
||||||
{
|
&Target,
|
||||||
ToWrite = UpperBound.QuadPart - Target.QuadPart;
|
ZeroBuf,
|
||||||
DPRINT("Zero first half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
|
PAGE_SIZE,
|
||||||
Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, TRUE, &IOSB);
|
TRUE,
|
||||||
if (!NT_SUCCESS(Status))
|
&IOSB);
|
||||||
{
|
|
||||||
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);
|
if (!NT_SUCCESS(Status))
|
||||||
return TRUE;
|
{
|
||||||
}
|
ExFreePool(ZeroBuf);
|
||||||
|
RtlRaiseStatus(Status);
|
||||||
CcpLock();
|
}
|
||||||
ListEntry = Map->AssociatedBcb.Flink;
|
|
||||||
|
|
||||||
while (ListEntry != &Map->AssociatedBcb)
|
DPRINT1("RtlZeroMemory(%x,%x)\n",
|
||||||
{
|
ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
|
||||||
Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
|
ToWrite);
|
||||||
CcpReferenceCache(Bcb - CcCacheSections);
|
|
||||||
|
|
||||||
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
|
RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
|
||||||
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
|
ToWrite);
|
||||||
{
|
|
||||||
DPRINT
|
|
||||||
("Bcb #%x (@%08x%08x)\n",
|
|
||||||
Bcb - CcCacheSections,
|
|
||||||
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
|
|
||||||
|
|
||||||
Target.QuadPart = MAX(Bcb->FileOffset.QuadPart, LowerBound.QuadPart);
|
Status = MiSimpleWrite(FileObject,
|
||||||
End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart, UpperBound.QuadPart);
|
&Target,
|
||||||
End.QuadPart = MIN(End.QuadPart, Bcb->FileOffset.QuadPart + Bcb->Length);
|
ZeroBuf,
|
||||||
CcpUnlock();
|
MIN(PAGE_SIZE,
|
||||||
|
UpperBound.QuadPart-Target.QuadPart),
|
||||||
|
&IOSB);
|
||||||
|
|
||||||
if (!CcPreparePinWrite
|
if (!NT_SUCCESS(Status))
|
||||||
(FileObject,
|
{
|
||||||
&Target,
|
ExFreePool(ZeroBuf);
|
||||||
End.QuadPart - Target.QuadPart,
|
RtlRaiseStatus(Status);
|
||||||
TRUE,
|
}
|
||||||
Wait,
|
Target.QuadPart += PAGE_SIZE;
|
||||||
&PinnedBcb,
|
}
|
||||||
&PinnedBuffer))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(PinnedBcb == Bcb);
|
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
|
||||||
|
RtlZeroMemory(ZeroBuf, PAGE_SIZE);
|
||||||
|
|
||||||
CcpLock();
|
while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
|
||||||
ListEntry = ListEntry->Flink;
|
{
|
||||||
// Return from pin state
|
DPRINT("Zero full page %08x%08x\n",
|
||||||
CcpUnpinData(PinnedBcb, TRUE);
|
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
|
PFILE_OBJECT
|
||||||
NTAPI
|
NTAPI
|
||||||
CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
|
CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT Result = NULL;
|
PFILE_OBJECT Result = NULL;
|
||||||
PNOCC_CACHE_MAP Map = SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = SectionObjectPointer->SharedCacheMap;
|
||||||
CcpLock();
|
CcpLock();
|
||||||
if (!IsListEmpty(&Map->AssociatedBcb))
|
if (!IsListEmpty(&Map->AssociatedBcb))
|
||||||
{
|
{
|
||||||
PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
|
PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink,
|
||||||
Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject);
|
NOCC_BCB,
|
||||||
}
|
ThisFileList);
|
||||||
CcpUnlock();
|
|
||||||
|
Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject);
|
||||||
|
}
|
||||||
|
CcpUnlock();
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,9 +630,9 @@ PFILE_OBJECT
|
||||||
NTAPI
|
NTAPI
|
||||||
CcGetFileObjectFromBcb(PVOID Bcb)
|
CcGetFileObjectFromBcb(PVOID Bcb)
|
||||||
{
|
{
|
||||||
PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
|
PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
|
||||||
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
|
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
|
||||||
return MmGetFileObjectForSection((PROS_SECTION_OBJECT)RealBcb->SectionObject);
|
return MmGetFileObjectForSection((PROS_SECTION_OBJECT)RealBcb->SectionObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
2
reactos/ntoskrnl/cache/lazyrite.c
vendored
2
reactos/ntoskrnl/cache/lazyrite.c
vendored
|
@ -22,7 +22,7 @@ KEVENT CcpLazyWriteEvent;
|
||||||
VOID NTAPI
|
VOID NTAPI
|
||||||
CcpLazyWriteThread(PVOID Unused)
|
CcpLazyWriteThread(PVOID Unused)
|
||||||
{
|
{
|
||||||
/* Not implemented */
|
/* Not implemented */
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
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 PVOID LogHandle,
|
||||||
IN PFLUSH_TO_LSN FlushToLsnRoutine)
|
IN PFLUSH_TO_LSN FlushToLsnRoutine)
|
||||||
{
|
{
|
||||||
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
if (!Map) return;
|
if (!Map) return;
|
||||||
Map->LogHandle = LogHandle;
|
Map->LogHandle = LogHandle;
|
||||||
Map->FlushToLsn = FlushToLsnRoutine;
|
Map->FlushToLsn = FlushToLsnRoutine;
|
||||||
}
|
}
|
||||||
|
|
||||||
LARGE_INTEGER
|
LARGE_INTEGER
|
||||||
|
|
102
reactos/ntoskrnl/cache/mdlsup.c
vendored
102
reactos/ntoskrnl/cache/mdlsup.c
vendored
|
@ -16,55 +16,47 @@
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
PMDL
|
PMDL
|
||||||
NTAPI
|
NTAPI
|
||||||
CcpBuildCacheMdl
|
CcpBuildCacheMdl(PFILE_OBJECT FileObject,
|
||||||
(PFILE_OBJECT FileObject,
|
PLARGE_INTEGER FileOffset,
|
||||||
PLARGE_INTEGER FileOffset,
|
ULONG Length,
|
||||||
ULONG Length,
|
PIO_STATUS_BLOCK IOSB)
|
||||||
PIO_STATUS_BLOCK IOSB)
|
|
||||||
{
|
{
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
PVOID Bcb, Buffer;
|
PVOID Bcb, Buffer;
|
||||||
|
|
||||||
BOOLEAN Result = CcMapData
|
BOOLEAN Result = CcMapData(FileObject,
|
||||||
(FileObject,
|
FileOffset,
|
||||||
FileOffset,
|
Length,
|
||||||
Length,
|
PIN_WAIT,
|
||||||
PIN_WAIT,
|
&Bcb,
|
||||||
&Bcb,
|
&Buffer);
|
||||||
&Buffer);
|
|
||||||
|
|
||||||
if (!Result)
|
if (!Result)
|
||||||
{
|
{
|
||||||
IOSB->Information = 0;
|
IOSB->Information = 0;
|
||||||
IOSB->Status = STATUS_UNSUCCESSFUL;
|
IOSB->Status = STATUS_UNSUCCESSFUL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IOSB->Information = Length;
|
|
||||||
IOSB->Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
Mdl = IoAllocateMdl
|
|
||||||
(Buffer,
|
|
||||||
Length,
|
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!Mdl)
|
IOSB->Information = Length;
|
||||||
{
|
IOSB->Status = STATUS_SUCCESS;
|
||||||
IOSB->Information = 0;
|
|
||||||
IOSB->Status = STATUS_NO_MEMORY;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
IOSB->Information = Length;
|
Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
|
||||||
IOSB->Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
return Mdl;
|
if (!Mdl)
|
||||||
|
{
|
||||||
|
IOSB->Information = 0;
|
||||||
|
IOSB->Status = STATUS_NO_MEMORY;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOSB->Information = Length;
|
||||||
|
IOSB->Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
return Mdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -75,29 +67,25 @@ CcMdlRead(IN PFILE_OBJECT FileObject,
|
||||||
OUT PMDL *MdlChain,
|
OUT PMDL *MdlChain,
|
||||||
OUT PIO_STATUS_BLOCK IoStatus)
|
OUT PIO_STATUS_BLOCK IoStatus)
|
||||||
{
|
{
|
||||||
*MdlChain = CcpBuildCacheMdl
|
*MdlChain = CcpBuildCacheMdl(FileObject, FileOffset, Length, IoStatus);
|
||||||
(FileObject,
|
|
||||||
FileOffset,
|
|
||||||
Length,
|
|
||||||
IoStatus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcMdlReadComplete(IN PFILE_OBJECT FileObject,
|
CcMdlReadComplete(IN PFILE_OBJECT FileObject,
|
||||||
IN PMDL MdlChain)
|
IN PMDL MdlChain)
|
||||||
{
|
{
|
||||||
IoFreeMdl(MdlChain);
|
IoFreeMdl(MdlChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcMdlReadComplete2(IN PMDL MdlChain,
|
CcMdlReadComplete2(IN PMDL MdlChain,
|
||||||
IN PFILE_OBJECT FileObject)
|
IN PFILE_OBJECT FileObject)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
|
CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
|
||||||
|
@ -106,11 +94,7 @@ CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
|
||||||
OUT PMDL *MdlChain,
|
OUT PMDL *MdlChain,
|
||||||
OUT PIO_STATUS_BLOCK IoStatus)
|
OUT PIO_STATUS_BLOCK IoStatus)
|
||||||
{
|
{
|
||||||
*MdlChain = CcpBuildCacheMdl
|
*MdlChain = CcpBuildCacheMdl(FileObject, FileOffset, Length, IoStatus);
|
||||||
(FileObject,
|
|
||||||
FileOffset,
|
|
||||||
Length,
|
|
||||||
IoStatus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -119,7 +103,7 @@ CcMdlWriteComplete(IN PFILE_OBJECT FileObject,
|
||||||
IN PLARGE_INTEGER FileOffset,
|
IN PLARGE_INTEGER FileOffset,
|
||||||
IN PMDL MdlChain)
|
IN PMDL MdlChain)
|
||||||
{
|
{
|
||||||
IoFreeMdl(MdlChain);
|
IoFreeMdl(MdlChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -128,7 +112,7 @@ CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
|
||||||
IN PLARGE_INTEGER FileOffset,
|
IN PLARGE_INTEGER FileOffset,
|
||||||
IN PMDL MdlChain)
|
IN PMDL MdlChain)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -136,8 +120,8 @@ NTAPI
|
||||||
CcMdlWriteAbort(IN PFILE_OBJECT FileObject,
|
CcMdlWriteAbort(IN PFILE_OBJECT FileObject,
|
||||||
IN PMDL MdlChain)
|
IN PMDL MdlChain)
|
||||||
{
|
{
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
IoFreeMdl(MdlChain);
|
IoFreeMdl(MdlChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* 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 part */
|
||||||
PUBLIC_BCB Bcb;
|
PUBLIC_BCB Bcb;
|
||||||
|
|
||||||
struct _NOCC_CACHE_MAP *Map;
|
struct _NOCC_CACHE_MAP *Map;
|
||||||
PROS_SECTION_OBJECT SectionObject;
|
PROS_SECTION_OBJECT SectionObject;
|
||||||
LARGE_INTEGER FileOffset;
|
LARGE_INTEGER FileOffset;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
BOOLEAN Dirty;
|
BOOLEAN Dirty;
|
||||||
PVOID OwnerPointer;
|
PVOID OwnerPointer;
|
||||||
|
|
||||||
/* Reference counts */
|
/* Reference counts */
|
||||||
ULONG RefCount;
|
ULONG RefCount;
|
||||||
|
|
||||||
LIST_ENTRY ThisFileList;
|
LIST_ENTRY ThisFileList;
|
||||||
|
|
||||||
KEVENT ExclusiveWait;
|
KEVENT ExclusiveWait;
|
||||||
ULONG ExclusiveWaiter;
|
ULONG ExclusiveWaiter;
|
||||||
BOOLEAN Exclusive;
|
BOOLEAN Exclusive;
|
||||||
|
@ -25,39 +25,33 @@ typedef struct _NOCC_BCB
|
||||||
|
|
||||||
typedef struct _NOCC_CACHE_MAP
|
typedef struct _NOCC_CACHE_MAP
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
LIST_ENTRY AssociatedBcb;
|
LIST_ENTRY AssociatedBcb;
|
||||||
LIST_ENTRY PrivateCacheMaps;
|
LIST_ENTRY PrivateCacheMaps;
|
||||||
ULONG NumberOfMaps;
|
ULONG NumberOfMaps;
|
||||||
ULONG RefCount;
|
ULONG RefCount;
|
||||||
CC_FILE_SIZES FileSizes;
|
CC_FILE_SIZES FileSizes;
|
||||||
CACHE_MANAGER_CALLBACKS Callbacks;
|
CACHE_MANAGER_CALLBACKS Callbacks;
|
||||||
PVOID LazyContext;
|
PVOID LazyContext;
|
||||||
PVOID LogHandle;
|
PVOID LogHandle;
|
||||||
PFLUSH_TO_LSN FlushToLsn;
|
PFLUSH_TO_LSN FlushToLsn;
|
||||||
ULONG ReadAheadGranularity;
|
ULONG ReadAheadGranularity;
|
||||||
} NOCC_CACHE_MAP, *PNOCC_CACHE_MAP;
|
} NOCC_CACHE_MAP, *PNOCC_CACHE_MAP;
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcPfInitializePrefetcher(
|
CcPfInitializePrefetcher(VOID);
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcMdlReadComplete2(
|
CcMdlReadComplete2(IN PMDL MemoryDescriptorList,
|
||||||
IN PMDL MemoryDescriptorList,
|
IN PFILE_OBJECT FileObject);
|
||||||
IN PFILE_OBJECT FileObject
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcMdlWriteComplete2(
|
CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
|
||||||
IN PFILE_OBJECT FileObject,
|
IN PLARGE_INTEGER FileOffset,
|
||||||
IN PLARGE_INTEGER FileOffset,
|
IN PMDL MdlChain);
|
||||||
IN PMDL MdlChain
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -65,7 +59,8 @@ CcInitView(VOID);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcpUnpinData(PNOCC_BCB Bcb, BOOLEAN ActuallyRelease);
|
CcpUnpinData(PNOCC_BCB Bcb,
|
||||||
|
BOOLEAN ActuallyRelease);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -82,24 +77,25 @@ CcInitCacheZeroPage(VOID);
|
||||||
/* Called by section.c */
|
/* Called by section.c */
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer, MMFLUSH_TYPE FlushType);
|
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||||
|
MMFLUSH_TYPE FlushType);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
_CcpFlushCache
|
_CcpFlushCache(IN PNOCC_CACHE_MAP Map,
|
||||||
(IN PNOCC_CACHE_MAP Map,
|
IN OPTIONAL PLARGE_INTEGER FileOffset,
|
||||||
IN OPTIONAL PLARGE_INTEGER FileOffset,
|
IN ULONG Length,
|
||||||
IN ULONG Length,
|
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
|
||||||
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
|
BOOLEAN Delete,
|
||||||
BOOLEAN Delete,
|
const char *File,
|
||||||
const char *File,
|
int Line);
|
||||||
int Line);
|
|
||||||
|
|
||||||
#define CcpFlushCache(M,F,L,I,D) _CcpFlushCache(M,F,L,I,D,__FILE__,__LINE__)
|
#define CcpFlushCache(M,F,L,I,D) _CcpFlushCache(M,F,L,I,D,__FILE__,__LINE__)
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcGetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
|
CcGetFileSizes(PFILE_OBJECT FileObject,
|
||||||
|
PCC_FILE_SIZES FileSizes);
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -125,13 +121,13 @@ CcpReleaseFileLock(PNOCC_CACHE_MAP Map);
|
||||||
/* Private data */
|
/* Private data */
|
||||||
|
|
||||||
#define CACHE_SINGLE_FILE_MAX (16)
|
#define CACHE_SINGLE_FILE_MAX (16)
|
||||||
#define CACHE_OVERALL_SIZE (32 * 1024 * 1024)
|
#define CACHE_OVERALL_SIZE (32 * 1024 * 1024)
|
||||||
#define CACHE_STRIPE VACB_MAPPING_GRANULARITY
|
#define CACHE_STRIPE VACB_MAPPING_GRANULARITY
|
||||||
#define CACHE_SHIFT 18
|
#define CACHE_SHIFT 18
|
||||||
#define CACHE_NUM_SECTIONS (CACHE_OVERALL_SIZE / CACHE_STRIPE)
|
#define CACHE_NUM_SECTIONS (CACHE_OVERALL_SIZE / CACHE_STRIPE)
|
||||||
#define CACHE_ROUND_UP(x) (((x) + (CACHE_STRIPE-1)) & ~(CACHE_STRIPE-1))
|
#define CACHE_ROUND_UP(x) (((x) + (CACHE_STRIPE-1)) & ~(CACHE_STRIPE-1))
|
||||||
#define CACHE_ROUND_DOWN(x) ((x) & ~(CACHE_STRIPE-1))
|
#define CACHE_ROUND_DOWN(x) ((x) & ~(CACHE_STRIPE-1))
|
||||||
#define INVALID_CACHE ((ULONG)~0)
|
#define INVALID_CACHE ((ULONG)~0)
|
||||||
|
|
||||||
extern NOCC_BCB CcCacheSections[CACHE_NUM_SECTIONS];
|
extern NOCC_BCB CcCacheSections[CACHE_NUM_SECTIONS];
|
||||||
extern PRTL_BITMAP CcCacheBitmap;
|
extern PRTL_BITMAP CcCacheBitmap;
|
||||||
|
@ -149,20 +145,20 @@ extern VOID _CcpUnlock(const char *file, int line);
|
||||||
|
|
||||||
extern VOID CcpReferenceCache(ULONG Sector);
|
extern VOID CcpReferenceCache(ULONG Sector);
|
||||||
extern VOID CcpDereferenceCache(ULONG Sector, BOOLEAN Immediate);
|
extern VOID CcpDereferenceCache(ULONG Sector, BOOLEAN Immediate);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcpMapData
|
CcpMapData(IN PFILE_OBJECT FileObject,
|
||||||
(IN PFILE_OBJECT FileObject,
|
IN PLARGE_INTEGER FileOffset,
|
||||||
IN PLARGE_INTEGER FileOffset,
|
IN ULONG Length,
|
||||||
IN ULONG Length,
|
IN ULONG Flags,
|
||||||
IN ULONG Flags,
|
OUT PVOID *BcbResult,
|
||||||
OUT PVOID *BcbResult,
|
OUT PVOID *Buffer);
|
||||||
OUT PVOID *Buffer);
|
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
CcpPinMappedData(IN PNOCC_CACHE_MAP Map,
|
CcpPinMappedData(IN PNOCC_CACHE_MAP Map,
|
||||||
IN PLARGE_INTEGER FileOffset,
|
IN PLARGE_INTEGER FileOffset,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
IN ULONG Flags,
|
IN ULONG Flags,
|
||||||
IN OUT PVOID *Bcb);
|
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,
|
caller. This lends itself to code that has a simple, structured form,
|
||||||
doesn't make assumptions about lock taking and breaking, and provides an
|
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
|
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
|
function pointer in the provided MM_REQUIRED_RESOURCES struct and return
|
||||||
STATUS_MORE_PROCESSING_REQUIRED. The function indicated will receive the
|
STATUS_MORE_PROCESSING_REQUIRED. The function indicated will receive the
|
||||||
provided struct and take action outside of any mm related locks and at
|
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.
|
Multiple stage handling of a not-present fault in a data section.
|
||||||
|
|
||||||
Required->State is used to accumulate flags that indicate the next action
|
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
|
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
|
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)
|
Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
if (Region->Protect == PAGE_READWRITE ||
|
if (Region->Protect == PAGE_READWRITE ||
|
||||||
Region->Protect == PAGE_EXECUTE_READWRITE)
|
Region->Protect == PAGE_EXECUTE_READWRITE)
|
||||||
#endif
|
#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
|
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
|
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.
|
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
|
MmpSectionAccsesFaultInner. It increments a fault depth count in the current
|
||||||
thread.
|
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);
|
return IoGetRelatedDeviceObject(FileObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
This completion function is really required. Paging io completion does almost
|
This completion function is really required. Paging io completion does almost
|
||||||
nothing, including freeing the mdls.
|
nothing, including freeing the mdls.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -282,7 +282,7 @@ FAST_MUTEX MiWriteMutex;
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Function which uses MiSimpleWrite to write back a single page to a file.
|
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
|
made a bit more efficient by avoiding the copy and making a system space
|
||||||
mdl.
|
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
|
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
|
MM_REQUIRED_RESOURCES with a pointer to the desired function and configure
|
||||||
the other members as below.
|
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:
|
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:
|
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
|
This file implements the section page table. It relies on rtl generic table
|
||||||
functionality to provide access to 256-page chunks. Calls to
|
functionality to provide access to 256-page chunks. Calls to
|
||||||
MiSetPageEntrySectionSegment and MiGetPageEntrySectionSegment must be
|
MiSetPageEntrySectionSegment and MiGetPageEntrySectionSegment must be
|
||||||
synchronized by holding the segment lock.
|
synchronized by holding the segment lock.
|
||||||
|
|
||||||
Each page table entry is a ULONG as in x86.
|
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
|
automatically maintain the segment rmap by calling MmSetSectionAssociation
|
||||||
and MmDeleteSectionAssociation. Segment rmaps are discussed in rmap.c. The
|
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
|
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.
|
paging machinery.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -310,10 +310,10 @@ MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment,
|
||||||
DPRINT("Done\n");
|
DPRINT("Done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Retrieves the MM_SECTION_SEGMENT and fills in the LARGE_INTEGER Offset given
|
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
|
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
|
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
|
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
|
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
|
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
|
written to protect against cases where a fault brings a stale copy of the page
|
||||||
back before writing is complete.
|
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
|
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
|
approriate. One small niggle here is that we might be holding the last
|
||||||
reference to the section segment associated with this page. That happens
|
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
|
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
|
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
|
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
|
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
|
Also misleading is the call to MmReleasePageMemoryConsumer, which releases
|
||||||
the reference held by this address space only. After all address spaces
|
the reference held by this address space only. After all address spaces
|
||||||
|
@ -319,7 +319,7 @@ MmPageOutCacheSection(PMMSUPPORT AddressSpace,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This function is called by rmap when spare pages are needed by the blancer.
|
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
|
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
|
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
|
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
|
STATUS_MORE_PROCESSING_REQUIRED and placing a pointer to a function from
|
||||||
reqtools.c in the MM_REQUIRED_RESOURCES struct.
|
reqtools.c in the MM_REQUIRED_RESOURCES struct.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue