mirror of
https://github.com/reactos/reactos.git
synced 2025-05-18 00:31:27 +00:00

Until now, our support for dirty volumes was totally broken to a point where, on FAT32 volume, the dirty couldn't even be written nor read from the disk. This commit totally rewrites its handling, for both FAT16 and FAT32 so that it's now fully functionnal. Furthermore, it also gets totally compatible with our vfatlib, and thus, autochk. Now, on mount, FastFAT will check if the volume is dirty or not, and autochk will be able to ask for a repair if dirty. vfatlib will repair the volume and remove the dirty bit. So that, on next reboot, the volume will be mounted clean. As a reminder, the dirty bit is set immediately after mounting the volume, so that, if you crash or have a powercut, autochk will always attempt to repair your volume (with more or less, that's FAT!). If you want to experience without breaking your FAT volume, just boot, open a cmd prompt and type: fsutil dirty set c: and reboot! CORE-13758 CORE-13760 CORE-13759
124 lines
3.3 KiB
C
124 lines
3.3 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* FILE: drivers/fs/vfat/shutdown.c
|
|
* PURPOSE: VFAT Filesystem
|
|
* PROGRAMMER: Eric Kohl
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include "vfat.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
static
|
|
NTSTATUS
|
|
VfatDiskShutDown(
|
|
PVCB Vcb)
|
|
{
|
|
PIRP Irp;
|
|
KEVENT Event;
|
|
NTSTATUS Status;
|
|
IO_STATUS_BLOCK IoStatus;
|
|
|
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, Vcb->StorageDevice,
|
|
NULL, 0, NULL, &Event, &IoStatus);
|
|
if (Irp)
|
|
{
|
|
Status = IoCallDriver(Vcb->StorageDevice, Irp);
|
|
if (Status == STATUS_PENDING)
|
|
{
|
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
Status = IoStatus.Status;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
VfatShutdown(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
NTSTATUS Status;
|
|
PLIST_ENTRY ListEntry;
|
|
PDEVICE_EXTENSION DeviceExt;
|
|
|
|
DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp);
|
|
|
|
FsRtlEnterFileSystem();
|
|
|
|
/* 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;
|
|
|
|
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
|
|
/* It was a clean volume mounted */
|
|
if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
|
|
{
|
|
/* So, drop the dirty bit we set */
|
|
if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE)))
|
|
DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
|
|
}
|
|
|
|
Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
Status = VfatDiskShutDown(DeviceExt);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
|
|
}
|
|
ExReleaseResourceLite(&DeviceExt->DirResource);
|
|
|
|
/* FIXME: Unmount the logical volume */
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
Irp->IoStatus.Status = Status;
|
|
}
|
|
ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
|
|
|
|
/* FIXME: Free all global acquired resources */
|
|
|
|
Status = Irp->IoStatus.Status;
|
|
}
|
|
else
|
|
{
|
|
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
}
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
FsRtlExitFileSystem();
|
|
|
|
return Status;
|
|
}
|
|
|
|
/* EOF */
|