}
/* And post it, it will be for lazy write */
- WorkItem->Function = LazyWrite;
+ WorkItem->Function = LazyScan;
CcPostWorkQueue(WorkItem, &CcRegularWorkQueue);
}
+VOID
+CcWriteBehind(VOID)
+{
+ ULONG Target, Count;
+
+ Target = CcTotalDirtyPages / 8;
+ if (Target != 0)
+ {
+ /* Flush! */
+ DPRINT("Lazy writer starting (%d)\n", Target);
+ CcRosFlushDirtyPages(Target, &Count, FALSE, TRUE);
+
+ /* And update stats */
+ CcLazyWritePages += Count;
+ ++CcLazyWriteIos;
+ DPRINT("Lazy writer done (%d)\n", Count);
+ }
+}
+
VOID
CcLazyWriteScan(VOID)
{
ULONG Target;
- ULONG Count;
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
LIST_ENTRY ToPost;
Target = CcTotalDirtyPages / 8;
if (Target != 0)
{
- /* Flush! */
- DPRINT("Lazy writer starting (%d)\n", Target);
- CcRosFlushDirtyPages(Target, &Count, FALSE, TRUE);
+ /* There is stuff to flush, schedule a write-behind operation */
- /* And update stats */
- CcLazyWritePages += Count;
- ++CcLazyWriteIos;
- DPRINT("Lazy writer done (%d)\n", Count);
+ /* Allocate a work item */
+ WorkItem = ExAllocateFromNPagedLookasideList(&CcTwilightLookasideList);
+ if (WorkItem != NULL)
+ {
+ WorkItem->Function = WriteBehind;
+ CcPostWorkQueue(WorkItem, &CcRegularWorkQueue);
+ }
}
/* Post items that were due for end of run */
IN PVOID Parameter)
{
KIRQL OldIrql;
- BOOLEAN DropThrottle;
+ BOOLEAN DropThrottle, WritePerformed;
PWORK_QUEUE_ITEM Item;
#if DBG
PIRP TopLevel;
Item = Parameter;
/* And by default, don't touch throttle */
DropThrottle = FALSE;
+ /* No write performed */
+ WritePerformed = FALSE;
#if DBG
/* Top level IRP should be clean when started
CcPerformReadAhead(WorkItem->Parameters.Read.FileObject);
break;
- case LazyWrite:
+ case WriteBehind:
+ CcWriteBehind();
+ WritePerformed = TRUE;
+ break;
+
+ case LazyScan:
CcLazyWriteScan();
break;
--CcNumberActiveWorkerThreads;
KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql);
+ /* If there are pending write openations and we have at least 20 dirty pages */
+ if (!IsListEmpty(&CcDeferredWrites) && CcTotalDirtyPages >= 20)
+ {
+ /* And if we performed a write operation previously, then
+ * stress the system a bit and reschedule a scan to find
+ * stuff to write
+ */
+ if (WritePerformed)
+ {
+ CcLazyWriteScan();
+ }
+ }
+
#if DBG
/* Top level shouldn't have changed */
if (TopLevel != IoGetTopLevelIrp())