aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c52
1 files changed, 40 insertions, 12 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index ff2b35114972..0144790e296e 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4879,13 +4879,15 @@ static inline int parity_smaller(u64 a, u64 b)
4879static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map) 4879static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map)
4880{ 4880{
4881 struct btrfs_bio_stripe s; 4881 struct btrfs_bio_stripe s;
4882 int real_stripes = bbio->num_stripes - bbio->num_tgtdevs;
4882 int i; 4883 int i;
4883 u64 l; 4884 u64 l;
4884 int again = 1; 4885 int again = 1;
4886 int m;
4885 4887
4886 while (again) { 4888 while (again) {
4887 again = 0; 4889 again = 0;
4888 for (i = 0; i < bbio->num_stripes - 1; i++) { 4890 for (i = 0; i < real_stripes - 1; i++) {
4889 if (parity_smaller(raid_map[i], raid_map[i+1])) { 4891 if (parity_smaller(raid_map[i], raid_map[i+1])) {
4890 s = bbio->stripes[i]; 4892 s = bbio->stripes[i];
4891 l = raid_map[i]; 4893 l = raid_map[i];
@@ -4893,6 +4895,14 @@ static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map)
4893 raid_map[i] = raid_map[i+1]; 4895 raid_map[i] = raid_map[i+1];
4894 bbio->stripes[i+1] = s; 4896 bbio->stripes[i+1] = s;
4895 raid_map[i+1] = l; 4897 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 again = 1; 4906 again = 1;
4897 } 4907 }
4898 } 4908 }
@@ -4921,6 +4931,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4921 int ret = 0; 4931 int ret = 0;
4922 int num_stripes; 4932 int num_stripes;
4923 int max_errors = 0; 4933 int max_errors = 0;
4934 int tgtdev_indexes = 0;
4924 struct btrfs_bio *bbio = NULL; 4935 struct btrfs_bio *bbio = NULL;
4925 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; 4936 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
4926 int dev_replace_is_ongoing = 0; 4937 int dev_replace_is_ongoing = 0;
@@ -5159,15 +5170,14 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5159 BTRFS_BLOCK_GROUP_RAID6)) { 5170 BTRFS_BLOCK_GROUP_RAID6)) {
5160 u64 tmp; 5171 u64 tmp;
5161 5172
5162 if (bbio_ret && ((rw & REQ_WRITE) || mirror_num > 1) 5173 if (raid_map_ret &&
5163 && raid_map_ret) { 5174 ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) ||
5175 mirror_num > 1)) {
5164 int i, rot; 5176 int i, rot;
5165 5177
5166 /* push stripe_nr back to the start of the full stripe */ 5178 /* push stripe_nr back to the start of the full stripe */
5167 stripe_nr = raid56_full_stripe_start; 5179 stripe_nr = raid56_full_stripe_start;
5168 do_div(stripe_nr, stripe_len); 5180 do_div(stripe_nr, stripe_len * nr_data_stripes(map));
5169
5170 stripe_index = do_div(stripe_nr, nr_data_stripes(map));
5171 5181
5172 /* RAID[56] write or recovery. Return all stripes */ 5182 /* RAID[56] write or recovery. Return all stripes */
5173 num_stripes = map->num_stripes; 5183 num_stripes = map->num_stripes;
@@ -5233,14 +5243,19 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5233 num_alloc_stripes <<= 1; 5243 num_alloc_stripes <<= 1;
5234 if (rw & REQ_GET_READ_MIRRORS) 5244 if (rw & REQ_GET_READ_MIRRORS)
5235 num_alloc_stripes++; 5245 num_alloc_stripes++;
5246 tgtdev_indexes = num_stripes;
5236 } 5247 }
5237 bbio = kzalloc(btrfs_bio_size(num_alloc_stripes), GFP_NOFS); 5248
5249 bbio = kzalloc(btrfs_bio_size(num_alloc_stripes, tgtdev_indexes),
5250 GFP_NOFS);
5238 if (!bbio) { 5251 if (!bbio) {
5239 kfree(raid_map); 5252 kfree(raid_map);
5240 ret = -ENOMEM; 5253 ret = -ENOMEM;
5241 goto out; 5254 goto out;
5242 } 5255 }
5243 atomic_set(&bbio->error, 0); 5256 atomic_set(&bbio->error, 0);
5257 if (dev_replace_is_ongoing)
5258 bbio->tgtdev_map = (int *)(bbio->stripes + num_alloc_stripes);
5244 5259
5245 if (rw & REQ_DISCARD) { 5260 if (rw & REQ_DISCARD) {
5246 int factor = 0; 5261 int factor = 0;
@@ -5325,6 +5340,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5325 if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) 5340 if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS))
5326 max_errors = btrfs_chunk_max_errors(map); 5341 max_errors = btrfs_chunk_max_errors(map);
5327 5342
5343 tgtdev_indexes = 0;
5328 if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) && 5344 if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) &&
5329 dev_replace->tgtdev != NULL) { 5345 dev_replace->tgtdev != NULL) {
5330 int index_where_to_add; 5346 int index_where_to_add;
@@ -5353,8 +5369,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5353 new->physical = old->physical; 5369 new->physical = old->physical;
5354 new->length = old->length; 5370 new->length = old->length;
5355 new->dev = dev_replace->tgtdev; 5371 new->dev = dev_replace->tgtdev;
5372 bbio->tgtdev_map[i] = index_where_to_add;
5356 index_where_to_add++; 5373 index_where_to_add++;
5357 max_errors++; 5374 max_errors++;
5375 tgtdev_indexes++;
5358 } 5376 }
5359 } 5377 }
5360 num_stripes = index_where_to_add; 5378 num_stripes = index_where_to_add;
@@ -5400,7 +5418,9 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5400 tgtdev_stripe->length = 5418 tgtdev_stripe->length =
5401 bbio->stripes[index_srcdev].length; 5419 bbio->stripes[index_srcdev].length;
5402 tgtdev_stripe->dev = dev_replace->tgtdev; 5420 tgtdev_stripe->dev = dev_replace->tgtdev;
5421 bbio->tgtdev_map[index_srcdev] = num_stripes;
5403 5422
5423 tgtdev_indexes++;
5404 num_stripes++; 5424 num_stripes++;
5405 } 5425 }
5406 } 5426 }
@@ -5410,6 +5430,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5410 bbio->num_stripes = num_stripes; 5430 bbio->num_stripes = num_stripes;
5411 bbio->max_errors = max_errors; 5431 bbio->max_errors = max_errors;
5412 bbio->mirror_num = mirror_num; 5432 bbio->mirror_num = mirror_num;
5433 bbio->num_tgtdevs = tgtdev_indexes;
5413 5434
5414 /* 5435 /*
5415 * this is the case that REQ_READ && dev_replace_is_ongoing && 5436 * this is the case that REQ_READ && dev_replace_is_ongoing &&
@@ -5441,6 +5462,16 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
5441 mirror_num, NULL); 5462 mirror_num, NULL);
5442} 5463}
5443 5464
5465/* For Scrub/replace */
5466int btrfs_map_sblock(struct btrfs_fs_info *fs_info, int rw,
5467 u64 logical, u64 *length,
5468 struct btrfs_bio **bbio_ret, int mirror_num,
5469 u64 **raid_map_ret)
5470{
5471 return __btrfs_map_block(fs_info, rw, logical, length, bbio_ret,
5472 mirror_num, raid_map_ret);
5473}
5474
5444int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, 5475int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
5445 u64 chunk_start, u64 physical, u64 devid, 5476 u64 chunk_start, u64 physical, u64 devid,
5446 u64 **logical, int *naddrs, int *stripe_len) 5477 u64 **logical, int *naddrs, int *stripe_len)
@@ -5810,12 +5841,9 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
5810 } else { 5841 } else {
5811 ret = raid56_parity_recover(root, bio, bbio, 5842 ret = raid56_parity_recover(root, bio, bbio,
5812 raid_map, map_length, 5843 raid_map, map_length,
5813 mirror_num); 5844 mirror_num, 1);
5814 } 5845 }
5815 /* 5846
5816 * FIXME, replace dosen't support raid56 yet, please fix
5817 * it in the future.
5818 */
5819 btrfs_bio_counter_dec(root->fs_info); 5847 btrfs_bio_counter_dec(root->fs_info);
5820 return ret; 5848 return ret;
5821 } 5849 }