aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2018-04-04 19:04:49 -0400
committerDavid Sterba <dsterba@suse.com>2018-10-15 11:23:38 -0400
commit7f8d236ae132a8886a0186008c828e21f7460474 (patch)
tree63bf1e2dd346ebefa152cc911919eb9f47254e33
parentaa144bfeaa7f87c536ab323edfe2692285343e68 (diff)
btrfs: dev-replace: move replace members out of fs_info
The replace_wait and bio_counter were mistakenly added to fs_info in commit c404e0dc2c843b154f ("Btrfs: fix use-after-free in the finishing procedure of the device replace"), but they logically belong to fs_info::dev_replace. Besides, bio_counter is a very generic name and is confusing in bare fs_info context. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/ctree.h6
-rw-r--r--fs/btrfs/dev-replace.c16
-rw-r--r--fs/btrfs/disk-io.c9
3 files changed, 16 insertions, 15 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index daa273c7e150..e8244c0b0597 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -365,6 +365,9 @@ struct btrfs_dev_replace {
365 wait_queue_head_t read_lock_wq; 365 wait_queue_head_t read_lock_wq;
366 366
367 struct btrfs_scrub_progress scrub_progress; 367 struct btrfs_scrub_progress scrub_progress;
368
369 struct percpu_counter bio_counter;
370 wait_queue_head_t replace_wait;
368}; 371};
369 372
370/* For raid type sysfs entries */ 373/* For raid type sysfs entries */
@@ -1087,9 +1090,6 @@ struct btrfs_fs_info {
1087 /* device replace state */ 1090 /* device replace state */
1088 struct btrfs_dev_replace dev_replace; 1091 struct btrfs_dev_replace dev_replace;
1089 1092
1090 struct percpu_counter bio_counter;
1091 wait_queue_head_t replace_wait;
1092
1093 struct semaphore uuid_tree_rescan_sem; 1093 struct semaphore uuid_tree_rescan_sem;
1094 1094
1095 /* Used to reclaim the metadata space in the background. */ 1095 /* Used to reclaim the metadata space in the background. */
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index c7f2d6b91a6f..d1ea76bccaaf 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -545,8 +545,8 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,
545static void btrfs_rm_dev_replace_blocked(struct btrfs_fs_info *fs_info) 545static void btrfs_rm_dev_replace_blocked(struct btrfs_fs_info *fs_info)
546{ 546{
547 set_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state); 547 set_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state);
548 wait_event(fs_info->replace_wait, !percpu_counter_sum( 548 wait_event(fs_info->dev_replace.replace_wait, !percpu_counter_sum(
549 &fs_info->bio_counter)); 549 &fs_info->dev_replace.bio_counter));
550} 550}
551 551
552/* 552/*
@@ -555,7 +555,7 @@ static void btrfs_rm_dev_replace_blocked(struct btrfs_fs_info *fs_info)
555static void btrfs_rm_dev_replace_unblocked(struct btrfs_fs_info *fs_info) 555static void btrfs_rm_dev_replace_unblocked(struct btrfs_fs_info *fs_info)
556{ 556{
557 clear_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state); 557 clear_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state);
558 wake_up(&fs_info->replace_wait); 558 wake_up(&fs_info->dev_replace.replace_wait);
559} 559}
560 560
561static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, 561static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
@@ -997,25 +997,25 @@ void btrfs_dev_replace_set_lock_blocking(
997 997
998void btrfs_bio_counter_inc_noblocked(struct btrfs_fs_info *fs_info) 998void btrfs_bio_counter_inc_noblocked(struct btrfs_fs_info *fs_info)
999{ 999{
1000 percpu_counter_inc(&fs_info->bio_counter); 1000 percpu_counter_inc(&fs_info->dev_replace.bio_counter);
1001} 1001}
1002 1002
1003void btrfs_bio_counter_sub(struct btrfs_fs_info *fs_info, s64 amount) 1003void btrfs_bio_counter_sub(struct btrfs_fs_info *fs_info, s64 amount)
1004{ 1004{
1005 percpu_counter_sub(&fs_info->bio_counter, amount); 1005 percpu_counter_sub(&fs_info->dev_replace.bio_counter, amount);
1006 cond_wake_up_nomb(&fs_info->replace_wait); 1006 cond_wake_up_nomb(&fs_info->dev_replace.replace_wait);
1007} 1007}
1008 1008
1009void btrfs_bio_counter_inc_blocked(struct btrfs_fs_info *fs_info) 1009void btrfs_bio_counter_inc_blocked(struct btrfs_fs_info *fs_info)
1010{ 1010{
1011 while (1) { 1011 while (1) {
1012 percpu_counter_inc(&fs_info->bio_counter); 1012 percpu_counter_inc(&fs_info->dev_replace.bio_counter);
1013 if (likely(!test_bit(BTRFS_FS_STATE_DEV_REPLACING, 1013 if (likely(!test_bit(BTRFS_FS_STATE_DEV_REPLACING,
1014 &fs_info->fs_state))) 1014 &fs_info->fs_state)))
1015 break; 1015 break;
1016 1016
1017 btrfs_bio_counter_dec(fs_info); 1017 btrfs_bio_counter_dec(fs_info);
1018 wait_event(fs_info->replace_wait, 1018 wait_event(fs_info->dev_replace.replace_wait,
1019 !test_bit(BTRFS_FS_STATE_DEV_REPLACING, 1019 !test_bit(BTRFS_FS_STATE_DEV_REPLACING,
1020 &fs_info->fs_state)); 1020 &fs_info->fs_state));
1021 } 1021 }
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 79903243877b..27f6a3348f94 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2156,7 +2156,7 @@ static void btrfs_init_dev_replace_locks(struct btrfs_fs_info *fs_info)
2156 mutex_init(&fs_info->dev_replace.lock_finishing_cancel_unmount); 2156 mutex_init(&fs_info->dev_replace.lock_finishing_cancel_unmount);
2157 rwlock_init(&fs_info->dev_replace.lock); 2157 rwlock_init(&fs_info->dev_replace.lock);
2158 atomic_set(&fs_info->dev_replace.blocking_readers, 0); 2158 atomic_set(&fs_info->dev_replace.blocking_readers, 0);
2159 init_waitqueue_head(&fs_info->replace_wait); 2159 init_waitqueue_head(&fs_info->dev_replace.replace_wait);
2160 init_waitqueue_head(&fs_info->dev_replace.read_lock_wq); 2160 init_waitqueue_head(&fs_info->dev_replace.read_lock_wq);
2161} 2161}
2162 2162
@@ -2646,7 +2646,8 @@ int open_ctree(struct super_block *sb,
2646 goto fail_dirty_metadata_bytes; 2646 goto fail_dirty_metadata_bytes;
2647 } 2647 }
2648 2648
2649 ret = percpu_counter_init(&fs_info->bio_counter, 0, GFP_KERNEL); 2649 ret = percpu_counter_init(&fs_info->dev_replace.bio_counter, 0,
2650 GFP_KERNEL);
2650 if (ret) { 2651 if (ret) {
2651 err = ret; 2652 err = ret;
2652 goto fail_delalloc_bytes; 2653 goto fail_delalloc_bytes;
@@ -3307,7 +3308,7 @@ fail_iput:
3307 3308
3308 iput(fs_info->btree_inode); 3309 iput(fs_info->btree_inode);
3309fail_bio_counter: 3310fail_bio_counter:
3310 percpu_counter_destroy(&fs_info->bio_counter); 3311 percpu_counter_destroy(&fs_info->dev_replace.bio_counter);
3311fail_delalloc_bytes: 3312fail_delalloc_bytes:
3312 percpu_counter_destroy(&fs_info->delalloc_bytes); 3313 percpu_counter_destroy(&fs_info->delalloc_bytes);
3313fail_dirty_metadata_bytes: 3314fail_dirty_metadata_bytes:
@@ -4016,7 +4017,7 @@ void close_ctree(struct btrfs_fs_info *fs_info)
4016 4017
4017 percpu_counter_destroy(&fs_info->dirty_metadata_bytes); 4018 percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
4018 percpu_counter_destroy(&fs_info->delalloc_bytes); 4019 percpu_counter_destroy(&fs_info->delalloc_bytes);
4019 percpu_counter_destroy(&fs_info->bio_counter); 4020 percpu_counter_destroy(&fs_info->dev_replace.bio_counter);
4020 cleanup_srcu_struct(&fs_info->subvol_srcu); 4021 cleanup_srcu_struct(&fs_info->subvol_srcu);
4021 4022
4022 btrfs_free_stripe_hash_table(fs_info); 4023 btrfs_free_stripe_hash_table(fs_info);