aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 059dfa048cc..a3e71b59f66 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -6728,6 +6728,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6728 struct btrfs_space_info *space_info; 6728 struct btrfs_space_info *space_info;
6729 struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; 6729 struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
6730 struct btrfs_device *device; 6730 struct btrfs_device *device;
6731 u64 min_free;
6732 int index;
6733 int dev_nr = 0;
6734 int dev_min = 1;
6731 int full = 0; 6735 int full = 0;
6732 int ret = 0; 6736 int ret = 0;
6733 6737
@@ -6737,8 +6741,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6737 if (!block_group) 6741 if (!block_group)
6738 return -1; 6742 return -1;
6739 6743
6744 min_free = btrfs_block_group_used(&block_group->item);
6745
6740 /* no bytes used, we're good */ 6746 /* no bytes used, we're good */
6741 if (!btrfs_block_group_used(&block_group->item)) 6747 if (!min_free)
6742 goto out; 6748 goto out;
6743 6749
6744 space_info = block_group->space_info; 6750 space_info = block_group->space_info;
@@ -6754,10 +6760,9 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6754 * all of the extents from this block group. If we can, we're good 6760 * all of the extents from this block group. If we can, we're good
6755 */ 6761 */
6756 if ((space_info->total_bytes != block_group->key.offset) && 6762 if ((space_info->total_bytes != block_group->key.offset) &&
6757 (space_info->bytes_used + space_info->bytes_reserved + 6763 (space_info->bytes_used + space_info->bytes_reserved +
6758 space_info->bytes_pinned + space_info->bytes_readonly + 6764 space_info->bytes_pinned + space_info->bytes_readonly +
6759 btrfs_block_group_used(&block_group->item) < 6765 min_free < space_info->total_bytes)) {
6760 space_info->total_bytes)) {
6761 spin_unlock(&space_info->lock); 6766 spin_unlock(&space_info->lock);
6762 goto out; 6767 goto out;
6763 } 6768 }
@@ -6774,9 +6779,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6774 if (full) 6779 if (full)
6775 goto out; 6780 goto out;
6776 6781
6782 /*
6783 * index:
6784 * 0: raid10
6785 * 1: raid1
6786 * 2: dup
6787 * 3: raid0
6788 * 4: single
6789 */
6790 index = get_block_group_index(block_group);
6791 if (index == 0) {
6792 dev_min = 4;
6793 min_free /= 2;
6794 } else if (index == 1) {
6795 dev_min = 2;
6796 } else if (index == 2) {
6797 min_free *= 2;
6798 } else if (index == 3) {
6799 dev_min = fs_devices->rw_devices;
6800 min_free /= dev_min;
6801 }
6802
6777 mutex_lock(&root->fs_info->chunk_mutex); 6803 mutex_lock(&root->fs_info->chunk_mutex);
6778 list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { 6804 list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
6779 u64 min_free = btrfs_block_group_used(&block_group->item);
6780 u64 dev_offset; 6805 u64 dev_offset;
6781 6806
6782 /* 6807 /*
@@ -6787,7 +6812,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6787 ret = find_free_dev_extent(NULL, device, min_free, 6812 ret = find_free_dev_extent(NULL, device, min_free,
6788 &dev_offset, NULL); 6813 &dev_offset, NULL);
6789 if (!ret) 6814 if (!ret)
6815 dev_nr++;
6816
6817 if (dev_nr >= dev_min)
6790 break; 6818 break;
6819
6791 ret = -1; 6820 ret = -1;
6792 } 6821 }
6793 } 6822 }