Liu Bo
2011-Aug-03 10:15 UTC
[PATCH] 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> --- 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 3213c39..02216cc 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -6682,6 +6682,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) struct btrfs_space_info *space_info; struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; struct btrfs_device *device; + u64 min_free; + int index; + int dev_nr = 0; + int dev_min = 1; int full = 0; int ret = 0; @@ -6691,8 +6695,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) if (!block_group) return -1; + min_free = btrfs_block_group_used(&block_group->item); + /* no bytes used, we''re good */ - if (!btrfs_block_group_used(&block_group->item)) + if (!min_free) goto out; space_info = block_group->space_info; @@ -6708,10 +6714,9 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) * all of the extents from this block group. If we can, we''re good */ if ((space_info->total_bytes != block_group->key.offset) && - (space_info->bytes_used + space_info->bytes_reserved + - space_info->bytes_pinned + space_info->bytes_readonly + - btrfs_block_group_used(&block_group->item) < - space_info->total_bytes)) { + (space_info->bytes_used + space_info->bytes_reserved + + space_info->bytes_pinned + space_info->bytes_readonly + + min_free < space_info->total_bytes)) { spin_unlock(&space_info->lock); goto out; } @@ -6728,9 +6733,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) if (full) goto out; + /* + * index: + * 0: raid10 + * 1: raid1 + * 2: dup + * 3: raid0 + * 4: single + */ + index = get_block_group_index(block_group); + if (index == 0) { + dev_min = 4; + min_free /= 2; + } else if (index == 1) { + dev_min = 2; + } else if (index == 2) { + min_free *= 2; + } else if (index == 3) { + dev_min = fs_devices->rw_devices; + min_free /= dev_min; + } + mutex_lock(&root->fs_info->chunk_mutex); list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { - u64 min_free = btrfs_block_group_used(&block_group->item); u64 dev_offset; /* @@ -6741,7 +6766,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) ret = find_free_dev_extent(NULL, device, min_free, &dev_offset, NULL); if (!ret) + dev_nr++; + + if (dev_nr >= dev_min) break; + ret = -1; } } -- 1.6.5.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2011-Aug-19 02:46 UTC
Re: [PATCH] Btrfs: check if there is enough space for balancing smarter
Hi, too late, already pulled On Wed, Aug 03, 2011 at 06:15:25PM +0800, Liu Bo wrote:> --- a/fs/btrfs/extent-tree.c > +++ b/fs/btrfs/extent-tree.c > @@ -6682,6 +6682,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) > struct btrfs_space_info *space_info; > struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; > struct btrfs_device *device; > + u64 min_free;^^^> + int index; > + int dev_nr = 0; > + int dev_min = 1; > int full = 0; > int ret = 0; > > @@ -6728,9 +6733,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) > if (full) > goto out; > > + /* > + * index: > + * 0: raid10 > + * 1: raid1 > + * 2: dup > + * 3: raid0 > + * 4: single > + */ > + index = get_block_group_index(block_group); > + if (index == 0) { > + dev_min = 4; > + min_free /= 2; > + } else if (index == 1) { > + dev_min = 2; > + } else if (index == 2) { > + min_free *= 2; > + } else if (index == 3) { > + dev_min = fs_devices->rw_devices; > + min_free /= dev_min;^^^^^^^^^^^^^^^^^^^ 64bit division will break 32bit builds, can you please convert it to do_div ? the other is ''div-by-power-of-2'' which will most probably be converted to shifts. david> + } > + > mutex_lock(&root->fs_info->chunk_mutex); > list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { > - u64 min_free = btrfs_block_group_used(&block_group->item); > u64 dev_offset; > > /* > @@ -6741,7 +6766,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) > ret = find_free_dev_extent(NULL, device, min_free, > &dev_offset, NULL); > if (!ret) > + dev_nr++; > + > + if (dev_nr >= dev_min) > break; > + > ret = -1; > } > } > -- > 1.6.5.2 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
liubo
2011-Aug-19 03:07 UTC
Re: [PATCH] Btrfs: check if there is enough space for balancing smarter
On 08/19/2011 10:46 AM, David Sterba wrote:> Hi, > > too late, already pulled > > On Wed, Aug 03, 2011 at 06:15:25PM +0800, Liu Bo wrote: >> --- a/fs/btrfs/extent-tree.c >> +++ b/fs/btrfs/extent-tree.c >> @@ -6682,6 +6682,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) >> struct btrfs_space_info *space_info; >> struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; >> struct btrfs_device *device; >> + u64 min_free; > ^^^ > >> + int index; >> + int dev_nr = 0; >> + int dev_min = 1; >> int full = 0; >> int ret = 0; >> >> @@ -6728,9 +6733,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) >> if (full) >> goto out; >> >> + /* >> + * index: >> + * 0: raid10 >> + * 1: raid1 >> + * 2: dup >> + * 3: raid0 >> + * 4: single >> + */ >> + index = get_block_group_index(block_group); >> + if (index == 0) { >> + dev_min = 4; >> + min_free /= 2; >> + } else if (index == 1) { >> + dev_min = 2; >> + } else if (index == 2) { >> + min_free *= 2; >> + } else if (index == 3) { >> + dev_min = fs_devices->rw_devices; >> + min_free /= dev_min; > ^^^^^^^^^^^^^^^^^^^ > > 64bit division will break 32bit builds, can you please convert it to > do_div ? the other is ''div-by-power-of-2'' which will most probably be > converted to shifts. >This is my fault, sorry. Will fix it soon. thanks, liubo> > david > >> + } >> + >> mutex_lock(&root->fs_info->chunk_mutex); >> list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { >> - u64 min_free = btrfs_block_group_used(&block_group->item); >> u64 dev_offset; >> >> /* >> @@ -6741,7 +6766,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) >> ret = find_free_dev_extent(NULL, device, min_free, >> &dev_offset, NULL); >> if (!ret) >> + dev_nr++; >> + >> + if (dev_nr >= dev_min) >> break; >> + >> ret = -1; >> } >> } >> -- >> 1.6.5.2 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html