aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2011-08-04 11:15:33 -0400
committerJan Schmidt <list.btrfs@jan-o-sch.net>2011-09-29 07:38:42 -0400
commita1d3c4786a4b9c71c0767aa656a759968f7554b6 (patch)
tree1dc5596ca57f261d2816111e51a2f33928bbe4a6 /fs/btrfs/volumes.c
parentd7728c960dccf775b92f2c4139f1216275a45c44 (diff)
btrfs: btrfs_multi_bio replaced with btrfs_bio
btrfs_bio is a bio abstraction able to split and not complete after the last bio has returned (like the old btrfs_multi_bio). Additionally, btrfs_bio tracks the mirror_num used to read data which can be used for error correction purposes. Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c128
1 files changed, 68 insertions, 60 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index f2a4cc79da61..9db4d7962f9b 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2848,7 +2848,7 @@ static int find_live_mirror(struct map_lookup *map, int first, int num,
2848 2848
2849static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, 2849static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
2850 u64 logical, u64 *length, 2850 u64 logical, u64 *length,
2851 struct btrfs_multi_bio **multi_ret, 2851 struct btrfs_bio **bbio_ret,
2852 int mirror_num) 2852 int mirror_num)
2853{ 2853{
2854 struct extent_map *em; 2854 struct extent_map *em;
@@ -2866,18 +2866,18 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
2866 int i; 2866 int i;
2867 int num_stripes; 2867 int num_stripes;
2868 int max_errors = 0; 2868 int max_errors = 0;
2869 struct btrfs_multi_bio *multi = NULL; 2869 struct btrfs_bio *bbio = NULL;
2870 2870
2871 if (multi_ret && !(rw & (REQ_WRITE | REQ_DISCARD))) 2871 if (bbio_ret && !(rw & (REQ_WRITE | REQ_DISCARD)))
2872 stripes_allocated = 1; 2872 stripes_allocated = 1;
2873again: 2873again:
2874 if (multi_ret) { 2874 if (bbio_ret) {
2875 multi = kzalloc(btrfs_multi_bio_size(stripes_allocated), 2875 bbio = kzalloc(btrfs_bio_size(stripes_allocated),
2876 GFP_NOFS); 2876 GFP_NOFS);
2877 if (!multi) 2877 if (!bbio)
2878 return -ENOMEM; 2878 return -ENOMEM;
2879 2879
2880 atomic_set(&multi->error, 0); 2880 atomic_set(&bbio->error, 0);
2881 } 2881 }
2882 2882
2883 read_lock(&em_tree->lock); 2883 read_lock(&em_tree->lock);
@@ -2898,7 +2898,7 @@ again:
2898 if (mirror_num > map->num_stripes) 2898 if (mirror_num > map->num_stripes)
2899 mirror_num = 0; 2899 mirror_num = 0;
2900 2900
2901 /* if our multi bio struct is too small, back off and try again */ 2901 /* if our btrfs_bio struct is too small, back off and try again */
2902 if (rw & REQ_WRITE) { 2902 if (rw & REQ_WRITE) {
2903 if (map->type & (BTRFS_BLOCK_GROUP_RAID1 | 2903 if (map->type & (BTRFS_BLOCK_GROUP_RAID1 |
2904 BTRFS_BLOCK_GROUP_DUP)) { 2904 BTRFS_BLOCK_GROUP_DUP)) {
@@ -2917,11 +2917,11 @@ again:
2917 stripes_required = map->num_stripes; 2917 stripes_required = map->num_stripes;
2918 } 2918 }
2919 } 2919 }
2920 if (multi_ret && (rw & (REQ_WRITE | REQ_DISCARD)) && 2920 if (bbio_ret && (rw & (REQ_WRITE | REQ_DISCARD)) &&
2921 stripes_allocated < stripes_required) { 2921 stripes_allocated < stripes_required) {
2922 stripes_allocated = map->num_stripes; 2922 stripes_allocated = map->num_stripes;
2923 free_extent_map(em); 2923 free_extent_map(em);
2924 kfree(multi); 2924 kfree(bbio);
2925 goto again; 2925 goto again;
2926 } 2926 }
2927 stripe_nr = offset; 2927 stripe_nr = offset;
@@ -2950,7 +2950,7 @@ again:
2950 *length = em->len - offset; 2950 *length = em->len - offset;
2951 } 2951 }
2952 2952
2953 if (!multi_ret) 2953 if (!bbio_ret)
2954 goto out; 2954 goto out;
2955 2955
2956 num_stripes = 1; 2956 num_stripes = 1;
@@ -2975,13 +2975,17 @@ again:
2975 stripe_index = find_live_mirror(map, 0, 2975 stripe_index = find_live_mirror(map, 0,
2976 map->num_stripes, 2976 map->num_stripes,
2977 current->pid % map->num_stripes); 2977 current->pid % map->num_stripes);
2978 mirror_num = stripe_index + 1;
2978 } 2979 }
2979 2980
2980 } else if (map->type & BTRFS_BLOCK_GROUP_DUP) { 2981 } else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
2981 if (rw & (REQ_WRITE | REQ_DISCARD)) 2982 if (rw & (REQ_WRITE | REQ_DISCARD)) {
2982 num_stripes = map->num_stripes; 2983 num_stripes = map->num_stripes;
2983 else if (mirror_num) 2984 } else if (mirror_num) {
2984 stripe_index = mirror_num - 1; 2985 stripe_index = mirror_num - 1;
2986 } else {
2987 mirror_num = 1;
2988 }
2985 2989
2986 } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) { 2990 } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
2987 int factor = map->num_stripes / map->sub_stripes; 2991 int factor = map->num_stripes / map->sub_stripes;
@@ -3001,6 +3005,7 @@ again:
3001 stripe_index = find_live_mirror(map, stripe_index, 3005 stripe_index = find_live_mirror(map, stripe_index,
3002 map->sub_stripes, stripe_index + 3006 map->sub_stripes, stripe_index +
3003 current->pid % map->sub_stripes); 3007 current->pid % map->sub_stripes);
3008 mirror_num = stripe_index + 1;
3004 } 3009 }
3005 } else { 3010 } else {
3006 /* 3011 /*
@@ -3009,15 +3014,16 @@ again:
3009 * stripe_index is the number of our device in the stripe array 3014 * stripe_index is the number of our device in the stripe array
3010 */ 3015 */
3011 stripe_index = do_div(stripe_nr, map->num_stripes); 3016 stripe_index = do_div(stripe_nr, map->num_stripes);
3017 mirror_num = stripe_index + 1;
3012 } 3018 }
3013 BUG_ON(stripe_index >= map->num_stripes); 3019 BUG_ON(stripe_index >= map->num_stripes);
3014 3020
3015 if (rw & REQ_DISCARD) { 3021 if (rw & REQ_DISCARD) {
3016 for (i = 0; i < num_stripes; i++) { 3022 for (i = 0; i < num_stripes; i++) {
3017 multi->stripes[i].physical = 3023 bbio->stripes[i].physical =
3018 map->stripes[stripe_index].physical + 3024 map->stripes[stripe_index].physical +
3019 stripe_offset + stripe_nr * map->stripe_len; 3025 stripe_offset + stripe_nr * map->stripe_len;
3020 multi->stripes[i].dev = map->stripes[stripe_index].dev; 3026 bbio->stripes[i].dev = map->stripes[stripe_index].dev;
3021 3027
3022 if (map->type & BTRFS_BLOCK_GROUP_RAID0) { 3028 if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
3023 u64 stripes; 3029 u64 stripes;
@@ -3038,16 +3044,16 @@ again:
3038 } 3044 }
3039 stripes = stripe_nr_end - 1 - j; 3045 stripes = stripe_nr_end - 1 - j;
3040 do_div(stripes, map->num_stripes); 3046 do_div(stripes, map->num_stripes);
3041 multi->stripes[i].length = map->stripe_len * 3047 bbio->stripes[i].length = map->stripe_len *
3042 (stripes - stripe_nr + 1); 3048 (stripes - stripe_nr + 1);
3043 3049
3044 if (i == 0) { 3050 if (i == 0) {
3045 multi->stripes[i].length -= 3051 bbio->stripes[i].length -=
3046 stripe_offset; 3052 stripe_offset;
3047 stripe_offset = 0; 3053 stripe_offset = 0;
3048 } 3054 }
3049 if (stripe_index == last_stripe) 3055 if (stripe_index == last_stripe)
3050 multi->stripes[i].length -= 3056 bbio->stripes[i].length -=
3051 stripe_end_offset; 3057 stripe_end_offset;
3052 } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) { 3058 } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
3053 u64 stripes; 3059 u64 stripes;
@@ -3072,11 +3078,11 @@ again:
3072 } 3078 }
3073 stripes = stripe_nr_end - 1 - j; 3079 stripes = stripe_nr_end - 1 - j;
3074 do_div(stripes, factor); 3080 do_div(stripes, factor);
3075 multi->stripes[i].length = map->stripe_len * 3081 bbio->stripes[i].length = map->stripe_len *
3076 (stripes - stripe_nr + 1); 3082 (stripes - stripe_nr + 1);
3077 3083
3078 if (i < map->sub_stripes) { 3084 if (i < map->sub_stripes) {
3079 multi->stripes[i].length -= 3085 bbio->stripes[i].length -=
3080 stripe_offset; 3086 stripe_offset;
3081 if (i == map->sub_stripes - 1) 3087 if (i == map->sub_stripes - 1)
3082 stripe_offset = 0; 3088 stripe_offset = 0;
@@ -3084,11 +3090,11 @@ again:
3084 if (stripe_index >= last_stripe && 3090 if (stripe_index >= last_stripe &&
3085 stripe_index <= (last_stripe + 3091 stripe_index <= (last_stripe +
3086 map->sub_stripes - 1)) { 3092 map->sub_stripes - 1)) {
3087 multi->stripes[i].length -= 3093 bbio->stripes[i].length -=
3088 stripe_end_offset; 3094 stripe_end_offset;
3089 } 3095 }
3090 } else 3096 } else
3091 multi->stripes[i].length = *length; 3097 bbio->stripes[i].length = *length;
3092 3098
3093 stripe_index++; 3099 stripe_index++;
3094 if (stripe_index == map->num_stripes) { 3100 if (stripe_index == map->num_stripes) {
@@ -3099,19 +3105,20 @@ again:
3099 } 3105 }
3100 } else { 3106 } else {
3101 for (i = 0; i < num_stripes; i++) { 3107 for (i = 0; i < num_stripes; i++) {
3102 multi->stripes[i].physical = 3108 bbio->stripes[i].physical =
3103 map->stripes[stripe_index].physical + 3109 map->stripes[stripe_index].physical +
3104 stripe_offset + 3110 stripe_offset +
3105 stripe_nr * map->stripe_len; 3111 stripe_nr * map->stripe_len;
3106 multi->stripes[i].dev = 3112 bbio->stripes[i].dev =
3107 map->stripes[stripe_index].dev; 3113 map->stripes[stripe_index].dev;
3108 stripe_index++; 3114 stripe_index++;
3109 } 3115 }
3110 } 3116 }
3111 if (multi_ret) { 3117 if (bbio_ret) {
3112 *multi_ret = multi; 3118 *bbio_ret = bbio;
3113 multi->num_stripes = num_stripes; 3119 bbio->num_stripes = num_stripes;
3114 multi->max_errors = max_errors; 3120 bbio->max_errors = max_errors;
3121 bbio->mirror_num = mirror_num;
3115 } 3122 }
3116out: 3123out:
3117 free_extent_map(em); 3124 free_extent_map(em);
@@ -3120,9 +3127,9 @@ out:
3120 3127
3121int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, 3128int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
3122 u64 logical, u64 *length, 3129 u64 logical, u64 *length,
3123 struct btrfs_multi_bio **multi_ret, int mirror_num) 3130 struct btrfs_bio **bbio_ret, int mirror_num)
3124{ 3131{
3125 return __btrfs_map_block(map_tree, rw, logical, length, multi_ret, 3132 return __btrfs_map_block(map_tree, rw, logical, length, bbio_ret,
3126 mirror_num); 3133 mirror_num);
3127} 3134}
3128 3135
@@ -3191,28 +3198,28 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
3191 return 0; 3198 return 0;
3192} 3199}
3193 3200
3194static void end_bio_multi_stripe(struct bio *bio, int err) 3201static void btrfs_end_bio(struct bio *bio, int err)
3195{ 3202{
3196 struct btrfs_multi_bio *multi = bio->bi_private; 3203 struct btrfs_bio *bbio = bio->bi_private;
3197 int is_orig_bio = 0; 3204 int is_orig_bio = 0;
3198 3205
3199 if (err) 3206 if (err)
3200 atomic_inc(&multi->error); 3207 atomic_inc(&bbio->error);
3201 3208
3202 if (bio == multi->orig_bio) 3209 if (bio == bbio->orig_bio)
3203 is_orig_bio = 1; 3210 is_orig_bio = 1;
3204 3211
3205 if (atomic_dec_and_test(&multi->stripes_pending)) { 3212 if (atomic_dec_and_test(&bbio->stripes_pending)) {
3206 if (!is_orig_bio) { 3213 if (!is_orig_bio) {
3207 bio_put(bio); 3214 bio_put(bio);
3208 bio = multi->orig_bio; 3215 bio = bbio->orig_bio;
3209 } 3216 }
3210 bio->bi_private = multi->private; 3217 bio->bi_private = bbio->private;
3211 bio->bi_end_io = multi->end_io; 3218 bio->bi_end_io = bbio->end_io;
3212 /* only send an error to the higher layers if it is 3219 /* only send an error to the higher layers if it is
3213 * beyond the tolerance of the multi-bio 3220 * beyond the tolerance of the multi-bio
3214 */ 3221 */
3215 if (atomic_read(&multi->error) > multi->max_errors) { 3222 if (atomic_read(&bbio->error) > bbio->max_errors) {
3216 err = -EIO; 3223 err = -EIO;
3217 } else if (err) { 3224 } else if (err) {
3218 /* 3225 /*
@@ -3222,7 +3229,7 @@ static void end_bio_multi_stripe(struct bio *bio, int err)
3222 set_bit(BIO_UPTODATE, &bio->bi_flags); 3229 set_bit(BIO_UPTODATE, &bio->bi_flags);
3223 err = 0; 3230 err = 0;
3224 } 3231 }
3225 kfree(multi); 3232 kfree(bbio);
3226 3233
3227 bio_endio(bio, err); 3234 bio_endio(bio, err);
3228 } else if (!is_orig_bio) { 3235 } else if (!is_orig_bio) {
@@ -3302,20 +3309,20 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
3302 u64 logical = (u64)bio->bi_sector << 9; 3309 u64 logical = (u64)bio->bi_sector << 9;
3303 u64 length = 0; 3310 u64 length = 0;
3304 u64 map_length; 3311 u64 map_length;
3305 struct btrfs_multi_bio *multi = NULL;
3306 int ret; 3312 int ret;
3307 int dev_nr = 0; 3313 int dev_nr = 0;
3308 int total_devs = 1; 3314 int total_devs = 1;
3315 struct btrfs_bio *bbio = NULL;
3309 3316
3310 length = bio->bi_size; 3317 length = bio->bi_size;
3311 map_tree = &root->fs_info->mapping_tree; 3318 map_tree = &root->fs_info->mapping_tree;
3312 map_length = length; 3319 map_length = length;
3313 3320
3314 ret = btrfs_map_block(map_tree, rw, logical, &map_length, &multi, 3321 ret = btrfs_map_block(map_tree, rw, logical, &map_length, &bbio,
3315 mirror_num); 3322 mirror_num);
3316 BUG_ON(ret); 3323 BUG_ON(ret);
3317 3324
3318 total_devs = multi->num_stripes; 3325 total_devs = bbio->num_stripes;
3319 if (map_length < length) { 3326 if (map_length < length) {
3320 printk(KERN_CRIT "mapping failed logical %llu bio len %llu " 3327 printk(KERN_CRIT "mapping failed logical %llu bio len %llu "
3321 "len %llu\n", (unsigned long long)logical, 3328 "len %llu\n", (unsigned long long)logical,
@@ -3323,25 +3330,28 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
3323 (unsigned long long)map_length); 3330 (unsigned long long)map_length);
3324 BUG(); 3331 BUG();
3325 } 3332 }
3326 multi->end_io = first_bio->bi_end_io; 3333
3327 multi->private = first_bio->bi_private; 3334 bbio->orig_bio = first_bio;
3328 multi->orig_bio = first_bio; 3335 bbio->private = first_bio->bi_private;
3329 atomic_set(&multi->stripes_pending, multi->num_stripes); 3336 bbio->end_io = first_bio->bi_end_io;
3337 atomic_set(&bbio->stripes_pending, bbio->num_stripes);
3330 3338
3331 while (dev_nr < total_devs) { 3339 while (dev_nr < total_devs) {
3332 if (total_devs > 1) { 3340 if (dev_nr < total_devs - 1) {
3333 if (dev_nr < total_devs - 1) { 3341 bio = bio_clone(first_bio, GFP_NOFS);
3334 bio = bio_clone(first_bio, GFP_NOFS); 3342 BUG_ON(!bio);
3335 BUG_ON(!bio); 3343 } else {
3336 } else { 3344 bio = first_bio;
3337 bio = first_bio;
3338 }
3339 bio->bi_private = multi;
3340 bio->bi_end_io = end_bio_multi_stripe;
3341 } 3345 }
3342 bio->bi_sector = multi->stripes[dev_nr].physical >> 9; 3346 bio->bi_private = bbio;
3343 dev = multi->stripes[dev_nr].dev; 3347 bio->bi_end_io = btrfs_end_bio;
3348 bio->bi_sector = bbio->stripes[dev_nr].physical >> 9;
3349 dev = bbio->stripes[dev_nr].dev;
3344 if (dev && dev->bdev && (rw != WRITE || dev->writeable)) { 3350 if (dev && dev->bdev && (rw != WRITE || dev->writeable)) {
3351 pr_debug("btrfs_map_bio: rw %d, secor=%llu, dev=%lu "
3352 "(%s id %llu), size=%u\n", rw,
3353 (u64)bio->bi_sector, (u_long)dev->bdev->bd_dev,
3354 dev->name, dev->devid, bio->bi_size);
3345 bio->bi_bdev = dev->bdev; 3355 bio->bi_bdev = dev->bdev;
3346 if (async_submit) 3356 if (async_submit)
3347 schedule_bio(root, dev, rw, bio); 3357 schedule_bio(root, dev, rw, bio);
@@ -3354,8 +3364,6 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
3354 } 3364 }
3355 dev_nr++; 3365 dev_nr++;
3356 } 3366 }
3357 if (total_devs == 1)
3358 kfree(multi);
3359 return 0; 3367 return 0;
3360} 3368}
3361 3369