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=6…
==============================================================================
--- 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=61…
==============================================================================
--- 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?r…
==============================================================================
--- 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);