[FASTFAT]

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
This commit is contained in:
Pierre Schweitzer 2016-08-06 08:30:30 +00:00
parent 60c0a0a00d
commit ccacd0b3f1
2 changed files with 11 additions and 7 deletions

View file

@ -153,6 +153,7 @@ vfatNewFCB(
rcFCB->RFCB.PagingIoResource = &rcFCB->PagingIoResource; rcFCB->RFCB.PagingIoResource = &rcFCB->PagingIoResource;
rcFCB->RFCB.Resource = &rcFCB->MainResource; rcFCB->RFCB.Resource = &rcFCB->MainResource;
rcFCB->RFCB.IsFastIoPossible = FastIoIsNotPossible; rcFCB->RFCB.IsFastIoPossible = FastIoIsNotPossible;
InitializeListHead(&rcFCB->ParentListHead);
return rcFCB; return rcFCB;
} }
@ -271,6 +272,8 @@ vfatDestroyFCB(
ExDeleteResourceLite(&pFCB->PagingIoResource); ExDeleteResourceLite(&pFCB->PagingIoResource);
ExDeleteResourceLite(&pFCB->MainResource); ExDeleteResourceLite(&pFCB->MainResource);
ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB); ExFreeToNPagedLookasideList(&VfatGlobalData->FcbLookasideList, pFCB);
RemoveEntryList(&pFCB->ParentListEntry);
ASSERT(IsListEmpty(&pFCB->ParentListHead));
} }
BOOLEAN BOOLEAN
@ -455,6 +458,7 @@ vfatUpdateFCB(
/* Save old parent */ /* Save old parent */
OldParent = Fcb->parentFcb; OldParent = Fcb->parentFcb;
RemoveEntryList(&Fcb->ParentListEntry);
/* Reinit FCB */ /* Reinit FCB */
vfatInitFCBFromDirEntry(pVCB, Fcb, DirContext); vfatInitFCBFromDirEntry(pVCB, Fcb, DirContext);
@ -464,6 +468,7 @@ vfatUpdateFCB(
CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL); CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, NULL);
} }
Fcb->parentFcb = ParentFcb; Fcb->parentFcb = ParentFcb;
InsertTailList(&ParentFcb->ParentListHead, &Fcb->ParentListEntry);
vfatAddFCBToTable(pVCB, Fcb); vfatAddFCBToTable(pVCB, Fcb);
/* If we moved across directories, dereference our old parent /* If we moved across directories, dereference our old parent
@ -673,6 +678,7 @@ vfatMakeFCBFromDirEntry(
vfatFCBInitializeCacheFromVolume(vcb, rcFCB); vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
} }
rcFCB->parentFcb = directoryFCB; rcFCB->parentFcb = directoryFCB;
InsertTailList(&directoryFCB->ParentListHead, &rcFCB->ParentListEntry);
vfatAddFCBToTable(vcb, rcFCB); vfatAddFCBToTable(vcb, rcFCB);
*fileFCB = rcFCB; *fileFCB = rcFCB;

View file

@ -704,19 +704,17 @@ VfatSetRenameInformation(
vfatSplitPathName(&NewName, &NewPath, &NewFile); vfatSplitPathName(&NewName, &NewPath, &NewFile);
DPRINT("New dir: %wZ, New file: %wZ\n", &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 if (vfatFCBIsDirectory(FCB) && !IsListEmpty(&FCB->ParentListHead))
* Note: The FIXME is the way MS FastFAT seems to do it
*/
if (vfatFCBIsDirectory(FCB))
{ {
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
PVFATFCB VolFCB; 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); VolFCB = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
if (VolFCB->parentFcb == FCB && VolFCB->OpenHandleCount != 0) 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); DPRINT1("At least one children file opened! %wZ (%u, %u)\n", &VolFCB->PathNameU, VolFCB->RefCount, VolFCB->OpenHandleCount);
Status = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
ASSERT(OldReferences == FCB->parentFcb->RefCount); ASSERT(OldReferences == FCB->parentFcb->RefCount);