diff --git a/drivers/filesystems/fastfat/cleanup.c b/drivers/filesystems/fastfat/cleanup.c index 291cd77a2fd..d09df956ca4 100644 --- a/drivers/filesystems/fastfat/cleanup.c +++ b/drivers/filesystems/fastfat/cleanup.c @@ -161,7 +161,7 @@ VfatCleanupFile( #ifdef ENABLE_SWAPOUT if (IsVolume && BooleanFlagOn(DeviceExt->Flags, VCB_DISMOUNT_PENDING)) { - VfatCheckForDismount(DeviceExt, FALSE); + VfatCheckForDismount(DeviceExt, TRUE); } #endif diff --git a/drivers/filesystems/fastfat/close.c b/drivers/filesystems/fastfat/close.c index d8f85a85a43..b6c250f92c9 100644 --- a/drivers/filesystems/fastfat/close.c +++ b/drivers/filesystems/fastfat/close.c @@ -21,8 +21,8 @@ VfatCommonCloseFile( PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb) { - /* Nothing to do for volumes */ - if (BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME)) + /* Nothing to do for volumes or for the FAT file object */ + if (BooleanFlagOn(pFcb->Flags, FCB_IS_FAT | FCB_IS_VOLUME)) { return; } diff --git a/drivers/filesystems/fastfat/fat.c b/drivers/filesystems/fastfat/fat.c index 8d4ecd9cde1..591e60b4fd9 100644 --- a/drivers/filesystems/fastfat/fat.c +++ b/drivers/filesystems/fastfat/fat.c @@ -20,12 +20,6 @@ #define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \ (pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE) -/* FIXME: because volume is not cached, we have to perform direct IOs - * The day this is fixed, just comment out that line, and check - * it still works (and delete old code ;-)) - */ -#define VOLUME_IS_NOT_CACHED_WORK_AROUND_IT - /* FUNCTIONS ****************************************************************/ /* diff --git a/drivers/filesystems/fastfat/fcb.c b/drivers/filesystems/fastfat/fcb.c index ed85ab277c0..a791c27a40d 100644 --- a/drivers/filesystems/fastfat/fcb.c +++ b/drivers/filesystems/fastfat/fcb.c @@ -277,6 +277,7 @@ vfatDestroyFCB( #endif FsRtlUninitializeFileLock(&pFCB->FileLock); + if (!vfatFCBIsRoot(pFCB) && !BooleanFlagOn(pFCB->Flags, FCB_IS_FAT) && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME)) { @@ -317,11 +318,15 @@ _vfatGrabFCB( { DPRINT1("Inc ref count (%d, oc: %d) for: %p (%wZ) at: %s(%d) %s\n", pFCB->RefCount, pFCB->OpenHandleCount, pFCB, &pFCB->PathNameU, File, Line, Func); } +#else + DPRINT("Grabbing FCB at %p: %wZ, refCount:%d\n", + pFCB, &pFCB->PathNameU, pFCB->RefCount); #endif ASSERT(ExIsResourceAcquiredExclusive(&pVCB->DirResource)); - ASSERT(pFCB != pVCB->VolumeFcb); + ASSERT(!BooleanFlagOn(pFCB->Flags, FCB_IS_FAT)); + ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME)); ASSERT(pFCB->RefCount > 0); ++pFCB->RefCount; } @@ -350,7 +355,7 @@ _vfatReleaseFCB( DPRINT1("Dec ref count (%d, oc: %d) for: %p (%wZ) at: %s(%d) %s\n", pFCB->RefCount, pFCB->OpenHandleCount, pFCB, &pFCB->PathNameU, File, Line, Func); } #else - DPRINT("releasing FCB at %p: %wZ, refCount:%d\n", + DPRINT("Releasing FCB at %p: %wZ, refCount:%d\n", pFCB, &pFCB->PathNameU, pFCB->RefCount); #endif @@ -360,7 +365,8 @@ _vfatReleaseFCB( { ULONG RefCount; - ASSERT(pFCB != pVCB->VolumeFcb); + ASSERT(!BooleanFlagOn(pFCB->Flags, FCB_IS_FAT)); + ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME)); ASSERT(pFCB->RefCount > 0); RefCount = --pFCB->RefCount; @@ -647,6 +653,8 @@ vfatMakeRootFCB( NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\"); + ASSERT(pVCB->RootFcb == NULL); + FCB = vfatNewFCB(pVCB, &NameU); if (vfatVolumeIsFatX(pVCB)) { @@ -690,6 +698,9 @@ vfatMakeRootFCB( vfatFCBInitializeCacheFromVolume(pVCB, FCB); vfatAddFCBToTable(pVCB, FCB); + /* Cache it */ + pVCB->RootFcb = FCB; + return FCB; } @@ -705,6 +716,7 @@ vfatOpenRootFCB( { FCB = vfatMakeRootFCB(pVCB); } + ASSERT(FCB == pVCB->RootFcb); return FCB; } @@ -747,8 +759,6 @@ vfatAttachFCBToFileObject( { PVFATCCB newCCB; - UNREFERENCED_PARAMETER(vcb); - #ifdef KDBG if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL)) { diff --git a/drivers/filesystems/fastfat/flush.c b/drivers/filesystems/fastfat/flush.c index 22a8c6d08fe..2861998420b 100644 --- a/drivers/filesystems/fastfat/flush.c +++ b/drivers/filesystems/fastfat/flush.c @@ -59,7 +59,9 @@ VfatFlushVolume( KEVENT Event; IO_STATUS_BLOCK IoStatusBlock; - DPRINT("VfatFlushVolume(DeviceExt %p, FatFcb %p)\n", DeviceExt, VolumeFcb); + DPRINT("VfatFlushVolume(DeviceExt %p, VolumeFcb %p)\n", DeviceExt, VolumeFcb); + + ASSERT(VolumeFcb == DeviceExt->VolumeFcb); ListEntry = DeviceExt->FcbListHead.Flink; while (ListEntry != &DeviceExt->FcbListHead) diff --git a/drivers/filesystems/fastfat/fsctl.c b/drivers/filesystems/fastfat/fsctl.c index 6523487368c..d8394e46a72 100644 --- a/drivers/filesystems/fastfat/fsctl.c +++ b/drivers/filesystems/fastfat/fsctl.c @@ -531,7 +531,6 @@ VfatMount( NTSTATUS Status; PVFATFCB Fcb = NULL; PVFATFCB VolumeFcb = NULL; - PVFATCCB Ccb = NULL; PDEVICE_OBJECT DeviceToMount; PVPB Vpb; UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\$$Fat$$"); @@ -706,23 +705,14 @@ VfatMount( goto ByeBye; } - Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList); - if (Ccb == NULL) - { - Status = STATUS_INSUFFICIENT_RESOURCES; + Status = vfatAttachFCBToFileObject(DeviceExt, Fcb, DeviceExt->FATFileObject); + if (!NT_SUCCESS(Status)) goto ByeBye; - } - RtlZeroMemory(Ccb, sizeof (VFATCCB)); - DeviceExt->FATFileObject->FsContext = Fcb; - DeviceExt->FATFileObject->FsContext2 = Ccb; - DeviceExt->FATFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; DeviceExt->FATFileObject->PrivateCacheMap = NULL; - DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb; Fcb->FileObject = DeviceExt->FATFileObject; - Fcb->Flags |= FCB_IS_FAT; - + Fcb->Flags = FCB_IS_FAT; Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector; Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize; Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize; @@ -798,9 +788,15 @@ VfatMount( SetFlag(DeviceExt->Flags, VCB_IS_SYS_OR_HAS_PAGE); } - FsRtlNotifyVolumeEvent(DeviceExt->FATFileObject, FSRTL_VOLUME_MOUNT); - FsRtlNotifyInitializeSync(&DeviceExt->NotifySync); + /* Initialize the notify list and synchronization object */ InitializeListHead(&DeviceExt->NotifyList); + FsRtlNotifyInitializeSync(&DeviceExt->NotifySync); + + /* The VCB is OK for usage */ + SetFlag(DeviceExt->Flags, VCB_GOOD); + + /* Send the mount notification */ + FsRtlNotifyVolumeEvent(DeviceExt->FATFileObject, FSRTL_VOLUME_MOUNT); DPRINT("Mount success\n"); @@ -811,15 +807,24 @@ ByeBye: { /* Cleanup */ if (DeviceExt && DeviceExt->FATFileObject) - ObDereferenceObject (DeviceExt->FATFileObject); + { + LARGE_INTEGER Zero = {{0,0}}; + PVFATCCB Ccb = (PVFATCCB)DeviceExt->FATFileObject->FsContext2; + + CcUninitializeCacheMap(DeviceExt->FATFileObject, + &Zero, + NULL); + ObDereferenceObject(DeviceExt->FATFileObject); + if (Ccb) + vfatDestroyCCB(Ccb); + DeviceExt->FATFileObject = NULL; + } + if (Fcb) + vfatDestroyFCB(Fcb); if (DeviceExt && DeviceExt->SpareVPB) ExFreePoolWithTag(DeviceExt->SpareVPB, TAG_VPB); if (DeviceExt && DeviceExt->Statistics) ExFreePoolWithTag(DeviceExt->Statistics, TAG_STATS); - if (Fcb) - vfatDestroyFCB(Fcb); - if (Ccb) - vfatDestroyCCB(Ccb); if (DeviceObject) IoDeleteDevice(DeviceObject); } @@ -1125,6 +1130,11 @@ VfatLockOrUnlockVolume( return STATUS_ACCESS_DENIED; } + if (Lock) + { + FsRtlNotifyVolumeEvent(IrpContext->Stack->FileObject, FSRTL_VOLUME_LOCK); + } + /* Deny locking if we're not alone */ if (Lock && DeviceExt->OpenHandleCount != 1) { @@ -1208,6 +1218,8 @@ VfatLockOrUnlockVolume( } } + FsRtlNotifyVolumeEvent(IrpContext->Stack->FileObject, FSRTL_VOLUME_LOCK_FAILED); + return STATUS_ACCESS_DENIED; #if 1 @@ -1225,6 +1237,18 @@ VfatLockOrUnlockVolume( /* Finally, proceed */ if (Lock) { + /* Flush volume & files */ + VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); + + /* The volume is now clean */ + if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY) && + BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY)) + { + /* Drop the dirty bit */ + if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE))) + ClearFlag(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY); + } + DeviceExt->Flags |= VCB_VOLUME_LOCKED; Vpb->Flags |= VPB_LOCKED; } @@ -1232,6 +1256,8 @@ VfatLockOrUnlockVolume( { DeviceExt->Flags &= ~VCB_VOLUME_LOCKED; Vpb->Flags &= ~VPB_LOCKED; + + FsRtlNotifyVolumeEvent(IrpContext->Stack->FileObject, FSRTL_VOLUME_UNLOCK); } return STATUS_SUCCESS; @@ -1277,25 +1303,35 @@ VfatDismountVolume( ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE); - /* We're performing a clean shutdown */ - if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY)) + /* Flush volume & files */ + VfatFlushVolume(DeviceExt, (PVFATFCB)FileObject->FsContext); + + /* The volume is now clean */ + if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY) && + BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY)) { /* Drop the dirty bit */ if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE))) DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY; } - /* Flush volume & files */ - VfatFlushVolume(DeviceExt, (PVFATFCB)FileObject->FsContext); - /* Rebrowse the FCB in order to free them now */ while (!IsListEmpty(&DeviceExt->FcbListHead)) { NextEntry = RemoveTailList(&DeviceExt->FcbListHead); Fcb = CONTAINING_RECORD(NextEntry, VFATFCB, FcbListEntry); + + if (Fcb == DeviceExt->RootFcb) + DeviceExt->RootFcb = NULL; + else if (Fcb == DeviceExt->VolumeFcb) + DeviceExt->VolumeFcb = NULL; + vfatDestroyFCB(Fcb); } + /* We are uninitializing, the VCB cannot be used anymore */ + ClearFlag(DeviceExt->Flags, VCB_GOOD); + /* Mark we're being dismounted */ DeviceExt->Flags |= VCB_DISMOUNT_PENDING; #ifndef ENABLE_SWAPOUT @@ -1304,12 +1340,6 @@ VfatDismountVolume( ExReleaseResourceLite(&DeviceExt->FatResource); - /* Release a few resources and quit, we're done */ - ExFreePoolWithTag(DeviceExt->Statistics, TAG_STATS); - ExDeleteResourceLite(&DeviceExt->DirResource); - ExDeleteResourceLite(&DeviceExt->FatResource); - ObDereferenceObject(DeviceExt->FATFileObject); - return STATUS_SUCCESS; } diff --git a/drivers/filesystems/fastfat/misc.c b/drivers/filesystems/fastfat/misc.c index ad5f4bcec3e..2068e8b5e43 100644 --- a/drivers/filesystems/fastfat/misc.c +++ b/drivers/filesystems/fastfat/misc.c @@ -416,23 +416,43 @@ VfatLockUserBuffer( BOOLEAN VfatCheckForDismount( IN PDEVICE_EXTENSION DeviceExt, - IN BOOLEAN Create) + IN BOOLEAN Force) { KIRQL OldIrql; + ULONG UnCleanCount; PVPB Vpb; BOOLEAN Delete; - DPRINT1("VfatCheckForDismount(%p, %u)\n", DeviceExt, Create); + DPRINT1("VfatCheckForDismount(%p, %u)\n", DeviceExt, Force); + + /* If the VCB is OK (not under uninitialization) and we don't force dismount, do nothing */ + if (BooleanFlagOn(DeviceExt->Flags, VCB_GOOD) && !Force) + { + return FALSE; + } + + /* + * NOTE: In their *CheckForDismount() function, our 3rd-party FS drivers + * as well as MS' fastfat, perform a comparison check of the current VCB's + * VPB ReferenceCount with some sort of "dangling"/"residual" open count, + * depending on whether or not we are in IRP_MJ_CREATE. + * It seems to be related to the fact that the volume root directory as + * well as auxiliary data stream(s) are still opened, and only these are + * allowed to be opened at that moment. After analysis it appears that for + * the ReactOS' fastfat, this number is equal to "3". + */ + UnCleanCount = 3; /* Lock VPB */ IoAcquireVpbSpinLock(&OldIrql); /* Reference it and check if a create is being done */ Vpb = DeviceExt->IoVPB; - if (Vpb->ReferenceCount != Create) + DPRINT("Vpb->ReferenceCount = %d\n", Vpb->ReferenceCount); + if (Vpb->ReferenceCount != UnCleanCount || DeviceExt->OpenHandleCount != 0) { - /* Copy the VPB to our local own to prepare later dismount */ - if (DeviceExt->SpareVPB != NULL) + /* If we force-unmount, copy the VPB to our local own to prepare later dismount */ + if (Force && Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL) { RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB)); DeviceExt->SpareVPB->Type = IO_TYPE_VPB; @@ -443,9 +463,12 @@ VfatCheckForDismount( DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB; DeviceExt->SpareVPB = NULL; DeviceExt->IoVPB->Flags |= VPB_PERSISTENT; + + /* We are uninitializing, the VCB cannot be used anymore */ + ClearFlag(DeviceExt->Flags, VCB_GOOD); } - /* Don't do anything */ + /* Don't do anything for now */ Delete = FALSE; } else @@ -453,12 +476,30 @@ VfatCheckForDismount( /* Otherwise, delete the volume */ Delete = TRUE; - /* Check if it has a VPB and unmount it */ - if (Vpb->RealDevice->Vpb == Vpb) + /* Swap the VPB with our local own */ + if (Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL) { - Vpb->DeviceObject = NULL; - Vpb->Flags &= ~VPB_MOUNTED; + RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB)); + DeviceExt->SpareVPB->Type = IO_TYPE_VPB; + DeviceExt->SpareVPB->Size = sizeof(VPB); + DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice; + DeviceExt->SpareVPB->DeviceObject = NULL; + DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & VPB_REMOVE_PENDING; + DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB; + DeviceExt->SpareVPB = NULL; + DeviceExt->IoVPB->Flags |= VPB_PERSISTENT; + + /* We are uninitializing, the VCB cannot be used anymore */ + ClearFlag(DeviceExt->Flags, VCB_GOOD); } + + /* + * We defer setting the VPB's DeviceObject to NULL for later because + * we want to handle the closing of the internal opened meta-files. + */ + + /* Clear the mounted and locked flags in the VPB */ + ClearFlag(Vpb->Flags, VPB_MOUNTED | VPB_LOCKED); } /* Release lock and return status */ @@ -467,34 +508,82 @@ VfatCheckForDismount( /* If we were to delete, delete volume */ if (Delete) { - PVPB DelVpb; + LARGE_INTEGER Zero = {{0,0}}; + PVFATFCB Fcb; + + /* We are uninitializing, the VCB cannot be used anymore */ + ClearFlag(DeviceExt->Flags, VCB_GOOD); + + /* Invalidate and close the internal opened meta-files */ + if (DeviceExt->RootFcb) + { + Fcb = DeviceExt->RootFcb; + CcUninitializeCacheMap(Fcb->FileObject, + &Zero, + NULL); + ObDereferenceObject(Fcb->FileObject); + DeviceExt->RootFcb = NULL; + vfatDestroyFCB(Fcb); + } + if (DeviceExt->VolumeFcb) + { + Fcb = DeviceExt->VolumeFcb; +#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT + CcUninitializeCacheMap(Fcb->FileObject, + &Zero, + NULL); + ObDereferenceObject(Fcb->FileObject); +#endif + DeviceExt->VolumeFcb = NULL; + vfatDestroyFCB(Fcb); + } + if (DeviceExt->FATFileObject) + { + Fcb = (PVFATFCB)DeviceExt->FATFileObject->FsContext; + CcUninitializeCacheMap(DeviceExt->FATFileObject, + &Zero, + NULL); + ObDereferenceObject(DeviceExt->FATFileObject); + DeviceExt->FATFileObject->FsContext = NULL; + DeviceExt->FATFileObject = NULL; + vfatDestroyFCB(Fcb); + } + + /* + * Now that the closing of the internal opened meta-files has been + * handled, we can now set the VPB's DeviceObject to NULL. + */ + Vpb->DeviceObject = NULL; /* If we have a local VPB, we'll have to delete it * but we won't dismount us - something went bad before */ if (DeviceExt->SpareVPB) { - DelVpb = DeviceExt->SpareVPB; + ExFreePool(DeviceExt->SpareVPB); } - /* Otherwise, dismount our device if possible */ - else + /* Otherwise, delete any of the available VPB if its reference count is zero */ + else if (DeviceExt->IoVPB->ReferenceCount == 0) { - if (DeviceExt->IoVPB->ReferenceCount) - { - ObfDereferenceObject(DeviceExt->StorageDevice); - IoDeleteDevice(DeviceExt->VolumeDevice); - return Delete; - } - - DelVpb = DeviceExt->IoVPB; + ExFreePool(DeviceExt->IoVPB); } - /* Delete any of the available VPB and dismount */ - ExFreePool(DelVpb); + /* Remove the volume from the list */ + ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE); + RemoveEntryList(&DeviceExt->VolumeListEntry); + ExReleaseResourceLite(&VfatGlobalData->VolumeListLock); + + /* Uninitialize the notify synchronization object */ + FsRtlNotifyUninitializeSync(&DeviceExt->NotifySync); + + /* Release resources */ + ExFreePoolWithTag(DeviceExt->Statistics, TAG_STATS); + ExDeleteResourceLite(&DeviceExt->DirResource); + ExDeleteResourceLite(&DeviceExt->FatResource); + + /* Dismount our device if possible */ ObfDereferenceObject(DeviceExt->StorageDevice); IoDeleteDevice(DeviceExt->VolumeDevice); - - return Delete; } return Delete; diff --git a/drivers/filesystems/fastfat/shutdown.c b/drivers/filesystems/fastfat/shutdown.c index c9e2bd5431d..8e367453357 100644 --- a/drivers/filesystems/fastfat/shutdown.c +++ b/drivers/filesystems/fastfat/shutdown.c @@ -74,15 +74,19 @@ VfatShutdown( ListEntry = ListEntry->Flink; ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE); - /* It was a clean volume mounted */ - if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY) + + /* Flush volume & files */ + Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); + + /* We're performing a clean shutdown */ + if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY) && + BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY)) { - /* So, drop the dirty bit we set */ + /* Drop the dirty bit */ if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE))) DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY; } - Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); if (NT_SUCCESS(Status)) { Status = VfatDiskShutDown(DeviceExt); @@ -97,7 +101,10 @@ VfatShutdown( } ExReleaseResourceLite(&DeviceExt->DirResource); - /* FIXME: Unmount the logical volume */ + /* Unmount the logical volume */ +#ifdef ENABLE_SWAPOUT + VfatCheckForDismount(DeviceExt, FALSE); +#endif if (!NT_SUCCESS(Status)) Irp->IoStatus.Status = Status; diff --git a/drivers/filesystems/fastfat/vfat.h b/drivers/filesystems/fastfat/vfat.h index e6c7c73e1d5..77b2998dade 100644 --- a/drivers/filesystems/fastfat/vfat.h +++ b/drivers/filesystems/fastfat/vfat.h @@ -16,12 +16,16 @@ #define INIT_SECTION /* Done via alloc_text for MSC */ #endif + #define USE_ROS_CC_AND_FS -#if 0 -#ifndef _MSC_VER #define ENABLE_SWAPOUT -#endif -#endif + +/* FIXME: because volume is not cached, we have to perform direct IOs + * The day this is fixed, just comment out that line, and check + * it still works (and delete old code ;-)) + */ +#define VOLUME_IS_NOT_CACHED_WORK_AROUND_IT + #define ROUND_DOWN(n, align) \ (((ULONG)n) & ~((align) - 1l)) @@ -244,6 +248,8 @@ typedef union _DIR_ENTRY DIR_ENTRY, *PDIR_ENTRY; #define VCB_IS_SYS_OR_HAS_PAGE 0x0008 #define VCB_IS_DIRTY 0x4000 /* Volume is dirty */ #define VCB_CLEAR_DIRTY 0x8000 /* Clean dirty flag at shutdown */ +/* VCB condition state */ +#define VCB_GOOD 0x0010 /* If not set, the VCB is improper for usage */ typedef struct { @@ -326,6 +332,7 @@ typedef struct DEVICE_EXTENSION BOOLEAN AvailableClustersValid; ULONG Flags; struct _VFATFCB *VolumeFcb; + struct _VFATFCB *RootFcb; PSTATISTICS Statistics; /* Pointers to functions for manipulating FAT. */