diff options
author | Li Zefan <lizf@cn.fujitsu.com> | 2011-11-30 23:55:47 -0500 |
---|---|---|
committer | Li Zefan <lizf@cn.fujitsu.com> | 2012-01-10 21:26:44 -0500 |
commit | de11cc12df17337979e0929d2831887432f236ca (patch) | |
tree | a9232dd3531707f49c5e56523019a1e0ce081876 /fs/btrfs | |
parent | 125ccb0ae6806dbec31abf4a85448971df3b4e39 (diff) |
Btrfs: don't pre-allocate btrfs bio
We pre-allocate a btrfs bio with fixed size, and then may re-allocate
memory if we find stripes are bigger than the fixed size. But this
pre-allocation is not necessary.
Also we don't have to calcuate the stripe number twice.
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/volumes.c | 67 |
1 files changed, 21 insertions, 46 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 73f673c8d8d8..540fdd25fb5e 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -2897,26 +2897,13 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, | |||
2897 | u64 stripe_nr; | 2897 | u64 stripe_nr; |
2898 | u64 stripe_nr_orig; | 2898 | u64 stripe_nr_orig; |
2899 | u64 stripe_nr_end; | 2899 | u64 stripe_nr_end; |
2900 | int stripes_allocated = 8; | ||
2901 | int stripes_required = 1; | ||
2902 | int stripe_index; | 2900 | int stripe_index; |
2903 | int i; | 2901 | int i; |
2902 | int ret = 0; | ||
2904 | int num_stripes; | 2903 | int num_stripes; |
2905 | int max_errors = 0; | 2904 | int max_errors = 0; |
2906 | struct btrfs_bio *bbio = NULL; | 2905 | struct btrfs_bio *bbio = NULL; |
2907 | 2906 | ||
2908 | if (bbio_ret && !(rw & (REQ_WRITE | REQ_DISCARD))) | ||
2909 | stripes_allocated = 1; | ||
2910 | again: | ||
2911 | if (bbio_ret) { | ||
2912 | bbio = kzalloc(btrfs_bio_size(stripes_allocated), | ||
2913 | GFP_NOFS); | ||
2914 | if (!bbio) | ||
2915 | return -ENOMEM; | ||
2916 | |||
2917 | atomic_set(&bbio->error, 0); | ||
2918 | } | ||
2919 | |||
2920 | read_lock(&em_tree->lock); | 2907 | read_lock(&em_tree->lock); |
2921 | em = lookup_extent_mapping(em_tree, logical, *length); | 2908 | em = lookup_extent_mapping(em_tree, logical, *length); |
2922 | read_unlock(&em_tree->lock); | 2909 | read_unlock(&em_tree->lock); |
@@ -2935,32 +2922,6 @@ again: | |||
2935 | if (mirror_num > map->num_stripes) | 2922 | if (mirror_num > map->num_stripes) |
2936 | mirror_num = 0; | 2923 | mirror_num = 0; |
2937 | 2924 | ||
2938 | /* if our btrfs_bio struct is too small, back off and try again */ | ||
2939 | if (rw & REQ_WRITE) { | ||
2940 | if (map->type & (BTRFS_BLOCK_GROUP_RAID1 | | ||
2941 | BTRFS_BLOCK_GROUP_DUP)) { | ||
2942 | stripes_required = map->num_stripes; | ||
2943 | max_errors = 1; | ||
2944 | } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) { | ||
2945 | stripes_required = map->sub_stripes; | ||
2946 | max_errors = 1; | ||
2947 | } | ||
2948 | } | ||
2949 | if (rw & REQ_DISCARD) { | ||
2950 | if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | | ||
2951 | BTRFS_BLOCK_GROUP_RAID1 | | ||
2952 | BTRFS_BLOCK_GROUP_DUP | | ||
2953 | BTRFS_BLOCK_GROUP_RAID10)) { | ||
2954 | stripes_required = map->num_stripes; | ||
2955 | } | ||
2956 | } | ||
2957 | if (bbio_ret && (rw & (REQ_WRITE | REQ_DISCARD)) && | ||
2958 | stripes_allocated < stripes_required) { | ||
2959 | stripes_allocated = map->num_stripes; | ||
2960 | free_extent_map(em); | ||
2961 | kfree(bbio); | ||
2962 | goto again; | ||
2963 | } | ||
2964 | stripe_nr = offset; | 2925 | stripe_nr = offset; |
2965 | /* | 2926 | /* |
2966 | * stripe_nr counts the total number of stripes we have to stride | 2927 | * stripe_nr counts the total number of stripes we have to stride |
@@ -3055,6 +3016,13 @@ again: | |||
3055 | } | 3016 | } |
3056 | BUG_ON(stripe_index >= map->num_stripes); | 3017 | BUG_ON(stripe_index >= map->num_stripes); |
3057 | 3018 | ||
3019 | bbio = kzalloc(btrfs_bio_size(num_stripes), GFP_NOFS); | ||
3020 | if (!bbio) { | ||
3021 | ret = -ENOMEM; | ||
3022 | goto out; | ||
3023 | } | ||
3024 | atomic_set(&bbio->error, 0); | ||
3025 | |||
3058 | if (rw & REQ_DISCARD) { | 3026 | if (rw & REQ_DISCARD) { |
3059 | for (i = 0; i < num_stripes; i++) { | 3027 | for (i = 0; i < num_stripes; i++) { |
3060 | bbio->stripes[i].physical = | 3028 | bbio->stripes[i].physical = |
@@ -3151,15 +3119,22 @@ again: | |||
3151 | stripe_index++; | 3119 | stripe_index++; |
3152 | } | 3120 | } |
3153 | } | 3121 | } |
3154 | if (bbio_ret) { | 3122 | |
3155 | *bbio_ret = bbio; | 3123 | if (rw & REQ_WRITE) { |
3156 | bbio->num_stripes = num_stripes; | 3124 | if (map->type & (BTRFS_BLOCK_GROUP_RAID1 | |
3157 | bbio->max_errors = max_errors; | 3125 | BTRFS_BLOCK_GROUP_RAID10 | |
3158 | bbio->mirror_num = mirror_num; | 3126 | BTRFS_BLOCK_GROUP_DUP)) { |
3127 | max_errors = 1; | ||
3128 | } | ||
3159 | } | 3129 | } |
3130 | |||
3131 | *bbio_ret = bbio; | ||
3132 | bbio->num_stripes = num_stripes; | ||
3133 | bbio->max_errors = max_errors; | ||
3134 | bbio->mirror_num = mirror_num; | ||
3160 | out: | 3135 | out: |
3161 | free_extent_map(em); | 3136 | free_extent_map(em); |
3162 | return 0; | 3137 | return ret; |
3163 | } | 3138 | } |
3164 | 3139 | ||
3165 | int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, | 3140 | int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, |