Author: ion
Date: Sun Jul 2 09:52:47 2006
New Revision: 22763
URL:
http://svn.reactos.org/svn/reactos?rev=22763&view=rev
Log:
- Improve list looping to remove gotos.
- Dereference the device object in case of failure.
- Add some optimizations to quickly skip invalid raw mounting.
- Add support for VPB_RAW_MOUNT.
- Allow raw mount if this is the only device on the list.
- Make the success case go through shared exit, otherwise the device wasn't getting
unlocked previously.
Modified:
trunk/reactos/ntoskrnl/io/iomgr/volume.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/volume.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/volume.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/volume.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/volume.c Sun Jul 2 09:52:47 2006
@@ -347,8 +347,31 @@
/* Now loop the fs list until one of the file systems accepts us */
Status = STATUS_UNSUCCESSFUL;
ListEntry = FsList->Flink;
- while (ListEntry != FsList)
- {
+ while ((ListEntry != FsList) && !(NT_SUCCESS(Status)))
+ {
+ /*
+ * If we're not allowed to mount this volume and this is our last
+ * (but not only) chance to mount it...
+ */
+ if (!(AllowRawMount) &&
+ (ListEntry->Flink == FsList) &&
+ (ListEntry != FsList->Flink))
+ {
+ /* Then fail this mount request */
+ break;
+ }
+
+ /*
+ * Also check if this is a raw mount and there are other file
+ * systems on the list.
+ */
+ if ((DeviceObject->Vpb->Flags & VPB_RAW_MOUNT) &&
+ (ListEntry->Flink != FsList))
+ {
+ /* Then skip this entry */
+ continue;
+ }
+
/* Get the Device Object for this FS */
FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
DEVICE_OBJECT,
@@ -368,56 +391,47 @@
FsStackOverhead++;
}
- /* If we are not allowed to mount this volume as a raw filesystem volume
- then don't try this */
- if (!AllowRawMount &&
RawFsIsRawFileSystemDeviceObject(FileSystemDeviceObject))
+ /* Clear the event */
+ KeClearEvent(&Event);
+
+ /* Allocate the IRP */
+ Irp = IoAllocateIrp(AttachedDeviceObject->StackSize +
+ FsStackOverhead,
+ TRUE);
+ if (!Irp)
{
- Status = STATUS_UNRECOGNIZED_VOLUME;
+ /* Fail */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
}
- else
+
+ /* Setup the IRP */
+ Irp->UserIosb = &IoStatusBlock;
+ Irp->UserEvent = &Event;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ Irp->Flags = IRP_MOUNT_COMPLETION | IRP_SYNCHRONOUS_PAGING_IO;
+ Irp->RequestorMode = KernelMode;
+
+ /* Get the I/O Stack location and set it up */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
+ StackPtr->MinorFunction = IRP_MN_MOUNT_VOLUME;
+ StackPtr->Flags = AllowRawMount;
+ StackPtr->Parameters.MountVolume.Vpb = DeviceObject->Vpb;
+ StackPtr->Parameters.MountVolume.DeviceObject =
+ AttachedDeviceObject;
+
+ /* Call the driver */
+ Status = IoCallDriver(FileSystemDeviceObject, Irp);
+ if (Status == STATUS_PENDING)
{
- /* Clear the event */
- KeClearEvent(&Event);
-
- /* Allocate the IRP */
- Irp = IoAllocateIrp(AttachedDeviceObject->StackSize +
- FsStackOverhead,
- TRUE);
- if (!Irp)
- {
- /* Fail */
- Status = STATUS_INSUFFICIENT_RESOURCES;
- break;
- }
-
- /* Setup the IRP */
- Irp->UserIosb = &IoStatusBlock;
- Irp->UserEvent = &Event;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- Irp->Flags = IRP_MOUNT_COMPLETION | IRP_SYNCHRONOUS_PAGING_IO;
- Irp->RequestorMode = KernelMode;
-
- /* Get the I/O Stack location and set it up */
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
- StackPtr->MinorFunction = IRP_MN_MOUNT_VOLUME;
- StackPtr->Flags = AllowRawMount;
- StackPtr->Parameters.MountVolume.Vpb = DeviceObject->Vpb;
- StackPtr->Parameters.MountVolume.DeviceObject =
- AttachedDeviceObject;
-
- /* Call the driver */
- Status = IoCallDriver(FileSystemDeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- /* Wait on it */
- KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- Status = IoStatusBlock.Status;
- }
+ /* Wait on it */
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock.Status;
}
switch (Status)
@@ -435,9 +449,6 @@
case STATUS_SUCCESS:
DeviceObject->Vpb->Flags = DeviceObject->Vpb->Flags |
VPB_MOUNTED;
- ExReleaseResourceLite(&FileSystemListLock);
- KeLeaveCriticalRegion();
- return(STATUS_SUCCESS);
case STATUS_UNRECOGNIZED_VOLUME:
default:
@@ -445,8 +456,12 @@
break;
}
+ /* Go to the next FS entry */
ListEntry = ListEntry->Flink;
}
+
+ /* Dereference the device if we failed */
+ if (!NT_SUCCESS(Status)) ObDereferenceObject(AttachedDeviceObject);
}
else if (DeviceObject->Vpb->Flags & VPB_REMOVE_PENDING)
{