All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Mason <chris.mason@fusionio.com>
To: Anand Jain <Anand.Jain@oracle.com>,
	Gene Czarcinski <gene@czarc.net>, <linux-btrfs@vger.kernel.org>,
	Eric Sandeen <sandeen@redhat.com>
Subject: Re: btrfs fi show
Date: Mon, 18 Nov 2013 14:32:06 -0500	[thread overview]
Message-ID: <20131118193206.5312.78304@localhost.localdomain> (raw)
In-Reply-To: <528978AF.3020806@oracle.com>

Quoting Anand Jain (2013-11-17 21:17:19)
> There is a fix for this (which David has integrated into the branch
> recently). This also needs the kernel side patch which is listed below.
> 
> [PATCH v4 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control
> [PATCH v4 2/3] btrfs-progs: fs show should handle if subvol(s) mounted
> 
> [PATCH v2] btrfs: add framework to read fs info from btrfs-control

Anand's updated patches are a better way to solve this, but until we get
the kernel feature in, I'm about to commit this patch:

>From 5aff090a3951e7d787b32bb5c49adfec65091385 Mon Sep 17 00:00:00 2001
From: Chris Mason <chris.mason@fusionio.com>
Date: Mon, 18 Nov 2013 14:18:08 -0500
Subject: [PATCH] btrfs filesystem show: skip duplicate fsids

If a given filesystem is mounted more than once, btrfs fi show will
print dups.  This adds a quick and dirty hash table of fsids it
has already printed and makes sure we don't print any fsid more than
once.

Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
 cmds-filesystem.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index aa361d6..1c1926b 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -38,6 +38,74 @@
 #include "commands.h"
 #include "list_sort.h"
 
+
+/*
+ * for btrfs fi show, we maintain a hash of fsids we've already printed.
+ * This way we don't print dups if a given FS is mounted more than once.
+ */
+#define SEEN_FSID_HASH_SIZE 256
+
+struct seen_fsid {
+	u8 fsid[BTRFS_FSID_SIZE];
+	struct seen_fsid *next;
+};
+
+static struct seen_fsid *seen_fsid_hash[SEEN_FSID_HASH_SIZE] = {NULL,};
+
+static int add_seen_fsid(u8 *fsid)
+{
+	u8 hash = fsid[0];
+	int slot = hash % SEEN_FSID_HASH_SIZE;
+	struct seen_fsid *seen = seen_fsid_hash[slot];
+	struct seen_fsid *alloc;
+
+	if (!seen)
+		goto insert;
+
+	while (1) {
+		if (memcmp(seen->fsid, fsid, BTRFS_FSID_SIZE) == 0)
+			return -EEXIST;
+
+		if (!seen->next)
+			break;
+
+		seen = seen->next;
+	}
+
+insert:
+
+	alloc = malloc(sizeof(*alloc));
+	if (!alloc)
+		return -ENOMEM;
+
+	alloc->next = NULL;
+	memcpy(alloc->fsid, fsid, BTRFS_FSID_SIZE);
+
+	if (seen)
+		seen->next = alloc;
+	else
+		seen_fsid_hash[slot] = alloc;
+
+	return 0;
+}
+
+static void free_seen_fsid(void)
+{
+	int slot;
+	struct seen_fsid *seen;
+	struct seen_fsid *next;
+
+	for (slot = 0; slot < SEEN_FSID_HASH_SIZE; slot++) {
+		seen = seen_fsid_hash[slot];
+		while (seen) {
+			next = seen->next;
+			free(seen);
+			seen = next;
+		}
+		seen_fsid_hash[slot] = NULL;
+	}
+}
+
 static const char * const filesystem_cmd_group_usage[] = {
 	"btrfs filesystem [<group>] <command> [<args>]",
 	NULL
@@ -224,6 +292,9 @@ static void print_one_uuid(struct btrfs_fs_devices *fs_devices)
 	u64 devs_found = 0;
 	u64 total;
 
+	if (add_seen_fsid(fs_devices->fsid))
+		return;
+
 	uuid_unparse(fs_devices->fsid, uuidbuf);
 	device = list_entry(fs_devices->devices.next, struct btrfs_device,
 			    dev_list);
@@ -274,6 +345,13 @@ static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info,
 	int i;
 	char uuidbuf[37];
 	struct btrfs_ioctl_dev_info_args *tmp_dev_info;
+	int ret;
+
+	ret = add_seen_fsid(fs_info->fsid);
+	if (ret == -EEXIST)
+		return 0;
+	else if (ret)
+		return ret;
 
 	uuid_unparse(fs_info->fsid, uuidbuf);
 	printf("Label: %s  uuid: %s\n",
@@ -478,6 +556,7 @@ devs_only:
 
 out:
 	printf("%s\n", BTRFS_BUILD_VERSION);
+	free_seen_fsid();
 	return 0;
 }
 
-- 
1.8.2


      reply	other threads:[~2013-11-18 19:32 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-16 14:58 btrfs fi show Gene Czarcinski
2013-11-16 16:04 ` Chris Murphy
2013-11-16 20:33   ` Duncan
2013-11-16 21:50     ` Chris Murphy
2013-11-16 22:36       ` Duncan
2013-11-18  2:17 ` Anand Jain
2013-11-18 19:32   ` Chris Mason [this message]

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=20131118193206.5312.78304@localhost.localdomain \
    --to=chris.mason@fusionio.com \
    --cc=Anand.Jain@oracle.com \
    --cc=gene@czarc.net \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=sandeen@redhat.com \
    /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.