[ros-diffs] [ion] 23590: - Add definitions for HCELL_NIL and HCELL_CACHED. - Add CM_DELAY_DEREF_KCB_ITEM. - Add CM_CACHED_VALUE_INDEX, CM_CACHED_VALUE. - Add macros for dealing with cached cells (CMP_GET_CACHED_CELL, CMP_GET_CACHED_DATA, _INDEX, _VALUE and CMP_IS_CELL_CACHED). - Implement CmpRemoveFromDelayedClose, CmpDelayDerefKCb, CmpCleanUpKcbValueCache, CmpCleanUpKcbCacheWithLock. - Fix return value of CmpAllocateDelayItem.

ion at svn.reactos.org ion at svn.reactos.org
Wed Aug 16 20:38:09 CEST 2006


Author: ion
Date: Wed Aug 16 22:38:09 2006
New Revision: 23590

URL: http://svn.reactos.org/svn/reactos?rev=23590&view=rev
Log:
- Add definitions for HCELL_NIL and HCELL_CACHED.
- Add CM_DELAY_DEREF_KCB_ITEM.
- Add CM_CACHED_VALUE_INDEX, CM_CACHED_VALUE.
- Add macros for dealing with cached cells (CMP_GET_CACHED_CELL, CMP_GET_CACHED_DATA, _INDEX, _VALUE and CMP_IS_CELL_CACHED).
- Implement CmpRemoveFromDelayedClose, CmpDelayDerefKCb, CmpCleanUpKcbValueCache, CmpCleanUpKcbCacheWithLock.
- Fix return value of CmpAllocateDelayItem.

Modified:
    branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h
    branches/alex-cm-branch/reactos/ntoskrnl/cm/cm_x.h
    branches/alex-cm-branch/reactos/ntoskrnl/cm/cmkcbncb.c

Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h
URL: http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h?rev=23590&r1=23589&r2=23590&view=diff
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h Wed Aug 16 22:38:09 2006
@@ -73,6 +73,12 @@
 #define HBLOCK_SIZE                                     0x1000
 #define HSECTOR_SIZE                                    0x200
 #define HSECTOR_COUNT                                   8
+
+//
+// Cell Masks
+//
+#define HCELL_NIL                                       0
+#define HCELL_CACHED                                    1
 
 //
 // CM_KEY_CONTROL_BLOCK Flags
@@ -367,6 +373,15 @@
     LIST_ENTRY DelayedLRUList;
     PCM_KEY_CONTROL_BLOCK KeyControlBlock;
 } CM_DELAYED_CLOSE_ENTRY, *PCM_DELAYED_CLOSE_ENTRY;
+
+//
+// Delayed KCB Dereference Entry
+//
+typedef struct _CM_DELAY_DEREF_KCB_ITEM
+{
+    LIST_ENTRY ListEntry;
+    PCM_KEY_CONTROL_BLOCK Kcb;
+} CM_DELAY_DEREF_KCB_ITEM, *PCM_DELAY_DEREF_KCB_ITEM;
 
 //
 // Use Count Log and Entry
@@ -521,6 +536,29 @@
 } CELL_DATA, *PCELL_DATA;
 
 //
+// Cached Value Index
+//
+typedef struct _CM_CACHED_VALUE_INDEX
+{
+    HCELL_INDEX CellIndex;
+    union
+    {
+        CELL_DATA CellData;
+        ULONG_PTR List[ANYSIZE_ARRAY];
+    } Data;
+} CM_CACHED_VALUE_INDEX, *PCM_CACHED_VALUE_INDEX;
+
+//
+// Cached Value
+//
+typedef struct _CM_CACHED_VALUE
+{
+    USHORT DataCacheType;
+    USHORT ValueKeySize;
+    CM_KEY_VALUE KeyValue;
+} CM_CACHED_VALUE, *PCM_CACHED_VALUE;
+
+//
 // Registry Validation Functions
 //
 BOOLEAN
@@ -531,7 +569,7 @@
 );
 
 //
-// Registry Lock
+// Registry Locking Functions
 //
 BOOLEAN
 NTAPI
@@ -540,6 +578,16 @@
 );
 
 //
