From d758597cd4f5c758d8ba418e5ea7453d93e8d7a2 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Thu, 23 Dec 2010 08:42:51 +0000 Subject: [PATCH] Do the required flush when the last reference to a cache stripe is released. The installer now completes given enough ram in NEWCC=1, and writes an understandable FS. There's at least one more problem preventing the resulting installation from booting however. Fix a bug in rmap where we were checking the next (unfortunately named current) rmap for a segment membership. Fix a mistake in cache trim. #ifdef detection of DirectMapping in section in NEWCC mode in page out. svn path=/trunk/; revision=50110 --- reactos/ntoskrnl/cache/cachesub.c | 4 ++-- reactos/ntoskrnl/cache/fssup.c | 8 ++++---- reactos/ntoskrnl/cache/newcc.h | 4 ++-- reactos/ntoskrnl/cache/pinsup.c | 21 +++++++++++++++++---- reactos/ntoskrnl/mm/rmap.c | 2 +- reactos/ntoskrnl/mm/section.c | 4 ++++ 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/reactos/ntoskrnl/cache/cachesub.c b/reactos/ntoskrnl/cache/cachesub.c index fb9d9e31eb9..6f816cba0dd 100644 --- a/reactos/ntoskrnl/cache/cachesub.c +++ b/reactos/ntoskrnl/cache/cachesub.c @@ -189,12 +189,12 @@ _CcpFlushCache(IN PNOCC_CACHE_MAP Map, CcpDereferenceCache(Bcb - CcCacheSections, FALSE); } else - CcpUnpinData(Bcb); + CcpUnpinData(Bcb, TRUE); } else { ListEntry = ListEntry->Flink; - CcpUnpinData(Bcb); + CcpUnpinData(Bcb, TRUE); } DPRINT("End loop\n"); diff --git a/reactos/ntoskrnl/cache/fssup.c b/reactos/ntoskrnl/cache/fssup.c index 8646513e3b0..f436e744b1e 100644 --- a/reactos/ntoskrnl/cache/fssup.c +++ b/reactos/ntoskrnl/cache/fssup.c @@ -53,7 +53,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) // Reference a cache stripe so it won't go away CcpLock(); if (CcCacheSections[BcbHead].BaseAddress) { - CcpReferenceCache(i); + CcpReferenceCache(BcbHead); CcpUnlock(); } else { CcpUnlock(); @@ -68,7 +68,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) *NrFreed += Freed; CcpLock(); - CcpDereferenceCache(BcbHead, FALSE); + CcpUnpinData(&CcCacheSections[BcbHead], TRUE); CcpUnlock(); } @@ -474,10 +474,10 @@ CcZeroData(IN PFILE_OBJECT FileObject, CcpLock(); ListEntry = ListEntry->Flink; // Return from pin state - CcpUnpinData(PinnedBcb); + CcpUnpinData(PinnedBcb, TRUE); } - CcpUnpinData(Bcb); + CcpUnpinData(Bcb, TRUE); } CcpUnlock(); diff --git a/reactos/ntoskrnl/cache/newcc.h b/reactos/ntoskrnl/cache/newcc.h index 5e0bd2608eb..ab93976f724 100644 --- a/reactos/ntoskrnl/cache/newcc.h +++ b/reactos/ntoskrnl/cache/newcc.h @@ -65,9 +65,9 @@ VOID NTAPI CcInitView(VOID); -VOID +BOOLEAN NTAPI -CcpUnpinData(PNOCC_BCB Bcb); +CcpUnpinData(PNOCC_BCB Bcb, BOOLEAN ActuallyRelease); BOOLEAN NTAPI diff --git a/reactos/ntoskrnl/cache/pinsup.c b/reactos/ntoskrnl/cache/pinsup.c index 5531bbb9720..c2a46398306 100644 --- a/reactos/ntoskrnl/cache/pinsup.c +++ b/reactos/ntoskrnl/cache/pinsup.c @@ -707,9 +707,9 @@ CcPreparePinWrite(IN PFILE_OBJECT FileObject, return Result; } -VOID +BOOLEAN NTAPI -CcpUnpinData(IN PNOCC_BCB RealBcb) +CcpUnpinData(IN PNOCC_BCB RealBcb, BOOLEAN ReleaseBit) { if (RealBcb->RefCount <= 2) { @@ -718,9 +718,11 @@ CcpUnpinData(IN PNOCC_BCB RealBcb) { DPRINT("Triggering exclusive waiter\n"); KeSetEvent(&RealBcb->ExclusiveWait, IO_NO_INCREMENT, FALSE); - return; + return TRUE; } } + if (RealBcb->RefCount == 2 && !ReleaseBit) + return FALSE; if (RealBcb->RefCount > 1) { DPRINT("Removing one reference #%x\n", RealBcb - CcCacheSections); @@ -730,6 +732,7 @@ CcpUnpinData(IN PNOCC_BCB RealBcb) if (RealBcb->RefCount == 1) { DPRINT("Clearing allocation bit #%x\n", RealBcb - CcCacheSections); + RtlClearBit(CcCacheBitmap, RealBcb - CcCacheSections); #ifdef PIN_WRITE_ONLY @@ -745,6 +748,8 @@ CcpUnpinData(IN PNOCC_BCB RealBcb) &OldProtect); #endif } + + return TRUE; } VOID @@ -753,13 +758,21 @@ CcUnpinData(IN PVOID Bcb) { PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb; ULONG Selected = RealBcb - CcCacheSections; + BOOLEAN Released; ASSERT(RealBcb >= CcCacheSections && RealBcb - CcCacheSections < CACHE_NUM_SECTIONS); DPRINT("CcUnpinData Bcb #%x (RefCount %d)\n", Selected, RealBcb->RefCount); CcpLock(); - CcpUnpinData(RealBcb); + Released = CcpUnpinData(RealBcb, FALSE); CcpUnlock(); + + if (!Released) { + MiFlushMappedSection(RealBcb->BaseAddress, &RealBcb->FileOffset, &RealBcb->Map->FileSizes.FileSize, RealBcb->Dirty); + CcpLock(); + CcpUnpinData(RealBcb, TRUE); + CcpUnlock(); + } } VOID diff --git a/reactos/ntoskrnl/mm/rmap.c b/reactos/ntoskrnl/mm/rmap.c index 8d6867e50cc..a4753349d9e 100644 --- a/reactos/ntoskrnl/mm/rmap.c +++ b/reactos/ntoskrnl/mm/rmap.c @@ -365,7 +365,7 @@ MmDeleteAllRmaps(PFN_NUMBER Page, PVOID Context, previous_entry = current_entry; current_entry = current_entry->Next; #ifdef NEWCC - if (!RMAP_IS_SEGMENT(current_entry->Address)) + if (!RMAP_IS_SEGMENT(previous_entry->Address)) #endif { if (DeleteMapping) diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index bef77f4cad5..6be64326ac7 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -2039,7 +2039,9 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace, ULONG FileOffset; NTSTATUS Status; PFILE_OBJECT FileObject; +#ifndef NEWCC PBCB Bcb = NULL; +#endif BOOLEAN DirectMapped; BOOLEAN IsImageSection; PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); @@ -2061,6 +2063,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace, FileObject = Context.Section->FileObject; DirectMapped = FALSE; +#ifndef NEWCC if (FileObject != NULL && !(Context.Segment->Characteristics & IMAGE_SCN_MEM_SHARED)) { @@ -2077,6 +2080,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace, DirectMapped = TRUE; } } +#endif /*