All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3
@ 2013-11-07 10:01 Anand Jain
  2013-11-07 10:01 ` [PATCH 2/3] btrfs-progs: fs show should handle if subvol(s) mounted v3 Anand Jain
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Anand Jain @ 2013-11-07 10:01 UTC (permalink / raw)
  To: linux-btrfs; +Cc: jbacik, zab, dsterba

need fsinfo from btrfs-control that is when mount path is
not known.
current method of going through each mount points isn't
efficient, and multiple subvol of a fsid could be mounted
means extra logic to handle that. Further this will help
to revamp check_mounted() (planned)

check_mounted is heavily used in the btrfs-progs, it
does full scan of all the disks in the system to confirm
if a multi-disk btrfs is mounted it doesn't scalable well
with few hundreds luns, check_mounted for sure needs a
revamp. using this it can be done easily. which is planned.

v3: accepts Josef suggested and fix git screwup
v2: commit reword

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 ioctl.h |   19 +++++++++++++++
 utils.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 utils.h |    1 +
 3 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/ioctl.h b/ioctl.h
index d21413f..29575d8 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -506,6 +506,23 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
 	}
 }
 
+/* fs flags */
+#define BTRFS_FS_MOUNTED	(1LLU << 0)
+
+struct btrfs_ioctl_fslist {
+	__u64 self_sz;			/* in/out */
+	__u8 fsid[BTRFS_FSID_SIZE];	/* out */
+	__u64 num_devices;
+	__u64 missing_devices;
+	__u64 total_devices;
+	__u64 flags;
+};
+
+struct btrfs_ioctl_fslist_args {
+	__u64 self_sz;		/* in/out */
+	__u64 count;		/* out */
+};
+
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -604,6 +621,8 @@ struct btrfs_ioctl_clone_range_args {
 				    struct btrfs_ioctl_dev_replace_args)
 #define BTRFS_IOC_DEDUP_CTL _IOWR(BTRFS_IOCTL_MAGIC, 55, \
 				  struct btrfs_ioctl_dedup_args)
+#define BTRFS_IOC_GET_FSLIST _IOWR(BTRFS_IOCTL_MAGIC, 56, \
+					struct btrfs_ioctl_fslist_args)
 #ifdef __cplusplus
 }
 #endif
diff --git a/utils.c b/utils.c
index 60d2c3a..4b90026 100644
--- a/utils.c
+++ b/utils.c
@@ -47,6 +47,7 @@
 #include "utils.h"
 #include "volumes.h"
 #include "ioctl.h"
+#include "btrfs-list.h"
 
 #ifndef BLKDISCARD
 #define BLKDISCARD	_IO(0x12,119)
@@ -2087,3 +2088,78 @@ int lookup_ino_rootid(int fd, u64 *rootid)
 
 	return 0;
 }
+
+/* scans for fsid(s) in the kernel using the btrfs-control
+ * interface.
+ */
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count)
+{
+	int ret, fd, e;
+	struct btrfs_ioctl_fslist_args *fsargs;
+	struct btrfs_ioctl_fslist_args *fsargs_saved = NULL;
+	struct btrfs_ioctl_fslist *fslist;
+	u64 sz;
+	int count;
+
+	fd = open("/dev/btrfs-control", O_RDWR);
+	e = errno;
+	if (fd < 0) {
+		perror("failed to open /dev/btrfs-control");
+		return -e;
+	}
+
+	/* space to hold 512 fsids, doesn't matter if small
+	 * it would fail and return count so then we try again
+	 */
+	count = 512;
+again:
+	sz = sizeof(*fsargs) + sizeof(*fslist) * count;
+
+	fsargs = malloc(sz);
+	if (!fsargs) {
+		close(fd);
+		return -ENOMEM;
+	}
+
+	memset(fsargs, 0, sz);
+	fsargs->count = count;
+
+	ret = ioctl(fd, BTRFS_IOC_GET_FSLIST, fsargs);
+	e = errno;
+	if (ret == 1) {
+		/* out of size so reallocate */
+		count = fsargs->count;
+		free(fsargs);
+		goto again;
+	} else if (ret < 0) {
+		printf("ERROR: scan_fsid ioctl failed - %s\n",
+			strerror(e));
+		ret = -e;
+		goto out;
+	}
+
+	/* ioctl returns fsid count in count parameter*/
+
+	*out_count = fsargs->count;
+	if (*out_count == 0) {
+		*out_fslist = NULL;
+		ret = 0;
+		goto out;
+	}
+
+	fsargs_saved = fsargs;
+	fslist = (struct btrfs_ioctl_fslist *) (++fsargs);
+
+	sz = sizeof(*fslist) * *out_count;
+	*out_fslist = malloc(sz);
+	if (*out_fslist == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	memcpy(*out_fslist, fslist, sz);
+	ret = 0;
+out:
+	free(fsargs_saved);
+	close(fd);
+	return 0;
+}
diff --git a/utils.h b/utils.h
index 6f4b10c..a14a887 100644
--- a/utils.h
+++ b/utils.h
@@ -94,5 +94,6 @@ int ask_user(char *question);
 int lookup_ino_rootid(int fd, u64 *rootid);
 int btrfs_scan_lblkid(int update_kernel);
 int get_btrfs_mount(const char *dev, char *mp, size_t mp_size);
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count);
 
 #endif
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo

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

* [PATCH 2/3] btrfs-progs: fs show should handle if subvol(s) mounted v3
  2013-11-07 10:01 [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Anand Jain
@ 2013-11-07 10:01 ` Anand Jain
  2013-11-07 10:01 ` [PATCH 3/3] btrfs-progs: lblkid wouldn't find non mapper path input v3 Anand Jain
  2013-11-07 10:04 ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Stefan Behrens
  2 siblings, 0 replies; 7+ messages in thread
From: Anand Jain @ 2013-11-07 10:01 UTC (permalink / raw)
  To: linux-btrfs; +Cc: jbacik, zab, dsterba

as of now with out this patch user would see
fsinfo per btrfs mount path but which mean multiple
entry if more than one subvol is mounted of the same
fsid. so this patch will handle that nicely.

v3: accepts Josef suggested and fix git screwup
v2: accepts Zach suggested

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-filesystem.c |   90 +++++++++++++++++++++++++++++++++--------------------
 utils.c           |   60 +++++++++++++++++++++++++++++++++++
 utils.h           |    1 +
 3 files changed, 117 insertions(+), 34 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index d2cad81..d237989 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -317,6 +317,29 @@ static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info,
 	return 0;
 }
 
+static void handle_print(char *mnt, char *label)
+{
+	int fd;
+	struct btrfs_ioctl_fs_info_args fs_info_arg;
+	struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL;
+	struct btrfs_ioctl_space_args *space_info_arg;
+
+	if (get_fs_info(mnt, &fs_info_arg, &dev_info_arg)) {
+		fprintf(stdout, "ERROR: get_fs_info failed\n");
+		return;
+	}
+
+	fd = open(mnt, O_RDONLY);
+	if (fd != -1 && !get_df(fd, &space_info_arg)) {
+		print_one_fs(&fs_info_arg, dev_info_arg,
+				space_info_arg, label, mnt);
+		kfree(space_info_arg);
+	}
+	if (fd != -1)
+		close(fd);
+	kfree(dev_info_arg);
+}
+
 /* This function checks if the given input parameter is
  * an uuid or a path
  * return -1: some error in the given input
@@ -350,47 +373,39 @@ static int check_arg_type(char *input)
 
 static int btrfs_scan_kernel(void *search)
 {
-	int ret = 0, fd;
-	FILE *f;
-	struct mntent *mnt;
-	struct btrfs_ioctl_fs_info_args fs_info_arg;
-	struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL;
-	struct btrfs_ioctl_space_args *space_info_arg;
+	int ret = 0;
 	char label[BTRFS_LABEL_SIZE];
-
-	f = setmntent("/proc/self/mounts", "r");
-	if (f == NULL)
-		return 1;
-
-	memset(label, 0, sizeof(label));
-	while ((mnt = getmntent(f)) != NULL) {
-		if (strcmp(mnt->mnt_type, "btrfs"))
+	char mnt[BTRFS_PATH_NAME_MAX + 1];
+	struct btrfs_ioctl_fslist *fslist;
+	struct btrfs_ioctl_fslist *fslist_saved;
+	u64 cnt_fs;
+	int cnt_mnt;
+	__u8 *fsid;
+	__u64 flags;
+
+	ret = get_fslist(&fslist, &cnt_fs);
+	if (ret)
+		return ret;
+	fslist_saved = fslist;
+	while (cnt_fs--) {
+		fsid = fslist->fsid;
+		flags = fslist->flags;
+		fslist++;
+		if (!(flags & BTRFS_FS_MOUNTED))
 			continue;
-		ret = get_fs_info(mnt->mnt_dir, &fs_info_arg,
-				&dev_info_arg);
+		memset(mnt, 0, BTRFS_PATH_NAME_MAX + 1);
+		memset(label, 0, sizeof(label));
+		ret = fsid_to_mntpt(fsid, mnt, &cnt_mnt);
 		if (ret)
 			return ret;
-
-		if (get_label_mounted(mnt->mnt_dir, label)) {
-			kfree(dev_info_arg);
+		if (get_label_mounted(mnt, label))
 			return 1;
-		}
-		if (search && !match_search_item_kernel(fs_info_arg.fsid,
-					mnt->mnt_dir, label, search)) {
-			kfree(dev_info_arg);
+
+		if (search && !match_search_item_kernel(fsid,
+					mnt, label, search))
 			continue;
-		}
 
-		fd = open(mnt->mnt_dir, O_RDONLY);
-		if (fd > 0 && !get_df(fd, &space_info_arg)) {
-			print_one_fs(&fs_info_arg, dev_info_arg,
-					space_info_arg, label, mnt->mnt_dir);
-			kfree(space_info_arg);
-			memset(label, 0, sizeof(label));
-		}
-		if (fd > 0)
-			close(fd);
-		kfree(dev_info_arg);
+		handle_print(mnt, label);
 		if (search)
 			return 0;
 	}
@@ -469,6 +484,13 @@ static int cmd_show(int argc, char **argv)
 					goto devs_only;
 			}
 		}
+		if (type == BTRFS_ARG_MNTPOINT) {
+			char label[BTRFS_LABEL_SIZE];
+			if (get_label_mounted(search, label))
+				return 1;
+			handle_print(search, label);
+			return 0;
+		}
 	}
 
 	if (where == BTRFS_SCAN_DEV)
diff --git a/utils.c b/utils.c
index 4b90026..6126af4 100644
--- a/utils.c
+++ b/utils.c
@@ -2163,3 +2163,63 @@ out:
 	close(fd);
 	return 0;
 }
+
+/* This finds the mount point for a given fsid,
+ *  subvols of the same fs/fsid can be mounted
+ *  so here this picks and lowest subvol id
+ *  and returns the mount point
+*/
+int fsid_to_mntpt(__u8 *fsid, char *mntpt, int *mnt_cnt)
+{
+	int fd = -1, ret = 0;
+	DIR *dirstream = NULL;
+	FILE *f;
+	struct btrfs_ioctl_fs_info_args fi_args;
+	u64 svid, saved_svid = (u64)-1;
+	struct mntent *mnt;
+	int mcnt = 0;
+
+	*mnt_cnt = 0;
+	f = setmntent("/proc/self/mounts", "r");
+	if (f == NULL)
+		return 1;
+
+	while ((mnt = getmntent(f)) != NULL) {
+		if (strcmp(mnt->mnt_type, "btrfs"))
+			continue;
+		fd = open_file_or_dir(mnt->mnt_dir, &dirstream);
+		if (fd < 0) {
+			ret = -errno;
+			return ret;
+		}
+		ret = ioctl(fd, BTRFS_IOC_FS_INFO, &fi_args);
+		if (ret < 0) {
+			ret = -errno;
+			close_file_or_dir(fd, dirstream);
+			break;
+		}
+		if (uuid_compare(fsid, fi_args.fsid)) {
+			close_file_or_dir(fd, dirstream);
+			continue;
+		}
+
+		/* found */
+		mcnt++;
+		ret = btrfs_list_get_path_rootid(fd, &svid);
+		if (ret) {
+			/* error so just copy and return*/
+			strcpy(mntpt, mnt->mnt_dir);
+			close_file_or_dir(fd, dirstream);
+			break;
+		}
+		if (svid < saved_svid) {
+			strcpy(mntpt, mnt->mnt_dir);
+			saved_svid = svid;
+		}
+	}
+	endmntent(f);
+	if (mcnt)
+		*mnt_cnt = mcnt;
+
+	return ret;
+}
diff --git a/utils.h b/utils.h
index a14a887..81fa603 100644
--- a/utils.h
+++ b/utils.h
@@ -95,5 +95,6 @@ int lookup_ino_rootid(int fd, u64 *rootid);
 int btrfs_scan_lblkid(int update_kernel);
 int get_btrfs_mount(const char *dev, char *mp, size_t mp_size);
 int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count);
+int fsid_to_mntpt(__u8 *fsid, char *mntpt, int *mnt_cnt);
 
 #endif
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo

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

* [PATCH 3/3] btrfs-progs: lblkid wouldn't find non mapper path input v3
  2013-11-07 10:01 [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Anand Jain
  2013-11-07 10:01 ` [PATCH 2/3] btrfs-progs: fs show should handle if subvol(s) mounted v3 Anand Jain
