All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us
@ 2020-05-27 20:37 Goffredo Baroncelli
  2020-05-27 20:37 ` [PATCH] Add support for RAID5/6 to the command "btrfs fi us" Goffredo Baroncelli
  2020-05-28 16:07 ` [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us David Sterba
  0 siblings, 2 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2020-05-27 20:37 UTC (permalink / raw)
  To: linux-btrfs; +Cc: DanglingPointer, Joshua Houghton, David Sterba


Hi all,

this patch adds support for the raid5/6 profiles in the command
'btrfs filesystem usage'.

Until now the problem was that the value r_{data,metadata}_used is not
easy to get for a RAID5/6, because it depends by the number of disks.
And in a filesystem it is possible to have several raid5/6 chunks with a
different number of disks.

In order to bypass this issue, I compute these values from the 
r_{data,metadata,system}_chunks values and the ratio
l_*_used / l_*_chunks.

So now if you run btrfs fi us in a raid6 filesystem you get:

$ sudo btrfs fi us / 
Overall:
    Device size:		  40.00GiB
    Device allocated:		   8.28GiB
    Device unallocated:		  31.72GiB
    Device missing:		     0.00B
    Used:			   5.00GiB
    Free (estimated):		  17.36GiB	(min: 17.36GiB)
    Data ratio:			      2.00
    Metadata ratio:		      0.00
    Global reserve:		   3.25MiB	(used: 0.00B)

Data,RAID6: Size:4.00GiB, Used:2.50GiB (62.53%)
[...]

Instead before:

$ sudo btrfs fi us /
WARNING: RAID56 detected, not implemented
WARNING: RAID56 detected, not implemented
WARNING: RAID56 detected, not implemented
Overall:
    Device size:		  40.00GiB
    Device allocated:		     0.00B
    Device unallocated:		  40.00GiB
    Device missing:		     0.00B
    Used:			     0.00B
    Free (estimated):		     0.00B	(min: 8.00EiB)
    Data ratio:			      0.00
    Metadata ratio:		      0.00
    Global reserve:		   3.25MiB	(used: 0.00B)

Data,RAID6: Size:4.00GiB, Used:2.50GiB (62.53%)
[...]


I want to point out that this patch should be compatible with my
previous patches set (the ones related to the new ioctl 
BTRFS_IOC_GET_CHUNK_INFO). If both are merged we will have a 'btrfs fi us'
commands with full support a raid5/6 filesystem without needing root
capability.

I rewrote the patch after some David's comments about the difficult to
review it because I changed too much code. So this time I tried to be less
intrusive. I leaved the old logic and I computed only the missing
values.

Comments are welcome.
BR
G.Baroncelli

V2:
The patch is completely rewritten to be less intrusive

V1:
First issue

-- 
gpg @keyserver.linux.it: Goffredo Baroncelli <kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] Add support for RAID5/6 to the command "btrfs fi us".
  2020-05-27 20:37 [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us Goffredo Baroncelli
@ 2020-05-27 20:37 ` Goffredo Baroncelli
  2020-05-28 16:07 ` [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us David Sterba
  1 sibling, 0 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2020-05-27 20:37 UTC (permalink / raw)
  To: linux-btrfs
  Cc: DanglingPointer, Joshua Houghton, David Sterba, Goffredo Baroncelli

From: Goffredo Baroncelli <kreijack@inwind.it>

The function print_filesystem_usage_overall() prints the info on the
basis of the r_*_chunk, r_*_used and l_*_chunks values computed for
data, metadata and system chunks.

For the RAID1/10/1C3/1C4/DUP these info are easily accessible from the
info returned by load_space_info().

However for RAID5/6 this is not true because the ration between the l_*
and r_* values are not fixed but depend by the number of disks involved
in the chunk.

A new function called get_raid56_space_info() is created to compute
the values r_*_chunk, and r_*_used for data, metadata and system
chunks in case of a RAID5/6 profile.

The r_*_chunk values are computed from the chunk_info array.

In order to compute the r_*_used values, a new function
get_raid56_logical_ratio() is created. This function computes the ratio
l_*_used / l_*_chunk from the ioctl_space_args array.
So we can get:

	'r_*_used' = 'r_*_chunk' * 'l_*_used' / 'l_*_chunk'

Even tough this is not mathematically true every time, it is true in
"average" (for example if the RAID5 chunks use different number of disks
the real values depend by which chunk contains the data).

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
 cmds/filesystem-usage.c | 144 +++++++++++++++++++++++++++++++---------
 1 file changed, 114 insertions(+), 30 deletions(-)

diff --git a/cmds/filesystem-usage.c b/cmds/filesystem-usage.c
index b091e927..12f63db0 100644
--- a/cmds/filesystem-usage.c
+++ b/cmds/filesystem-usage.c
@@ -282,24 +282,111 @@ static struct btrfs_ioctl_space_args *load_space_info(int fd, const char *path)
 }
 
 /*
- * This function computes the space occupied by a *single* RAID5/RAID6 chunk.
- * The computation is performed on the basis of the number of stripes
- * which compose the chunk, which could be different from the number of devices
- * if a disk is added later.
+ * Compute the ratio between logical space used over logical space allocated
+ * by profile basis
  */
-static void get_raid56_used(struct chunk_info *chunks, int chunkcount,
-		u64 *raid5_used, u64 *raid6_used)
+static void get_raid56_logical_ratio(struct btrfs_ioctl_space_args *sargs,
+				     u64 type, double *data_ratio,
+				     double *metadata_ratio,
+				     double *system_ratio) {
+	u64	l_data_chunk = 0, l_data_used = 0;
+	u64	l_metadata_chunk = 0, l_metadata_used = 0;
+	u64	l_system_chunk = 0, l_system_used = 0;
+	int	i;
+
+	for (i = 0; i < sargs->total_spaces; i++) {
+		u64 flags = sargs->spaces[i].flags;
+
+		if (!(flags & type))
+			continue;
+
+		if (flags & BTRFS_BLOCK_GROUP_DATA) {
+			l_data_used += sargs->spaces[i].used_bytes;
+			l_data_chunk += sargs->spaces[i].total_bytes;
+		} else if (flags & BTRFS_BLOCK_GROUP_METADATA) {
+			l_metadata_used += sargs->spaces[i].used_bytes;
+			l_metadata_chunk += sargs->spaces[i].total_bytes;
+		} else if (flags & BTRFS_BLOCK_GROUP_SYSTEM) {
+			l_system_used += sargs->spaces[i].used_bytes;
+			l_system_chunk += sargs->spaces[i].total_bytes;
+		}
+	}
+
+	*data_ratio = *metadata_ratio = *system_ratio = -1.0;
+
+	if (l_data_chunk)
+		*data_ratio = (double)l_data_used/l_data_chunk;
+	if (l_metadata_chunk)
+		*metadata_ratio = (double)l_metadata_used/l_metadata_chunk;
+	if (l_system_chunk)
+		*system_ratio = (double)l_system_used/l_system_chunk;
+
+}
+
+/*
+ * Compute the "raw" space allocated for a chunk (r_*_chunks)
+ * and the "raw" space used by a chunk (r_*_used)
+ */
+static void get_raid56_space_info(struct btrfs_ioctl_space_args *sargs,
+				  struct chunk_info *chunks, int chunkcount,
+				  double *max_data_ratio,
+				  u64 *r_data_chunks, u64 *r_data_used,
+				  u64 *r_metadata_chunks, u64 *r_metadata_used,
+				  u64 *r_system_chunks, u64 *r_system_used)
 {
-	struct chunk_info *info_ptr = chunks;
-	*raid5_used = 0;
-	*raid6_used = 0;
-
-	while (chunkcount-- > 0) {
-		if (info_ptr->type & BTRFS_BLOCK_GROUP_RAID5)
-			(*raid5_used) += info_ptr->size / (info_ptr->num_stripes - 1);
-		if (info_ptr->type & BTRFS_BLOCK_GROUP_RAID6)
-			(*raid6_used) += info_ptr->size / (info_ptr->num_stripes - 2);
-		info_ptr++;
+	struct chunk_info *info_ptr;
+	double l_data_ratio_r5, l_metadata_ratio_r5, l_system_ratio_r5;
+	double l_data_ratio_r6, l_metadata_ratio_r6, l_system_ratio_r6;
+
+	get_raid56_logical_ratio(sargs, BTRFS_BLOCK_GROUP_RAID5,
+		 &l_data_ratio_r5, &l_metadata_ratio_r5, &l_system_ratio_r5);
+	get_raid56_logical_ratio(sargs, BTRFS_BLOCK_GROUP_RAID6,
+		 &l_data_ratio_r6, &l_metadata_ratio_r6, &l_system_ratio_r6);
+
+	for(info_ptr = chunks ; chunkcount > 0 ; chunkcount--, info_ptr++) {
+		int parities_count;
+		u64 size;
+		double l_data_ratio, l_metadata_ratio, l_system_ratio, rt;
+
+		if (info_ptr->type & BTRFS_BLOCK_GROUP_RAID5) {
+			parities_count = 1;
+			l_data_ratio = l_data_ratio_r5;
+			l_metadata_ratio = l_metadata_ratio_r5;
+			l_system_ratio = l_system_ratio_r5;
+		} else if (info_ptr->type & BTRFS_BLOCK_GROUP_RAID6) {
+			parities_count = 2;
+			l_data_ratio = l_data_ratio_r6;
+			l_metadata_ratio = l_metadata_ratio_r6;
+			l_system_ratio = l_system_ratio_r6;
+		} else {
+			continue;
+		}
+
+		rt = (double)info_ptr->num_stripes /
+			(info_ptr->num_stripes - parities_count);
+		if (rt > *max_data_ratio)
+			*max_data_ratio = rt;
+
+		/*
+		 * - 'size' is the total disk(s) space occuped by a chunk
+		 * - the product of 'size' and  '*_ratio' is "in average"
+		 * the disk(s) space used by the data
+		 */
+		size = info_ptr->size / (info_ptr->num_stripes - parities_count);
+
+		if (info_ptr->type & BTRFS_BLOCK_GROUP_DATA) {
+			assert(l_data_ratio >= 0);
+			*r_data_chunks += size;
+			*r_data_used += size * l_data_ratio;
+		} else if (info_ptr->type & BTRFS_BLOCK_GROUP_METADATA) {
+			assert(l_metadata_ratio >= 0);
+			*r_metadata_chunks += size;
+			*r_metadata_used += size * l_metadata_ratio;
+		} else if (info_ptr->type & BTRFS_BLOCK_GROUP_SYSTEM) {
+			assert(l_system_ratio >= 0);
+			*r_system_chunks += size;
+			*r_system_used += size * l_system_ratio;
+		}
 	}
 }
 
@@ -315,7 +402,9 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
 	int width = 10;		/* default 10 for human units */
 	/*
 	 * r_* prefix is for raw data
-	 * l_* is for logical
+	 * l_* prefix is for logical
+	 * *_used postfix is for space used for data or metadata
+	 * *_chunks postfix is for total space used by the chunk
 	 */
 	u64 r_total_size = 0;	/* filesystem size, sum of device sizes */
 	u64 r_total_chunks = 0;	/* sum of chunks sizes on disk(s) */
@@ -333,13 +422,11 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
 	double data_ratio;
 	double metadata_ratio;
 	/* logical */
-	u64 raid5_used = 0;
-	u64 raid6_used = 0;
 	u64 l_global_reserve = 0;
 	u64 l_global_reserve_used = 0;
 	u64 free_estimated = 0;
 	u64 free_min = 0;
-	int max_data_ratio = 1;
+	double max_data_ratio = 1.0;
 	int mixed = 0;
 
 	sargs = load_space_info(fd, path);
@@ -361,7 +448,12 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
 		ret = 1;
 		goto exit;
 	}
-	get_raid56_used(chunkinfo, chunkcount, &raid5_used, &raid6_used);
+
+	get_raid56_space_info(sargs, chunkinfo, chunkcount,
+				&max_data_ratio,
+				&r_data_chunks, &r_data_used,
+				&r_metadata_chunks, &r_metadata_used,
+				&r_system_chunks, &r_system_used);
 
 	for (i = 0; i < sargs->total_spaces; i++) {
 		int ratio;
@@ -369,7 +461,7 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
 
 		/*
 		 * The raid5/raid6 ratio depends by the stripes number
-		 * used by every chunk. It is computed separately
+		 * used by every chunk. It was computed separately
 		 */
 		if (flags & BTRFS_BLOCK_GROUP_RAID0)
 			ratio = 1;
@@ -390,9 +482,6 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
 		else
 			ratio = 1;
 
-		if (!ratio)
-			warning("RAID56 detected, not implemented");
-
 		if (ratio > max_data_ratio)
 			max_data_ratio = ratio;
 
@@ -435,11 +524,6 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
 	else
 		metadata_ratio = (double)r_metadata_chunks / l_metadata_chunks;
 
-#if 0
-	/* add the raid5/6 allocated space */
-	total_chunks += raid5_used + raid6_used;
-#endif
-
 	/*
 	 * We're able to fill at least DATA for the unused space
 	 *
-- 
2.27.0.rc2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us
  2020-05-27 20:37 [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us Goffredo Baroncelli
  2020-05-27 20:37 ` [PATCH] Add support for RAID5/6 to the command "btrfs fi us" Goffredo Baroncelli
@ 2020-05-28 16:07 ` David Sterba
  2020-05-28 16:46   ` Goffredo Baroncelli
  1 sibling, 1 reply; 4+ messages in thread
From: David Sterba @ 2020-05-28 16:07 UTC (permalink / raw)
  To: Goffredo Baroncelli
  Cc: linux-btrfs, DanglingPointer, Joshua Houghton, David Sterba

On Wed, May 27, 2020 at 10:37:47PM +0200, Goffredo Baroncelli wrote:
> this patch adds support for the raid5/6 profiles in the command
> 'btrfs filesystem usage'.

> $ sudo btrfs fi us / 
> Overall:
>     Device size:		  40.00GiB
>     Device allocated:		   8.28GiB
>     Device unallocated:		  31.72GiB
>     Device missing:		     0.00B
>     Used:			   5.00GiB
>     Free (estimated):		  17.36GiB	(min: 17.36GiB)
>     Data ratio:			      2.00
>     Metadata ratio:		      0.00
>     Global reserve:		   3.25MiB	(used: 0.00B)
> 
> Data,RAID6: Size:4.00GiB, Used:2.50GiB (62.53%)

> Instead before:
> 
> $ sudo btrfs fi us /
> WARNING: RAID56 detected, not implemented
> WARNING: RAID56 detected, not implemented
> WARNING: RAID56 detected, not implemented
> Overall:
>     Device size:		  40.00GiB
>     Device allocated:		     0.00B
>     Device unallocated:		  40.00GiB
>     Device missing:		     0.00B
>     Used:			     0.00B
>     Free (estimated):		     0.00B	(min: 8.00EiB)
>     Data ratio:			      0.00
>     Metadata ratio:		      0.00
>     Global reserve:		   3.25MiB	(used: 0.00B)
> 
> Data,RAID6: Size:4.00GiB, Used:2.50GiB (62.53%)

> I rewrote the patch after some David's comments about the difficult to
> review it because I changed too much code. So this time I tried to be less
> intrusive. I leaved the old logic and I computed only the missing
> values.

Thanks, that's what I expected. Patch added to devel.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us
  2020-05-28 16:07 ` [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us David Sterba
@ 2020-05-28 16:46   ` Goffredo Baroncelli
  0 siblings, 0 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2020-05-28 16:46 UTC (permalink / raw)
  To: dsterba, linux-btrfs, DanglingPointer, Joshua Houghton, David Sterba

On 5/28/20 6:07 PM, David Sterba wrote:
> On Wed, May 27, 2020 at 10:37:47PM +0200, Goffredo Baroncelli wrote:
>> this patch adds support for the raid5/6 profiles in the command
>> 'btrfs filesystem usage'.
> 
>> $ sudo btrfs fi us /
>> Overall:
>>      Device size:		  40.00GiB
>>      Device allocated:		   8.28GiB
>>      Device unallocated:		  31.72GiB
>>      Device missing:		     0.00B
>>      Used:			   5.00GiB
>>      Free (estimated):		  17.36GiB	(min: 17.36GiB)
>>      Data ratio:			      2.00
>>      Metadata ratio:		      0.00
>>      Global reserve:		   3.25MiB	(used: 0.00B)
>>
>> Data,RAID6: Size:4.00GiB, Used:2.50GiB (62.53%)
> 
>> Instead before:
>>
>> $ sudo btrfs fi us /
>> WARNING: RAID56 detected, not implemented
>> WARNING: RAID56 detected, not implemented
>> WARNING: RAID56 detected, not implemented
>> Overall:
>>      Device size:		  40.00GiB
>>      Device allocated:		     0.00B
>>      Device unallocated:		  40.00GiB
>>      Device missing:		     0.00B
>>      Used:			     0.00B
>>      Free (estimated):		     0.00B	(min: 8.00EiB)
>>      Data ratio:			      0.00
>>      Metadata ratio:		      0.00
>>      Global reserve:		   3.25MiB	(used: 0.00B)
>>
>> Data,RAID6: Size:4.00GiB, Used:2.50GiB (62.53%)
> 
>> I rewrote the patch after some David's comments about the difficult to
>> review it because I changed too much code. So this time I tried to be less
>> intrusive. I leaved the old logic and I computed only the missing
>> values.
> 
> Thanks, that's what I expected. Patch added to devel.
> 

Greath ! Many thanks
BR
G.Baroncelli

-- 
gpg @keyserver.linux.it: Goffredo Baroncelli <kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-28 16:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-27 20:37 [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us Goffredo Baroncelli
2020-05-27 20:37 ` [PATCH] Add support for RAID5/6 to the command "btrfs fi us" Goffredo Baroncelli
2020-05-28 16:07 ` [PATCH V2] btrfs-progs: add RAID5/6 support to btrfs fi us David Sterba
2020-05-28 16:46   ` Goffredo Baroncelli

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.