···130130 ++CcLazyWriteIos;
131131 DPRINT("Lazy writer done (%d)\n", Count);
132132 }
133133+134134+ /* Make sure we're not throttling writes after this */
135135+ while (MmAvailablePages < MmThrottleTop)
136136+ {
137137+ /* Break if we can't even find one to free */
138138+ if (!CcRosFreeOneUnusedVacb())
139139+ {
140140+ break;
141141+ }
142142+ }
133143}
134144135145VOID
+30-58
ntoskrnl/cc/view.c
···595595 }
596596}
597597598598-static
599598BOOLEAN
600600-CcRosFreeUnusedVacb (
601601- PULONG Count)
599599+CcRosFreeOneUnusedVacb(
600600+ VOID)
602601{
603603- ULONG cFreed;
604604- BOOLEAN Freed;
605602 KIRQL oldIrql;
606606- PROS_VACB current;
607607- LIST_ENTRY FreeList;
608603 PLIST_ENTRY current_entry;
609609-610610- cFreed = 0;
611611- Freed = FALSE;
612612- InitializeListHead(&FreeList);
604604+ PROS_VACB to_free = NULL;
613605614606 oldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
615607616608 /* Browse all the available VACB */
617609 current_entry = VacbLruListHead.Flink;
618618- while (current_entry != &VacbLruListHead)
610610+ while ((current_entry != &VacbLruListHead) && (to_free == NULL))
619611 {
620612 ULONG Refs;
613613+ PROS_VACB current;
621614622615 current = CONTAINING_RECORD(current_entry,
623616 ROS_VACB,
624617 VacbLruListEntry);
625625- current_entry = current_entry->Flink;
626618627619 KeAcquireSpinLockAtDpcLevel(¤t->SharedCacheMap->CacheMapLock);
628620···634626 ASSERT(!current->MappedCount);
635627 ASSERT(Refs == 1);
636628637637- /* Reset and move to free list */
629629+ /* Reset it, this is the one we want to free */
638630 RemoveEntryList(¤t->CacheMapVacbListEntry);
631631+ InitializeListHead(¤t->CacheMapVacbListEntry);
639632 RemoveEntryList(¤t->VacbLruListEntry);
640633 InitializeListHead(¤t->VacbLruListEntry);
641641- InsertHeadList(&FreeList, ¤t->CacheMapVacbListEntry);
634634+635635+ to_free = current;
642636 }
643637644638 KeReleaseSpinLockFromDpcLevel(¤t->SharedCacheMap->CacheMapLock);
645639640640+ current_entry = current_entry->Flink;
646641 }
647642648643 KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql);
649644650650- /* And now, free any of the found VACB, that'll free memory! */
651651- while (!IsListEmpty(&FreeList))
652652- {
653653- ULONG Refs;
654654-655655- current_entry = RemoveHeadList(&FreeList);
656656- current = CONTAINING_RECORD(current_entry,
657657- ROS_VACB,
658658- CacheMapVacbListEntry);
659659- InitializeListHead(¤t->CacheMapVacbListEntry);
660660- Refs = CcRosVacbDecRefCount(current);
661661- ASSERT(Refs == 0);
662662- ++cFreed;
663663- }
664664-665665- /* If we freed at least one VACB, return success */
666666- if (cFreed != 0)
645645+ /* And now, free the VACB that we found, if any. */
646646+ if (to_free == NULL)
667647 {
668668- Freed = TRUE;
648648+ return FALSE;
669649 }
670650671671- /* If caller asked for free count, return it */
672672- if (Count != NULL)
673673- {
674674- *Count = cFreed;
675675- }
651651+ /* This must be its last ref */
652652+ NT_VERIFY(CcRosVacbDecRefCount(to_free) == 0);
676653677677- return Freed;
654654+ return TRUE;
678655}
679656680657static
···690667 NTSTATUS Status;
691668 KIRQL oldIrql;
692669 ULONG Refs;
693693- BOOLEAN Retried;
694670 SIZE_T ViewSize = VACB_MAPPING_GRANULARITY;
695671696672 ASSERT(SharedCacheMap);
···711687712688 CcRosVacbIncRefCount(current);
713689714714- Retried = FALSE;
715715-Retry:
716716- /* Map VACB in system space */
717717- Status = MmMapViewInSystemSpaceEx(SharedCacheMap->Section, ¤t->BaseAddress, &ViewSize, ¤t->FileOffset, 0);
718718-719719- if (!NT_SUCCESS(Status))
690690+ while (TRUE)
720691 {
721721- ULONG Freed;
722722- /* If no space left, try to prune unused VACB
723723- * to recover space to map our VACB
724724- * If it succeed, retry to map, otherwise
725725- * just fail.
726726- */
727727- if (!Retried && CcRosFreeUnusedVacb(&Freed))
692692+ /* Map VACB in system space */
693693+ Status = MmMapViewInSystemSpaceEx(SharedCacheMap->Section, ¤t->BaseAddress, &ViewSize, ¤t->FileOffset, 0);
694694+ if (NT_SUCCESS(Status))
728695 {
729729- DPRINT("Prunned %d VACB, trying again\n", Freed);
730730- Retried = TRUE;
731731- goto Retry;
696696+ break;
732697 }
733698734734- ExFreeToNPagedLookasideList(&VacbLookasideList, current);
735735- return Status;
699699+ /*
700700+ * If no space left, try to prune one unused VACB to recover space to map our VACB.
701701+ * If it succeeds, retry to map, otherwise just fail.
702702+ */
703703+ if (!CcRosFreeOneUnusedVacb())
704704+ {
705705+ ExFreeToNPagedLookasideList(&VacbLookasideList, current);
706706+ return Status;
707707+ }
736708 }
737709738710#if DBG