diff mbox series

btrfs: fix percent calculation for reclaim message

Message ID 6107ccae94e0af75c60d1d1f6a5a0dd59aaafc58.1677003060.git.johannes.thumshirn@wdc.com (mailing list archive)
State New, archived
Headers show
Series btrfs: fix percent calculation for reclaim message | expand

Commit Message

Johannes Thumshirn Feb. 21, 2023, 6:11 p.m. UTC
We have a report, that the info message for block-group reclaim is crossing the
100% used mark.

This is happening as we were truncaating the divisor for the division (the
block_group->length) to a 32bit value.

Fix this by using div64_u64() to not truncate the divisor.

Reported-by: Forza <forza@tnonline.net>
Link: https://lore.kernel.org/linux-btrfs/e99483.c11a58d.1863591ca52@tnonline.net/
Fixes: 5f93e776c673 ("btrfs: zoned: print unusable percentage when reclaiming block groups")
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
 fs/btrfs/block-group.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Anand Jain Feb. 22, 2023, 2:18 p.m. UTC | #1
LGTM

Reviewed-by: Anand Jain <anand.jain@oracle.com>
Qu Wenruo Feb. 23, 2023, 10:07 a.m. UTC | #2
On 2023/2/22 02:11, Johannes Thumshirn wrote:
> We have a report, that the info message for block-group reclaim is crossing the
> 100% used mark.
> 
> This is happening as we were truncaating the divisor for the division (the
> block_group->length) to a 32bit value.
> 
> Fix this by using div64_u64() to not truncate the divisor.

Reviewed-by: Qu Wenruo <wqu@suse.com>

In the worst case, it can lead to a div by zero error.

And I believe it's not that hard to trigger, just 4 disks RAID0, and 
each device is large enough, then we're doomed:

   $ mkfs.btrfs  -f /dev/test/scratch[1234] -m raid1 -d raid0
   btrfs-progs v6.1
   [...]
   Filesystem size:    40.00GiB
   Block group profiles:
     Data:             RAID0             4.00GiB <<<
     Metadata:         RAID1           256.00MiB
     System:           RAID1             8.00MiB

Maybe this can be turned into a test case?

Thanks,
Qu
> 
> Reported-by: Forza <forza@tnonline.net>
> Link: https://lore.kernel.org/linux-btrfs/e99483.c11a58d.1863591ca52@tnonline.net/
> Fixes: 5f93e776c673 ("btrfs: zoned: print unusable percentage when reclaiming block groups")
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> ---
>   fs/btrfs/block-group.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
> index fe4a60d7a49e..c6b9d5a04f3e 100644
> --- a/fs/btrfs/block-group.c
> +++ b/fs/btrfs/block-group.c
> @@ -1826,7 +1826,8 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
>   
>   		btrfs_info(fs_info,
>   			"reclaiming chunk %llu with %llu%% used %llu%% unusable",
> -				bg->start, div_u64(bg->used * 100, bg->length),
> +				bg->start,
> +				div64_u64(bg->used * 100, bg->length),
>   				div64_u64(zone_unusable * 100, bg->length));
>   		trace_btrfs_reclaim_block_group(bg);
>   		ret = btrfs_relocate_chunk(fs_info, bg->start);
David Sterba Feb. 23, 2023, 9:04 p.m. UTC | #3
On Tue, Feb 21, 2023 at 10:11:24AM -0800, Johannes Thumshirn wrote:
> We have a report, that the info message for block-group reclaim is crossing the
> 100% used mark.
> 
> This is happening as we were truncaating the divisor for the division (the
> block_group->length) to a 32bit value.
> 
> Fix this by using div64_u64() to not truncate the divisor.
> 
> Reported-by: Forza <forza@tnonline.net>
> Link: https://lore.kernel.org/linux-btrfs/e99483.c11a58d.1863591ca52@tnonline.net/
> Fixes: 5f93e776c673 ("btrfs: zoned: print unusable percentage when reclaiming block groups")
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

Added to misc-next with Qu's note how to possibly reproduce it, thanks.
diff mbox series

Patch

diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index fe4a60d7a49e..c6b9d5a04f3e 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -1826,7 +1826,8 @@  void btrfs_reclaim_bgs_work(struct work_struct *work)
 
 		btrfs_info(fs_info,
 			"reclaiming chunk %llu with %llu%% used %llu%% unusable",
-				bg->start, div_u64(bg->used * 100, bg->length),
+				bg->start,
+				div64_u64(bg->used * 100, bg->length),
 				div64_u64(zone_unusable * 100, bg->length));
 		trace_btrfs_reclaim_block_group(bg);
 		ret = btrfs_relocate_chunk(fs_info, bg->start);