https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cbaa8e7dfb941f8038ff5…
commit cbaa8e7dfb941f8038ff50eeca516696af8268bd
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Nov 11 21:27:30 2018 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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;