/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel
- * FILE: ntoskrnl/cache/cachesup.c
+ * FILE: ntoskrnl/cache/cachesub.c
* PURPOSE: Logging and configuration routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Art Yerkes
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 ******************************************************************/
IN ULONG Granularity)
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
- if (Map)
- {
- Map->ReadAheadGranularity = Granularity;
- }
+ if (Map)
+ {
+ Map->ReadAheadGranularity = Granularity;
+ }
}
-\f
+
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;
- DPRINT("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
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(&WorkItem->WorkItem,
+ (PWORKER_THREAD_ROUTINE)CcpReadAhead,
+ WorkItem);
+
+ ExQueueWorkItem(&WorkItem->WorkItem, DelayedWorkQueue);
+ DPRINT("Done\n");
}
-\f
+
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
IN BOOLEAN CcInternalCaller)
{
LARGE_INTEGER Result = {{0}};
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_DBGBREAK();
return Result;
}
-\f
+
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 = { };
-
- DPRINT1("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;
- }
-
- 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);
-
- 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(Bcb - CcCacheSections, FALSE);
- }
- else
- CcpUnpinData(Bcb, TRUE);
- }
- else
- {
- ListEntry = ListEntry->Flink;
- CcpUnpinData(Bcb, TRUE);
- }
-
- DPRINT("End loop\n");
- }
- CcpUnlock();
-
+ LARGE_INTEGER LowerBound, UpperBound;
+ PLIST_ENTRY ListEntry;
+ IO_STATUS_BLOCK IOSB;
+
+ RtlZeroMemory(&IOSB, sizeof(IO_STATUS_BLOCK));
+
+ 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;
+ }
+
+ CcpLock();
+ ListEntry = Map->AssociatedBcb.Flink;
+
+ 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);
+
+ 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);
+ }
+
+ DPRINT("End loop\n");
+ }
+ CcpUnlock();
+
if (IoStatus) *IoStatus = IOSB;
}
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
- // Not cached
- if (!Map)
- {
- if (IoStatus)
- {
- IoStatus->Status = STATUS_SUCCESS;
- IoStatus->Information = 0;
- }
- return;
- }
-
- CcpFlushCache(Map, FileOffset, Length, IoStatus, TRUE);
+ /* Not cached */
+ if (!Map)
+ {
+ if (IoStatus)
+ {
+ IoStatus->Status = STATUS_SUCCESS;
+ IoStatus->Information = 0;
+ }
+ return;
+ }
+
+ 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;
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);
-
- 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;
- }
+ Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
+
+ 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;
+ }
}
return Result;
}
-// Always succeeds for us
+/* Always succeeds for us */
PVOID
NTAPI
CcRemapBcb(IN PVOID Bcb)
{
- CcpLock();
- ASSERT(RtlTestBit(CcCacheBitmap, ((PNOCC_BCB)Bcb) - CcCacheSections));
- CcpReferenceCache(((PNOCC_BCB)Bcb) - CcCacheSections);
- 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;
-
- 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;
- }
- }
-
- DPRINT1("Done\n");
+ ULONG i, Result;
+ NTSTATUS Status;
+
+ 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;
+ }
+ }
+
+ /* Evict all section pages */
+ Status = MiRosTrimCache(~0, 0, &Result);
+
+ DPRINT1("Done (Evicted %d, Status %x)\n", Result, Status);
}
-\f
+
VOID
NTAPI
CcRepinBcb(IN PVOID Bcb)
{
- CcpLock();
- ASSERT(RtlTestBit(CcCacheBitmap, ((PNOCC_BCB)Bcb) - CcCacheSections));
- DPRINT("CcRepinBcb(#%x)\n", ((PNOCC_BCB)Bcb) - CcCacheSections);
- CcpReferenceCache(((PNOCC_BCB)Bcb) - CcCacheSections);
- CcpUnlock();
+ ULONG Number = (ULONG)(((PNOCC_BCB)Bcb) - CcCacheSections);
+ CcpLock();
+ ASSERT(RtlTestBit(CcCacheBitmap, Number));
+ DPRINT("CcRepinBcb(#%x)\n", Number);
+ CcpReferenceCache(Number);
+ CcpUnlock();
}
VOID
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);