Author: ion
Date: Sun Jul 2 05:44:53 2006
New Revision: 22757
URL:
http://svn.reactos.org/svn/reactos?rev=22757&view=rev
Log:
- Get rid of the stupid LIST_FOR_EACH macros in FS Notifcation APIs.
- Each new change request should be queued at the end of the list, not at the head.
- Also, reference the device object for each registration, since one more object is
holding a pointer to it, likewise, dereference the object on deregistration.
- IopLoadFileSystem should use the base FSD in case the device object is an attachee.
Also, use IoBuildDEviceIoControlRequest to minimize the IRP setup to only a couple of
lines.
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 05:44:53 2006
@@ -145,12 +145,28 @@
IN BOOLEAN DriverActive)
{
PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
-
+ PLIST_ENTRY ListEntry;
+
+ /* Acquire the notification lock */
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
- LIST_FOR_EACH(ChangeEntry, &FsChangeNotifyListHead,FS_CHANGE_NOTIFY_ENTRY,
FsChangeNotifyList)
- {
- (ChangeEntry->FSDNotificationProc)(DeviceObject, DriverActive);
- }
+
+ /* Loop the list */
+ ListEntry = FsChangeNotifyListHead.Flink;
+ while (ListEntry != &FsChangeNotifyListHead)
+ {
+ /* Get the entry */
+ ChangeEntry = CONTAINING_RECORD(ListEntry,
+ FS_CHANGE_NOTIFY_ENTRY,
+ FsChangeNotifyList);
+
+ /* Call the notification procedure */
+ ChangeEntry->FSDNotificationProc(DeviceObject, DriverActive);
+
+ /* Go to the next entry */
+ ListEntry = ListEntry->Flink;
+ }
+
+ /* Release the lock */
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
}
@@ -240,7 +256,7 @@
return(Status);
}
-NTSTATUS
+VOID
NTAPI
IopLoadFileSystem(IN PDEVICE_OBJECT DeviceObject)
{
@@ -249,36 +265,42 @@
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
- ASSERT_IRQL(PASSIVE_LEVEL);
-
+ PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
+ PAGED_CODE();
+
+ /* Loop as long as we're attached */
+ while (AttachedDeviceObject->AttachedDevice)
+ {
+ /* Get the attached device object */
+ AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
+ }
+
+ /* Initialize the event and build the IRP */
KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
- if (Irp==NULL)
- {
- return(STATUS_INSUFFICIENT_RESOURCES);
- }
-
- Irp->UserIosb = &IoStatusBlock;
- Irp->UserEvent = &Event;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
- StackPtr->MinorFunction = IRP_MN_LOAD_FILE_SYSTEM;
- StackPtr->Flags = 0;
- StackPtr->Control = 0;
- StackPtr->DeviceObject = DeviceObject;
- StackPtr->FileObject = NULL;
- StackPtr->CompletionRoutine = NULL;
-
- Status = IoCallDriver(DeviceObject,Irp);
- if (Status==STATUS_PENDING)
- {
- KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
- Status = IoStatusBlock.Status;
- }
-
- return(Status);
+ Irp = IoBuildDeviceIoControlRequest(IRP_MJ_DEVICE_CONTROL,
+ AttachedDeviceObject,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ FALSE,
+ &Event,
+ &IoStatusBlock);
+ if (Irp)
+ {
+ /* Set the major and minor functions */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
+ StackPtr->MinorFunction = IRP_MN_LOAD_FILE_SYSTEM;
+
+ /* Call the driver */
+ Status = IoCallDriver(AttachedDeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait on it */
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ }
+ }
}
NTSTATUS
@@ -347,12 +369,7 @@
case STATUS_FS_DRIVER_REQUIRED:
DevObject = current->DeviceObject;
ExReleaseResourceLite(&FileSystemListLock);
- Status = IopLoadFileSystem(DevObject);
- if (!NT_SUCCESS(Status))
- {
- KeLeaveCriticalRegion();
- return(Status);
- }
+ IopLoadFileSystem(DevObject);
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
goto restart;
@@ -584,20 +601,26 @@
IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
{
PFS_CHANGE_NOTIFY_ENTRY Entry;
-
- Entry = ExAllocatePoolWithTag(NonPagedPool,
+ PAGED_CODE();
+
+ /* Allocate a notification entry */
+ Entry = ExAllocatePoolWithTag(PagedPool,
sizeof(FS_CHANGE_NOTIFY_ENTRY),
TAG_FS_CHANGE_NOTIFY);
- if (Entry == NULL) return(STATUS_INSUFFICIENT_RESOURCES);
-
+ if (!Entry) return(STATUS_INSUFFICIENT_RESOURCES);
+
+ /* Save the driver object and notification routine */
Entry->DriverObject = DriverObject;
Entry->FSDNotificationProc = FSDNotificationProc;
+ /* Insert it into the notification list */
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
- InsertHeadList(&FsChangeNotifyListHead, &Entry->FsChangeNotifyList);
+ InsertTailList(&FsChangeNotifyListHead, &Entry->FsChangeNotifyList);
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
- return(STATUS_SUCCESS);
+ /* Reference the driver */
+ ObReferenceObject(DriverObject);
+ return STATUS_SUCCESS;
}
/*
@@ -609,20 +632,38 @@
IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
{
PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
-
- LIST_FOR_EACH(ChangeEntry, &FsChangeNotifyListHead, FS_CHANGE_NOTIFY_ENTRY,
FsChangeNotifyList)
- {
- if (ChangeEntry->DriverObject == DriverObject &&
- ChangeEntry->FSDNotificationProc == FSDNotificationProc)
- {
- KeAcquireGuardedMutex(&FsChangeNotifyListLock);
+ PLIST_ENTRY NextEntry;
+ PAGED_CODE();
+
+ /* Acquire the list lock */
+ KeAcquireGuardedMutex(&FsChangeNotifyListLock);
+
+ /* Loop the list */
+ NextEntry = FsChangeNotifyListHead.Flink;
+ while (NextEntry != &FsChangeNotifyListHead)
+ {
+ /* Get the entry */
+ ChangeEntry = CONTAINING_RECORD(NextEntry,
+ FS_CHANGE_NOTIFY_ENTRY,
+ FsChangeNotifyList);
+
+ /* Check if it matches this de-registration */
+ if ((ChangeEntry->DriverObject == DriverObject) &&
+ (ChangeEntry->FSDNotificationProc == FSDNotificationProc))
+ {
+ /* It does, remove it from the list */
RemoveEntryList(&ChangeEntry->FsChangeNotifyList);
- KeReleaseGuardedMutex(&FsChangeNotifyListLock);
-
ExFreePoolWithTag(ChangeEntry, TAG_FS_CHANGE_NOTIFY);
- return;
- }
- }
+ break;
+ }
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Release the lock and dereference the driver */
+ KeReleaseGuardedMutex(&FsChangeNotifyListLock);
+ ObDereferenceObject(DriverObject);
}
/*
@@ -632,6 +673,7 @@
NTAPI
IoAcquireVpbSpinLock(OUT PKIRQL Irql)
{
+ /* Simply acquire the lock */
KeAcquireSpinLock(&IoVpbLock, Irql);
}
@@ -642,6 +684,7 @@
NTAPI
IoReleaseVpbSpinLock(IN KIRQL Irql)
{
+ /* Just release the lock */
KeReleaseSpinLock(&IoVpbLock, Irql);
}