aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/dev-replace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/dev-replace.c')
-rw-r--r--fs/btrfs/dev-replace.c31
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
512leave: 510leave:
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;