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); }