All of lore.kernel.org
 help / color / mirror / Atom feed
From: Goffredo Baroncelli <kreijack@libero.it>
To: linux-btrfs@vger.kernel.org
Cc: Goffredo Baroncelli <kreijack@inwind.it>
Subject: [PATCH 3/3] btrfs-progs: use the new ioctl BTRFS_IOC_GET_CHUNK_INFO
Date: Sun, 15 Mar 2020 16:24:30 +0100	[thread overview]
Message-ID: <20200315152430.7532-4-kreijack@libero.it> (raw)
In-Reply-To: <20200315152430.7532-1-kreijack@libero.it>

From: Goffredo Baroncelli <kreijack@inwind.it>

Use the new ioctl BTRFS_IOC_GET_CHUNK_INFO in load_chunk_info() instead of
the BTRFS_IOC_TREE_SEARCH. The old method is still present as fallback for
compatibility reason.

The goal is to avoid BTRFS_IOC_TREE_SEARCH because it requires root
privileges.

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

diff --git a/cmds/filesystem-usage.c b/cmds/filesystem-usage.c
index aa7065d5..79792ee1 100644
--- a/cmds/filesystem-usage.c
+++ b/cmds/filesystem-usage.c
@@ -39,7 +39,7 @@
 /*
  * Add the chunk info to the chunk_info list
  */
-static int add_info_to_list(struct chunk_info **info_ptr,
+static int legacy_add_info_to_list(struct chunk_info **info_ptr,
 			int *info_count,
 			struct btrfs_chunk *chunk)
 {
@@ -130,7 +130,8 @@ static int cmp_chunk_info(const void *a, const void *b)
 		((struct chunk_info *)b)->type);
 }
 
-static int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count)
+static int legacy_load_chunk_info(int fd, struct chunk_info **info_ptr,
+					int *info_count)
 {
 	int ret;
 	struct btrfs_ioctl_search_args args;
@@ -182,7 +183,7 @@ static int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count
 			off += sizeof(*sh);
 			item = (struct btrfs_chunk *)(args.buf + off);
 
-			ret = add_info_to_list(info_ptr, info_count, item);
+			ret = legacy_add_info_to_list(info_ptr, info_count, item);
 			if (ret) {
 				*info_ptr = NULL;
 				return 1;
@@ -215,6 +216,107 @@ static int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count
 	return 0;
 }
 
+/*
+ * Add the chunk info to the chunk_info list
+ */
+static int add_info_to_list(struct chunk_info **info_ptr,
+			int *info_count,
+			struct btrfs_chunk_info *chunk)
+{
+
+	u64 type = chunk->type;
+	u64 size = chunk->length;
+	int num_stripes = chunk->num_stripes;
+	int j;
+
+	for (j = 0 ; j < num_stripes ; j++) {
+		int i;
+		struct chunk_info *p = NULL;
+		u64    devid;
+
+		devid = chunk->stripes[j].devid;
+
+		for (i = 0 ; i < *info_count ; i++)
+			if ((*info_ptr)[i].type == type &&
+			    (*info_ptr)[i].devid == devid &&
+			    (*info_ptr)[i].num_stripes == num_stripes) {
+				p = (*info_ptr) + i;
+				break;
+			}
+
+		if (!p) {
+			int tmp = sizeof(struct btrfs_chunk) *
+						(*info_count + 1);
+			struct chunk_info *res = realloc(*info_ptr, tmp);
+
+			if (!res) {
+				free(*info_ptr);
+				error("not enough memory");
+				return -ENOMEM;
+			}
+
+			*info_ptr = res;
+			p = res + *info_count;
+			(*info_count)++;
+
+			p->devid = devid;
+			p->type = type;
+			p->size = 0;
+			p->num_stripes = num_stripes;
+		}
+
+		p->size += size;
+
+	}
+
+	return 0;
+
+}
+
+static int load_chunk_info(int fd, struct chunk_info **info_ptr,
+				int *info_count)
+{
+
+	char buf[4096];
+	struct btrfs_ioctl_chunk_info *bici =
+		(struct btrfs_ioctl_chunk_info *)buf;
+	int cont;
+
+	bici->buf_size = sizeof(buf);
+	bici->offset = (u64)0;
+
+	do {
+		int i;
+		struct btrfs_chunk_info *ci;
+		int ret;
+
+		cont = false;
+		ret = ioctl(fd, BTRFS_IOC_GET_CHUNK_INFO, bici);
+		if (ret < 0) {
+			int e = errno;
+
+			if (e == ENOTTY)
+				return legacy_load_chunk_info(fd, info_ptr,
+								info_count);
+			else if (e == EAGAIN)
+				cont = true;
+			else
+				return -e;
+		}
+
+		ci = btrfs_first_chunk_info(bici);
+		for (i = 0 ; i < bici->items_count ; i++) {
+			add_info_to_list(info_ptr, info_count, ci);
+			ci = btrfs_next_chunk_info(ci);
+		}
+
+	} while (cont);
+
+	qsort(*info_ptr, *info_count, sizeof(struct chunk_info),
+		cmp_chunk_info);
+
+	return 0;
+}
 /*
  * Helper to sort the struct btrfs_ioctl_space_info
  */
-- 
2.25.1


  parent reply	other threads:[~2020-03-15 15:32 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-15 15:24 [RFC] btrfs-progs: use the new ioctl BTRFS_IOC_GET_CHUNK_INFO Goffredo Baroncelli
2020-03-15 15:24 ` [PATCH 1/3] btrfs-progs: remove use BLKGETSIZE64 Goffredo Baroncelli
2020-03-15 15:24 ` [PATCH 2/3] btrfs-progs: Add BTRFS_IOC_GET_CHUNK_INFO ioctl Goffredo Baroncelli
2020-03-15 15:24 ` Goffredo Baroncelli [this message]
2020-03-25 20:12 ` [RFC] btrfs-progs: use the new ioctl BTRFS_IOC_GET_CHUNK_INFO Goffredo Baroncelli
2020-03-31 19:17 ` Goffredo Baroncelli
2020-03-31 19:18 ` Goffredo Baroncelli

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=20200315152430.7532-4-kreijack@libero.it \
    --to=kreijack@libero.it \
    --cc=kreijack@inwind.it \
    --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.