- Save hive flags instead of ignoring them (but ignore no lazy flush for now).

- Get rid of CmiKeyObjectListHead and code that was adding/removing entries into it, it wasn't used for anything.
- Change the stupid subkey array (which caused pool fragmentation and slow-downs) with a linked-list version, since we never used the array for random indexing (the point of an array vs a linked list).
- Link key object children to parent key control blocks so that KCBs now own PKEY_OBJECTs (will help with parsing later).
- Get rid of CmiAddKeyToList since this is just an InsertTailList now.
- Remove ReactOS hacks in flush code.
- Do full parallel hive loading code in normal boot too, not just in cd-rom boot: CmpSetFileSize was causing the problem to happen so it's been disabled for now; this allowed removal of multiple ReactOS hacks.
- Use the "Allocate" flag during linking instead of hard-coding FALSE, since this also works now.
- Set HIVE_NOLAZYFLUSH to newly create hives since this is required for later.
- Remove CmiConnectedHiveList since it's not used for anything.

svn path=/trunk/; revision=31030
This commit is contained in:
Aleksey Bragin 2007-12-05 22:30:33 +00:00
parent 60b1915ae7
commit 6dea234022
8 changed files with 34 additions and 151 deletions

View file

@ -460,6 +460,7 @@ HvInitialize(
Hive->StorageTypeCount = HTYPE_COUNT;
Hive->Cluster = 1;
Hive->Version = HSYS_MINOR;
Hive->HiveFlags = HiveFlags &~ HIVE_NOLAZYFLUSH;
switch (Operation)
{

View file

@ -4,14 +4,9 @@
#include "ntoskrnl/config/cm.h"
extern POBJECT_TYPE CmpKeyObjectType;
extern KSPIN_LOCK CmiKeyListLock;
extern ERESOURCE CmpRegistryLock;
extern EX_PUSH_LOCK CmpHiveListHeadLock;
NTSTATUS
CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
IN PVOID Argument2);
#define VERIFY_BIN_HEADER(x) ASSERT(x->HeaderId == REG_BIN_ID)
#define VERIFY_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE)
#define VERIFY_ROOT_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE)

View file

@ -175,7 +175,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
KeyObject->KeyControlBlock->ValueCache.Count = Node->ValueList.Count;
/* Link child to parent */
CmiAddKeyToList(Parent, KeyObject);
CmiAddKeyToList(Parent->KeyControlBlock, KeyObject);
/* Create the actual handle to the object */
Status = CmpCreateHandle(KeyObject,

View file

@ -17,7 +17,6 @@
#include "cm.h"
extern LIST_ENTRY CmiKeyObjectListHead;
extern ULONG CmiTimer;
static NTSTATUS
@ -440,22 +439,18 @@ Next:
/* Preconditions: Must be called with CmpRegistryLock held. */
NTSTATUS
CmiScanKeyList(PKEY_OBJECT Parent,
CmiScanKeyList(PCM_KEY_CONTROL_BLOCK Parent,
PCUNICODE_STRING KeyName,
ULONG Attributes,
PKEY_OBJECT* ReturnedObject)
{
PKEY_OBJECT CurKey = NULL;
ULONG Index;
DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
KeyName, &Parent->Name);
/* FIXME: if list maintained in alphabetic order, use dichotomic search */
/* (a binary search) */
for (Index=0; Index < Parent->SubKeyCounts; Index++)
PLIST_ENTRY NextEntry;
NextEntry = Parent->KeyBodyListHead.Flink;
while (NextEntry != &Parent->KeyBodyListHead)
{
CurKey = Parent->SubKeys[Index];
CurKey = CONTAINING_RECORD(NextEntry, KEY_OBJECT, KeyBodyEntry);
if (Attributes & OBJ_CASE_INSENSITIVE)
{
DPRINT("Comparing %wZ and %wZ\n", KeyName, &CurKey->Name);
@ -473,9 +468,11 @@ CmiScanKeyList(PKEY_OBJECT Parent,
break;
}
}
NextEntry = NextEntry->Flink;
}
if (Index < Parent->SubKeyCounts)
if (NextEntry != &Parent->KeyBodyListHead)
{
if (CurKey->KeyControlBlock->Delete)
{
@ -588,7 +585,7 @@ CmpParseKey(IN PVOID ParsedObject,
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
Status = CmiScanKeyList(ParsedKey,
Status = CmiScanKeyList(ParsedKey->KeyControlBlock,
&KeyName,
Attributes,
&FoundObject);
@ -722,9 +719,8 @@ CmpParseKey(IN PVOID ParsedObject,
FoundObject->KeyControlBlock = Kcb;
ASSERT(FoundObject->KeyControlBlock->KeyHive == ParsedKey->KeyControlBlock->KeyHive);
InsertTailList(&CmiKeyObjectListHead, &FoundObject->KeyBodyList);
RtlpCreateUnicodeString(&FoundObject->Name, KeyName.Buffer, NonPagedPool);
CmiAddKeyToList(ParsedKey, FoundObject);
CmiAddKeyToList(ParsedKey->KeyControlBlock, FoundObject);
DPRINT("Created object 0x%p\n", FoundObject);
}
else
@ -784,9 +780,6 @@ CmpParseKey(IN PVOID ParsedObject,
}
}
RemoveEntryList(&FoundObject->KeyBodyList);
InsertHeadList(&CmiKeyObjectListHead, &FoundObject->KeyBodyList);
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
@ -831,16 +824,10 @@ CmpDeleteKeyObject(PVOID DeletedObject)
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
RemoveEntryList(&KeyObject->KeyBodyList);
RtlFreeUnicodeString(&KeyObject->Name);
ASSERT((KeyObject->KeyControlBlock->Delete) == FALSE);
if (KeyObject->SizeOfSubKeys)
{
ExFreePool(KeyObject->SubKeys);
}
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_SUCCESS;
@ -917,41 +904,10 @@ CmpQueryKeyName(PVOID ObjectBody,
}
VOID
CmiAddKeyToList(PKEY_OBJECT ParentKey,
CmiAddKeyToList(PCM_KEY_CONTROL_BLOCK ParentKey,
PKEY_OBJECT NewKey)
{
DPRINT("ParentKey %.08x\n", ParentKey);
if (ParentKey->SizeOfSubKeys <= ParentKey->SubKeyCounts)
{
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool,
(ParentKey->SubKeyCounts + 1) * sizeof(ULONG));
if (ParentKey->SubKeyCounts > 0)
{
RtlCopyMemory (tmpSubKeys,
ParentKey->SubKeys,
ParentKey->SubKeyCounts * sizeof(ULONG));
}
if (ParentKey->SubKeys)
ExFreePool(ParentKey->SubKeys);
ParentKey->SubKeys = tmpSubKeys;
ParentKey->SizeOfSubKeys = ParentKey->SubKeyCounts + 1;
}
/* FIXME: Please maintain the list in alphabetic order */
/* to allow a dichotomic search */
ParentKey->SubKeys[ParentKey->SubKeyCounts++] = NewKey;
DPRINT("Reference parent key: 0x%p\n", ParentKey);
ObReferenceObjectByPointer(ParentKey,
STANDARD_RIGHTS_REQUIRED,
CmpKeyObjectType,
KernelMode);
//NewKey->ParentKey = ParentKey;
InsertTailList(&ParentKey->KeyBodyListHead, &NewKey->KeyBodyEntry);
}
static NTSTATUS

View file

@ -202,8 +202,6 @@ typedef struct _CM_KEY_BODY
struct _CM_KEY_CONTROL_BLOCK *KeyControlBlock;
struct _CM_NOTIFY_BLOCK *NotifyBlock;
HANDLE ProcessID;
ULONG Callers;
PVOID CallerAddress[10];
LIST_ENTRY KeyBodyList;
} CM_KEY_BODY, *PCM_KEY_BODY;
@ -496,11 +494,8 @@ typedef struct _KEY_OBJECT
{
ULONG Type;
UNICODE_STRING Name;
LIST_ENTRY KeyBodyList;
ULONG SubKeyCounts;
ULONG SizeOfSubKeys;
struct _KEY_OBJECT **SubKeys;
PCM_KEY_CONTROL_BLOCK KeyControlBlock;
LIST_ENTRY KeyBodyEntry;
} KEY_OBJECT, *PKEY_OBJECT;
NTSTATUS
NTAPI
@ -513,7 +508,7 @@ CmFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
IN PVOID ParseContext);
NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2);
VOID
CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
CmiAddKeyToList(IN PCM_KEY_CONTROL_BLOCK ParentKey,
IN PKEY_OBJECT NewKey);
///////////////////////////////////////////////////////////////////////////////

View file

@ -39,26 +39,9 @@ CmpDoFlushAll(IN BOOLEAN ForceFlush)
Hive = CONTAINING_RECORD(NextEntry, CMHIVE, HiveList);
if (!(Hive->Hive.HiveFlags & HIVE_NOLAZYFLUSH))
{
/* Find out why this is needed? [Aleksey] */
ULONG Disposition;
CmpOpenHiveFiles(&Hive->FileFullPath,
L".LOG",
&Hive->FileHandles[HFILE_TYPE_PRIMARY],
&Hive->FileHandles[HFILE_TYPE_LOG],
&Disposition,
&Disposition,
FALSE,
FALSE,
TRUE,
NULL);
/* Do the sync */
Status = HvSyncHive(&Hive->Hive);
if (!NT_SUCCESS(Status)) Result = FALSE;
/* ReactOS requires this */
ZwClose(Hive->FileHandles[HFILE_TYPE_PRIMARY]);
ZwClose(Hive->FileHandles[HFILE_TYPE_LOG]);
}
/* Try the next entry */
@ -1170,30 +1153,12 @@ CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
}
else
{
ULONG Disposition;
/* ReactOS Requires this */
CmpOpenHiveFiles(&CmHive->FileFullPath,
L".LOG",
&CmHive->FileHandles[HFILE_TYPE_PRIMARY],
&CmHive->FileHandles[HFILE_TYPE_LOG],
&Disposition,
&Disposition,
FALSE,
FALSE,
TRUE,
NULL);
/* Flush only this hive */
if (!HvSyncHive(Hive))
{
/* Fail */
Status = STATUS_REGISTRY_IO_FAILED;
}
/* ReactOS requires this */
ZwClose(CmHive->FileHandles[HFILE_TYPE_PRIMARY]);
ZwClose(CmHive->FileHandles[HFILE_TYPE_LOG]);
}
/* Return the status */

View file

@ -230,10 +230,6 @@ CmpDoCreateChild(IN PHHIVE Hive,
/* Now fill out the Cm object */
KeyBody->KeyControlBlock = Kcb;
KeyBody->SubKeyCounts = 0;
KeyBody->SubKeys = NULL;
KeyBody->SizeOfSubKeys = 0;
InsertTailList(&CmiKeyObjectListHead, &KeyBody->KeyBodyList);
Quickie:
/* Check if we got here because of failure */
@ -488,10 +484,6 @@ CmpDoOpen(IN PHHIVE Hive,
/* Get the key body and fill it out */
KeyBody = (PKEY_OBJECT)(*Object);
KeyBody->KeyControlBlock = Kcb;
KeyBody->SubKeyCounts = 0;
KeyBody->SubKeys = NULL;
KeyBody->SizeOfSubKeys = 0;
InsertTailList(&CmiKeyObjectListHead, &KeyBody->KeyBodyList);
}
else
{

View file

@ -17,8 +17,6 @@ POBJECT_TYPE CmpKeyObjectType;
PCMHIVE CmiVolatileHive;
LIST_ENTRY CmpHiveListHead;
ERESOURCE CmpRegistryLock;
LIST_ENTRY CmiKeyObjectListHead;
LIST_ENTRY CmiConnectedHiveList;
KGUARDED_MUTEX CmpSelfHealQueueLock;
LIST_ENTRY CmpSelfHealQueueListHead;
KEVENT CmpLoadWorkerEvent;
@ -184,10 +182,6 @@ CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName,
NewHive->FileFullPath.MaximumLength = HiveName->MaximumLength;
}
/* ROS: Close the hive files */
ZwClose(FileHandle);
if (LogHandle) ZwClose(LogHandle);
/* Return success */
return STATUS_SUCCESS;
}
@ -530,8 +524,8 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName,
/* We have one */
ParseContext.ChildHive.KeyCell = RegistryHive->Hive.BaseBlock->RootCell;
}
DPRINT1("Ready to parse\n");
/* Create the link node */
Status = ObOpenObjectByName(&ObjectAttributes,
CmpKeyObjectType,
KernelMode,
@ -539,8 +533,6 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName,
KEY_READ | KEY_WRITE,
(PVOID)&ParseContext,
&KeyHandle);
DPRINT1("Parse done: %lx\n", Status);
//while (TRUE);
/* Capture all the info */
Status = ObpCaptureObjectAttributes(&ObjectAttributes,
@ -622,7 +614,7 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName,
ObReferenceObject(NewKey);
/* Link this key to the parent */
CmiAddKeyToList(ParentKey, NewKey);
CmiAddKeyToList(ParentKey->KeyControlBlock, NewKey);
return STATUS_SUCCESS;
}
@ -670,7 +662,7 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
((PHBASE_BLOCK)HiveBase)->Length = LoaderBlock->RegistryLength;
Status = CmpInitializeHive((PCMHIVE*)&SystemHive,
HINIT_MEMORY,
0, //HIVE_NOLAZYFLUSH,
HIVE_NOLAZYFLUSH,
HFILE_TYPE_LOG,
HiveBase,
NULL,
@ -915,14 +907,8 @@ CmpCreateRegistryRoot(VOID)
RootKey->ProcessID = PsGetCurrentProcessId();
#else
RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool);
RootKey->SubKeyCounts = 0;
RootKey->SubKeys = NULL;
RootKey->SizeOfSubKeys = 0;
#endif
/* Insert it into the object list head */
InsertTailList(&CmiKeyObjectListHead, &RootKey->KeyBodyList);
/* Insert the key into the namespace */
Status = ObInsertObject(RootKey,
NULL,
@ -1023,8 +1009,8 @@ CmpLoadHiveThread(IN PVOID StartContext)
{
WCHAR FileBuffer[MAX_PATH], RegBuffer[MAX_PATH], ConfigPath[MAX_PATH];
UNICODE_STRING TempName, FileName, RegName;
ULONG FileStart, RegStart, i, ErrorResponse, ClusterSize, WorkerCount;
ULONG PrimaryDisposition, SecondaryDisposition, Length;
ULONG FileStart, RegStart, i, ErrorResponse, WorkerCount, Length;
ULONG PrimaryDisposition, SecondaryDisposition, ClusterSize;
PCMHIVE CmHive;
HANDLE PrimaryHandle, LogHandle;
NTSTATUS Status = STATUS_SUCCESS;
@ -1101,13 +1087,12 @@ CmpLoadHiveThread(IN PVOID StartContext)
}
else
{
if (ExpInTextModeSetup) {
/* We already have a hive, is it volatile? */
CmHive = CmpMachineHiveList[i].CmHive;
/* We already have a hive, is it volatile? */
if (!(CmHive->Hive.HiveFlags & HIVE_VOLATILE))
{
DPRINT1("[HiveLoad]: Open from file %wZ\n", &FileName);
/* It's now, open the hive file and log */
Status = CmpOpenHiveFiles(&FileName,
L".LOG",
@ -1137,31 +1122,31 @@ CmpLoadHiveThread(IN PVOID StartContext)
/* Save the file handles. This should remove our sync hacks */
CmHive->FileHandles[HFILE_TYPE_LOG] = LogHandle;
CmHive->FileHandles[HFILE_TYPE_PRIMARY] = PrimaryHandle;
/* Allow lazy flushing since the handles are there -- remove sync hacks */
//ASSERT(CmHive->Hive.HiveFlags & HIVE_NOLAZYFLUSH);
CmHive->Hive.HiveFlags &= ~HIVE_NOLAZYFLUSH;
/* Get the real size of the hive */
Length = CmHive->Hive.Storage[Stable].Length + HBLOCK_SIZE;
/* Check if the cluster size doesn't match */
if (CmHive->Hive.Cluster != ClusterSize) ASSERT(FALSE);
/* Set the file size */
if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length))
//if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length))
{
/* This shouldn't fail */
ASSERT(FALSE);
//ASSERT(FALSE);
}
/* Another thing we don't support is NTLDR-recovery */
if (CmHive->Hive.BaseBlock->BootRecover) ASSERT(FALSE);
/* Finally, set our allocated hive to the same hive we've had */
CmpMachineHiveList[i].CmHive2 = CmHive;
ASSERT(CmpMachineHiveList[i].CmHive == CmpMachineHiveList[i].CmHive2);
}}
}
}
/* We're done */
@ -1289,7 +1274,7 @@ CmpInitializeHiveList(IN USHORT Flag)
Status = CmpLinkHiveToMaster(&RegName,
NULL,
CmpMachineHiveList[i].CmHive2,
FALSE, //CmpMachineHiveList[i].Allocate,
CmpMachineHiveList[i].Allocate,
SecurityDescriptor);
if (Status != STATUS_SUCCESS)
{
@ -1368,12 +1353,6 @@ CmInitSystem1(VOID)
/* Save the current process and lock the registry */
CmpSystemProcess = PsGetCurrentProcess();
#if 1
/* OLD CM: Initialize the key object list */
InitializeListHead(&CmiKeyObjectListHead);
InitializeListHead(&CmiConnectedHiveList);
#endif
/* Create the key object types */
Status = CmpCreateObjectTypes();
if (!NT_SUCCESS(Status))
@ -1475,7 +1454,7 @@ CmInitSystem1(VOID)
((PHBASE_BLOCK)BaseAddress)->Length = Length;
Status = CmpInitializeHive((PCMHIVE*)&HardwareHive,
HINIT_MEMORY, //HINIT_CREATE,
HIVE_VOLATILE,
HIVE_VOLATILE | HIVE_NOLAZYFLUSH,
HFILE_TYPE_PRIMARY,
BaseAddress, // NULL,
NULL,