From a40ba448d401e53788db2356108130e81b597a6f Mon Sep 17 00:00:00 2001 From: Trevor Thompson Date: Fri, 1 Sep 2017 00:27:34 +0000 Subject: [PATCH] [NTFS] - Fix some errors that break building in C89 mode, and remove an extraneous "ninja livecd" that got inserted in a comment. Thanks to Doug Lyons for spotting these errors. SplitBTree() - comment-out redundant code for finding the median key and improve comments. svn path=/branches/GSoC_2016/NTFS/; revision=75727 --- drivers/filesystems/ntfs/btree.c | 30 ++++++++++++++++++++++-------- drivers/filesystems/ntfs/mft.c | 10 ++++++---- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/drivers/filesystems/ntfs/btree.c b/drivers/filesystems/ntfs/btree.c index bb745c5e9e2..9fb1b29c0f5 100644 --- a/drivers/filesystems/ntfs/btree.c +++ b/drivers/filesystems/ntfs/btree.c @@ -1139,7 +1139,7 @@ DemoteBTreeRoot(PB_TREE Tree) #ifndef NDEBUG DumpBTree(Tree); -#endif; +#endif return STATUS_SUCCESS; } @@ -1779,7 +1779,7 @@ NtfsInsertKey(PB_TREE Tree, #ifndef NDEBUG DumpBTree(Tree); -#endif NDEBUG +#endif } } else @@ -1880,6 +1880,9 @@ SplitBTreeNode(PB_TREE Tree, { ULONG MedianKeyIndex; PB_TREE_KEY LastKeyBeforeMedian, FirstKeyAfterMedian; + ULONG KeyCount; + ULONG HalfSize; + ULONG SizeSum; ULONG i; DPRINT1("SplitBTreeNode(%p, %p, %p, %p, %s) called\n", @@ -1889,7 +1892,9 @@ SplitBTreeNode(PB_TREE Tree, NewRightHandSibling, CaseSensitive ? "TRUE" : "FALSE"); - //DumpBTreeNode(Node, 0, 0); +#ifndef NDEBUG + DumpBTreeNode(Node, 0, 0); +#endif // Create the right hand sibling *NewRightHandSibling = ExAllocatePoolWithTag(NonPagedPool, sizeof(B_TREE_FILENAME_NODE), TAG_NTFS); @@ -1901,20 +1906,29 @@ SplitBTreeNode(PB_TREE Tree, RtlZeroMemory(*NewRightHandSibling, sizeof(B_TREE_FILENAME_NODE)); (*NewRightHandSibling)->DiskNeedsUpdating = TRUE; + + // Find the last key before the median + + // This is roughly how NTFS-3G calculates median, and it's not congruent with what Windows does: + /* // find the median key index MedianKeyIndex = (Node->KeyCount + 1) / 2; MedianKeyIndex--; - // Find the last key before the median LastKeyBeforeMedian = Node->FirstKey; for (i = 0; i < MedianKeyIndex - 1; i++) - LastKeyBeforeMedian = LastKeyBeforeMedian->NextKey; + LastKeyBeforeMedian = LastKeyBeforeMedian->NextKey;*/ + + // The method we'll use is a little bit closer to how Windows determines the median but it's not identical. + // What Windows does is actually more complicated than this, I think because Windows allocates more slack space to Odd-numbered + // Index Records, leaving less room for index entries in these records (I haven't discovered why this is done). + // (Neither Windows nor chkdsk complain if we choose a different median than Windows would have chosen, as our median will be in the ballpark) // Use size to locate the median key / index - ULONG HalfSize = 2016; // half the allocated size after subtracting the first index entry offset (TODO: MATH) - ULONG SizeSum = 0; LastKeyBeforeMedian = Node->FirstKey; MedianKeyIndex = 0; + HalfSize = 2016; // half the allocated size after subtracting the first index entry offset (TODO: MATH) + SizeSum = 0; for (i = 0; i < Node->KeyCount; i++) { SizeSum += LastKeyBeforeMedian->IndexEntry->Length; @@ -1989,7 +2003,7 @@ SplitBTreeNode(PB_TREE Tree, // Update Node's KeyCount (remember to add 1 for the new dummy key) Node->KeyCount = MedianKeyIndex + 2; - ULONG KeyCount = CountBTreeKeys(Node->FirstKey); + KeyCount = CountBTreeKeys(Node->FirstKey); ASSERT(Node->KeyCount == KeyCount); // everything to the right of MedianKey becomes the right hand sibling of Node diff --git a/drivers/filesystems/ntfs/mft.c b/drivers/filesystems/ntfs/mft.c index c4328a0491a..9d96bad239a 100644 --- a/drivers/filesystems/ntfs/mft.c +++ b/drivers/filesystems/ntfs/mft.c @@ -2138,6 +2138,9 @@ NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt, ULONG MaxIndexRootSize; PB_TREE_KEY NewLeftKey; PB_TREE_FILENAME_NODE NewRightHandNode; + LARGE_INTEGER MinIndexRootSize; + ULONG NewMaxIndexRootSize; + ULONG NodeSize; // Allocate memory for the parent directory ParentFileRecord = ExAllocatePoolWithTag(NonPagedPool, @@ -2287,7 +2290,6 @@ NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt, // This a bit hacky, but it seems to be functional. // Calculate the minimum size of the index root attribute, considering one dummy key and one VCN - LARGE_INTEGER MinIndexRootSize; MinIndexRootSize.QuadPart = sizeof(INDEX_ROOT_ATTRIBUTE) // size of the index root headers + 0x18; // Size of dummy key with a VCN for a subnode ASSERT(MinIndexRootSize.QuadPart % ATTR_RECORD_ALIGNMENT == 0); @@ -2335,7 +2337,7 @@ NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt, // Find the maximum index root size given what the file record can hold // First, find the max index size assuming index root is the last attribute - ULONG NewMaxIndexRootSize = + NewMaxIndexRootSize = DeviceExt->NtfsInfo.BytesPerFileRecord // Start with the size of a file record - IndexRootOffset // Subtract the length of everything that comes before index root - IndexRootContext->pRecord->Resident.ValueOffset // Subtract the length of the attribute header for index root @@ -2361,7 +2363,7 @@ NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt, // The index allocation and index bitmap may have grown, leaving less room for the index root, // so now we need to double-check that index root isn't too large - ULONG NodeSize = GetSizeOfIndexEntries(NewTree->RootNode); + NodeSize = GetSizeOfIndexEntries(NewTree->RootNode); if (NodeSize > NewMaxIndexRootSize) { DPRINT1("Demoting index root.\nNodeSize: 0x%lx\nNewMaxIndexRootSize: 0x%lx\n", NodeSize, NewMaxIndexRootSize); @@ -2624,7 +2626,7 @@ CompareFileName(PUNICODE_STRING FileName, * @param Vcb * Pointer to an NTFS_VCB for the volume whose Mft mirror is being updated. * -* @returninja livecd +* @return * STATUS_SUCCESS on success. * STATUS_INSUFFICIENT_RESOURCES if an allocation failed.