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/caches... ============================================================================== --- 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@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/copysu... ============================================================================== --- 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@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@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/lazyri... ============================================================================== --- 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@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/logsup... ============================================================================== --- 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@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/mdlsup... ============================================================================== --- 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@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/pinsup... ============================================================================== --- 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@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/vacbsu... ============================================================================== --- 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@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/inte... ============================================================================== --- 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/inte... ============================================================================== --- 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/inte... ============================================================================== --- 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?rev... ============================================================================== --- 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?re... ============================================================================== --- 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.c... ============================================================================== --- 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-gen... ============================================================================== --- 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?r... ============================================================================== --- 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; }