diff --git a/reactos/ntoskrnl/cache/cachesub.c b/reactos/ntoskrnl/cache/cachesub.c index c8e918d15fb..f9a949d69d0 100644 --- a/reactos/ntoskrnl/cache/cachesub.c +++ b/reactos/ntoskrnl/cache/cachesub.c @@ -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); diff --git a/reactos/ntoskrnl/cache/copysup.c b/reactos/ntoskrnl/cache/copysup.c index ae6e0532495..eb344ee50b5 100644 --- a/reactos/ntoskrnl/cache/copysup.c +++ b/reactos/ntoskrnl/cache/copysup.c @@ -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 diff --git a/reactos/ntoskrnl/cache/fssup.c b/reactos/ntoskrnl/cache/fssup.c index 188382fedef..4b4bc15cf23 100644 --- a/reactos/ntoskrnl/cache/fssup.c +++ b/reactos/ntoskrnl/cache/fssup.c @@ -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 */ diff --git a/reactos/ntoskrnl/cache/lazyrite.c b/reactos/ntoskrnl/cache/lazyrite.c index b478ae6f4d0..a7ff7998d7b 100644 --- a/reactos/ntoskrnl/cache/lazyrite.c +++ b/reactos/ntoskrnl/cache/lazyrite.c @@ -22,7 +22,7 @@ KEVENT CcpLazyWriteEvent; VOID NTAPI CcpLazyWriteThread(PVOID Unused) { - /* Not implemented */ + /* Not implemented */ } NTSTATUS diff --git a/reactos/ntoskrnl/cache/logsup.c b/reactos/ntoskrnl/cache/logsup.c index bdf2f89f9d7..6c5f3540ed5 100644 --- a/reactos/ntoskrnl/cache/logsup.c +++ b/reactos/ntoskrnl/cache/logsup.c @@ -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 diff --git a/reactos/ntoskrnl/cache/mdlsup.c b/reactos/ntoskrnl/cache/mdlsup.c index 79a1c5aeec4..9f705b50b8b 100644 --- a/reactos/ntoskrnl/cache/mdlsup.c +++ b/reactos/ntoskrnl/cache/mdlsup.c @@ -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 */ diff --git a/reactos/ntoskrnl/cache/newcc.h b/reactos/ntoskrnl/cache/newcc.h index 416a417d1ef..2e34a53ed3e 100644 --- a/reactos/ntoskrnl/cache/newcc.h +++ b/reactos/ntoskrnl/cache/newcc.h @@ -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); diff --git a/reactos/ntoskrnl/cache/pinsup.c b/reactos/ntoskrnl/cache/pinsup.c index e316e245476..ada1a53ddc1 100644 --- a/reactos/ntoskrnl/cache/pinsup.c +++ b/reactos/ntoskrnl/cache/pinsup.c @@ -17,8 +17,9 @@ /* The following is a test mode that only works with modified filesystems. * it maps the cache sections read only until they're pinned writable, and then - * turns them readonly again when they're unpinned. + * turns them readonly again when they're unpinned. * This helped me determine that a certain bug was not a memory overwrite. */ + //#define PIN_WRITE_ONLY /* @@ -28,7 +29,7 @@ Pinsup implements the core of NewCC. A couple of things about this code: I wrote this code over the course of about 2 years, often referring to Rajeev -Nagar's Filesystem Internals, book, the msdn pages on the Cc interface, and +Nagar's Filesystem Internals, book, the msdn pages on the Cc interface, and a few NT filesystems that are open sourced. I went to fairly great lengths to achieve a couple of goals. @@ -68,7 +69,7 @@ All BCB pointers yielded to a driver are a pointer to one of these cache stripe structures. The data structure is specified as opaque and so it contains information convenient to NEWCC's implementation here. Free entries are summarized in CcpBitmapBuffer, for which bits are set when the entry may be -safely evicted and redirected for use by another client. Note that the +safely evicted and redirected for use by another client. Note that the reference count for an evictable cache section will generally be 1, since we'll keep a reference to wait for any subsequent mapping of the same stripe. We use CcCacheClockHand as a hint to start checking free bits at a point that @@ -106,13 +107,18 @@ LONG CcOutstandingDeletes; /* FUNCTIONS ******************************************************************/ PETHREAD LastThread; -VOID _CcpLock(const char *file, int line) + +VOID +_CcpLock(const char *file, + int line) { //DPRINT("<<<---<<< CC In Mutex(%s:%d %x)!\n", file, line, PsGetCurrentThread()); ExAcquireFastMutex(&CcMutex); } -VOID _CcpUnlock(const char *file, int line) +VOID +_CcpUnlock(const char *file, + int line) { ExReleaseFastMutex(&CcMutex); //DPRINT(">>>--->>> CC Exit Mutex!\n", file, line); @@ -130,43 +136,43 @@ should not count when determining whether the file can be resized. */ -NTSTATUS CcpAllocateSection -(PFILE_OBJECT FileObject, - ULONG Length, - ULONG Protect, - PROS_SECTION_OBJECT *Result) +NTSTATUS +CcpAllocateSection(PFILE_OBJECT FileObject, + ULONG Length, + ULONG Protect, + PROS_SECTION_OBJECT *Result) { NTSTATUS Status; LARGE_INTEGER MaxSize; MaxSize.QuadPart = Length; - DPRINT("Making Section for File %x\n", FileObject); - DPRINT("File name %wZ\n", &FileObject->FileName); - Status = MmCreateSection - ((PVOID*)Result, - STANDARD_RIGHTS_REQUIRED, - NULL, - &MaxSize, - Protect, - SEC_RESERVE | SEC_CACHE, - NULL, - FileObject); - + DPRINT("Making Section for File %x\n", FileObject); + DPRINT("File name %wZ\n", &FileObject->FileName); + + Status = MmCreateSection((PVOID*)Result, + STANDARD_RIGHTS_REQUIRED, + NULL, + &MaxSize, + Protect, + SEC_RESERVE | SEC_CACHE, + NULL, + FileObject); + return Status; } -typedef struct _WORK_QUEUE_WITH_CONTEXT -{ - WORK_QUEUE_ITEM WorkItem; - PVOID ToUnmap; - LARGE_INTEGER FileOffset; - LARGE_INTEGER MapSize; - PROS_SECTION_OBJECT ToDeref; - PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite; - PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite; - PVOID LazyContext; - BOOLEAN Dirty; +typedef struct _WORK_QUEUE_WITH_CONTEXT +{ + WORK_QUEUE_ITEM WorkItem; + PVOID ToUnmap; + LARGE_INTEGER FileOffset; + LARGE_INTEGER MapSize; + PROS_SECTION_OBJECT ToDeref; + PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite; + PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite; + PVOID LazyContext; + BOOLEAN Dirty; } WORK_QUEUE_WITH_CONTEXT, *PWORK_QUEUE_WITH_CONTEXT; /* @@ -180,20 +186,20 @@ is uninitialized in the last file object, or a cache stripe is evicted. VOID CcpUnmapCache(PVOID Context) { - PWORK_QUEUE_WITH_CONTEXT WorkItem = (PWORK_QUEUE_WITH_CONTEXT)Context; - DPRINT("Unmapping (finally) %x\n", WorkItem->ToUnmap); - MmUnmapCacheViewInSystemSpace(WorkItem->ToUnmap); - ObDereferenceObject(WorkItem->ToDeref); - ExFreePool(WorkItem); - DPRINT("Done\n"); + PWORK_QUEUE_WITH_CONTEXT WorkItem = (PWORK_QUEUE_WITH_CONTEXT)Context; + DPRINT("Unmapping (finally) %x\n", WorkItem->ToUnmap); + MmUnmapCacheViewInSystemSpace(WorkItem->ToUnmap); + ObDereferenceObject(WorkItem->ToDeref); + ExFreePool(WorkItem); + DPRINT("Done\n"); } /* -Somewhat deceptively named function which removes the last reference to a +Somewhat deceptively named function which removes the last reference to a cache stripe and completely removes it using CcUnmapCache. This may be done either inline (if the Immediate BOOLEAN is set), or using a work item -at a later time. Whether this is called to unmap immeidately is mainly +at a later time. Whether this is called to unmap immeidately is mainly determined by whether the caller is calling from a place in filesystem code where a deadlock may occur if immediate flushing is required. @@ -203,29 +209,31 @@ this. */ /* Must have acquired the mutex */ -VOID CcpDereferenceCache(ULONG Start, BOOLEAN Immediate) +VOID +CcpDereferenceCache(ULONG Start, + BOOLEAN Immediate) { - PVOID ToUnmap; + PVOID ToUnmap; PNOCC_BCB Bcb; - BOOLEAN Dirty; - LARGE_INTEGER MappedSize; - LARGE_INTEGER BaseOffset; - PWORK_QUEUE_WITH_CONTEXT WorkItem; + BOOLEAN Dirty; + LARGE_INTEGER MappedSize; + LARGE_INTEGER BaseOffset; + PWORK_QUEUE_WITH_CONTEXT WorkItem; DPRINT("CcpDereferenceCache(#%x)\n", Start); Bcb = &CcCacheSections[Start]; - Dirty = Bcb->Dirty; - ToUnmap = Bcb->BaseAddress; - BaseOffset = Bcb->FileOffset; - MappedSize = Bcb->Map->FileSizes.ValidDataLength; + Dirty = Bcb->Dirty; + ToUnmap = Bcb->BaseAddress; + BaseOffset = Bcb->FileOffset; + MappedSize = Bcb->Map->FileSizes.ValidDataLength; DPRINT("Dereference #%x (count %d)\n", Start, Bcb->RefCount); ASSERT(Bcb->SectionObject); ASSERT(Bcb->RefCount == 1); - - DPRINT("Firing work item for %x\n", Bcb->BaseAddress); + + DPRINT("Firing work item for %x\n", Bcb->BaseAddress); if (Dirty) { CcpUnlock(); @@ -235,52 +243,54 @@ VOID CcpDereferenceCache(ULONG Start, BOOLEAN Immediate) CcpLock(); } - if (Immediate) - { - PROS_SECTION_OBJECT ToDeref = Bcb->SectionObject; - Bcb->Map = NULL; - Bcb->SectionObject = NULL; - Bcb->BaseAddress = NULL; - Bcb->FileOffset.QuadPart = 0; - Bcb->Length = 0; - Bcb->RefCount = 0; - Bcb->Dirty = FALSE; - RemoveEntryList(&Bcb->ThisFileList); + if (Immediate) + { + PROS_SECTION_OBJECT ToDeref = Bcb->SectionObject; + Bcb->Map = NULL; + Bcb->SectionObject = NULL; + Bcb->BaseAddress = NULL; + Bcb->FileOffset.QuadPart = 0; + Bcb->Length = 0; + Bcb->RefCount = 0; + Bcb->Dirty = FALSE; + RemoveEntryList(&Bcb->ThisFileList); - CcpUnlock(); - MmUnmapCacheViewInSystemSpace(ToUnmap); - ObDereferenceObject(ToDeref); - CcpLock(); - } - else - { - WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem)); - if (!WorkItem) KeBugCheck(0); - WorkItem->ToUnmap = Bcb->BaseAddress; - WorkItem->FileOffset = Bcb->FileOffset; - WorkItem->Dirty = Bcb->Dirty; - WorkItem->MapSize = MappedSize; - WorkItem->ToDeref = Bcb->SectionObject; - WorkItem->AcquireForLazyWrite = Bcb->Map->Callbacks.AcquireForLazyWrite; - WorkItem->ReleaseFromLazyWrite = Bcb->Map->Callbacks.ReleaseFromLazyWrite; - WorkItem->LazyContext = Bcb->Map->LazyContext; - - ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpUnmapCache, WorkItem); - - Bcb->Map = NULL; - Bcb->SectionObject = NULL; - Bcb->BaseAddress = NULL; - Bcb->FileOffset.QuadPart = 0; - Bcb->Length = 0; - Bcb->RefCount = 0; - Bcb->Dirty = FALSE; - RemoveEntryList(&Bcb->ThisFileList); + CcpUnlock(); + MmUnmapCacheViewInSystemSpace(ToUnmap); + ObDereferenceObject(ToDeref); + CcpLock(); + } + else + { + WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem)); + if (!WorkItem) KeBugCheck(0); + WorkItem->ToUnmap = Bcb->BaseAddress; + WorkItem->FileOffset = Bcb->FileOffset; + WorkItem->Dirty = Bcb->Dirty; + WorkItem->MapSize = MappedSize; + WorkItem->ToDeref = Bcb->SectionObject; + WorkItem->AcquireForLazyWrite = Bcb->Map->Callbacks.AcquireForLazyWrite; + WorkItem->ReleaseFromLazyWrite = Bcb->Map->Callbacks.ReleaseFromLazyWrite; + WorkItem->LazyContext = Bcb->Map->LazyContext; - CcpUnlock(); - ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue); - CcpLock(); - } - DPRINT("Done\n"); + ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), + (PWORKER_THREAD_ROUTINE)CcpUnmapCache, + WorkItem); + + Bcb->Map = NULL; + Bcb->SectionObject = NULL; + Bcb->BaseAddress = NULL; + Bcb->FileOffset.QuadPart = 0; + Bcb->Length = 0; + Bcb->RefCount = 0; + Bcb->Dirty = FALSE; + RemoveEntryList(&Bcb->ThisFileList); + + CcpUnlock(); + ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue); + CcpLock(); + } + DPRINT("Done\n"); } /* @@ -296,16 +306,16 @@ on failure. */ /* Needs mutex */ -ULONG CcpAllocateCacheSections -(PFILE_OBJECT FileObject, - PROS_SECTION_OBJECT SectionObject) +ULONG +CcpAllocateCacheSections(PFILE_OBJECT FileObject, + PROS_SECTION_OBJECT SectionObject) { ULONG i = INVALID_CACHE; PNOCC_CACHE_MAP Map; PNOCC_BCB Bcb; - + DPRINT("AllocateCacheSections: FileObject %x\n", FileObject); - + if (!FileObject->SectionObjectPointer) return INVALID_CACHE; @@ -322,27 +332,27 @@ ULONG CcpAllocateCacheSections if (i != INVALID_CACHE) { DPRINT("Setting up Bcb #%x\n", i); - + Bcb = &CcCacheSections[i]; - + ASSERT(Bcb->RefCount < 2); - + if (Bcb->RefCount > 0) { CcpDereferenceCache(i, FALSE); } - + ASSERT(!Bcb->RefCount); Bcb->RefCount = 1; - + DPRINT("Bcb #%x RefCount %d\n", Bcb - CcCacheSections, Bcb->RefCount); - + if (!RtlTestBit(CcCacheBitmap, i)) { DPRINT1("Somebody stoeled BCB #%x\n", i); } ASSERT(RtlTestBit(CcCacheBitmap, i)); - + DPRINT("Allocated #%x\n", i); ASSERT(CcCacheSections[i].RefCount); } @@ -354,7 +364,8 @@ ULONG CcpAllocateCacheSections } /* Must have acquired the mutex */ -VOID CcpReferenceCache(ULONG Start) +VOID +CcpReferenceCache(ULONG Start) { PNOCC_BCB Bcb; Bcb = &CcCacheSections[Start]; @@ -364,7 +375,8 @@ VOID CcpReferenceCache(ULONG Start) } -VOID CcpMarkForExclusive(ULONG Start) +VOID +CcpMarkForExclusive(ULONG Start) { PNOCC_BCB Bcb; Bcb = &CcCacheSections[Start]; @@ -380,11 +392,17 @@ Bcb. */ /* Must not have the mutex */ -VOID CcpReferenceCacheExclusive(ULONG Start) +VOID +CcpReferenceCacheExclusive(ULONG Start) { PNOCC_BCB Bcb = &CcCacheSections[Start]; - KeWaitForSingleObject(&Bcb->ExclusiveWait, Executive, KernelMode, FALSE, NULL); + KeWaitForSingleObject(&Bcb->ExclusiveWait, + Executive, + KernelMode, + FALSE, + NULL); + CcpLock(); ASSERT(Bcb->ExclusiveWaiter); ASSERT(Bcb->SectionObject); @@ -394,10 +412,10 @@ VOID CcpReferenceCacheExclusive(ULONG Start) CcpUnlock(); } -/* +/* Find a map that encompasses the target range. This function does not check -whether the desired range is partly outside the stripe. This could be +whether the desired range is partly outside the stripe. This could be implemented with a generic table, but we generally aren't carring around a lot of segments at once for a particular file. @@ -408,22 +426,25 @@ Returns a valid index or INVALID_CACHE. */ /* Must have the mutex */ -ULONG CcpFindMatchingMap(PLIST_ENTRY Head, PLARGE_INTEGER FileOffset, ULONG Length) +ULONG +CcpFindMatchingMap(PLIST_ENTRY Head, + PLARGE_INTEGER FileOffset, + ULONG Length) { - PLIST_ENTRY Entry; + PLIST_ENTRY Entry; //DPRINT("Find Matching Map: (%x) %x:%x\n", FileOffset->LowPart, Length); for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink) { - //DPRINT("Link @%x\n", Entry); - PNOCC_BCB Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList); - //DPRINT("Selected BCB %x #%x\n", Bcb, Bcb - CcCacheSections); - //DPRINT("This File: %x:%x\n", Bcb->FileOffset.LowPart, Bcb->Length); - if (FileOffset->QuadPart >= Bcb->FileOffset.QuadPart && - FileOffset->QuadPart < Bcb->FileOffset.QuadPart + CACHE_STRIPE) - { - //DPRINT("Found match at #%x\n", Bcb - CcCacheSections); - return Bcb - CcCacheSections; - } + //DPRINT("Link @%x\n", Entry); + PNOCC_BCB Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList); + //DPRINT("Selected BCB %x #%x\n", Bcb, Bcb - CcCacheSections); + //DPRINT("This File: %x:%x\n", Bcb->FileOffset.LowPart, Bcb->Length); + if (FileOffset->QuadPart >= Bcb->FileOffset.QuadPart && + FileOffset->QuadPart < Bcb->FileOffset.QuadPart + CACHE_STRIPE) + { + //DPRINT("Found match at #%x\n", Bcb - CcCacheSections); + return Bcb - CcCacheSections; + } } //DPRINT("This region isn't mapped\n"); @@ -441,256 +462,273 @@ possibly evicting another stripe in order to get our stripe. 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 Success = FALSE, FaultIn = FALSE; /* Note: windows 2000 drivers treat this as a bool */ //BOOLEAN Wait = (Flags & MAP_WAIT) || (Flags == TRUE); LARGE_INTEGER Target, EndInterval; - ULONG BcbHead, SectionSize, ViewSize; + ULONG BcbHead, SectionSize, ViewSize; PNOCC_BCB Bcb = NULL; PROS_SECTION_OBJECT SectionObject = NULL; NTSTATUS Status; - PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; - ViewSize = CACHE_STRIPE; + PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; + ViewSize = CACHE_STRIPE; - if (!Map) - { - DPRINT1("File object was not mapped\n"); - return FALSE; - } + if (!Map) + { + DPRINT1("File object was not mapped\n"); + return FALSE; + } - DPRINT("CcMapData(F->%x,%08x%08x:%d)\n", FileObject, FileOffset->HighPart, FileOffset->LowPart, Length); + DPRINT("CcMapData(F->%x,%08x%08x:%d)\n", + FileObject, + FileOffset->HighPart, + FileOffset->LowPart, + Length); ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); Target.HighPart = FileOffset->HighPart; - Target.LowPart = CACHE_ROUND_DOWN(FileOffset->LowPart); + Target.LowPart = CACHE_ROUND_DOWN(FileOffset->LowPart); CcpLock(); /* Find out if any range is a superset of what we want */ - /* Find an accomodating section */ - BcbHead = CcpFindMatchingMap(&Map->AssociatedBcb, FileOffset, Length); - - if (BcbHead != INVALID_CACHE) - { - Bcb = &CcCacheSections[BcbHead]; - Success = TRUE; - *BcbResult = Bcb; - *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart); - DPRINT - ("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n", - Bcb - CcCacheSections, - Bcb->FileOffset.HighPart, - Bcb->FileOffset.LowPart, - Bcb->BaseAddress, - Bcb->Length, - *Buffer, - Length, - &FileObject->FileName); - DPRINT("w1n\n"); - goto cleanup; - } + /* Find an accomodating section */ + BcbHead = CcpFindMatchingMap(&Map->AssociatedBcb, FileOffset, Length); + + if (BcbHead != INVALID_CACHE) + { + Bcb = &CcCacheSections[BcbHead]; + Success = TRUE; + *BcbResult = Bcb; + *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart); + + DPRINT("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n", + Bcb - CcCacheSections, + Bcb->FileOffset.HighPart, + Bcb->FileOffset.LowPart, + Bcb->BaseAddress, + Bcb->Length, + *Buffer, + Length, + &FileObject->FileName); + + DPRINT("w1n\n"); + goto cleanup; + } + + DPRINT("File size %08x%08x\n", + Map->FileSizes.ValidDataLength.HighPart, + Map->FileSizes.ValidDataLength.LowPart); - DPRINT("File size %08x%08x\n", Map->FileSizes.ValidDataLength.HighPart, Map->FileSizes.ValidDataLength.LowPart); - /* Not all files have length, in fact filesystems often use stream file objects for various internal purposes and are loose about the file length, since the filesystem promises itself to write the right number of bytes to the internal stream. In these cases, we just allow the file to have the full stripe worth of space. */ - if (Map->FileSizes.ValidDataLength.QuadPart) - { - SectionSize = min(CACHE_STRIPE, Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart); - } - else - { - SectionSize = CACHE_STRIPE; - } + if (Map->FileSizes.ValidDataLength.QuadPart) + { + SectionSize = min(CACHE_STRIPE, + Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart); + } + else + { + SectionSize = CACHE_STRIPE; + } - DPRINT("Allocating a cache stripe at %x:%d\n", - Target.LowPart, SectionSize); - //ASSERT(SectionSize <= CACHE_STRIPE); + DPRINT("Allocating a cache stripe at %x:%d\n", + Target.LowPart, SectionSize); - CcpUnlock(); + //ASSERT(SectionSize <= CACHE_STRIPE); + + CcpUnlock(); /* CcpAllocateSection doesn't need the lock, so we'll give other action a chance in here. */ - Status = CcpAllocateSection - (FileObject, - SectionSize, + Status = CcpAllocateSection(FileObject, + SectionSize, #ifdef PIN_WRITE_ONLY - PAGE_READONLY, + PAGE_READONLY, #else - PAGE_READWRITE, + PAGE_READWRITE, #endif - &SectionObject); - CcpLock(); + &SectionObject); + CcpLock(); + + if (!NT_SUCCESS(Status)) + { + *BcbResult = NULL; + *Buffer = NULL; + DPRINT1("End %08x\n", Status); + goto cleanup; + } - if (!NT_SUCCESS(Status)) - { - *BcbResult = NULL; - *Buffer = NULL; - DPRINT1("End %08x\n", Status); - goto cleanup; - } - retry: /* Returns a reference */ - DPRINT("Allocating cache sections: %wZ\n", &FileObject->FileName); - BcbHead = CcpAllocateCacheSections(FileObject, SectionObject); + DPRINT("Allocating cache sections: %wZ\n", &FileObject->FileName); + BcbHead = CcpAllocateCacheSections(FileObject, SectionObject); /* XXX todo: we should handle the immediate fail case here, but don't */ - if (BcbHead == INVALID_CACHE) - { - ULONG i; - DbgPrint("Cache Map:"); - for (i = 0; i < CACHE_NUM_SECTIONS; i++) - { - if (!(i % 64)) DbgPrint("\n"); - DbgPrint("%c", CcCacheSections[i].RefCount + (RtlTestBit(CcCacheBitmap, i) ? '@' : '`')); - } - DbgPrint("\n"); - KeWaitForSingleObject(&CcDeleteEvent, Executive, KernelMode, FALSE, NULL); - goto retry; - } + if (BcbHead == INVALID_CACHE) + { + ULONG i; + DbgPrint("Cache Map:"); + for (i = 0; i < CACHE_NUM_SECTIONS; i++) + { + if (!(i % 64)) DbgPrint("\n"); + DbgPrint("%c", + CcCacheSections[i].RefCount + (RtlTestBit(CcCacheBitmap, i) ? '@' : '`')); + } + DbgPrint("\n"); - DPRINT("BcbHead #%x (final)\n", BcbHead); + KeWaitForSingleObject(&CcDeleteEvent, + Executive, + KernelMode, + FALSE, + NULL); + + goto retry; + } + + DPRINT("BcbHead #%x (final)\n", BcbHead); if (BcbHead == INVALID_CACHE) { - *BcbResult = NULL; - *Buffer = NULL; - DPRINT1("End\n"); - goto cleanup; + *BcbResult = NULL; + *Buffer = NULL; + DPRINT1("End\n"); + goto cleanup; } - + DPRINT("Selected BCB #%x\n", BcbHead); - ViewSize = CACHE_STRIPE; + ViewSize = CACHE_STRIPE; Bcb = &CcCacheSections[BcbHead]; /* MmMapCacheViewInSystemSpaceAtOffset is one of three methods of Mm - that are specific to NewCC. In this case, it's implementation + that are specific to NewCC. In this case, it's implementation exactly mirrors MmMapViewInSystemSpace, but allows an offset to be specified. */ - Status = MmMapCacheViewInSystemSpaceAtOffset - (SectionObject->Segment, - &Bcb->BaseAddress, - &Target, - &ViewSize); - - /* Summary: Failure. Dereference our section and tell the user we failed - */ + Status = MmMapCacheViewInSystemSpaceAtOffset(SectionObject->Segment, + &Bcb->BaseAddress, + &Target, + &ViewSize); + + /* Summary: Failure. Dereference our section and tell the user we failed */ if (!NT_SUCCESS(Status)) { - *BcbResult = NULL; - *Buffer = NULL; - ObDereferenceObject(SectionObject); - RemoveEntryList(&Bcb->ThisFileList); - RtlZeroMemory(Bcb, sizeof(*Bcb)); - RtlClearBit(CcCacheBitmap, BcbHead); - DPRINT1("Failed to map\n"); - goto cleanup; - } - + *BcbResult = NULL; + *Buffer = NULL; + ObDereferenceObject(SectionObject); + RemoveEntryList(&Bcb->ThisFileList); + RtlZeroMemory(Bcb, sizeof(*Bcb)); + RtlClearBit(CcCacheBitmap, BcbHead); + DPRINT1("Failed to map\n"); + goto cleanup; + } + /* Summary: Success. Put together a valid Bcb and link it with the others * in the NOCC_CACHE_MAP. */ - Success = TRUE; - //DPRINT("w1n\n"); + Success = TRUE; + //DPRINT("w1n\n"); - Bcb->Length = MIN(Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart, CACHE_STRIPE); - Bcb->SectionObject = SectionObject; - Bcb->Map = Map; - Bcb->FileOffset = Target; - InsertTailList(&Map->AssociatedBcb, &Bcb->ThisFileList); - - *BcbResult = &CcCacheSections[BcbHead]; - *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart); - FaultIn = TRUE; + Bcb->Length = MIN(Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart, + CACHE_STRIPE); - DPRINT - ("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n", - Bcb - CcCacheSections, - Bcb->FileOffset.HighPart, - Bcb->FileOffset.LowPart, - Bcb->BaseAddress, - Bcb->Length, - *Buffer, - Length, - &FileObject->FileName); + Bcb->SectionObject = SectionObject; + Bcb->Map = Map; + Bcb->FileOffset = Target; + InsertTailList(&Map->AssociatedBcb, &Bcb->ThisFileList); + + *BcbResult = &CcCacheSections[BcbHead]; + *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart); + FaultIn = TRUE; + + DPRINT("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n", + Bcb - CcCacheSections, + Bcb->FileOffset.HighPart, + Bcb->FileOffset.LowPart, + Bcb->BaseAddress, + Bcb->Length, + *Buffer, + Length, + &FileObject->FileName); + + EndInterval.QuadPart = Bcb->FileOffset.QuadPart + Bcb->Length - 1; + ASSERT((EndInterval.QuadPart & ~(CACHE_STRIPE - 1)) == + (Bcb->FileOffset.QuadPart & ~(CACHE_STRIPE - 1))); - EndInterval.QuadPart = Bcb->FileOffset.QuadPart + Bcb->Length - 1; - ASSERT((EndInterval.QuadPart & ~(CACHE_STRIPE - 1)) == (Bcb->FileOffset.QuadPart & ~(CACHE_STRIPE - 1))); - //DPRINT("TERM!\n"); - + cleanup: - CcpUnlock(); - if (Success) - { - if (FaultIn) - { - // Fault in the pages. This forces reads to happen now. - ULONG i; - PCHAR FaultIn = Bcb->BaseAddress; - DPRINT - ("Faulting in pages at this point: file %wZ %08x%08x:%x\n", - &FileObject->FileName, - Bcb->FileOffset.HighPart, - Bcb->FileOffset.LowPart, - Bcb->Length); - for (i = 0; i < Bcb->Length; i += PAGE_SIZE) - { - FaultIn[i] ^= 0; - } - } - ASSERT(Bcb >= CcCacheSections && Bcb < (CcCacheSections + CACHE_NUM_SECTIONS)); - } - else - { - ASSERT(FALSE); - } + CcpUnlock(); + if (Success) + { + if (FaultIn) + { + /* Fault in the pages. This forces reads to happen now. */ + ULONG i; + PCHAR FaultIn = Bcb->BaseAddress; + + DPRINT("Faulting in pages at this point: file %wZ %08x%08x:%x\n", + &FileObject->FileName, + Bcb->FileOffset.HighPart, + Bcb->FileOffset.LowPart, + Bcb->Length); + + for (i = 0; i < Bcb->Length; i += PAGE_SIZE) + { + FaultIn[i] ^= 0; + } + } + ASSERT(Bcb >= CcCacheSections && + Bcb < (CcCacheSections + CACHE_NUM_SECTIONS)); + } + else + { + ASSERT(FALSE); + } return Success; } BOOLEAN NTAPI -CcMapData -(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG Flags, - OUT PVOID *BcbResult, - OUT PVOID *Buffer) +CcMapData(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG Flags, + OUT PVOID *BcbResult, + OUT PVOID *Buffer) { BOOLEAN Result; - Result = CcpMapData - (FileObject, - FileOffset, - Length, - Flags, - BcbResult, - Buffer); - - if (Result) - { - PNOCC_BCB Bcb = (PNOCC_BCB)*BcbResult; - ASSERT(Bcb >= CcCacheSections && Bcb < CcCacheSections + CACHE_NUM_SECTIONS); - ASSERT(Bcb->BaseAddress); - CcpLock(); - CcpReferenceCache(Bcb - CcCacheSections); - CcpUnlock(); - } + Result = CcpMapData(FileObject, + FileOffset, + Length, + Flags, + BcbResult, + Buffer); - return Result; + if (Result) + { + PNOCC_BCB Bcb = (PNOCC_BCB)*BcbResult; + + ASSERT(Bcb >= CcCacheSections && + Bcb < CcCacheSections + CACHE_NUM_SECTIONS); + + ASSERT(Bcb->BaseAddress); + CcpLock(); + CcpReferenceCache(Bcb - CcCacheSections); + CcpUnlock(); + } + + return Result; } /* Used by functions that repin data, CcpPinMappedData does not alter the map, @@ -698,10 +736,10 @@ CcMapData 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) { BOOLEAN Exclusive = Flags & PIN_EXCLUSIVE; ULONG BcbHead; @@ -709,62 +747,62 @@ CcpPinMappedData(IN PNOCC_CACHE_MAP Map, CcpLock(); - ASSERT(Map->AssociatedBcb.Flink == &Map->AssociatedBcb || (CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList) >= CcCacheSections && CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList) < CcCacheSections + CACHE_NUM_SECTIONS)); - BcbHead = CcpFindMatchingMap(&Map->AssociatedBcb, FileOffset, Length); - if (BcbHead == INVALID_CACHE) - { - CcpUnlock(); - return FALSE; - } + ASSERT(Map->AssociatedBcb.Flink == &Map->AssociatedBcb || (CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList) >= CcCacheSections && CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList) < CcCacheSections + CACHE_NUM_SECTIONS)); + BcbHead = CcpFindMatchingMap(&Map->AssociatedBcb, FileOffset, Length); + if (BcbHead == INVALID_CACHE) + { + CcpUnlock(); + return FALSE; + } - TheBcb = &CcCacheSections[BcbHead]; + TheBcb = &CcCacheSections[BcbHead]; if (Exclusive) { - DPRINT("Requesting #%x Exclusive\n", BcbHead); - CcpMarkForExclusive(BcbHead); + DPRINT("Requesting #%x Exclusive\n", BcbHead); + CcpMarkForExclusive(BcbHead); } else { - DPRINT("Reference #%x\n", BcbHead); - CcpReferenceCache(BcbHead); + DPRINT("Reference #%x\n", BcbHead); + CcpReferenceCache(BcbHead); } if (Exclusive) - CcpReferenceCacheExclusive(BcbHead); + CcpReferenceCacheExclusive(BcbHead); - CcpUnlock(); + CcpUnlock(); - *Bcb = TheBcb; + *Bcb = TheBcb; return TRUE; } BOOLEAN NTAPI CcPinMappedData(IN PFILE_OBJECT FileObject, - 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) { - PVOID Buffer; - PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; + PVOID Buffer; + PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; - if (!Map) - { - DPRINT1("Not cached\n"); - return FALSE; - } - - if (CcpMapData(FileObject, FileOffset, Length, Flags, Bcb, &Buffer)) - { - return CcpPinMappedData(Map, FileOffset, Length, Flags, Bcb); - } - else - { - DPRINT1("could not map\n"); - return FALSE; - } + if (!Map) + { + DPRINT1("Not cached\n"); + return FALSE; + } + + if (CcpMapData(FileObject, FileOffset, Length, Flags, Bcb, &Buffer)) + { + return CcpPinMappedData(Map, FileOffset, Length, Flags, Bcb); + } + else + { + DPRINT1("could not map\n"); + return FALSE; + } } BOOLEAN @@ -779,24 +817,19 @@ CcPinRead(IN PFILE_OBJECT FileObject, PNOCC_BCB RealBcb; BOOLEAN Result; - Result = CcPinMappedData - (FileObject, - FileOffset, - Length, - Flags, - Bcb); + Result = CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb); if (Result) { - CcpLock(); - RealBcb = *Bcb; - *Buffer = ((PCHAR)RealBcb->BaseAddress) + (int)(FileOffset->QuadPart - RealBcb->FileOffset.QuadPart); - CcpUnlock(); + CcpLock(); + RealBcb = *Bcb; + *Buffer = ((PCHAR)RealBcb->BaseAddress) + (int)(FileOffset->QuadPart - RealBcb->FileOffset.QuadPart); + CcpUnlock(); } return Result; } - + BOOLEAN NTAPI CcPreparePinWrite(IN PFILE_OBJECT FileObject, @@ -810,56 +843,48 @@ CcPreparePinWrite(IN PFILE_OBJECT FileObject, BOOLEAN Result; PNOCC_BCB RealBcb; #ifdef PIN_WRITE_ONLY - PVOID BaseAddress; - SIZE_T NumberOfBytes; - ULONG OldProtect; + PVOID BaseAddress; + SIZE_T NumberOfBytes; + ULONG OldProtect; #endif - DPRINT("CcPreparePinWrite(%x:%x)\n", Buffer, Length); + DPRINT("CcPreparePinWrite(%x:%x)\n", Buffer, Length); + + Result = CcPinRead(FileObject, FileOffset, Length, Flags, Bcb, Buffer); - Result = CcPinRead - (FileObject, - FileOffset, - Length, - Flags, - Bcb, - Buffer); - if (Result) { - CcpLock(); - RealBcb = *Bcb; + CcpLock(); + RealBcb = *Bcb; #ifdef PIN_WRITE_ONLY - BaseAddress = RealBcb->BaseAddress; - NumberOfBytes = RealBcb->Length; + BaseAddress = RealBcb->BaseAddress; + NumberOfBytes = RealBcb->Length; - MiProtectVirtualMemory - (NULL, - &BaseAddress, - &NumberOfBytes, - PAGE_READWRITE, - &OldProtect); + MiProtectVirtualMemory(NULL, + &BaseAddress, + &NumberOfBytes, + PAGE_READWRITE, + &OldProtect); #endif - CcpUnlock(); - RealBcb->Dirty = TRUE; + CcpUnlock(); + RealBcb->Dirty = TRUE; - if (Zero) - { - DPRINT - ("Zero fill #%x %08x%08x:%x Buffer %x %wZ\n", - RealBcb - CcCacheSections, - FileOffset->u.HighPart, - FileOffset->u.LowPart, - Length, - *Buffer, - &FileObject->FileName); + if (Zero) + { + DPRINT("Zero fill #%x %08x%08x:%x Buffer %x %wZ\n", + RealBcb - CcCacheSections, + FileOffset->u.HighPart, + FileOffset->u.LowPart, + Length, + *Buffer, + &FileObject->FileName); - DPRINT1("RtlZeroMemory(%x,%x)\n", *Buffer, Length); - RtlZeroMemory(*Buffer, Length); - } - } + DPRINT1("RtlZeroMemory(%x,%x)\n", *Buffer, Length); + RtlZeroMemory(*Buffer, Length); + } + } return Result; } @@ -875,17 +900,17 @@ give one up. Note that it's an error to take more than one exclusive reference or to take a non-exclusive reference after an exclusive reference, so detecting or handling that case is not considered. -ReleaseBit is unset if we want to detect when a cache stripe would become +ReleaseBit is unset if we want to detect when a cache stripe would become evictable without actually giving up our reference. We might want to do that if we were going to flush before formally releasing the cache stripe, although that facility is not used meaningfully at this time. -A reference count of exactly 1 means that the stripe could potentially be -reused, but could also be evicted for another mapping. In general, most +A reference count of exactly 1 means that the stripe could potentially be +reused, but could also be evicted for another mapping. In general, most stripes should be in that state most of the time. A reference count of zero means that the Bcb is completely unused. That's the -start state and the state of a Bcb formerly owned by a file that is +start state and the state of a Bcb formerly owned by a file that is uninitialized. */ @@ -896,65 +921,66 @@ CcpUnpinData(IN PNOCC_BCB RealBcb, BOOLEAN ReleaseBit) { if (RealBcb->RefCount <= 2) { - RealBcb->Exclusive = FALSE; - if (RealBcb->ExclusiveWaiter) - { - DPRINT("Triggering exclusive waiter\n"); - KeSetEvent(&RealBcb->ExclusiveWait, IO_NO_INCREMENT, FALSE); - return TRUE; - } + RealBcb->Exclusive = FALSE; + if (RealBcb->ExclusiveWaiter) + { + DPRINT("Triggering exclusive waiter\n"); + KeSetEvent(&RealBcb->ExclusiveWait, IO_NO_INCREMENT, FALSE); + return TRUE; + } } - if (RealBcb->RefCount == 2 && !ReleaseBit) - return FALSE; + if (RealBcb->RefCount == 2 && !ReleaseBit) + return FALSE; if (RealBcb->RefCount > 1) { - DPRINT("Removing one reference #%x\n", RealBcb - CcCacheSections); - RealBcb->RefCount--; - KeSetEvent(&CcDeleteEvent, IO_DISK_INCREMENT, FALSE); + DPRINT("Removing one reference #%x\n", RealBcb - CcCacheSections); + RealBcb->RefCount--; + KeSetEvent(&CcDeleteEvent, IO_DISK_INCREMENT, FALSE); } - if (RealBcb->RefCount == 1) - { - DPRINT("Clearing allocation bit #%x\n", RealBcb - CcCacheSections); + if (RealBcb->RefCount == 1) + { + DPRINT("Clearing allocation bit #%x\n", RealBcb - CcCacheSections); - RtlClearBit(CcCacheBitmap, RealBcb - CcCacheSections); + RtlClearBit(CcCacheBitmap, RealBcb - CcCacheSections); #ifdef PIN_WRITE_ONLY - PVOID BaseAddress = RealBcb->BaseAddress; - SIZE_T NumberOfBytes = RealBcb->Length; - ULONG OldProtect; + PVOID BaseAddress = RealBcb->BaseAddress; + SIZE_T NumberOfBytes = RealBcb->Length; + ULONG OldProtect; - MiProtectVirtualMemory - (NULL, - &BaseAddress, - &NumberOfBytes, - PAGE_READONLY, - &OldProtect); + MiProtectVirtualMemory(NULL, + &BaseAddress, + &NumberOfBytes, + PAGE_READONLY, + &OldProtect); #endif - } + } - return TRUE; + return TRUE; } - + VOID NTAPI CcUnpinData(IN PVOID Bcb) { PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb; ULONG Selected = RealBcb - CcCacheSections; - BOOLEAN Released; + BOOLEAN Released; + + ASSERT(RealBcb >= CcCacheSections && + RealBcb - CcCacheSections < CACHE_NUM_SECTIONS); - ASSERT(RealBcb >= CcCacheSections && RealBcb - CcCacheSections < CACHE_NUM_SECTIONS); DPRINT("CcUnpinData Bcb #%x (RefCount %d)\n", Selected, RealBcb->RefCount); CcpLock(); - Released = CcpUnpinData(RealBcb, FALSE); + Released = CcpUnpinData(RealBcb, FALSE); CcpUnlock(); - if (!Released) { - CcpLock(); - CcpUnpinData(RealBcb, TRUE); - CcpUnlock(); - } + if (!Released) { + CcpLock(); + CcpUnpinData(RealBcb, TRUE); + CcpUnlock(); + } } VOID @@ -966,9 +992,9 @@ CcSetBcbOwnerPointer(IN PVOID Bcb, CcpLock(); CcpReferenceCache(RealBcb - CcCacheSections); RealBcb->OwnerPointer = OwnerPointer; - CcpUnlock(); + CcpUnlock(); } - + VOID NTAPI CcUnpinDataForThread(IN PVOID Bcb, diff --git a/reactos/ntoskrnl/cache/section/fault.c b/reactos/ntoskrnl/cache/section/fault.c index 08519f49467..c2f0a8790bc 100644 --- a/reactos/ntoskrnl/cache/section/fault.c +++ b/reactos/ntoskrnl/cache/section/fault.c @@ -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. diff --git a/reactos/ntoskrnl/cache/section/io.c b/reactos/ntoskrnl/cache/section/io.c index dd32ad3f5f3..432eb5029cd 100644 --- a/reactos/ntoskrnl/cache/section/io.c +++ b/reactos/ntoskrnl/cache/section/io.c @@ -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. diff --git a/reactos/ntoskrnl/cache/section/reqtools.c b/reactos/ntoskrnl/cache/section/reqtools.c index a5a64fa2eda..1dae6b7aa36 100644 --- a/reactos/ntoskrnl/cache/section/reqtools.c +++ b/reactos/ntoskrnl/cache/section/reqtools.c @@ -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: diff --git a/reactos/ntoskrnl/cache/section/sptab.c b/reactos/ntoskrnl/cache/section/sptab.c index 16879b07334..544913cc96a 100644 --- a/reactos/ntoskrnl/cache/section/sptab.c +++ b/reactos/ntoskrnl/cache/section/sptab.c @@ -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 diff --git a/reactos/ntoskrnl/cache/section/swapout.c b/reactos/ntoskrnl/cache/section/swapout.c index e367b5b3cb8..9c8a969caa0 100644 --- a/reactos/ntoskrnl/cache/section/swapout.c +++ b/reactos/ntoskrnl/cache/section/swapout.c @@ -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.