From 965149e8dba5da1628282d277f660b4e0b8829b6 Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Sun, 9 Feb 2003 18:02:56 +0000 Subject: [PATCH] Implemented IRP_MJ_FLUSH_BUFFERS. Added cache flushing at shutdown. svn path=/trunk/; revision=4123 --- reactos/drivers/fs/vfat/flush.c | 119 +++++++++++++++++++++++++++++ reactos/drivers/fs/vfat/fsctl.c | 8 +- reactos/drivers/fs/vfat/iface.c | 6 +- reactos/drivers/fs/vfat/makefile | 5 +- reactos/drivers/fs/vfat/misc.c | 4 +- reactos/drivers/fs/vfat/shutdown.c | 46 +++++++---- reactos/drivers/fs/vfat/vfat.h | 12 ++- 7 files changed, 177 insertions(+), 23 deletions(-) create mode 100644 reactos/drivers/fs/vfat/flush.c diff --git a/reactos/drivers/fs/vfat/flush.c b/reactos/drivers/fs/vfat/flush.c new file mode 100644 index 00000000000..f3878b46014 --- /dev/null +++ b/reactos/drivers/fs/vfat/flush.c @@ -0,0 +1,119 @@ +/* $Id: flush.c,v 1.1 2003/02/09 18:02:55 hbirr Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: drivers/fs/vfat/flush.c + * PURPOSE: VFAT Filesystem + * PROGRAMMER: Hartmut Birr + */ + +/* INCLUDES *****************************************************************/ + +#include +#include "vfat.h" + +#define NDEBUG +#include + +/* FUNCTIONS ****************************************************************/ + +NTSTATUS VfatFlushFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb) +{ + IO_STATUS_BLOCK IoStatus; + + DPRINT("VfatFlushFile(DeviceExt %x, Fcb %x) for '%S'\n", DeviceExt, Fcb, Fcb->PathName); + + CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus); + if (IoStatus.Status == STATUS_INVALID_PARAMETER) + { + /* FIXME: Caching was possible not initialized */ + IoStatus.Status = STATUS_SUCCESS; + } + return IoStatus.Status; +} + +NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb) +{ + PLIST_ENTRY ListEntry; + PVFATFCB Fcb; + PVFATCCB Ccb; + NTSTATUS Status, ReturnStatus = STATUS_SUCCESS; + + DPRINT("VfatFlushVolume(DeviceExt %x, FatFcb %x)\n", DeviceExt, VolumeFcb); + + ListEntry = DeviceExt->FcbListHead.Flink; + while (ListEntry != &DeviceExt->FcbListHead) + { + Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry); + ListEntry = ListEntry->Flink; + ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE); + Status = VfatFlushFile(DeviceExt, Fcb); + ExReleaseResourceLite (&Fcb->MainResource); + if (!NT_SUCCESS(Status)) + { + DPRINT1("VfatFlushFile failed, status = %x\n", Status); + ReturnStatus = Status; + } + /* FIXME: Stop flushing if this a removable media and the media was removed */ + } + + Ccb = (PVFATCCB) DeviceExt->FATFileObject->FsContext2; + Fcb = Ccb->pFcb; + + ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE); + Status = VfatFlushFile(DeviceExt, Fcb); + ExReleaseResourceLite(&DeviceExt->FatResource); + + /* FIXME: Flush the buffers from storage device */ + + if (!NT_SUCCESS(Status)) + { + DPRINT1("VfatFlushFile failed, status = %x\n", Status); + ReturnStatus = Status; + } + + return ReturnStatus; +} + +NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext) +{ + NTSTATUS Status; + PVFATFCB Fcb; + PVFATCCB Ccb; + /* + * This request is not allowed on the main device object. + */ + if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) + { + Status = STATUS_INVALID_DEVICE_REQUEST; + goto ByeBye; + } + + Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2; + assert(Ccb); + Fcb = Ccb->pFcb; + assert(Fcb); + + if (Fcb->Flags & FCB_IS_VOLUME) + { + ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE); + Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb); + ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource); + } + else + { + ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE); + Status = VfatFlushFile(IrpContext->DeviceExt, Fcb); + ExReleaseResourceLite (&Fcb->MainResource); + } + +ByeBye: + IrpContext->Irp->IoStatus.Status = Status; + IrpContext->Irp->IoStatus.Information = 0; + IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); + + return (Status); +} + +/* EOF */ diff --git a/reactos/drivers/fs/vfat/fsctl.c b/reactos/drivers/fs/vfat/fsctl.c index 6039fa04a34..21376e6cf76 100644 --- a/reactos/drivers/fs/vfat/fsctl.c +++ b/reactos/drivers/fs/vfat/fsctl.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: fsctl.c,v 1.12 2002/11/11 21:49:18 hbirr Exp $ +/* $Id: fsctl.c,v 1.13 2003/02/09 18:02:55 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -330,7 +330,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext) DbgPrint ("CcRosInitializeFileCache failed\n"); goto ByeBye; } - DeviceExt->LastAvailableCluster = 0; + DeviceExt->LastAvailableCluster = 2; ExInitializeResourceLite(&DeviceExt->DirResource); ExInitializeResourceLite(&DeviceExt->FatResource); @@ -352,6 +352,10 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext) VolumeFcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice; DeviceExt->VolumeFcb = VolumeFcb; + ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE); + InsertHeadList(&VfatGlobalData->VolumeListHead, &DeviceExt->VolumeListEntry); + ExReleaseResourceLite(&VfatGlobalData->VolumeListLock); + /* read serial number */ DeviceObject->Vpb->SerialNumber = DeviceExt->FatInfo.VolumeID; diff --git a/reactos/drivers/fs/vfat/iface.c b/reactos/drivers/fs/vfat/iface.c index 4a613dc6b1c..23a58d4f178 100644 --- a/reactos/drivers/fs/vfat/iface.c +++ b/reactos/drivers/fs/vfat/iface.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: iface.c,v 1.67 2003/01/25 15:55:07 hbirr Exp $ +/* $Id: iface.c,v 1.68 2003/02/09 18:02:55 hbirr Exp $ * * PROJECT: ReactOS kernel * FILE: services/fs/vfat/iface.c @@ -86,6 +86,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest; + DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = VfatBuildRequest; DriverObject->DriverUnload = NULL; @@ -95,6 +96,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject, NULL, NULL, 0, sizeof(VFATCCB), TAG_CCB, 0); ExInitializeNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, NULL, NULL, 0, sizeof(VFAT_IRP_CONTEXT), TAG_IRP, 0); + + ExInitializeResourceLite(&VfatGlobalData->VolumeListLock); + InitializeListHead(&VfatGlobalData->VolumeListHead); IoRegisterFileSystem(DeviceObject); return(STATUS_SUCCESS); } diff --git a/reactos/drivers/fs/vfat/makefile b/reactos/drivers/fs/vfat/makefile index 951fa775188..e0bff303635 100644 --- a/reactos/drivers/fs/vfat/makefile +++ b/reactos/drivers/fs/vfat/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.40 2002/08/14 20:58:31 dwelch Exp $ +# $Id: makefile,v 1.41 2003/02/09 18:02:56 hbirr Exp $ PATH_TO_TOP = ../../.. @@ -26,7 +26,8 @@ TARGET_OBJECTS = \ volume.o \ misc.o \ fsctl.o \ - ea.o + ea.o \ + flush.o DEP_OBJECTS = $(TARGET_OBJECTS) diff --git a/reactos/drivers/fs/vfat/misc.c b/reactos/drivers/fs/vfat/misc.c index f5694e4f6cc..ed45fb8e08a 100644 --- a/reactos/drivers/fs/vfat/misc.c +++ b/reactos/drivers/fs/vfat/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.5 2003/01/25 15:55:07 hbirr Exp $ +/* $Id: misc.c,v 1.6 2003/02/09 18:02:55 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -55,6 +55,8 @@ NTSTATUS VfatDispatchRequest ( return VfatLockControl(IrpContext); case IRP_MJ_CLEANUP: return VfatCleanup(IrpContext); + case IRP_MJ_FLUSH_BUFFERS: + return VfatFlush(IrpContext); default: DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction); IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR; diff --git a/reactos/drivers/fs/vfat/shutdown.c b/reactos/drivers/fs/vfat/shutdown.c index c5612ab3a22..853f0649a84 100644 --- a/reactos/drivers/fs/vfat/shutdown.c +++ b/reactos/drivers/fs/vfat/shutdown.c @@ -1,4 +1,4 @@ -/* $Id: shutdown.c,v 1.4 2001/05/01 23:08:21 chorns Exp $ +/* $Id: shutdown.c,v 1.5 2003/02/09 18:02:55 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -22,29 +22,43 @@ NTSTATUS STDCALL VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp) { NTSTATUS Status; + PLIST_ENTRY ListEntry; + PDEVICE_EXTENSION DeviceExt; DPRINT("VfatShutdown(DeviceObject %x, Irp %x)\n",DeviceObject, Irp); -#if 0 /* FIXME: block new mount requests */ + if (DeviceObject == VfatGlobalData->DeviceObject) + { + Irp->IoStatus.Status = STATUS_SUCCESS; + ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE); + ListEntry = VfatGlobalData->VolumeListHead.Flink; + while (ListEntry != &VfatGlobalData->VolumeListHead) + { + DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry); + ListEntry = ListEntry->Flink; - /* FIXME: Traverse list of logical volumes. For each volume: */ - { - /* FIXME: acquire vcb resource exclusively */ + ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE); + Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); + ExReleaseResourceLite(&DeviceExt->DirResource); + if (!NT_SUCCESS(Status)) + { + DPRINT1("VfatFlushVolume failed, status = %x\n", Status); + Irp->IoStatus.Status = Status; + } + /* FIXME: Unmount the logical volume */ - /* FIXME: Flush logical volume */ + ExReleaseResourceLite(&VfatGlobalData->VolumeListLock); + } + /* FIXME: Free all global acquired resources */ - /* FIXME: send IRP_MJ_SHUTDOWN to each volume */ - - /* FIXME: wait for completion of IRP_MJ_SHUTDOWN */ - - /* FIXME: release vcb resource */ - } - -#endif - - Status = STATUS_SUCCESS; + Status = Irp->IoStatus.Status; + } + else + { + Status = STATUS_INVALID_DEVICE_REQUEST; + } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; diff --git a/reactos/drivers/fs/vfat/vfat.h b/reactos/drivers/fs/vfat/vfat.h index 2d6dbd5b52a..a550de33119 100644 --- a/reactos/drivers/fs/vfat/vfat.h +++ b/reactos/drivers/fs/vfat/vfat.h @@ -1,4 +1,4 @@ -/* $Id: vfat.h,v 1.54 2003/01/31 15:55:18 ekohl Exp $ */ +/* $Id: vfat.h,v 1.55 2003/02/09 18:02:55 hbirr Exp $ */ #include @@ -155,6 +155,8 @@ typedef struct ULONG Flags; struct _VFATFCB * VolumeFcb; struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE]; + + LIST_ENTRY VolumeListEntry; } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB; typedef struct @@ -162,6 +164,8 @@ typedef struct PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT DeviceObject; ULONG Flags; + ERESOURCE VolumeListLock; + LIST_ENTRY VolumeListHead; NPAGED_LOOKASIDE_LIST FcbLookasideList; NPAGED_LOOKASIDE_LIST CcbLookasideList; NPAGED_LOOKASIDE_LIST IrpContextLookasideList; @@ -509,4 +513,10 @@ NTSTATUS VfatSetExtendedAttributes(PFILE_OBJECT FileObject, PVOID Ea, ULONG EaLength); +/* ------------------------------------------------------------- flush.c */ + +NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext); + +NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb); + /* EOF */