Author: jgardou Date: Mon May 23 20:15:54 2016 New Revision: 71389
URL: http://svn.reactos.org/svn/reactos?rev=71389&view=rev Log: [NEWCC] - Create section object when creating the file shared cache map - Map the said section PsInitialSystemProcess address space and map it in kernel space using MmProbeAndLockProcessPages - Implement CcSetFileSizes on top of MmExtendSection
Modified: branches/TransitionPte/ntoskrnl/cache/cachesub.c branches/TransitionPte/ntoskrnl/cache/fssup.c branches/TransitionPte/ntoskrnl/cache/newcc.h branches/TransitionPte/ntoskrnl/cache/pinsup.c branches/TransitionPte/ntoskrnl/cache/section/data.c
Modified: branches/TransitionPte/ntoskrnl/cache/cachesub.c URL: http://svn.reactos.org/svn/reactos/branches/TransitionPte/ntoskrnl/cache/cac... ============================================================================== --- branches/TransitionPte/ntoskrnl/cache/cachesub.c [iso-8859-1] (original) +++ branches/TransitionPte/ntoskrnl/cache/cachesub.c [iso-8859-1] Mon May 23 20:15:54 2016 @@ -64,6 +64,10 @@ PLIST_ENTRY ListEntry; volatile char *chptr; PNOCC_BCB Bcb; + KAPC_STATE ApcState; + + KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState); + for (ListEntry = Map->AssociatedBcb.Flink; ListEntry != &Map->AssociatedBcb; ListEntry = ListEntry->Flink) @@ -81,6 +85,8 @@ *chptr ^= 0; } } + + KeUnstackDetachProcess(&ApcState); } ObDereferenceObject(WorkItem->FileObject); ExFreePool(WorkItem); @@ -306,13 +312,13 @@ for (i = 0; i < CACHE_NUM_SECTIONS; i++) { PNOCC_BCB Bcb = &CcCacheSections[i]; - if (Bcb->SectionObject) + if (Bcb->Map->SectionObject) { DPRINT1("Evicting #%02x %08x%08x %wZ\n", i, Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart, - &MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName); + &MmGetFileObjectForSection(Bcb->Map->SectionObject)->FileName);
CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE); Bcb->Dirty = FALSE;
Modified: branches/TransitionPte/ntoskrnl/cache/fssup.c URL: http://svn.reactos.org/svn/reactos/branches/TransitionPte/ntoskrnl/cache/fss... ============================================================================== --- branches/TransitionPte/ntoskrnl/cache/fssup.c [iso-8859-1] (original) +++ branches/TransitionPte/ntoskrnl/cache/fssup.c [iso-8859-1] Mon May 23 20:15:54 2016 @@ -218,6 +218,9 @@ /* We still don't have a shared cache map. We need to create one. */ if (!Map) { + NTSTATUS Status; + LARGE_INTEGER MaxSize = FileSizes->AllocationSize; + DPRINT("Initializing file object for (%p) %wZ\n", FileObject, &FileObject->FileName); @@ -237,6 +240,20 @@ InitializeListHead(&Map->PrivateCacheMaps); InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry); DPRINT("New Map %p\n", Map); + + Status = MmCreateSection(&Map->SectionObject, + STANDARD_RIGHTS_REQUIRED | SECTION_EXTEND_SIZE, + NULL, + &MaxSize, + PAGE_READWRITE, + SEC_RESERVE, // Use ARM3 implementation + NULL, + FileObject); + if (!NT_SUCCESS(Status)) + { + ExFreePool(Map); + RtlRaiseStatus(Status); + } } /* We don't have a private cache map. Link it with the shared cache map to serve as a held reference. When the list in the shared cache map @@ -325,6 +342,7 @@ CcpDereferenceCache(Bcb - CcCacheSections, TRUE); } RemoveEntryList(&PrivateCacheMap->Map->Entry); + ObDereferenceObject(PrivateCacheMap->Map->SectionObject); ExFreePool(PrivateCacheMap->Map); FileObject->SectionObjectPointer->SharedCacheMap = NULL; LastMap = TRUE; @@ -354,18 +372,36 @@ CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes) { - PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; - PNOCC_BCB Bcb; - - if (!Map) return; + PNOCC_CACHE_MAP Map; + + CcpLock(); + + Map = FileObject->SectionObjectPointer->SharedCacheMap; + + if (!Map) + { + CcpUnlock(); + return; + } + + /* FS should have unmapped the whole thing. */ + //ASSERT(IsListEmpty(&Map->AssociatedBcb)); + + if (Map->FileSizes.AllocationSize.QuadPart != FileSizes->AllocationSize.QuadPart) + { + LARGE_INTEGER SectionSize = FileSizes->AllocationSize; + NTSTATUS Status = MmExtendSection(Map->SectionObject, &SectionSize); + + if (!NT_SUCCESS(Status)) + { + CcpUnlock(); + ExRaiseStatus(Status); + } + } + Map->FileSizes = *FileSizes; - Bcb = Map->AssociatedBcb.Flink == &Map->AssociatedBcb ? - NULL : CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList); - if (!Bcb) return; - MmExtendCacheSection(Bcb->SectionObject, &FileSizes->FileSize, FALSE); - DPRINT("FileSizes->FileSize %x\n", FileSizes->FileSize.LowPart); - DPRINT("FileSizes->AllocationSize %x\n", FileSizes->AllocationSize.LowPart); - DPRINT("FileSizes->ValidDataLength %x\n", FileSizes->ValidDataLength.LowPart); + + CcpUnlock(); }
BOOLEAN @@ -612,7 +648,7 @@ NOCC_BCB, ThisFileList);
- Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject); + Result = MmGetFileObjectForSection(Bcb->Map->SectionObject); } CcpUnlock(); return Result; @@ -624,7 +660,7 @@ { PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb; DPRINT("BCB #%x\n", RealBcb - CcCacheSections); - return MmGetFileObjectForSection((PROS_SECTION_OBJECT)RealBcb->SectionObject); + return MmGetFileObjectForSection(RealBcb->Map->SectionObject); }
/* EOF */
Modified: branches/TransitionPte/ntoskrnl/cache/newcc.h URL: http://svn.reactos.org/svn/reactos/branches/TransitionPte/ntoskrnl/cache/new... ============================================================================== --- branches/TransitionPte/ntoskrnl/cache/newcc.h [iso-8859-1] (original) +++ branches/TransitionPte/ntoskrnl/cache/newcc.h [iso-8859-1] Mon May 23 20:15:54 2016 @@ -6,12 +6,14 @@ PUBLIC_BCB Bcb;
struct _NOCC_CACHE_MAP *Map; - PROS_SECTION_OBJECT SectionObject; LARGE_INTEGER FileOffset; ULONG Length; PVOID BaseAddress; BOOLEAN Dirty; PVOID OwnerPointer; + + PMDL Mdl; + PVOID MdlAddress;
/* Reference counts */ ULONG RefCount; @@ -36,6 +38,7 @@ PVOID LogHandle; PFLUSH_TO_LSN FlushToLsn; ULONG ReadAheadGranularity; + PVOID SectionObject; } NOCC_CACHE_MAP, *PNOCC_CACHE_MAP;
VOID
Modified: branches/TransitionPte/ntoskrnl/cache/pinsup.c URL: http://svn.reactos.org/svn/reactos/branches/TransitionPte/ntoskrnl/cache/pin... ============================================================================== --- branches/TransitionPte/ntoskrnl/cache/pinsup.c [iso-8859-1] (original) +++ branches/TransitionPte/ntoskrnl/cache/pinsup.c [iso-8859-1] Mon May 23 20:15:54 2016 @@ -12,7 +12,7 @@ #include <ntoskrnl.h> #include "newcc.h" #include "section/newmm.h" -#define NDEBUG +//#define NDEBUG #include <debug.h>
/* The following is a test mode that only works with modified filesystems. @@ -128,47 +128,12 @@ NTAPI MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject);
-/* - -Allocate an almost ordinary section object for use by the cache system. -The special internal SEC_CACHE flag is used to indicate that the section -should not count when determining whether the file can be resized. - -*/ - -NTSTATUS -CcpAllocateSection(PFILE_OBJECT FileObject, - ULONG Length, - ULONG Protect, - PROS_SECTION_OBJECT *Result) -{ - NTSTATUS Status; - LARGE_INTEGER MaxSize; - - MaxSize.QuadPart = Length; - - DPRINT("Making Section for File %x\n", FileObject); - DPRINT("File name %wZ\n", &FileObject->FileName); - - Status = MmCreateSection((PVOID*)Result, - STANDARD_RIGHTS_REQUIRED, - NULL, - &MaxSize, - Protect, - SEC_RESERVE | SEC_CACHE, - NULL, - FileObject); - - return Status; -} - typedef struct _WORK_QUEUE_WITH_CONTEXT { WORK_QUEUE_ITEM WorkItem; PVOID ToUnmap; LARGE_INTEGER FileOffset; LARGE_INTEGER MapSize; - PROS_SECTION_OBJECT ToDeref; PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite; PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite; PVOID LazyContext; @@ -188,8 +153,7 @@ { PWORK_QUEUE_WITH_CONTEXT WorkItem = (PWORK_QUEUE_WITH_CONTEXT)Context; DPRINT("Unmapping (finally) %x\n", WorkItem->ToUnmap); - MmUnmapCacheViewInSystemSpace(WorkItem->ToUnmap); - ObDereferenceObject(WorkItem->ToDeref); + MmUnmapViewOfSection(PsInitialSystemProcess, WorkItem->ToUnmap); ExFreePool(WorkItem); DPRINT("Done\n"); } @@ -230,7 +194,7 @@ MappedSize = Bcb->Map->FileSizes.ValidDataLength;
DPRINT("Dereference #%x (count %d)\n", Start, Bcb->RefCount); - ASSERT(Bcb->SectionObject); + ASSERT(Bcb->Map->SectionObject); ASSERT(Bcb->RefCount == 1);
DPRINT("Firing work item for %x\n", Bcb->BaseAddress); @@ -245,9 +209,7 @@
if (Immediate) { - PROS_SECTION_OBJECT ToDeref = Bcb->SectionObject; Bcb->Map = NULL; - Bcb->SectionObject = NULL; Bcb->BaseAddress = NULL; Bcb->FileOffset.QuadPart = 0; Bcb->Length = 0; @@ -256,8 +218,7 @@ RemoveEntryList(&Bcb->ThisFileList);
CcpUnlock(); - MmUnmapCacheViewInSystemSpace(ToUnmap); - ObDereferenceObject(ToDeref); + MmUnmapViewOfSection(PsInitialSystemProcess, ToUnmap); CcpLock(); } else @@ -268,7 +229,6 @@ WorkItem->FileOffset = Bcb->FileOffset; WorkItem->Dirty = Bcb->Dirty; WorkItem->MapSize = MappedSize; - WorkItem->ToDeref = Bcb->SectionObject; WorkItem->AcquireForLazyWrite = Bcb->Map->Callbacks.AcquireForLazyWrite; WorkItem->ReleaseFromLazyWrite = Bcb->Map->Callbacks.ReleaseFromLazyWrite; WorkItem->LazyContext = Bcb->Map->LazyContext; @@ -278,7 +238,6 @@ WorkItem);
Bcb->Map = NULL; - Bcb->SectionObject = NULL; Bcb->BaseAddress = NULL; Bcb->FileOffset.QuadPart = 0; Bcb->Length = 0; @@ -308,7 +267,7 @@ /* Needs mutex */ ULONG CcpAllocateCacheSections(PFILE_OBJECT FileObject, - PROS_SECTION_OBJECT SectionObject) + PVOID SectionObject) { ULONG i = INVALID_CACHE; PNOCC_CACHE_MAP Map; @@ -369,7 +328,6 @@ { PNOCC_BCB Bcb; Bcb = &CcCacheSections[Start]; - ASSERT(Bcb->SectionObject); Bcb->RefCount++; RtlSetBit(CcCacheBitmap, Start);
@@ -405,7 +363,6 @@
CcpLock(); ASSERT(Bcb->ExclusiveWaiter); - ASSERT(Bcb->SectionObject); Bcb->Exclusive = TRUE; Bcb->ExclusiveWaiter--; RtlSetBit(CcCacheBitmap, Start); @@ -469,13 +426,12 @@ OUT PVOID *BcbResult, OUT PVOID *Buffer) { - BOOLEAN Success = FALSE, FaultIn = FALSE; + BOOLEAN Success = FALSE; /* Note: windows 2000 drivers treat this as a bool */ //BOOLEAN Wait = (Flags & MAP_WAIT) || (Flags == TRUE); LARGE_INTEGER Target, EndInterval; ULONG BcbHead, SectionSize, ViewSize; PNOCC_BCB Bcb = NULL; - PROS_SECTION_OBJECT SectionObject = NULL; NTSTATUS Status; PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; ViewSize = CACHE_STRIPE; @@ -486,8 +442,9 @@ return FALSE; }
- DPRINT("CcMapData(F->%x, %I64x:%d)\n", + DPRINT("CcMapData(F->%x, %S, %I64x:%d)\n", FileObject, + FileObject->FileName.Buffer, FileOffset->QuadPart, Length);
@@ -506,8 +463,6 @@ { Bcb = &CcCacheSections[BcbHead]; Success = TRUE; - *BcbResult = Bcb; - *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart);
DPRINT("Bcb #%x Buffer maps (%I64x) At %x Length %x (Getting %p:%x) %wZ\n", Bcb - CcCacheSections, @@ -545,31 +500,10 @@
//ASSERT(SectionSize <= CACHE_STRIPE);
- CcpUnlock(); - /* CcpAllocateSection doesn't need the lock, so we'll give other action - a chance in here. */ - Status = CcpAllocateSection(FileObject, - SectionSize, -#ifdef PIN_WRITE_ONLY - PAGE_READONLY, -#else - PAGE_READWRITE, -#endif - &SectionObject); - CcpLock(); - - if (!NT_SUCCESS(Status)) - { - *BcbResult = NULL; - *Buffer = NULL; - DPRINT1("End %08x\n", Status); - goto cleanup; - } - retry: /* Returns a reference */ DPRINT("Allocating cache sections: %wZ\n", &FileObject->FileName); - BcbHead = CcpAllocateCacheSections(FileObject, SectionObject); + BcbHead = CcpAllocateCacheSections(FileObject, Map->SectionObject); /* XXX todo: we should handle the immediate fail case here, but don't */ if (BcbHead == INVALID_CACHE) { @@ -603,24 +537,27 @@ }
DPRINT("Selected BCB #%x\n", BcbHead); - ViewSize = CACHE_STRIPE; + ViewSize = SectionSize;
Bcb = &CcCacheSections[BcbHead]; - /* MmMapCacheViewInSystemSpaceAtOffset is one of three methods of Mm - that are specific to NewCC. In this case, it's implementation - exactly mirrors MmMapViewInSystemSpace, but allows an offset to - be specified. */ - Status = MmMapCacheViewInSystemSpaceAtOffset(SectionObject->Segment, - &Bcb->BaseAddress, - &Target, - &ViewSize); + Status = MmMapViewOfSection(Map->SectionObject, + PsInitialSystemProcess, + &Bcb->BaseAddress, + 0, + ViewSize, + &Target, + &ViewSize, + ViewShare, + 0, + PAGE_READWRITE); + + DPRINT("MmMapViewOfSection, Status 0x%08x.\n", Status);
/* Summary: Failure. Dereference our section and tell the user we failed */ if (!NT_SUCCESS(Status)) { *BcbResult = NULL; *Buffer = NULL; - ObDereferenceObject(SectionObject); RemoveEntryList(&Bcb->ThisFileList); RtlZeroMemory(Bcb, sizeof(*Bcb)); RtlClearBit(CcCacheBitmap, BcbHead); @@ -636,14 +573,9 @@ Bcb->Length = MIN(Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart, CACHE_STRIPE);
- Bcb->SectionObject = SectionObject; Bcb->Map = Map; Bcb->FileOffset = Target; InsertTailList(&Map->AssociatedBcb, &Bcb->ThisFileList); - - *BcbResult = &CcCacheSections[BcbHead]; - *Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart); - FaultIn = TRUE;
DPRINT("Bcb #%x Buffer maps (%I64x) At %x Length %x (Getting %p:%lx) %wZ\n", Bcb - CcCacheSections, @@ -659,32 +591,48 @@ (Bcb->FileOffset.QuadPart & ~(CACHE_STRIPE - 1)));
cleanup: - CcpUnlock(); if (Success) { - if (FaultIn) + if (!Bcb->Mdl) { - /* Fault in the pages. This forces reads to happen now. */ - ULONG i; - PCHAR FaultIn = Bcb->BaseAddress; - - DPRINT("Faulting in pages at this point: file %wZ %I64x:%x\n", - &FileObject->FileName, - Bcb->FileOffset.QuadPart, - Bcb->Length); - - for (i = 0; i < Bcb->Length; i += PAGE_SIZE) + PMDL Mdl; + PVOID MdlAddress; + CcpUnlock(); + + DPRINT("Allocating MDL for Bcb #%x.\n", Bcb - CcCacheSections); + + Mdl = IoAllocateMdl(Bcb->BaseAddress, Bcb->Length, FALSE, FALSE, NULL); + if (!Mdl) + RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); + + MmProbeAndLockProcessPages(Mdl, PsInitialSystemProcess, KernelMode, IoModifyAccess); + MdlAddress = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); + + CcpLock(); + if (Bcb->Mdl) { - FaultIn[i] ^= 0; + /* Someone beat us */ + MmUnlockPages(Mdl); + IoFreeMdl(Mdl); + } + else + { + Bcb->Mdl = Mdl; + Bcb->MdlAddress = MdlAddress; } } ASSERT(Bcb >= CcCacheSections && Bcb < (CcCacheSections + CACHE_NUM_SECTIONS)); + + *BcbResult = Bcb; + *Buffer = ((PCHAR)Bcb->MdlAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart); } else { ASSERT(FALSE); } + + CcpUnlock();
return Success; } @@ -815,7 +763,7 @@ { CcpLock(); RealBcb = *Bcb; - *Buffer = ((PCHAR)RealBcb->BaseAddress) + (int)(FileOffset->QuadPart - RealBcb->FileOffset.QuadPart); + *Buffer = ((PCHAR)RealBcb->MdlAddress) + (int)(FileOffset->QuadPart - RealBcb->FileOffset.QuadPart); CcpUnlock(); }
@@ -934,6 +882,14 @@
RtlClearBit(CcCacheBitmap, RealBcb - CcCacheSections);
+ if(RealBcb->Mdl) + { + MmUnlockPages(RealBcb->Mdl); + IoFreeMdl(RealBcb->Mdl); + RealBcb->Mdl = NULL; + RealBcb->MdlAddress = NULL; + } + #ifdef PIN_WRITE_ONLY PVOID BaseAddress = RealBcb->BaseAddress; SIZE_T NumberOfBytes = RealBcb->Length;
Modified: branches/TransitionPte/ntoskrnl/cache/section/data.c URL: http://svn.reactos.org/svn/reactos/branches/TransitionPte/ntoskrnl/cache/sec... ============================================================================== --- branches/TransitionPte/ntoskrnl/cache/section/data.c [iso-8859-1] (original) +++ branches/TransitionPte/ntoskrnl/cache/section/data.c [iso-8859-1] Mon May 23 20:15:54 2016 @@ -77,7 +77,7 @@ #include <ntoskrnl.h> #include "newmm.h" #include <cache/newcc.h> -#define NDEBUG +// #define NDEBUG #include <debug.h> #include <mm/ARM3/miarm.h>
@@ -157,7 +157,7 @@ if (!MemoryArea || MemoryArea->Type != MEMORY_AREA_CACHE || MemoryArea->DeleteInProgress) { MmUnlockAddressSpace(AddressSpace); - DPRINT("STATUS_NOT_MAPPED_DATA\n"); + DPRINT1("STATUS_NOT_MAPPED_DATA\n"); return STATUS_NOT_MAPPED_DATA; } BeginningAddress = PAGE_ROUND_DOWN(MA_GetStartingAddress(MemoryArea));