aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/dev-replace.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2018-03-23 21:11:38 -0400
committerDavid Sterba <dsterba@suse.com>2018-03-30 20:01:07 -0400
commit7e79cb86be28ed8073870c22f479b3b1293ecb85 (patch)
tree40473571871d71e5ab63bd4f6521882e92bd100e /fs/btrfs/dev-replace.c
parente7ab0af6c30f763e41a1206318d4756d270e93a0 (diff)
btrfs: split dev-replace locking helpers for read and write
The current calls are unclear in what way btrfs_dev_replace_lock takes the locks, so drop the argument, split the helpers and use similar naming as for read and write locks. Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/dev-replace.c')
-rw-r--r--fs/btrfs/dev-replace.c98
1 files changed, 49 insertions, 49 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index e279f04b3388..0d203633bb96 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -205,13 +205,13 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
205 struct btrfs_dev_replace_item *ptr; 205 struct btrfs_dev_replace_item *ptr;
206 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; 206 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
207 207
208 btrfs_dev_replace_lock(dev_replace, 0); 208 btrfs_dev_replace_read_lock(dev_replace);
209 if (!dev_replace->is_valid || 209 if (!dev_replace->is_valid ||
210 !dev_replace->item_needs_writeback) { 210 !dev_replace->item_needs_writeback) {
211 btrfs_dev_replace_unlock(dev_replace, 0); 211 btrfs_dev_replace_read_unlock(dev_replace);
212 return 0; 212 return 0;
213 } 213 }
214 btrfs_dev_replace_unlock(dev_replace, 0); 214 btrfs_dev_replace_read_unlock(dev_replace);
215 215
216 key.objectid = 0; 216 key.objectid = 0;
217 key.type = BTRFS_DEV_REPLACE_KEY; 217 key.type = BTRFS_DEV_REPLACE_KEY;
@@ -269,7 +269,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
269 ptr = btrfs_item_ptr(eb, path->slots[0], 269 ptr = btrfs_item_ptr(eb, path->slots[0],
270 struct btrfs_dev_replace_item); 270 struct btrfs_dev_replace_item);
271 271
272 btrfs_dev_replace_lock(dev_replace, 1); 272 btrfs_dev_replace_write_lock(dev_replace);
273 if (dev_replace->srcdev) 273 if (dev_replace->srcdev)
274 btrfs_set_dev_replace_src_devid(eb, ptr, 274 btrfs_set_dev_replace_src_devid(eb, ptr,
275 dev_replace->srcdev->devid); 275 dev_replace->srcdev->devid);
@@ -292,7 +292,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
292 btrfs_set_dev_replace_cursor_right(eb, ptr, 292 btrfs_set_dev_replace_cursor_right(eb, ptr,
293 dev_replace->cursor_right); 293 dev_replace->cursor_right);
294 dev_replace->item_needs_writeback = 0; 294 dev_replace->item_needs_writeback = 0;
295 btrfs_dev_replace_unlock(dev_replace, 1); 295 btrfs_dev_replace_write_unlock(dev_replace);
296 296
297 btrfs_mark_buffer_dirty(eb); 297 btrfs_mark_buffer_dirty(eb);
298 298
@@ -357,7 +357,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
357 return PTR_ERR(trans); 357 return PTR_ERR(trans);
358 } 358 }
359 359
360 btrfs_dev_replace_lock(dev_replace, 1); 360 btrfs_dev_replace_write_lock(dev_replace);
361 switch (dev_replace->replace_state) { 361 switch (dev_replace->replace_state) {
362 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: 362 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
363 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: 363 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
@@ -395,7 +395,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
395 dev_replace->item_needs_writeback = 1; 395 dev_replace->item_needs_writeback = 1;
396 atomic64_set(&dev_replace->num_write_errors, 0); 396 atomic64_set(&dev_replace->num_write_errors, 0);
397 atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0); 397 atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0);
398 btrfs_dev_replace_unlock(dev_replace, 1); 398 btrfs_dev_replace_write_unlock(dev_replace);
399 399
400 ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device); 400 ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device);
401 if (ret) 401 if (ret)
@@ -407,7 +407,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
407 trans = btrfs_start_transaction(root, 0); 407 trans = btrfs_start_transaction(root, 0);
408 if (IS_ERR(trans)) { 408 if (IS_ERR(trans)) {
409 ret = PTR_ERR(trans); 409 ret = PTR_ERR(trans);
410 btrfs_dev_replace_lock(dev_replace, 1); 410 btrfs_dev_replace_write_lock(dev_replace);
411 goto leave; 411 goto leave;
412 } 412 }
413 413
@@ -431,7 +431,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
431leave: 431leave:
432 dev_replace->srcdev = NULL; 432 dev_replace->srcdev = NULL;
433 dev_replace->tgtdev = NULL; 433 dev_replace->tgtdev = NULL;
434 btrfs_dev_replace_unlock(dev_replace, 1); 434 btrfs_dev_replace_write_unlock(dev_replace);
435 btrfs_destroy_dev_replace_tgtdev(fs_info, tgt_device); 435 btrfs_destroy_dev_replace_tgtdev(fs_info, tgt_device);
436 return ret; 436 return ret;
437} 437}
@@ -498,18 +498,18 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
498 /* don't allow cancel or unmount to disturb the finishing procedure */ 498 /* don't allow cancel or unmount to disturb the finishing procedure */
499 mutex_lock(&dev_replace->lock_finishing_cancel_unmount); 499 mutex_lock(&dev_replace->lock_finishing_cancel_unmount);
500 500
501 btrfs_dev_replace_lock(dev_replace, 0); 501 btrfs_dev_replace_read_lock(dev_replace);
502 /* was the operation canceled, or is it finished? */ 502 /* was the operation canceled, or is it finished? */
503 if (dev_replace->replace_state != 503 if (dev_replace->replace_state !=
504 BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED) { 504 BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED) {
505 btrfs_dev_replace_unlock(dev_replace, 0); 505 btrfs_dev_replace_read_unlock(dev_replace);
506 mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); 506 mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
507 return 0; 507 return 0;
508 } 508 }
509 509
510 tgt_device = dev_replace->tgtdev; 510 tgt_device = dev_replace->tgtdev;
511 src_device = dev_replace->srcdev; 511 src_device = dev_replace->srcdev;
512 btrfs_dev_replace_unlock(dev_replace, 0); 512 btrfs_dev_replace_read_unlock(dev_replace);
513 513
514 /* 514 /*
515 * flush all outstanding I/O and inode extent mappings before the 515 * flush all outstanding I/O and inode extent mappings before the
@@ -534,7 +534,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
534 /* keep away write_all_supers() during the finishing procedure */ 534 /* keep away write_all_supers() during the finishing procedure */
535 mutex_lock(&fs_info->fs_devices->device_list_mutex); 535 mutex_lock(&fs_info->fs_devices->device_list_mutex);
536 mutex_lock(&fs_info->chunk_mutex); 536 mutex_lock(&fs_info->chunk_mutex);
537 btrfs_dev_replace_lock(dev_replace, 1); 537 btrfs_dev_replace_write_lock(dev_replace);
538 dev_replace->replace_state = 538 dev_replace->replace_state =
539 scrub_ret ? BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED 539 scrub_ret ? BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED
540 : BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED; 540 : BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED;
@@ -554,7 +554,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
554 btrfs_dev_name(src_device), 554 btrfs_dev_name(src_device),
555 src_device->devid, 555 src_device->devid,
556 rcu_str_deref(tgt_device->name), scrub_ret); 556 rcu_str_deref(tgt_device->name), scrub_ret);
557 btrfs_dev_replace_unlock(dev_replace, 1); 557 btrfs_dev_replace_write_unlock(dev_replace);
558 mutex_unlock(&fs_info->chunk_mutex); 558 mutex_unlock(&fs_info->chunk_mutex);
559 mutex_unlock(&fs_info->fs_devices->device_list_mutex); 559 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
560 mutex_unlock(&uuid_mutex); 560 mutex_unlock(&uuid_mutex);
@@ -591,7 +591,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
591 list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); 591 list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list);
592 fs_info->fs_devices->rw_devices++; 592 fs_info->fs_devices->rw_devices++;
593 593
594 btrfs_dev_replace_unlock(dev_replace, 1); 594 btrfs_dev_replace_write_unlock(dev_replace);
595 595
596 btrfs_rm_dev_replace_blocked(fs_info); 596 btrfs_rm_dev_replace_blocked(fs_info);
597 597
@@ -684,7 +684,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
684{ 684{
685 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; 685 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
686 686
687 btrfs_dev_replace_lock(dev_replace, 0); 687 btrfs_dev_replace_read_lock(dev_replace);
688 /* even if !dev_replace_is_valid, the values are good enough for 688 /* even if !dev_replace_is_valid, the values are good enough for
689 * the replace_status ioctl */ 689 * the replace_status ioctl */
690 args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; 690 args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
@@ -696,7 +696,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
696 args->status.num_uncorrectable_read_errors = 696 args->status.num_uncorrectable_read_errors =
697 atomic64_read(&dev_replace->num_uncorrectable_read_errors); 697 atomic64_read(&dev_replace->num_uncorrectable_read_errors);
698 args->status.progress_1000 = btrfs_dev_replace_progress(fs_info); 698 args->status.progress_1000 = btrfs_dev_replace_progress(fs_info);
699 btrfs_dev_replace_unlock(dev_replace, 0); 699 btrfs_dev_replace_read_unlock(dev_replace);
700} 700}
701 701
702int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info) 702int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
@@ -713,13 +713,13 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
713 return -EROFS; 713 return -EROFS;
714 714
715 mutex_lock(&dev_replace->lock_finishing_cancel_unmount); 715 mutex_lock(&dev_replace->lock_finishing_cancel_unmount);
716 btrfs_dev_replace_lock(dev_replace, 1); 716 btrfs_dev_replace_write_lock(dev_replace);
717 switch (dev_replace->replace_state) { 717 switch (dev_replace->replace_state) {
718 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: 718 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
719 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: 719 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
720 case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: 720 case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
721 result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED; 721 result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED;
722 btrfs_dev_replace_unlock(dev_replace, 1); 722 btrfs_dev_replace_write_unlock(dev_replace);
723 goto leave; 723 goto leave;
724 case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: 724 case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
725 case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: 725 case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
@@ -733,7 +733,7 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
733 dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED; 733 dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED;
734 dev_replace->time_stopped = get_seconds(); 734 dev_replace->time_stopped = get_seconds();
735 dev_replace->item_needs_writeback = 1; 735 dev_replace->item_needs_writeback = 1;
736 btrfs_dev_replace_unlock(dev_replace, 1); 736 btrfs_dev_replace_write_unlock(dev_replace);
737 btrfs_scrub_cancel(fs_info); 737 btrfs_scrub_cancel(fs_info);
738 738
739 trans = btrfs_start_transaction(root, 0); 739 trans = btrfs_start_transaction(root, 0);
@@ -762,7 +762,7 @@ void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info)
762 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; 762 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
763 763
764 mutex_lock(&dev_replace->lock_finishing_cancel_unmount); 764 mutex_lock(&dev_replace->lock_finishing_cancel_unmount);
765 btrfs_dev_replace_lock(dev_replace, 1); 765 btrfs_dev_replace_write_lock(dev_replace);
766 switch (dev_replace->replace_state) { 766 switch (dev_replace->replace_state) {
767 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: 767 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
768 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: 768 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
@@ -778,7 +778,7 @@ void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info)
778 break; 778 break;
779 } 779 }
780 780
781 btrfs_dev_replace_unlock(dev_replace, 1); 781 btrfs_dev_replace_write_unlock(dev_replace);
782 mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); 782 mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
783} 783}
784 784
@@ -788,12 +788,12 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
788 struct task_struct *task; 788 struct task_struct *task;
789 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; 789 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
790 790
791 btrfs_dev_replace_lock(dev_replace, 1); 791 btrfs_dev_replace_write_lock(dev_replace);
792 switch (dev_replace->replace_state) { 792 switch (dev_replace->replace_state) {
793 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: 793 case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
794 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: 794 case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
795 case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: 795 case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
796 btrfs_dev_replace_unlock(dev_replace, 1); 796 btrfs_dev_replace_write_unlock(dev_replace);
797 return 0; 797 return 0;
798 case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: 798 case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
799 break; 799 break;
@@ -807,10 +807,10 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
807 "cannot continue dev_replace, tgtdev is missing"); 807 "cannot continue dev_replace, tgtdev is missing");
808 btrfs_info(fs_info, 808 btrfs_info(fs_info,
809 "you may cancel the operation after 'mount -o degraded'"); 809 "you may cancel the operation after 'mount -o degraded'");
810 btrfs_dev_replace_unlock(dev_replace, 1); 810 btrfs_dev_replace_write_unlock(dev_replace);
811 return 0; 811 return 0;
812 } 812 }
813 btrfs_dev_replace_unlock(dev_replace, 1); 813 btrfs_dev_replace_write_unlock(dev_replace);
814 814
815 WARN_ON(test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)); 815 WARN_ON(test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags));
816 task = kthread_run(btrfs_dev_replace_kthread, fs_info, "btrfs-devrepl"); 816 task = kthread_run(btrfs_dev_replace_kthread, fs_info, "btrfs-devrepl");
@@ -879,37 +879,37 @@ int btrfs_dev_replace_is_ongoing(struct btrfs_dev_replace *dev_replace)
879 return 1; 879 return 1;
880} 880}
881 881
882void btrfs_dev_replace_lock(struct btrfs_dev_replace *dev_replace, int rw) 882void btrfs_dev_replace_read_lock(struct btrfs_dev_replace *dev_replace)
883{ 883{
884 if (rw == 1) { 884 read_lock(&dev_replace->lock);
885 /* write */ 885 atomic_inc(&dev_replace->read_locks);
886again:
887 wait_event(dev_replace->read_lock_wq,
888 atomic_read(&dev_replace->blocking_readers) == 0);
889 write_lock(&dev_replace->lock);
890 if (atomic_read(&dev_replace->blocking_readers)) {
891 write_unlock(&dev_replace->lock);
892 goto again;
893 }
894 } else {
895 read_lock(&dev_replace->lock);
896 atomic_inc(&dev_replace->read_locks);
897 }
898} 886}
899 887
900void btrfs_dev_replace_unlock(struct btrfs_dev_replace *dev_replace, int rw) 888void btrfs_dev_replace_read_unlock(struct btrfs_dev_replace *dev_replace)
901{ 889{
902 if (rw == 1) { 890 ASSERT(atomic_read(&dev_replace->read_locks) > 0);
903 /* write */ 891 atomic_dec(&dev_replace->read_locks);
904 ASSERT(atomic_read(&dev_replace->blocking_readers) == 0); 892 read_unlock(&dev_replace->lock);
893}
894
895void btrfs_dev_replace_write_lock(struct btrfs_dev_replace *dev_replace)
896{
897again:
898 wait_event(dev_replace->read_lock_wq,
899 atomic_read(&dev_replace->blocking_readers) == 0);
900 write_lock(&dev_replace->lock);
901 if (atomic_read(&dev_replace->blocking_readers)) {
905 write_unlock(&dev_replace->lock); 902 write_unlock(&dev_replace->lock);
906 } else { 903 goto again;
907 ASSERT(atomic_read(&dev_replace->read_locks) > 0);
908 atomic_dec(&dev_replace->read_locks);
909 read_unlock(&dev_replace->lock);
910 } 904 }
911} 905}
912 906
907void btrfs_dev_replace_write_unlock(struct btrfs_dev_replace *dev_replace)
908{
909 ASSERT(atomic_read(&dev_replace->blocking_readers) == 0);
910 write_unlock(&dev_replace->lock);
911}
912
913/* inc blocking cnt and release read lock */ 913/* inc blocking cnt and release read lock */
914void btrfs_dev_replace_set_lock_blocking( 914void btrfs_dev_replace_set_lock_blocking(
915 struct btrfs_dev_replace *dev_replace) 915 struct btrfs_dev_replace *dev_replace)