diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
| -rw-r--r-- | fs/btrfs/volumes.c | 249 |
1 files changed, 149 insertions, 100 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 50c5a8762aed..8222f6f74147 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,48 @@ 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 | /* the size of the btrfs_bio */ | ||
| 4907 | sizeof(struct btrfs_bio) + | ||
| 4908 | /* plus the variable array for the stripes */ | ||
| 4909 | sizeof(struct btrfs_bio_stripe) * (total_stripes) + | ||
| 4910 | /* plus the variable array for the tgt dev */ | ||
| 4911 | sizeof(int) * (real_stripes) + | ||
| 4912 | /* | ||
| 4913 | * plus the raid_map, which includes both the tgt dev | ||
| 4914 | * and the stripes | ||
| 4915 | */ | ||
| 4916 | sizeof(u64) * (total_stripes), | ||
| 4917 | GFP_NOFS); | ||
| 4918 | if (!bbio) | ||
| 4919 | return NULL; | ||
| 4920 | |||
| 4921 | atomic_set(&bbio->error, 0); | ||
| 4922 | atomic_set(&bbio->refs, 1); | ||
| 4923 | |||
| 4924 | return bbio; | ||
| 4925 | } | ||
| 4926 | |||
| 4927 | void btrfs_get_bbio(struct btrfs_bio *bbio) | ||
| 4928 | { | ||
| 4929 | WARN_ON(!atomic_read(&bbio->refs)); | ||
| 4930 | atomic_inc(&bbio->refs); | ||
| 4931 | } | ||
| 4932 | |||
| 4933 | void btrfs_put_bbio(struct btrfs_bio *bbio) | ||
| 4934 | { | ||
| 4935 | if (!bbio) | ||
| 4936 | return; | ||
| 4937 | if (atomic_dec_and_test(&bbio->refs)) | ||
| 4938 | kfree(bbio); | ||
| 4939 | } | ||
| 4940 | |||
| 4912 | static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | 4941 | static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, |
| 4913 | u64 logical, u64 *length, | 4942 | u64 logical, u64 *length, |
| 4914 | struct btrfs_bio **bbio_ret, | 4943 | struct btrfs_bio **bbio_ret, |
| 4915 | int mirror_num, u64 **raid_map_ret) | 4944 | int mirror_num, int need_raid_map) |
| 4916 | { | 4945 | { |
| 4917 | struct extent_map *em; | 4946 | struct extent_map *em; |
| 4918 | struct map_lookup *map; | 4947 | struct map_lookup *map; |
| @@ -4925,7 +4954,6 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 4925 | u64 stripe_nr_orig; | 4954 | u64 stripe_nr_orig; |
| 4926 | u64 stripe_nr_end; | 4955 | u64 stripe_nr_end; |
| 4927 | u64 stripe_len; | 4956 | u64 stripe_len; |
| 4928 | u64 *raid_map = NULL; | ||
| 4929 | int stripe_index; | 4957 | int stripe_index; |
| 4930 | int i; | 4958 | int i; |
| 4931 | int ret = 0; | 4959 | int ret = 0; |
| @@ -4976,7 +5004,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 4976 | stripe_offset = offset - stripe_offset; | 5004 | stripe_offset = offset - stripe_offset; |
| 4977 | 5005 | ||
| 4978 | /* if we're here for raid56, we need to know the stripe aligned start */ | 5006 | /* 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)) { | 5007 | if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { |
| 4980 | unsigned long full_stripe_len = stripe_len * nr_data_stripes(map); | 5008 | unsigned long full_stripe_len = stripe_len * nr_data_stripes(map); |
| 4981 | raid56_full_stripe_start = offset; | 5009 | raid56_full_stripe_start = offset; |
| 4982 | 5010 | ||
| @@ -4989,8 +5017,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 4989 | 5017 | ||
| 4990 | if (rw & REQ_DISCARD) { | 5018 | if (rw & REQ_DISCARD) { |
| 4991 | /* we don't discard raid56 yet */ | 5019 | /* we don't discard raid56 yet */ |
| 4992 | if (map->type & | 5020 | if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { |
| 4993 | (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6)) { | ||
| 4994 | ret = -EOPNOTSUPP; | 5021 | ret = -EOPNOTSUPP; |
| 4995 | goto out; | 5022 | goto out; |
| 4996 | } | 5023 | } |
| @@ -5000,7 +5027,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. | 5027 | /* 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 | 5028 | For other RAID types and for RAID[56] reads, just allow a single |
| 5002 | stripe (on a single disk). */ | 5029 | stripe (on a single disk). */ |
| 5003 | if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6) && | 5030 | if ((map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) && |
| 5004 | (rw & REQ_WRITE)) { | 5031 | (rw & REQ_WRITE)) { |
| 5005 | max_len = stripe_len * nr_data_stripes(map) - | 5032 | max_len = stripe_len * nr_data_stripes(map) - |
| 5006 | (offset - raid56_full_stripe_start); | 5033 | (offset - raid56_full_stripe_start); |
| @@ -5047,7 +5074,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 5047 | u64 physical_of_found = 0; | 5074 | u64 physical_of_found = 0; |
| 5048 | 5075 | ||
| 5049 | ret = __btrfs_map_block(fs_info, REQ_GET_READ_MIRRORS, | 5076 | ret = __btrfs_map_block(fs_info, REQ_GET_READ_MIRRORS, |
| 5050 | logical, &tmp_length, &tmp_bbio, 0, NULL); | 5077 | logical, &tmp_length, &tmp_bbio, 0, 0); |
| 5051 | if (ret) { | 5078 | if (ret) { |
| 5052 | WARN_ON(tmp_bbio != NULL); | 5079 | WARN_ON(tmp_bbio != NULL); |
| 5053 | goto out; | 5080 | goto out; |
| @@ -5061,7 +5088,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 5061 | * is not left of the left cursor | 5088 | * is not left of the left cursor |
| 5062 | */ | 5089 | */ |
| 5063 | ret = -EIO; | 5090 | ret = -EIO; |
| 5064 | kfree(tmp_bbio); | 5091 | btrfs_put_bbio(tmp_bbio); |
| 5065 | goto out; | 5092 | goto out; |
| 5066 | } | 5093 | } |
| 5067 | 5094 | ||
| @@ -5096,11 +5123,11 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 5096 | } else { | 5123 | } else { |
| 5097 | WARN_ON(1); | 5124 | WARN_ON(1); |
| 5098 | ret = -EIO; | 5125 | ret = -EIO; |
| 5099 | kfree(tmp_bbio); | 5126 | btrfs_put_bbio(tmp_bbio); |
| 5100 | goto out; | 5127 | goto out; |
| 5101 | } | 5128 | } |
| 5102 | 5129 | ||
| 5103 | kfree(tmp_bbio); | 5130 | btrfs_put_bbio(tmp_bbio); |
| 5104 | } else if (mirror_num > map->num_stripes) { | 5131 | } else if (mirror_num > map->num_stripes) { |
| 5105 | mirror_num = 0; | 5132 | mirror_num = 0; |
| 5106 | } | 5133 | } |
| @@ -5166,15 +5193,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 5166 | mirror_num = stripe_index - old_stripe_index + 1; | 5193 | mirror_num = stripe_index - old_stripe_index + 1; |
| 5167 | } | 5194 | } |
| 5168 | 5195 | ||
| 5169 | } else if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | | 5196 | } else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { |
| 5170 | BTRFS_BLOCK_GROUP_RAID6)) { | 5197 | if (need_raid_map && |
| 5171 | u64 tmp; | ||
| 5172 | |||
| 5173 | if (raid_map_ret && | ||
| 5174 | ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) || | 5198 | ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) || |
| 5175 | mirror_num > 1)) { | 5199 | mirror_num > 1)) { |
| 5176 | int i, rot; | ||
| 5177 | |||
| 5178 | /* push stripe_nr back to the start of the full stripe */ | 5200 | /* push stripe_nr back to the start of the full stripe */ |
| 5179 | stripe_nr = raid56_full_stripe_start; | 5201 | stripe_nr = raid56_full_stripe_start; |
| 5180 | do_div(stripe_nr, stripe_len * nr_data_stripes(map)); | 5202 | do_div(stripe_nr, stripe_len * nr_data_stripes(map)); |
| @@ -5183,32 +5205,12 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 5183 | num_stripes = map->num_stripes; | 5205 | num_stripes = map->num_stripes; |
| 5184 | max_errors = nr_parity_stripes(map); | 5206 | max_errors = nr_parity_stripes(map); |
| 5185 | 5207 | ||
| 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; | 5208 | *length = map->stripe_len; |
| 5209 | stripe_index = 0; | 5209 | stripe_index = 0; |
| 5210 | stripe_offset = 0; | 5210 | stripe_offset = 0; |
| 5211 | } else { | 5211 | } else { |
| 5212 | u64 tmp; | ||
| 5213 | |||
| 5212 | /* | 5214 | /* |
| 5213 | * Mirror #0 or #1 means the original data block. | 5215 | * Mirror #0 or #1 means the original data block. |
| 5214 | * Mirror #2 is RAID5 parity block. | 5216 | * Mirror #2 is RAID5 parity block. |
| @@ -5246,17 +5248,42 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 5246 | tgtdev_indexes = num_stripes; | 5248 | tgtdev_indexes = num_stripes; |
| 5247 | } | 5249 | } |
| 5248 | 5250 | ||
| 5249 | bbio = kzalloc(btrfs_bio_size(num_alloc_stripes, tgtdev_indexes), | 5251 | bbio = alloc_btrfs_bio(num_alloc_stripes, tgtdev_indexes); |
| 5250 | GFP_NOFS); | ||
| 5251 | if (!bbio) { | 5252 | if (!bbio) { |
| 5252 | kfree(raid_map); | ||
| 5253 | ret = -ENOMEM; | 5253 | ret = -ENOMEM; |
| 5254 | goto out; | 5254 | goto out; |
| 5255 | } | 5255 | } |
| 5256 | atomic_set(&bbio->error, 0); | ||
| 5257 | if (dev_replace_is_ongoing) | 5256 | if (dev_replace_is_ongoing) |
| 5258 | bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes); | 5257 | bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes); |
| 5259 | 5258 | ||
| 5259 | /* build raid_map */ | ||
| 5260 | if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK && | ||
| 5261 | need_raid_map && ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) || | ||
| 5262 | mirror_num > 1)) { | ||
| 5263 | u64 tmp; | ||
| 5264 | int i, rot; | ||
| 5265 | |||
| 5266 | bbio->raid_map = (u64 *)((void *)bbio->stripes + | ||
| 5267 | sizeof(struct btrfs_bio_stripe) * | ||
| 5268 | num_alloc_stripes + | ||
| 5269 | sizeof(int) * tgtdev_indexes); | ||
| 5270 | |||
| 5271 | /* Work out the disk rotation on this stripe-set */ | ||
| 5272 | tmp = stripe_nr; | ||
| 5273 | rot = do_div(tmp, num_stripes); | ||
| 5274 | |||
| 5275 | /* Fill in the logical address of each stripe */ | ||
| 5276 | tmp = stripe_nr * nr_data_stripes(map); | ||
| 5277 | for (i = 0; i < nr_data_stripes(map); i++) | ||
| 5278 | bbio->raid_map[(i+rot) % num_stripes] = | ||
| 5279 | em->start + (tmp + i) * map->stripe_len; | ||
| 5280 | |||
| 5281 | bbio->raid_map[(i+rot) % map->num_stripes] = RAID5_P_STRIPE; | ||
| 5282 | if (map->type & BTRFS_BLOCK_GROUP_RAID6) | ||
| 5283 | bbio->raid_map[(i+rot+1) % num_stripes] = | ||
| 5284 | RAID6_Q_STRIPE; | ||
| 5285 | } | ||
| 5286 | |||
| 5260 | if (rw & REQ_DISCARD) { | 5287 | if (rw & REQ_DISCARD) { |
| 5261 | int factor = 0; | 5288 | int factor = 0; |
| 5262 | int sub_stripes = 0; | 5289 | int sub_stripes = 0; |
| @@ -5340,6 +5367,9 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 5340 | if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) | 5367 | if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) |
| 5341 | max_errors = btrfs_chunk_max_errors(map); | 5368 | max_errors = btrfs_chunk_max_errors(map); |
| 5342 | 5369 | ||
| 5370 | if (bbio->raid_map) | ||
| 5371 | sort_parity_stripes(bbio, num_stripes); | ||
| 5372 | |||
| 5343 | tgtdev_indexes = 0; | 5373 | tgtdev_indexes = 0; |
| 5344 | if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) && | 5374 | if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) && |
| 5345 | dev_replace->tgtdev != NULL) { | 5375 | dev_replace->tgtdev != NULL) { |
| @@ -5427,6 +5457,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 5427 | } | 5457 | } |
| 5428 | 5458 | ||
| 5429 | *bbio_ret = bbio; | 5459 | *bbio_ret = bbio; |
| 5460 | bbio->map_type = map->type; | ||
| 5430 | bbio->num_stripes = num_stripes; | 5461 | bbio->num_stripes = num_stripes; |
| 5431 | bbio->max_errors = max_errors; | 5462 | bbio->max_errors = max_errors; |
| 5432 | bbio->mirror_num = mirror_num; | 5463 | bbio->mirror_num = mirror_num; |
| @@ -5443,10 +5474,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; | 5474 | bbio->stripes[0].physical = physical_to_patch_in_first_stripe; |
| 5444 | bbio->mirror_num = map->num_stripes + 1; | 5475 | bbio->mirror_num = map->num_stripes + 1; |
| 5445 | } | 5476 | } |
| 5446 | if (raid_map) { | ||
| 5447 | sort_parity_stripes(bbio, raid_map); | ||
| 5448 | *raid_map_ret = raid_map; | ||
| 5449 | } | ||
| 5450 | out: | 5477 | out: |
| 5451 | if (dev_replace_is_ongoing) | 5478 | if (dev_replace_is_ongoing) |
| 5452 | btrfs_dev_replace_unlock(dev_replace); | 5479 | btrfs_dev_replace_unlock(dev_replace); |
| @@ -5459,17 +5486,17 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
| 5459 | struct btrfs_bio **bbio_ret, int mirror_num) | 5486 | struct btrfs_bio **bbio_ret, int mirror_num) |
| 5460 | { | 5487 | { |
| 5461 | return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret, | 5488 | return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret, |
| 5462 | mirror_num, NULL); | 5489 | mirror_num, 0); |
| 5463 | } | 5490 | } |
| 5464 | 5491 | ||
| 5465 | /* For Scrub/replace */ | 5492 | /* For Scrub/replace */ |
| 5466 | int btrfs_map_sblock(struct btrfs_fs_info *fs_info, int rw, | 5493 | int btrfs_map_sblock(struct btrfs_fs_info *fs_info, int rw, |
| 5467 | u64 logical, u64 *length, | 5494 | u64 logical, u64 *length, |
| 5468 | struct btrfs_bio **bbio_ret, int mirror_num, | 5495 | struct btrfs_bio **bbio_ret, int mirror_num, |
| 5469 | u64 **raid_map_ret) | 5496 | int need_raid_map) |
| 5470 | { | 5497 | { |
| 5471 | return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret, | 5498 | return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret, |
| 5472 | mirror_num, raid_map_ret); | 5499 | mirror_num, need_raid_map); |
| 5473 | } | 5500 | } |
| 5474 | 5501 | ||
| 5475 | int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | 5502 | int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, |
| @@ -5511,8 +5538,7 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | |||
| 5511 | do_div(length, map->num_stripes / map->sub_stripes); | 5538 | do_div(length, map->num_stripes / map->sub_stripes); |
| 5512 | else if (map->type & BTRFS_BLOCK_GROUP_RAID0) | 5539 | else if (map->type & BTRFS_BLOCK_GROUP_RAID0) |
| 5513 | do_div(length, map->num_stripes); | 5540 | do_div(length, map->num_stripes); |
| 5514 | else if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | | 5541 | else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) { |
| 5515 | BTRFS_BLOCK_GROUP_RAID6)) { | ||
| 5516 | do_div(length, nr_data_stripes(map)); | 5542 | do_div(length, nr_data_stripes(map)); |
| 5517 | rmap_len = map->stripe_len * nr_data_stripes(map); | 5543 | rmap_len = map->stripe_len * nr_data_stripes(map); |
| 5518 | } | 5544 | } |
| @@ -5565,7 +5591,7 @@ static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int e | |||
| 5565 | bio_endio_nodec(bio, err); | 5591 | bio_endio_nodec(bio, err); |
| 5566 | else | 5592 | else |
| 5567 | bio_endio(bio, err); | 5593 | bio_endio(bio, err); |
| 5568 | kfree(bbio); | 5594 | btrfs_put_bbio(bbio); |
| 5569 | } | 5595 | } |
| 5570 | 5596 | ||
| 5571 | static void btrfs_end_bio(struct bio *bio, int err) | 5597 | static void btrfs_end_bio(struct bio *bio, int err) |
| @@ -5808,7 +5834,6 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
| 5808 | u64 logical = (u64)bio->bi_iter.bi_sector << 9; | 5834 | u64 logical = (u64)bio->bi_iter.bi_sector << 9; |
| 5809 | u64 length = 0; | 5835 | u64 length = 0; |
| 5810 | u64 map_length; | 5836 | u64 map_length; |
| 5811 | u64 *raid_map = NULL; | ||
| 5812 | int ret; | 5837 | int ret; |
| 5813 | int dev_nr = 0; | 5838 | int dev_nr = 0; |
| 5814 | int total_devs = 1; | 5839 | int total_devs = 1; |
| @@ -5819,7 +5844,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
| 5819 | 5844 | ||
| 5820 | btrfs_bio_counter_inc_blocked(root->fs_info); | 5845 | btrfs_bio_counter_inc_blocked(root->fs_info); |
| 5821 | ret = __btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio, | 5846 | ret = __btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio, |
| 5822 | mirror_num, &raid_map); | 5847 | mirror_num, 1); |
| 5823 | if (ret) { | 5848 | if (ret) { |
| 5824 | btrfs_bio_counter_dec(root->fs_info); | 5849 | btrfs_bio_counter_dec(root->fs_info); |
| 5825 | return ret; | 5850 | return ret; |
| @@ -5832,15 +5857,13 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
| 5832 | bbio->fs_info = root->fs_info; | 5857 | bbio->fs_info = root->fs_info; |
| 5833 | atomic_set(&bbio->stripes_pending, bbio->num_stripes); | 5858 | atomic_set(&bbio->stripes_pending, bbio->num_stripes); |
| 5834 | 5859 | ||
| 5835 | if (raid_map) { | 5860 | if (bbio->raid_map) { |
| 5836 | /* In this case, map_length has been set to the length of | 5861 | /* In this case, map_length has been set to the length of |
| 5837 | a single stripe; not the whole write */ | 5862 | a single stripe; not the whole write */ |
| 5838 | if (rw & WRITE) { | 5863 | if (rw & WRITE) { |
| 5839 | ret = raid56_parity_write(root, bio, bbio, | 5864 | ret = raid56_parity_write(root, bio, bbio, map_length); |
| 5840 | raid_map, map_length); | ||
| 5841 | } else { | 5865 | } else { |
| 5842 | ret = raid56_parity_recover(root, bio, bbio, | 5866 | ret = raid56_parity_recover(root, bio, bbio, map_length, |
| 5843 | raid_map, map_length, | ||
| 5844 | mirror_num, 1); | 5867 | mirror_num, 1); |
| 5845 | } | 5868 | } |
| 5846 | 5869 | ||
| @@ -6238,17 +6261,22 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
| 6238 | struct extent_buffer *sb; | 6261 | struct extent_buffer *sb; |
| 6239 | struct btrfs_disk_key *disk_key; | 6262 | struct btrfs_disk_key *disk_key; |
| 6240 | struct btrfs_chunk *chunk; | 6263 | struct btrfs_chunk *chunk; |
| 6241 | u8 *ptr; | 6264 | u8 *array_ptr; |
| 6242 | unsigned long sb_ptr; | 6265 | unsigned long sb_array_offset; |
| 6243 | int ret = 0; | 6266 | int ret = 0; |
| 6244 | u32 num_stripes; | 6267 | u32 num_stripes; |
| 6245 | u32 array_size; | 6268 | u32 array_size; |
| 6246 | u32 len = 0; | 6269 | u32 len = 0; |
| 6247 | u32 cur; | 6270 | u32 cur_offset; |
| 6248 | struct btrfs_key key; | 6271 | struct btrfs_key key; |
| 6249 | 6272 | ||
| 6250 | sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET, | 6273 | ASSERT(BTRFS_SUPER_INFO_SIZE <= root->nodesize); |
| 6251 | BTRFS_SUPER_INFO_SIZE); | 6274 | /* |
| 6275 | * This will create extent buffer of nodesize, superblock size is | ||
| 6276 | * fixed to BTRFS_SUPER_INFO_SIZE. If nodesize > sb size, this will | ||
| 6277 | * overallocate but we can keep it as-is, only the first page is used. | ||
| 6278 | */ | ||
| 6279 | sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET); | ||
| 6252 | if (!sb) | 6280 | if (!sb) |
| 6253 | return -ENOMEM; | 6281 | return -ENOMEM; |
| 6254 | btrfs_set_buffer_uptodate(sb); | 6282 | btrfs_set_buffer_uptodate(sb); |
| @@ -6271,35 +6299,56 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
| 6271 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); | 6299 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); |
| 6272 | array_size = btrfs_super_sys_array_size(super_copy); | 6300 | array_size = btrfs_super_sys_array_size(super_copy); |
| 6273 | 6301 | ||
| 6274 | ptr = super_copy->sys_chunk_array; | 6302 | array_ptr = super_copy->sys_chunk_array; |
| 6275 | sb_ptr = offsetof(struct btrfs_super_block, sys_chunk_array); | 6303 | sb_array_offset = offsetof(struct btrfs_super_block, sys_chunk_array); |
| 6276 | cur = 0; | 6304 | cur_offset = 0; |
| 6305 | |||
| 6306 | while (cur_offset < array_size) { | ||
| 6307 | disk_key = (struct btrfs_disk_key *)array_ptr; | ||
| 6308 | len = sizeof(*disk_key); | ||
| 6309 | if (cur_offset + len > array_size) | ||
| 6310 | goto out_short_read; | ||
| 6277 | 6311 | ||
| 6278 | while (cur < array_size) { | ||
| 6279 | disk_key = (struct btrfs_disk_key *)ptr; | ||
| 6280 | btrfs_disk_key_to_cpu(&key, disk_key); | 6312 | btrfs_disk_key_to_cpu(&key, disk_key); |
| 6281 | 6313 | ||
| 6282 | len = sizeof(*disk_key); ptr += len; | 6314 | array_ptr += len; |
| 6283 | sb_ptr += len; | 6315 | sb_array_offset += len; |
| 6284 | cur += len; | 6316 | cur_offset += len; |
| 6285 | 6317 | ||
| 6286 | if (key.type == BTRFS_CHUNK_ITEM_KEY) { | 6318 | if (key.type == BTRFS_CHUNK_ITEM_KEY) { |
| 6287 | chunk = (struct btrfs_chunk *)sb_ptr; | 6319 | chunk = (struct btrfs_chunk *)sb_array_offset; |
| 6320 | /* | ||
| 6321 | * At least one btrfs_chunk with one stripe must be | ||
| 6322 | * present, exact stripe count check comes afterwards | ||
| 6323 | */ | ||
| 6324 | len = btrfs_chunk_item_size(1); | ||
| 6325 | if (cur_offset + len > array_size) | ||
| 6326 | goto out_short_read; | ||
| 6327 | |||
| 6328 | num_stripes = btrfs_chunk_num_stripes(sb, chunk); | ||
| 6329 | len = btrfs_chunk_item_size(num_stripes); | ||
| 6330 | if (cur_offset + len > array_size) | ||
| 6331 | goto out_short_read; | ||
| 6332 | |||
| 6288 | ret = read_one_chunk(root, &key, sb, chunk); | 6333 | ret = read_one_chunk(root, &key, sb, chunk); |
| 6289 | if (ret) | 6334 | if (ret) |
| 6290 | break; | 6335 | break; |
| 6291 | num_stripes = btrfs_chunk_num_stripes(sb, chunk); | ||
| 6292 | len = btrfs_chunk_item_size(num_stripes); | ||
| 6293 | } else { | 6336 | } else { |
| 6294 | ret = -EIO; | 6337 | ret = -EIO; |
| 6295 | break; | 6338 | break; |
| 6296 | } | 6339 | } |
| 6297 | ptr += len; | 6340 | array_ptr += len; |
| 6298 | sb_ptr += len; | 6341 | sb_array_offset += len; |
| 6299 | cur += len; | 6342 | cur_offset += len; |
| 6300 | } | 6343 | } |
| 6301 | free_extent_buffer(sb); | 6344 | free_extent_buffer(sb); |
| 6302 | return ret; | 6345 | return ret; |
| 6346 | |||
| 6347 | out_short_read: | ||
| 6348 | printk(KERN_ERR "BTRFS: sys_array too short to read %u bytes at offset %u\n", | ||
| 6349 | len, cur_offset); | ||
| 6350 | free_extent_buffer(sb); | ||
| 6351 | return -EIO; | ||
| 6303 | } | 6352 | } |
| 6304 | 6353 | ||
| 6305 | int btrfs_read_chunk_tree(struct btrfs_root *root) | 6354 | int btrfs_read_chunk_tree(struct btrfs_root *root) |
