[FASTFAT]
authorPierre Schweitzer <pierre@reactos.org>
Sat, 6 Aug 2016 08:30:30 +0000 (08:30 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Sat, 6 Aug 2016 08:30:30 +0000 (08:30 +0000)
Track child FCB in parent FCB to allow browsing them in case it's needed.
This allows fixing a FIXME and offering better performances when renaming a directory.

CORE-11377
CORE-11426

svn path=/trunk/; revision=72124

reactos/drivers/filesystems/fastfat/fcb.c
reactos/drivers/filesystems/fastfat/finfo.c

index ad17fa6..f8b0a48 100644 (file)
@@ -153,6 +153,7 @@ vfatNewFCB(
     rcFCB->RFCB.PagingIoResource = &rcFCB->PagingIoResource;
     rcFCB->RFCB.Resource = &rcFCB->MainResource;
     rcFCB->RFCB.IsFastIoPossible = FastIoIsNotPossible;
     rcFCB->RFCB.PagingIoResource = &rcFCB->PagingIoResource;
     rcFCB->RFCB.Resource = &rcFCB->MainResource;
     rcFCB->RFCB.IsFastIoPossible = FastIoIsNotPossible;
+    InitializeListHead(&rcFCB->ParentListHead);
 
     return  rcFCB;
 }
 
     return  rcFCB;
 }
@@ -271,6 +272,8 @@ vfatDestroyFCB(
     ExDeleteResourceLite(&pFCB->PagingIoResource);
     ExDeleteResourceLite(&pFCB->MainResource);
     ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
     ExDeleteResourceLite(&pFCB->PagingIoResource);
     ExDeleteResourceLite(&pFCB->MainResource);
     ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
+    RemoveEntryList(&pFCB->ParentListEntry);
+    ASSERT(IsListEmpty(&pFCB->ParentListHead));
 }
 
 BOOLEAN
 }
 
 BOOLEAN
@@ -455,6 +458,7 @@ vfatUpdateFCB(
 
     /* Save old parent */
     OldParent = Fcb->parentFcb;
 
     /* Save old parent */
     OldParent = Fcb->parentFcb;
+    RemoveEntryList(&Fcb->ParentListEntry);
 
     /* Reinit FCB */
     vfatInitFCBFromDirEntry(pVCB, Fcb, DirContext);
 
     /* Reinit FCB */
     vfatInitFCBFromDirEntry(pVCB, Fcb, DirContext);
@@ -464,6 +468,7 @@ vfatUpdateFCB(
         CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL);
     }
     Fcb->parentFcb = ParentFcb;
         CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL);
     }
     Fcb->parentFcb = ParentFcb;
+    InsertTailList(&ParentFcb->ParentListHead, &Fcb->ParentListEntry);
     vfatAddFCBToTable(pVCB, Fcb);
 
     /* If we moved across directories, dereference our old parent
     vfatAddFCBToTable(pVCB, Fcb);
 
     /* If we moved across directories, dereference our old parent
@@ -673,6 +678,7 @@ vfatMakeFCBFromDirEntry(
         vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
     }
     rcFCB->parentFcb = directoryFCB;
         vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
     }
     rcFCB->parentFcb = directoryFCB;
+    InsertTailList(&directoryFCB->ParentListHead, &rcFCB->ParentListEntry);
     vfatAddFCBToTable(vcb, rcFCB);
     *fileFCB = rcFCB;
 
     vfatAddFCBToTable(vcb, rcFCB);
     *fileFCB = rcFCB;
 
index 7ce51ee..3f18eae 100644 (file)
@@ -704,19 +704,17 @@ VfatSetRenameInformation(
     vfatSplitPathName(&NewName, &NewPath, &NewFile);
     DPRINT("New dir: %wZ, New file: %wZ\n", &NewPath, &NewFile);
 
     vfatSplitPathName(&NewName, &NewPath, &NewFile);
     DPRINT("New dir: %wZ, New file: %wZ\n", &NewPath, &NewFile);
 
-    /* FIXME: Do it in a more efficient way, like linking FCBs to their parent FCB so that we browse less FCBs
-     * Note: The FIXME is the way MS FastFAT seems to do it
-     */
-    if (vfatFCBIsDirectory(FCB))
+    if (vfatFCBIsDirectory(FCB) && !IsListEmpty(&FCB->ParentListHead))
     {
         PLIST_ENTRY Entry;
         PVFATFCB VolFCB;
 
     {
         PLIST_ENTRY Entry;
         PVFATFCB VolFCB;
 
-        for (Entry = DeviceExt->FcbListHead.Flink; Entry != &DeviceExt->FcbListHead; Entry = Entry->Flink)
+        for (Entry = FCB->ParentListHead.Flink; Entry != &FCB->ParentListHead; Entry = Entry->Flink)
         {
         {
-            VolFCB = CONTAINING_RECORD(Entry, VFATFCB, FcbListEntry);
-            if (VolFCB->parentFcb == FCB && VolFCB->OpenHandleCount != 0)
+            VolFCB = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
+            if (VolFCB->OpenHandleCount != 0)
             {
             {
+                ASSERT(VolFCB->parentFCB == FCB);
                 DPRINT1("At least one children file opened! %wZ (%u, %u)\n", &VolFCB->PathNameU, VolFCB->RefCount, VolFCB->OpenHandleCount);
                 Status = STATUS_ACCESS_DENIED;
                 ASSERT(OldReferences == FCB->parentFcb->RefCount);
                 DPRINT1("At least one children file opened! %wZ (%u, %u)\n", &VolFCB->PathNameU, VolFCB->RefCount, VolFCB->OpenHandleCount);
                 Status = STATUS_ACCESS_DENIED;
                 ASSERT(OldReferences == FCB->parentFcb->RefCount);