diff options
Diffstat (limited to 'fs/btrfs/dev-replace.c')
-rw-r--r-- | fs/btrfs/dev-replace.c | 31 |
1 files changed, 13 insertions, 18 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index ee0989c7e3a9..6b2e9aa83ffa 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c | |||
@@ -201,7 +201,7 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, | |||
201 | return PTR_ERR(bdev); | 201 | return PTR_ERR(bdev); |
202 | } | 202 | } |
203 | 203 | ||
204 | filemap_write_and_wait(bdev->bd_inode->i_mapping); | 204 | sync_blockdev(bdev); |
205 | 205 | ||
206 | devices = &fs_info->fs_devices->devices; | 206 | devices = &fs_info->fs_devices->devices; |
207 | list_for_each_entry(device, devices, dev_list) { | 207 | list_for_each_entry(device, devices, dev_list) { |
@@ -237,7 +237,6 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, | |||
237 | } | 237 | } |
238 | rcu_assign_pointer(device->name, name); | 238 | rcu_assign_pointer(device->name, name); |
239 | 239 | ||
240 | mutex_lock(&fs_info->fs_devices->device_list_mutex); | ||
241 | set_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state); | 240 | set_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state); |
242 | device->generation = 0; | 241 | device->generation = 0; |
243 | device->io_width = fs_info->sectorsize; | 242 | device->io_width = fs_info->sectorsize; |
@@ -256,6 +255,8 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, | |||
256 | device->dev_stats_valid = 1; | 255 | device->dev_stats_valid = 1; |
257 | set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE); | 256 | set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE); |
258 | device->fs_devices = fs_info->fs_devices; | 257 | device->fs_devices = fs_info->fs_devices; |
258 | |||
259 | mutex_lock(&fs_info->fs_devices->device_list_mutex); | ||
259 | list_add(&device->dev_list, &fs_info->fs_devices->devices); | 260 | list_add(&device->dev_list, &fs_info->fs_devices->devices); |
260 | fs_info->fs_devices->num_devices++; | 261 | fs_info->fs_devices->num_devices++; |
261 | fs_info->fs_devices->open_devices++; | 262 | fs_info->fs_devices->open_devices++; |
@@ -399,7 +400,6 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, | |||
399 | int ret; | 400 | int ret; |
400 | struct btrfs_device *tgt_device = NULL; | 401 | struct btrfs_device *tgt_device = NULL; |
401 | struct btrfs_device *src_device = NULL; | 402 | struct btrfs_device *src_device = NULL; |
402 | bool need_unlock; | ||
403 | 403 | ||
404 | src_device = btrfs_find_device_by_devspec(fs_info, srcdevid, | 404 | src_device = btrfs_find_device_by_devspec(fs_info, srcdevid, |
405 | srcdev_name); | 405 | srcdev_name); |
@@ -413,11 +413,6 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, | |||
413 | return -ETXTBSY; | 413 | return -ETXTBSY; |
414 | } | 414 | } |
415 | 415 | ||
416 | ret = btrfs_init_dev_replace_tgtdev(fs_info, tgtdev_name, | ||
417 | src_device, &tgt_device); | ||
418 | if (ret) | ||
419 | return ret; | ||
420 | |||
421 | /* | 416 | /* |
422 | * Here we commit the transaction to make sure commit_total_bytes | 417 | * Here we commit the transaction to make sure commit_total_bytes |
423 | * of all the devices are updated. | 418 | * of all the devices are updated. |
@@ -431,7 +426,11 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, | |||
431 | return PTR_ERR(trans); | 426 | return PTR_ERR(trans); |
432 | } | 427 | } |
433 | 428 | ||
434 | need_unlock = true; | 429 | ret = btrfs_init_dev_replace_tgtdev(fs_info, tgtdev_name, |
430 | src_device, &tgt_device); | ||
431 | if (ret) | ||
432 | return ret; | ||
433 | |||
435 | down_write(&dev_replace->rwsem); | 434 | down_write(&dev_replace->rwsem); |
436 | switch (dev_replace->replace_state) { | 435 | switch (dev_replace->replace_state) { |
437 | case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: | 436 | case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: |
@@ -442,11 +441,11 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, | |||
442 | case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: | 441 | case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: |
443 | ASSERT(0); | 442 | ASSERT(0); |
444 | ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED; | 443 | ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED; |
444 | up_write(&dev_replace->rwsem); | ||
445 | goto leave; | 445 | goto leave; |
446 | } | 446 | } |
447 | 447 | ||
448 | dev_replace->cont_reading_from_srcdev_mode = read_src; | 448 | dev_replace->cont_reading_from_srcdev_mode = read_src; |
449 | WARN_ON(!src_device); | ||
450 | dev_replace->srcdev = src_device; | 449 | dev_replace->srcdev = src_device; |
451 | dev_replace->tgtdev = tgt_device; | 450 | dev_replace->tgtdev = tgt_device; |
452 | 451 | ||
@@ -471,7 +470,6 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, | |||
471 | atomic64_set(&dev_replace->num_write_errors, 0); | 470 | atomic64_set(&dev_replace->num_write_errors, 0); |
472 | atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0); | 471 | atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0); |
473 | up_write(&dev_replace->rwsem); | 472 | up_write(&dev_replace->rwsem); |
474 | need_unlock = false; | ||
475 | 473 | ||
476 | ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device); | 474 | ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device); |
477 | if (ret) | 475 | if (ret) |
@@ -479,16 +477,16 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, | |||
479 | 477 | ||
480 | btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1); | 478 | btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1); |
481 | 479 | ||
482 | /* force writing the updated state information to disk */ | 480 | /* Commit dev_replace state and reserve 1 item for it. */ |
483 | trans = btrfs_start_transaction(root, 0); | 481 | trans = btrfs_start_transaction(root, 1); |
484 | if (IS_ERR(trans)) { | 482 | if (IS_ERR(trans)) { |
485 | ret = PTR_ERR(trans); | 483 | ret = PTR_ERR(trans); |
486 | need_unlock = true; | ||
487 | down_write(&dev_replace->rwsem); | 484 | down_write(&dev_replace->rwsem); |
488 | dev_replace->replace_state = | 485 | dev_replace->replace_state = |
489 | BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED; | 486 | BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED; |
490 | dev_replace->srcdev = NULL; | 487 | dev_replace->srcdev = NULL; |
491 | dev_replace->tgtdev = NULL; | 488 | dev_replace->tgtdev = NULL; |
489 | up_write(&dev_replace->rwsem); | ||
492 | goto leave; | 490 | goto leave; |
493 | } | 491 | } |
494 | 492 | ||
@@ -510,8 +508,6 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, | |||
510 | return ret; | 508 | return ret; |
511 | 509 | ||
512 | leave: | 510 | leave: |
513 | if (need_unlock) | ||
514 | up_write(&dev_replace->rwsem); | ||
515 | btrfs_destroy_dev_replace_tgtdev(tgt_device); | 511 | btrfs_destroy_dev_replace_tgtdev(tgt_device); |
516 | return ret; | 512 | return ret; |
517 | } | 513 | } |
@@ -678,7 +674,6 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | |||
678 | btrfs_device_set_disk_total_bytes(tgt_device, | 674 | btrfs_device_set_disk_total_bytes(tgt_device, |
679 | src_device->disk_total_bytes); | 675 | src_device->disk_total_bytes); |
680 | btrfs_device_set_bytes_used(tgt_device, src_device->bytes_used); | 676 | btrfs_device_set_bytes_used(tgt_device, src_device->bytes_used); |
681 | tgt_device->commit_total_bytes = src_device->commit_total_bytes; | ||
682 | tgt_device->commit_bytes_used = src_device->bytes_used; | 677 | tgt_device->commit_bytes_used = src_device->bytes_used; |
683 | 678 | ||
684 | btrfs_assign_next_active_device(src_device, tgt_device); | 679 | btrfs_assign_next_active_device(src_device, tgt_device); |
@@ -728,7 +723,7 @@ static void btrfs_dev_replace_update_device_in_mapping_tree( | |||
728 | struct btrfs_device *srcdev, | 723 | struct btrfs_device *srcdev, |
729 | struct btrfs_device *tgtdev) | 724 | struct btrfs_device *tgtdev) |
730 | { | 725 | { |
731 | struct extent_map_tree *em_tree = &fs_info->mapping_tree.map_tree; | 726 | struct extent_map_tree *em_tree = &fs_info->mapping_tree; |
732 | struct extent_map *em; | 727 | struct extent_map *em; |
733 | struct map_lookup *map; | 728 | struct map_lookup *map; |
734 | u64 start = 0; | 729 | u64 start = 0; |