aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorWang Shilong <wangsl.fnst@cn.fujitsu.com>2013-10-11 14:11:12 -0400
committerChris Mason <chris.mason@fusionio.com>2013-11-11 22:12:58 -0500
commit3b7a016f44d51ba8425c244f4c607f93fa213fd2 (patch)
tree5277f63351808793d863e08fe5c2e395af29e254 /fs
parent007d31f755294b9db69c3d18e90d6edae9f1604d (diff)
Btrfs: avoid unnecessary scrub workers allocation
We only allocate scrub workers if we pass all the necessary checks, for example, there are no operation in progress. Besides, move mutex lock protection outside of scrub_workers_get() /scrub_workers_put(). Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/scrub.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 12009b4279ad..2544805544f0 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -2784,7 +2784,6 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info,
2784{ 2784{
2785 int ret = 0; 2785 int ret = 0;
2786 2786
2787 mutex_lock(&fs_info->scrub_lock);
2788 if (fs_info->scrub_workers_refcnt == 0) { 2787 if (fs_info->scrub_workers_refcnt == 0) {
2789 if (is_dev_replace) 2788 if (is_dev_replace)
2790 btrfs_init_workers(&fs_info->scrub_workers, "scrub", 1, 2789 btrfs_init_workers(&fs_info->scrub_workers, "scrub", 1,
@@ -2814,21 +2813,17 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info,
2814 } 2813 }
2815 ++fs_info->scrub_workers_refcnt; 2814 ++fs_info->scrub_workers_refcnt;
2816out: 2815out:
2817 mutex_unlock(&fs_info->scrub_lock);
2818
2819 return ret; 2816 return ret;
2820} 2817}
2821 2818
2822static noinline_for_stack void scrub_workers_put(struct btrfs_fs_info *fs_info) 2819static noinline_for_stack void scrub_workers_put(struct btrfs_fs_info *fs_info)
2823{ 2820{
2824 mutex_lock(&fs_info->scrub_lock);
2825 if (--fs_info->scrub_workers_refcnt == 0) { 2821 if (--fs_info->scrub_workers_refcnt == 0) {
2826 btrfs_stop_workers(&fs_info->scrub_workers); 2822 btrfs_stop_workers(&fs_info->scrub_workers);
2827 btrfs_stop_workers(&fs_info->scrub_wr_completion_workers); 2823 btrfs_stop_workers(&fs_info->scrub_wr_completion_workers);
2828 btrfs_stop_workers(&fs_info->scrub_nocow_workers); 2824 btrfs_stop_workers(&fs_info->scrub_nocow_workers);
2829 } 2825 }
2830 WARN_ON(fs_info->scrub_workers_refcnt < 0); 2826 WARN_ON(fs_info->scrub_workers_refcnt < 0);
2831 mutex_unlock(&fs_info->scrub_lock);
2832} 2827}
2833 2828
2834int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, 2829int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
@@ -2889,23 +2884,18 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
2889 return -EINVAL; 2884 return -EINVAL;
2890 } 2885 }
2891 2886
2892 ret = scrub_workers_get(fs_info, is_dev_replace);
2893 if (ret)
2894 return ret;
2895 2887
2896 mutex_lock(&fs_info->fs_devices->device_list_mutex); 2888 mutex_lock(&fs_info->fs_devices->device_list_mutex);
2897 dev = btrfs_find_device(fs_info, devid, NULL, NULL); 2889 dev = btrfs_find_device(fs_info, devid, NULL, NULL);
2898 if (!dev || (dev->missing && !is_dev_replace)) { 2890 if (!dev || (dev->missing && !is_dev_replace)) {
2899 mutex_unlock(&fs_info->fs_devices->device_list_mutex); 2891 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
2900 scrub_workers_put(fs_info);
2901 return -ENODEV; 2892 return -ENODEV;
2902 } 2893 }
2903 mutex_lock(&fs_info->scrub_lock);
2904 2894
2895 mutex_lock(&fs_info->scrub_lock);
2905 if (!dev->in_fs_metadata || dev->is_tgtdev_for_dev_replace) { 2896 if (!dev->in_fs_metadata || dev->is_tgtdev_for_dev_replace) {
2906 mutex_unlock(&fs_info->scrub_lock); 2897 mutex_unlock(&fs_info->scrub_lock);
2907 mutex_unlock(&fs_info->fs_devices->device_list_mutex); 2898 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
2908 scrub_workers_put(fs_info);
2909 return -EIO; 2899 return -EIO;
2910 } 2900 }
2911 2901
@@ -2916,10 +2906,17 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
2916 btrfs_dev_replace_unlock(&fs_info->dev_replace); 2906 btrfs_dev_replace_unlock(&fs_info->dev_replace);
2917 mutex_unlock(&fs_info->scrub_lock); 2907 mutex_unlock(&fs_info->scrub_lock);
2918 mutex_unlock(&fs_info->fs_devices->device_list_mutex); 2908 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
2919 scrub_workers_put(fs_info);
2920 return -EINPROGRESS; 2909 return -EINPROGRESS;
2921 } 2910 }
2922 btrfs_dev_replace_unlock(&fs_info->dev_replace); 2911 btrfs_dev_replace_unlock(&fs_info->dev_replace);
2912
2913 ret = scrub_workers_get(fs_info, is_dev_replace);
2914 if (ret) {
2915 mutex_unlock(&fs_info->scrub_lock);
2916 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
2917 return ret;
2918 }
2919
2923 sctx = scrub_setup_ctx(dev, is_dev_replace); 2920 sctx = scrub_setup_ctx(dev, is_dev_replace);
2924 if (IS_ERR(sctx)) { 2921 if (IS_ERR(sctx)) {
2925 mutex_unlock(&fs_info->scrub_lock); 2922 mutex_unlock(&fs_info->scrub_lock);
@@ -2957,10 +2954,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
2957 2954
2958 mutex_lock(&fs_info->scrub_lock); 2955 mutex_lock(&fs_info->scrub_lock);
2959 dev->scrub_device = NULL; 2956 dev->scrub_device = NULL;
2957 scrub_workers_put(fs_info);
2960 mutex_unlock(&fs_info->scrub_lock); 2958 mutex_unlock(&fs_info->scrub_lock);
2961 2959
2962 scrub_free_ctx(sctx); 2960 scrub_free_ctx(sctx);
2963 scrub_workers_put(fs_info);
2964 2961
2965 return ret; 2962 return ret;
2966} 2963}