https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cbaa8e7dfb941f8038ff50...
commit cbaa8e7dfb941f8038ff50eeca516696af8268bd Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Sun Nov 11 21:27:30 2018 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Sun Nov 11 21:56:18 2018 +0100
[NTOS:IO] RAW-FS: Few improvements.
- Simplify the volume-deletion code in RawCheckForDismount().
- Fixes the OpenCount check in RawClose(): the VCB mutex must be released when the volume has not been dismounted, either because OpenCount != 0 or because RawCheckForDismount() returned FALSE.
- Explicitly use VCB_STATE_LOCKED instead of hardcoding its value.
- In IRP_MN_VERIFY_VOLUME handling, lock the volume before playing with it, and again let the volume be dismounted only if OpenCount == 0 (and the IoDeleteDevice() call is done by RawCheckForDismount()). --- ntoskrnl/io/iomgr/rawfs.c | 57 ++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 33 deletions(-)
diff --git a/ntoskrnl/io/iomgr/rawfs.c b/ntoskrnl/io/iomgr/rawfs.c index d08bb22f49..569be1a1bf 100644 --- a/ntoskrnl/io/iomgr/rawfs.c +++ b/ntoskrnl/io/iomgr/rawfs.c @@ -131,41 +131,27 @@ RawCheckForDismount(IN PVCB Vcb, /* If we were to delete, delete the volume */ if (Delete) { - PVPB DelVpb; - /* Release our Vcb lock to be able delete us */ - KeReleaseMutex(&Vcb->Mutex, 0); + KeReleaseMutex(&Vcb->Mutex, FALSE);
/* If we have a local VPB, we'll have to delete it * but we won't dismount us - something went bad before */ if (Vcb->LocalVpb) { - DelVpb = Vcb->LocalVpb; + ExFreePool(Vcb->LocalVpb); } - /* Otherwise, dismount our device if possible */ - else + /* Otherwise, delete any of the available VPB if its reference count is zero */ + else if (Vcb->Vpb->ReferenceCount == 0) { - if (Vcb->Vpb->ReferenceCount) - { - ObfDereferenceObject(Vcb->TargetDeviceObject); - IoDeleteDevice((PDEVICE_OBJECT)CONTAINING_RECORD(Vcb, - VOLUME_DEVICE_OBJECT, - Vcb)); - return Delete; - } - - DelVpb = Vcb->Vpb; + ExFreePool(Vcb->Vpb); }
- /* Delete any of the available VPB and dismount */ - ExFreePool(DelVpb); + /* Dismount our device if possible */ ObfDereferenceObject(Vcb->TargetDeviceObject); IoDeleteDevice((PDEVICE_OBJECT)CONTAINING_RECORD(Vcb, VOLUME_DEVICE_OBJECT, Vcb)); - - return Delete; }
return Delete; @@ -227,7 +213,7 @@ RawClose(IN PVCB Vcb,
/* Decrease the open count and check if this is a dismount */ Vcb->OpenCount--; - if (!Vcb->OpenCount || !RawCheckForDismount(Vcb, FALSE)) + if (Vcb->OpenCount != 0 || !RawCheckForDismount(Vcb, FALSE)) { KeReleaseMutex(&Vcb->Mutex, FALSE); } @@ -509,10 +495,10 @@ RawUserFsCtrl(IN PIO_STACK_LOCATION IoStackLocation, case FSCTL_LOCK_VOLUME:
/* Make sure we're not locked, and that we're alone */ - if (!(Vcb->VcbState & 1) && (Vcb->OpenCount == 1)) + if (!(Vcb->VcbState & VCB_STATE_LOCKED) && (Vcb->OpenCount == 1)) { /* Lock the VCB */ - Vcb->VcbState |= 1; + Vcb->VcbState |= VCB_STATE_LOCKED; Status = STATUS_SUCCESS; } else @@ -526,7 +512,7 @@ RawUserFsCtrl(IN PIO_STACK_LOCATION IoStackLocation, case FSCTL_UNLOCK_VOLUME:
/* Make sure we're locked */ - if (!(Vcb->VcbState & 1)) + if (!(Vcb->VcbState & VCB_STATE_LOCKED)) { /* Let caller know we're not */ Status = STATUS_NOT_LOCKED; @@ -534,7 +520,7 @@ RawUserFsCtrl(IN PIO_STACK_LOCATION IoStackLocation, else { /* Unlock the VCB */ - Vcb->VcbState &= ~1; + Vcb->VcbState &= ~VCB_STATE_LOCKED; Status = STATUS_SUCCESS; } break; @@ -543,7 +529,7 @@ RawUserFsCtrl(IN PIO_STACK_LOCATION IoStackLocation, case FSCTL_DISMOUNT_VOLUME:
/* Make sure we're locked */ - if (Vcb->VcbState & 1) + if (Vcb->VcbState & VCB_STATE_LOCKED) { /* Do nothing, just return success */ Status = STATUS_SUCCESS; @@ -616,18 +602,23 @@ RawFileSystemControl(IN PVCB Vcb,
case IRP_MN_VERIFY_VOLUME:
+ /* Lock the device */ + Status = KeWaitForSingleObject(&Vcb->Mutex, + Executive, + KernelMode, + FALSE, + NULL); + ASSERT(NT_SUCCESS(Status)); + /* We don't do verifies */ Status = STATUS_WRONG_VOLUME; Vcb->Vpb->RealDevice->Flags &= ~DO_VERIFY_VOLUME;
/* Check if we should delete the device */ - if (RawCheckForDismount(Vcb, FALSE)) + if (Vcb->OpenCount != 0 || !RawCheckForDismount(Vcb, FALSE)) { - /* Do it */ - IoDeleteDevice((PDEVICE_OBJECT) - CONTAINING_RECORD(Vcb, - VOLUME_DEVICE_OBJECT, - Vcb)); + /* In case of deletion, the mutex is already released */ + KeReleaseMutex(&Vcb->Mutex, FALSE); }
/* We're done */ @@ -752,7 +743,7 @@ RawQueryFsVolumeInfo(IN PVCB Vcb, DPRINT("RawQueryFsVolumeInfo(%p, %p, %p)\n", Vcb, Buffer, Length);
/* Clear the buffer and stub it out */ - RtlZeroMemory( Buffer, sizeof(FILE_FS_VOLUME_INFORMATION)); + RtlZeroMemory(Buffer, sizeof(FILE_FS_VOLUME_INFORMATION)); Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber; Buffer->SupportsObjects = FALSE; Buffer->VolumeLabelLength = 0;