diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 90 |
1 files changed, 58 insertions, 32 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index d47289c715c8..0144790e296e 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -53,16 +53,6 @@ static void btrfs_dev_stat_print_on_load(struct btrfs_device *device); | |||
53 | DEFINE_MUTEX(uuid_mutex); | 53 | DEFINE_MUTEX(uuid_mutex); |
54 | static LIST_HEAD(fs_uuids); | 54 | static LIST_HEAD(fs_uuids); |
55 | 55 | ||
56 | static void lock_chunks(struct btrfs_root *root) | ||
57 | { | ||
58 | mutex_lock(&root->fs_info->chunk_mutex); | ||
59 | } | ||
60 | |||
61 | static void unlock_chunks(struct btrfs_root *root) | ||
62 | { | ||
63 | mutex_unlock(&root->fs_info->chunk_mutex); | ||
64 | } | ||
65 | |||
66 | static struct btrfs_fs_devices *__alloc_fs_devices(void) | 56 | static struct btrfs_fs_devices *__alloc_fs_devices(void) |
67 | { | 57 | { |
68 | struct btrfs_fs_devices *fs_devs; | 58 | struct btrfs_fs_devices *fs_devs; |
@@ -1068,9 +1058,11 @@ static int contains_pending_extent(struct btrfs_trans_handle *trans, | |||
1068 | u64 *start, u64 len) | 1058 | u64 *start, u64 len) |
1069 | { | 1059 | { |
1070 | struct extent_map *em; | 1060 | struct extent_map *em; |
1061 | struct list_head *search_list = &trans->transaction->pending_chunks; | ||
1071 | int ret = 0; | 1062 | int ret = 0; |
1072 | 1063 | ||
1073 | list_for_each_entry(em, &trans->transaction->pending_chunks, list) { | 1064 | again: |
1065 | list_for_each_entry(em, search_list, list) { | ||
1074 | struct map_lookup *map; | 1066 | struct map_lookup *map; |
1075 | int i; | 1067 | int i; |
1076 | 1068 | ||
@@ -1087,6 +1079,10 @@ static int contains_pending_extent(struct btrfs_trans_handle *trans, | |||
1087 | ret = 1; | 1079 | ret = 1; |
1088 | } | 1080 | } |
1089 | } | 1081 | } |
1082 | if (search_list == &trans->transaction->pending_chunks) { | ||
1083 | search_list = &trans->root->fs_info->pinned_chunks; | ||
1084 | goto again; | ||
1085 | } | ||
1090 | 1086 | ||
1091 | return ret; | 1087 | return ret; |
1092 | } | 1088 | } |
@@ -1800,8 +1796,8 @@ error_undo: | |||
1800 | goto error_brelse; | 1796 | goto error_brelse; |
1801 | } | 1797 | } |
1802 | 1798 | ||
1803 | void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info, | 1799 | void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info, |
1804 | struct btrfs_device *srcdev) | 1800 | struct btrfs_device *srcdev) |
1805 | { | 1801 | { |
1806 | struct btrfs_fs_devices *fs_devices; | 1802 | struct btrfs_fs_devices *fs_devices; |
1807 | 1803 | ||
@@ -1829,6 +1825,12 @@ void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info, | |||
1829 | 1825 | ||
1830 | if (srcdev->bdev) | 1826 | if (srcdev->bdev) |
1831 | fs_devices->open_devices--; | 1827 | fs_devices->open_devices--; |
1828 | } | ||
1829 | |||
1830 | void btrfs_rm_dev_replace_free_srcdev(struct btrfs_fs_info *fs_info, | ||
1831 | struct btrfs_device *srcdev) | ||
1832 | { | ||
1833 | struct btrfs_fs_devices *fs_devices = srcdev->fs_devices; | ||
1832 | 1834 | ||
1833 | call_rcu(&srcdev->rcu, free_device); | 1835 | call_rcu(&srcdev->rcu, free_device); |
1834 | 1836 | ||
@@ -2647,18 +2649,12 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, | |||
2647 | } | 2649 | } |
2648 | } | 2650 | } |
2649 | 2651 | ||
2650 | ret = btrfs_remove_block_group(trans, extent_root, chunk_offset); | 2652 | ret = btrfs_remove_block_group(trans, extent_root, chunk_offset, em); |
2651 | if (ret) { | 2653 | if (ret) { |
2652 | btrfs_abort_transaction(trans, extent_root, ret); | 2654 | btrfs_abort_transaction(trans, extent_root, ret); |
2653 | goto out; | 2655 | goto out; |
2654 | } | 2656 | } |
2655 | 2657 | ||
2656 | write_lock(&em_tree->lock); | ||
2657 | remove_extent_mapping(em_tree, em); | ||
2658 | write_unlock(&em_tree->lock); | ||
2659 | |||
2660 | /* once for the tree */ | ||
2661 | free_extent_map(em); | ||
2662 | out: | 2658 | out: |
2663 | /* once for us */ | 2659 | /* once for us */ |
2664 | free_extent_map(em); | 2660 | free_extent_map(em); |
@@ -4505,6 +4501,8 @@ error_del_extent: | |||
4505 | free_extent_map(em); | 4501 | free_extent_map(em); |
4506 | /* One for the tree reference */ | 4502 | /* One for the tree reference */ |
4507 | free_extent_map(em); | 4503 | free_extent_map(em); |
4504 | /* One for the pending_chunks list reference */ | ||
4505 | free_extent_map(em); | ||
4508 | error: | 4506 | error: |
4509 | kfree(devices_info); | 4507 | kfree(devices_info); |
4510 | return ret; | 4508 | return ret; |
@@ -4881,13 +4879,15 @@ static inline int parity_smaller(u64 a, u64 b) | |||
4881 | static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map) | 4879 | static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map) |
4882 | { | 4880 | { |
4883 | struct btrfs_bio_stripe s; | 4881 | struct btrfs_bio_stripe s; |
4882 | int real_stripes = bbio->num_stripes - bbio->num_tgtdevs; | ||
4884 | int i; | 4883 | int i; |
4885 | u64 l; | 4884 | u64 l; |
4886 | int again = 1; | 4885 | int again = 1; |
4886 | int m; | ||
4887 | 4887 | ||
4888 | while (again) { | 4888 | while (again) { |
4889 | again = 0; | 4889 | again = 0; |
4890 | for (i = 0; i < bbio->num_stripes - 1; i++) { | 4890 | for (i = 0; i < real_stripes - 1; i++) { |
4891 | if (parity_smaller(raid_map[i], raid_map[i+1])) { | 4891 | if (parity_smaller(raid_map[i], raid_map[i+1])) { |
4892 | s = bbio->stripes[i]; | 4892 | s = bbio->stripes[i]; |
4893 | l = raid_map[i]; | 4893 | l = raid_map[i]; |
@@ -4895,6 +4895,14 @@ static void sort_parity_stripes(struct btrfs_bio *bbio, u64 *raid_map) | |||
4895 | raid_map[i] = raid_map[i+1]; | 4895 | raid_map[i] = raid_map[i+1]; |
4896 | bbio->stripes[i+1] = s; | 4896 | bbio->stripes[i+1] = s; |
4897 | 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 | |||
4898 | again = 1; | 4906 | again = 1; |
4899 | } | 4907 | } |
4900 | } | 4908 | } |
@@ -4923,6 +4931,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
4923 | int ret = 0; | 4931 | int ret = 0; |
4924 | int num_stripes; | 4932 | int num_stripes; |
4925 | int max_errors = 0; | 4933 | int max_errors = 0; |
4934 | int tgtdev_indexes = 0; | ||
4926 | struct btrfs_bio *bbio = NULL; | 4935 | struct btrfs_bio *bbio = NULL; |
4927 | struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; | 4936 | struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; |
4928 | int dev_replace_is_ongoing = 0; | 4937 | int dev_replace_is_ongoing = 0; |
@@ -5161,15 +5170,14 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5161 | BTRFS_BLOCK_GROUP_RAID6)) { | 5170 | BTRFS_BLOCK_GROUP_RAID6)) { |
5162 | u64 tmp; | 5171 | u64 tmp; |
5163 | 5172 | ||
5164 | if (bbio_ret && ((rw & REQ_WRITE) || mirror_num > 1) | 5173 | if (raid_map_ret && |
5165 | && raid_map_ret) { | 5174 | ((rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) || |
5175 | mirror_num > 1)) { | ||
5166 | int i, rot; | 5176 | int i, rot; |
5167 | 5177 | ||
5168 | /* push stripe_nr back to the start of the full stripe */ | 5178 | /* push stripe_nr back to the start of the full stripe */ |
5169 | stripe_nr = raid56_full_stripe_start; | 5179 | stripe_nr = raid56_full_stripe_start; |
5170 | do_div(stripe_nr, stripe_len); | 5180 | do_div(stripe_nr, stripe_len * nr_data_stripes(map)); |
5171 | |||
5172 | stripe_index = do_div(stripe_nr, nr_data_stripes(map)); | ||
5173 | 5181 | ||
5174 | /* RAID[56] write or recovery. Return all stripes */ | 5182 | /* RAID[56] write or recovery. Return all stripes */ |
5175 | num_stripes = map->num_stripes; | 5183 | num_stripes = map->num_stripes; |
@@ -5235,14 +5243,19 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5235 | num_alloc_stripes <<= 1; | 5243 | num_alloc_stripes <<= 1; |
5236 | if (rw & REQ_GET_READ_MIRRORS) | 5244 | if (rw & REQ_GET_READ_MIRRORS) |
5237 | num_alloc_stripes++; | 5245 | num_alloc_stripes++; |
5246 | tgtdev_indexes = num_stripes; | ||
5238 | } | 5247 | } |
5239 | 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); | ||
5240 | if (!bbio) { | 5251 | if (!bbio) { |
5241 | kfree(raid_map); | 5252 | kfree(raid_map); |
5242 | ret = -ENOMEM; | 5253 | ret = -ENOMEM; |
5243 | goto out; | 5254 | goto out; |
5244 | } | 5255 | } |
5245 | 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); | ||
5246 | 5259 | ||
5247 | if (rw & REQ_DISCARD) { | 5260 | if (rw & REQ_DISCARD) { |
5248 | int factor = 0; | 5261 | int factor = 0; |
@@ -5327,6 +5340,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5327 | if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) | 5340 | if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) |
5328 | max_errors = btrfs_chunk_max_errors(map); | 5341 | max_errors = btrfs_chunk_max_errors(map); |
5329 | 5342 | ||
5343 | tgtdev_indexes = 0; | ||
5330 | if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) && | 5344 | if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) && |
5331 | dev_replace->tgtdev != NULL) { | 5345 | dev_replace->tgtdev != NULL) { |
5332 | int index_where_to_add; | 5346 | int index_where_to_add; |
@@ -5355,8 +5369,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5355 | new->physical = old->physical; | 5369 | new->physical = old->physical; |
5356 | new->length = old->length; | 5370 | new->length = old->length; |
5357 | new->dev = dev_replace->tgtdev; | 5371 | new->dev = dev_replace->tgtdev; |
5372 | bbio->tgtdev_map[i] = index_where_to_add; | ||
5358 | index_where_to_add++; | 5373 | index_where_to_add++; |
5359 | max_errors++; | 5374 | max_errors++; |
5375 | tgtdev_indexes++; | ||
5360 | } | 5376 | } |
5361 | } | 5377 | } |
5362 | num_stripes = index_where_to_add; | 5378 | num_stripes = index_where_to_add; |
@@ -5402,7 +5418,9 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5402 | tgtdev_stripe->length = | 5418 | tgtdev_stripe->length = |
5403 | bbio->stripes[index_srcdev].length; | 5419 | bbio->stripes[index_srcdev].length; |
5404 | tgtdev_stripe->dev = dev_replace->tgtdev; | 5420 | tgtdev_stripe->dev = dev_replace->tgtdev; |
5421 | bbio->tgtdev_map[index_srcdev] = num_stripes; | ||
5405 | 5422 | ||
5423 | tgtdev_indexes++; | ||
5406 | num_stripes++; | 5424 | num_stripes++; |
5407 | } | 5425 | } |
5408 | } | 5426 | } |
@@ -5412,6 +5430,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5412 | bbio->num_stripes = num_stripes; | 5430 | bbio->num_stripes = num_stripes; |
5413 | bbio->max_errors = max_errors; | 5431 | bbio->max_errors = max_errors; |
5414 | bbio->mirror_num = mirror_num; | 5432 | bbio->mirror_num = mirror_num; |
5433 | bbio->num_tgtdevs = tgtdev_indexes; | ||
5415 | 5434 | ||
5416 | /* | 5435 | /* |
5417 | * this is the case that REQ_READ && dev_replace_is_ongoing && | 5436 | * this is the case that REQ_READ && dev_replace_is_ongoing && |
@@ -5443,6 +5462,16 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
5443 | mirror_num, NULL); | 5462 | mirror_num, NULL); |
5444 | } | 5463 | } |
5445 | 5464 | ||
5465 | /* For Scrub/replace */ | ||
5466 | int 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 | |||
5446 | int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | 5475 | int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, |
5447 | u64 chunk_start, u64 physical, u64 devid, | 5476 | u64 chunk_start, u64 physical, u64 devid, |
5448 | u64 **logical, int *naddrs, int *stripe_len) | 5477 | u64 **logical, int *naddrs, int *stripe_len) |
@@ -5812,12 +5841,9 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
5812 | } else { | 5841 | } else { |
5813 | ret = raid56_parity_recover(root, bio, bbio, | 5842 | ret = raid56_parity_recover(root, bio, bbio, |
5814 | raid_map, map_length, | 5843 | raid_map, map_length, |
5815 | mirror_num); | 5844 | mirror_num, 1); |
5816 | } | 5845 | } |
5817 | /* | 5846 | |
5818 | * FIXME, replace dosen't support raid56 yet, please fix | ||
5819 | * it in the future. | ||
5820 | */ | ||
5821 | btrfs_bio_counter_dec(root->fs_info); | 5847 | btrfs_bio_counter_dec(root->fs_info); |
5822 | return ret; | 5848 | return ret; |
5823 | } | 5849 | } |