All of lore.kernel.org
 help / color / mirror / Atom feed
From: stephane_btrfs@lesimple.fr
To: linux-btrfs@vger.kernel.org
Cc: "Stéphane Lesimple" <stephane_btrfs@lesimple.fr>
Subject: [PATCH 1/1] btrfs-progs: fi usage: implement raid56
Date: Sun, 17 Mar 2019 13:51:50 +0100	[thread overview]
Message-ID: <20190317125150.26265-2-stephane_btrfs@lesimple.fr> (raw)
In-Reply-To: <20190317125150.26265-1-stephane_btrfs@lesimple.fr>

From: Stéphane Lesimple <stephane_btrfs@lesimple.fr>

Implement RAID5 and RAID6 support in `filesystem usage'.

Before:
> WARNING: RAID56 detected, not implemented
> WARNING: RAID56 detected, not implemented
> WARNING: RAID56 detected, not implemented
>      Device allocated:     0.00B
>      Device unallocated:   2.04GiB
>      Used:                 0.00B
>      Free (estimated):     0.00B      (min: 8.00EiB)
>      Data ratio:           0.00
>      Metadata ratio:       0.00

After:
>      Device allocated:     1.83GiB
>      Device unallocated:   211.50MiB
>      Used:                 1.83GiB
>      Free (estimated):     128.44MiB  (min: 128.44MiB)
>      Data ratio:           1.65
>      Metadata ratio:       1.20

Note that this might need some fine-tuning for mixed mode.

We may also overestimate the free space incorrectly in
some complex disk configurations, i.e. when some of the
unallocated space is in fact unallocatable because the
redundancy profile requisites can't be matched with how
the remaining unallocated space is distributed over the
devices. This is not specific to raid56 and also happens
with other raid profiles, it'll need to be taken care of
separately.

Signed-off-by: Stéphane Lesimple <stephane_btrfs@lesimple.fr>
---
 cmds-fi-usage.c | 96 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 60 insertions(+), 36 deletions(-)

diff --git a/cmds-fi-usage.c b/cmds-fi-usage.c
index 9a23e176..baa1ff89 100644
--- a/cmds-fi-usage.c
+++ b/cmds-fi-usage.c
@@ -280,28 +280,6 @@ static struct btrfs_ioctl_space_args *load_space_info(int fd, const char *path)
 	return sargs;
 }
 
-/*
- * 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.
- */
-static void get_raid56_used(struct chunk_info *chunks, int chunkcount,
-		u64 *raid5_used, u64 *raid6_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++;
-	}
-}
-
 #define	MIN_UNALOCATED_THRESH	SZ_16M
 static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
 		int chunkcount, struct device_info *devinfo, int devcount,
@@ -331,13 +309,15 @@ 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 r_data_raid56_chunks = 0;
+	u64 l_data_raid56_chunks = 0;
+	u64 r_metadata_raid56_chunks = 0;
+	u64 l_metadata_raid56_chunks = 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;
 	int mixed = 0;
 
 	sargs = load_space_info(fd, path);
@@ -359,24 +339,29 @@ 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);
 
 	for (i = 0; i < sargs->total_spaces; i++) {
 		int ratio;
 		u64 flags = sargs->spaces[i].flags;
 
+		if ((flags & (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA))
+		    == (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA)) {
+			mixed = 1;
+		}
+
 		/*
 		 * The raid5/raid6 ratio depends by the stripes number
-		 * used by every chunk. It is computed separately
+		 * used by every chunk. It is computed separately,
+		 * after we're done with this loop, so skip those.
 		 */
 		if (flags & BTRFS_BLOCK_GROUP_RAID0)
 			ratio = 1;
 		else if (flags & BTRFS_BLOCK_GROUP_RAID1)
 			ratio = 2;
 		else if (flags & BTRFS_BLOCK_GROUP_RAID5)
-			ratio = 0;
+			continue;
 		else if (flags & BTRFS_BLOCK_GROUP_RAID6)
-			ratio = 0;
+			continue;
 		else if (flags & BTRFS_BLOCK_GROUP_DUP)
 			ratio = 2;
 		else if (flags & BTRFS_BLOCK_GROUP_RAID10)
@@ -384,9 +369,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;
 
@@ -394,10 +376,6 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
 			l_global_reserve = sargs->spaces[i].total_bytes;
 			l_global_reserve_used = sargs->spaces[i].used_bytes;
 		}
-		if ((flags & (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA))
-		    == (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA)) {
-			mixed = 1;
-		}
 		if (flags & BTRFS_BLOCK_GROUP_DATA) {
 			r_data_used += sargs->spaces[i].used_bytes * ratio;
 			r_data_chunks += sargs->spaces[i].total_bytes * ratio;
@@ -414,6 +392,52 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
 		}
 	}
 
+	/*
+	 * Here we compute the space occupied by every RAID5/RAID6 chunks.
+	 * The computation is performed on the basis of the number of stripes
+	 * which compose each chunk, which could be different from the number of devices
+	 * if a disk is added later, or if the disks are of different sizes..
+	 */
+	struct chunk_info *info_ptr;
+	for (info_ptr = chunkinfo, i = chunkcount; i > 0; i--, info_ptr++) {
+		int flags = info_ptr->type;
+		int nparity;
+
+		if (flags & BTRFS_BLOCK_GROUP_RAID5) {
+			nparity = 1;
+		}
+		else if (flags & BTRFS_BLOCK_GROUP_RAID6) {
+			nparity = 2;
+		}
+		else {
+			// We're only interested in raid56 here
+			continue;
+		}
+
+		if (flags & BTRFS_BLOCK_GROUP_DATA) {
+			r_data_raid56_chunks += info_ptr->size / (info_ptr->num_stripes - nparity);
+			l_data_raid56_chunks += info_ptr->size / info_ptr->num_stripes;
+		}
+		if (flags & BTRFS_BLOCK_GROUP_METADATA) {
+			r_metadata_raid56_chunks += info_ptr->size / (info_ptr->num_stripes - nparity);
+			l_metadata_raid56_chunks += info_ptr->size / info_ptr->num_stripes;
+		}
+	}
+
+	if (l_data_raid56_chunks > 0) {
+		double ratio = (double)r_data_raid56_chunks / l_data_raid56_chunks;
+		r_data_used += r_data_raid56_chunks;
+		r_data_chunks += r_data_raid56_chunks;
+		l_data_chunks += l_data_raid56_chunks;
+		if (ratio > max_data_ratio)
+			max_data_ratio = ratio;
+	}
+	if (l_metadata_raid56_chunks > 0) {
+		r_metadata_used += r_metadata_raid56_chunks;
+		r_metadata_chunks += r_metadata_raid56_chunks;
+		l_metadata_chunks += l_metadata_raid56_chunks;
+	}
+
 	r_total_chunks = r_data_chunks + r_system_chunks;
 	r_total_used = r_data_used + r_system_used;
 	if (!mixed) {
-- 
2.17.1


  reply	other threads:[~2019-03-17 12:54 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-17 12:51 [PATCH 0/1] btrfs-progs: fi usage: implement raid56 stephane_btrfs
2019-03-17 12:51 ` stephane_btrfs [this message]
2019-03-17 18:41   ` [PATCH 1/1] " Goffredo Baroncelli
2019-03-18 19:12     ` Stéphane Lesimple
2019-03-18 21:05       ` Goffredo Baroncelli
2019-03-17 23:23   ` Hans van Kranenburg
2019-03-18 19:41     ` Stéphane Lesimple
2019-03-19  1:14       ` Hans van Kranenburg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190317125150.26265-2-stephane_btrfs@lesimple.fr \
    --to=stephane_btrfs@lesimple.fr \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.