Merge tag 'for-6.0-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[sfrench/cifs-2.6.git] / fs / btrfs / disk-io.c
index 1af28b066b42a1a54c78951de8a0839b6a545532..2633137c3e9f1efc4d07bd262152104a3633e32a 100644 (file)
@@ -4474,6 +4474,17 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
 
        set_bit(BTRFS_FS_CLOSING_START, &fs_info->flags);
 
+       /*
+        * If we had UNFINISHED_DROPS we could still be processing them, so
+        * clear that bit and wake up relocation so it can stop.
+        * We must do this before stopping the block group reclaim task, because
+        * at btrfs_relocate_block_group() we wait for this bit, and after the
+        * wait we stop with -EINTR if btrfs_fs_closing() returns non-zero - we
+        * have just set BTRFS_FS_CLOSING_START, so btrfs_fs_closing() will
+        * return 1.
+        */
+       btrfs_wake_unfinished_drop(fs_info);
+
        /*
         * We may have the reclaim task running and relocating a data block group,
         * in which case it may create delayed iputs. So stop it before we park
@@ -4492,12 +4503,6 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
         */
        kthread_park(fs_info->cleaner_kthread);
 
-       /*
-        * If we had UNFINISHED_DROPS we could still be processing them, so
-        * clear that bit and wake up relocation so it can stop.
-        */
-       btrfs_wake_unfinished_drop(fs_info);
-
        /* wait for the qgroup rescan worker to stop */
        btrfs_qgroup_wait_for_completion(fs_info, false);
 
@@ -4520,6 +4525,31 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
        /* clear out the rbtree of defraggable inodes */
        btrfs_cleanup_defrag_inodes(fs_info);
 
+       /*
+        * After we parked the cleaner kthread, ordered extents may have
+        * completed and created new delayed iputs. If one of the async reclaim
+        * tasks is running and in the RUN_DELAYED_IPUTS flush state, then we
+        * can hang forever trying to stop it, because if a delayed iput is
+        * added after it ran btrfs_run_delayed_iputs() and before it called
+        * btrfs_wait_on_delayed_iputs(), it will hang forever since there is
+        * no one else to run iputs.
+        *
+        * So wait for all ongoing ordered extents to complete and then run
+        * delayed iputs. This works because once we reach this point no one
+        * can either create new ordered extents nor create delayed iputs
+        * through some other means.
+        *
+        * Also note that btrfs_wait_ordered_roots() is not safe here, because
+        * it waits for BTRFS_ORDERED_COMPLETE to be set on an ordered extent,
+        * but the delayed iput for the respective inode is made only when doing
+        * the final btrfs_put_ordered_extent() (which must happen at
+        * btrfs_finish_ordered_io() when we are unmounting).
+        */
+       btrfs_flush_workqueue(fs_info->endio_write_workers);
+       /* Ordered extents for free space inodes. */
+       btrfs_flush_workqueue(fs_info->endio_freespace_worker);
+       btrfs_run_delayed_iputs(fs_info);
+
        cancel_work_sync(&fs_info->async_reclaim_work);
        cancel_work_sync(&fs_info->async_data_reclaim_work);
        cancel_work_sync(&fs_info->preempt_reclaim_work);