diff options
Diffstat (limited to 'fs/btrfs/dev-replace.c')
-rw-r--r-- | fs/btrfs/dev-replace.c | 63 |
1 files changed, 41 insertions, 22 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 33d07c426c59..08092d329f66 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c | |||
@@ -803,39 +803,58 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info) | |||
803 | case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: | 803 | case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: |
804 | result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED; | 804 | result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED; |
805 | btrfs_dev_replace_write_unlock(dev_replace); | 805 | btrfs_dev_replace_write_unlock(dev_replace); |
806 | goto leave; | 806 | break; |
807 | case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: | 807 | case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: |
808 | result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; | ||
809 | tgt_device = dev_replace->tgtdev; | ||
810 | src_device = dev_replace->srcdev; | ||
811 | btrfs_dev_replace_write_unlock(dev_replace); | ||
812 | btrfs_scrub_cancel(fs_info); | ||
813 | /* btrfs_dev_replace_finishing() will handle the cleanup part */ | ||
814 | btrfs_info_in_rcu(fs_info, | ||
815 | "dev_replace from %s (devid %llu) to %s canceled", | ||
816 | btrfs_dev_name(src_device), src_device->devid, | ||
817 | btrfs_dev_name(tgt_device)); | ||
818 | break; | ||
808 | case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: | 819 | case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: |
820 | /* | ||
821 | * Scrub doing the replace isn't running so we need to do the | ||
822 | * cleanup step of btrfs_dev_replace_finishing() here | ||
823 | */ | ||
809 | result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; | 824 | result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; |
810 | tgt_device = dev_replace->tgtdev; | 825 | tgt_device = dev_replace->tgtdev; |
811 | src_device = dev_replace->srcdev; | 826 | src_device = dev_replace->srcdev; |
812 | dev_replace->tgtdev = NULL; | 827 | dev_replace->tgtdev = NULL; |
813 | dev_replace->srcdev = NULL; | 828 | dev_replace->srcdev = NULL; |
814 | break; | 829 | dev_replace->replace_state = |
815 | } | 830 | BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED; |
816 | dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED; | 831 | dev_replace->time_stopped = ktime_get_real_seconds(); |
817 | dev_replace->time_stopped = ktime_get_real_seconds(); | 832 | dev_replace->item_needs_writeback = 1; |
818 | dev_replace->item_needs_writeback = 1; | ||
819 | btrfs_dev_replace_write_unlock(dev_replace); | ||
820 | btrfs_scrub_cancel(fs_info); | ||
821 | 833 | ||
822 | trans = btrfs_start_transaction(root, 0); | 834 | btrfs_dev_replace_write_unlock(dev_replace); |
823 | if (IS_ERR(trans)) { | ||
824 | mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); | ||
825 | return PTR_ERR(trans); | ||
826 | } | ||
827 | ret = btrfs_commit_transaction(trans); | ||
828 | WARN_ON(ret); | ||
829 | 835 | ||
830 | btrfs_info_in_rcu(fs_info, | 836 | btrfs_scrub_cancel(fs_info); |
831 | "dev_replace from %s (devid %llu) to %s canceled", | 837 | |
832 | btrfs_dev_name(src_device), src_device->devid, | 838 | trans = btrfs_start_transaction(root, 0); |
833 | btrfs_dev_name(tgt_device)); | 839 | if (IS_ERR(trans)) { |
840 | mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); | ||
841 | return PTR_ERR(trans); | ||
842 | } | ||
843 | ret = btrfs_commit_transaction(trans); | ||
844 | WARN_ON(ret); | ||
834 | 845 | ||
835 | if (tgt_device) | 846 | btrfs_info_in_rcu(fs_info, |
836 | btrfs_destroy_dev_replace_tgtdev(tgt_device); | 847 | "suspended dev_replace from %s (devid %llu) to %s canceled", |
848 | btrfs_dev_name(src_device), src_device->devid, | ||
849 | btrfs_dev_name(tgt_device)); | ||
850 | |||
851 | if (tgt_device) | ||
852 | btrfs_destroy_dev_replace_tgtdev(tgt_device); | ||
853 | break; | ||
854 | default: | ||
855 | result = -EINVAL; | ||
856 | } | ||
837 | 857 | ||
838 | leave: | ||
839 | mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); | 858 | mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); |
840 | return result; | 859 | return result; |
841 | } | 860 | } |