[NTOSKRNL] Misc fixes to Cc:

- CcUnpinDataForThread() only release VACB when the last BCB reference is gone. This avoids having a valid BCB with an invalid VACB
- CcRosMarkDirtyVacb() will only accept non-dirty VACB now. This avoids a major bug where a an already dirty VACB was over-dereferenced
- Thanks to previous point, simplify CcRosUnmapVacb(), CcRosReleaseVacb() implementation
- And only set VACB dirty once in CcSetDirtyPinnedData()
- Add a few sanity checks

With that I can again install ReactOS with 128MB RAM :-).

CORE-14263
CORE-14268
This commit is contained in:
Pierre Schweitzer 2018-01-28 11:09:21 +01:00
parent d3e0eb2026
commit 52287be9a9
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
2 changed files with 25 additions and 49 deletions

View file

@ -247,8 +247,11 @@ CcSetDirtyPinnedData (
Bcb, Lsn); Bcb, Lsn);
iBcb->Dirty = TRUE; iBcb->Dirty = TRUE;
if (!iBcb->Vacb->Dirty)
{
CcRosMarkDirtyVacb(iBcb->Vacb); CcRosMarkDirtyVacb(iBcb->Vacb);
} }
}
/* /*
@ -284,14 +287,14 @@ CcUnpinDataForThread (
iBcb->Vacb->PinCount--; iBcb->Vacb->PinCount--;
} }
if (--iBcb->RefCount == 0)
{
CcRosReleaseVacb(iBcb->Vacb->SharedCacheMap, CcRosReleaseVacb(iBcb->Vacb->SharedCacheMap,
iBcb->Vacb, iBcb->Vacb,
TRUE, TRUE,
iBcb->Dirty, iBcb->Dirty,
FALSE); FALSE);
if (--iBcb->RefCount == 0)
{
ExDeleteResourceLite(&iBcb->Lock); ExDeleteResourceLite(&iBcb->Lock);
ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
} }

View file

@ -99,6 +99,7 @@ static void CcRosVacbIncRefCount_(PROS_VACB vacb, const char* file, int line)
static void CcRosVacbDecRefCount_(PROS_VACB vacb, const char* file, int line) static void CcRosVacbDecRefCount_(PROS_VACB vacb, const char* file, int line)
{ {
--vacb->ReferenceCount; --vacb->ReferenceCount;
ASSERT(!(vacb->ReferenceCount == 0 && vacb->Dirty));
if (vacb->SharedCacheMap->Trace) if (vacb->SharedCacheMap->Trace)
{ {
DbgPrint("(%s:%i) VACB %p --RefCount=%lu, Dirty %u, PageOut %lu\n", DbgPrint("(%s:%i) VACB %p --RefCount=%lu, Dirty %u, PageOut %lu\n",
@ -518,8 +519,6 @@ CcRosReleaseVacb (
BOOLEAN Dirty, BOOLEAN Dirty,
BOOLEAN Mapped) BOOLEAN Mapped)
{ {
BOOLEAN WasDirty;
ASSERT(SharedCacheMap); ASSERT(SharedCacheMap);
DPRINT("CcRosReleaseVacb(SharedCacheMap 0x%p, Vacb 0x%p, Valid %u)\n", DPRINT("CcRosReleaseVacb(SharedCacheMap 0x%p, Vacb 0x%p, Valid %u)\n",
@ -527,18 +526,10 @@ CcRosReleaseVacb (
Vacb->Valid = Valid; Vacb->Valid = Valid;
WasDirty = FALSE; if (Dirty && !Vacb->Dirty)
if (Dirty)
{
if (!Vacb->Dirty)
{ {
CcRosMarkDirtyVacb(Vacb); CcRosMarkDirtyVacb(Vacb);
} }
else
{
WasDirty = TRUE;
}
}
if (Mapped) if (Mapped)
{ {
@ -549,10 +540,6 @@ CcRosReleaseVacb (
{ {
CcRosVacbIncRefCount(Vacb); CcRosVacbIncRefCount(Vacb);
} }
if (!WasDirty && Vacb->Dirty)
{
CcRosVacbIncRefCount(Vacb);
}
CcRosReleaseVacbLock(Vacb); CcRosReleaseVacbLock(Vacb);
@ -618,16 +605,12 @@ CcRosMarkDirtyVacb (
KeAcquireGuardedMutex(&ViewLock); KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql); KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
if (!Vacb->Dirty) ASSERT(!Vacb->Dirty);
{
InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry); InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE; CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
Vacb->SharedCacheMap->DirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE; Vacb->SharedCacheMap->DirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
} CcRosVacbIncRefCount(Vacb);
else
{
CcRosVacbDecRefCount(Vacb);
}
/* Move to the tail of the LRU list */ /* Move to the tail of the LRU list */
RemoveEntryList(&Vacb->VacbLruListEntry); RemoveEntryList(&Vacb->VacbLruListEntry);
@ -658,7 +641,10 @@ CcRosMarkDirtyFile (
KeBugCheck(CACHE_MANAGER); KeBugCheck(CACHE_MANAGER);
} }
if (!Vacb->Dirty)
{
CcRosMarkDirtyVacb(Vacb); CcRosMarkDirtyVacb(Vacb);
}
CcRosReleaseVacbLock(Vacb); CcRosReleaseVacbLock(Vacb);
@ -673,7 +659,6 @@ CcRosUnmapVacb (
BOOLEAN NowDirty) BOOLEAN NowDirty)
{ {
PROS_VACB Vacb; PROS_VACB Vacb;
BOOLEAN WasDirty;
ASSERT(SharedCacheMap); ASSERT(SharedCacheMap);
@ -686,26 +671,14 @@ CcRosUnmapVacb (
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
WasDirty = FALSE; if (NowDirty && !Vacb->Dirty)
if (NowDirty)
{
if (!Vacb->Dirty)
{ {
CcRosMarkDirtyVacb(Vacb); CcRosMarkDirtyVacb(Vacb);
} }
else
{
WasDirty = TRUE;
}
}
Vacb->MappedCount--; Vacb->MappedCount--;
CcRosVacbDecRefCount(Vacb); CcRosVacbDecRefCount(Vacb);
if (!WasDirty && NowDirty)
{
CcRosVacbIncRefCount(Vacb);
}
if (Vacb->MappedCount == 0) if (Vacb->MappedCount == 0)
{ {
CcRosVacbDecRefCount(Vacb); CcRosVacbDecRefCount(Vacb);