diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 54 |
1 files changed, 12 insertions, 42 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 0e925ced971b..8bffb9174afb 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -3120,14 +3120,13 @@ int btrfs_balance(struct btrfs_balance_control *bctl, | |||
3120 | allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE; | 3120 | allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE; |
3121 | if (num_devices == 1) | 3121 | if (num_devices == 1) |
3122 | allowed |= BTRFS_BLOCK_GROUP_DUP; | 3122 | allowed |= BTRFS_BLOCK_GROUP_DUP; |
3123 | else if (num_devices < 4) | 3123 | else if (num_devices > 1) |
3124 | allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1); | 3124 | allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1); |
3125 | else | 3125 | if (num_devices > 2) |
3126 | allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 | | 3126 | allowed |= BTRFS_BLOCK_GROUP_RAID5; |
3127 | BTRFS_BLOCK_GROUP_RAID10 | | 3127 | if (num_devices > 3) |
3128 | BTRFS_BLOCK_GROUP_RAID5 | | 3128 | allowed |= (BTRFS_BLOCK_GROUP_RAID10 | |
3129 | BTRFS_BLOCK_GROUP_RAID6); | 3129 | BTRFS_BLOCK_GROUP_RAID6); |
3130 | |||
3131 | if ((bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) && | 3130 | if ((bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) && |
3132 | (!alloc_profile_is_valid(bctl->data.target, 1) || | 3131 | (!alloc_profile_is_valid(bctl->data.target, 1) || |
3133 | (bctl->data.target & ~allowed))) { | 3132 | (bctl->data.target & ~allowed))) { |
@@ -5019,42 +5018,16 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | |||
5019 | return 0; | 5018 | return 0; |
5020 | } | 5019 | } |
5021 | 5020 | ||
5022 | static void *merge_stripe_index_into_bio_private(void *bi_private, | ||
5023 | unsigned int stripe_index) | ||
5024 | { | ||
5025 | /* | ||
5026 | * with single, dup, RAID0, RAID1 and RAID10, stripe_index is | ||
5027 | * at most 1. | ||
5028 | * The alternative solution (instead of stealing bits from the | ||
5029 | * pointer) would be to allocate an intermediate structure | ||
5030 | * that contains the old private pointer plus the stripe_index. | ||
5031 | */ | ||
5032 | BUG_ON((((uintptr_t)bi_private) & 3) != 0); | ||
5033 | BUG_ON(stripe_index > 3); | ||
5034 | return (void *)(((uintptr_t)bi_private) | stripe_index); | ||
5035 | } | ||
5036 | |||
5037 | static struct btrfs_bio *extract_bbio_from_bio_private(void *bi_private) | ||
5038 | { | ||
5039 | return (struct btrfs_bio *)(((uintptr_t)bi_private) & ~((uintptr_t)3)); | ||
5040 | } | ||
5041 | |||
5042 | static unsigned int extract_stripe_index_from_bio_private(void *bi_private) | ||
5043 | { | ||
5044 | return (unsigned int)((uintptr_t)bi_private) & 3; | ||
5045 | } | ||
5046 | |||
5047 | static void btrfs_end_bio(struct bio *bio, int err) | 5021 | static void btrfs_end_bio(struct bio *bio, int err) |
5048 | { | 5022 | { |
5049 | struct btrfs_bio *bbio = extract_bbio_from_bio_private(bio->bi_private); | 5023 | struct btrfs_bio *bbio = bio->bi_private; |
5050 | int is_orig_bio = 0; | 5024 | int is_orig_bio = 0; |
5051 | 5025 | ||
5052 | if (err) { | 5026 | if (err) { |
5053 | atomic_inc(&bbio->error); | 5027 | atomic_inc(&bbio->error); |
5054 | if (err == -EIO || err == -EREMOTEIO) { | 5028 | if (err == -EIO || err == -EREMOTEIO) { |
5055 | unsigned int stripe_index = | 5029 | unsigned int stripe_index = |
5056 | extract_stripe_index_from_bio_private( | 5030 | btrfs_io_bio(bio)->stripe_index; |
5057 | bio->bi_private); | ||
5058 | struct btrfs_device *dev; | 5031 | struct btrfs_device *dev; |
5059 | 5032 | ||
5060 | BUG_ON(stripe_index >= bbio->num_stripes); | 5033 | BUG_ON(stripe_index >= bbio->num_stripes); |
@@ -5084,8 +5057,7 @@ static void btrfs_end_bio(struct bio *bio, int err) | |||
5084 | } | 5057 | } |
5085 | bio->bi_private = bbio->private; | 5058 | bio->bi_private = bbio->private; |
5086 | bio->bi_end_io = bbio->end_io; | 5059 | bio->bi_end_io = bbio->end_io; |
5087 | bio->bi_bdev = (struct block_device *) | 5060 | btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; |
5088 | (unsigned long)bbio->mirror_num; | ||
5089 | /* only send an error to the higher layers if it is | 5061 | /* only send an error to the higher layers if it is |
5090 | * beyond the tolerance of the btrfs bio | 5062 | * beyond the tolerance of the btrfs bio |
5091 | */ | 5063 | */ |
@@ -5211,8 +5183,7 @@ static void submit_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio, | |||
5211 | struct btrfs_device *dev = bbio->stripes[dev_nr].dev; | 5183 | struct btrfs_device *dev = bbio->stripes[dev_nr].dev; |
5212 | 5184 | ||
5213 | bio->bi_private = bbio; | 5185 | bio->bi_private = bbio; |
5214 | bio->bi_private = merge_stripe_index_into_bio_private( | 5186 | btrfs_io_bio(bio)->stripe_index = dev_nr; |
5215 | bio->bi_private, (unsigned int)dev_nr); | ||
5216 | bio->bi_end_io = btrfs_end_bio; | 5187 | bio->bi_end_io = btrfs_end_bio; |
5217 | bio->bi_sector = physical >> 9; | 5188 | bio->bi_sector = physical >> 9; |
5218 | #ifdef DEBUG | 5189 | #ifdef DEBUG |
@@ -5273,8 +5244,7 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical) | |||
5273 | if (atomic_dec_and_test(&bbio->stripes_pending)) { | 5244 | if (atomic_dec_and_test(&bbio->stripes_pending)) { |
5274 | bio->bi_private = bbio->private; | 5245 | bio->bi_private = bbio->private; |
5275 | bio->bi_end_io = bbio->end_io; | 5246 | bio->bi_end_io = bbio->end_io; |
5276 | bio->bi_bdev = (struct block_device *) | 5247 | btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; |
5277 | (unsigned long)bbio->mirror_num; | ||
5278 | bio->bi_sector = logical >> 9; | 5248 | bio->bi_sector = logical >> 9; |
5279 | kfree(bbio); | 5249 | kfree(bbio); |
5280 | bio_endio(bio, -EIO); | 5250 | bio_endio(bio, -EIO); |
@@ -5352,7 +5322,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
5352 | } | 5322 | } |
5353 | 5323 | ||
5354 | if (dev_nr < total_devs - 1) { | 5324 | if (dev_nr < total_devs - 1) { |
5355 | bio = bio_clone(first_bio, GFP_NOFS); | 5325 | bio = btrfs_bio_clone(first_bio, GFP_NOFS); |
5356 | BUG_ON(!bio); /* -ENOMEM */ | 5326 | BUG_ON(!bio); /* -ENOMEM */ |
5357 | } else { | 5327 | } else { |
5358 | bio = first_bio; | 5328 | bio = first_bio; |