aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorliubo <liubo2009@cn.fujitsu.com>2011-08-03 06:15:25 -0400
committerChris Mason <chris.mason@oracle.com>2011-08-16 21:09:15 -0400
commitcdcb725c05fe0cb71777c66ddc2445fedbbb3c59 (patch)
treea2128e008636ad4dd4d6db2131363cc71d45ad73 /fs
parent38c01b9605923cfdff5413e0a12e58ee8d962257 (diff)
Btrfs: check if there is enough space for balancing smarter
When checking if there is enough space for balancing a block group, since we do not take raid types into consideration, we do not account corrent amounts of space that we needed. This makes us do some extra work before we get ENOSPC. Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-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 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 }