@ 2013-11-07 10:01 ` Anand Jain
  2013-11-07 10:05   ` Anand Jain
  2013-11-07 11:18   ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v4 Anand Jain
  2013-11-07 10:04 ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Stefan Behrens
  2 siblings, 2 replies; 7+ messages in thread
From: Anand Jain @ 2013-11-07 10:01 UTC (permalink / raw)
  To: linux-btrfs; +Cc: jbacik, zab, dsterba

A new test case when disk is unmounted and if the non mapper
disk path is given as the argument to the btrfs filesystem show <arg>
we still need this to work but lblkid will pull only mapper disks,
it won't match. So this will normalize the input to find btrfs
by fsid and pass it to the search.

v2: accepts Josef suggested
v2: accepts Josef suggested

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-filesystem.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index d237989..72ffe46 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -37,6 +37,7 @@
 #include "version.h"
 #include "commands.h"
 #include "list_sort.h"
+#include "disk-io.h"
 
 static const char * const filesystem_cmd_group_usage[] = {
 	"btrfs filesystem [<group>] <command> [<args>]",
@@ -414,6 +415,39 @@ static int btrfs_scan_kernel(void *search)
 	return 0;
 }
 
+static int dev_to_fsid(char *dev, __u8 *fsid)
+{
+	struct btrfs_super_block *disk_super;
+	char *buf;
+	int ret;
+	int fd;
+
+	buf = malloc(4096);
+	if (!buf)
+		return -ENOMEM;
+
+	fd = open(dev, O_RDONLY);
+	if (fd < 0) {
+		ret = -errno;
+		free(buf);
+		return ret;
+	}
+
+	disk_super = (struct btrfs_super_block *)buf;
+	ret = btrfs_read_dev_super(fd, disk_super,
+			BTRFS_SUPER_INFO_OFFSET);
+	if (ret)
+		goto out;
+
+	memcpy(fsid, disk_super->fsid, BTRFS_FSID_SIZE);
+	ret = 0;
+
+out:
+	close(fd);
+	free(buf);
+	return ret;
+}
+
 static const char * const cmd_show_usage[] = {
 	"btrfs filesystem show [options] [<path>|<uuid>|<device>|label]",
 	"Show the structure of a filesystem",
@@ -434,6 +468,8 @@ static int cmd_show(int argc, char **argv)
 	int type = 0;
 	char mp[BTRFS_PATH_NAME_MAX + 1];
 	char path[PATH_MAX];
+	__u8 fsid[BTRFS_FSID_SIZE];
+	char uuid_buf[37];
 
 	while (1) {
 		int long_index;
@@ -466,6 +502,10 @@ static int cmd_show(int argc, char **argv)
 		if (strlen(search) == 0)
 			usage(cmd_show_usage);
 		type = check_arg_type(search);
+		/* needs spl handling if input arg is block dev
+		 * And if input arg is mount-point just print it
+		 * right away
+		 */
 		if (type == BTRFS_ARG_BLKDEV) {
 			if (where == BTRFS_SCAN_DEV) {
 				/* we need to do this because
@@ -477,14 +517,25 @@ static int cmd_show(int argc, char **argv)
 			} else {
 				ret = get_btrfs_mount(search,
 						mp, sizeof(mp));
-				if (!ret)
+				if (!ret) {
 					/* given block dev is mounted*/
 					search = mp;
-				else
+					type = BTRFS_ARG_MNTPOINT;
+				} else {
+					ret = dev_to_fsid(search, fsid);
+					if (ret) {
+						fprintf(stderr,
+							"ERROR: No btrfs on %s\n",
+							search);
+						return 1;
+					}
+					uuid_unparse(fsid, uuid_buf);
+					search = uuid_buf;
+					type = BTRFS_ARG_UUID;
 					goto devs_only;
+				}
 			}
-		}
-		if (type == BTRFS_ARG_MNTPOINT) {
+		} else if (type == BTRFS_ARG_MNTPOINT) {
 			char label[BTRFS_LABEL_SIZE];
 			if (get_label_mounted(search, label))
 				return 1;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo

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

* Re: [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3
  2013-11-07 10:01 [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Anand Jain
  2013-11-07 10:01 ` [PATCH 2/3] btrfs-progs: fs show should handle if subvol(s) mounted v3 Anand Jain
  2013-11-07 10:01 ` [PATCH 3/3] btrfs-progs: lblkid wouldn't find non mapper path input v3 Anand Jain
@ 2013-11-07 10:04 ` Stefan Behrens
  2013-11-07 11:21   ` Anand Jain
  2 siblings, 1 reply; 7+ messages in thread
From: Stefan Behrens @ 2013-11-07 10:04 UTC (permalink / raw)
  To: Anand Jain, linux-btrfs; +Cc: jbacik, zab, dsterba

On Thu,  7 Nov 2013 18:01:41 +0800, Anand Jain wrote:
> +	*out_fslist = malloc(sz);
> +	if (*out_fslist == NULL) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +	memcpy(*out_fslist, fslist, sz);
> +	ret = 0;
> +out:
> +	free(fsargs_saved);
> +	close(fd);
> +	return 0;
> +}

return ret;


--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-

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

* [PATCH 3/3] btrfs-progs: lblkid wouldn't find non mapper path input v3
  2013-11-07 10:01 ` [PATCH 3/3] btrfs-progs: lblkid wouldn't find non mapper path input v3 Anand Jain
@ 2013-11-07 10:05   ` Anand Jain
  2013-11-07 11:18   ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v4 Anand Jain
  1 sibling, 0 replies; 7+ messages in thread
From: Anand Jain @ 2013-11-07 10:05 UTC (permalink / raw)
  To: linux-btrfs; +Cc: jbacik, zab, dsterba

A new test case when disk is unmounted and if the non mapper
disk path is given as the argument to the btrfs filesystem show <arg>
we still need this to work but lblkid will pull only mapper disks,
it won't match. So this will normalize the input to find btrfs
by fsid and pass it to the search.

v3: accepts Josef suggested
v2: accepts Josef suggested

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-filesystem.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index d237989..72ffe46 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -37,6 +37,7 @@
 #include "version.h"
 #include "commands.h"
 #include "list_sort.h"
+#include "disk-io.h"
 
 static const char * const filesystem_cmd_group_usage[] = {
 	"btrfs filesystem [<group>] <command> [<args>]",
@@ -414,6 +415,39 @@ static int btrfs_scan_kernel(void *search)
 	return 0;
 }
 
+static int dev_to_fsid(char *dev, __u8 *fsid)
+{
+	struct btrfs_super_block *disk_super;
+	char *buf;
+	int ret;
+	int fd;
+
+	buf = malloc(4096);
+	if (!buf)
+		return -ENOMEM;
+
+	fd = open(dev, O_RDONLY);
+	if (fd < 0) {
+		ret = -errno;
+		free(buf);
+		return ret;
+	}
+
+	disk_super = (struct btrfs_super_block *)buf;
+	ret = btrfs_read_dev_super(fd, disk_super,
+			BTRFS_SUPER_INFO_OFFSET);
+	if (ret)
+		goto out;
+
+	memcpy(fsid, disk_super->fsid, BTRFS_FSID_SIZE);
+	ret = 0;
+
+out:
+	close(fd);
+	free(buf);
+	return ret;
+}
+
 static const char * const cmd_show_usage[] = {
 	"btrfs filesystem show [options] [<path>|<uuid>|<device>|label]",
 	"Show the structure of a filesystem",
@@ -434,6 +468,8 @@ static int cmd_show(int argc, char **argv)
 	int type = 0;
 	char mp[BTRFS_PATH_NAME_MAX + 1];
 	char path[PATH_MAX];
+	__u8 fsid[BTRFS_FSID_SIZE];
+	char uuid_buf[37];
 
 	while (1) {
 		int long_index;
@@ -466,6 +502,10 @@ static int cmd_show(int argc, char **argv)
 		if (strlen(search) == 0)
 			usage(cmd_show_usage);
 		type = check_arg_type(search);
+		/* needs spl handling if input arg is block dev
+		 * And if input arg is mount-point just print it
+		 * right away
+		 */
 		if (type == BTRFS_ARG_BLKDEV) {
 			if (where == BTRFS_SCAN_DEV) {
 				/* we need to do this because
@@ -477,14 +517,25 @@ static int cmd_show(int argc, char **argv)
 			} else {
 				ret = get_btrfs_mount(search,
 						mp, sizeof(mp));
-				if (!ret)
+				if (!ret) {
 					/* given block dev is mounted*/
 					search = mp;
-				else
+					type = BTRFS_ARG_MNTPOINT;
+				} else {
+					ret = dev_to_fsid(search, fsid);
+					if (ret) {
+						fprintf(stderr,
+							"ERROR: No btrfs on %s\n",
+							search);
+						return 1;
+					}
+					uuid_unparse(fsid, uuid_buf);
+					search = uuid_buf;
+					type = BTRFS_ARG_UUID;
 					goto devs_only;
+				}
 			}
-		}
-		if (type == BTRFS_ARG_MNTPOINT) {
+		} else if (type == BTRFS_ARG_MNTPOINT) {
 			char label[BTRFS_LABEL_SIZE];
 			if (get_label_mounted(search, label))
 				return 1;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo

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

* [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v4
  2013-11-07 10:01 ` [PATCH 3/3] btrfs-progs: lblkid wouldn't find non mapper path input v3 Anand Jain
  2013-11-07 10:05   ` Anand Jain
@ 2013-11-07 11:18   ` Anand Jain
  1 sibling, 0 replies; 7+ messages in thread
From: Anand Jain @ 2013-11-07 11:18 UTC (permalink / raw)
  To: linux-btrfs; +Cc: jbacik, zab, dsterba

need fsinfo from btrfs-control that is when mount path is
not known.
current method of going through each mount points isn't
efficient, and multiple subvol of a fsid could be mounted
means extra logic to handle that. Further this will help
to revamp check_mounted() (planned)

check_mounted is heavily used in the btrfs-progs, it
does full scan of all the disks in the system to confirm
if a multi-disk btrfs is mounted it doesn't scalable well
with few hundreds luns, check_mounted for sure needs a
revamp. using this it can be done easily. which is planned.

Signed-off-by: Anand Jain <anand.jain@oracle.com>

v4: bug fix and accepts Stefan suggested
v3: accepts Josef suggested
v2: commit reword
---
 ioctl.h |   19 ++++++++++++++++
 utils.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 utils.h |    1 +
 3 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/ioctl.h b/ioctl.h
index d21413f..29575d8 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -506,6 +506,23 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
 	}
 }
 
+/* fs flags */
+#define BTRFS_FS_MOUNTED	(1LLU << 0)
+
+struct btrfs_ioctl_fslist {
+	__u64 self_sz;			/* in/out */
+	__u8 fsid[BTRFS_FSID_SIZE];	/* out */
+	__u64 num_devices;
+	__u64 missing_devices;
+	__u64 total_devices;
+	__u64 flags;
+};
+
+struct btrfs_ioctl_fslist_args {
+	__u64 self_sz;		/* in/out */
+	__u64 count;		/* out */
+};
+
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -604,6 +621,8 @@ struct btrfs_ioctl_clone_range_args {
 				    struct btrfs_ioctl_dev_replace_args)
 #define BTRFS_IOC_DEDUP_CTL _IOWR(BTRFS_IOCTL_MAGIC, 55, \
 				  struct btrfs_ioctl_dedup_args)
+#define BTRFS_IOC_GET_FSLIST _IOWR(BTRFS_IOCTL_MAGIC, 56, \
+					struct btrfs_ioctl_fslist_args)
 #ifdef __cplusplus
 }
 #endif
diff --git a/utils.c b/utils.c
index 60d2c3a..9983db2 100644
--- a/utils.c
+++ b/utils.c
@@ -47,6 +47,7 @@
 #include "utils.h"
 #include "volumes.h"
 #include "ioctl.h"
+#include "btrfs-list.h"
 
 #ifndef BLKDISCARD
 #define BLKDISCARD	_IO(0x12,119)
@@ -2087,3 +2088,77 @@ int lookup_ino_rootid(int fd, u64 *rootid)
 
 	return 0;
 }
+
+/* scans for fsid(s) in the kernel using the btrfs-control
+ * interface.
+ */
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count)
+{
+	int ret, fd, e;
+	struct btrfs_ioctl_fslist_args *fsargs;
+	struct btrfs_ioctl_fslist_args *fsargs_saved = NULL;
+	struct btrfs_ioctl_fslist *fslist;
+	u64 sz;
+	int count;
+
+	fd = open("/dev/btrfs-control", O_RDWR);
+	e = errno;
+	if (fd < 0) {
+		perror("failed to open /dev/btrfs-control");
+		return -e;
+	}
+
+	/* space to hold 512 fsids, doesn't matter if small
+	 * it would fail and return count so then we try again
+	 */
+	count = 512;
+again:
+	sz = sizeof(*fsargs) + sizeof(*fslist) * count;
+
+	fsargs_saved = fsargs = malloc(sz);
+	if (!fsargs) {
+		close(fd);
+		return -ENOMEM;
+	}
+
+	memset(fsargs, 0, sz);
+	fsargs->count = count;
+
+	ret = ioctl(fd, BTRFS_IOC_GET_FSLIST, fsargs);
+	e = errno;
+	if (ret == 1) {
+		/* out of size so reallocate */
+		count = fsargs->count;
+		free(fsargs);
+		goto again;
+	} else if (ret < 0) {
+		printf("ERROR: scan_fsid ioctl failed - %s\n",
+			strerror(e));
+		ret = -e;
+		goto out;
+	}
+
+	/* ioctl returns fsid count in count parameter*/
+
+	*out_count = fsargs->count;
+	if (*out_count == 0) {
+		*out_fslist = NULL;
+		ret = 0;
+		goto out;
+	}
+
+	fslist = (struct btrfs_ioctl_fslist *) (++fsargs);
+
+	sz = sizeof(*fslist) * *out_count;
+	*out_fslist = malloc(sz);
+	if (*out_fslist == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	memcpy(*out_fslist, fslist, sz);
+	ret = 0;
+out:
+	free(fsargs_saved);
+	close(fd);
+	return ret;
+}
diff --git a/utils.h b/utils.h
index 6f4b10c..a14a887 100644
--- a/utils.h
+++ b/utils.h
@@ -94,5 +94,6 @@ int ask_user(char *question);
 int lookup_ino_rootid(int fd, u64 *rootid);
 int btrfs_scan_lblkid(int update_kernel);
 int get_btrfs_mount(const char *dev, char *mp, size_t mp_size);
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count);
 
 #endif
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo

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

* Re: [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3
  2013-11-07 10:04 ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Stefan Behrens
@ 2013-11-07 11:21   ` Anand Jain
  0 siblings, 0 replies; 7+ messages in thread
From: Anand Jain @ 2013-11-07 11:21 UTC (permalink / raw)
  To: Stefan Behrens; +Cc: linux-btrfs, jbacik, zab, dsterba



On 11/07/2013 06:04 PM, Stefan Behrens wrote:
> On Thu,  7 Nov 2013 18:01:41 +0800, Anand Jain wrote:
>> +	*out_fslist = malloc(sz);
>> +	if (*out_fslist == NULL) {
>> +		ret = -ENOMEM;
>> +		goto out;
>> +	}
>> +	memcpy(*out_fslist, fslist, sz);
>> +	ret = 0;
>> +out:
>> +	free(fsargs_saved);
>> +	close(fd);
>> +	return 0;
>> +}
>
> return ret;

  nice catch. Thanks.
  Also fsargs_saved wasn't initialized along with one of early goto out.
  I have fixed it as well in v4 which was sent out.

Thanks, Anand

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-

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

end of thread, other threads:[~2013-11-07 11:13 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-07 10:01 [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Anand Jain
2013-11-07 10:01 ` [PATCH 2/3] btrfs-progs: fs show should handle if subvol(s) mounted v3 Anand Jain
2013-11-07 10:01 ` [PATCH 3/3] btrfs-progs: lblkid wouldn't find non mapper path input v3 Anand Jain
2013-11-07 10:05   ` Anand Jain
2013-11-07 11:18   ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v4 Anand Jain
2013-11-07 10:04 ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Stefan Behrens
2013-11-07 11:21   ` Anand Jain

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.