reactos/ntoskrnl/cache/cachesub.c
Cameron Gutman c2d0d784c7 [USB-BRINGUP-TRUNK]
- Create a branch to do a proper merge of USB work from a trunk base instead of from cmake-bringup
- In the future, DO NOT under any circumstances branch another branch. This leads to merge problems!

svn path=/branches/usb-bringup-trunk/; revision=55018
2012-01-20 20:58:46 +00:00

347 lines
7.9 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/cache/cachesup.c
* PURPOSE: Logging and configuration routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Art Yerkes
*/
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#include "newcc.h"
#include "section/newmm.h"
#define NDEBUG
#include <debug.h>
/* STRUCTURES *****************************************************************/
typedef struct _WORK_QUEUE_WITH_READ_AHEAD
{
WORK_QUEUE_ITEM WorkItem;
PFILE_OBJECT FileObject;
LARGE_INTEGER FileOffset;
ULONG Length;
} WORK_QUEUE_WITH_READ_AHEAD, *PWORK_QUEUE_WITH_READ_AHEAD;
/* FUNCTIONS ******************************************************************/
PDEVICE_OBJECT
NTAPI
MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject);
VOID
NTAPI
CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject,
IN ULONG Granularity)
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
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;
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");
}
VOID
NTAPI
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");
}
VOID
NTAPI
CcSetDirtyPinnedData(IN PVOID BcbVoid,
IN OPTIONAL PLARGE_INTEGER Lsn)
{
PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid;
Bcb->Dirty = TRUE;
}
LARGE_INTEGER
NTAPI
CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
IN BOOLEAN CcInternalCaller)
{
LARGE_INTEGER Result = {{0}};
UNIMPLEMENTED;
while (TRUE);
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)
{
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();
if (IoStatus) *IoStatus = IOSB;
}
VOID
NTAPI
CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
IN OPTIONAL PLARGE_INTEGER FileOffset,
IN ULONG Length,
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
{
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);
}
BOOLEAN
NTAPI
CcFlushImageSection
(PSECTION_OBJECT_POINTERS SectionObjectPointer,
MMFLUSH_TYPE FlushType)
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
PNOCC_BCB Bcb;
PLIST_ENTRY Entry;
IO_STATUS_BLOCK IOSB;
BOOLEAN Result = TRUE;
if (!Map) return TRUE;
for (Entry = Map->AssociatedBcb.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;
}
}
return Result;
}
// Always succeeds for us
PVOID
NTAPI
CcRemapBcb(IN PVOID Bcb)
{
CcpLock();
ASSERT(RtlTestBit(CcCacheBitmap, ((PNOCC_BCB)Bcb) - CcCacheSections));
CcpReferenceCache(((PNOCC_BCB)Bcb) - CcCacheSections);
CcpUnlock();
return Bcb;
}
VOID
NTAPI
CcShutdownSystem()
{
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");
}
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();
}
VOID
NTAPI
CcUnpinRepinnedBcb(IN PVOID Bcb,
IN BOOLEAN WriteThrough,
OUT PIO_STATUS_BLOCK IoStatus)
{
PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
if (WriteThrough)
{
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
CcpFlushCache
(RealBcb->Map,
&RealBcb->FileOffset,
RealBcb->Length,
IoStatus, RealBcb->Dirty);
}
CcUnpinData(Bcb);
}
/* EOF */