Implemented IRP_MJ_FLUSH_BUFFERS.

Added cache flushing at shutdown.

svn path=/trunk/; revision=4123
This commit is contained in:
Hartmut Birr 2003-02-09 18:02:56 +00:00
parent 8a23cc7a5b
commit 965149e8db
7 changed files with 177 additions and 23 deletions

View file

@ -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 <ddk/ntddk.h>
#include "vfat.h"
#define NDEBUG
#include <debug.h>
/* 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 */

View file

@ -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;

View file

@ -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);
}

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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 <ddk/ntifs.h>
@ -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 */