btrfs: replace seed device followed by unmount causes kernel WARNING
[deliverable/linux.git] / fs / btrfs / volumes.c
index ff8386eb3367c05b312d98b100d0e4cc82a33a0f..361a66e2c179699104c2b6e9fabf7dc557f15353 100644 (file)
@@ -1815,19 +1815,29 @@ error_undo:
 void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info,
                                 struct btrfs_device *srcdev)
 {
+       struct btrfs_fs_devices *fs_devices;
+
        WARN_ON(!mutex_is_locked(&fs_info->fs_devices->device_list_mutex));
 
+       /*
+        * in case of fs with no seed, srcdev->fs_devices will point
+        * to fs_devices of fs_info. However when the dev being replaced is
+        * a seed dev it will point to the seed's local fs_devices. In short
+        * srcdev will have its correct fs_devices in both the cases.
+        */
+       fs_devices = srcdev->fs_devices;
+
        list_del_rcu(&srcdev->dev_list);
        list_del_rcu(&srcdev->dev_alloc_list);
-       fs_info->fs_devices->num_devices--;
+       fs_devices->num_devices--;
        if (srcdev->missing) {
-               fs_info->fs_devices->missing_devices--;
-               fs_info->fs_devices->rw_devices++;
+               fs_devices->missing_devices--;
+               fs_devices->rw_devices++;
        }
        if (srcdev->can_discard)
-               fs_info->fs_devices->num_can_discard--;
+               fs_devices->num_can_discard--;
        if (srcdev->bdev) {
-               fs_info->fs_devices->open_devices--;
+               fs_devices->open_devices--;
 
                /*
                 * zero out the old super if it is not writable
This page took 0.031133 seconds and 5 git commands to generate.