[FORMATTING]

* Addendum to r56262.

svn path=/trunk/; revision=56273
This commit is contained in:
Amine Khaldi 2012-03-29 12:14:58 +00:00
parent 4d61c55638
commit aabb4465a0
13 changed files with 1259 additions and 1151 deletions

View file

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

View file

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

View file

@ -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 */

View file

@ -22,7 +22,7 @@ KEVENT CcpLazyWriteEvent;
VOID NTAPI
CcpLazyWriteThread(PVOID Unused)
{
/* Not implemented */
/* Not implemented */
}
NTSTATUS

View file

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

View file

@ -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 */

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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