diff options
author | Chris Mason <chris.mason@oracle.com> | 2011-11-06 03:07:10 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2011-11-06 03:07:10 -0500 |
commit | 806468f8bf76a3cb2b626dd282946a6c9c0a50f0 (patch) | |
tree | 2de54229a5623756417a9bad7f426a2e8b06cad7 /fs/btrfs/volumes.c | |
parent | 531f4b1ae5e0fc8c9b3f03838218e5ea178f80d3 (diff) | |
parent | 5da6fcbc4eb50c0f55d520750332f5a6ab13508c (diff) |
Merge git://git.jan-o-sch.net/btrfs-unstable into integration
Conflicts:
fs/btrfs/Makefile
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/scrub.c
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 130 |
1 files changed, 70 insertions, 60 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index f1685a2b45c8..f8e2943101a1 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -2880,7 +2880,7 @@ static int find_live_mirror(struct map_lookup *map, int first, int num, | |||
2880 | 2880 | ||
2881 | static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, | 2881 | static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, |
2882 | u64 logical, u64 *length, | 2882 | u64 logical, u64 *length, |
2883 | struct btrfs_multi_bio **multi_ret, | 2883 | struct btrfs_bio **bbio_ret, |
2884 | int mirror_num) | 2884 | int mirror_num) |
2885 | { | 2885 | { |
2886 | struct extent_map *em; | 2886 | struct extent_map *em; |
@@ -2898,18 +2898,18 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, | |||
2898 | int i; | 2898 | int i; |
2899 | int num_stripes; | 2899 | int num_stripes; |
2900 | int max_errors = 0; | 2900 | int max_errors = 0; |
2901 | struct btrfs_multi_bio *multi = NULL; | 2901 | struct btrfs_bio *bbio = NULL; |
2902 | 2902 | ||
2903 | if (multi_ret && !(rw & (REQ_WRITE | REQ_DISCARD))) | 2903 | if (bbio_ret && !(rw & (REQ_WRITE | REQ_DISCARD))) |
2904 | stripes_allocated = 1; | 2904 | stripes_allocated = 1; |
2905 | again: | 2905 | again: |
2906 | if (multi_ret) { | 2906 | if (bbio_ret) { |
2907 | multi = kzalloc(btrfs_multi_bio_size(stripes_allocated), | 2907 | bbio = kzalloc(btrfs_bio_size(stripes_allocated), |
2908 | GFP_NOFS); | 2908 | GFP_NOFS); |
2909 | if (!multi) | 2909 | if (!bbio) |
2910 | return -ENOMEM; | 2910 | return -ENOMEM; |
2911 | 2911 | ||
2912 | atomic_set(&multi->error, 0); | 2912 | atomic_set(&bbio->error, 0); |
2913 | } | 2913 | } |
2914 | 2914 | ||
2915 | read_lock(&em_tree->lock); | 2915 | read_lock(&em_tree->lock); |
@@ -2930,7 +2930,7 @@ again: | |||
2930 | if (mirror_num > map->num_stripes) | 2930 | if (mirror_num > map->num_stripes) |
2931 | mirror_num = 0; | 2931 | mirror_num = 0; |
2932 | 2932 | ||
2933 | /* if our multi bio struct is too small, back off and try again */ | 2933 | /* if our btrfs_bio struct is too small, back off and try again */ |
2934 | if (rw & REQ_WRITE) { | 2934 | if (rw & REQ_WRITE) { |
2935 | if (map->type & (BTRFS_BLOCK_GROUP_RAID1 | | 2935 | if (map->type & (BTRFS_BLOCK_GROUP_RAID1 | |
2936 | BTRFS_BLOCK_GROUP_DUP)) { | 2936 | BTRFS_BLOCK_GROUP_DUP)) { |
@@ -2949,11 +2949,11 @@ again: | |||
2949 | stripes_required = map->num_stripes; | 2949 | stripes_required = map->num_stripes; |
2950 | } | 2950 | } |
2951 | } | 2951 | } |
2952 | if (multi_ret && (rw & (REQ_WRITE | REQ_DISCARD)) && | 2952 | if (bbio_ret && (rw & (REQ_WRITE | REQ_DISCARD)) && |
2953 | stripes_allocated < stripes_required) { | 2953 | stripes_allocated < stripes_required) { |
2954 | stripes_allocated = map->num_stripes; | 2954 | stripes_allocated = map->num_stripes; |
2955 | free_extent_map(em); | 2955 | free_extent_map(em); |
2956 | kfree(multi); | 2956 | kfree(bbio); |
2957 | goto again; | 2957 | goto again; |
2958 | } | 2958 | } |
2959 | stripe_nr = offset; | 2959 | stripe_nr = offset; |
@@ -2982,7 +2982,7 @@ again: | |||
2982 | *length = em->len - offset; | 2982 | *length = em->len - offset; |
2983 | } | 2983 | } |
2984 | 2984 | ||
2985 | if (!multi_ret) | 2985 | if (!bbio_ret) |
2986 | goto out; | 2986 | goto out; |
2987 | 2987 | ||
2988 | num_stripes = 1; | 2988 | num_stripes = 1; |
@@ -3007,13 +3007,17 @@ again: | |||
3007 | stripe_index = find_live_mirror(map, 0, | 3007 | stripe_index = find_live_mirror(map, 0, |
3008 | map->num_stripes, | 3008 | map->num_stripes, |
3009 | current->pid % map->num_stripes); | 3009 | current->pid % map->num_stripes); |
3010 | mirror_num = stripe_index + 1; | ||
3010 | } | 3011 | } |
3011 | 3012 | ||
3012 | } else if (map->type & BTRFS_BLOCK_GROUP_DUP) { | 3013 | } else if (map->type & BTRFS_BLOCK_GROUP_DUP) { |
3013 | if (rw & (REQ_WRITE | REQ_DISCARD)) | 3014 | if (rw & (REQ_WRITE | REQ_DISCARD)) { |
3014 | num_stripes = map->num_stripes; | 3015 | num_stripes = map->num_stripes; |
3015 | else if (mirror_num) | 3016 | } else if (mirror_num) { |
3016 | stripe_index = mirror_num - 1; | 3017 | stripe_index = mirror_num - 1; |
3018 | } else { | ||
3019 | mirror_num = 1; | ||
3020 | } | ||
3017 | 3021 | ||
3018 | } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) { | 3022 | } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) { |
3019 | int factor = map->num_stripes / map->sub_stripes; | 3023 | int factor = map->num_stripes / map->sub_stripes; |
@@ -3033,6 +3037,7 @@ again: | |||
3033 | stripe_index = find_live_mirror(map, stripe_index, | 3037 | stripe_index = find_live_mirror(map, stripe_index, |
3034 | map->sub_stripes, stripe_index + | 3038 | map->sub_stripes, stripe_index + |
3035 | current->pid % map->sub_stripes); | 3039 | current->pid % map->sub_stripes); |
3040 | mirror_num = stripe_index + 1; | ||
3036 | } | 3041 | } |
3037 | } else { | 3042 | } else { |
3038 | /* | 3043 | /* |
@@ -3041,15 +3046,16 @@ again: | |||
3041 | * stripe_index is the number of our device in the stripe array | 3046 | * stripe_index is the number of our device in the stripe array |
3042 | */ | 3047 | */ |
3043 | stripe_index = do_div(stripe_nr, map->num_stripes); | 3048 | stripe_index = do_div(stripe_nr, map->num_stripes); |
3049 | mirror_num = stripe_index + 1; | ||
3044 | } | 3050 | } |
3045 | BUG_ON(stripe_index >= map->num_stripes); | 3051 | BUG_ON(stripe_index >= map->num_stripes); |
3046 | 3052 | ||
3047 | if (rw & REQ_DISCARD) { | 3053 | if (rw & REQ_DISCARD) { |
3048 | for (i = 0; i < num_stripes; i++) { | 3054 | for (i = 0; i < num_stripes; i++) { |
3049 | multi->stripes[i].physical = | 3055 | bbio->stripes[i].physical = |
3050 | map->stripes[stripe_index].physical + | 3056 | map->stripes[stripe_index].physical + |
3051 | stripe_offset + stripe_nr * map->stripe_len; | 3057 | stripe_offset + stripe_nr * map->stripe_len; |
3052 | multi->stripes[i].dev = map->stripes[stripe_index].dev; | 3058 | bbio->stripes[i].dev = map->stripes[stripe_index].dev; |
3053 | 3059 | ||
3054 | if (map->type & BTRFS_BLOCK_GROUP_RAID0) { | 3060 | if (map->type & BTRFS_BLOCK_GROUP_RAID0) { |
3055 | u64 stripes; | 3061 | u64 stripes; |
@@ -3070,16 +3076,16 @@ again: | |||
3070 | } | 3076 | } |
3071 | stripes = stripe_nr_end - 1 - j; | 3077 | stripes = stripe_nr_end - 1 - j; |
3072 | do_div(stripes, map->num_stripes); | 3078 | do_div(stripes, map->num_stripes); |
3073 | multi->stripes[i].length = map->stripe_len * | 3079 | bbio->stripes[i].length = map->stripe_len * |
3074 | (stripes - stripe_nr + 1); | 3080 | (stripes - stripe_nr + 1); |
3075 | 3081 | ||
3076 | if (i == 0) { | 3082 | if (i == 0) { |
3077 | multi->stripes[i].length -= | 3083 | bbio->stripes[i].length -= |
3078 | stripe_offset; | 3084 | stripe_offset; |
3079 | stripe_offset = 0; | 3085 | stripe_offset = 0; |
3080 | } | 3086 | } |
3081 | if (stripe_index == last_stripe) | 3087 | if (stripe_index == last_stripe) |
3082 | multi->stripes[i].length -= | 3088 | bbio->stripes[i].length -= |
3083 | stripe_end_offset; | 3089 | stripe_end_offset; |
3084 | } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) { | 3090 | } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) { |
3085 | u64 stripes; | 3091 | u64 stripes; |
@@ -3104,11 +3110,11 @@ again: | |||
3104 | } | 3110 | } |
3105 | stripes = stripe_nr_end - 1 - j; | 3111 | stripes = stripe_nr_end - 1 - j; |
3106 | do_div(stripes, factor); | 3112 | do_div(stripes, factor); |
3107 | multi->stripes[i].length = map->stripe_len * | 3113 | bbio->stripes[i].length = map->stripe_len * |
3108 | (stripes - stripe_nr + 1); | 3114 | (stripes - stripe_nr + 1); |
3109 | 3115 | ||
3110 | if (i < map->sub_stripes) { | 3116 | if (i < map->sub_stripes) { |
3111 | multi->stripes[i].length -= | 3117 | bbio->stripes[i].length -= |
3112 | stripe_offset; | 3118 | stripe_offset; |
3113 | if (i == map->sub_stripes - 1) | 3119 | if (i == map->sub_stripes - 1) |
3114 | stripe_offset = 0; | 3120 | stripe_offset = 0; |
@@ -3116,11 +3122,11 @@ again: | |||
3116 | if (stripe_index >= last_stripe && | 3122 | if (stripe_index >= last_stripe && |
3117 | stripe_index <= (last_stripe + | 3123 | stripe_index <= (last_stripe + |
3118 | map->sub_stripes - 1)) { | 3124 | map->sub_stripes - 1)) { |
3119 | multi->stripes[i].length -= | 3125 | bbio->stripes[i].length -= |
3120 | stripe_end_offset; | 3126 | stripe_end_offset; |
3121 | } | 3127 | } |
3122 | } else | 3128 | } else |
3123 | multi->stripes[i].length = *length; | 3129 | bbio->stripes[i].length = *length; |
3124 | 3130 | ||
3125 | stripe_index++; | 3131 | stripe_index++; |
3126 | if (stripe_index == map->num_stripes) { | 3132 | if (stripe_index == map->num_stripes) { |
@@ -3131,19 +3137,20 @@ again: | |||
3131 | } | 3137 | } |
3132 | } else { | 3138 | } else { |
3133 | for (i = 0; i < num_stripes; i++) { | 3139 | for (i = 0; i < num_stripes; i++) { |
3134 | multi->stripes[i].physical = | 3140 | bbio->stripes[i].physical = |
3135 | map->stripes[stripe_index].physical + | 3141 | map->stripes[stripe_index].physical + |
3136 | stripe_offset + | 3142 | stripe_offset + |
3137 | stripe_nr * map->stripe_len; | 3143 | stripe_nr * map->stripe_len; |
3138 | multi->stripes[i].dev = | 3144 | bbio->stripes[i].dev = |
3139 | map->stripes[stripe_index].dev; | 3145 | map->stripes[stripe_index].dev; |
3140 | stripe_index++; | 3146 | stripe_index++; |
3141 | } | 3147 | } |
3142 | } | 3148 | } |
3143 | if (multi_ret) { | 3149 | if (bbio_ret) { |
3144 | *multi_ret = multi; | 3150 | *bbio_ret = bbio; |
3145 | multi->num_stripes = num_stripes; | 3151 | bbio->num_stripes = num_stripes; |
3146 | multi->max_errors = max_errors; | 3152 | bbio->max_errors = max_errors; |
3153 | bbio->mirror_num = mirror_num; | ||
3147 | } | 3154 | } |
3148 | out: | 3155 | out: |
3149 | free_extent_map(em); | 3156 | free_extent_map(em); |
@@ -3152,9 +3159,9 @@ out: | |||
3152 | 3159 | ||
3153 | int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, | 3160 | int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, |
3154 | u64 logical, u64 *length, | 3161 | u64 logical, u64 *length, |
3155 | struct btrfs_multi_bio **multi_ret, int mirror_num) | 3162 | struct btrfs_bio **bbio_ret, int mirror_num) |
3156 | { | 3163 | { |
3157 | return __btrfs_map_block(map_tree, rw, logical, length, multi_ret, | 3164 | return __btrfs_map_block(map_tree, rw, logical, length, bbio_ret, |
3158 | mirror_num); | 3165 | mirror_num); |
3159 | } | 3166 | } |
3160 | 3167 | ||
@@ -3223,28 +3230,30 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | |||
3223 | return 0; | 3230 | return 0; |
3224 | } | 3231 | } |
3225 | 3232 | ||
3226 | static void end_bio_multi_stripe(struct bio *bio, int err) | 3233 | static void btrfs_end_bio(struct bio *bio, int err) |
3227 | { | 3234 | { |
3228 | struct btrfs_multi_bio *multi = bio->bi_private; | 3235 | struct btrfs_bio *bbio = bio->bi_private; |
3229 | int is_orig_bio = 0; | 3236 | int is_orig_bio = 0; |
3230 | 3237 | ||
3231 | if (err) | 3238 | if (err) |
3232 | atomic_inc(&multi->error); | 3239 | atomic_inc(&bbio->error); |
3233 | 3240 | ||
3234 | if (bio == multi->orig_bio) | 3241 | if (bio == bbio->orig_bio) |
3235 | is_orig_bio = 1; | 3242 | is_orig_bio = 1; |
3236 | 3243 | ||
3237 | if (atomic_dec_and_test(&multi->stripes_pending)) { | 3244 | if (atomic_dec_and_test(&bbio->stripes_pending)) { |
3238 | if (!is_orig_bio) { | 3245 | if (!is_orig_bio) { |
3239 | bio_put(bio); | 3246 | bio_put(bio); |
3240 | bio = multi->orig_bio; | 3247 | bio = bbio->orig_bio; |
3241 | } | 3248 | } |
3242 | bio->bi_private = multi->private; | 3249 | bio->bi_private = bbio->private; |
3243 | bio->bi_end_io = multi->end_io; | 3250 | bio->bi_end_io = bbio->end_io; |
3251 | bio->bi_bdev = (struct block_device *) | ||
3252 | (unsigned long)bbio->mirror_num; | ||
3244 | /* only send an error to the higher layers if it is | 3253 | /* only send an error to the higher layers if it is |
3245 | * beyond the tolerance of the multi-bio | 3254 | * beyond the tolerance of the multi-bio |
3246 | */ | 3255 | */ |
3247 | if (atomic_read(&multi->error) > multi->max_errors) { | 3256 | if (atomic_read(&bbio->error) > bbio->max_errors) { |
3248 | err = -EIO; | 3257 | err = -EIO; |
3249 | } else if (err) { | 3258 | } else if (err) { |
3250 | /* | 3259 | /* |
@@ -3254,7 +3263,7 @@ static void end_bio_multi_stripe(struct bio *bio, int err) | |||
3254 | set_bit(BIO_UPTODATE, &bio->bi_flags); | 3263 | set_bit(BIO_UPTODATE, &bio->bi_flags); |
3255 | err = 0; | 3264 | err = 0; |
3256 | } | 3265 | } |
3257 | kfree(multi); | 3266 | kfree(bbio); |
3258 | 3267 | ||
3259 | bio_endio(bio, err); | 3268 | bio_endio(bio, err); |
3260 | } else if (!is_orig_bio) { | 3269 | } else if (!is_orig_bio) { |
@@ -3334,20 +3343,20 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
3334 | u64 logical = (u64)bio->bi_sector << 9; | 3343 | u64 logical = (u64)bio->bi_sector << 9; |
3335 | u64 length = 0; | 3344 | u64 length = 0; |
3336 | u64 map_length; | 3345 | u64 map_length; |
3337 | struct btrfs_multi_bio *multi = NULL; | ||
3338 | int ret; | 3346 | int ret; |
3339 | int dev_nr = 0; | 3347 | int dev_nr = 0; |
3340 | int total_devs = 1; | 3348 | int total_devs = 1; |
3349 | struct btrfs_bio *bbio = NULL; | ||
3341 | 3350 | ||
3342 | length = bio->bi_size; | 3351 | length = bio->bi_size; |
3343 | map_tree = &root->fs_info->mapping_tree; | 3352 | map_tree = &root->fs_info->mapping_tree; |
3344 | map_length = length; | 3353 | map_length = length; |
3345 | 3354 | ||
3346 | ret = btrfs_map_block(map_tree, rw, logical, &map_length, &multi, | 3355 | ret = btrfs_map_block(map_tree, rw, logical, &map_length, &bbio, |
3347 | mirror_num); | 3356 | mirror_num); |
3348 | BUG_ON(ret); | 3357 | BUG_ON(ret); |
3349 | 3358 | ||
3350 | total_devs = multi->num_stripes; | 3359 | total_devs = bbio->num_stripes; |
3351 | if (map_length < length) { | 3360 | if (map_length < length) { |
3352 | printk(KERN_CRIT "mapping failed logical %llu bio len %llu " | 3361 | printk(KERN_CRIT "mapping failed logical %llu bio len %llu " |
3353 | "len %llu\n", (unsigned long long)logical, | 3362 | "len %llu\n", (unsigned long long)logical, |
@@ -3355,25 +3364,28 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
3355 | (unsigned long long)map_length); | 3364 | (unsigned long long)map_length); |
3356 | BUG(); | 3365 | BUG(); |
3357 | } | 3366 | } |
3358 | multi->end_io = first_bio->bi_end_io; | 3367 | |
3359 | multi->private = first_bio->bi_private; | 3368 | bbio->orig_bio = first_bio; |
3360 | multi->orig_bio = first_bio; | 3369 | bbio->private = first_bio->bi_private; |
3361 | atomic_set(&multi->stripes_pending, multi->num_stripes); | 3370 | bbio->end_io = first_bio->bi_end_io; |
3371 | atomic_set(&bbio->stripes_pending, bbio->num_stripes); | ||
3362 | 3372 | ||
3363 | while (dev_nr < total_devs) { | 3373 | while (dev_nr < total_devs) { |
3364 | if (total_devs > 1) { | 3374 | if (dev_nr < total_devs - 1) { |
3365 | if (dev_nr < total_devs - 1) { | 3375 | bio = bio_clone(first_bio, GFP_NOFS); |
3366 | bio = bio_clone(first_bio, GFP_NOFS); | 3376 | BUG_ON(!bio); |
3367 | BUG_ON(!bio); | 3377 | } else { |
3368 | } else { | 3378 | bio = first_bio; |
3369 | bio = first_bio; | ||
3370 | } | ||
3371 | bio->bi_private = multi; | ||
3372 | bio->bi_end_io = end_bio_multi_stripe; | ||
3373 | } | 3379 | } |
3374 | bio->bi_sector = multi->stripes[dev_nr].physical >> 9; | 3380 | bio->bi_private = bbio; |
3375 | dev = multi->stripes[dev_nr].dev; | 3381 | bio->bi_end_io = btrfs_end_bio; |
3382 | bio->bi_sector = bbio->stripes[dev_nr].physical >> 9; | ||
3383 | dev = bbio->stripes[dev_nr].dev; | ||
3376 | if (dev && dev->bdev && (rw != WRITE || dev->writeable)) { | 3384 | if (dev && dev->bdev && (rw != WRITE || dev->writeable)) { |
3385 | pr_debug("btrfs_map_bio: rw %d, secor=%llu, dev=%lu " | ||
3386 | "(%s id %llu), size=%u\n", rw, | ||
3387 | (u64)bio->bi_sector, (u_long)dev->bdev->bd_dev, | ||
3388 | dev->name, dev->devid, bio->bi_size); | ||
3377 | bio->bi_bdev = dev->bdev; | 3389 | bio->bi_bdev = dev->bdev; |
3378 | if (async_submit) | 3390 | if (async_submit) |
3379 | schedule_bio(root, dev, rw, bio); | 3391 | schedule_bio(root, dev, rw, bio); |
@@ -3386,8 +3398,6 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
3386 | } | 3398 | } |
3387 | dev_nr++; | 3399 | dev_nr++; |
3388 | } | 3400 | } |
3389 | if (total_devs == 1) | ||
3390 | kfree(multi); | ||
3391 | return 0; | 3401 | return 0; |
3392 | } | 3402 | } |
3393 | 3403 | ||