Skip to content

Commit cdcb725

Browse files
liubchrismason-xx
authored andcommitted
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 <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent 38c01b9 commit cdcb725

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed

fs/btrfs/extent-tree.c

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6728,6 +6728,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67286728
struct btrfs_space_info *space_info;
67296729
struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
67306730
struct btrfs_device *device;
6731+
u64 min_free;
6732+
int index;
6733+
int dev_nr = 0;
6734+
int dev_min = 1;
67316735
int full = 0;
67326736
int ret = 0;
67336737

@@ -6737,8 +6741,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67376741
if (!block_group)
67386742
return -1;
67396743

6744+
min_free = btrfs_block_group_used(&block_group->item);
6745+
67406746
/* no bytes used, we're good */
6741-
if (!btrfs_block_group_used(&block_group->item))
6747+
if (!min_free)
67426748
goto out;
67436749

67446750
space_info = block_group->space_info;
@@ -6754,10 +6760,9 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67546760
* all of the extents from this block group. If we can, we're good
67556761
*/
67566762
if ((space_info->total_bytes != block_group->key.offset) &&
6757-
(space_info->bytes_used + space_info->bytes_reserved +
6758-
space_info->bytes_pinned + space_info->bytes_readonly +
6759-
btrfs_block_group_used(&block_group->item) <
6760-
space_info->total_bytes)) {
6763+
(space_info->bytes_used + space_info->bytes_reserved +
6764+
space_info->bytes_pinned + space_info->bytes_readonly +
6765+
min_free < space_info->total_bytes)) {
67616766
spin_unlock(&space_info->lock);
67626767
goto out;
67636768
}
@@ -6774,9 +6779,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67746779
if (full)
67756780
goto out;
67766781

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+
67776803
mutex_lock(&root->fs_info->chunk_mutex);
67786804
list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
6779-
u64 min_free = btrfs_block_group_used(&block_group->item);
67806805
u64 dev_offset;
67816806

67826807
/*
@@ -6787,7 +6812,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67876812
ret = find_free_dev_extent(NULL, device, min_free,
67886813
&dev_offset, NULL);
67896814
if (!ret)
6815+
dev_nr++;
6816+
6817+
if (dev_nr >= dev_min)
67906818
break;
6819+
67916820
ret = -1;
67926821
}
67936822
}

0 commit comments

Comments
 (0)