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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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