+// KCB Functions
+//
+VOID
+NTAPI
+CmpDereferenceKcbWithLock(
+    IN PCM_KEY_CONTROL_BLOCK Kcb,
+    IN BOOLEAN LockHeldExclusively
+);
+
+//
 // Global variables accessible from all of Cm
 //
 

Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cm_x.h
URL: http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl/cm/cm_x.h?rev=23590&r1=23589&r2=23590&view=diff
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cm_x.h (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cm_x.h Wed Aug 16 22:38:09 2006
@@ -19,6 +19,24 @@
     GET_HASH_KEY(ConvKey) % CmpHashTableSize
 #define GET_HASH_ENTRY(Table, ConvKey)                              \
     (*Table[GET_HASH_INDEX(ConvKey)])
+
+//
+// Returns whether or not the cell is cached
+//
+#define CMP_IS_CELL_CACHED(c)                                       \
+    (((c) & HCELL_CACHED) && ((c) != HCELL_NIL))
+
+//
+// Return data from a cached cell
+//
+#define CMP_GET_CACHED_CELL(c)                                      \
+    (ULONG_PTR)((c) & ~HCELL_CACHED)
+#define CMP_GET_CACHED_DATA(c)                                      \
+    (&(((PCM_CACHED_VALUE_INDEX)(CMP_GET_CACHED_CELL(c)))->Data.CellData))
+#define CMP_GET_CACHED_INDEX(c)                                     \
+    (&(((PCM_CACHED_ENTRY)(CMP_GET_CACHED_CELL(c)))->CellIndex))
+#define CMP_GET_CACHED_VALUE(c)                                     \
+    (&(((PCM_CACHED_VALUE)(CMP_GET_CACHED_CELL(c)))->KeyValue))
 
 //
 // Makes sure that the registry is locked

Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cmkcbncb.c
URL: http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl/cm/cmkcbncb.c?rev=23590&r1=23589&r2=23590&view=diff
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cmkcbncb.c (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cmkcbncb.c Wed Aug 16 22:38:09 2006
@@ -29,6 +29,14 @@
 ULONG CmpDelayCloseIntervalInSeconds = 5;
 KDPC CmpDelayCloseDpc;
 KTIMER CmpDelayCloseTimer;
+
+KGUARDED_MUTEX CmpDelayDerefKCBLock;
+BOOLEAN CmpDelayDerefKCBWorkItemActive;
+LIST_ENTRY CmpDelayDerefKCBListHead;
+ULONG CmpDelayDerefKCBIntervalInSeconds = 5;
+KDPC CmpDelayDerefKCBDpc;
+KTIMER CmpDelayDerefKCBTimer;
+
 BOOLEAN CmpHoldLazyFlush;
 
 /* FUNCTIONS *****************************************************************/
@@ -281,6 +289,56 @@
     }
 }
 
+VOID
+NTAPI
+CmpRemoveFromDelayedClose(IN PCM_KEY_CONTROL_BLOCK Kcb)
+{
+    PCM_DELAYED_CLOSE_ENTRY Entry;
+    ULONG NewRefCount, OldRefCount;
+    PAGED_CODE();
+
+    /* Sanity checks */
+    ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
+           (CmpTestRegistryLockExclusive() == TRUE));
+    if (Kcb->DelayedCloseIndex == CmpDelayedCloseSize) ASSERT(FALSE);
+
+    /* Get the entry and lock the table */
+    Entry = Kcb->DelayCloseEntry;
+    KeAcquireGuardedMutex(&CmpDelayedCloseTableLock);
+
+    /* Remove the entry */
+    RemoveEntryList(&Entry->DelayedLRUList);
+
+    /* Release the lock */
+    KeReleaseGuardedMutex(&CmpDelayedCloseTableLock);
+
+    /* Free the entry */
+    CmpFreeDelayItem(Entry);
+
+    /* Reduce the number of elements */
+    InterlockedDecrement(&CmpDelayedCloseElements);
+
+    /* Sanity check */
+    if (!Kcb->InDelayClose) ASSERT(FALSE);
+
+    /* Get the old reference count */
+    OldRefCount = Kcb->InDelayClose;
+    ASSERT(OldRefCount == 1);
+
+    /* Set it to 0 */
+    NewRefCount = InterlockedCompareExchange(&Kcb->InDelayClose,
+                                             0,
+                                             OldRefCount);
+    if (NewRefCount != OldRefCount) ASSERT(FALSE);
+
+    /* Remove the link to the entry */
+    Kcb->DelayCloseEntry = NULL;
+
+    /* Set new delay size and remove the delete flag */
+    Kcb->DelayedCloseIndex = CmpDelayedCloseSize;
+    Kcb->Delete = FALSE;
+}
+
 BOOLEAN
 NTAPI
 CmpReferenceKcb(IN PCM_KEY_CONTROL_BLOCK Kcb)
@@ -359,7 +417,7 @@
 }
 
 // FIXME: THIS FUNCTION IS PARTIALLY FUCKED
