Author: jgardou Date: Thu Jan 23 21:06:48 2014 New Revision: 61783
URL: http://svn.reactos.org/svn/reactos?rev=61783&view=rev Log: [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.
Modified: trunk/reactos/lib/cmlib/hivecell.c trunk/reactos/lib/cmlib/hivewrt.c trunk/reactos/ntoskrnl/config/cmlazy.c trunk/reactos/ntoskrnl/config/cmsysini.c
Modified: trunk/reactos/lib/cmlib/hivecell.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/hivecell.c?rev=61... ============================================================================== --- trunk/reactos/lib/cmlib/hivecell.c [iso-8859-1] (original) +++ trunk/reactos/lib/cmlib/hivecell.c [iso-8859-1] Thu Jan 23 21:06:48 2014 @@ -120,6 +120,7 @@
RtlSetBits(&RegistryHive->DirtyVector, CellBlock, CellLastBlock - CellBlock); + RegistryHive->DirtyCount++; return TRUE; }
Modified: trunk/reactos/lib/cmlib/hivewrt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/cmlib/hivewrt.c?rev=617... ============================================================================== --- trunk/reactos/lib/cmlib/hivewrt.c [iso-8859-1] (original) +++ trunk/reactos/lib/cmlib/hivewrt.c [iso-8859-1] Thu Jan 23 21:06:48 2014 @@ -265,6 +265,7 @@
/* Clear dirty bitmap. */ RtlClearAllBits(&RegistryHive->DirtyVector); + RegistryHive->DirtyCount = 0;
return TRUE; }
Modified: trunk/reactos/ntoskrnl/config/cmlazy.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmlazy.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/config/cmlazy.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cmlazy.c [iso-8859-1] Thu Jan 23 21:06:48 2014 @@ -23,7 +23,7 @@ BOOLEAN CmpForceForceFlush; BOOLEAN CmpHoldLazyFlush = TRUE; ULONG CmpLazyFlushIntervalInSeconds = 5; -ULONG CmpLazyFlushHiveCount = 7; +static ULONG CmpLazyFlushHiveCount = 7; ULONG CmpLazyFlushCount = 1; LONG CmpFlushStarveWriters;
@@ -31,9 +31,9 @@
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 @@ /* 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 @@ /* 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 @@ /* Let them know we failed */ *Error = TRUE; Result = FALSE; + break; } + CmHive->FlushCount = CmpLazyFlushCount; } } else if ((CmHive->Hive.DirtyCount) && @@ -95,6 +98,7 @@ /* 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 @@ 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 @@ 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 */ + DPRINT("Not forcing flush.\n"); + /* Starve writers before locking */ + InterlockedIncrement(&CmpFlushStarveWriters); CmpLockRegistry(); - InterlockedIncrement(&CmpFlushStarveWriters); }
/* Flush the next hive */ @@ -198,14 +210,21 @@ }
/* 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
Modified: trunk/reactos/ntoskrnl/config/cmsysini.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsysini.c?... ============================================================================== --- trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] Thu Jan 23 21:06:48 2014 @@ -1949,6 +1949,11 @@ CmpDoFlushAll(TRUE); CmpFlushOnLockRelease = FALSE; } + else + { + /* Lazy flush the registry */ + CmpLazyFlush(); + }
/* Release the lock and leave the critical region */ ExReleaseResourceLite(&CmpRegistryLock);