diff options
Diffstat (limited to 'fs/btrfs/dev-replace.c')
-rw-r--r-- | fs/btrfs/dev-replace.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 6f662b34ba0e..ca6a3a3b6b6c 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c | |||
@@ -316,11 +316,6 @@ int btrfs_dev_replace_start(struct btrfs_root *root, | |||
316 | struct btrfs_device *tgt_device = NULL; | 316 | struct btrfs_device *tgt_device = NULL; |
317 | struct btrfs_device *src_device = NULL; | 317 | struct btrfs_device *src_device = NULL; |
318 | 318 | ||
319 | if (btrfs_fs_incompat(fs_info, RAID56)) { | ||
320 | btrfs_warn(fs_info, "dev_replace cannot yet handle RAID5/RAID6"); | ||
321 | return -EOPNOTSUPP; | ||
322 | } | ||
323 | |||
324 | switch (args->start.cont_reading_from_srcdev_mode) { | 319 | switch (args->start.cont_reading_from_srcdev_mode) { |
325 | case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS: | 320 | case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS: |
326 | case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID: | 321 | case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID: |
@@ -422,9 +417,15 @@ int btrfs_dev_replace_start(struct btrfs_root *root, | |||
422 | &dev_replace->scrub_progress, 0, 1); | 417 | &dev_replace->scrub_progress, 0, 1); |
423 | 418 | ||
424 | ret = btrfs_dev_replace_finishing(root->fs_info, ret); | 419 | ret = btrfs_dev_replace_finishing(root->fs_info, ret); |
425 | WARN_ON(ret); | 420 | /* don't warn if EINPROGRESS, someone else might be running scrub */ |
421 | if (ret == -EINPROGRESS) { | ||
422 | args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS; | ||
423 | ret = 0; | ||
424 | } else { | ||
425 | WARN_ON(ret); | ||
426 | } | ||
426 | 427 | ||
427 | return 0; | 428 | return ret; |
428 | 429 | ||
429 | leave: | 430 | leave: |
430 | dev_replace->srcdev = NULL; | 431 | dev_replace->srcdev = NULL; |
@@ -542,7 +543,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | |||
542 | btrfs_destroy_dev_replace_tgtdev(fs_info, tgt_device); | 543 | btrfs_destroy_dev_replace_tgtdev(fs_info, tgt_device); |
543 | mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); | 544 | mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); |
544 | 545 | ||
545 | return 0; | 546 | return scrub_ret; |
546 | } | 547 | } |
547 | 548 | ||
548 | printk_in_rcu(KERN_INFO | 549 | printk_in_rcu(KERN_INFO |
@@ -571,15 +572,11 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | |||
571 | list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); | 572 | list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); |
572 | fs_info->fs_devices->rw_devices++; | 573 | fs_info->fs_devices->rw_devices++; |
573 | 574 | ||
574 | /* replace the sysfs entry */ | ||
575 | btrfs_kobj_rm_device(fs_info, src_device); | ||
576 | btrfs_kobj_add_device(fs_info, tgt_device); | ||
577 | |||
578 | btrfs_dev_replace_unlock(dev_replace); | 575 | btrfs_dev_replace_unlock(dev_replace); |
579 | 576 | ||
580 | btrfs_rm_dev_replace_blocked(fs_info); | 577 | btrfs_rm_dev_replace_blocked(fs_info); |
581 | 578 | ||
582 | btrfs_rm_dev_replace_srcdev(fs_info, src_device); | 579 | btrfs_rm_dev_replace_remove_srcdev(fs_info, src_device); |
583 | 580 | ||
584 | btrfs_rm_dev_replace_unblocked(fs_info); | 581 | btrfs_rm_dev_replace_unblocked(fs_info); |
585 | 582 | ||
@@ -594,6 +591,11 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | |||
594 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | 591 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); |
595 | mutex_unlock(&uuid_mutex); | 592 | mutex_unlock(&uuid_mutex); |
596 | 593 | ||
594 | /* replace the sysfs entry */ | ||
595 | btrfs_kobj_rm_device(fs_info, src_device); | ||
596 | btrfs_kobj_add_device(fs_info, tgt_device); | ||
597 | btrfs_rm_dev_replace_free_srcdev(fs_info, src_device); | ||
598 | |||
597 | /* write back the superblocks */ | 599 | /* write back the superblocks */ |
598 | trans = btrfs_start_transaction(root, 0); | 600 | trans = btrfs_start_transaction(root, 0); |
599 | if (!IS_ERR(trans)) | 601 | if (!IS_ERR(trans)) |
@@ -920,9 +922,9 @@ void btrfs_bio_counter_inc_noblocked(struct btrfs_fs_info *fs_info) | |||
920 | percpu_counter_inc(&fs_info->bio_counter); | 922 | percpu_counter_inc(&fs_info->bio_counter); |
921 | } | 923 | } |
922 | 924 | ||
923 | void btrfs_bio_counter_dec(struct btrfs_fs_info *fs_info) | 925 | void btrfs_bio_counter_sub(struct btrfs_fs_info *fs_info, s64 amount) |
924 | { | 926 | { |
925 | percpu_counter_dec(&fs_info->bio_counter); | 927 | percpu_counter_sub(&fs_info->bio_counter, amount); |
926 | 928 | ||
927 | if (waitqueue_active(&fs_info->replace_wait)) | 929 | if (waitqueue_active(&fs_info->replace_wait)) |
928 | wake_up(&fs_info->replace_wait); | 930 | wake_up(&fs_info->replace_wait); |