diff options
-rw-r--r-- | fs/btrfs/extent-tree.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 059dfa048cc0..a3e71b59f66e 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 | } |