Author: pschweitzer
Date: Sun Aug 7 12:29:48 2016
New Revision: 72145
URL:
http://svn.reactos.org/svn/reactos?rev=72145&view=rev
Log:
[FASTFAT]
After renaming a directory, rename any children FCB that would still exist in the FSD.
This will allow next directory opening to properly work and open correct data.
This defeats corruption on directory renaming.
Unfortunately, this solution is not ideal and our driver should be reworked so that it
quits using a hash table and it quits storing the whole path in the FCBs.
Deep thanks to Wim Hueskes and Thomas Faber for their help debugging the issue!
CORE-11377
Modified:
trunk/reactos/drivers/filesystems/fastfat/fcb.c
trunk/reactos/drivers/filesystems/fastfat/finfo.c
trunk/reactos/drivers/filesystems/fastfat/vfat.h
Modified: trunk/reactos/drivers/filesystems/fastfat/fcb.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/fcb.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/fcb.c [iso-8859-1] Sun Aug 7 12:29:48 2016
@@ -425,6 +425,53 @@
Fcb->RFCB.FileSize.QuadPart = Size;
Fcb->RFCB.ValidDataLength.QuadPart = Size;
Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP_64(Size,
Vcb->FatInfo.BytesPerCluster);
+}
+
+NTSTATUS
+vfatSetFCBNewDirName(
+ PDEVICE_EXTENSION pVCB,
+ PVFATFCB Fcb,
+ PVFATFCB ParentFcb)
+{
+ NTSTATUS Status;
+ UNICODE_STRING NewNameU;
+
+ /* Get full path name */
+ Status = vfatMakeFullName(ParentFcb, &Fcb->LongNameU, &Fcb->ShortNameU,
&NewNameU);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Delete old name */
+ if (Fcb->PathNameBuffer)
+ {
+ ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB);
+ }
+ Fcb->PathNameU = NewNameU;
+
+ /* Delete from table */
+ vfatDelFCBFromTable(pVCB, Fcb);
+
+ /* Split it properly */
+ Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
+ Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
+ vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU,
&Fcb->LongNameU);
+
+ if (pVCB->Flags & VCB_IS_FATX)
+ {
+ Fcb->ShortHash.Hash = Fcb->Hash.Hash;
+ }
+ else
+ {
+ Fcb->ShortHash.Hash = vfatNameHash(0, &Fcb->DirNameU);
+ Fcb->ShortHash.Hash = vfatNameHash(Fcb->ShortHash.Hash,
&Fcb->ShortNameU);
+ }
+
+ vfatAddFCBToTable(pVCB, Fcb);
+ vfatReleaseFCB(pVCB, ParentFcb);
+
+ return STATUS_SUCCESS;
}
NTSTATUS
Modified: trunk/reactos/drivers/filesystems/fastfat/finfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/finfo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/finfo.c [iso-8859-1] Sun Aug 7 12:29:48
2016
@@ -487,6 +487,36 @@
return FALSE;
}
+static
+VOID
+VfatRenameChildFCB(
+ PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB FCB)
+{
+ PLIST_ENTRY Entry;
+ PVFATFCB Child;
+
+ if (IsListEmpty(&FCB->ParentListHead))
+ return;
+
+ for (Entry = FCB->ParentListHead.Flink; Entry != &FCB->ParentListHead;
Entry = Entry->Flink)
+ {
+ NTSTATUS Status;
+
+ Child = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
+ DPRINT("Found %wZ with still %lu references (parent: %lu)!\n",
&Child->PathNameU, Child->RefCount, FCB->RefCount);
+
+ Status = vfatSetFCBNewDirName(DeviceExt, Child, FCB);
+ if (!NT_SUCCESS(Status))
+ continue;
+
+ if (vfatFCBIsDirectory(Child))
+ {
+ VfatRenameChildFCB(DeviceExt, Child);
+ }
+ }
+}
+
/*
* FUNCTION: Set the file name information
*/
@@ -911,6 +941,11 @@
}
}
+ if (NT_SUCCESS(Status) && vfatFCBIsDirectory(FCB))
+ {
+ VfatRenameChildFCB(DeviceExt, FCB);
+ }
+
ASSERT(OldReferences == OldParent->RefCount + 1); // removed file
ASSERT(NewReferences == ParentFCB->RefCount - 1); // new file
Cleanup:
Modified: trunk/reactos/drivers/filesystems/fastfat/vfat.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/vfat.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/vfat.h [iso-8859-1] Sun Aug 7 12:29:48
2016
@@ -818,6 +818,12 @@
PUNICODE_STRING pFileNameU);
NTSTATUS
+vfatSetFCBNewDirName(
+ PDEVICE_EXTENSION pVCB,
+ PVFATFCB Fcb,
+ PVFATFCB ParentFcb);
+
+NTSTATUS
vfatUpdateFCB(
PDEVICE_EXTENSION pVCB,
PVFATFCB Fcb,