diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 242 |
1 files changed, 142 insertions, 100 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 50c5a8762aed..cd4d1315aaa9 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1310,6 +1310,8 @@ again: | |||
1310 | if (ret) { | 1310 | if (ret) { |
1311 | btrfs_error(root->fs_info, ret, | 1311 | btrfs_error(root->fs_info, ret, |
1312 | "Failed to remove dev extent item"); | 1312 | "Failed to remove dev extent item"); |
1313 | } else { | ||
1314 | trans->transaction->have_free_bgs = 1; | ||
1313 | } | 1315 | } |
1314 | out: | 1316 | out: |
1315 | btrfs_free_path(path); | 1317 | btrfs_free_path(path); |
@@ -4196,7 +4198,7 @@ static u32 find_raid56_stripe_len(u32 data_devices, u32 dev_stripe_target) | |||
4196 | 4198 | ||
4197 | static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type) | 4199 | static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type) |
4198 | { | 4200 | { |
4199 | if (!(type & (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6))) | 4201 | if (!(type & BTRFS_BLOCK_GROUP_RAID56_MASK)) |
4200 | return; | 4202 | return; |
4201 | 4203 | ||
4202 | btrfs_set_fs_incompat(info, RAID56); | 4204 | btrfs_set_fs_incompat(info, RAID56); |
@@ -4803,10 +4805,8 @@ unsigned long btrfs_full_stripe_len(struct btrfs_root *root, | |||
4803 | 4805 | ||
4804 | BUG_ON(em->start > logical || em->start + em->len < logical); | 4806 | BUG_ON(em->start > logical || em->start + em->len < logical); |
4805 | map = (struct map_lookup *)em->bdev; | 4807 | map = (struct map_lookup *)em->bdev; |
4806 | if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | | 4808 | if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) |
4807 | BTRFS_BLOCK_GROUP_RAID6)) { | ||
4808 | len = map->stripe_len * nr_data_stripes(map); | 4809 | len = map->stripe_len * nr_data_stripes(map); |
4809 | } | ||
4810 | free_extent_map(em); | 4810 | free_extent_map(em); |
4811 | return len; | 4811 | return len; |
4812 | } | 4812 | } |
@@ -4826,8 +4826,7 @@ int btrfs_is_parity_mirror(struct btrfs_mapping_tree *map_tree, | |||
4826 | 4826 | ||
4827 | BUG_ON(em->start > logical || em->start + em->len < logical); | 4827 | BUG_ON(em->start > logical || em->start + em->len < logical); |
4828 | map = (struct map_lookup *)em->bdev; | 4828 | map = (struct map_lookup *)em->bdev; |
4829 | if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | | 4829 | if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) |
4830 | BTRFS_BLOCK_GROUP_RAID6)) | ||
4831 | ret = 1; | 4830 | ret = 1; |
4832 | free_extent_map(em); | 4831 | free_extent_map(em); |
4833 | return ret; | 4832 | return ret; |
@@ -4876,32 +4875,24 @@ static inline int parity_smaller(u64 a, u64 b) | |||
4876 | } | 4875 | } |
4877 | 4876 | ||
4878 | /* Bubble-sort the stripe set to put the parity/syndrome stripes last */ | 4877 | /* Bubble-sort the stripe set to put the parity/syndrome stripes last */ |
4879 | static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map) | 4878 | static void sort_parity_stripes(struct btrfs_bio *bbio, int num_stripes) |
4880 | { | 4879 | { |
4881 | struct btrfs_bio_stripe s; | 4880 | struct btrfs_bio_stripe s; |
4882 | int real_stripes = bbio->num_stripes - bbio->num_tgtdevs; | ||
4883 | int i; | 4881 | int i; |
4884 | u64 l; | 4882 | u64 l; |
4885 | int again = 1; | 4883 | int again = 1; |
4886 | int m; | ||
4887 | 4884 | ||
4888 | while (again) { | 4885 | while (again) { |
4889 | again = 0; | 4886 | again = 0; |
4890 | for (i = 0; i < real_stripes - 1; i++) { | 4887 | for (i = 0; i < num_stripes - 1; i++) { |
4891 | if (parity_smaller(raid_map[i], raid_map[i+1])) { | 4888 | if (parity_smaller(bbio->raid_map[i], |
4889 | bbio->raid_map[i+1])) { | ||
4892 | s = bbio->stripes[i]; | 4890 | s = bbio->stripes[i]; |
4893 | l = raid_map[i]; | 4891 | l = bbio->raid_map[i]; |
4894 | bbio->stripes[i] = bbio->stripes[i+1]; | 4892 | bbio->stripes[i] = bbio->stripes[i+1]; |
4895 | raid_map[i] = raid_map[i+1]; | 4893 | bbio->raid_map[i] = bbio->raid_map[i+1]; |
4896 | bbio->stripes[i+1] = s; | 4894 | bbio->stripes[i+1] = s; |
4897 | raid_map[i+1] = l; | 4895 | bbio->raid_map[i+1] = l; |
4898 | |||
4899 | if (bbio->tgtdev_map) { | ||
4900 | m = bbio->tgtdev_map[i]; | ||
4901 | bbio->tgtdev_map[i] = | ||
4902 | bbio->tgtdev_map[i + 1]; | ||
4903 | bbio->tgtdev_map[i + 1] = m; | ||
4904 | } | ||
4905 | 4896 | ||
4906 | again = 1; | 4897 | again = 1; |
4907 | } | 4898 | } |
@@ -4909,10 +4900,41 @@ static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map) | |||
4909 | } | 4900 | } |
4910 | } | 4901 | } |
4911 | 4902 | ||
4903 | static struct btrfs_bio *alloc_btrfs_bio(int total_stripes, int real_stripes) | ||
4904 | { | ||
4905 | struct btrfs_bio *bbio = kzalloc( | ||
4906 | sizeof(struct btrfs_bio) + | ||
4907 | sizeof(struct btrfs_bio_stripe) * (total_stripes) + | ||
4908 | sizeof(int) * (real_stripes) + | ||
4909 | sizeof(u64) * (real_stripes), | ||
4910 | GFP_NOFS); | ||
4911 | if (!bbio) | ||
4912 | return NULL; | ||
4913 | |||
4914 | atomic_set(&bbio->error, 0); | ||
4915 | atomic_set(&bbio->refs, 1); | ||
4916 | |||
4917 | return bbio; | ||
4918 | } | ||
4919 | |||
4920 | void btrfs_get_bbio(struct btrfs_bio *bbio) | ||
4921 | { | ||
4922 | WARN_ON(!atomic_read(&bbio->refs)); | ||
4923 | atomic_inc(&bbio->refs); | ||
4924 | } | ||
4925 | |||
4926 | void btrfs_put_bbio(struct btrfs_bio *bbio) | ||
4927 | { | ||
4928 | if (!bbio) | ||
4929 | return; | ||
4930 | if (atomic_dec_and_test(&bbio->refs)) | ||
4931 | kfree(bbio); | ||
4932 | } | ||
4933 | |||
4912 | static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | 4934 | static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, |
4913 | u64 logical, u64 *length, | 4935 | u64 logical, u64 *length, |
4914 | struct btrfs_bio **bbio_ret, | 4936 | struct btrfs_bio **bbio_ret, |
4915 | int mirror_num, u64 **raid_map_ret) | 4937 | int mirror_num, int need_raid_map) |
4916 | { | 4938 | { |
4917 | struct extent_map *em; | 4939 | struct extent_map *em; |
4918 | struct map_lookup *map; | 4940 | struct map_lookup *map; |
@@ -4925,7 +4947,6 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
4925 | u64 stripe_nr_orig; | 4947 | u64 stripe_nr_orig; |
4926 | u64 stripe_nr_end; | 4948 | u64 stripe_nr_end; |
4927 | u64 stripe_len; | 4949 | u64 stripe_len; |
4928 | u64 *raid_map = NULL; | ||
4929 | int stripe_index; | 4950 | int stripe_index; |
4930 | int i; | 4951 | int i; |
4931 | int ret = 0; | 4952 | int ret = 0; |
@@ -4976,7 +4997,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
4976 | stripe_offset = offset - stripe_offset; | 4997 | stripe_offset = offset - stripe_offset; |
4977 | 4998 | ||
4978 | /* if we're here for raid56, we need to know the stripe aligned start */ | 4999 | /* if we're here for raid56, we need to know the stripe aligned start */ |
4979 | if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6)) { | 5000 | if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { |
4980 | unsigned long full_stripe_len = stripe_len * nr_data_stripes(map); | 5001 | unsigned long full_stripe_len = stripe_len * nr_data_stripes(map); |
4981 | raid56_full_stripe_start = offset; | 5002 | raid56_full_stripe_start = offset; |
4982 | 5003 | ||
@@ -4989,8 +5010,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
4989 | 5010 | ||
4990 | if (rw & REQ_DISCARD) { | 5011 | if (rw & REQ_DISCARD) { |
4991 | /* we don't discard raid56 yet */ | 5012 | /* we don't discard raid56 yet */ |
4992 | if (map->type & | 5013 | if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { |
4993 | (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6)) { | ||
4994 | ret = -EOPNOTSUPP; | 5014 | ret = -EOPNOTSUPP; |
4995 | goto out; | 5015 | goto out; |
4996 | } | 5016 | } |
@@ -5000,7 +5020,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5000 | /* For writes to RAID[56], allow a full stripeset across all disks. | 5020 | /* For writes to RAID[56], allow a full stripeset across all disks. |
5001 | For other RAID types and for RAID[56] reads, just allow a single | 5021 | For other RAID types and for RAID[56] reads, just allow a single |
5002 | stripe (on a single disk). */ | 5022 | stripe (on a single disk). */ |
5003 | if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6) && | 5023 | if ((map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) && |
5004 | (rw & REQ_WRITE)) { | 5024 | (rw & REQ_WRITE)) { |
5005 | max_len = stripe_len * nr_data_stripes(map) - | 5025 | max_len = stripe_len * nr_data_stripes(map) - |
5006 | (offset - raid56_full_stripe_start); | 5026 | (offset - raid56_full_stripe_start); |
@@ -5047,7 +5067,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5047 | u64 physical_of_found = 0; | 5067 | u64 physical_of_found = 0; |
5048 | 5068 | ||
5049 | ret = __btrfs_map_block(fs_info, REQ_GET_READ_MIRRORS, | 5069 | ret = __btrfs_map_block(fs_info, REQ_GET_READ_MIRRORS, |
5050 | logical, &tmp_length, &tmp_bbio, 0, NULL); | 5070 | logical, &tmp_length, &tmp_bbio, 0, 0); |
5051 | if (ret) { | 5071 | if (ret) { |
5052 | WARN_ON(tmp_bbio != NULL); | 5072 | WARN_ON(tmp_bbio != NULL); |
5053 | goto out; | 5073 | goto out; |
@@ -5061,7 +5081,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5061 | * is not left of the left cursor | 5081 | * is not left of the left cursor |
5062 | */ | 5082 | */ |
5063 | ret = -EIO; | 5083 | ret = -EIO; |
5064 | kfree(tmp_bbio); | 5084 | btrfs_put_bbio(tmp_bbio); |
5065 | goto out; | 5085 | goto out; |
5066 | } | 5086 | } |
5067 | 5087 | ||
@@ -5096,11 +5116,11 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5096 | } else { | 5116 | } else { |
5097 | WARN_ON(1); | 5117 | WARN_ON(1); |
5098 | ret = -EIO; | 5118 | ret = -EIO; |
5099 | kfree(tmp_bbio); | 5119 | btrfs_put_bbio(tmp_bbio); |
5100 | goto out; | 5120 | goto out; |
5101 | } | 5121 | } |
5102 | 5122 | ||
5103 | kfree(tmp_bbio); | 5123 | btrfs_put_bbio(tmp_bbio); |
5104 | } else if (mirror_num > map->num_stripes) { | 5124 | } else if (mirror_num > map->num_stripes) { |
5105 | mirror_num = 0; | 5125 | mirror_num = 0; |
5106 | } | 5126 | } |
@@ -5166,15 +5186,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5166 | mirror_num = stripe_index - old_stripe_index + 1; | 5186 | mirror_num = stripe_index - old_stripe_index + 1; |
5167 | } | 5187 | } |
5168 | 5188 | ||
5169 | } else if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | | 5189 | } else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { |
5170 | BTRFS_BLOCK_GROUP_RAID6)) { | 5190 | if (need_raid_map && |
5171 | u64 tmp; | ||
5172 | |||
5173 | if (raid_map_ret && | ||
5174 | ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) || | 5191 | ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) || |
5175 | mirror_num > 1)) { | 5192 | mirror_num > 1)) { |
5176 | int i, rot; | ||
5177 | |||
5178 | /* push stripe_nr back to the start of the full stripe */ | 5193 | /* push stripe_nr back to the start of the full stripe */ |
5179 | stripe_nr = raid56_full_stripe_start; | 5194 | stripe_nr = raid56_full_stripe_start; |
5180 | do_div(stripe_nr, stripe_len * nr_data_stripes(map)); | 5195 | do_div(stripe_nr, stripe_len * nr_data_stripes(map)); |
@@ -5183,32 +5198,12 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5183 | num_stripes = map->num_stripes; | 5198 | num_stripes = map->num_stripes; |
5184 | max_errors = nr_parity_stripes(map); | 5199 | max_errors = nr_parity_stripes(map); |
5185 | 5200 | ||
5186 | raid_map = kmalloc_array(num_stripes, sizeof(u64), | ||
5187 | GFP_NOFS); | ||
5188 | if (!raid_map) { | ||
5189 | ret = -ENOMEM; | ||
5190 | goto out; | ||
5191 | } | ||
5192 | |||
5193 | /* Work out the disk rotation on this stripe-set */ | ||
5194 | tmp = stripe_nr; | ||
5195 | rot = do_div(tmp, num_stripes); | ||
5196 | |||
5197 | /* Fill in the logical address of each stripe */ | ||
5198 | tmp = stripe_nr * nr_data_stripes(map); | ||
5199 | for (i = 0; i < nr_data_stripes(map); i++) | ||
5200 | raid_map[(i+rot) % num_stripes] = | ||
5201 | em->start + (tmp + i) * map->stripe_len; | ||
5202 | |||
5203 | raid_map[(i+rot) % map->num_stripes] = RAID5_P_STRIPE; | ||
5204 | if (map->type & BTRFS_BLOCK_GROUP_RAID6) | ||
5205 | raid_map[(i+rot+1) % num_stripes] = | ||
5206 | RAID6_Q_STRIPE; | ||
5207 | |||
5208 | *length = map->stripe_len; | 5201 | *length = map->stripe_len; |
5209 | stripe_index = 0; | 5202 | stripe_index = 0; |
5210 | stripe_offset = 0; | 5203 | stripe_offset = 0; |
5211 | } else { | 5204 | } else { |
5205 | u64 tmp; | ||
5206 | |||
5212 | /* | 5207 | /* |
5213 | * Mirror #0 or #1 means the original data block. | 5208 | * Mirror #0 or #1 means the original data block. |
5214 | * Mirror #2 is RAID5 parity block. | 5209 | * Mirror #2 is RAID5 parity block. |
@@ -5246,17 +5241,42 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5246 | tgtdev_indexes = num_stripes; | 5241 | tgtdev_indexes = num_stripes; |
5247 | } | 5242 | } |
5248 | 5243 | ||
5249 | bbio = kzalloc(btrfs_bio_size(num_alloc_stripes, tgtdev_indexes), | 5244 | bbio = alloc_btrfs_bio(num_alloc_stripes, tgtdev_indexes); |
5250 | GFP_NOFS); | ||
5251 | if (!bbio) { | 5245 | if (!bbio) { |
5252 | kfree(raid_map); | ||
5253 | ret = -ENOMEM; | 5246 | ret = -ENOMEM; |
5254 | goto out; | 5247 | goto out; |
5255 | } | 5248 | } |
5256 | atomic_set(&bbio->error, 0); | ||
5257 | if (dev_replace_is_ongoing) | 5249 | if (dev_replace_is_ongoing) |
5258 | bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes); | 5250 | bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes); |
5259 | 5251 | ||
5252 | /* build raid_map */ | ||
5253 | if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK && | ||
5254 | need_raid_map && ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) || | ||
5255 | mirror_num > 1)) { | ||
5256 | u64 tmp; | ||
5257 | int i, rot; | ||
5258 | |||
5259 | bbio->raid_map = (u64 *)((void *)bbio->stripes + | ||
5260 | sizeof(struct btrfs_bio_stripe) * | ||
5261 | num_alloc_stripes + | ||
5262 | sizeof(int) * tgtdev_indexes); | ||
5263 | |||
5264 | /* Work out the disk rotation on this stripe-set */ | ||
5265 | tmp = stripe_nr; | ||
5266 | rot = do_div(tmp, num_stripes); | ||
5267 | |||
5268 | /* Fill in the logical address of each stripe */ | ||
5269 | tmp = stripe_nr * nr_data_stripes(map); | ||
5270 | for (i = 0; i < nr_data_stripes(map); i++) | ||
5271 | bbio->raid_map[(i+rot) % num_stripes] = | ||
5272 | em->start + (tmp + i) * map->stripe_len; | ||
5273 | |||
5274 | bbio->raid_map[(i+rot) % map->num_stripes] = RAID5_P_STRIPE; | ||
5275 | if (map->type & BTRFS_BLOCK_GROUP_RAID6) | ||
5276 | bbio->raid_map[(i+rot+1) % num_stripes] = | ||
5277 | RAID6_Q_STRIPE; | ||
5278 | } | ||
5279 | |||
5260 | if (rw & REQ_DISCARD) { | 5280 | if (rw & REQ_DISCARD) { |
5261 | int factor = 0; | 5281 | int factor = 0; |
5262 | int sub_stripes = 0; | 5282 | int sub_stripes = 0; |
@@ -5340,6 +5360,9 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5340 | if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) | 5360 | if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) |
5341 | max_errors = btrfs_chunk_max_errors(map); | 5361 | max_errors = btrfs_chunk_max_errors(map); |
5342 | 5362 | ||
5363 | if (bbio->raid_map) | ||
5364 | sort_parity_stripes(bbio, num_stripes); | ||
5365 | |||
5343 | tgtdev_indexes = 0; | 5366 | tgtdev_indexes = 0; |
5344 | if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) && | 5367 | if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) && |
5345 | dev_replace->tgtdev != NULL) { | 5368 | dev_replace->tgtdev != NULL) { |
@@ -5427,6 +5450,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5427 | } | 5450 | } |
5428 | 5451 | ||
5429 | *bbio_ret = bbio; | 5452 | *bbio_ret = bbio; |
5453 | bbio->map_type = map->type; | ||
5430 | bbio->num_stripes = num_stripes; | 5454 | bbio->num_stripes = num_stripes; |
5431 | bbio->max_errors = max_errors; | 5455 | bbio->max_errors = max_errors; |
5432 | bbio->mirror_num = mirror_num; | 5456 | bbio->mirror_num = mirror_num; |
@@ -5443,10 +5467,6 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5443 | bbio->stripes[0].physical = physical_to_patch_in_first_stripe; | 5467 | bbio->stripes[0].physical = physical_to_patch_in_first_stripe; |
5444 | bbio->mirror_num = map->num_stripes + 1; | 5468 | bbio->mirror_num = map->num_stripes + 1; |
5445 | } | 5469 | } |
5446 | if (raid_map) { | ||
5447 | sort_parity_stripes(bbio, raid_map); | ||
5448 | *raid_map_ret = raid_map; | ||
5449 | } | ||
5450 | out: | 5470 | out: |
5451 | if (dev_replace_is_ongoing) | 5471 | if (dev_replace_is_ongoing) |
5452 | btrfs_dev_replace_unlock(dev_replace); | 5472 | btrfs_dev_replace_unlock(dev_replace); |
@@ -5459,17 +5479,17 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5459 | struct btrfs_bio **bbio_ret, int mirror_num) | 5479 | struct btrfs_bio **bbio_ret, int mirror_num) |
5460 | { | 5480 | { |
5461 | return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret, | 5481 | return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret, |
5462 | mirror_num, NULL); | 5482 | mirror_num, 0); |
5463 | } | 5483 | } |
5464 | 5484 | ||
5465 | /* For Scrub/replace */ | 5485 | /* For Scrub/replace */ |
5466 | int btrfs_map_sblock(struct btrfs_fs_info *fs_info, int rw, | 5486 | int btrfs_map_sblock(struct btrfs_fs_info *fs_info, int rw, |
5467 | u64 logical, u64 *length, | 5487 | u64 logical, u64 *length, |
5468 | struct btrfs_bio **bbio_ret, int mirror_num, | 5488 | struct btrfs_bio **bbio_ret, int mirror_num, |
5469 | u64 **raid_map_ret) | 5489 | int need_raid_map) |
5470 | { | 5490 | { |
5471 | return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret, | 5491 | return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret, |
5472 | mirror_num, raid_map_ret); | 5492 | mirror_num, need_raid_map); |
5473 | } | 5493 | } |
5474 | 5494 | ||
5475 | int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | 5495 | int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, |
@@ -5511,8 +5531,7 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | |||
5511 | do_div(length, map->num_stripes / map->sub_stripes); | 5531 | do_div(length, map->num_stripes / map->sub_stripes); |
5512 | else if (map->type & BTRFS_BLOCK_GROUP_RAID0) | 5532 | else if (map->type & BTRFS_BLOCK_GROUP_RAID0) |
5513 | do_div(length, map->num_stripes); | 5533 | do_div(length, map->num_stripes); |
5514 | else if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | | 5534 | else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { |
5515 | BTRFS_BLOCK_GROUP_RAID6)) { | ||
5516 | do_div(length, nr_data_stripes(map)); | 5535 | do_div(length, nr_data_stripes(map)); |
5517 | rmap_len = map->stripe_len * nr_data_stripes(map); | 5536 | rmap_len = map->stripe_len * nr_data_stripes(map); |
5518 | } | 5537 | } |
@@ -5565,7 +5584,7 @@ static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int e | |||
5565 | bio_endio_nodec(bio, err); | 5584 | bio_endio_nodec(bio, err); |
5566 | else | 5585 | else |
5567 | bio_endio(bio, err); | 5586 | bio_endio(bio, err); |
5568 | kfree(bbio); | 5587 | btrfs_put_bbio(bbio); |
5569 | } | 5588 | } |
5570 | 5589 | ||
5571 | static void btrfs_end_bio(struct bio *bio, int err) | 5590 | static void btrfs_end_bio(struct bio *bio, int err) |
@@ -5808,7 +5827,6 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
5808 | u64 logical = (u64)bio->bi_iter.bi_sector << 9; | 5827 | u64 logical = (u64)bio->bi_iter.bi_sector << 9; |
5809 | u64 length = 0; | 5828 | u64 length = 0; |
5810 | u64 map_length; | 5829 | u64 map_length; |
5811 | u64 *raid_map = NULL; | ||
5812 | int ret; | 5830 | int ret; |
5813 | int dev_nr = 0; | 5831 | int dev_nr = 0; |
5814 | int total_devs = 1; | 5832 | int total_devs = 1; |
@@ -5819,7 +5837,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
5819 | 5837 | ||
5820 | btrfs_bio_counter_inc_blocked(root->fs_info); | 5838 | btrfs_bio_counter_inc_blocked(root->fs_info); |
5821 | ret = __btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio, | 5839 | ret = __btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio, |
5822 | mirror_num, &raid_map); | 5840 | mirror_num, 1); |
5823 | if (ret) { | 5841 | if (ret) { |
5824 | btrfs_bio_counter_dec(root->fs_info); | 5842 | btrfs_bio_counter_dec(root->fs_info); |
5825 | return ret; | 5843 | return ret; |
@@ -5832,15 +5850,13 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
5832 | bbio->fs_info = root->fs_info; | 5850 | bbio->fs_info = root->fs_info; |
5833 | atomic_set(&bbio->stripes_pending, bbio->num_stripes); | 5851 | atomic_set(&bbio->stripes_pending, bbio->num_stripes); |
5834 | 5852 | ||
5835 | if (raid_map) { | 5853 | if (bbio->raid_map) { |
5836 | /* In this case, map_length has been set to the length of | 5854 | /* In this case, map_length has been set to the length of |
5837 | a single stripe; not the whole write */ | 5855 | a single stripe; not the whole write */ |
5838 | if (rw & WRITE) { | 5856 | if (rw & WRITE) { |
5839 | ret = raid56_parity_write(root, bio, bbio, | 5857 | ret = raid56_parity_write(root, bio, bbio, map_length); |
5840 | raid_map, map_length); | ||
5841 | } else { | 5858 | } else { |
5842 | ret = raid56_parity_recover(root, bio, bbio, | 5859 | ret = raid56_parity_recover(root, bio, bbio, map_length, |
5843 | raid_map, map_length, | ||
5844 | mirror_num, 1); | 5860 | mirror_num, 1); |
5845 | } | 5861 | } |
5846 | 5862 | ||
@@ -6238,17 +6254,22 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
6238 | struct extent_buffer *sb; | 6254 | struct extent_buffer *sb; |
6239 | struct btrfs_disk_key *disk_key; | 6255 | struct btrfs_disk_key *disk_key; |
6240 | struct btrfs_chunk *chunk; | 6256 | struct btrfs_chunk *chunk; |
6241 | u8 *ptr; | 6257 | u8 *array_ptr; |
6242 | unsigned long sb_ptr; | 6258 | unsigned long sb_array_offset; |
6243 | int ret = 0; | 6259 | int ret = 0; |
6244 | u32 num_stripes; | 6260 | u32 num_stripes; |
6245 | u32 array_size; | 6261 | u32 array_size; |
6246 | u32 len = 0; | 6262 | u32 len = 0; |
6247 | u32 cur; | 6263 | u32 cur_offset; |
6248 | struct btrfs_key key; | 6264 | struct btrfs_key key; |
6249 | 6265 | ||
6250 | sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET, | 6266 | ASSERT(BTRFS_SUPER_INFO_SIZE <= root->nodesize); |
6251 | BTRFS_SUPER_INFO_SIZE); | 6267 | /* |
6268 | * This will create extent buffer of nodesize, superblock size is | ||
6269 | * fixed to BTRFS_SUPER_INFO_SIZE. If nodesize > sb size, this will | ||
6270 | * overallocate but we can keep it as-is, only the first page is used. | ||
6271 | */ | ||
6272 | sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET); | ||
6252 | if (!sb) | 6273 | if (!sb) |
6253 | return -ENOMEM; | 6274 | return -ENOMEM; |
6254 | btrfs_set_buffer_uptodate(sb); | 6275 | btrfs_set_buffer_uptodate(sb); |
@@ -6271,35 +6292,56 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
6271 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); | 6292 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); |
6272 | array_size = btrfs_super_sys_array_size(super_copy); | 6293 | array_size = btrfs_super_sys_array_size(super_copy); |
6273 | 6294 | ||
6274 | ptr = super_copy->sys_chunk_array; | 6295 | array_ptr = super_copy->sys_chunk_array; |
6275 | sb_ptr = offsetof(struct btrfs_super_block, sys_chunk_array); | 6296 | sb_array_offset = offsetof(struct btrfs_super_block, sys_chunk_array); |
6276 | cur = 0; | 6297 | cur_offset = 0; |
6298 | |||
6299 | while (cur_offset < array_size) { | ||
6300 | disk_key = (struct btrfs_disk_key *)array_ptr; | ||
6301 | len = sizeof(*disk_key); | ||
6302 | if (cur_offset + len > array_size) | ||
6303 | goto out_short_read; | ||
6277 | 6304 | ||
6278 | while (cur < array_size) { | ||
6279 | disk_key = (struct btrfs_disk_key *)ptr; | ||
6280 | btrfs_disk_key_to_cpu(&key, disk_key); | 6305 | btrfs_disk_key_to_cpu(&key, disk_key); |
6281 | 6306 | ||
6282 | len = sizeof(*disk_key); ptr += len; | 6307 | array_ptr += len; |
6283 | sb_ptr += len; | 6308 | sb_array_offset += len; |
6284 | cur += len; | 6309 | cur_offset += len; |
6285 | 6310 | ||
6286 | if (key.type == BTRFS_CHUNK_ITEM_KEY) { | 6311 | if (key.type == BTRFS_CHUNK_ITEM_KEY) { |
6287 | chunk = (struct btrfs_chunk *)sb_ptr; | 6312 | chunk = (struct btrfs_chunk *)sb_array_offset; |
6313 | /* | ||
6314 | * At least one btrfs_chunk with one stripe must be | ||
6315 | * present, exact stripe count check comes afterwards | ||
6316 | */ | ||
6317 | len = btrfs_chunk_item_size(1); | ||
6318 | if (cur_offset + len > array_size) | ||
6319 | goto out_short_read; | ||
6320 | |||
6321 | num_stripes = btrfs_chunk_num_stripes(sb, chunk); | ||
6322 | len = btrfs_chunk_item_size(num_stripes); | ||
6323 | if (cur_offset + len > array_size) | ||
6324 | goto out_short_read; | ||
6325 | |||
6288 | ret = read_one_chunk(root, &key, sb, chunk); | 6326 | ret = read_one_chunk(root, &key, sb, chunk); |
6289 | if (ret) | 6327 | if (ret) |
6290 | break; | 6328 | break; |
6291 | num_stripes = btrfs_chunk_num_stripes(sb, chunk); | ||
6292 | len = btrfs_chunk_item_size(num_stripes); | ||
6293 | } else { | 6329 | } else { |
6294 | ret = -EIO; | 6330 | ret = -EIO; |
6295 | break; | 6331 | break; |
6296 | } | 6332 | } |
6297 | ptr += len; | 6333 | array_ptr += len; |
6298 | sb_ptr += len; | 6334 | sb_array_offset += len; |
6299 | cur += len; | 6335 | cur_offset += len; |
6300 | } | 6336 | } |
6301 | free_extent_buffer(sb); | 6337 | free_extent_buffer(sb); |
6302 | return ret; | 6338 | return ret; |
6339 | |||
6340 | out_short_read: | ||
6341 | printk(KERN_ERR "BTRFS: sys_array too short to read %u bytes at offset %u\n", | ||
6342 | len, cur_offset); | ||
6343 | free_extent_buffer(sb); | ||
6344 | return -EIO; | ||
6303 | } | 6345 | } |
6304 | 6346 | ||
6305 | int btrfs_read_chunk_tree(struct btrfs_root *root) | 6347 | int btrfs_read_chunk_tree(struct btrfs_root *root) |