Author: arty
Date: Sun Aug 10 05:14:55 2008
New Revision: 35259
URL:
http://svn.reactos.org/svn/reactos?rev=35259&view=rev
Log:
Current state of CC work.
We implement a cache based on a fixed number of cache cells and a simple
replacement algorithm.
Cache cells are evicted of the file is closed, or if something else needs
one and there's at least one unpinned at the time. We have a simple grace
scheme for pinned vs not-pinned sections.
Mm gains a couple of new functions for internal use: MiSimpleRead and
MiSimpleWrite that handle reading from and writing to the actual underlying
file using paging io.
There is a bit of a trick to detecting the actual length of the file that
I'm not totally happy with.
Added:
branches/arty-newcc/ntoskrnl/cache/
branches/arty-newcc/ntoskrnl/cache/cachesub.c (with props)
branches/arty-newcc/ntoskrnl/cache/copysup.c (with props)
branches/arty-newcc/ntoskrnl/cache/fssup.c (with props)
branches/arty-newcc/ntoskrnl/cache/lazyrite.c (with props)
branches/arty-newcc/ntoskrnl/cache/logsup.c (with props)
branches/arty-newcc/ntoskrnl/cache/mdlsup.c (with props)
branches/arty-newcc/ntoskrnl/cache/pinsup.c (with props)
branches/arty-newcc/ntoskrnl/cache/vacbsup.c (with props)
Modified:
branches/arty-newcc/ntoskrnl/include/internal/cc.h
branches/arty-newcc/ntoskrnl/include/internal/io_x.h
branches/arty-newcc/ntoskrnl/include/internal/mm.h
branches/arty-newcc/ntoskrnl/mm/mpw.c
branches/arty-newcc/ntoskrnl/mm/pe.c
branches/arty-newcc/ntoskrnl/mm/rmap.c
branches/arty-newcc/ntoskrnl/mm/section.c
branches/arty-newcc/ntoskrnl/ntoskrnl-generic.rbuild
branches/arty-newcc/ntoskrnl/ob/obref.c
Added: branches/arty-newcc/ntoskrnl/cache/cachesub.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/cache…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/cachesub.c (added)
+++ branches/arty-newcc/ntoskrnl/cache/cachesub.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -1,0 +1,222 @@
+/*
+ * 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(a)reactos.org)
+ * Art Yerkes
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+PDEVICE_OBJECT
+NTAPI
+MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject);
+
+NTSTATUS
+NTAPI
+CcpSimpleWrite
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ PIO_STATUS_BLOCK ReadStatus)
+{
+ NTSTATUS Status;
+ PIRP Irp = NULL;
+ KEVENT ReadWait;
+ PDEVICE_OBJECT DeviceObject = MmGetDeviceObjectForFile(FileObject);
+ PIO_STACK_LOCATION IrpSp;
+
+ KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
+
+ Irp = IoBuildAsynchronousFsdRequest
+ (IRP_MJ_WRITE,
+ DeviceObject,
+ Buffer,
+ PAGE_SIZE,
+ FileOffset,
+ ReadStatus);
+
+ if (!Irp)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ Irp->Flags |= IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE;
+
+ ObReferenceObject(FileObject);
+
+ Irp->UserEvent = &ReadWait;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ IrpSp = IoGetNextIrpStackLocation(Irp);
+ IrpSp->FileObject = FileObject;
+
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ if (!NT_SUCCESS
+ (KeWaitForSingleObject
+ (&ReadWait,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL)))
+ {
+ DPRINT1("Warning: Failed to wait for synchronous IRP\n");
+ ASSERT(FALSE);
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+ }
+
+ ObDereferenceObject(FileObject);
+
+ DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
+
+ return ReadStatus->Status;
+}
+
+VOID
+NTAPI
+CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject,
+ IN ULONG Granularity)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+VOID
+NTAPI
+CcScheduleReadAhead(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+VOID
+NTAPI
+CcSetDirtyPinnedData(IN PVOID BcbVoid,
+ IN OPTIONAL PLARGE_INTEGER Lsn)
+{
+ PCHAR Buffer;
+ PNOCC_BCB Bcb = (PNOCC_BCB)BcbVoid;
+ Bcb->Dirty = TRUE;
+ for (Buffer = Bcb->BaseAddress;
+ Buffer < ((PCHAR)Bcb->BaseAddress) + Bcb->Length;
+ Buffer += PAGE_SIZE)
+ {
+ /* Do a fake write on the buffer pages to mark them for mm */
+ *Buffer ^= 0;
+ }
+}
+
+LARGE_INTEGER
+NTAPI
+CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
+ IN BOOLEAN CcInternalCaller)
+{
+ LARGE_INTEGER Result = {{0}};
+ UNIMPLEMENTED;
+ while (TRUE);
+ return Result;
+}
+
+BOOLEAN
+NTAPI
+CcpMapData
+(IN PNOCC_CACHE_MAP Map,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ OUT PVOID *BcbResult,
+ OUT PVOID *Buffer);
+
+
+VOID
+NTAPI
+CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
+ IN OPTIONAL PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
+{
+ PCHAR BufPage, BufStart;
+ PVOID Buffer;
+ PNOCC_BCB Bcb;
+ LARGE_INTEGER ToWrite = *FileOffset;
+ IO_STATUS_BLOCK IOSB;
+
+ BOOLEAN Result = CcpMapData
+ ((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap,
+ FileOffset,
+ Length,
+ PIN_WAIT,
+ (PVOID *)&Bcb,
+ &Buffer);
+
+ if (!Result) return;
+
+ BufStart = (PCHAR)PAGE_ROUND_DOWN(((ULONG_PTR)Buffer));
+ ToWrite.LowPart = PAGE_ROUND_DOWN(FileOffset->LowPart);
+
+ for (BufPage = BufStart;
+ BufPage < BufStart + PAGE_ROUND_UP(Length);
+ BufPage += PAGE_SIZE)
+ {
+ CcpSimpleWrite(Bcb->FileObject, &ToWrite, BufPage, &IOSB);
+ ToWrite.QuadPart += PAGE_SIZE;
+ }
+
+ CcUnpinData(Bcb);
+
+ if (IoStatus && NT_SUCCESS(IOSB.Status))
+ {
+ IoStatus->Status = STATUS_SUCCESS;
+ IoStatus->Information = Length;
+ }
+ else if (IoStatus)
+ {
+ IoStatus->Status = IOSB.Status;
+ IoStatus->Information = 0;
+ }
+}
+
+PVOID
+NTAPI
+CcRemapBcb(IN PVOID Bcb)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return NULL;
+}
+
+
+VOID
+NTAPI
+CcRepinBcb(IN PVOID Bcb)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+VOID
+NTAPI
+CcUnpinRepinnedBcb(IN PVOID Bcb,
+ IN BOOLEAN WriteThrough,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+/* EOF */
Propchange: branches/arty-newcc/ntoskrnl/cache/cachesub.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/arty-newcc/ntoskrnl/cache/copysup.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/copys…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/copysup.c (added)
+++ branches/arty-newcc/ntoskrnl/cache/copysup.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -1,0 +1,251 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/copysup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+//#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+ULONG CcFastMdlReadWait;
+ULONG CcFastMdlReadNotPossible;
+ULONG CcFastReadNotPossible;
+ULONG CcFastReadWait;
+ULONG CcFastReadNoWait;
+ULONG CcFastReadResourceMiss;
+
+#define TAG_COPY_READ TAG('C', 'o', 'p', 'y')
+#define TAG_COPY_WRITE TAG('R', 'i', 't', 'e')
+
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+NTAPI
+DoDeviceRead(PFILE_OBJECT FileObject,
+ LARGE_INTEGER SectorBase,
+ PCHAR SystemBuffer,
+ ULONG AlignSize,
+ ULONG *LengthRead)
+{
+ IO_STATUS_BLOCK IoStatusBlock = {{0}};
+ NTSTATUS Status;
+ KEVENT Event;
+ PMDL Mdl;
+
+ /* Create an MDL for the transfer */
+ Mdl = IoAllocateMdl(SystemBuffer, AlignSize, TRUE, FALSE, NULL);
+ MmBuildMdlForNonPagedPool(Mdl),
+ Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
+
+ /* Setup the event */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ /* Read the page */
+ Status = IoPageRead(FileObject, Mdl, &SectorBase, &Event,
&IoStatusBlock);
+ if (Status == STATUS_PENDING)
+ {
+ /* Do the wait */
+ KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ /* Free the MDL */
+ IoFreeMdl(Mdl);
+
+ /* Save how much we read, if needed */
+ if (LengthRead) *LengthRead = IoStatusBlock.Information;
+
+ return Status;
+}
+
+BOOLEAN
+NTAPI
+CcCopyRead(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ OUT PVOID Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ INT i, Count;
+ PCHAR ReadBuf;
+ ULONG ReadLen;
+ PVOID Bcbs[CACHE_NUM_SECTIONS];
+ PVOID ReadBuffers[CACHE_NUM_SECTIONS];
+
+ DPRINT
+ ("CcCopyRead(%x,%x,%d,%d,%x)\n",
+ FileObject,
+ FileOffset->LowPart,
+ Length,
+ Wait,
+ Buffer);
+
+ for (ReadLen = Length, i = 0;
+ ReadLen > 0;
+ ReadLen -= min(ReadLen, CACHE_STRIPE), i++)
+ {
+ if (!CcPinRead
+ (FileObject,
+ FileOffset,
+ min(ReadLen, CACHE_STRIPE),
+ Wait ? PIN_WAIT : PIN_IF_BCB,
+ &Bcbs[i],
+ &ReadBuffers[i]))
+ {
+ --i;
+ while (i >= 0)
+ CcUnpinData(Bcbs[i--]);
+ IoStatus->Status = STATUS_UNSUCCESSFUL;
+ IoStatus->Information = 0;
+ DPRINT("Failed CcCopyRead\n");
+ return FALSE;
+ }
+ }
+
+ Count = i;
+
+ DPRINT("Copying %d bytes for Read (%d buffers)\n", Length, Count);
+ for (i = 0; i < Count; i++)
+ {
+ DPRINT(" %d: [#%02x:%x]\n", i, Bcbs[i], ReadBuffers[i]);
+ }
+
+ for (ReadBuf = (PCHAR)Buffer, ReadLen = Length, i = 0;
+ ReadLen > 0;
+ ReadBuf += CACHE_STRIPE, ReadLen -= min(ReadLen, CACHE_STRIPE), i++)
+ RtlCopyMemory(ReadBuf, ReadBuffers[i], min(ReadLen, CACHE_STRIPE));
+
+ for (i = 0; i < Count; i++)
+ CcUnpinData(Bcbs[i]);
+
+ IoStatus->Status = STATUS_SUCCESS;
+ IoStatus->Information = Length;
+
+ DPRINT("Done with CcCopyRead\n");
+
+ return TRUE;
+}
+
+VOID
+NTAPI
+CcFastCopyRead(IN PFILE_OBJECT FileObject,
+ IN ULONG FileOffset,
+ IN ULONG Length,
+ IN ULONG PageCount,
+ OUT PVOID Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+BOOLEAN
+NTAPI
+CcCopyWrite(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ IN PVOID Buffer)
+{
+ INT i, Count;
+ PCHAR WriteBuf;
+ ULONG WriteLen;
+ PVOID Bcbs[CACHE_NUM_SECTIONS];
+ PVOID WriteBuffers[CACHE_NUM_SECTIONS];
+
+ DPRINT
+ ("CcCopyWrite(%x,%x,%d,%d,%x)\n",
+ FileObject,
+ FileOffset->LowPart,
+ Length,
+ Wait,
+ Buffer);
+
+ for (WriteLen = Length, i = 0;
+ WriteLen > 0;
+ WriteLen -= min(WriteLen, CACHE_STRIPE), i++)
+ {
+ if (!CcPreparePinWrite
+ (FileObject,
+ FileOffset,
+ min(WriteLen, CACHE_STRIPE),
+ FALSE,
+ Wait ? PIN_WAIT : PIN_IF_BCB,
+ &Bcbs[i],
+ &WriteBuffers[i]))
+ {
+ --i;
+ while (i >= 0)
+ CcUnpinData(Bcbs[i--]);
+ DPRINT("Failed CcCopyWrite\n");
+ return FALSE;
+ }
+ }
+
+ Count = i;
+
+ DPRINT("Copying %d bytes for Read\n", Length);
+
+ for (WriteBuf = (PCHAR)Buffer, WriteLen = Length, i = 0;
+ WriteLen > 0;
+ WriteBuf += CACHE_STRIPE, WriteLen -= min(WriteLen, CACHE_STRIPE), i++)
+ RtlCopyMemory(WriteBuffers[i], WriteBuf, min(WriteLen, CACHE_STRIPE));
+
+ Count = i;
+
+ DPRINT("Copying %d bytes for Write\n", Length);
+ for (i = 0; i < Count; i++)
+ {
+ DPRINT(" %d: [#%02x:%x]\n", i, Bcbs[i], WriteBuffers[i]);
+ }
+
+ DPRINT("Done with CcCopyWrite\n");
+
+ return TRUE;
+}
+
+VOID
+NTAPI
+CcFastCopyWrite(IN PFILE_OBJECT FileObject,
+ IN ULONG FileOffset,
+ IN ULONG Length,
+ IN PVOID Buffer)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+BOOLEAN
+NTAPI
+CcCanIWrite(IN PFILE_OBJECT FileObject,
+ IN ULONG BytesToWrite,
+ IN BOOLEAN Wait,
+ IN UCHAR Retrying)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return FALSE;
+}
+
+VOID
+NTAPI
+CcDeferWrite(IN PFILE_OBJECT FileObject,
+ IN PCC_POST_DEFERRED_WRITE PostRoutine,
+ IN PVOID Context1,
+ IN PVOID Context2,
+ IN ULONG BytesToWrite,
+ IN BOOLEAN Retrying)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+/* EOF */
Propchange: branches/arty-newcc/ntoskrnl/cache/copysup.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/arty-newcc/ntoskrnl/cache/fssup.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/fssup…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/fssup.c (added)
+++ branches/arty-newcc/ntoskrnl/cache/fssup.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -1,0 +1,190 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/fssup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Art Yerkes
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+//#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+PFSN_PREFETCHER_GLOBALS CcPfGlobals;
+extern LONG CcOutstandingDeletes;
+extern VOID STDCALL CcpUnmapThread(PVOID Unused);
+HANDLE CcUnmapThreadHandle;
+CLIENT_ID CcUnmapThreadId;
+
+/* FUNCTIONS ******************************************************************/
+
+BOOLEAN
+NTAPI
+CcInitializeCacheManager(VOID)
+{
+ int i;
+ NTSTATUS Status;
+
+ DPRINT("Initialize\n");
+ for (i = 0; i < CACHE_NUM_SECTIONS; i++)
+ {
+ KeInitializeEvent(&CcCacheSections[i].ExclusiveWait, SynchronizationEvent, FALSE);
+ InitializeListHead(&CcCacheSections[i].ThisFileList);
+ }
+
+ KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
+ CcCacheBitmap->Buffer = ((PULONG)&CcCacheBitmap[1]);
+ CcCacheBitmap->SizeOfBitMap = ROUND_UP(CACHE_NUM_SECTIONS, 32);
+ DPRINT("Cache has %d entries\n", CcCacheBitmap->SizeOfBitMap);
+ KeInitializeGuardedMutex(&CcMutex);
+ Status = PsCreateSystemThread
+ (&CcUnmapThreadHandle,
+ THREAD_ALL_ACCESS,
+ NULL,
+ NULL,
+ &CcUnmapThreadId,
+ (PKSTART_ROUTINE) CcpUnmapThread,
+ NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ KEBUGCHECK(0);
+ }
+
+ return TRUE;
+}
+
+VOID
+NTAPI
+CcPfInitializePrefetcher(VOID)
+{
+ /* Notify debugger */
+ DbgPrintEx(DPFLTR_PREFETCHER_ID,
+ DPFLTR_TRACE_LEVEL,
+ "CCPF: InitializePrefetecher()\n");
+
+ /* Setup the Prefetcher Data */
+ InitializeListHead(&CcPfGlobals.ActiveTraces);
+ InitializeListHead(&CcPfGlobals.CompletedTraces);
+ ExInitializeFastMutex(&CcPfGlobals.CompletedTracesLock);
+
+ /* FIXME: Setup the rest of the prefetecher */
+}
+
+VOID
+NTAPI
+CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
+ IN PCC_FILE_SIZES FileSizes,
+ IN BOOLEAN PinAccess,
+ IN PCACHE_MANAGER_CALLBACKS Callbacks,
+ IN PVOID LazyWriteContext)
+{
+ DPRINT("Initializing file object for %wZ\n", &FileObject->FileName);
+ PNOCC_CACHE_MAP Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
+ FileObject->SectionObjectPointer->SharedCacheMap = Map;
+ Map->FileObject = FileObject;
+ Map->NumberOfMaps = 0;
+ InitializeListHead(&Map->AssociatedBcb);
+ return;
+}
+
+BOOLEAN
+NTAPI
+CcUninitializeCacheMap(IN PFILE_OBJECT FileObject,
+ IN OPTIONAL PLARGE_INTEGER TruncateSize,
+ IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
+{
+ PNOCC_CACHE_MAP Map =
(PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+ PNOCC_BCB Bcb;
+ PLIST_ENTRY Entry;
+
+ DPRINT("Uninitializing file object for %wZ\n", &FileObject->FileName);
+
+ ASSERT(UninitializeEvent == NULL);
+ CcpLock();
+
+ for (Entry =
((PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap)->AssociatedBcb.Flink;
+ Entry !=
&((PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap)->AssociatedBcb;
+ Entry = Entry->Flink)
+ {
+ Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
+ if (Bcb->RefCount == 1)
+ {
+ DPRINT("Unmapping #%x\n", Bcb - CcCacheSections);
+ CcpDereferenceCache(Bcb - CcCacheSections);
+ }
+ }
+ CcpUnlock();
+
+ ExFreePool(Map);
+
+ /* Clear the cache map */
+ FileObject->SectionObjectPointer->SharedCacheMap = NULL;
+ return TRUE;
+}
+
+VOID
+NTAPI
+CcSetFileSizes(IN PFILE_OBJECT FileObject,
+ IN PCC_FILE_SIZES FileSizes)
+{
+ /* Nothing to do */
+}
+
+BOOLEAN
+NTAPI
+CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
+ IN OPTIONAL PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN UninitializeCacheMaps)
+{
+ IO_STATUS_BLOCK IOSB;
+ CcFlushCache(SectionObjectPointer, FileOffset, Length, &IOSB);
+ return NT_SUCCESS(IOSB.Status);
+}
+
+VOID
+NTAPI
+CcSetDirtyPageThreshold(IN PFILE_OBJECT FileObject,
+ IN ULONG DirtyPageThreshold)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+BOOLEAN
+NTAPI
+CcZeroData(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER StartOffset,
+ IN PLARGE_INTEGER EndOffset,
+ IN BOOLEAN Wait)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return FALSE;
+}
+
+PFILE_OBJECT
+NTAPI
+CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return NULL;
+}
+
+PFILE_OBJECT
+NTAPI
+CcGetFileObjectFromBcb(IN PVOID Bcb)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return NULL;
+}
+
+/* EOF */
Propchange: branches/arty-newcc/ntoskrnl/cache/fssup.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/arty-newcc/ntoskrnl/cache/lazyrite.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/lazyr…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/lazyrite.c (added)
+++ branches/arty-newcc/ntoskrnl/cache/lazyrite.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -1,0 +1,28 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/lazyrite.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+NTAPI
+CcWaitForCurrentLazyWriterActivity(VOID)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_SUCCESS;
+}
+
+/* EOF */
Propchange: branches/arty-newcc/ntoskrnl/cache/lazyrite.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/arty-newcc/ntoskrnl/cache/logsup.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/logsu…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/logsup.c (added)
+++ branches/arty-newcc/ntoskrnl/cache/logsup.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -1,0 +1,72 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/logsup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+CcSetAdditionalCacheAttributes(IN PFILE_OBJECT FileObject,
+ IN BOOLEAN DisableReadAhead,
+ IN BOOLEAN DisableWriteBehind)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+VOID
+NTAPI
+CcSetLogHandleForFile(IN PFILE_OBJECT FileObject,
+ IN PVOID LogHandle,
+ IN PFLUSH_TO_LSN FlushToLsnRoutine)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+LARGE_INTEGER
+NTAPI
+CcGetDirtyPages(IN PVOID LogHandle,
+ IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine,
+ IN PVOID Context1,
+ IN PVOID Context2)
+{
+ LARGE_INTEGER Result = {{0}};
+ UNIMPLEMENTED;
+ while (TRUE);
+ return Result;
+}
+
+BOOLEAN
+NTAPI
+CcIsThereDirtyData(IN PVPB Vpb)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return FALSE;
+}
+
+LARGE_INTEGER
+NTAPI
+CcGetLsnForFileObject(IN PFILE_OBJECT FileObject,
+ OUT OPTIONAL PLARGE_INTEGER OldestLsn)
+{
+ LARGE_INTEGER Result = {{0}};
+ UNIMPLEMENTED;
+ while (TRUE);
+ return Result;
+}
+
+/* EOF */
Propchange: branches/arty-newcc/ntoskrnl/cache/logsup.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/arty-newcc/ntoskrnl/cache/mdlsup.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/mdlsu…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/mdlsup.c (added)
+++ branches/arty-newcc/ntoskrnl/cache/mdlsup.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -1,0 +1,142 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/logsup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+
+PMDL
+NTAPI
+CcpBuildCacheMdl
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ ULONG Length,
+ PIO_STATUS_BLOCK IOSB)
+{
+ PMDL Mdl;
+ PVOID 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 (!Mdl)
+ {
+ IOSB->Information = 0;
+ IOSB->Status = STATUS_NO_MEMORY;
+ return NULL;
+ }
+
+ IOSB->Information = Length;
+ IOSB->Status = STATUS_SUCCESS;
+
+ return Mdl;
+}
+
+VOID
+NTAPI
+CcMdlRead(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ OUT PMDL *MdlChain,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ *MdlChain = CcpBuildCacheMdl
+ (FileObject,
+ FileOffset,
+ Length,
+ IoStatus);
+}
+
+VOID
+NTAPI
+CcMdlReadComplete(IN PFILE_OBJECT FileObject,
+ IN PMDL MdlChain)
+{
+ IoFreeMdl(MdlChain);
+}
+
+VOID
+NTAPI
+CcMdlReadComplete2(IN PMDL MdlChain,
+ IN PFILE_OBJECT FileObject)
+{
+ DPRINT("Not sure\n");
+}
+
+VOID
+NTAPI
+CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ OUT PMDL *MdlChain,
+ OUT PIO_STATUS_BLOCK IoStatus)
+{
+ *MdlChain = CcpBuildCacheMdl
+ (FileObject,
+ FileOffset,
+ Length,
+ IoStatus);
+}
+
+VOID
+NTAPI
+CcMdlWriteComplete(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PMDL MdlChain)
+{
+ IoFreeMdl(MdlChain);
+}
+
+VOID
+NTAPI
+CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN PMDL MdlChain)
+{
+ DPRINT("Not sure\n");
+}
+
+VOID
+NTAPI
+CcMdlWriteAbort(IN PFILE_OBJECT FileObject,
+ IN PMDL MdlChain)
+{
+ ASSERT(FALSE);
+ IoFreeMdl(MdlChain);
+}
+
+/* EOF */
Propchange: branches/arty-newcc/ntoskrnl/cache/mdlsup.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/arty-newcc/ntoskrnl/cache/pinsup.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/pinsu…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/pinsup.c (added)
+++ branches/arty-newcc/ntoskrnl/cache/pinsup.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -1,0 +1,634 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/pinsup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Art Yerkes
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+#define TAG_MAP_SEC TAG('C', 'c', 'S', 'x')
+#define TAG_MAP_READ TAG('M', 'c', 'p', 'y')
+#define TAG_MAP_BCB TAG('B', 'c', 'b', ' ')
+
+NOCC_BCB CcCacheSections[CACHE_NUM_SECTIONS];
+CHAR CcpBitmapBuffer[sizeof(RTL_BITMAP) + ROUND_UP((CACHE_NUM_SECTIONS), 32) / 8];
+PRTL_BITMAP CcCacheBitmap = (PRTL_BITMAP)&CcpBitmapBuffer;
+KGUARDED_MUTEX CcMutex;
+KEVENT CcDeleteEvent;
+ULONG CcCacheClockHand;
+LONG CcOutstandingDeletes;
+
+typedef struct _NOCC_UNMAP_CHAIN
+{
+ PVOID Buffer;
+ PVOID SectionObject;
+ PVOID FileObject;
+} NOCC_UNMAP_CHAIN, *PNOCC_UNMAP_CHAIN;
+NOCC_UNMAP_CHAIN CcUnmapChain[CACHE_NUM_SECTIONS];
+
+/* FUNCTIONS ******************************************************************/
+
+VOID CcpUnlinkedFromFile
+(PFILE_OBJECT FileObject,
+ PNOCC_BCB Bcb)
+{
+ PLIST_ENTRY Entry;
+
+ for (Entry =
((PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap)->AssociatedBcb.Flink;
+ Entry !=
&((PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap)->AssociatedBcb;
+ Entry = Entry->Flink)
+ {
+ ASSERT(CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList) != Bcb);
+ }
+}
+
+VOID CcpLock()
+{
+ KeAcquireGuardedMutex(&CcMutex);
+ //DPRINT("<<<---<<< CC In Mutex!\n");
+}
+
+VOID CcpPerformUnmapWork()
+{
+ NOCC_UNMAP_CHAIN WorkingOn;
+ ULONG NumElements;
+
+ KeAcquireGuardedMutex(&CcMutex);
+ while (CcOutstandingDeletes > 0)
+ {
+ NumElements = InterlockedDecrement(&CcOutstandingDeletes);
+ DPRINT1("Unmapping %d ...\n", NumElements);
+ WorkingOn = CcUnmapChain[0];
+ RtlMoveMemory(&CcUnmapChain[0], &CcUnmapChain[1], NumElements *
sizeof(NOCC_UNMAP_CHAIN));
+ KeReleaseGuardedMutex(&CcMutex);
+ MmUnmapViewInSystemSpace(WorkingOn.Buffer);
+ ObDereferenceObject(WorkingOn.SectionObject);
+ DPRINT1("Done unmapping\n");
+ KeAcquireGuardedMutex(&CcMutex);
+ }
+ KeReleaseGuardedMutex(&CcMutex);
+}
+
+VOID CcpUnlock()
+{
+ //DPRINT(">>>--->>> CC Exit Mutex!\n");
+ KeReleaseGuardedMutex(&CcMutex);
+}
+
+VOID STDCALL
+CcpUnmapThread(PVOID Unused)
+{
+ while (TRUE)
+ {
+ KeWaitForSingleObject(&CcDeleteEvent, UserRequest, KernelMode, FALSE, NULL);
+ CcpPerformUnmapWork();
+ }
+}
+
+PDEVICE_OBJECT
+NTAPI
+MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject);
+
+VOID CcpUnmapSegment(ULONG Segment)
+{
+ PNOCC_BCB Bcb = &CcCacheSections[Segment];
+ PNOCC_UNMAP_CHAIN UnmapWork = &CcUnmapChain[CcOutstandingDeletes];
+
+ ASSERT(Bcb->RefCount > 0);
+ DPRINT("CcpUnmapSegment(#%x)\n", Segment);
+
+ InterlockedIncrement(&CcOutstandingDeletes);
+ UnmapWork->Buffer = Bcb->BaseAddress;
+ UnmapWork->SectionObject = Bcb->SectionObject;
+ UnmapWork->FileObject = Bcb->FileObject;
+
+ Bcb->BaseAddress = NULL;
+ Bcb->Length = 0;
+ Bcb->FileOffset.QuadPart = 0;
+
+ KeSetEvent(&CcDeleteEvent, IO_DISK_INCREMENT, FALSE);
+}
+
+NTSTATUS CcpMapSegment(ULONG Start)
+{
+ PNOCC_BCB Bcb = &CcCacheSections[Start];
+ ULONG ViewSize = CACHE_STRIPE;
+ NTSTATUS Status;
+
+ ASSERT(RtlTestBit(CcCacheBitmap, Start));
+ DPRINT("CcpMapSegment(#%x)\n", Start);
+
+ Status = MmMapViewInSystemSpaceAtOffset
+ (Bcb->SectionObject,
+ &Bcb->BaseAddress,
+ &Bcb->FileOffset,
+ &ViewSize);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Failed to map view in system space: %x\n", Status);
+ return Status;
+ }
+
+ DPRINT("System view is at %x\n", Bcb->BaseAddress);
+ Bcb->Length = ViewSize;
+
+ return TRUE;
+}
+
+NTSTATUS CcpAllocateSection
+(PFILE_OBJECT FileObject,
+ ULONG Length,
+ ULONG Protect,
+ PSECTION_OBJECT *Result)
+{
+ NTSTATUS Status;
+ LARGE_INTEGER MaxSize;
+
+ MaxSize.QuadPart = Length;
+
+ Status = MmCreateSection
+ ((PVOID*)Result,
+ STANDARD_RIGHTS_REQUIRED,
+ NULL,
+ &MaxSize,
+ Protect,
+ SEC_RESERVE,
+ NULL,
+ FileObject);
+
+ return Status;
+}
+
+/* Must have acquired the mutex */
+VOID CcpDereferenceCache(ULONG Start)
+{
+ PNOCC_BCB Bcb;
+ PNOCC_CACHE_MAP Map;
+
+ DPRINT("CcpDereferenceCache(#%x)\n", Start);
+
+ Bcb = &CcCacheSections[Start];
+ DPRINT("Dereference #%x (count %d)\n", Start, Bcb->RefCount);
+ ASSERT(Bcb->FileObject);
+ ASSERT(Bcb->SectionObject);
+ ASSERT(Bcb->RefCount == 1);
+
+ Map = (PNOCC_CACHE_MAP)Bcb->FileObject->SectionObjectPointer->SharedCacheMap;
+ Map->NumberOfMaps--;
+
+ DPRINT("Fully unreferencing Bcb #%x\n", Start);
+ CcpUnmapSegment(Start);
+
+ RemoveEntryList(&Bcb->ThisFileList);
+
+ Bcb->FileObject = NULL;
+ Bcb->SectionObject = NULL;
+ Bcb->BaseAddress = NULL;
+ Bcb->FileOffset.QuadPart = 0;
+ Bcb->Length = 0;
+ Bcb->RefCount = 0;
+}
+
+/* Needs mutex */
+ULONG CcpAllocateCacheSections
+(PFILE_OBJECT FileObject,
+ PSECTION_OBJECT SectionObject,
+ PLARGE_INTEGER FileOffset)
+{
+ ULONG i = INVALID_CACHE;
+ PNOCC_CACHE_MAP Map =
(PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
+ PNOCC_BCB Bcb;
+
+ DPRINT("Allocating Cache Section (File already has %d sections)\n",
Map->NumberOfMaps);
+
+ i = RtlFindClearBitsAndSet
+ (CcCacheBitmap, 1, CcCacheClockHand);
+ CcCacheClockHand = i + 1;
+
+ if (i != INVALID_CACHE)
+ {
+ Bcb = &CcCacheSections[i];
+
+ ASSERT(Bcb->RefCount < 2);
+
+ if (Bcb->RefCount > 0)
+ {
+ CcpDereferenceCache(i);
+ }
+
+ ASSERT(!Bcb->RefCount);
+
+ Bcb->RefCount = 1;
+ //DPRINT("Bcb #%x RefCount %d\n", Bcb - CcCacheSections, Bcb->RefCount);
+ ObReferenceObject(SectionObject);
+
+ Bcb->FileObject = FileObject;
+ Bcb->SectionObject = SectionObject;
+ Bcb->FileOffset = *FileOffset;
+ Bcb->Length = CACHE_STRIPE;
+ Map->NumberOfMaps++;
+
+ InsertTailList(&Map->AssociatedBcb, &Bcb->ThisFileList);
+
+ ASSERT(RtlTestBit(CcCacheBitmap, i));
+
+ DPRINT("Allocated #%x\n", i);
+ ASSERT(CcCacheSections[i].RefCount);
+ }
+ else
+ {
+ DPRINT("Failed to allocate cache segment\n");
+ }
+ return i;
+}
+
+/*
+ * Must have mutex
+ */
+ULONG CcpFindCacheFor(PNOCC_CACHE_MAP Map)
+{
+ if (!Map)
+ return INVALID_CACHE;
+ else
+ {
+ if (IsListEmpty(&Map->AssociatedBcb))
+ return INVALID_CACHE;
+ PNOCC_BCB Bcb = CONTAINING_RECORD
+ (Map->AssociatedBcb.Flink,
+ NOCC_BCB,
+ ThisFileList);
+ return Bcb - CcCacheSections;
+ }
+}
+
+/* Must have acquired the mutex */
+VOID CcpReferenceCache(ULONG Start)
+{
+ PNOCC_BCB Bcb;
+ Bcb = &CcCacheSections[Start];
+ ASSERT(Bcb->FileObject);
+ ASSERT(Bcb->SectionObject);
+ Bcb->RefCount++;
+ RtlSetBit(CcCacheBitmap, Start);
+
+}
+
+VOID CcpMarkForExclusive(ULONG Start)
+{
+ PNOCC_BCB Bcb;
+ Bcb = &CcCacheSections[Start];
+ Bcb->ExclusiveWaiter++;
+}
+
+/* Must not have the mutex */
+VOID CcpReferenceCacheExclusive(ULONG Start)
+{
+ PNOCC_BCB Bcb = &CcCacheSections[Start];
+
+ KeWaitForSingleObject(&Bcb->ExclusiveWait, Executive, KernelMode, FALSE, NULL);
+ CcpLock();
+ ASSERT(Bcb->ExclusiveWaiter);
+ ASSERT(Bcb->FileObject);
+ ASSERT(Bcb->SectionObject);
+ Bcb->RefCount++;
+ Bcb->Exclusive = TRUE;
+ Bcb->ExclusiveWaiter--;
+ RtlSetBit(CcCacheBitmap, Start);
+ CcpUnlock();
+}
+
+/* Find a map that encompasses the target range */
+/* Must have the mutex */
+ULONG CcpFindMatchingMap(PNOCC_BCB Head, PLARGE_INTEGER FileOffset, ULONG Length)
+{
+ PLIST_ENTRY Entry;
+
+ //DPRINT("Find Matching Map: %x:%x\n", FileOffset->LowPart, Length);
+
+ if (FileOffset->QuadPart >= Head->FileOffset.QuadPart &&
+ FileOffset->QuadPart + Length <= Head->FileOffset.QuadPart + Head->Length)
+ {
+ //DPRINT("Head matched\n");
+ return Head - CcCacheSections;
+ }
+
+ for (Entry = Head->ThisFileList.Flink; Entry != &Head->ThisFileList; Entry =
Entry->Flink)
+ {
+ PNOCC_BCB Bcb = CONTAINING_RECORD(Entry, NOCC_BCB, ThisFileList);
+ //DPRINT("This File: %x:%x\n", Bcb->FileOffset.LowPart, Bcb->Length);
+ if (FileOffset->QuadPart >= Bcb->FileOffset.QuadPart &&
+ FileOffset->QuadPart + Length <= Bcb->FileOffset.QuadPart + Bcb->Length)
+ {
+ //DPRINT("Found match at #%x\n", Bcb - CcCacheSections);
+ return Bcb - CcCacheSections;
+ }
+ }
+
+ //DPRINT("This region isn't mapped\n");
+
+ return INVALID_CACHE;
+}
+
+BOOLEAN
+NTAPI
+CcpMapData
+(IN PNOCC_CACHE_MAP Map,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ OUT PVOID *BcbResult,
+ OUT PVOID *Buffer)
+{
+ BOOLEAN Success = FALSE;
+ PFILE_OBJECT FileObject = Map->FileObject;
+ /* Note: windows 2000 drivers treat this as a bool */
+ BOOLEAN Wait = (Flags & MAP_WAIT) || (Flags == TRUE);
+ LARGE_INTEGER Target;
+ ULONG BcbHead;
+ PNOCC_BCB Bcb = NULL;
+ PSECTION_OBJECT SectionObject = NULL;
+ NTSTATUS Status;
+
+ DPRINT("CcMapData(F->%x,%x:%d)\n", Map, FileOffset->LowPart, Length);
+
+ ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
+
+ Target.QuadPart = CACHE_ROUND_DOWN(FileOffset->QuadPart);
+
+ CcpLock();
+
+ /* Find out if any range is a superset of what we want */
+ BcbHead = CcpFindCacheFor(Map);
+
+ /* No bcbs for this file */
+ if (BcbHead != INVALID_CACHE)
+ {
+ /* Find an accomodating section */
+ //DPRINT("Selected BCB #%x\n", BcbHead);
+ Bcb = &CcCacheSections[BcbHead];
+ SectionObject = Bcb->SectionObject;
+ BcbHead = CcpFindMatchingMap(Bcb, FileOffset, Length);
+
+ if (BcbHead == INVALID_CACHE)
+ {
+ if (!Wait)
+ {
+ CcpUnlock();
+ //DPRINT("End\n");
+ goto cleanup;
+ }
+ }
+ else
+ {
+ Bcb = &CcCacheSections[BcbHead];
+ Success = TRUE;
+ *BcbResult = Bcb;
+ *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart -
Bcb->FileOffset.QuadPart);
+ DPRINT
+ ("Bcb #%x Buffer maps (%x) At %x Length %x (Getting %x:%x)\n",
+ Bcb - CcCacheSections,
+ Bcb->FileOffset.LowPart,
+ Bcb->BaseAddress,
+ Bcb->Length,
+ *Buffer,
+ Length);
+ CcpUnlock();
+ //DPRINT("w1n\n");
+ goto cleanup;
+ }
+ }
+
+ CcpUnlock();
+
+ if (!SectionObject)
+ {
+ Status = CcpAllocateSection
+ (FileObject,
+ CACHE_STRIPE,
+ PAGE_READWRITE,
+ &SectionObject);
+
+ if (!NT_SUCCESS(Status))
+ {
+ //DPRINT("End %08x\n", Status);
+ goto cleanup;
+ }
+ }
+
+ /* Returns a reference */
+ do
+ {
+ CcpLock();
+
+ BcbHead = CcpAllocateCacheSections
+ (FileObject,
+ SectionObject,
+ &Target);
+
+ CcpUnlock();
+ }
+ while (BcbHead == INVALID_CACHE &&
+ NT_SUCCESS
+ (KeWaitForSingleObject
+ (&CcDeleteEvent, UserRequest, KernelMode, FALSE, NULL)));
+
+ if (BcbHead == INVALID_CACHE)
+ {
+ //DPRINT("End\n");
+ goto cleanup;
+ }
+
+ //DPRINT("Selected BCB #%x\n", BcbHead);
+ Bcb = &CcCacheSections[BcbHead];
+ Status = CcpMapSegment(BcbHead);
+
+ if (NT_SUCCESS(Status))
+ {
+ Success = TRUE;
+ //DPRINT("w1n\n");
+ *BcbResult = &CcCacheSections[BcbHead];
+ *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart -
Bcb->FileOffset.QuadPart);
+ DPRINT
+ ("Bcb #%x Buffer maps (%x) At %x Length %x (Getting %x:%x)\n",
+ Bcb - CcCacheSections,
+ Bcb->FileOffset.LowPart,
+ Bcb->BaseAddress,
+ Bcb->Length,
+ *Buffer,
+ Length);
+ goto cleanup;
+ }
+
+ //DPRINT("TERM!\n");
+
+cleanup:
+ 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)
+{
+ if (!(PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap)
+ {
+ PNOCC_CACHE_MAP Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
+ FileObject->SectionObjectPointer->SharedCacheMap = Map;
+ Map->FileObject = FileObject;
+ InitializeListHead(&Map->AssociatedBcb);
+ }
+
+ return CcpMapData
+ ((PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap,
+ FileOffset,
+ Length,
+ Flags,
+ BcbResult,
+ Buffer);
+}
+
+BOOLEAN
+NTAPI
+CcPinMappedData(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ IN OUT PVOID *Bcb)
+{
+ BOOLEAN Wait = Flags & PIN_WAIT;
+ BOOLEAN Exclusive = Flags & PIN_EXCLUSIVE;
+ BOOLEAN Result;
+ ULONG BcbHead;
+ PVOID Buffer;
+
+ Result = CcMapData(FileObject, FileOffset, Length, Wait ? MAP_WAIT : 0, Bcb,
&Buffer);
+ BcbHead = ((PNOCC_BCB)*Bcb) - CcCacheSections;
+
+ if (!Result) return FALSE;
+
+ CcpLock();
+ if (Exclusive)
+ {
+ DPRINT("Requesting #%x Exclusive\n", BcbHead);
+ CcpMarkForExclusive(BcbHead);
+ }
+ else
+ CcpReferenceCache(BcbHead);
+ CcpUnlock();
+
+ if (Exclusive)
+ CcpReferenceCacheExclusive(BcbHead);
+
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CcPinRead(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN ULONG Flags,
+ OUT PVOID *Bcb,
+ OUT PVOID *Buffer)
+{
+ return CcMapData(FileObject, FileOffset, Length, Flags, Bcb, Buffer);
+}
+
+BOOLEAN
+NTAPI
+CcPreparePinWrite(IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Zero,
+ IN ULONG Flags,
+ OUT PVOID *Bcb,
+ OUT PVOID *Buffer)
+{
+ BOOLEAN GotIt = CcPinMappedData
+ (FileObject,
+ FileOffset,
+ Length,
+ Flags,
+ Bcb);
+
+ PNOCC_BCB TheBcb = (PNOCC_BCB)*Bcb;
+ ULONG Start = TheBcb - CcCacheSections;
+
+ DPRINT("CcPreparePinWrite(#%x)\n", Start);
+
+ if (GotIt)
+ {
+ CcCacheSections[Start].Dirty = TRUE;
+ *Buffer = (PVOID)((PCHAR)TheBcb->BaseAddress + (FileOffset->QuadPart -
TheBcb->FileOffset.QuadPart));
+ DPRINT("Returning Buffer: %x\n", *Buffer);
+ }
+
+ DPRINT("Done\n");
+ return GotIt;
+}
+
+VOID
+NTAPI
+CcUnpinData(IN PVOID Bcb)
+{
+ PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
+ ULONG Selected = RealBcb - CcCacheSections;
+ DPRINT("CcUnpinData Bcb #%x (RefCount %d)\n", Selected,
RealBcb->RefCount);
+ CcpLock();
+ if (RealBcb->RefCount <= 2)
+ {
+ DPRINT("Unset allocation bit #%x\n", Selected);
+ RtlClearBit(CcCacheBitmap, Selected);
+ RealBcb->Exclusive = FALSE;
+ if (RealBcb->ExclusiveWaiter)
+ {
+ DPRINT("Triggering exclusive waiter\n");
+ KeSetEvent(&RealBcb->ExclusiveWait, IO_NO_INCREMENT, FALSE);
+ }
+ }
+ if (RealBcb->RefCount > 1)
+ {
+ DPRINT("Removing one reference #%x\n", Selected);
+ RealBcb->RefCount--;
+ ASSERT(RealBcb->RefCount);
+ }
+ CcpUnlock();
+ KeSetEvent(&CcDeleteEvent, IO_DISK_INCREMENT, FALSE);
+}
+
+VOID
+NTAPI
+CcSetBcbOwnerPointer(IN PVOID Bcb,
+ IN PVOID OwnerPointer)
+{
+ PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
+ CcpLock();
+ CcpReferenceCache(RealBcb - CcCacheSections);
+ RealBcb->OwnerPointer = OwnerPointer;
+ CcpUnlock();
+}
+
+VOID
+NTAPI
+CcUnpinDataForThread(IN PVOID Bcb,
+ IN ERESOURCE_THREAD ResourceThreadId)
+{
+ CcUnpinData(Bcb);
+}
+
+/* EOF */
Propchange: branches/arty-newcc/ntoskrnl/cache/pinsup.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/arty-newcc/ntoskrnl/cache/vacbsup.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/vacbs…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/vacbsup.c (added)
+++ branches/arty-newcc/ntoskrnl/cache/vacbsup.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -1,0 +1,19 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/cache/vacbsup.c
+ * PURPOSE: Logging and configuration routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+/* EOF */
Propchange: branches/arty-newcc/ntoskrnl/cache/vacbsup.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/arty-newcc/ntoskrnl/include/internal/cc.h
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/include/int…
==============================================================================
--- branches/arty-newcc/ntoskrnl/include/internal/cc.h [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/include/internal/cc.h [iso-8859-1] Sun Aug 10 05:14:55
2008
@@ -102,6 +102,7 @@
LONG ActivePrefetches;
} PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS;
+#if 0
typedef struct _BCB
{
LIST_ENTRY BcbSegmentListHead;
@@ -120,49 +121,38 @@
BOOLEAN Trace; /* enable extra trace output for this BCB and it's cache segments */
#endif
} BCB, *PBCB;
-
-typedef struct _CACHE_SEGMENT
-{
- /* Base address of the region where the cache segment data is mapped. */
- PVOID BaseAddress;
- /*
- * Memory area representing the region where the cache segment data is
- * mapped.
- */
- struct _MEMORY_AREA* MemoryArea;
- /* Are the contents of the cache segment data valid. */
- BOOLEAN Valid;
- /* Are the contents of the cache segment data newer than those on disk. */
- BOOLEAN Dirty;
- /* Page out in progress */
- BOOLEAN PageOut;
- ULONG MappedCount;
- /* Entry in the list of segments for this BCB. */
- LIST_ENTRY BcbSegmentListEntry;
- /* Entry in the list of segments which are dirty. */
- LIST_ENTRY DirtySegmentListEntry;
- /* Entry in the list of segments. */
- LIST_ENTRY CacheSegmentListEntry;
- LIST_ENTRY CacheSegmentLRUListEntry;
- /* Offset in the file which this cache segment maps. */
- ULONG FileOffset;
- /* Lock. */
- EX_PUSH_LOCK Lock;
- /* Number of references. */
- ULONG ReferenceCount;
- /* Pointer to the BCB for the file which this cache segment maps data for. */
- PBCB Bcb;
- /* Pointer to the next cache segment in a chain. */
- struct _CACHE_SEGMENT* NextInChain;
-} CACHE_SEGMENT, *PCACHE_SEGMENT;
-
-typedef struct _INTERNAL_BCB
-{
- PUBLIC_BCB PFCB;
- PCACHE_SEGMENT CacheSegment;
- BOOLEAN Dirty;
- CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
-} INTERNAL_BCB, *PINTERNAL_BCB;
+#endif
+
+typedef struct _NOCC_BCB
+{
+ /* Public part */
+ PUBLIC_BCB Bcb;
+
+ /* So we know the initial request that was made */
+ PFILE_OBJECT FileObject;
+ PSECTION_OBJECT SectionObject;
+ LARGE_INTEGER FileOffset;
+ ULONG Length;
+ PVOID BaseAddress;
+ BOOLEAN Dirty;
+ PVOID OwnerPointer;
+
+ /* Reference counts */
+ ULONG RefCount;
+
+ LIST_ENTRY ThisFileList;
+
+ KEVENT ExclusiveWait;
+ BOOLEAN Exclusive;
+ ULONG ExclusiveWaiter;
+} NOCC_BCB, *PNOCC_BCB;
+
+typedef struct _NOCC_CACHE_MAP
+{
+ LIST_ENTRY AssociatedBcb;
+ PFILE_OBJECT FileObject;
+ ULONG NumberOfMaps;
+} NOCC_CACHE_MAP, *PNOCC_CACHE_MAP;
VOID
NTAPI
@@ -185,78 +175,17 @@
IN PMDL MdlChain
);
-NTSTATUS
-NTAPI
-CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment);
-
-NTSTATUS
-NTAPI
-CcRosGetCacheSegment(
- PBCB Bcb,
- ULONG FileOffset,
- PULONG BaseOffset,
- PVOID *BaseAddress,
- PBOOLEAN UptoDate,
- PCACHE_SEGMENT *CacheSeg
-);
-
VOID
NTAPI
CcInitView(VOID);
-NTSTATUS
-NTAPI
-CcRosFreeCacheSegment(
- PBCB,
- PCACHE_SEGMENT
-);
-
-NTSTATUS
-NTAPI
-ReadCacheSegment(PCACHE_SEGMENT CacheSeg);
-
-NTSTATUS
-NTAPI
-WriteCacheSegment(PCACHE_SEGMENT CacheSeg);
-
BOOLEAN
NTAPI
CcInitializeCacheManager(VOID);
-NTSTATUS
-NTAPI
-CcRosUnmapCacheSegment(
- PBCB Bcb,
- ULONG FileOffset,
- BOOLEAN NowDirty
-);
-
-PCACHE_SEGMENT
-NTAPI
-CcRosLookupCacheSegment(
- PBCB Bcb,
- ULONG FileOffset
-);
-
-NTSTATUS
-NTAPI
-CcRosGetCacheSegmentChain(
- PBCB Bcb,
- ULONG FileOffset,
- ULONG Length,
- PCACHE_SEGMENT* CacheSeg
-);
-
VOID
NTAPI
CcInitCacheZeroPage(VOID);
-
-NTSTATUS
-NTAPI
-CcRosMarkDirtyCacheSegment(
- PBCB Bcb,
- ULONG FileOffset
-);
NTSTATUS
NTAPI
@@ -276,26 +205,6 @@
VOID
NTAPI
CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer);
-
-NTSTATUS
-NTAPI
-CcRosReleaseCacheSegment(
- BCB* Bcb,
- CACHE_SEGMENT *CacheSeg,
- BOOLEAN Valid,
- BOOLEAN Dirty,
- BOOLEAN Mapped
-);
-
-NTSTATUS
-NTAPI
-CcRosRequestCacheSegment(
- BCB *Bcb,
- ULONG FileOffset,
- PVOID* BaseAddress,
- PBOOLEAN UptoDate,
- CACHE_SEGMENT **CacheSeg
-);
NTSTATUS
NTAPI
@@ -310,4 +219,29 @@
(*(ULONG*)(__FILE__ + sizeof(__FILE__) - 4) << 16) | \
(__LINE__ & 0xFFFF), 0, 0, 0)
+/* 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 CACHE_NEED_SECTIONS(OFFSET,LENGTH) \
+ ((CACHE_ROUND_UP((OFFSET)->QuadPart + (LENGTH)) - \
+ CACHE_ROUND_DOWN((OFFSET)->QuadPart)) >> CACHE_SHIFT)
+#define INVALID_CACHE ((ULONG)~0)
+
+extern NOCC_BCB CcCacheSections[CACHE_NUM_SECTIONS];
+extern PRTL_BITMAP CcCacheBitmap;
+extern KGUARDED_MUTEX CcMutex;
+extern KEVENT CcDeleteEvent;
+extern ULONG CcCacheClockHand;
+extern LIST_ENTRY CcPendingUnmap;
+
+extern VOID CcpLock();
+extern VOID CcpUnlock();
+extern VOID CcpDereferenceCache(ULONG Sector);
+
#endif
Modified: branches/arty-newcc/ntoskrnl/include/internal/io_x.h
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/include/int…
==============================================================================
--- branches/arty-newcc/ntoskrnl/include/internal/io_x.h [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/include/internal/io_x.h [iso-8859-1] Sun Aug 10 05:14:55
2008
@@ -10,11 +10,19 @@
static __inline
IopLockFileObject(IN PFILE_OBJECT FileObject)
{
+ ULONG CurrentThread = (ULONG)PsGetCurrentThread();
+
/* Lock the FO and check for contention */
+ if (FileObject->Busy == CurrentThread)
+ {
+ // Hack: Use the top byte for own-thread waiting
+ ExInterlockedAddUlong((PULONG)&FileObject->Waiters, 1<<24,
&FileObject->IrpListLock);
+ return;
+ }
InterlockedIncrement((PLONG)&FileObject->Waiters);
- while (InterlockedCompareExchange((PLONG)&FileObject->Busy, TRUE, FALSE) !=
FALSE)
+ while (InterlockedCompareExchange((PLONG)&FileObject->Busy, CurrentThread,
FALSE) != FALSE)
{
- /* FIXME - pause for a little while? */
+ KeWaitForSingleObject(&FileObject->Lock, UserRequest, KeGetPreviousMode(),
FALSE, NULL);
}
InterlockedDecrement((PLONG)&FileObject->Waiters);
}
Modified: branches/arty-newcc/ntoskrnl/include/internal/mm.h
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/include/int…
==============================================================================
--- branches/arty-newcc/ntoskrnl/include/internal/mm.h [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/include/internal/mm.h [iso-8859-1] Sun Aug 10 05:14:55
2008
@@ -176,7 +176,7 @@
typedef struct _MM_SECTION_SEGMENT
{
- LONG FileOffset; /* start offset into the file for image sections */
+ LARGE_INTEGER FileOffset; /* start offset into the file for image sections */
ULONG_PTR VirtualAddress; /* dtart offset into the address range for image sections
*/
ULONG RawLength; /* length of the segment which is part of the mapped file */
ULONG Length; /* absolute length of the segment */
@@ -1479,6 +1479,13 @@
NTAPI
MmFreeSectionSegments(PFILE_OBJECT FileObject);
+NTSTATUS STDCALL
+MmMapViewInSystemSpaceAtOffset
+(IN PVOID SectionObject,
+ OUT PVOID *MappedBase,
+ PLARGE_INTEGER FileOffset,
+ IN OUT PULONG ViewSize);
+
/* mpw.c *********************************************************************/
NTSTATUS
Modified: branches/arty-newcc/ntoskrnl/mm/mpw.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/mpw.c?re…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/mpw.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/mpw.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -81,14 +81,10 @@
}
PagesWritten = 0;
-#if 0
/*
* FIXME: MmWriteDirtyPages doesn't work correctly.
*/
MmWriteDirtyPages(128, &PagesWritten);
-#endif
-
- CcRosFlushDirtyPages(128, &PagesWritten);
}
}
Modified: branches/arty-newcc/ntoskrnl/mm/pe.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/pe.c?rev…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/pe.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/pe.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -182,6 +182,7 @@
ASSERT(((UINT_PTR)FileHeader % TYPE_ALIGNMENT(IMAGE_DOS_HEADER)) == 0);
#define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; }
+#define GASP(CODE,ARGS_) { nStatus = CODE; DPRINT ARGS_; goto l_Return; }
pBuffer = NULL;
pidhDosHeader = FileHeader;
@@ -199,7 +200,7 @@
/* not a Windows executable */
if(pidhDosHeader->e_lfanew <= 0)
- DIE(("Not a Windows executable, e_lfanew is %d\n",
pidhDosHeader->e_lfanew));
+ GASP(STATUS_INVALID_IMAGE_NE_FORMAT,("Not a Windows executable, e_lfanew is
%d\n", pidhDosHeader->e_lfanew));
/* NT HEADER */
nStatus = STATUS_INVALID_IMAGE_FORMAT;
@@ -567,7 +568,7 @@
if(!AlignUp(&nPrevVirtualEndOfSegment, cbHeadersSize, nSectionAlignment))
DIE(("Cannot align the size of the section headers\n"));
- pssSegments[0].FileOffset = 0;
+ pssSegments[0].FileOffset.QuadPart = 0;
pssSegments[0].Protection = PAGE_READONLY;
pssSegments[0].Length = nPrevVirtualEndOfSegment;
pssSegments[0].RawLength = nFileSizeOfHeaders;
@@ -609,16 +610,16 @@
// DIE(("PointerToRawData[%u] is not aligned\n", i));
/* conversion */
- pssSegments[i].FileOffset = pishSectionHeaders[i].PointerToRawData;
+ pssSegments[i].FileOffset.QuadPart = pishSectionHeaders[i].PointerToRawData;
pssSegments[i].RawLength = pishSectionHeaders[i].SizeOfRawData;
}
else
{
- ASSERT(pssSegments[i].FileOffset == 0);
+ ASSERT(pssSegments[i].FileOffset.QuadPart == 0);
ASSERT(pssSegments[i].RawLength == 0);
}
- ASSERT(Intsafe_CanAddLong64(pssSegments[i].FileOffset, pssSegments[i].RawLength));
+ ASSERT(Intsafe_CanAddLong64(pssSegments[i].FileOffset.QuadPart,
pssSegments[i].RawLength));
nCharacteristics = pishSectionHeaders[i].Characteristics;
Modified: branches/arty-newcc/ntoskrnl/mm/rmap.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/rmap.c?r…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -245,7 +245,7 @@
if (Type == MEMORY_AREA_SECTION_VIEW)
{
Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
- + MemoryArea->Data.SectionData.ViewOffset;;
+ + MemoryArea->Data.SectionData.ViewOffset;
/*
* Get or create a pageop
Modified: branches/arty-newcc/ntoskrnl/mm/section.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section.…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -94,6 +94,21 @@
/* FUNCTIONS *****************************************************************/
+PDEVICE_OBJECT
+NTAPI
+MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject)
+{
+ if (FileObject->Flags & (FO_DIRECT_DEVICE_OPEN | FO_STREAM_FILE))
+ {
+ /* Get the device object */
+ return IoGetAttachedDevice(FileObject->DeviceObject);
+ }
+ else
+ {
+ return IoGetRelatedDeviceObject(FileObject);
+ }
+}
+
PFILE_OBJECT
NTAPI
MmGetFileObjectForSection(IN PROS_SECTION_OBJECT Section)
@@ -103,6 +118,162 @@
/* Return the file object */
return Section->FileObject; // Section->ControlArea->FileObject on NT
+}
+
+NTSTATUS
+NTAPI
+MiSimpleReadComplete
+(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID Context)
+{
+ /* Unlock MDL Pages, page 167. */
+ PMDL Mdl = Irp->MdlAddress;
+ while (Mdl)
+ {
+ MmUnlockPages(Mdl);
+ Mdl = Mdl->Next;
+ }
+
+ /* Check if there's an MDL */
+ while ((Mdl = Irp->MdlAddress))
+ {
+ /* Clear all of them */
+ Irp->MdlAddress = Mdl->Next;
+ IoFreeMdl(Mdl);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+MiSimpleRead
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ ULONG Length,
+ PIO_STATUS_BLOCK ReadStatus)
+{
+ NTSTATUS Status;
+ PIRP Irp = NULL;
+ KEVENT ReadWait;
+ PDEVICE_OBJECT DeviceObject = MmGetDeviceObjectForFile(FileObject);
+ PIO_STACK_LOCATION IrpSp;
+
+ KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
+
+ Irp = IoBuildAsynchronousFsdRequest
+ (IRP_MJ_READ,
+ DeviceObject,
+ Buffer,
+ PAGE_SIZE,
+ FileOffset,
+ ReadStatus);
+
+ if (!Irp)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ Irp->Flags |= IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE;
+
+ ObReferenceObject(FileObject);
+
+ Irp->UserEvent = &ReadWait;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ IrpSp = IoGetNextIrpStackLocation(Irp);
+ IrpSp->FileObject = FileObject;
+
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ if (!NT_SUCCESS
+ (KeWaitForSingleObject
+ (&ReadWait,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL)))
+ {
+ DPRINT1("Warning: Failed to wait for synchronous IRP\n");
+ ASSERT(FALSE);
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+ }
+
+ ObDereferenceObject(FileObject);
+
+ DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
+
+ return ReadStatus->Status;
+}
+
+NTSTATUS
+NTAPI
+MiSimpleWrite
+(PFILE_OBJECT FileObject,
+ PLARGE_INTEGER FileOffset,
+ PVOID Buffer,
+ ULONG Length,
+ PIO_STATUS_BLOCK ReadStatus)
+{
+ NTSTATUS Status;
+ PIRP Irp = NULL;
+ KEVENT ReadWait;
+ PDEVICE_OBJECT DeviceObject = MmGetDeviceObjectForFile(FileObject);
+ PIO_STACK_LOCATION IrpSp;
+
+ KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
+
+ Irp = IoBuildAsynchronousFsdRequest
+ (IRP_MJ_WRITE,
+ DeviceObject,
+ Buffer,
+ Length,
+ FileOffset,
+ ReadStatus);
+
+ if (!Irp)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ Irp->Flags |= IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE;
+
+ ObReferenceObject(FileObject);
+
+ Irp->UserEvent = &ReadWait;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ IrpSp = IoGetNextIrpStackLocation(Irp);
+ IrpSp->FileObject = FileObject;
+
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ if (!NT_SUCCESS
+ (KeWaitForSingleObject
+ (&ReadWait,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL)))
+ {
+ DPRINT1("Warning: Failed to wait for synchronous IRP\n");
+ ASSERT(FALSE);
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+ }
+
+ ObDereferenceObject(FileObject);
+
+ DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
+
+ return ReadStatus->Status;
}
NTSTATUS
@@ -418,13 +589,12 @@
if (SHARE_COUNT_FROM_SSE(Entry) == 0)
{
PFILE_OBJECT FileObject;
- PBCB Bcb;
SWAPENTRY SavedSwapEntry;
PFN_TYPE Page;
BOOLEAN IsImageSection;
- ULONG FileOffset;
-
- FileOffset = Offset + Segment->FileOffset;
+ LARGE_INTEGER FileOffset;
+
+ FileOffset.QuadPart = Segment->FileOffset.QuadPart + Offset;
IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
@@ -434,18 +604,10 @@
!(Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
{
- if ((FileOffset % PAGE_SIZE) == 0 &&
+ if ((FileOffset.QuadPart % PAGE_SIZE) == 0 &&
(Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection))
{
- NTSTATUS Status;
- Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
IsDirectMapped = TRUE;
- Status = CcRosUnmapCacheSegment(Bcb, FileOffset, Dirty);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CcRosUnmapCacheSegment failed, status = %x\n",
Status);
- KEBUGCHECK(0);
- }
}
}
@@ -515,28 +677,10 @@
return(SHARE_COUNT_FROM_SSE(Entry) > 0);
}
-BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
- ULONG SegOffset)
-{
- if (!(MemoryArea->Data.SectionData.Segment->Characteristics &
IMAGE_SCN_MEM_SHARED))
- {
- PBCB Bcb;
- PCACHE_SEGMENT CacheSeg;
- Bcb =
MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap;
- CacheSeg = CcRosLookupCacheSegment(Bcb, SegOffset +
MemoryArea->Data.SectionData.Segment->FileOffset);
- if (CacheSeg)
- {
- CcRosReleaseCacheSegment(Bcb, CacheSeg, CacheSeg->Valid, FALSE, TRUE);
- return TRUE;
- }
- }
- return FALSE;
-}
-
NTSTATUS
NTAPI
MiReadPage(PMEMORY_AREA MemoryArea,
- ULONG SegOffset,
+ PLARGE_INTEGER FileOffset,
PPFN_TYPE Page)
/*
* FUNCTION: Read a page for a section backed memory area.
@@ -546,163 +690,68 @@
* Page - Variable that receives a page contains the read data.
*/
{
- ULONG BaseOffset;
- ULONG FileOffset;
- PVOID BaseAddress;
- BOOLEAN UptoDate;
- PCACHE_SEGMENT CacheSeg;
PFILE_OBJECT FileObject;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
ULONG RawLength;
- PBCB Bcb;
BOOLEAN IsImageSection;
- ULONG Length;
+ PVOID Buffer = NULL;
+ IO_STATUS_BLOCK ReadStatus;
+ FILE_STANDARD_INFORMATION FileInfo;
+
+ *Page = 0;
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
- Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
+ ASSERT(FileObject);
RawLength = MemoryArea->Data.SectionData.Segment->RawLength;
- FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->FileOffset;
IsImageSection = MemoryArea->Data.SectionData.Section->AllocationAttributes
& SEC_IMAGE ? TRUE : FALSE;
- ASSERT(Bcb);
-
- DPRINT("%S %x\n", FileObject->FileName.Buffer, FileOffset);
-
- /*
- * If the file system is letting us go directly to the cache and the
- * memory area was mapped at an offset in the file which is page aligned
- * then get the related cache segment.
- */
- if ((FileOffset % PAGE_SIZE) == 0 &&
- (SegOffset + PAGE_SIZE <= RawLength || !IsImageSection) &&
- !(MemoryArea->Data.SectionData.Segment->Characteristics &
IMAGE_SCN_MEM_SHARED))
- {
-
- /*
- * Get the related cache segment; we use a lower level interface than
- * filesystems do because it is safe for us to use an offset with a
- * alignment less than the file system block size.
- */
- Status = CcRosGetCacheSegment(Bcb,
- FileOffset,
- &BaseOffset,
- &BaseAddress,
- &UptoDate,
- &CacheSeg);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- if (!UptoDate)
- {
- /*
- * If the cache segment isn't up to date then call the file
- * system to read in the data.
- */
- Status = ReadCacheSegment(CacheSeg);
- if (!NT_SUCCESS(Status))
- {
- CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
- return Status;
- }
- }
- /*
- * Retrieve the page from the cache segment that we actually want.
- */
- (*Page) = MmGetPhysicalAddress((char*)BaseAddress +
- FileOffset - BaseOffset).LowPart >>
PAGE_SHIFT;
-
- CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, TRUE);
+ DPRINT("MiReadPage: FileObject %x, Offset %x\n", FileObject,
FileOffset->LowPart);
+
+ Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, Page);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Buffer = MmCreateHyperspaceMapping(*Page);
+ if (!Buffer)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+
+ DPRINT("Read File Name:[%wZ] At:%x\n", &FileObject->FileName,
FileOffset->LowPart);
+
+ Status = IoQueryFileInformation
+ (FileObject,
+ FileStandardInformation,
+ sizeof(FILE_STANDARD_INFORMATION),
+ &FileInfo,
+ &ReadStatus.Information);
+
+ if (NT_SUCCESS(Status) &&
+ FileOffset->QuadPart + PAGE_SIZE > PAGE_ROUND_UP(FileInfo.EndOfFile.QuadPart))
+ {
+ RtlZeroMemory(Buffer, PAGE_SIZE);
}
else
{
- PVOID PageAddr;
- ULONG CacheSegOffset;
- /*
- * Allocate a page, this is rather complicated by the possibility
- * we might have to move other things out of memory
- */
- Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, Page);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- Status = CcRosGetCacheSegment(Bcb,
- FileOffset,
- &BaseOffset,
- &BaseAddress,
- &UptoDate,
- &CacheSeg);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- if (!UptoDate)
- {
- /*
- * If the cache segment isn't up to date then call the file
- * system to read in the data.
- */
- Status = ReadCacheSegment(CacheSeg);
- if (!NT_SUCCESS(Status))
- {
- CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
- return Status;
- }
- }
- PageAddr = MmCreateHyperspaceMapping(*Page);
- CacheSegOffset = BaseOffset + CacheSeg->Bcb->CacheSegmentSize - FileOffset;
- Length = RawLength - SegOffset;
- if (Length <= CacheSegOffset && Length <= PAGE_SIZE)
- {
- memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, Length);
- }
- else if (CacheSegOffset >= PAGE_SIZE)
- {
- memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, PAGE_SIZE);
- }
- else
- {
- memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, CacheSegOffset);
- CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
- Status = CcRosGetCacheSegment(Bcb,
- FileOffset + CacheSegOffset,
- &BaseOffset,
- &BaseAddress,
- &UptoDate,
- &CacheSeg);
- if (!NT_SUCCESS(Status))
- {
- MmDeleteHyperspaceMapping(PageAddr);
- return(Status);
- }
- if (!UptoDate)
- {
- /*
- * If the cache segment isn't up to date then call the file
- * system to read in the data.
- */
- Status = ReadCacheSegment(CacheSeg);
- if (!NT_SUCCESS(Status))
- {
- CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
- MmDeleteHyperspaceMapping(PageAddr);
- return Status;
- }
- }
- if (Length < PAGE_SIZE)
- {
- memcpy((char*)PageAddr + CacheSegOffset, BaseAddress, Length -
CacheSegOffset);
- }
- else
- {
- memcpy((char*)PageAddr + CacheSegOffset, BaseAddress, PAGE_SIZE -
CacheSegOffset);
- }
- }
- CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
- MmDeleteHyperspaceMapping(PageAddr);
- }
- return(STATUS_SUCCESS);
+ /*
+ * If the cache segment isn't up to date then call the file
+ * system to read in the data.
+ */
+
+ Status = MiSimpleRead(FileObject, FileOffset, Buffer, PAGE_SIZE, &ReadStatus);
+ DPRINT("MiSimpleRead: Status %08x\n", Status);
+ }
+
+cleanup:
+ if (Buffer) MmDeleteHyperspaceMapping(Buffer);
+ if (!NT_SUCCESS(Status) && *Page) MmReleasePageMemoryConsumer(MC_USER,
*Page);
+
+ DPRINT("Finished MiReadPage: Status %x\n", Status);
+
+ return Status;
}
NTSTATUS
@@ -1040,7 +1089,7 @@
MmUnlockSectionSegment(Segment);
MmUnlockAddressSpace(AddressSpace);
- if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
+ if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
(Offset >= PAGE_ROUND_UP(Segment->RawLength) &&
Section->AllocationAttributes & SEC_IMAGE))
{
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
@@ -1051,11 +1100,16 @@
}
else
{
- Status = MiReadPage(MemoryArea, Offset, &Page);
+ LARGE_INTEGER ReadOffset;
+ ReadOffset.QuadPart =
+ Segment->FileOffset.QuadPart +
+ Offset;
+ Status = MiReadPage(MemoryArea, &ReadOffset, &Page);
if (!NT_SUCCESS(Status))
{
DPRINT1("MiReadPage failed (Status %x)\n", Status);
}
+ DPRINT("PAGING IO DONE: %08x\n", Status);
}
if (!NT_SUCCESS(Status))
{
@@ -1458,10 +1512,9 @@
MM_SECTION_PAGEOUT_CONTEXT Context;
SWAPENTRY SwapEntry;
ULONG Entry;
- ULONG FileOffset;
+ LARGE_INTEGER FileOffset;
NTSTATUS Status;
PFILE_OBJECT FileObject;
- PBCB Bcb = NULL;
BOOLEAN DirectMapped;
BOOLEAN IsImageSection;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
@@ -1476,7 +1529,7 @@
Context.Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+ MemoryArea->Data.SectionData.ViewOffset;
- FileOffset = Context.Offset + Context.Segment->FileOffset;
+ FileOffset.QuadPart = Context.Segment->FileOffset.QuadPart + Context.Offset;
IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE :
FALSE;
@@ -1485,14 +1538,12 @@
if (FileObject != NULL &&
!(Context.Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
{
- Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-
/*
* If the file system is letting us go directly to the cache and the
* memory area was mapped at an offset in the file which is page aligned
* then note this is a direct mapped page.
*/
- if ((FileOffset % PAGE_SIZE) == 0 &&
+ if ((FileOffset.QuadPart % PAGE_SIZE) == 0 &&
(Context.Offset + PAGE_SIZE <= Context.Segment->RawLength ||
!IsImageSection))
{
DirectMapped = TRUE;
@@ -1543,15 +1594,7 @@
/*
* Take an additional reference to the page or the cache segment.
*/
- if (DirectMapped && !Context.Private)
- {
- if(!MiIsPageFromCache(MemoryArea, Context.Offset))
- {
- DPRINT1("Direct mapped non private page is not associated with the
cache.\n");
- KEBUGCHECK(0);
- }
- }
- else
+ if (!(DirectMapped && !Context.Private))
{
MmReferencePage(Page);
}
@@ -1624,12 +1667,6 @@
{
DPRINT1("Found a swapentry for a non private and direct mapped page
(address %x)\n",
Address);
- KEBUGCHECK(0);
- }
- Status = CcRosUnmapCacheSegment(Bcb, FileOffset, FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CCRosUnmapCacheSegment failed, status = %x\n", Status);
KEBUGCHECK(0);
}
PageOp->Status = STATUS_SUCCESS;
@@ -1817,7 +1854,6 @@
BOOLEAN Private;
NTSTATUS Status;
PFILE_OBJECT FileObject;
- PBCB Bcb = NULL;
BOOLEAN DirectMapped;
BOOLEAN IsImageSection;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
@@ -1825,7 +1861,7 @@
Address = (PVOID)PAGE_ROUND_DOWN(Address);
Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
- + MemoryArea->Data.SectionData.ViewOffset;
+ + MemoryArea->Data.SectionData.ViewOffset;
/*
* Get the segment and section.
@@ -1839,14 +1875,12 @@
if (FileObject != NULL &&
!(Segment->Characteristics & IMAGE_SCN_MEM_SHARED))
{
- Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-
/*
* If the file system is letting us go directly to the cache and the
* memory area was mapped at an offset in the file which is page aligned
* then note this is a direct mapped page.
*/
- if (((Offset + Segment->FileOffset) % PAGE_SIZE) == 0 &&
+ if (((Offset + Segment->FileOffset.QuadPart) % PAGE_SIZE) == 0 &&
(Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection))
{
DirectMapped = TRUE;
@@ -1903,11 +1937,31 @@
*/
if (DirectMapped && !Private)
{
- ASSERT(SwapEntry == 0);
- CcRosMarkDirtyCacheSegment(Bcb, Offset + Segment->FileOffset);
- PageOp->Status = STATUS_SUCCESS;
- MmspCompleteAndReleasePageOp(PageOp);
- return(STATUS_SUCCESS);
+ LONG RemainingLength;
+ NTSTATUS Status;
+ LARGE_INTEGER FileOffset;
+ IO_STATUS_BLOCK ReadStatus;
+
+ FileOffset.QuadPart = Offset;
+
+ RemainingLength = min(PAGE_SIZE, Segment->FileOffset.QuadPart + Segment->Length
- FileOffset.QuadPart);
+ DPRINT("Writing no more than %d bytes\n", RemainingLength);
+
+ if (RemainingLength > 0)
+ {
+ Status = MiSimpleWrite
+ (Section->FileObject,
+ &FileOffset,
+ Address,
+ RemainingLength,
+ &ReadStatus);
+ } else
+ Status = STATUS_SUCCESS;
+
+ PageOp->Status = Status;
+ MmspCompleteAndReleasePageOp(PageOp);
+
+ return(Status);
}
/*
@@ -1991,7 +2045,7 @@
PFN_TYPE Page;
Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
- + MemoryArea->Data.SectionData.ViewOffset;
+ + MemoryArea->Data.SectionData.ViewOffset;
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
Page = MmGetPfnForProcess(Process, Address);
@@ -2193,7 +2247,6 @@
}
if (Section->FileObject != NULL)
{
- CcRosDereferenceCache(Section->FileObject);
ObDereferenceObject(Section->FileObject);
Section->FileObject = NULL;
}
@@ -2345,7 +2398,7 @@
Section->Segment = Segment;
Segment->ReferenceCount = 1;
ExInitializeFastMutex(&Segment->Lock);
- Segment->FileOffset = 0;
+ Segment->FileOffset.QuadPart = 0;
Segment->Protection = SectionPageProtection;
Segment->RawLength = MaximumSize.u.LowPart;
Segment->Length = PAGE_ROUND_UP(MaximumSize.u.LowPart);
@@ -2367,21 +2420,20 @@
PLARGE_INTEGER UMaximumSize,
ULONG SectionPageProtection,
ULONG AllocationAttributes,
- HANDLE FileHandle)
+ PFILE_OBJECT FileObject)
/*
* Create a section backed by a data file
*/
{
PROS_SECTION_OBJECT Section;
+ LARGE_INTEGER MaximumSize;
+ PMM_SECTION_SEGMENT Segment;
NTSTATUS Status;
- LARGE_INTEGER MaximumSize;
- PFILE_OBJECT FileObject;
- PMM_SECTION_SEGMENT Segment;
ULONG FileAccess;
IO_STATUS_BLOCK Iosb;
- LARGE_INTEGER Offset;
- CHAR Buffer;
FILE_STANDARD_INFORMATION FileInfo;
+
+ DPRINT("MmCreateDataFileSection [%wZ]\n", &FileObject->FileName);
/*
* Create the section
@@ -2397,6 +2449,7 @@
(PVOID*)(PVOID)&Section);
if (!NT_SUCCESS(Status))
{
+ DPRINT("Failed: %08x\n", Status);
return(Status);
}
/*
@@ -2417,21 +2470,6 @@
else
{
FileAccess = FILE_READ_DATA;
- }
-
- /*
- * Reference the file handle
- */
- Status = ObReferenceObjectByHandle(FileHandle,
- FileAccess,
- IoFileObjectType,
- ExGetPreviousMode(),
- (PVOID*)(PVOID)&FileObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(Section);
- return(Status);
}
/*
@@ -2445,10 +2483,12 @@
sizeof(FILE_STANDARD_INFORMATION),
&FileInfo,
&Iosb.Information);
+
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(Section);
ObDereferenceObject(FileObject);
+ DPRINT("Failed: %08x\n", Status);
return Status;
}
@@ -2468,55 +2508,8 @@
{
ObDereferenceObject(Section);
ObDereferenceObject(FileObject);
+ DPRINT("Failed: STATUS_FILE_INVALID\n");
return STATUS_FILE_INVALID;
- }
- }
-
- if (MaximumSize.QuadPart > FileInfo.EndOfFile.QuadPart)
- {
- Status = IoSetInformation(FileObject,
- FileAllocationInformation,
- sizeof(LARGE_INTEGER),
- &MaximumSize);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(Section);
- ObDereferenceObject(FileObject);
- return(STATUS_SECTION_NOT_EXTENDED);
- }
- }
-
- if (FileObject->SectionObjectPointer == NULL ||
- FileObject->SectionObjectPointer->SharedCacheMap == NULL)
- {
- /*
- * Read a bit so caching is initiated for the file object.
- * This is only needed because MiReadPage currently cannot
- * handle non-cached streams.
- */
- Offset.QuadPart = 0;
- Status = ZwReadFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- &Buffer,
- sizeof (Buffer),
- &Offset,
- 0);
- if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
- {
- ObDereferenceObject(Section);
- ObDereferenceObject(FileObject);
- return(Status);
- }
- if (FileObject->SectionObjectPointer == NULL ||
- FileObject->SectionObjectPointer->SharedCacheMap == NULL)
- {
- /* FIXME: handle this situation */
- ObDereferenceObject(Section);
- ObDereferenceObject(FileObject);
- return STATUS_INVALID_PARAMETER;
}
}
@@ -2528,6 +2521,7 @@
{
ObDereferenceObject(Section);
ObDereferenceObject(FileObject);
+ DPRINT("Failed: %08x\n", Status);
return(Status);
}
@@ -2544,6 +2538,7 @@
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
ObDereferenceObject(Section);
ObDereferenceObject(FileObject);
+ DPRINT("Failed: STATUS_NO_MEMORY\n");
return(STATUS_NO_MEMORY);
}
Section->Segment = Segment;
@@ -2555,11 +2550,12 @@
ExAcquireFastMutex(&Segment->Lock);
FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment;
- Segment->FileOffset = 0;
+ Segment->FileOffset.QuadPart = 0;
Segment->Protection = SectionPageProtection;
Segment->Flags = MM_DATAFILE_SEGMENT;
Segment->Characteristics = 0;
Segment->WriteCopy = FALSE;
+
if (AllocationAttributes & SEC_RESERVE)
{
Segment->Length = Segment->RawLength = 0;
@@ -2567,7 +2563,7 @@
else
{
Segment->RawLength = MaximumSize.u.LowPart;
- Segment->Length = PAGE_ROUND_UP(Segment->RawLength);
+ Segment->Length = FileInfo.AllocationSize.QuadPart;
}
Segment->VirtualAddress = 0;
RtlZeroMemory(&Segment->PageDirectory, sizeof(SECTION_PAGE_DIRECTORY));
@@ -2595,9 +2591,8 @@
MmUnlockSectionSegment(Segment);
Section->FileObject = FileObject;
Section->MaximumSize = MaximumSize;
- CcRosReferenceCache(FileObject);
- //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
*SectionObject = Section;
+ DPRINT("Success\n");
return(STATUS_SUCCESS);
}
@@ -2672,13 +2667,15 @@
OUT PULONG ReadSize)
{
NTSTATUS Status;
+ PFILE_OBJECT FileObject = (PFILE_OBJECT)File;
LARGE_INTEGER FileOffset;
ULONG AdjustOffset;
ULONG OffsetAdjustment;
ULONG BufferSize;
ULONG UsedSize;
PVOID Buffer;
-
+ IO_STATUS_BLOCK ReadStatus;
+
ASSERT_IRQL_LESS(DISPATCH_LEVEL);
if(Length == 0)
@@ -2713,38 +2710,12 @@
UsedSize = 0;
-#if 0
- Status = MmspPageRead(File,
- Buffer,
- BufferSize,
- &FileOffset,
- &UsedSize);
-#else
-/*
- * FIXME: if we don't use ZwReadFile, caching is not enabled for the file and
- * nothing will work. But using ZwReadFile is wrong, and using its side effects
- * to initialize internal state is even worse. Our cache manager is in need of
- * professional help
- */
- {
- IO_STATUS_BLOCK Iosb;
-
- Status = ZwReadFile(File,
- NULL,
- NULL,
- NULL,
- &Iosb,
- Buffer,
- BufferSize,
- &FileOffset,
- NULL);
-
- if(NT_SUCCESS(Status))
- {
- UsedSize = Iosb.Information;
- }
- }
-#endif
+ Status = MiSimpleRead(FileObject, &FileOffset, Buffer, Length, &ReadStatus);
+ DPRINT("MiSimpleRead: Status %08x\n", Status);
+
+ UsedSize = ReadStatus.Information;
+
+ DPRINT("ExeFmtpReadFile -> %x:%x\n", Status, UsedSize);
if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
{
@@ -2757,6 +2728,8 @@
*Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment);
*AllocBase = Buffer;
*ReadSize = UsedSize - OffsetAdjustment;
+ DPRINT("Data @ %x Buffer @ %x Read Size %d\n", *Data, *AllocBase,
*ReadSize);
+ DPRINT("First couple of bytes: %02x%02x\n", ((PCHAR)Data)[0] & 0xff,
((PCHAR)Data)[1] & 0xff);
}
else
{
@@ -2961,7 +2934,7 @@
/* Adjust the raw address and size */
VirtualOffset = VirtualAddress - EffectiveSegment->VirtualAddress;
- if (EffectiveSegment->FileOffset < VirtualOffset)
+ if (EffectiveSegment->FileOffset.QuadPart < VirtualOffset)
{
return FALSE;
}
@@ -2971,7 +2944,7 @@
* offset point in curious and odd places, but that's what we were
* asked for
*/
- EffectiveSegment->FileOffset -= VirtualOffset;
+ EffectiveSegment->FileOffset.QuadPart -= VirtualOffset;
EffectiveSegment->RawLength += VirtualOffset;
}
else
@@ -3043,8 +3016,9 @@
*/
/* Unaligned segments must be contiguous within the file */
- if (Segment->FileOffset != (EffectiveSegment->FileOffset +
- EffectiveSegment->RawLength))
+ if (Segment->FileOffset.QuadPart !=
+ (EffectiveSegment->FileOffset.QuadPart +
+ EffectiveSegment->RawLength))
{
return FALSE;
}
@@ -3104,7 +3078,7 @@
}
NTSTATUS
-ExeFmtpCreateImageSection(HANDLE FileHandle,
+ExeFmtpCreateImageSection(PFILE_OBJECT FileObject,
PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
{
LARGE_INTEGER Offset;
@@ -3123,7 +3097,7 @@
Offset.QuadPart = 0;
/* FIXME: use FileObject instead of FileHandle */
- Status = ExeFmtpReadFile (FileHandle,
+ Status = ExeFmtpReadFile (FileObject,
&Offset,
PAGE_SIZE * 2,
&FileHeader,
@@ -3150,7 +3124,7 @@
/* FIXME: use FileObject instead of FileHandle */
Status = ExeFmtpLoaders[i](FileHeader,
FileHeaderSize,
- FileHandle,
+ FileObject,
ImageSectionObject,
&Flags,
ExeFmtpReadFile,
@@ -3197,10 +3171,10 @@
if(ImageSectionObject->ImageBase == 0)
{
- if(ImageSectionObject->ImageCharacteristics & IMAGE_FILE_DLL)
- ImageSectionObject->ImageBase = 0x10000000;
- else
- ImageSectionObject->ImageBase = 0x00400000;
+ if(ImageSectionObject->ImageCharacteristics & IMAGE_FILE_DLL)
+ ImageSectionObject->ImageBase = 0x10000000;
+ else
+ ImageSectionObject->ImageBase = 0x00400000;
}
/*
@@ -3245,7 +3219,7 @@
{
ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock);
ImageSectionObject->Segments[i].ReferenceCount = 1;
-
+
RtlZeroMemory(&ImageSectionObject->Segments[i].PageDirectory,
sizeof(ImageSectionObject->Segments[i].PageDirectory));
}
@@ -3261,11 +3235,10 @@
PLARGE_INTEGER UMaximumSize,
ULONG SectionPageProtection,
ULONG AllocationAttributes,
- HANDLE FileHandle)
+ PFILE_OBJECT FileObject)
{
PROS_SECTION_OBJECT Section;
NTSTATUS Status;
- PFILE_OBJECT FileObject;
PMM_SECTION_SEGMENT SectionSegments;
PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
ULONG i;
@@ -3295,12 +3268,7 @@
/*
* Reference the file handle
*/
- Status = ObReferenceObjectByHandle(FileHandle,
- FileAccess,
- IoFileObjectType,
- ExGetPreviousMode(),
- (PVOID*)(PVOID)&FileObject,
- NULL);
+ Status = ObReferenceObject(FileObject);
if (!NT_SUCCESS(Status))
{
@@ -3331,12 +3299,6 @@
Section->SectionPageProtection = SectionPageProtection;
Section->AllocationAttributes = AllocationAttributes;
- /*
- * Initialized caching for this file object if previously caching
- * was initialized for the same on disk file
- */
- Status = CcTryToInitializeFileCache(FileObject);
-
if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject
== NULL)
{
NTSTATUS StatusExeFmt;
@@ -3351,7 +3313,7 @@
RtlZeroMemory(ImageSectionObject, sizeof(MM_IMAGE_SECTION_OBJECT));
- StatusExeFmt = ExeFmtpCreateImageSection(FileHandle, ImageSectionObject);
+ StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject);
if (!NT_SUCCESS(StatusExeFmt))
{
@@ -3428,8 +3390,6 @@
Status = STATUS_SUCCESS;
}
Section->FileObject = FileObject;
- CcRosReferenceCache(FileObject);
- //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
*SectionObject = Section;
return(Status);
}
@@ -3491,6 +3451,7 @@
SectionHandle);
}
+ DPRINT("NtCreateSection -> %08x\n", Status);
return Status;
}
@@ -3832,8 +3793,6 @@
PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
{
ULONG Entry;
- PFILE_OBJECT FileObject;
- PBCB Bcb;
ULONG Offset;
SWAPENTRY SavedSwapEntry;
PMM_PAGEOP PageOp;
@@ -3842,6 +3801,7 @@
PMM_SECTION_SEGMENT Segment;
PMM_AVL_TABLE AddressSpace;
PEPROCESS Process;
+
AddressSpace = (PMM_AVL_TABLE)Context;
Process = MmGetAddressSpaceOwner(AddressSpace);
@@ -3849,7 +3809,7 @@
Address = (PVOID)PAGE_ROUND_DOWN(Address);
Offset = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) +
- MemoryArea->Data.SectionData.ViewOffset;
+ MemoryArea->Data.SectionData.ViewOffset;
Section = MemoryArea->Data.SectionData.Section;
Segment = MemoryArea->Data.SectionData.Segment;
@@ -3882,13 +3842,39 @@
*/
if (Segment->Flags & MM_DATAFILE_SEGMENT)
{
- if (Page == PFN_FROM_SSE(Entry) && Dirty)
- {
- FileObject = MemoryArea->Data.SectionData.Section->FileObject;
- Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
- CcRosMarkDirtyCacheSegment(Bcb, Offset + Segment->FileOffset);
- ASSERT(SwapEntry == 0);
- }
+ if (Page == PFN_FROM_SSE(Entry) && Dirty)
+ {
+ LARGE_INTEGER FileOffset;
+ IO_STATUS_BLOCK ReadStatus;
+ ULONG RemainingLength;
+ PVOID Buffer = MmCreateHyperspaceMapping(Page);
+ NTSTATUS Status;
+
+ FileOffset.QuadPart = Offset;
+
+ MmUnlockSectionSegment(Segment);
+ MmUnlockAddressSpace(AddressSpace);
+
+ RemainingLength = min(PAGE_SIZE, Segment->FileOffset.QuadPart + Segment->Length
- FileOffset.QuadPart);
+ DPRINT("Writing no more than %d bytes\n", RemainingLength);
+
+ if (RemainingLength > 0)
+ {
+ Status = MiSimpleWrite
+ (Section->FileObject,
+ &FileOffset,
+ Buffer,
+ min(RemainingLength, PAGE_SIZE),
+ &ReadStatus);
+ }
+ else
+ Status = STATUS_SUCCESS;
+
+ MmLockAddressSpace(AddressSpace);
+ MmLockSectionSegment(Segment);
+
+ MmDeleteHyperspaceMapping(Buffer);
+ }
}
if (SwapEntry != 0)
@@ -4705,6 +4691,7 @@
MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
IN MMFLUSH_TYPE FlushType)
{
+
switch(FlushType)
{
case MmFlushForDelete:
@@ -4713,11 +4700,20 @@
{
return FALSE;
}
- CcRosSetRemoveOnClose(SectionObjectPointer);
- return TRUE;
+ break;
+
case MmFlushForWrite:
break;
}
+
+#if 0
+ CcFlushCache
+ (SectionObjectPointer,
+ NULL,
+ 0,
+ NULL);
+#endif
+
return FALSE;
}
@@ -4734,6 +4730,50 @@
}
+NTSTATUS STDCALL
+MmMapViewInSystemSpaceAtOffset
+(IN PVOID SectionObject,
+ OUT PVOID *MappedBase,
+ PLARGE_INTEGER FileOffset,
+ IN OUT PULONG ViewSize)
+{
+ PROS_SECTION_OBJECT Section;
+ PMM_AVL_TABLE AddressSpace;
+ NTSTATUS Status;
+
+ DPRINT("MmMapViewInSystemSpaceAtOffset() called offset %x\n",
FileOffset->LowPart);
+
+ Section = (PROS_SECTION_OBJECT)SectionObject;
+ AddressSpace = MmGetKernelAddressSpace();
+
+ MmLockAddressSpace(AddressSpace);
+
+ if ((*ViewSize) == 0)
+ {
+ (*ViewSize) = Section->MaximumSize.u.LowPart;
+ }
+ else if ((*ViewSize) > Section->MaximumSize.u.LowPart)
+ {
+ (*ViewSize) = Section->MaximumSize.u.LowPart;
+ }
+
+ MmLockSectionSegment(Section->Segment);
+
+ Status = MmMapViewOfSegment(AddressSpace,
+ Section,
+ Section->Segment,
+ MappedBase,
+ *ViewSize,
+ PAGE_READWRITE,
+ FileOffset->LowPart,
+ 0);
+
+ MmUnlockSectionSegment(Section->Segment);
+ MmUnlockAddressSpace(AddressSpace);
+
+ return Status;
+}
+
/*
* @implemented
*/
@@ -4753,7 +4793,6 @@
MmLockAddressSpace(AddressSpace);
-
if ((*ViewSize) == 0)
{
(*ViewSize) = Section->MaximumSize.u.LowPart;
@@ -4764,7 +4803,6 @@
}
MmLockSectionSegment(Section->Segment);
-
Status = MmMapViewOfSegment(AddressSpace,
Section,
@@ -4772,7 +4810,7 @@
MappedBase,
*ViewSize,
PAGE_READWRITE,
- 0,
+ 0,
0);
MmUnlockSectionSegment(Section->Segment);
@@ -4810,7 +4848,11 @@
AddressSpace = MmGetKernelAddressSpace();
+ MmLockAddressSpace(AddressSpace);
+
Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
+
+ MmUnlockAddressSpace(AddressSpace);
return Status;
}
@@ -4891,8 +4933,9 @@
* Handle to a file to create a section mapped to a file
* instead of a memory backed section;
*
- * File
- * Unknown.
+ * FileObject
+ * Specifies a FILE_OBJECT. If this isn't NULL, then FileHandle
+ * is ignored.
*
* RETURN VALUE
* Status.
@@ -4907,9 +4950,13 @@
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
IN HANDLE FileHandle OPTIONAL,
- IN PFILE_OBJECT File OPTIONAL)
-{
+ IN PFILE_OBJECT FileObject OPTIONAL)
+{
+ PFILE_OBJECT OriginalFileObject = FileObject;
ULONG Protection;
+ NTSTATUS Status;
+ ULONG FileAccess = 0;
+ BOOLEAN ReferencedFile = FALSE;
PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
/*
@@ -4929,34 +4976,73 @@
return STATUS_INVALID_PAGE_PROTECTION;
}
+ if ((DesiredAccess == SECTION_ALL_ACCESS ||
+ (DesiredAccess & SECTION_MAP_WRITE)) &&
+ (Protection == PAGE_READWRITE ||
+ Protection == PAGE_EXECUTE_READWRITE))
+ FileAccess = FILE_GENERIC_WRITE;
+ else
+ FileAccess = FILE_GENERIC_READ;
+
+ /*
+ * Reference the file handle
+ */
+ if (!FileObject && FileHandle)
+ {
+ Status = ObReferenceObjectByHandle(FileHandle,
+ FileAccess,
+ IoFileObjectType,
+ ExGetPreviousMode(),
+ (PVOID*)(PVOID)&FileObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Failed: %x\n", Status);
+ return Status;
+ }
+ else
+ ReferencedFile = TRUE;
+ }
+
if (AllocationAttributes & SEC_IMAGE)
{
- return(MmCreateImageSection(SectionObject,
- DesiredAccess,
- ObjectAttributes,
- MaximumSize,
- SectionPageProtection,
- AllocationAttributes,
- FileHandle));
- }
-
- if (FileHandle != NULL)
- {
- return(MmCreateDataFileSection(SectionObject,
- DesiredAccess,
- ObjectAttributes,
- MaximumSize,
- SectionPageProtection,
- AllocationAttributes,
- FileHandle));
- }
-
- return(MmCreatePageFileSection(SectionObject,
- DesiredAccess,
- ObjectAttributes,
- MaximumSize,
- SectionPageProtection,
- AllocationAttributes));
+ DPRINT("Creating an image section\n");
+ Status = MmCreateImageSection(SectionObject,
+ DesiredAccess,
+ ObjectAttributes,
+ MaximumSize,
+ SectionPageProtection,
+ AllocationAttributes,
+ FileObject);
+ if (!NT_SUCCESS(Status))
+ DPRINT("Failed: %x\n", Status);
+ }
+
+ else if (FileHandle != NULL || OriginalFileObject != NULL)
+ {
+ Status = MmCreateDataFileSection(SectionObject,
+ DesiredAccess,
+ ObjectAttributes,
+ MaximumSize,
+ SectionPageProtection,
+ AllocationAttributes,
+ FileObject);
+ if (!NT_SUCCESS(Status))
+ DPRINT("Failed: %x\n", Status);
+ }
+ else
+ {
+ Status = MmCreatePageFileSection(SectionObject,
+ DesiredAccess,
+ ObjectAttributes,
+ MaximumSize,
+ SectionPageProtection,
+ AllocationAttributes);
+ if (!NT_SUCCESS(Status))
+ DPRINT("Failed: %x\n", Status);
+ }
+
+ return(Status);
}
NTSTATUS
Modified: branches/arty-newcc/ntoskrnl/ntoskrnl-generic.rbuild
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/ntoskrnl-ge…
==============================================================================
--- branches/arty-newcc/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Sun Aug 10 05:14:55
2008
@@ -112,14 +112,28 @@
<file>timerobj.c</file>
<file>wait.c</file>
</directory>
- <directory name="cc">
- <file>cacheman.c</file>
- <file>copy.c</file>
- <file>fs.c</file>
- <file>mdl.c</file>
- <file>pin.c</file>
- <file>view.c</file>
- </directory>
+ <if property="CC" value="1">
+ <directory name="cc">
+ <file>cacheman.c</file>
+ <file>copy.c</file>
+ <file>fs.c</file>
+ <file>mdl.c</file>
+ <file>pin.c</file>
+ <file>view.c</file>
+ </directory>
+ </if>
+ <if property="CC" value="0">
+ <directory name="cache">
+ <file>cachesub.c</file>
+ <file>copysup.c</file>
+ <file>fssup.c</file>
+ <file>lazyrite.c</file>
+ <file>logsup.c</file>
+ <file>mdlsup.c</file>
+ <file>pinsup.c</file>
+ <file>vacbsup.c</file>
+ </directory>
+ </if>
<directory name="config">
<if property="ARCH" value="i386">
<directory name="i386">
Modified: branches/arty-newcc/ntoskrnl/ob/obref.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/ob/obref.c?…
==============================================================================
--- branches/arty-newcc/ntoskrnl/ob/obref.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/ob/obref.c [iso-8859-1] Sun Aug 10 05:14:55 2008
@@ -291,6 +291,7 @@
if (Header->PointerCount < Header->HandleCount)
{
DPRINT1("Misbehaving object: %wZ\n", &Header->Type->Name);
+ ASSERT(FALSE);
return Header->PointerCount;
}
@@ -302,6 +303,7 @@
if (Header->HandleCount)
{
DPRINT1("Misbehaving object: %wZ\n",
&Header->Type->Name);
+ ASSERT(FALSE);
return Header->PointerCount;
}