[09/20] btrfs: parameterize dev_extent_min
diff mbox series

Message ID 20200206104214.400857-10-naohiro.aota@wdc.com
State New
Headers show
Series
  • btrfs: refactor and generalize chunk/dev_extent/extent allocation
Related show

Commit Message

Naohiro Aota Feb. 6, 2020, 10:42 a.m. UTC
Currently, we ignore a device whose available space is less than
"BTRFS_STRIPE_LEN * dev_stripes". This is a lower limit for current
allocation policy (to maximize the number of stripes). This commit
parameterizes dev_extent_min, so that other policies can set their own
lower limitation to ignore a device with an insufficient space.

Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 fs/btrfs/volumes.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Comments

Josef Bacik Feb. 6, 2020, 4:52 p.m. UTC | #1
On 2/6/20 5:42 AM, Naohiro Aota wrote:
> Currently, we ignore a device whose available space is less than
> "BTRFS_STRIPE_LEN * dev_stripes". This is a lower limit for current
> allocation policy (to maximize the number of stripes). This commit
> parameterizes dev_extent_min, so that other policies can set their own
> lower limitation to ignore a device with an insufficient space.
> 
> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
> ---
>   fs/btrfs/volumes.c | 9 +++++----
>   1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 15837374db9c..4a6cc098ee3e 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -4836,6 +4836,7 @@ struct alloc_chunk_ctl {
>   				   store parity information */
>   	u64 max_stripe_size;
>   	u64 max_chunk_size;
> +	u64 dev_extent_min;
>   	u64 stripe_size;
>   	u64 chunk_size;
>   	int ndevs;
> @@ -4868,6 +4869,7 @@ static void set_parameters_regular(struct btrfs_fs_devices *fs_devices,
>   	/* We don't want a chunk larger than 10% of writable space */
>   	ctl->max_chunk_size = min(div_factor(fs_devices->total_rw_bytes, 1),
>   				  ctl->max_chunk_size);
> +	ctl->dev_extent_min = BTRFS_STRIPE_LEN * ctl->dev_stripes;
>   }
>   
>   static void set_parameters(struct btrfs_fs_devices *fs_devices,
> @@ -4903,7 +4905,6 @@ static int gather_device_info(struct btrfs_fs_devices *fs_devices,
>   	struct btrfs_device *device;
>   	u64 total_avail;
>   	u64 dev_extent_want = ctl->max_stripe_size * ctl->dev_stripes;
> -	u64 dev_extent_min = BTRFS_STRIPE_LEN * ctl->dev_stripes;
>   	int ret;
>   	int ndevs = 0;
>   	u64 max_avail;
> @@ -4931,7 +4932,7 @@ static int gather_device_info(struct btrfs_fs_devices *fs_devices,
>   			total_avail = 0;
>   
>   		/* If there is no space on this device, skip it. */
> -		if (total_avail == 0)
> +		if (total_avail < ctl->dev_extent_min)

This isn't correct, dev_extent_min is the total size with all stripes added up, 
not the size of a single stripe.  Thanks,

Josef
Naohiro Aota Feb. 7, 2020, 9 a.m. UTC | #2
On Thu, Feb 06, 2020 at 11:52:19AM -0500, Josef Bacik wrote:
>On 2/6/20 5:42 AM, Naohiro Aota wrote:
>>Currently, we ignore a device whose available space is less than
>>"BTRFS_STRIPE_LEN * dev_stripes". This is a lower limit for current
>>allocation policy (to maximize the number of stripes). This commit
>>parameterizes dev_extent_min, so that other policies can set their own
>>lower limitation to ignore a device with an insufficient space.
>>
>>Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
>>---
>>  fs/btrfs/volumes.c | 9 +++++----
>>  1 file changed, 5 insertions(+), 4 deletions(-)
>>
>>diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
>>index 15837374db9c..4a6cc098ee3e 100644
>>--- a/fs/btrfs/volumes.c
>>+++ b/fs/btrfs/volumes.c
>>@@ -4836,6 +4836,7 @@ struct alloc_chunk_ctl {
>>  				   store parity information */
>>  	u64 max_stripe_size;
>>  	u64 max_chunk_size;
>>+	u64 dev_extent_min;
>>  	u64 stripe_size;
>>  	u64 chunk_size;
>>  	int ndevs;
>>@@ -4868,6 +4869,7 @@ static void set_parameters_regular(struct btrfs_fs_devices *fs_devices,
>>  	/* We don't want a chunk larger than 10% of writable space */
>>  	ctl->max_chunk_size = min(div_factor(fs_devices->total_rw_bytes, 1),
>>  				  ctl->max_chunk_size);
>>+	ctl->dev_extent_min = BTRFS_STRIPE_LEN * ctl->dev_stripes;
>>  }
>>  static void set_parameters(struct btrfs_fs_devices *fs_devices,
>>@@ -4903,7 +4905,6 @@ static int gather_device_info(struct btrfs_fs_devices *fs_devices,
>>  	struct btrfs_device *device;
>>  	u64 total_avail;
>>  	u64 dev_extent_want = ctl->max_stripe_size * ctl->dev_stripes;
>>-	u64 dev_extent_min = BTRFS_STRIPE_LEN * ctl->dev_stripes;
>>  	int ret;
>>  	int ndevs = 0;
>>  	u64 max_avail;
>>@@ -4931,7 +4932,7 @@ static int gather_device_info(struct btrfs_fs_devices *fs_devices,
>>  			total_avail = 0;
>>  		/* If there is no space on this device, skip it. */
>>-		if (total_avail == 0)
>>+		if (total_avail < ctl->dev_extent_min)
>
>This isn't correct, dev_extent_min is the total size with all stripes 
>added up, not the size of a single stripe.  Thanks,

Hm, I can revert here, but isn't it no use to search into a device
whose available bytes is less than dev_extent_min (= BTRFS_STRIPE_LEN
* ctl->dev_stripes)? Since max_avail can only be less than
dev_extent_min, we anyway skip such device with the below "if
(max_avail < dev_extent_min) { ... }" part.

Patch
diff mbox series

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 15837374db9c..4a6cc098ee3e 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4836,6 +4836,7 @@  struct alloc_chunk_ctl {
 				   store parity information */
 	u64 max_stripe_size;
 	u64 max_chunk_size;
+	u64 dev_extent_min;
 	u64 stripe_size;
 	u64 chunk_size;
 	int ndevs;
@@ -4868,6 +4869,7 @@  static void set_parameters_regular(struct btrfs_fs_devices *fs_devices,
 	/* We don't want a chunk larger than 10% of writable space */
 	ctl->max_chunk_size = min(div_factor(fs_devices->total_rw_bytes, 1),
 				  ctl->max_chunk_size);
+	ctl->dev_extent_min = BTRFS_STRIPE_LEN * ctl->dev_stripes;
 }
 
 static void set_parameters(struct btrfs_fs_devices *fs_devices,
@@ -4903,7 +4905,6 @@  static int gather_device_info(struct btrfs_fs_devices *fs_devices,
 	struct btrfs_device *device;
 	u64 total_avail;
 	u64 dev_extent_want = ctl->max_stripe_size * ctl->dev_stripes;
-	u64 dev_extent_min = BTRFS_STRIPE_LEN * ctl->dev_stripes;
 	int ret;
 	int ndevs = 0;
 	u64 max_avail;
@@ -4931,7 +4932,7 @@  static int gather_device_info(struct btrfs_fs_devices *fs_devices,
 			total_avail = 0;
 
 		/* If there is no space on this device, skip it. */
-		if (total_avail == 0)
+		if (total_avail < ctl->dev_extent_min)
 			continue;
 
 		ret = find_free_dev_extent(device, dev_extent_want, &dev_offset,
@@ -4942,12 +4943,12 @@  static int gather_device_info(struct btrfs_fs_devices *fs_devices,
 		if (ret == 0)
 			max_avail = dev_extent_want;
 
-		if (max_avail < dev_extent_min) {
+		if (max_avail < ctl->dev_extent_min) {
 			if (btrfs_test_opt(info, ENOSPC_DEBUG))
 				btrfs_debug(info,
 			"%s: devid %llu has no free space, have=%llu want=%llu",
 					    __func__, device->devid, max_avail,
-					    dev_extent_min);
+					    ctl->dev_extent_min);
 			continue;
 		}