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/ca…
==============================================================================
--- 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/fs…
==============================================================================
--- 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/ne…
==============================================================================
--- 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/pi…
==============================================================================
--- 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/se…
==============================================================================
--- 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));