mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
[CMLIB]
- Increase Hive dirty counter when marking cells as dirty - Clear the counter accordingly when flushing the hive [NTOSKRNL] - Lazy flush the registry when unlocking it - Correctly update hive lazy flush count when actully flushing it - Respect the force flush parameter CORE-6762 #comment Should be fixed with r61783, let's see what testbot says. svn path=/trunk/; revision=61783
This commit is contained in:
parent
3cdb13b7e3
commit
9f87212d66
4 changed files with 43 additions and 17 deletions
|
@ -120,6 +120,7 @@ HvMarkCellDirty(
|
|||
|
||||
RtlSetBits(&RegistryHive->DirtyVector,
|
||||
CellBlock, CellLastBlock - CellBlock);
|
||||
RegistryHive->DirtyCount++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -265,6 +265,7 @@ HvSyncHive(
|
|||
|
||||
/* Clear dirty bitmap. */
|
||||
RtlClearAllBits(&RegistryHive->DirtyVector);
|
||||
RegistryHive->DirtyCount = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ BOOLEAN CmpLazyFlushPending;
|
|||
BOOLEAN CmpForceForceFlush;
|
||||
BOOLEAN CmpHoldLazyFlush = TRUE;
|
||||
ULONG CmpLazyFlushIntervalInSeconds = 5;
|
||||
ULONG CmpLazyFlushHiveCount = 7;
|
||||
static ULONG CmpLazyFlushHiveCount = 7;
|
||||
ULONG CmpLazyFlushCount = 1;
|
||||
LONG CmpFlushStarveWriters;
|
||||
|
||||
|
@ -31,9 +31,9 @@ LONG CmpFlushStarveWriters;
|
|||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmpDoFlushNextHive(IN BOOLEAN ForceFlush,
|
||||
OUT PBOOLEAN Error,
|
||||
OUT PULONG DirtyCount)
|
||||
CmpDoFlushNextHive(_In_ BOOLEAN ForceFlush,
|
||||
_Out_ PBOOLEAN Error,
|
||||
_Out_ PULONG DirtyCount)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PLIST_ENTRY NextEntry;
|
||||
|
@ -51,13 +51,10 @@ CmpDoFlushNextHive(IN BOOLEAN ForceFlush,
|
|||
/* Make sure we have to flush at least one hive */
|
||||
if (!HiveCount) HiveCount = 1;
|
||||
|
||||
/* Don't force flush */
|
||||
CmpForceForceFlush = FALSE;
|
||||
|
||||
/* Acquire the list lock and loop */
|
||||
ExAcquirePushLockShared(&CmpHiveListHeadLock);
|
||||
NextEntry = CmpHiveListHead.Flink;
|
||||
while (NextEntry != &CmpHiveListHead)
|
||||
while ((NextEntry != &CmpHiveListHead) && HiveCount)
|
||||
{
|
||||
/* Get the hive and check if we should flush it */
|
||||
CmHive = CONTAINING_RECORD(NextEntry, CMHIVE, HiveList);
|
||||
|
@ -67,17 +64,21 @@ CmpDoFlushNextHive(IN BOOLEAN ForceFlush,
|
|||
/* Great sucess! */
|
||||
Result = TRUE;
|
||||
|
||||
/* Ignore clean or volatile hves */
|
||||
if (!(CmHive->Hive.DirtyCount) ||
|
||||
/* One less to flush */
|
||||
HiveCount--;
|
||||
|
||||
/* Ignore clean or volatile hives */
|
||||
if ((!CmHive->Hive.DirtyCount && !ForceFlush) ||
|
||||
(CmHive->Hive.HiveFlags & HIVE_VOLATILE))
|
||||
{
|
||||
/* Don't do anything but do update the count */
|
||||
CmHive->FlushCount = CmpLazyFlushCount;
|
||||
DPRINT("Hive %wZ is clean.\n", &CmHive->FileFullPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do the sync */
|
||||
DPRINT1("Flushing: %wZ\n", CmHive->FileFullPath);
|
||||
DPRINT1("Flushing: %wZ\n", &CmHive->FileFullPath);
|
||||
DPRINT1("Handle: %p\n", CmHive->FileHandles[HFILE_TYPE_PRIMARY]);
|
||||
Status = HvSyncHive(&CmHive->Hive);
|
||||
if(!NT_SUCCESS(Status))
|
||||
|
@ -85,7 +86,9 @@ CmpDoFlushNextHive(IN BOOLEAN ForceFlush,
|
|||
/* Let them know we failed */
|
||||
*Error = TRUE;
|
||||
Result = FALSE;
|
||||
break;
|
||||
}
|
||||
CmHive->FlushCount = CmpLazyFlushCount;
|
||||
}
|
||||
}
|
||||
else if ((CmHive->Hive.DirtyCount) &&
|
||||
|
@ -95,6 +98,7 @@ CmpDoFlushNextHive(IN BOOLEAN ForceFlush,
|
|||
/* Use another lazy flusher for this hive */
|
||||
ASSERT(CmHive->FlushCount == CmpLazyFlushCount);
|
||||
*DirtyCount += CmHive->Hive.DirtyCount;
|
||||
DPRINT("CmHive %wZ already uptodate.\n", &CmHive->FileFullPath);
|
||||
}
|
||||
|
||||
/* Try the next one */
|
||||
|
@ -139,6 +143,7 @@ CmpLazyFlushDpcRoutine(IN PKDPC Dpc,
|
|||
IN PVOID SystemArgument2)
|
||||
{
|
||||
/* Check if we should queue the lazy flush worker */
|
||||
DPRINT("Flush pending: %s, Holding lazy flush: %s.\n", CmpLazyFlushPending ? "yes" : "no", CmpHoldLazyFlush ? "yes" : "no");
|
||||
if ((!CmpLazyFlushPending) && (!CmpHoldLazyFlush))
|
||||
{
|
||||
CmpLazyFlushPending = TRUE;
|
||||
|
@ -173,20 +178,27 @@ CmpLazyFlushWorker(IN PVOID Parameter)
|
|||
PAGED_CODE();
|
||||
|
||||
/* Don't do anything if lazy flushing isn't enabled yet */
|
||||
if (CmpHoldLazyFlush) return;
|
||||
if (CmpHoldLazyFlush)
|
||||
{
|
||||
DPRINT1("Lazy flush held. Bye bye.\n");
|
||||
CmpLazyFlushPending = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if we are forcing a flush */
|
||||
ForceFlush = CmpForceForceFlush;
|
||||
if (ForceFlush)
|
||||
{
|
||||
DPRINT("Forcing flush.\n");
|
||||
/* Lock the registry exclusively */
|
||||
CmpLockRegistryExclusive();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do a normal lock */
|
||||
CmpLockRegistry();
|
||||
DPRINT("Not forcing flush.\n");
|
||||
/* Starve writers before locking */
|
||||
InterlockedIncrement(&CmpFlushStarveWriters);
|
||||
CmpLockRegistry();
|
||||
}
|
||||
|
||||
/* Flush the next hive */
|
||||
|
@ -198,14 +210,21 @@ CmpLazyFlushWorker(IN PVOID Parameter)
|
|||
}
|
||||
|
||||
/* Check if we have starved writers */
|
||||
if (!ForceFlush) InterlockedDecrement(&CmpFlushStarveWriters);
|
||||
if (!ForceFlush)
|
||||
InterlockedDecrement(&CmpFlushStarveWriters);
|
||||
|
||||
/* Not pending anymore, release the registry lock */
|
||||
CmpLazyFlushPending = FALSE;
|
||||
CmpUnlockRegistry();
|
||||
|
||||
/* Check if we need to flush another hive */
|
||||
if ((MoreWork) || (DirtyCount)) CmpLazyFlush();
|
||||
DPRINT("Lazy flush done. More work to be done: %s. Entries still dirty: %u.\n",
|
||||
MoreWork ? "Yes" : "No", DirtyCount);
|
||||
|
||||
if (MoreWork)
|
||||
{
|
||||
/* Relaunch the flush timer, so the remaining hives get flushed */
|
||||
CmpLazyFlush();
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
|
@ -1949,6 +1949,11 @@ CmpUnlockRegistry(VOID)
|
|||
CmpDoFlushAll(TRUE);
|
||||
CmpFlushOnLockRelease = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lazy flush the registry */
|
||||
CmpLazyFlush();
|
||||
}
|
||||
|
||||
/* Release the lock and leave the critical region */
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
|
|
Loading…
Reference in a new issue