-PCM_DELAYED_CLOSE_ENTRY
+PVOID
 NTAPI
 CmpAllocateDelayItem(VOID)
 {
@@ -408,6 +466,131 @@
     /* Release the lock */
     KeReleaseGuardedMutex(&CmpDelayAllocBucketLock);
     return Entry;
+}
+
+VOID
+NTAPI
+CmpDelayDerefKcb(IN PCM_KEY_CONTROL_BLOCK Kcb)
+{
+    USHORT OldRefCount, NewRefCount;
+    LARGE_INTEGER Timeout;
+    PCM_DELAY_DEREF_KCB_ITEM Entry;
+    PAGED_CODE();
+
+    /* Get the previous reference count */
+    OldRefCount = Kcb->RefCount;
+
+    /* Write the new one */
+    NewRefCount = (USHORT)InterlockedCompareExchange((PLONG)&Kcb->RefCount,
+                                                     OldRefCount - 1,
+                                                     OldRefCount);
+    if (NewRefCount != OldRefCount) return;
+
+    /* Allocate a delay item */
+    Entry = CmpAllocateDelayItem();
+    if (!Entry) return;
+
+    /* Set the KCB */
+    Entry->Kcb = Kcb;
+
+    /* Acquire the delayed deref table lock */
+    KeAcquireGuardedMutex(&CmpDelayDerefKCBLock);
+
+    /* Insert the entry into the list */
+    InsertHeadList(&CmpDelayDerefKCBListHead, &Entry->ListEntry);
+
+    /* Check if we need to enable anything */
+    if (CmpDelayDerefKCBWorkItemActive)
+    {
+        /* Yes, we have no work item, setup the interval */
+        Timeout.QuadPart = CmpDelayDerefKCBIntervalInSeconds * -10000000;
+        KeSetTimer(&CmpDelayDerefKCBTimer, Timeout, &CmpDelayDerefKCBDpc);
+    }
+
+    /* Release the table lock */
+    KeReleaseGuardedMutex(&CmpDelayDerefKCBLock);
+}
+
+VOID
+NTAPI
+CmpCleanUpKcbValueCache(IN PCM_KEY_CONTROL_BLOCK Kcb)
+{
+    PULONG_PTR CachedList;
+    ULONG i;
+
+    /* Sanity check */
+    ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
+           (CmpTestRegistryLockExclusive() == TRUE));
+
+    /* Check if the value list is cached */
+    if (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))
+    {
+        /* Get the cache list */
+        CachedList = (PULONG_PTR)CMP_GET_CACHED_DATA(Kcb->ValueCache.ValueList);
+        for (i = 0; i < Kcb->ValueCache.Count; i++)
+        {
+            /* Check if this cell is cached */
+            if (CMP_IS_CELL_CACHED(CachedList[i]))
+            {
+                /* Free it */
+                ExFreePool((PVOID)CMP_GET_CACHED_CELL(CachedList[i]));
+            }
+        }
+
+        /* Now free the list */
+        ExFreePool((PVOID)CMP_GET_CACHED_CELL(Kcb->ValueCache.ValueList));
+        Kcb->ValueCache.ValueList = HCELL_NIL;
+    }
+    else if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
+    {
+        /* This is a sym link, check if there's only one reference left */
+        if ((Kcb->ValueCache.RealKcb->RefCount == 1) &&
+            !(Kcb->ValueCache.RealKcb->Delete))
+        {
+            /* Disable delay close for the KCB */
+            Kcb->ValueCache.RealKcb->ExtFlags |= CM_KCB_NO_DELAY_CLOSE;
+        }
+
+        /* Dereference the KCB */
+        CmpDelayDerefKcb(Kcb->ValueCache.RealKcb);
+        Kcb->ExtFlags &= ~ CM_KCB_SYM_LINK_FOUND;
+    }
+}
+
+VOID
+NTAPI
+CmpCleanUpKcbCacheWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb,
+                           IN BOOLEAN LockHeldExclusively)
+{
+    PCM_KEY_CONTROL_BLOCK Parent;
+    PAGED_CODE();
+
+    /* Sanity checks */
+    ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
+           (CmpTestRegistryLockExclusive() == TRUE));
+    ASSERT(Kcb->RefCount == 0);
+
+    /* Cleanup the value cache */
+    CmpCleanUpKcbValueCache(Kcb);
+
+    /* Reference the NCB */
+    CmpDereferenceNcbWithLock(Kcb->NameBlock);
+
+    /* Check if we have an index hint block and free it */
+    if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT) ExFreePool(Kcb->IndexHint);
+
+    /* Check if we were already deleted */
+    Parent = Kcb->ParentKcb;
+    if (!Kcb->Delete) CmpFreeKcb(Kcb);
+
+    /* Check if we have a parent */
+    if (Parent)
+    {
+        /* Dereference the parent */
+        LockHeldExclusively ? CmpDereferenceKcbWithLock(Kcb,
+                              LockHeldExclusively) :
+                              CmpDelayDerefKcb(Kcb);
+    }
 }
 
 VOID




More information about the Ros-diffs mailing list