[USBOHCI_NEW][USBUHCI_NEW] Avoid unnecessary/incorrect status defines.
[reactos.git] / drivers / filesystems / btrfs / btrfs.c
index 0e3e917..bdc2988 100644 (file)
@@ -464,7 +464,11 @@ BOOL get_xattr(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vc
 
 _Dispatch_type_(IRP_MJ_CLOSE)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_close(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_close(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     NTSTATUS Status;
     PIO_STACK_LOCATION IrpSp;
     device_extension* Vcb = DeviceObject->DeviceExtension;
@@ -513,7 +517,11 @@ end:
 
 _Dispatch_type_(IRP_MJ_FLUSH_BUFFERS)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_flush_buffers(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_flush_buffers(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     NTSTATUS Status;
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
     PFILE_OBJECT FileObject = IrpSp->FileObject;
@@ -708,7 +716,11 @@ static BOOL lie_about_fs_type() {
 
 _Dispatch_type_(IRP_MJ_QUERY_VOLUME_INFORMATION)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_query_volume_information(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_query_volume_information(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     PIO_STACK_LOCATION IrpSp;
     NTSTATUS Status;
     ULONG BytesCopied = 0;
@@ -1147,7 +1159,11 @@ end:
 
 _Dispatch_type_(IRP_MJ_SET_VOLUME_INFORMATION)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_set_volume_information(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_set_volume_information(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
     device_extension* Vcb = DeviceObject->DeviceExtension;
     NTSTATUS Status;
@@ -1352,7 +1368,7 @@ void send_notification_fcb(_In_ file_ref* fileref, _In_ ULONG filter_match, _In_
         return;
     }
 
-    ExAcquireResourceExclusiveLite(&fcb->Vcb->fcb_lock, TRUE);
+    acquire_fcb_lock_exclusive(fcb->Vcb);
 
     le = fcb->hardlinks.Flink;
     while (le != &fcb->hardlinks) {
@@ -1419,7 +1435,7 @@ void send_notification_fcb(_In_ file_ref* fileref, _In_ ULONG filter_match, _In_
         le = le->Flink;
     }
 
-    ExReleaseResourceLite(&fcb->Vcb->fcb_lock);
+    release_fcb_lock(fcb->Vcb);
 }
 
 void mark_fcb_dirty(_In_ fcb* fcb) {
@@ -1698,14 +1714,14 @@ static NTSTATUS close_file(_In_ PFILE_OBJECT FileObject, _In_ PIRP Irp) {
 
     Vcb = fcb->Vcb;
 
-    ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+    acquire_fcb_lock_exclusive(Vcb);
 
     if (fileref)
         free_fileref(fcb->Vcb, fileref);
     else
         free_fcb(Vcb, fcb);
 
-    ExReleaseResourceLite(&Vcb->fcb_lock);
+    release_fcb_lock(Vcb);
 
     return STATUS_SUCCESS;
 }
@@ -1804,10 +1820,10 @@ void uninit(_In_ device_extension* Vcb, _In_ BOOL flush) {
     KeSetTimer(&Vcb->flush_thread_timer, time, NULL); // trigger the timer early
     KeWaitForSingleObject(&Vcb->flush_thread_finished, Executive, KernelMode, FALSE, NULL);
 
-    ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+    acquire_fcb_lock_exclusive(Vcb);
     free_fcb(Vcb, Vcb->volume_fcb);
     free_fcb(Vcb, Vcb->dummy_fcb);
-    ExReleaseResourceLite(&Vcb->fcb_lock);
+    release_fcb_lock(Vcb);
 
     if (Vcb->root_file)
         ObDereferenceObject(Vcb->root_file);
@@ -1817,9 +1833,9 @@ void uninit(_In_ device_extension* Vcb, _In_ BOOL flush) {
         chunk* c = CONTAINING_RECORD(le, chunk, list_entry);
 
         if (c->cache) {
-            ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+            acquire_fcb_lock_exclusive(Vcb);
             free_fcb(Vcb, c->cache);
-            ExReleaseResourceLite(&Vcb->fcb_lock);
+            release_fcb_lock(Vcb);
             c->cache = NULL;
         }
 
@@ -1855,9 +1871,9 @@ void uninit(_In_ device_extension* Vcb, _In_ BOOL flush) {
             ExFreePool(c->devices);
 
         if (c->cache) {
-            ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+            acquire_fcb_lock_exclusive(Vcb);
             free_fcb(Vcb, c->cache);
-            ExReleaseResourceLite(&Vcb->fcb_lock);
+            release_fcb_lock(Vcb);
         }
 
         ExDeleteResourceLite(&c->range_locks_lock);
@@ -1915,7 +1931,7 @@ void uninit(_In_ device_extension* Vcb, _In_ BOOL flush) {
     ZwClose(Vcb->flush_thread_handle);
 }
 
-NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback) {
+NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_opt_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback) {
     LARGE_INTEGER newlength, time;
     BTRFS_TIME now;
     NTSTATUS Status;
@@ -1995,6 +2011,18 @@ NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_ PFILE_OBJECT FileObject, _I
                 }
 
                 fileref->fcb->deleted = TRUE;
+
+                le = fileref->children.Flink;
+                while (le != &fileref->children) {
+                    file_ref* fr2 = CONTAINING_RECORD(le, file_ref, list_entry);
+
+                    if (fr2->fcb->ads) {
+                        fr2->fcb->deleted = TRUE;
+                        mark_fcb_dirty(fr2->fcb);
+                    }
+
+                    le = le->Flink;
+                }
             }
 
             if (fileref->dc) {
@@ -2024,11 +2052,25 @@ NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_ PFILE_OBJECT FileObject, _I
 
                 mark_fcb_dirty(fileref->fcb); // so ROOT_ITEM gets updated
             } else {
+                LIST_ENTRY* le;
+
                 // FIXME - we need a lock here
 
                 RemoveEntryList(&fileref->fcb->subvol->list_entry);
 
                 InsertTailList(&fileref->fcb->Vcb->drop_roots, &fileref->fcb->subvol->list_entry);
+
+                le = fileref->children.Flink;
+                while (le != &fileref->children) {
+                    file_ref* fr2 = CONTAINING_RECORD(le, file_ref, list_entry);
+
+                    if (fr2->fcb->ads) {
+                        fr2->fcb->deleted = TRUE;
+                        mark_fcb_dirty(fr2->fcb);
+                    }
+
+                    le = le->Flink;
+                }
             }
         }
     } else {
@@ -2103,7 +2145,11 @@ NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_ PFILE_OBJECT FileObject, _I
 
 _Dispatch_type_(IRP_MJ_CLEANUP)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     NTSTATUS Status;
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
     PFILE_OBJECT FileObject = IrpSp->FileObject;
@@ -2209,18 +2255,18 @@ static NTSTATUS drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
                     locked = FALSE;
 
                     // fcb_lock needs to be acquired before fcb->Header.Resource
-                    ExAcquireResourceExclusiveLite(&fcb->Vcb->fcb_lock, TRUE);
+                    acquire_fcb_lock_exclusive(fcb->Vcb);
 
                     Status = delete_fileref(fileref, FileObject, Irp, &rollback);
                     if (!NT_SUCCESS(Status)) {
                         ERR("delete_fileref returned %08x\n", Status);
                         do_rollback(fcb->Vcb, &rollback);
-                        ExReleaseResourceLite(&fcb->Vcb->fcb_lock);
+                        release_fcb_lock(fcb->Vcb);
                         ExReleaseResourceLite(&fcb->Vcb->tree_lock);
                         goto exit;
                     }
 
-                    ExReleaseResourceLite(&fcb->Vcb->fcb_lock);
+                    release_fcb_lock(fcb->Vcb);
 
                     locked = FALSE;
 
@@ -4427,7 +4473,21 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
         goto exit;
     }
 
+    /* HACK: stream file object seems to get deleted at some point
+     * leading to use after free when installing ReactOS on
+     * BtrFS.
+     * Workaround: leak a handle to the fileobject
+     * XXX: Could be improved by storing it somewhere and releasing it
+     * on dismount. Or even by referencing again the file object.
+     */
+#ifndef __REACTOS__
     Vcb->root_file = IoCreateStreamFileObject(NULL, DeviceToMount);
+#else
+    {
+        HANDLE Dummy;
+        Vcb->root_file = IoCreateStreamFileObjectEx(NULL, DeviceToMount, &Dummy);
+    }
+#endif
     Vcb->root_file->FsContext = root_fcb;
     Vcb->root_file->SectionObjectPointer = &root_fcb->nonpaged->segment_object;
     Vcb->root_file->Vpb = DeviceObject->Vpb;
@@ -4522,19 +4582,19 @@ exit2:
             if (Vcb->root_file)
                 ObDereferenceObject(Vcb->root_file);
             else if (Vcb->root_fileref) {
-                ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+                acquire_fcb_lock_exclusive(Vcb);
                 free_fileref(Vcb, Vcb->root_fileref);
-                ExReleaseResourceLite(&Vcb->fcb_lock);
+                release_fcb_lock(Vcb);
             } else if (root_fcb) {
-                ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+                acquire_fcb_lock_exclusive(Vcb);
                 free_fcb(Vcb, root_fcb);
-                ExReleaseResourceLite(&Vcb->fcb_lock);
+                release_fcb_lock(Vcb);
             }
 
             if (Vcb->volume_fcb) {
-                ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+                acquire_fcb_lock_exclusive(Vcb);
                 free_fcb(Vcb, Vcb->volume_fcb);
-                ExReleaseResourceLite(&Vcb->fcb_lock);
+                release_fcb_lock(Vcb);
             }
 
             ExDeleteResourceLite(&Vcb->tree_lock);
@@ -4728,7 +4788,11 @@ static NTSTATUS verify_volume(_In_ PDEVICE_OBJECT devobj) {
 
 _Dispatch_type_(IRP_MJ_FILE_SYSTEM_CONTROL)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_file_system_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_file_system_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     PIO_STACK_LOCATION IrpSp;
     NTSTATUS Status;
     device_extension* Vcb = DeviceObject->DeviceExtension;
@@ -4809,7 +4873,11 @@ end:
 
 _Dispatch_type_(IRP_MJ_LOCK_CONTROL)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_lock_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_lock_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     NTSTATUS Status;
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
     fcb* fcb = IrpSp->FileObject->FsContext;
@@ -4848,10 +4916,17 @@ exit:
 
 _Dispatch_type_(IRP_MJ_SHUTDOWN)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_shutdown(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_shutdown(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     NTSTATUS Status;
     BOOL top_level;
     device_extension* Vcb = DeviceObject->DeviceExtension;
+#ifdef __REACTOS__
+    LIST_ENTRY *Vcble, *le;
+#endif
 
     FsRtlEnterFileSystem();
 
@@ -4869,6 +4944,7 @@ static NTSTATUS drv_shutdown(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
     shutting_down = TRUE;
     KeSetEvent(&mountmgr_thread_event, 0, FALSE);
 
+#ifndef __REACTOS__
     while (!IsListEmpty(&VcbList)) {
         Vcb = CONTAINING_RECORD(VcbList.Flink, device_extension, list_entry);
 
@@ -4876,6 +4952,71 @@ static NTSTATUS drv_shutdown(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
 
         uninit(Vcb, TRUE);
     }
+#else
+    Vcble = VcbList.Flink;
+    while (Vcble != &VcbList) {
+        Vcb = CONTAINING_RECORD(Vcble, device_extension, list_entry);
+
+        TRACE("shutting down Vcb %p\n", Vcb);
+
+        if (Vcb->balance.thread) {
+            Vcb->balance.paused = FALSE;
+            Vcb->balance.stopping = TRUE;
+            KeSetEvent(&Vcb->balance.event, 0, FALSE);
+            KeWaitForSingleObject(&Vcb->balance.finished, Executive, KernelMode, FALSE, NULL);
+        }
+
+        if (Vcb->scrub.thread) {
+            Vcb->scrub.paused = FALSE;
+            Vcb->scrub.stopping = TRUE;
+            KeSetEvent(&Vcb->scrub.event, 0, FALSE);
+            KeWaitForSingleObject(&Vcb->scrub.finished, Executive, KernelMode, FALSE, NULL);
+        }
+
+        if (Vcb->running_sends != 0) {
+            BOOL send_cancelled = FALSE;
+
+            ExAcquireResourceExclusiveLite(&Vcb->send_load_lock, TRUE);
+
+            le = Vcb->send_ops.Flink;
+            while (le != &Vcb->send_ops) {
+                send_info* send = CONTAINING_RECORD(le, send_info, list_entry);
+
+                if (!send->cancelling) {
+                    send->cancelling = TRUE;
+                    send_cancelled = TRUE;
+                    send->ccb = NULL;
+                    KeSetEvent(&send->cleared_event, 0, FALSE);
+                }
+
+                le = le->Flink;
+            }
+
+            ExReleaseResourceLite(&Vcb->send_load_lock);
+
+            if (send_cancelled) {
+                while (Vcb->running_sends != 0) {
+                    ExAcquireResourceExclusiveLite(&Vcb->send_load_lock, TRUE);
+                    ExReleaseResourceLite(&Vcb->send_load_lock);
+                }
+            }
+        }
+
+        ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);
+
+        if (Vcb->need_write && !Vcb->readonly) {
+            Status = do_write(Vcb, Irp);
+
+            if (!NT_SUCCESS(Status))
+                ERR("do_write returned %08x\n", Status);
+        }
+
+        Vcb->removing = TRUE;
+
+        ExReleaseResourceLite(&Vcb->tree_lock);
+        Vcble = Vcble->Flink;
+    }
+#endif
 
 #ifdef _DEBUG
     if (comfo) {
@@ -4901,7 +5042,11 @@ end:
 
 _Dispatch_type_(IRP_MJ_POWER)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_power(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_power(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     NTSTATUS Status;
     device_extension* Vcb = DeviceObject->DeviceExtension;
     BOOL top_level;
@@ -4942,7 +5087,11 @@ exit:
 
 _Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
 _Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_system_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
 static NTSTATUS drv_system_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
     NTSTATUS Status;
     device_extension* Vcb = DeviceObject->DeviceExtension;
     BOOL top_level;
@@ -5471,6 +5620,30 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Regi
 
     DriverObject->DriverExtension->AddDevice = AddDevice;
 
+#ifdef __REACTOS__
+    DriverObject->MajorFunction[IRP_MJ_CREATE]                   = drv_create;
+    DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = drv_close;
+    DriverObject->MajorFunction[IRP_MJ_READ]                     = drv_read;
+    DriverObject->MajorFunction[IRP_MJ_WRITE]                    = drv_write;
+    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = drv_query_information;
+    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]          = drv_set_information;
+    DriverObject->MajorFunction[IRP_MJ_QUERY_EA]                 = drv_query_ea;
+    DriverObject->MajorFunction[IRP_MJ_SET_EA]                   = drv_set_ea;
+    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]            = drv_flush_buffers;
+    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = drv_query_volume_information;
+    DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]   = drv_set_volume_information;
+    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]        = drv_directory_control;
+    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]      = drv_file_system_control;
+    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = drv_device_control;
+    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]                 = drv_shutdown;
+    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL]             = drv_lock_control;
+    DriverObject->MajorFunction[IRP_MJ_CLEANUP]                  = drv_cleanup;
+    DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY]           = drv_query_security;
+    DriverObject->MajorFunction[IRP_MJ_SET_SECURITY]             = drv_set_security;
+    DriverObject->MajorFunction[IRP_MJ_POWER]                    = drv_power;
+    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]           = drv_system_control;
+    DriverObject->MajorFunction[IRP_MJ_PNP]                      = drv_pnp;
+#else
     DriverObject->MajorFunction[IRP_MJ_CREATE]                   = (PDRIVER_DISPATCH)drv_create;
     DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = (PDRIVER_DISPATCH)drv_close;
     DriverObject->MajorFunction[IRP_MJ_READ]                     = (PDRIVER_DISPATCH)drv_read;
@@ -5493,6 +5666,7 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Regi
     DriverObject->MajorFunction[IRP_MJ_POWER]                    = (PDRIVER_DISPATCH)drv_power;
     DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]           = (PDRIVER_DISPATCH)drv_system_control;
     DriverObject->MajorFunction[IRP_MJ_PNP]                      = (PDRIVER_DISPATCH)drv_pnp;
+#endif
 
     init_fast_io_dispatch(&DriverObject->FastIoDispatch);
 
@@ -5537,12 +5711,19 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Regi
 
     InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
     Status = ZwCreateKey(&regh, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos);
+    /* ReactOS specific hack: allow BtrFS driver to start in 1st stage with no hive */
+#ifndef __REACTOS__
     if (!NT_SUCCESS(Status)) {
         ERR("ZwCreateKey returned %08x\n", Status);
         return Status;
     }
 
     watch_registry(regh);
+#else
+    if (NT_SUCCESS(Status)) {
+        watch_registry(regh);
+    }
+#endif
 
     Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF,
                                     NULL, NULL, 0, &cde->buspdo);