Author: ion
Date: Sun Jul 2 10:28:29 2006
New Revision: 22767
URL: http://svn.reactos.org/svn/reactos?rev=22767&view=rev
Log:
- Move IoGetBaseFileSystemDeviceObject to device.c and make it check for FO_DIRECT_DEVICE_OPEN, which it wasn't before (and also code it in a less confusing way like the other IoGetXxxDeviceObject APIs)
- Mask out the DO_VERIFY_VOLUME flag when mounting a device.
Modified:
trunk/reactos/ntoskrnl/io/iomgr/device.c
trunk/reactos/ntoskrnl/io/iomgr/volume.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/device.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/device.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/device.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/device.c Sun Jul 2 10:28:29 2006
@@ -1164,6 +1164,41 @@
}
/* Return the DO we found */
+ return DeviceObject;
+}
+
+/*
+ * @implemented
+ */
+PDEVICE_OBJECT
+NTAPI
+IoGetBaseFileSystemDeviceObject(IN PFILE_OBJECT FileObject)
+{
+ PDEVICE_OBJECT DeviceObject;
+
+ /*
+ * If the FILE_OBJECT's VPB is defined,
+ * get the device from it.
+ */
+ if ((FileObject->Vpb) && (FileObject->Vpb->DeviceObject))
+ {
+ /* Use the VPB's Device Object's */
+ DeviceObject = FileObject->Vpb->DeviceObject;
+ }
+ else if (!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN) &&
+ (FileObject->DeviceObject->Vpb) &&
+ (FileObject->DeviceObject->Vpb->DeviceObject))
+ {
+ /* Use the VPB's File System Object */
+ DeviceObject = FileObject->DeviceObject->Vpb->DeviceObject;
+ }
+ else
+ {
+ /* Use the FO's Device Object */
+ DeviceObject = FileObject->DeviceObject;
+ }
+
+ /* Return the device object we found */
return DeviceObject;
}
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 10:28:29 2006
@@ -35,7 +35,8 @@
NTAPI
IoInitVpbImplementation(VOID)
{
- KeInitializeSpinLock(&IoVpbLock);
+ /* Just initialize the VPB Lock */
+ KeInitializeSpinLock(&IoVpbLock);
}
VOID
@@ -348,7 +349,8 @@
/* Initialize the event to wait on */
KeInitializeEvent(&Event, NotificationEvent, FALSE);
- /* Get the actual device to mount */
+ /* Remove the verify flag and get the actual device to mount */
+ DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
while (AttachedDeviceObject->AttachedDevice)
{
/* Get the next one */
@@ -782,48 +784,6 @@
/*
* @implemented
*/
-PDEVICE_OBJECT
-NTAPI
-IoGetBaseFileSystemDeviceObject(IN PFILE_OBJECT FileObject)
-{
- PDEVICE_OBJECT DeviceObject = NULL;
- PVPB Vpb = NULL;
-
- /*
- * If the FILE_OBJECT's VPB is defined,
- * get the device from it.
- */
- if (NULL != (Vpb = FileObject->Vpb))
- {
- if (NULL != (DeviceObject = Vpb->DeviceObject))
- {
- /* Vpb->DeviceObject DEFINED! */
- return DeviceObject;
- }
- }
-
- /*
- * If that failed, try the VPB
- * in the FILE_OBJECT's DeviceObject.
- */
- DeviceObject = FileObject->DeviceObject;
- if (NULL == (Vpb = DeviceObject->Vpb))
- {
- /* DeviceObject->Vpb UNDEFINED! */
- return DeviceObject;
- }
-
- /*
- * If that pointer to the VPB is again
- * undefined, return directly the
- * device object from the FILE_OBJECT.
- */
- return ((NULL == Vpb->DeviceObject) ? DeviceObject : Vpb->DeviceObject);
-}
-
-/*
- * @implemented
- */
NTSTATUS
NTAPI
IoRegisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject,
Author: ion
Date: Sun Jul 2 10:18:55 2006
New Revision: 22766
URL: http://svn.reactos.org/svn/reactos?rev=22766&view=rev
Log:
- Small optimization: don't bother to get the File System Listhead we'll parse if we're going to fail because of wrong VPB flags later... get the list only after we're sure we need it.
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 10:18:55 2006
@@ -316,10 +316,9 @@
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PLIST_ENTRY FsList, ListEntry;
- PDEVICE_OBJECT ParentFsDeviceObject;
+ LIST_ENTRY LocalList;
PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
- PDEVICE_OBJECT FileSystemDeviceObject;
- LIST_ENTRY LocalList;
+ PDEVICE_OBJECT FileSystemDeviceObject, ParentFsDeviceObject;
ULONG FsStackOverhead;
PAGED_CODE();
@@ -343,24 +342,6 @@
KeEnterCriticalRegion();
ExAcquireResourceSharedLite(&FileSystemListLock, TRUE);
- /* For a mount operation, this can only be a Disk, CD-ROM or tape */
- if ((DeviceObject->DeviceType == FILE_DEVICE_DISK) ||
- (DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK))
- {
- /* Use the disk list */
- FsList = &IopDiskFsListHead;
- }
- else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM)
- {
- /* Use the CD-ROM list */
- FsList = &IopCdRomFsListHead;
- }
- else
- {
- /* It's gotta be a tape... */
- FsList = &IopTapeFsListHead;
- }
-
/* Make sure we weren't already mounted */
if (!(DeviceObject->Vpb->Flags & (VPB_MOUNTED | VPB_REMOVE_PENDING)))
{
@@ -376,6 +357,24 @@
/* Reference it */
ObReferenceObject(AttachedDeviceObject);
+
+ /* For a mount operation, this can only be a Disk, CD-ROM or tape */
+ if ((DeviceObject->DeviceType == FILE_DEVICE_DISK) ||
+ (DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK))
+ {
+ /* Use the disk list */
+ FsList = &IopDiskFsListHead;
+ }
+ else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM)
+ {
+ /* Use the CD-ROM list */
+ FsList = &IopCdRomFsListHead;
+ }
+ else
+ {
+ /* It's gotta be a tape... */
+ FsList = &IopTapeFsListHead;
+ }
/* Now loop the fs list until one of the file systems accepts us */
Status = STATUS_UNSUCCESSFUL;
Author: ion
Date: Sun Jul 2 10:15:52 2006
New Revision: 22765
URL: http://svn.reactos.org/svn/reactos?rev=22765&view=rev
Log:
- Use IoIsErrorUserInoduced to check if we couldn't mount the device because it was not actually inserted, was unrocognized, write-protected, etc... and completely break out of the mounting procedure if so.
- Also use FsRtlIsTotalDeviceFailure to check if the error was a fatal device error (like a CRC error) and abandon mounting in this case as well.
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 10:15:52 2006
@@ -479,6 +479,15 @@
}
else
{
+ /* Check if we failed because of the user */
+ if ((IoIsErrorUserInduced(Status)) &&
+ (IoStatusBlock.Information == 1))
+ {
+ /* Break out and fail */
+ break;
+ }
+
+ /* Otherwise, check if we need to load the FS driver */
if (Status == STATUS_FS_DRIVER_REQUIRED)
{
/* We need to release the lock */
@@ -497,7 +506,6 @@
if (!DeviceIsLocked)
{
/* Lock it ourselves */
- DPRINT1("Waiting\n");
Status = KeWaitForSingleObject(&DeviceObject->
DeviceLock,
Executive,
@@ -531,6 +539,19 @@
LocalList.Flink = FsList->Flink;
ListEntry = &LocalList;
}
+
+ /*
+ * Check if we failed with any other error then an unrecognized
+ * volume, and if this request doesn't allow mounting the raw
+ * file system.
+ */
+ if (!(AllowRawMount) &&
+ (Status != STATUS_UNRECOGNIZED_VOLUME) &&
+ (FsRtlIsTotalDeviceFailure(Status)))
+ {
+ /* Break out and give up */
+ break;
+ }
}
/* Go to the next FS entry */
Author: ion
Date: Sun Jul 2 10:11:19 2006
New Revision: 22764
URL: http://svn.reactos.org/svn/reactos?rev=22764&view=rev
Log:
- Implement IopInitailizeVpbForMount for the purpose of setting up the VPB for a newly mounted DO. It properly references the VPB and sets up its stack size and flags, adding support for VPB_RAW_MOUNT. Also sets the VPB pointer in the DevObjExtension.
- Fix a bug which was causing us to incorrectly unlock the device if it was already locked by the caller isntead of by IopMountVolume.
- When loading the file system, make sure to unlock the device object if we had locked it in IopMountVolume, as well as to re-lock it afterwards. Also handle a potential race condition due to this unloacking, in which the VPB might've become mounted behind our back, and simply return success if this happened.
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 10:11:19 2006
@@ -130,6 +130,39 @@
/* Release the VPB lock and return status */
IoReleaseVpbSpinLock(OldIrql);
return Result;
+}
+
+PVPB
+NTAPI
+IopInitializeVpbForMount(IN PDEVICE_OBJECT DeviceObject,
+ IN PDEVICE_OBJECT AttachedDeviceObject,
+ IN BOOLEAN Raw)
+{
+ KIRQL OldIrql;
+ PVPB Vpb;
+
+ /* Lock the VPBs */
+ IoAcquireVpbSpinLock(&OldIrql);
+ Vpb = DeviceObject->Vpb;
+
+ /* Set the VPB as mounted and possibly raw */
+ Vpb->Flags |= VPB_MOUNTED | Raw ? VPB_RAW_MOUNT : 0;
+
+ /* Set the stack size */
+ Vpb->DeviceObject->StackSize = AttachedDeviceObject->StackSize;
+
+ /* Add one for the FS Driver */
+ Vpb->DeviceObject->StackSize++;
+
+ /* Set the VPB in the device extension */
+ IoGetDevObjExtension(Vpb->DeviceObject)->Vpb = Vpb;
+
+ /* Reference it */
+ Vpb->ReferenceCount++;
+
+ /* Release the VPB lock and return it */
+ IoReleaseVpbSpinLock(OldIrql);
+ return Vpb;
}
VOID
@@ -283,7 +316,7 @@
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PLIST_ENTRY FsList, ListEntry;
- PDEVICE_OBJECT DevObject;
+ PDEVICE_OBJECT ParentFsDeviceObject;
PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
PDEVICE_OBJECT FileSystemDeviceObject;
LIST_ENTRY LocalList;
@@ -376,6 +409,7 @@
FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
DEVICE_OBJECT,
Queue.ListEntry);
+ ParentFsDeviceObject = FileSystemDeviceObject;
/*
* If this file system device is attached to some other device,
@@ -434,26 +468,69 @@
Status = IoStatusBlock.Status;
}
- switch (Status)
+ /* Check if mounting was successful */
+ if (NT_SUCCESS(Status))
{
- case STATUS_FS_DRIVER_REQUIRED:
- DevObject = FileSystemDeviceObject;
+ /* Mount the VPB */
+ *Vpb = IopInitializeVpbForMount(DeviceObject,
+ AttachedDeviceObject,
+ (DeviceObject->Vpb->Flags &
+ VPB_RAW_MOUNT));
+ }
+ else
+ {
+ if (Status == STATUS_FS_DRIVER_REQUIRED)
+ {
+ /* We need to release the lock */
ExReleaseResourceLite(&FileSystemListLock);
- IopLoadFileSystem(DevObject);
- ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
+
+ /* Release the device lock if we're holding it */
+ if (!DeviceIsLocked)
+ {
+ KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
+ }
+
+ /* Load the FS */
+ IopLoadFileSystem(ParentFsDeviceObject);
+
+ /* Check if the device isn't already locked */
+ if (!DeviceIsLocked)
+ {
+ /* Lock it ourselves */
+ DPRINT1("Waiting\n");
+ Status = KeWaitForSingleObject(&DeviceObject->
+ DeviceLock,
+ Executive,
+ KeGetPreviousMode(),
+ Alertable,
+ NULL);
+ if ((Status == STATUS_ALERTED) ||
+ (Status == STATUS_USER_APC))
+ {
+ /* Don't mount if we were interrupted */
+ ObDereferenceObject(AttachedDeviceObject);
+ return Status;
+ }
+ }
+
+ /* Reacquire the lock */
+ ExAcquireResourceSharedLite(&FileSystemListLock, TRUE);
+
+ /* When we released the lock, make sure nobody beat us */
+ if (DeviceObject->Vpb->Flags & VPB_MOUNTED)
+ {
+ /* Someone did, break out */
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ /* Start over by setting a failure */
+ Status = STATUS_UNRECOGNIZED_VOLUME;
+
/* We need to setup a local list to pickup where we left */
LocalList.Flink = FsList->Flink;
ListEntry = &LocalList;
- break;
-
- case STATUS_SUCCESS:
- DeviceObject->Vpb->Flags = DeviceObject->Vpb->Flags |
- VPB_MOUNTED;
-
- case STATUS_UNRECOGNIZED_VOLUME:
- default:
- /* do nothing */
- break;
+ }
}
/* Go to the next FS entry */
@@ -479,7 +556,7 @@
KeLeaveCriticalRegion();
/* Release the device lock if we're holding it */
- if (DeviceIsLocked) KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
+ if (!DeviceIsLocked) KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
/* Check if we failed to mount the boot partition */
if ((!NT_SUCCESS(Status)) &&
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)
{
Author: ion
Date: Sun Jul 2 09:44:27 2006
New Revision: 22762
URL: http://svn.reactos.org/svn/reactos?rev=22762&view=rev
Log:
- If the device to be mounted is an attachee, find the base device object
- Reference the device object being mounted.
- If the file system being mounted is an atachee, find its base device object too, and increase the IRP Stack for each attached FSD.
- Fix IRP parameters with this new information.
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:44:27 2006
@@ -284,8 +284,10 @@
PIO_STACK_LOCATION StackPtr;
PLIST_ENTRY FsList, ListEntry;
PDEVICE_OBJECT DevObject;
+ PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
PDEVICE_OBJECT FileSystemDeviceObject;
LIST_ENTRY LocalList;
+ ULONG FsStackOverhead;
PAGED_CODE();
/* Check if the device isn't already locked */
@@ -332,6 +334,16 @@
/* Initialize the event to wait on */
KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ /* Get the actual device to mount */
+ while (AttachedDeviceObject->AttachedDevice)
+ {
+ /* Get the next one */
+ AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
+ }
+
+ /* Reference it */
+ ObReferenceObject(AttachedDeviceObject);
+
/* Now loop the fs list until one of the file systems accepts us */
Status = STATUS_UNSUCCESSFUL;
ListEntry = FsList->Flink;
@@ -341,6 +353,20 @@
FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
DEVICE_OBJECT,
Queue.ListEntry);
+
+ /*
+ * If this file system device is attached to some other device,
+ * then we must make sure to increase the stack size for the IRP.
+ * The default is +1, for the FS device itself.
+ */
+ FsStackOverhead = 1;
+ while (FileSystemDeviceObject->AttachedDevice)
+ {
+ /* Get the next attached device and increase overhead */
+ FileSystemDeviceObject = FileSystemDeviceObject->
+ AttachedDevice;
+ FsStackOverhead++;
+ }
/* If we are not allowed to mount this volume as a raw filesystem volume
then don't try this */
@@ -354,8 +380,8 @@
KeClearEvent(&Event);
/* Allocate the IRP */
- Irp = IoAllocateIrp(FileSystemDeviceObject->StackSize +
- 1,
+ Irp = IoAllocateIrp(AttachedDeviceObject->StackSize +
+ FsStackOverhead,
TRUE);
if (!Irp)
{
@@ -378,7 +404,7 @@
StackPtr->Flags = AllowRawMount;
StackPtr->Parameters.MountVolume.Vpb = DeviceObject->Vpb;
StackPtr->Parameters.MountVolume.DeviceObject =
- DeviceObject;
+ AttachedDeviceObject;
/* Call the driver */
Status = IoCallDriver(FileSystemDeviceObject, Irp);
Author: ion
Date: Sun Jul 2 09:30:45 2006
New Revision: 22760
URL: http://svn.reactos.org/svn/reactos?rev=22760&view=rev
Log:
- Respect DeviceIsLocked flag and Alertable in IopMountVolume
- Don't mount if the VPB is alread ymoutned or being removed
- Bugcheck the system if we failed to mount the boot partition.
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:30:45 2006
@@ -330,8 +330,25 @@
LIST_ENTRY LocalList;
ASSERT_IRQL(PASSIVE_LEVEL);
+ /* Check if the device isn't already locked */
+ if (!DeviceIsLocked)
+ {
+ /* Lock it ourselves */
+ Status = KeWaitForSingleObject(&DeviceObject->DeviceLock,
+ Executive,
+ KeGetPreviousMode(),
+ Alertable,
+ NULL);
+ if ((Status == STATUS_ALERTED) || (Status == STATUS_USER_APC))
+ {
+ /* Don't mount if we were interrupted */
+ return Status;
+ }
+ }
+
+ /* Acquire the FS Lock*/
KeEnterCriticalRegion();
- ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
+ ExAcquireResourceSharedLite(&FileSystemListLock, TRUE);
/* For a mount operation, this can only be a Disk, CD-ROM or tape */
if ((DeviceObject->DeviceType == FILE_DEVICE_DISK) ||
@@ -351,57 +368,90 @@
FsList = &IopTapeFsListHead;
}
- /* Now loop the fs list until one of the file systems accepts us */
- ListEntry = FsList->Flink;
- while (ListEntry != FsList)
- {
- /* Get the Device Object for this FS */
- FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
- DEVICE_OBJECT,
- Queue.ListEntry);
-
- /* If we are not allowed to mount this volume as a raw filesystem volume
- then don't try this */
- if (!AllowRawMount && RawFsIsRawFileSystemDeviceObject(FileSystemDeviceObject))
- {
- Status = STATUS_UNRECOGNIZED_VOLUME;
- }
- else
- {
- Status = IopMountFileSystem(FileSystemDeviceObject, DeviceObject);
- }
-
- switch (Status)
- {
- case STATUS_FS_DRIVER_REQUIRED:
- DevObject = FileSystemDeviceObject;
- ExReleaseResourceLite(&FileSystemListLock);
- IopLoadFileSystem(DevObject);
- ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
- /* We need to setup a local list to pickup where we left */
- LocalList.Flink = FsList->Flink;
- ListEntry = &LocalList;
- break;
-
- case STATUS_SUCCESS:
- DeviceObject->Vpb->Flags = DeviceObject->Vpb->Flags |
- VPB_MOUNTED;
- ExReleaseResourceLite(&FileSystemListLock);
- KeLeaveCriticalRegion();
- return(STATUS_SUCCESS);
-
- case STATUS_UNRECOGNIZED_VOLUME:
- default:
- /* do nothing */
- break;
- }
-
- ListEntry = ListEntry->Flink;
- }
-
+ /* Make sure we weren't already mounted */
+ if (!(DeviceObject->Vpb->Flags & (VPB_MOUNTED | VPB_REMOVE_PENDING)))
+ {
+ /* Now loop the fs list until one of the file systems accepts us */
+ Status = STATUS_UNSUCCESSFUL;
+ ListEntry = FsList->Flink;
+ while (ListEntry != FsList)
+ {
+ /* Get the Device Object for this FS */
+ FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
+ DEVICE_OBJECT,
+ Queue.ListEntry);
+
+ /* If we are not allowed to mount this volume as a raw filesystem volume
+ then don't try this */
+ if (!AllowRawMount && RawFsIsRawFileSystemDeviceObject(FileSystemDeviceObject))
+ {
+ Status = STATUS_UNRECOGNIZED_VOLUME;
+ }
+ else
+ {
+ Status = IopMountFileSystem(FileSystemDeviceObject, DeviceObject);
+ }
+
+ switch (Status)
+ {
+ case STATUS_FS_DRIVER_REQUIRED:
+ DevObject = FileSystemDeviceObject;
+ ExReleaseResourceLite(&FileSystemListLock);
+ IopLoadFileSystem(DevObject);
+ ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
+ /* We need to setup a local list to pickup where we left */
+ LocalList.Flink = FsList->Flink;
+ ListEntry = &LocalList;
+ break;
+
+ case STATUS_SUCCESS:
+ DeviceObject->Vpb->Flags = DeviceObject->Vpb->Flags |
+ VPB_MOUNTED;
+ ExReleaseResourceLite(&FileSystemListLock);
+ KeLeaveCriticalRegion();
+ return(STATUS_SUCCESS);
+
+ case STATUS_UNRECOGNIZED_VOLUME:
+ default:
+ /* do nothing */
+ break;
+ }
+
+ ListEntry = ListEntry->Flink;
+ }
+ }
+ else if (DeviceObject->Vpb->Flags & VPB_REMOVE_PENDING)
+ {
+ /* Someone wants to remove us */
+ Status = STATUS_DEVICE_DOES_NOT_EXIST;
+ }
+ else
+ {
+ /* Someone already mounted us */
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Release the FS lock */
ExReleaseResourceLite(&FileSystemListLock);
KeLeaveCriticalRegion();
- return(STATUS_UNRECOGNIZED_VOLUME);
+
+ /* Release the device lock if we're holding it */
+ if (DeviceIsLocked) KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
+
+ /* Check if we failed to mount the boot partition */
+ if ((!NT_SUCCESS(Status)) &&
+ (DeviceObject->Flags & DO_SYSTEM_BOOT_PARTITION))
+ {
+ /* Bugcheck the system */
+ KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE,
+ (ULONG_PTR)DeviceObject,
+ Status,
+ 0,
+ 0);
+ }
+
+ /* Return the mount status */
+ return Status;
}
/* PUBLIC FUNCTIONS **********************************************************/
Author: ion
Date: Sun Jul 2 08:33:45 2006
New Revision: 22759
URL: http://svn.reactos.org/svn/reactos?rev=22759&view=rev
Log:
- Fix the hack in the previous commit which broke FS support.
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 08:33:45 2006
@@ -327,12 +327,12 @@
PLIST_ENTRY FsList, ListEntry;
PDEVICE_OBJECT DevObject;
PDEVICE_OBJECT FileSystemDeviceObject;
+ LIST_ENTRY LocalList;
ASSERT_IRQL(PASSIVE_LEVEL);
KeEnterCriticalRegion();
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
- restart:
/* For a mount operation, this can only be a Disk, CD-ROM or tape */
if ((DeviceObject->DeviceType == FILE_DEVICE_DISK) ||
(DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK))
@@ -378,7 +378,10 @@
ExReleaseResourceLite(&FileSystemListLock);
IopLoadFileSystem(DevObject);
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
- goto restart;
+ /* We need to setup a local list to pickup where we left */
+ LocalList.Flink = FsList->Flink;
+ ListEntry = &LocalList;
+ break;
case STATUS_SUCCESS:
DeviceObject->Vpb->Flags = DeviceObject->Vpb->Flags |
@@ -392,6 +395,8 @@
/* do nothing */
break;
}
+
+ ListEntry = ListEntry->Flink;
}
ExReleaseResourceLite(&FileSystemListLock);