https://git.reactos.org/?p=reactos.git;a=commitdiff;h=578f2fc51236893d579734f715ef035e1497f6c7

commit 578f2fc51236893d579734f715ef035e1497f6c7
Author:     George Bișoc <[email protected]>
AuthorDate: Thu Dec 22 22:12:55 2022 +0100
Commit:     George Bișoc <[email protected]>
CommitDate: Fri Dec 23 19:45:13 2022 +0100

    [NTOS:CM] Don't lazy flush the registry during unlocking operation
    
    Whenever ReactOS finishes its operations onto the registry and unlocks it, 
a lazy flush is invoked to do an eventual flushing of the registry to the 
backing storage of the system. Except that... lazy flushing never comes into 
place.
    
    This is because whenever CmpLazyFlush is called that sets up a timer which 
needs to expire in order to trigger the lazy flusher engine worker. However, 
registry locking/unlocking is a frequent occurrence, mainly when on desktop. 
Therefore as a matter of fact, CmpLazyFlush keeps removing and inserting the 
timer and the lazy flusher will never kick in that way.
    
    Ironically the lazy flusher actually does the flushing when on USETUP 
installation phase because during text-mode setup installation in ReactOS the 
frequency of registry operations is actually less so the timer has the 
opportunity to expire and fire up the flusher.
    
    In addition to that, we must queue a lazy flush when marking cells as dirty 
because such dirty data has to be flushed down to the media storage of the 
system. Of course, the real place where lazy flushing operation is done should 
be in a subset helper like HvMarkDirty that marks parts of a hive as dirty but 
since we do not have that, we'll be lazy flushing the registry during cells 
dirty marking instead for now.
    
    CORE-18303
---
 ntoskrnl/config/cmsysini.c |  5 -----
 sdk/lib/cmlib/hivecell.c   | 28 ++++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/ntoskrnl/config/cmsysini.c b/ntoskrnl/config/cmsysini.c
index 5260cb69a42..572f8a342f8 100644
--- a/ntoskrnl/config/cmsysini.c
+++ b/ntoskrnl/config/cmsysini.c
@@ -1956,11 +1956,6 @@ CmpUnlockRegistry(VOID)
         CmpDoFlushAll(TRUE);
         CmpFlushOnLockRelease = FALSE;
     }
-    else
-    {
-        /* Lazy flush the registry */
-        CmpLazyFlush();
-    }
 
     /* Release the lock and leave the critical region */
     ExReleaseResourceLite(&CmpRegistryLock);
diff --git a/sdk/lib/cmlib/hivecell.c b/sdk/lib/cmlib/hivecell.c
index 9820ab8de22..2354631ad8c 100644
--- a/sdk/lib/cmlib/hivecell.c
+++ b/sdk/lib/cmlib/hivecell.c
@@ -9,6 +9,16 @@
 #define NDEBUG
 #include <debug.h>
 
+/* DECLARATIONS *************************************************************/
+
+#if !defined(CMLIB_HOST) && !defined(_BLDR_)
+VOID
+NTAPI
+CmpLazyFlush(VOID);
+#endif
+
+/* FUNCTIONS *****************************************************************/
+
 static __inline PHCELL CMAPI
 HvpGetCellHeader(
     PHHIVE RegistryHive,
@@ -118,6 +128,24 @@ HvMarkCellDirty(
     RtlSetBits(&RegistryHive->DirtyVector,
                CellBlock, CellLastBlock - CellBlock);
     RegistryHive->DirtyCount++;
+
+    /*
+     * FIXME: Querying a lazy flush operation is needed to
+     * ensure that the dirty data is being flushed to disk
+     * accordingly. However, this operation has to be done
+     * in a helper like HvMarkDirty that marks specific parts
+     * of the hive as dirty. Since we do not have such kind
+     * of helper we have to perform an eventual lazy flush
+     * when marking cells as dirty here for the moment being,
+     * so that not only we flush dirty data but also write
+     * logs.
+     */
+#if !defined(CMLIB_HOST) && !defined(_BLDR_)
+    if (!(RegistryHive->HiveFlags & HIVE_NOLAZYFLUSH))
+    {
+        CmpLazyFlush();
+    }
+#endif
     return TRUE;
 }
 

Reply via email to