[ros-diffs] [ion] 22757: - 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.

ion at svn.reactos.org ion at svn.reactos.org
Sun Jul 2 03:44:53 CEST 2006


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?rev=22757&r1=22756&r2=22757&view=diff
==============================================================================
--- 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);
 }
 




More information about the Ros-diffs mailing list