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.c185
1 files changed, 66 insertions, 119 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 9489a2aca47b..e0b7bb92a170 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -830,7 +830,6 @@ out:
830 830
831/* 831/*
832 * find_free_dev_extent - find free space in the specified device 832 * find_free_dev_extent - find free space in the specified device
833 * @trans: transaction handler
834 * @device: the device which we search the free space in 833 * @device: the device which we search the free space in
835 * @num_bytes: the size of the free space that we need 834 * @num_bytes: the size of the free space that we need
836 * @start: store the start of the free space. 835 * @start: store the start of the free space.
@@ -849,8 +848,7 @@ out:
849 * But if we don't find suitable free space, it is used to store the size of 848 * But if we don't find suitable free space, it is used to store the size of
850 * the max free space. 849 * the max free space.
851 */ 850 */
852int find_free_dev_extent(struct btrfs_trans_handle *trans, 851int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
853 struct btrfs_device *device, u64 num_bytes,
854 u64 *start, u64 *len) 852 u64 *start, u64 *len)
855{ 853{
856 struct btrfs_key key; 854 struct btrfs_key key;
@@ -894,7 +892,7 @@ int find_free_dev_extent(struct btrfs_trans_handle *trans,
894 key.offset = search_start; 892 key.offset = search_start;
895 key.type = BTRFS_DEV_EXTENT_KEY; 893 key.type = BTRFS_DEV_EXTENT_KEY;
896 894
897 ret = btrfs_search_slot(trans, root, &key, path, 0, 0); 895 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
898 if (ret < 0) 896 if (ret < 0)
899 goto out; 897 goto out;
900 if (ret > 0) { 898 if (ret > 0) {
@@ -1468,8 +1466,7 @@ error_undo:
1468/* 1466/*
1469 * does all the dirty work required for changing file system's UUID. 1467 * does all the dirty work required for changing file system's UUID.
1470 */ 1468 */
1471static int btrfs_prepare_sprout(struct btrfs_trans_handle *trans, 1469static int btrfs_prepare_sprout(struct btrfs_root *root)
1472 struct btrfs_root *root)
1473{ 1470{
1474 struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; 1471 struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
1475 struct btrfs_fs_devices *old_devices; 1472 struct btrfs_fs_devices *old_devices;
@@ -1693,7 +1690,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
1693 1690
1694 if (seeding_dev) { 1691 if (seeding_dev) {
1695 sb->s_flags &= ~MS_RDONLY; 1692 sb->s_flags &= ~MS_RDONLY;
1696 ret = btrfs_prepare_sprout(trans, root); 1693 ret = btrfs_prepare_sprout(root);
1697 BUG_ON(ret); 1694 BUG_ON(ret);
1698 } 1695 }
1699 1696
@@ -3044,8 +3041,7 @@ done:
3044 return ret; 3041 return ret;
3045} 3042}
3046 3043
3047static int btrfs_add_system_chunk(struct btrfs_trans_handle *trans, 3044static int btrfs_add_system_chunk(struct btrfs_root *root,
3048 struct btrfs_root *root,
3049 struct btrfs_key *key, 3045 struct btrfs_key *key,
3050 struct btrfs_chunk *chunk, int item_size) 3046 struct btrfs_chunk *chunk, int item_size)
3051{ 3047{
@@ -3221,7 +3217,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
3221 if (total_avail == 0) 3217 if (total_avail == 0)
3222 continue; 3218 continue;
3223 3219
3224 ret = find_free_dev_extent(trans, device, 3220 ret = find_free_dev_extent(device,
3225 max_stripe_size * dev_stripes, 3221 max_stripe_size * dev_stripes,
3226 &dev_offset, &max_avail); 3222 &dev_offset, &max_avail);
3227 if (ret && ret != -ENOSPC) 3223 if (ret && ret != -ENOSPC)
@@ -3412,7 +3408,7 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans,
3412 BUG_ON(ret); 3408 BUG_ON(ret);
3413 3409
3414 if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) { 3410 if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) {
3415 ret = btrfs_add_system_chunk(trans, chunk_root, &key, chunk, 3411 ret = btrfs_add_system_chunk(chunk_root, &key, chunk,
3416 item_size); 3412 item_size);
3417 BUG_ON(ret); 3413 BUG_ON(ret);
3418 } 3414 }
@@ -3624,26 +3620,13 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
3624 u64 stripe_nr; 3620 u64 stripe_nr;
3625 u64 stripe_nr_orig; 3621 u64 stripe_nr_orig;
3626 u64 stripe_nr_end; 3622 u64 stripe_nr_end;
3627 int stripes_allocated = 8;
3628 int stripes_required = 1;
3629 int stripe_index; 3623 int stripe_index;
3630 int i; 3624 int i;
3625 int ret = 0;
3631 int num_stripes; 3626 int num_stripes;
3632 int max_errors = 0; 3627 int max_errors = 0;
3633 struct btrfs_bio *bbio = NULL; 3628 struct btrfs_bio *bbio = NULL;
3634 3629
3635 if (bbio_ret && !(rw & (REQ_WRITE | REQ_DISCARD)))
3636 stripes_allocated = 1;
3637again:
3638 if (bbio_ret) {
3639 bbio = kzalloc(btrfs_bio_size(stripes_allocated),
3640 GFP_NOFS);
3641 if (!bbio)
3642 return -ENOMEM;
3643
3644 atomic_set(&bbio->error, 0);
3645 }
3646
3647 read_lock(&em_tree->lock); 3630 read_lock(&em_tree->lock);
3648 em = lookup_extent_mapping(em_tree, logical, *length); 3631 em = lookup_extent_mapping(em_tree, logical, *length);
3649 read_unlock(&em_tree->lock); 3632 read_unlock(&em_tree->lock);
@@ -3662,28 +3645,6 @@ again:
3662 if (mirror_num > map->num_stripes) 3645 if (mirror_num > map->num_stripes)
3663 mirror_num = 0; 3646 mirror_num = 0;
3664 3647
3665 /* if our btrfs_bio struct is too small, back off and try again */
3666 if (rw & REQ_WRITE) {
3667 if (map->type & (BTRFS_BLOCK_GROUP_RAID1 |
3668 BTRFS_BLOCK_GROUP_DUP)) {
3669 stripes_required = map->num_stripes;
3670 max_errors = 1;
3671 } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
3672 stripes_required = map->sub_stripes;
3673 max_errors = 1;
3674 }
3675 }
3676 if (rw & REQ_DISCARD) {
3677 if (map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK)
3678 stripes_required = map->num_stripes;
3679 }
3680 if (bbio_ret && (rw & (REQ_WRITE | REQ_DISCARD)) &&
3681 stripes_allocated < stripes_required) {
3682 stripes_allocated = map->num_stripes;
3683 free_extent_map(em);
3684 kfree(bbio);
3685 goto again;
3686 }
3687 stripe_nr = offset; 3648 stripe_nr = offset;
3688 /* 3649 /*
3689 * stripe_nr counts the total number of stripes we have to stride 3650 * stripe_nr counts the total number of stripes we have to stride
@@ -3775,81 +3736,55 @@ again:
3775 } 3736 }
3776 BUG_ON(stripe_index >= map->num_stripes); 3737 BUG_ON(stripe_index >= map->num_stripes);
3777 3738
3739 bbio = kzalloc(btrfs_bio_size(num_stripes), GFP_NOFS);
3740 if (!bbio) {
3741 ret = -ENOMEM;
3742 goto out;
3743 }
3744 atomic_set(&bbio->error, 0);
3745
3778 if (rw & REQ_DISCARD) { 3746 if (rw & REQ_DISCARD) {
3747 int factor = 0;
3748 int sub_stripes = 0;
3749 u64 stripes_per_dev = 0;
3750 u32 remaining_stripes = 0;
3751
3752 if (map->type &
3753 (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10)) {
3754 if (map->type & BTRFS_BLOCK_GROUP_RAID0)
3755 sub_stripes = 1;
3756 else
3757 sub_stripes = map->sub_stripes;
3758
3759 factor = map->num_stripes / sub_stripes;
3760 stripes_per_dev = div_u64_rem(stripe_nr_end -
3761 stripe_nr_orig,
3762 factor,
3763 &remaining_stripes);
3764 }
3765
3779 for (i = 0; i < num_stripes; i++) { 3766 for (i = 0; i < num_stripes; i++) {
3780 bbio->stripes[i].physical = 3767 bbio->stripes[i].physical =
3781 map->stripes[stripe_index].physical + 3768 map->stripes[stripe_index].physical +
3782 stripe_offset + stripe_nr * map->stripe_len; 3769 stripe_offset + stripe_nr * map->stripe_len;
3783 bbio->stripes[i].dev = map->stripes[stripe_index].dev; 3770 bbio->stripes[i].dev = map->stripes[stripe_index].dev;
3784 3771
3785 if (map->type & BTRFS_BLOCK_GROUP_RAID0) { 3772 if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
3786 u64 stripes; 3773 BTRFS_BLOCK_GROUP_RAID10)) {
3787 u32 last_stripe = 0; 3774 bbio->stripes[i].length = stripes_per_dev *
3788 int j; 3775 map->stripe_len;
3789 3776 if (i / sub_stripes < remaining_stripes)
3790 div_u64_rem(stripe_nr_end - 1, 3777 bbio->stripes[i].length +=
3791 map->num_stripes, 3778 map->stripe_len;
3792 &last_stripe); 3779 if (i < sub_stripes)
3793
3794 for (j = 0; j < map->num_stripes; j++) {
3795 u32 test;
3796
3797 div_u64_rem(stripe_nr_end - 1 - j,
3798 map->num_stripes, &test);
3799 if (test == stripe_index)
3800 break;
3801 }
3802 stripes = stripe_nr_end - 1 - j;
3803 do_div(stripes, map->num_stripes);
3804 bbio->stripes[i].length = map->stripe_len *
3805 (stripes - stripe_nr + 1);
3806
3807 if (i == 0) {
3808 bbio->stripes[i].length -=
3809 stripe_offset;
3810 stripe_offset = 0;
3811 }
3812 if (stripe_index == last_stripe)
3813 bbio->stripes[i].length -=
3814 stripe_end_offset;
3815 } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
3816 u64 stripes;
3817 int j;
3818 int factor = map->num_stripes /
3819 map->sub_stripes;
3820 u32 last_stripe = 0;
3821
3822 div_u64_rem(stripe_nr_end - 1,
3823 factor, &last_stripe);
3824 last_stripe *= map->sub_stripes;
3825
3826 for (j = 0; j < factor; j++) {
3827 u32 test;
3828
3829 div_u64_rem(stripe_nr_end - 1 - j,
3830 factor, &test);
3831
3832 if (test ==
3833 stripe_index / map->sub_stripes)
3834 break;
3835 }
3836 stripes = stripe_nr_end - 1 - j;
3837 do_div(stripes, factor);
3838 bbio->stripes[i].length = map->stripe_len *
3839 (stripes - stripe_nr + 1);
3840
3841 if (i < map->sub_stripes) {
3842 bbio->stripes[i].length -= 3780 bbio->stripes[i].length -=
3843 stripe_offset; 3781 stripe_offset;
3844 if (i == map->sub_stripes - 1) 3782 if ((i / sub_stripes + 1) %
3845 stripe_offset = 0; 3783 sub_stripes == remaining_stripes)
3846 }
3847 if (stripe_index >= last_stripe &&
3848 stripe_index <= (last_stripe +
3849 map->sub_stripes - 1)) {
3850 bbio->stripes[i].length -= 3784 bbio->stripes[i].length -=
3851 stripe_end_offset; 3785 stripe_end_offset;
3852 } 3786 if (i == sub_stripes - 1)
3787 stripe_offset = 0;
3853 } else 3788 } else
3854 bbio->stripes[i].length = *length; 3789 bbio->stripes[i].length = *length;
3855 3790
@@ -3871,15 +3806,22 @@ again:
3871 stripe_index++; 3806 stripe_index++;
3872 } 3807 }
3873 } 3808 }
3874 if (bbio_ret) { 3809
3875 *bbio_ret = bbio; 3810 if (rw & REQ_WRITE) {
3876 bbio->num_stripes = num_stripes; 3811 if (map->type & (BTRFS_BLOCK_GROUP_RAID1 |
3877 bbio->max_errors = max_errors; 3812 BTRFS_BLOCK_GROUP_RAID10 |
3878 bbio->mirror_num = mirror_num; 3813 BTRFS_BLOCK_GROUP_DUP)) {
3814 max_errors = 1;
3815 }
3879 } 3816 }
3817
3818 *bbio_ret = bbio;
3819 bbio->num_stripes = num_stripes;
3820 bbio->max_errors = max_errors;
3821 bbio->mirror_num = mirror_num;
3880out: 3822out:
3881 free_extent_map(em); 3823 free_extent_map(em);
3882 return 0; 3824 return ret;
3883} 3825}
3884 3826
3885int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, 3827int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
@@ -4284,7 +4226,7 @@ static int open_seed_devices(struct btrfs_root *root, u8 *fsid)
4284 struct btrfs_fs_devices *fs_devices; 4226 struct btrfs_fs_devices *fs_devices;
4285 int ret; 4227 int ret;
4286 4228
4287 mutex_lock(&uuid_mutex); 4229 BUG_ON(!mutex_is_locked(&uuid_mutex));
4288 4230
4289 fs_devices = root->fs_info->fs_devices->seed; 4231 fs_devices = root->fs_info->fs_devices->seed;
4290 while (fs_devices) { 4232 while (fs_devices) {
@@ -4322,7 +4264,6 @@ static int open_seed_devices(struct btrfs_root *root, u8 *fsid)
4322 fs_devices->seed = root->fs_info->fs_devices->seed; 4264 fs_devices->seed = root->fs_info->fs_devices->seed;
4323 root->fs_info->fs_devices->seed = fs_devices; 4265 root->fs_info->fs_devices->seed = fs_devices;
4324out: 4266out:
4325 mutex_unlock(&uuid_mutex);
4326 return ret; 4267 return ret;
4327} 4268}
4328 4269
@@ -4465,6 +4406,9 @@ int btrfs_read_chunk_tree(struct btrfs_root *root)
4465 if (!path) 4406 if (!path)
4466 return -ENOMEM; 4407 return -ENOMEM;
4467 4408
4409 mutex_lock(&uuid_mutex);
4410 lock_chunks(root);
4411
4468 /* first we search for all of the device items, and then we 4412 /* first we search for all of the device items, and then we
4469 * read in all of the chunk items. This way we can create chunk 4413 * read in all of the chunk items. This way we can create chunk
4470 * mappings that reference all of the devices that are afound 4414 * mappings that reference all of the devices that are afound
@@ -4515,6 +4459,9 @@ again:
4515 } 4459 }
4516 ret = 0; 4460 ret = 0;
4517error: 4461error:
4462 unlock_chunks(root);
4463 mutex_unlock(&uuid_mutex);
4464
4518 btrfs_free_path(path); 4465 btrfs_free_path(path);
4519 return ret; 4466 return ret;
4520} 4467}