btrfs: dev-replace: go back to suspended state if target device is missing
[sfrench/cifs-2.6.git] / fs / btrfs / dev-replace.c
index 2aa48aecc52b75a95eb1e19e7a1974d8ad800dde..11df8f778b637478701dbc02c31ed70f6f11505a 100644 (file)
@@ -59,7 +59,6 @@ no_valid_dev_replace_entry_found:
                        BTRFS_DEV_REPLACE_ITEM_STATE_NEVER_STARTED;
                dev_replace->cont_reading_from_srcdev_mode =
                    BTRFS_DEV_REPLACE_ITEM_CONT_READING_FROM_SRCDEV_MODE_ALWAYS;
-               dev_replace->replace_state = 0;
                dev_replace->time_started = 0;
                dev_replace->time_stopped = 0;
                atomic64_set(&dev_replace->num_write_errors, 0);
@@ -390,7 +389,7 @@ static char* btrfs_dev_name(struct btrfs_device *device)
                return rcu_str_deref(device->name);
 }
 
-int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
+static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
                const char *tgtdev_name, u64 srcdevid, const char *srcdev_name,
                int read_src)
 {
@@ -407,6 +406,13 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
        if (IS_ERR(src_device))
                return PTR_ERR(src_device);
 
+       if (btrfs_pinned_by_swapfile(fs_info, src_device)) {
+               btrfs_warn_in_rcu(fs_info,
+         "cannot replace device %s (devid %llu) due to active swapfile",
+                       btrfs_dev_name(src_device), src_device->devid);
+               return -ETXTBSY;
+       }
+
        ret = btrfs_init_dev_replace_tgtdev(fs_info, tgtdev_name,
                                            src_device, &tgt_device);
        if (ret)
@@ -884,6 +890,8 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
                           "cannot continue dev_replace, tgtdev is missing");
                btrfs_info(fs_info,
                           "you may cancel the operation after 'mount -o degraded'");
+               dev_replace->replace_state =
+                                       BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED;
                btrfs_dev_replace_write_unlock(dev_replace);
                return 0;
        }