diff mbox

Btrfs: check if there is enough space for balancing smarter

Message ID 1312366525-19677-1-git-send-email-liubo2009@cn.fujitsu.com (mailing list archive)
State New, archived
Headers show

Commit Message

liubo Aug. 3, 2011, 10:15 a.m. UTC
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(-)

Comments

David Sterba Aug. 19, 2011, 2:46 a.m. UTC | #1
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 Aug. 19, 2011, 3:07 a.m. UTC | #2
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
diff mbox

Patch

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;
 		}
 	}