linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/13] Introduce show --kernel
@ 2013-06-21  7:58 Anand Jain
  2013-06-21  7:58 ` [PATCH 09/13] btrfs-progs: function to release a specific fsid from the list Anand Jain
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Anand Jain @ 2013-06-21  7:58 UTC (permalink / raw)
  To: linux-btrfs

 In an attempt to address the reviewer concern, and to
 find a suitable solution to the btrfs-progs not been
 able to in sync with the kernel changes, found a 
 solution which doesn't introduce new ioctl.
 
 Along with it comes with new set of the dependent
 patches viz 09/13 to 12/13. below.

  btrfs-progs: function to release a specific fsid from the list
  btrfs-progs: move out print in cmd_df to another function
  btrfs-progs: get string for the group profile and type
  btrfs-progs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl

Anand Jain (13):
  btrfs-progs: btrfs_scan_for_fsid doesn't need all the arguments
  btrfs-progs: label option in btrfs filesystem show is not coded
  btrfs-progs: update device scan usage
  btrfs-progs: congregate dev scan
  btrfs-progs: btrfs_scan_one_dir not to skip links when /dev/mapper is
    provided
  btrfs-progs: scan /dev/mapper in filesystem show and device scan
  btrfs-progs: device delete to get errors from the kernel
  btrfs-progs: get_label_mounted to return label instead of print
  btrfs-progs: function to release a specific fsid from the list
  btrfs-progs: move out print in cmd_df to another function
  btrfs-progs: get string for the group profile and type
  btrfs-progs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl
  btrfs-progs: introduce btrfs filesystem show --kernel

 btrfs-find-root.c |   2 +-
 cmds-device.c     |  29 ++++---
 cmds-filesystem.c | 227 ++++++++++++++++++++++++++++++++++--------------------
 ctree.h           |  11 +++
 disk-io.c         |   2 +-
 ioctl.h           |  46 ++++++++++-
 man/btrfs.8.in    |  16 ++--
 utils.c           |  56 +++++++++++---
 utils.h           |  10 ++-
 volumes.c         |  48 +++++++++++-
 volumes.h         |   5 ++
 11 files changed, 331 insertions(+), 121 deletions(-)

-- 
1.8.1.227.g44fe835


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

* [PATCH 09/13] btrfs-progs: function to release a specific fsid from the list
  2013-06-21  7:58 [PATCH 00/13] Introduce show --kernel Anand Jain
@ 2013-06-21  7:58 ` Anand Jain
  2013-06-21  7:58 ` [PATCH 10/13] btrfs-progs: move out print in cmd_df to another function Anand Jain
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Anand Jain @ 2013-06-21  7:58 UTC (permalink / raw)
  To: linux-btrfs

this is preparatory so that fsid found in the kernel can be
added

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 volumes.c | 20 +++++++++++++++++++-
 volumes.h |  3 +++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/volumes.c b/volumes.c
index aa1c3dd..81904c6 100644
--- a/volumes.c
+++ b/volumes.c
@@ -87,7 +87,7 @@ static struct btrfs_fs_devices *find_fsid(u8 *fsid)
 	return NULL;
 }
 
-static int device_list_add(const char *path,
+int device_list_add(const char *path,
 			   struct btrfs_super_block *disk_super,
 			   u64 devid, struct btrfs_fs_devices **fs_devices_ret)
 {
@@ -154,6 +154,24 @@ static int device_list_add(const char *path,
 	return 0;
 }
 
+void device_list_fini(u8 *fsid)
+{
+	struct list_head *fsids;
+	struct list_head *cur_fsid;
+	struct btrfs_fs_devices *fs_devices;
+
+	fsids = btrfs_scanned_uuids();
+	list_for_each(cur_fsid, fsids) {
+		fs_devices = list_entry(cur_fsid, struct btrfs_fs_devices,
+				list);
+		if (!memcmp(fs_devices->fsid, fsid, BTRFS_FSID_SIZE)) {
+			list_del(&fs_devices->devices);
+			list_del(&fs_devices->list);
+			break;
+		}
+	}
+}
+
 int btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 {
 	struct btrfs_fs_devices *seed_devices;
diff --git a/volumes.h b/volumes.h
index 911f788..6286d83 100644
--- a/volumes.h
+++ b/volumes.h
@@ -190,4 +190,7 @@ int btrfs_add_system_chunk(struct btrfs_trans_handle *trans,
 int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);
 struct btrfs_device *btrfs_find_device_by_devid(struct btrfs_root *root,
                                                 u64 devid, int instance);
+int device_list_add(const char *path, struct btrfs_super_block *disk_super,
+			   u64 devid, struct btrfs_fs_devices **fs_devices_ret);
+void device_list_fini(u8 *fsid);
 #endif
-- 
1.8.1.227.g44fe835


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

* [PATCH 10/13] btrfs-progs: move out print in cmd_df to another function
  2013-06-21  7:58 [PATCH 00/13] Introduce show --kernel Anand Jain
  2013-06-21  7:58 ` [PATCH 09/13] btrfs-progs: function to release a specific fsid from the list Anand Jain
@ 2013-06-21  7:58 ` Anand Jain
  2013-06-21  7:58 ` [PATCH 11/13] btrfs-progs: get string for the group profile and type Anand Jain
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Anand Jain @ 2013-06-21  7:58 UTC (permalink / raw)
  To: linux-btrfs

This is a prepatory work for the following btrfs fi show command
fixes. So that we have a function get_df to get the fs sizes.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-filesystem.c | 146 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 79 insertions(+), 67 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 9b7bcf1..ea69328 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -44,71 +44,9 @@ static const char * const cmd_df_usage[] = {
 	NULL
 };
 
-static int cmd_df(int argc, char **argv)
+static void print_df(struct btrfs_ioctl_space_args *sargs)
 {
-	struct btrfs_ioctl_space_args *sargs, *sargs_orig;
-	u64 count = 0, i;
-	int ret;
-	int fd;
-	int e;
-	char *path;
-
-	if (check_argc_exact(argc, 2))
-		usage(cmd_df_usage);
-
-	path = argv[1];
-
-	fd = open_file_or_dir(path);
-	if (fd < 0) {
-		fprintf(stderr, "ERROR: can't access to '%s'\n", path);
-		return 12;
-	}
-
-	sargs_orig = sargs = malloc(sizeof(struct btrfs_ioctl_space_args));
-	if (!sargs)
-		return -ENOMEM;
-
-	sargs->space_slots = 0;
-	sargs->total_spaces = 0;
-
-	ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs);
-	e = errno;
-	if (ret) {
-		fprintf(stderr, "ERROR: couldn't get space info on '%s' - %s\n",
-			path, strerror(e));
-		close(fd);
-		free(sargs);
-		return ret;
-	}
-	if (!sargs->total_spaces) {
-		close(fd);
-		free(sargs);
-		return 0;
-	}
-
-	count = sargs->total_spaces;
-
-	sargs = realloc(sargs, sizeof(struct btrfs_ioctl_space_args) +
-			(count * sizeof(struct btrfs_ioctl_space_info)));
-	if (!sargs) {
-		close(fd);
-		free(sargs_orig);
-		return -ENOMEM;
-	}
-
-	sargs->space_slots = count;
-	sargs->total_spaces = 0;
-
-	ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs);
-	e = errno;
-	if (ret) {
-		fprintf(stderr, "ERROR: couldn't get space info on '%s' - %s\n",
-			path, strerror(e));
-		close(fd);
-		free(sargs);
-		return ret;
-	}
-
+	u64 i;
 	for (i = 0; i < sargs->total_spaces; i++) {
 		char description[80];
 		char *total_bytes;
@@ -160,10 +98,84 @@ static int cmd_df(int argc, char **argv)
 		printf("%s: total=%s, used=%s\n", description, total_bytes,
 		       used_bytes);
 	}
-	close(fd);
-	free(sargs);
+}
 
-	return 0;
+static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret)
+{
+	u64 count = 0;
+	int ret, e;
+	struct btrfs_ioctl_space_args *sargs_orig;
+	struct btrfs_ioctl_space_args *sargs;
+
+	sargs_orig = sargs = malloc(sizeof(struct btrfs_ioctl_space_args));
+	if (!sargs)
+		return -ENOMEM;
+
+	sargs->space_slots = 0;
+	sargs->total_spaces = 0;
+
+	ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs);
+	e = errno;
+	if (ret) {
+		free(sargs);
+		return -e;
+	}
+	if (!sargs->total_spaces) {
+		free(sargs);
+		return 0;
+	}
+
+	count = sargs->total_spaces;
+
+	sargs = realloc(sargs, sizeof(struct btrfs_ioctl_space_args) +
+			(count * sizeof(struct btrfs_ioctl_space_info)));
+	if (!sargs) {
+		free(sargs_orig);
+		return -ENOMEM;
+	}
+
+	sargs->space_slots = count;
+	sargs->total_spaces = 0;
+
+	ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs);
+	e = errno;
+	if (ret) {
+		free(sargs);
+		return -e;
+	}
+	*sargs_ret = sargs;
+	return ret;
+}
+
+static int cmd_df(int argc, char **argv)
+{
+	struct btrfs_ioctl_space_args *sargs = NULL;
+	int ret;
+	int fd;
+	char *path;
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_df_usage);
+
+	path = argv[1];
+
+	fd = open_file_or_dir(path);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access to '%s'\n", path);
+		return 12;
+	}
+	ret = get_df(fd, &sargs);
+
+	if (!ret) {
+		if (sargs) {
+			print_df(sargs);
+			free(sargs);
+		}
+	} else
+		fprintf(stderr, "ERROR: get_df failed %s\n", strerror(ret));
+
+	close(fd);
+	return ret;
 }
 
 static int uuid_search(struct btrfs_fs_devices *fs_devices, char *search)
-- 
1.8.1.227.g44fe835


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

* [PATCH 11/13] btrfs-progs: get string for the group profile and type
  2013-06-21  7:58 [PATCH 00/13] Introduce show --kernel Anand Jain
  2013-06-21  7:58 ` [PATCH 09/13] btrfs-progs: function to release a specific fsid from the list Anand Jain
  2013-06-21  7:58 ` [PATCH 10/13] btrfs-progs: move out print in cmd_df to another function Anand Jain
@ 2013-06-21  7:58 ` Anand Jain
  2013-06-21  7:58 ` [PATCH 12/13] btrfs-progs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl Anand Jain
  2013-06-21  7:58 ` [PATCH 13/13 v3] btrfs-progs: introduce btrfs filesystem show --kernel Anand Jain
  4 siblings, 0 replies; 9+ messages in thread
From: Anand Jain @ 2013-06-21  7:58 UTC (permalink / raw)
  To: linux-btrfs

Code can be well reused and this is the prepatory work
for the patch following this.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-filesystem.c | 83 ++++++++++++++++++++++++++++++++-----------------------
 ctree.h           | 11 ++++++++
 2 files changed, 59 insertions(+), 35 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index ea69328..5f8c258 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -38,6 +38,44 @@ static const char * const filesystem_cmd_group_usage[] = {
 	NULL
 };
 
+static char * group_type_str(u64 flag)
+{
+	switch (flag & BTRFS_BLOCK_GROUP_TYPE_MASK) {
+	case BTRFS_BLOCK_GROUP_DATA:
+		return "data";
+	case BTRFS_BLOCK_GROUP_SYSTEM:
+		return "system";
+	case BTRFS_BLOCK_GROUP_METADATA:
+		return "metadata";
+	case BTRFS_BLOCK_GROUP_DATA|BTRFS_BLOCK_GROUP_METADATA:
+		return "mixed";
+	default:
+		return "unknown";
+	}
+}
+
+static char * group_profile_str(u64 flag)
+{
+	switch (flag & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
+	case 0:
+		return "single";
+	case BTRFS_BLOCK_GROUP_RAID0:
+		return "RAID0";
+	case BTRFS_BLOCK_GROUP_RAID1:
+		return "RAID1";
+	case BTRFS_BLOCK_GROUP_RAID5:
+		return "RAID5";
+	case BTRFS_BLOCK_GROUP_RAID6:
+		return "RAID6";
+	case BTRFS_BLOCK_GROUP_DUP:
+		return "DUP";
+	case BTRFS_BLOCK_GROUP_RAID10:
+		return "RAID10";
+	default:
+		return "unknown";
+	}
+}
+
 static const char * const cmd_df_usage[] = {
 	"btrfs filesystem df <path>",
 	"Show space usage information for a mount point",
@@ -53,45 +91,20 @@ static void print_df(struct btrfs_ioctl_space_args *sargs)
 		char *used_bytes;
 		int written = 0;
 		u64 flags = sargs->spaces[i].flags;
+		char g_str[64];
+		int g_sz;
 
 		memset(description, 0, 80);
 
-		if (flags & BTRFS_BLOCK_GROUP_DATA) {
-			if (flags & BTRFS_BLOCK_GROUP_METADATA) {
-				snprintf(description, 14, "%s",
-					 "Data+Metadata");
-				written += 13;
-			} else {
-				snprintf(description, 5, "%s", "Data");
-				written += 4;
-			}
-		} else if (flags & BTRFS_BLOCK_GROUP_SYSTEM) {
-			snprintf(description, 7, "%s", "System");
-			written += 6;
-		} else if (flags & BTRFS_BLOCK_GROUP_METADATA) {
-			snprintf(description, 9, "%s", "Metadata");
-			written += 8;
-		}
+		strcpy(g_str, group_type_str(flags));
+		g_sz = strlen(g_str);
+		snprintf(description, g_sz + 1, "%s", g_str);
+		written += g_sz;
 
-		if (flags & BTRFS_BLOCK_GROUP_RAID0) {
-			snprintf(description+written, 8, "%s", ", RAID0");
-			written += 7;
-		} else if (flags & BTRFS_BLOCK_GROUP_RAID1) {
-			snprintf(description+written, 8, "%s", ", RAID1");
-			written += 7;
-		} else if (flags & BTRFS_BLOCK_GROUP_DUP) {
-			snprintf(description+written, 6, "%s", ", DUP");
-			written += 5;
-		} else if (flags & BTRFS_BLOCK_GROUP_RAID10) {
-			snprintf(description+written, 9, "%s", ", RAID10");
-			written += 8;
-		} else if (flags & BTRFS_BLOCK_GROUP_RAID5) {
-			snprintf(description+written, 9, "%s", ", RAID5");
-			written += 7;
-		} else if (flags & BTRFS_BLOCK_GROUP_RAID6) {
-			snprintf(description+written, 9, "%s", ", RAID6");
-			written += 7;
-		}
+		strcpy(g_str, group_profile_str(flags));
+		g_sz = strlen(g_str);
+		snprintf(description+written, g_sz + 3, ", %s", g_str);
+		written += g_sz + 2;
 
 		total_bytes = pretty_sizes(sargs->spaces[i].total_bytes);
 		used_bytes = pretty_sizes(sargs->spaces[i].used_bytes);
diff --git a/ctree.h b/ctree.h
index 0af7477..6e4a954 100644
--- a/ctree.h
+++ b/ctree.h
@@ -823,6 +823,17 @@ struct btrfs_csum_item {
 #define BTRFS_BLOCK_GROUP_RAID6    (1ULL << 8)
 #define BTRFS_BLOCK_GROUP_RESERVED	BTRFS_AVAIL_ALLOC_BIT_SINGLE
 
+#define BTRFS_BLOCK_GROUP_TYPE_MASK	(BTRFS_BLOCK_GROUP_DATA |    \
+					 BTRFS_BLOCK_GROUP_SYSTEM |  \
+					 BTRFS_BLOCK_GROUP_METADATA)
+
+#define BTRFS_BLOCK_GROUP_PROFILE_MASK	(BTRFS_BLOCK_GROUP_RAID0 |   \
+					 BTRFS_BLOCK_GROUP_RAID1 |   \
+					 BTRFS_BLOCK_GROUP_RAID5 |   \
+					 BTRFS_BLOCK_GROUP_RAID6 |   \
+					 BTRFS_BLOCK_GROUP_DUP |     \
+					 BTRFS_BLOCK_GROUP_RAID10)
+
 /* used in struct btrfs_balance_args fields */
 #define BTRFS_AVAIL_ALLOC_BIT_SINGLE	(1ULL << 48)
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 12/13] btrfs-progs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl
  2013-06-21  7:58 [PATCH 00/13] Introduce show --kernel Anand Jain
                   ` (2 preceding siblings ...)
  2013-06-21  7:58 ` [PATCH 11/13] btrfs-progs: get string for the group profile and type Anand Jain
@ 2013-06-21  7:58 ` Anand Jain
  2013-06-25  8:39   ` Anand Jain
  2013-06-21  7:58 ` [PATCH 13/13 v3] btrfs-progs: introduce btrfs filesystem show --kernel Anand Jain
  4 siblings, 1 reply; 9+ messages in thread
From: Anand Jain @ 2013-06-21  7:58 UTC (permalink / raw)
  To: linux-btrfs

btrfs-progs has to read fs info from the kernel to
read the latest info instead of reading it from the disks,
which generally is a stale info after certain critical
operation.

getting used_bytes parameter will help to fix
      btrfs filesystem show --kernel
to show the current info of the fs

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 ioctl.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ioctl.h b/ioctl.h
index a40a4a1..d035201 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -169,7 +169,8 @@ struct btrfs_ioctl_fs_info_args {
 	__u64 max_id;				/* out */
 	__u64 num_devices;			/* out */
 	__u8 fsid[BTRFS_FSID_SIZE];		/* out */
-	__u64 reserved[124];			/* pad to 1k */
+	__u64 used_bytes;			/* out */
+	__u64 reserved[123];			/* pad to 1k */
 };
 
 /* balance control ioctl modes */
-- 
1.8.1.227.g44fe835


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

* [PATCH 13/13 v3] btrfs-progs: introduce btrfs filesystem show --kernel
  2013-06-21  7:58 [PATCH 00/13] Introduce show --kernel Anand Jain
                   ` (3 preceding siblings ...)
  2013-06-21  7:58 ` [PATCH 12/13] btrfs-progs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl Anand Jain
@ 2013-06-21  7:58 ` Anand Jain
  2013-06-25  8:44   ` [PATCH 12/12 v4] " Anand Jain
  2013-06-25  8:50   ` Anand Jain
  4 siblings, 2 replies; 9+ messages in thread
From: Anand Jain @ 2013-06-21  7:58 UTC (permalink / raw)
  To: linux-btrfs

As of now btrfs filesystem show reads directly from
disks. So sometimes output can be stale, mainly when
user want to verify their last operation like,
labeling or device delete or add... etc.

This patch adds --kernel option to the 'filesystem show'
subcli, which will read from the kernel instead of
the disks directly.

This btrfs-progs patch depends on the kernel patch
 btrfs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl

v2->v3:
	Do the stuffs without adding new ioctl
	new dependencies: this patch also depends on
	path 9/13 to 12/13 also sent here.
v1->v2:
	code optimized to remove redundancy

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-filesystem.c | 44 ++++++++++++++++++++++++++++++++++++++++----
 volumes.c         | 28 ++++++++++++++++++++++++++++
 volumes.h         |  2 ++
 3 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 5f8c258..10fdf41 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -22,6 +22,8 @@
 #include <errno.h>
 #include <uuid/uuid.h>
 #include <ctype.h>
+#include <mntent.h>
+#include <fcntl.h>
 
 #include "kerncompat.h"
 #include "ctree.h"
@@ -256,8 +258,35 @@ static void print_one_uuid(struct btrfs_fs_devices *fs_devices)
 	printf("\n");
 }
 
+int btrfs_scan_kernel()
+{
+	int ret = 0;
+	FILE *f;
+	struct mntent *mnt;
+
+	if ((f = setmntent ("/proc/mounts", "r")) == NULL)
+		return -errno;
+	while ((mnt = getmntent (f)) != NULL)  {
+		if (!strcmp(mnt->mnt_type, "btrfs")) {
+			struct btrfs_ioctl_fs_info_args fi;
+			struct btrfs_ioctl_dev_info_args *di = NULL;
+			char label[BTRFS_LABEL_SIZE];
+
+			get_label_mounted(mnt->mnt_dir, label);
+			ret = get_fs_info(mnt->mnt_dir, &fi, &di);
+			if (!ret) {
+				device_list_fini(fi.fsid);
+				device_list_add_from_kernel(&fi, di, label);
+				free(di);
+			}
+		}
+	}
+	return ret;
+}
+
+
 static const char * const cmd_show_usage[] = {
-	"btrfs filesystem show [--all-devices|--mapper|<uuid>]",
+	"btrfs filesystem show [--all-devices|--mapper|--kernel|<uuid>]",
 	"Show the structure of a filesystem",
 	"If no argument is given, structure of all present filesystems is shown.",
 	NULL
@@ -279,15 +308,22 @@ static int cmd_show(int argc, char **argv)
 	} else if (argc > 1 && !strcmp(argv[1],"--mapper")) {
 		where = BTRFS_SCAN_MAPPER;
 		searchstart += 1;
+	} else if (argc > 1 && !strcmp(argv[1],"--kernel")) {
+		where = 0;
+		searchstart += 1;
 	}
 
 	if (check_argc_max(argc, searchstart + 1))
 		usage(cmd_show_usage);
 
-	ret = scan_for_btrfs(where, 0);
+	if (where)
+		ret = scan_for_btrfs(where, 0);
+	else {
+		ret = btrfs_scan_kernel();
+	}
 
-	if (ret){
-		fprintf(stderr, "ERROR: error %d while scanning\n", ret);
+	if (ret) {
+		fprintf(stderr, "ERROR: %d while scanning\n", ret);
 		return 18;
 	}
 	
diff --git a/volumes.c b/volumes.c
index 81904c6..01247bf 100644
--- a/volumes.c
+++ b/volumes.c
@@ -172,6 +172,34 @@ void device_list_fini(u8 *fsid)
 	}
 }
 
+int device_list_add_from_kernel(struct btrfs_ioctl_fs_info_args *fi,
+			struct btrfs_ioctl_dev_info_args *di_n, char *label)
+{
+	int ret = 0, i;
+	struct btrfs_super_block ds;
+	struct btrfs_fs_devices *fs_devices;
+	struct btrfs_ioctl_dev_info_args *di;
+
+	memcpy(ds.fsid, fi->fsid, BTRFS_FSID_SIZE);
+	memcpy(ds.label, label, BTRFS_LABEL_SIZE);
+	ds.num_devices = fi->num_devices; /*Todo Fix this */
+	ds.generation = 0;
+	ds.bytes_used = fi->used_bytes;
+
+	di = di_n;
+	for (i = 0; i < fi->num_devices; i++) {
+		memcpy(ds.dev_item.uuid, di->uuid, BTRFS_UUID_SIZE);
+		ds.dev_item.total_bytes = di->total_bytes;
+		ds.dev_item.bytes_used = di->bytes_used;
+
+		ret = device_list_add((char *)di->path, &ds, di->devid, &fs_devices);
+		if (ret)
+			break;
+		di++;
+	}
+	return ret;
+}
+
 int btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 {
 	struct btrfs_fs_devices *seed_devices;
diff --git a/volumes.h b/volumes.h
index 6286d83..a64c8dd 100644
--- a/volumes.h
+++ b/volumes.h
@@ -193,4 +193,6 @@ struct btrfs_device *btrfs_find_device_by_devid(struct btrfs_root *root,
 int device_list_add(const char *path, struct btrfs_super_block *disk_super,
 			   u64 devid, struct btrfs_fs_devices **fs_devices_ret);
 void device_list_fini(u8 *fsid);
+int device_list_add_from_kernel(struct btrfs_ioctl_fs_info_args *fi,
+			struct btrfs_ioctl_dev_info_args *di, char *label);
 #endif
-- 
1.8.1.227.g44fe835


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

* Re: [PATCH 12/13] btrfs-progs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl
  2013-06-21  7:58 ` [PATCH 12/13] btrfs-progs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl Anand Jain
@ 2013-06-25  8:39   ` Anand Jain
  0 siblings, 0 replies; 9+ messages in thread
From: Anand Jain @ 2013-06-25  8:39 UTC (permalink / raw)
  To: linux-btrfs


kindly ignore this patch, the feature now is implemented
without adding any _new_ ioctl or _new_ parameters.

Thanks, Anand


On 06/21/2013 03:58 PM, Anand Jain wrote:
> btrfs-progs has to read fs info from the kernel to
> read the latest info instead of reading it from the disks,
> which generally is a stale info after certain critical
> operation.
>
> getting used_bytes parameter will help to fix
>        btrfs filesystem show --kernel
> to show the current info of the fs
>
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
>   ioctl.h | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/ioctl.h b/ioctl.h
> index a40a4a1..d035201 100644
> --- a/ioctl.h
> +++ b/ioctl.h
> @@ -169,7 +169,8 @@ struct btrfs_ioctl_fs_info_args {
>   	__u64 max_id;				/* out */
>   	__u64 num_devices;			/* out */
>   	__u8 fsid[BTRFS_FSID_SIZE];		/* out */
> -	__u64 reserved[124];			/* pad to 1k */
> +	__u64 used_bytes;			/* out */
> +	__u64 reserved[123];			/* pad to 1k */
>   };
>
>   /* balance control ioctl modes */
>

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

* [PATCH 12/12 v4] btrfs-progs: introduce btrfs filesystem show --kernel
  2013-06-21  7:58 ` [PATCH 13/13 v3] btrfs-progs: introduce btrfs filesystem show --kernel Anand Jain
@ 2013-06-25  8:44   ` Anand Jain
  2013-06-25  8:50   ` Anand Jain
  1 sibling, 0 replies; 9+ messages in thread
From: Anand Jain @ 2013-06-25  8:44 UTC (permalink / raw)
  To: linux-btrfs

As of now btrfs filesystem show reads directly from
disks. So sometimes output can be stale, mainly when
user want to verify their last operation like,
labeling or device delete or add... etc.

This patch adds --kernel option to the 'filesystem show'
subcli, which will read from the kernel instead of
the disks directly.

This btrfs-progs patch depends on the kernel patch
 btrfs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl

v3->v4:
	dropped the dependence of used_bytes from the ioctl
	kernel, Instead used the get_df to calculate the
	used space.
	dropped the function device_list_add_from_kernel
	to update the original device_list_add instead
	I have my own print and device filters, this way I
	can add the group profile information in the show
	output.
v2->v3:
	Do the stuffs without adding new ioctl
	new dependencies: this patch also depends on
	path 9/13 to 12/13 also sent here.
v1->v2:
	code optimized to remove redundancy

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

merg

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-filesystem.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 159 insertions(+), 7 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 5f8c258..a028e1d 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -22,6 +22,9 @@
 #include <errno.h>
 #include <uuid/uuid.h>
 #include <ctype.h>
+#include <mntent.h>
+#include <fcntl.h>
+#include <linux/limits.h>
 
 #include "kerncompat.h"
 #include "ctree.h"
@@ -256,8 +259,129 @@ static void print_one_uuid(struct btrfs_fs_devices *fs_devices)
 	printf("\n");
 }
 
+/* adds up all the used spaces as reported by the space info ioctl
+ */
+static u64 cal_used_bytes(struct btrfs_ioctl_space_args *si)
+{
+	u64 ret = 0;
+	int i;
+	for (i = 0; i < si->total_spaces; i++)
+		ret += si->spaces[i].used_bytes;
+	return ret;
+}
+
+static int print_one_fs(struct btrfs_ioctl_fs_info_args *fi,
+		struct btrfs_ioctl_dev_info_args *di_n,
+		struct btrfs_ioctl_space_args *si_n, char *label, char *path)
+{
+	int i;
+	char uuidbuf[37];
+	char *sz1;
+	char *sz2;
+	struct btrfs_ioctl_dev_info_args *di = di_n;
+	u64 flags;
+
+	uuid_unparse(fi->fsid, uuidbuf);
+	printf("Label: %s  uuid: %s mounted: %s\n",
+		strlen(label)?label:"none", uuidbuf, path);
+	printf("\tGroup profile:");
+	for (i = si_n->total_spaces - 1; i >= 0; i--) {
+		flags = si_n->spaces[i].flags;
+		if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
+			continue;
+		printf(" %s: %s", group_type_str(flags),
+					group_profile_str(flags));
+		printf(" ");
+	}
+	printf("\n");
+
+	sz1 = pretty_sizes(cal_used_bytes(si_n));
+	printf("\tTotal devices %llu FS bytes used %s\n",
+				fi->num_devices, sz1);
+	free(sz1);
+
+	for (i = 0; i < fi->num_devices; i++) {
+		di = (struct btrfs_ioctl_dev_info_args *)&di_n[i];
+		sz1 = pretty_sizes(di->total_bytes);
+		sz2 = pretty_sizes(di->bytes_used);
+		printf("\tdevid    %llu size %s used %s path %s\n",
+			di->devid, sz1, sz2, di->path);
+		free(sz1);
+		free(sz2);
+	}
+
+	printf("\n");
+	return 0;
+}
+
+/* This function checks if the given input parameter is
+ * an uuid or a path
+ * return -1: some error in the given input
+ * return 0: unknow input
+ * return 1: given input is uuid
+ * return 2: given input is path
+ */
+static int check_arg_type(char *input, u8 *processed)
+{
+	int ret = 0;
+	if (!uuid_parse(input, processed))
+		ret = 1;
+	else if (realpath(input, (char *)processed))
+		ret = 2;
+	return ret;
+}
+
+
+static int btrfs_scan_kernel(void *input, int type)
+{
+	int ret = 0, fd;
+	FILE *f;
+	struct mntent *mnt;
+	struct btrfs_ioctl_fs_info_args fi;
+	struct btrfs_ioctl_dev_info_args *di = NULL;
+	struct btrfs_ioctl_space_args *si;
+	char label[BTRFS_LABEL_SIZE];
+
+	if ((f = setmntent ("/proc/mounts", "r")) == NULL)
+		return -errno;
+
+	while ((mnt = getmntent (f)) != NULL) {
+		if (strcmp(mnt->mnt_type, "btrfs"))
+			continue;
+		ret = get_fs_info(mnt->mnt_dir, &fi, &di);
+		if (ret)
+			return ret;
+
+		switch (type) {
+		case 0:
+			break;
+		case 1:
+			if (uuid_compare(fi.fsid, (u8 *)input))
+				continue;
+			break;
+		case 2:
+			if (strcmp(input, mnt->mnt_dir))
+				continue;
+			break;
+		default:
+			break;
+		}
+
+		fd = open(mnt->mnt_dir, O_RDONLY);
+		if (fd > 0 && !get_df(fd, &si)) {
+			get_label_mounted(mnt->mnt_dir, label);
+			print_one_fs(&fi, di, si, label, mnt->mnt_dir);
+			free(si);
+		}
+		if (fd > 0)
+			close(fd);
+		free(di);
+	}
+	return ret;
+}
+
 static const char * const cmd_show_usage[] = {
-	"btrfs filesystem show [--all-devices|--mapper|<uuid>]",
+	"btrfs filesystem show [--all-devices|--mapper|--kernel|<uuid>]",
 	"Show the structure of a filesystem",
 	"If no argument is given, structure of all present filesystems is shown.",
 	NULL
@@ -269,9 +393,10 @@ static int cmd_show(int argc, char **argv)
 	struct btrfs_fs_devices *fs_devices;
 	struct list_head *cur_uuid;
 	char *search = 0;
-	int ret;
+	int ret = 0;
 	int where = BTRFS_SCAN_PROC;
 	int searchstart = 1;
+	u8 processed[PATH_MAX];
 
 	if (argc > 1 && !strcmp(argv[1],"--all-devices")) {
 		where = BTRFS_SCAN_DEV;
@@ -279,15 +404,42 @@ static int cmd_show(int argc, char **argv)
 	} else if (argc > 1 && !strcmp(argv[1],"--mapper")) {
 		where = BTRFS_SCAN_MAPPER;
 		searchstart += 1;
+	} else if (argc > 1 && !strcmp(argv[1],"--kernel")) {
+		where = 0;
+		searchstart += 1;
 	}
 
-	if (check_argc_max(argc, searchstart + 1))
-		usage(cmd_show_usage);
+	if (!where) {
+		if (! (searchstart < argc))
+			ret = btrfs_scan_kernel(NULL, 0);
 
-	ret = scan_for_btrfs(where, 0);
+		while (searchstart < argc) {
+			ret = check_arg_type(argv[searchstart], processed);
+			if (ret < 0) {
+				fprintf(stderr, "ERROR at the input %s\n",
+							argv[searchstart]);
+				return 1;
+			}
+			if (!ret) {
+				fprintf(stderr, "ERROR unknown %s\n",
+					argv[searchstart]);
+				return 1;
+			}
 
-	if (ret){
-		fprintf(stderr, "ERROR: error %d while scanning\n", ret);
+			ret = btrfs_scan_kernel(processed, ret);
+			if (ret)
+				break;
+			searchstart++;
+		}
+		if (ret)
+			fprintf(stderr, "ERROR: failed to obtain one or more FS %d\n",
+				ret);
+		return ret;
+	}
+
+	ret = scan_for_btrfs(where, 0);
+	if (ret) {
+		fprintf(stderr, "ERROR: %d while scanning\n", ret);
 		return 18;
 	}
 	
-- 
1.8.1.227.g44fe835


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

* [PATCH 12/12 v4] btrfs-progs: introduce btrfs filesystem show --kernel
  2013-06-21  7:58 ` [PATCH 13/13 v3] btrfs-progs: introduce btrfs filesystem show --kernel Anand Jain
  2013-06-25  8:44   ` [PATCH 12/12 v4] " Anand Jain
@ 2013-06-25  8:50   ` Anand Jain
  1 sibling, 0 replies; 9+ messages in thread
From: Anand Jain @ 2013-06-25  8:50 UTC (permalink / raw)
  To: linux-btrfs

As of now btrfs filesystem show reads directly from
disks. So sometimes output can be stale, mainly when
user want to verify their last operation like,
labeling or device delete or add... etc.

This patch adds --kernel option to the 'filesystem show'
subcli, which will read from the kernel instead of
the disks directly.

also this path adds the group profile info to the 
output

eg:
-----------------
btrfs fi show --kernel
Label: none  uuid: 39f55f14-e5ca-4a01-899d-915fd35bde05 mounted: /btrfs
	Group profile: metadata: RAID1  data: RAID1 
	Total devices 2 FS bytes used 7.40GB
	devid    1 size 48.23GB used 11.04GB path /dev/dm-5
	devid    2 size 44.99GB used 11.03GB path /dev/mapper/mpathe

Label: none  uuid: a0beeb78-0019-4bdf-8002-0900a123ee07 mounted: /btrfs1
	Group profile: mixed: single 
	Total devices 1 FS bytes used 7.40GB
	devid    1 size 15.00GB used 9.01GB path /dev/mapper/mpathbp1

btrfs fi show --kernel /btrfs2
Label: none  uuid: 9d6a347e-e8a0-44fe-9d2a-d28ee45ef33f mounted: /btrfs2
	Group profile: metadata: DUP  data: single 
	Total devices 1 FS bytes used 2.22MB
	devid    1 size 15.00GB used 1.32GB path /dev/mapper/mpathcp1

btrfs fi show --kernel 9d6a347e-e8a0-44fe-9d2a-d28ee45ef33f
Label: none  uuid: 9d6a347e-e8a0-44fe-9d2a-d28ee45ef33f mounted: /btrfs2
	Group profile: metadata: DUP  data: single 
	Total devices 1 FS bytes used 2.22MB
	devid    1 size 15.00GB used 1.32GB path /dev/mapper/mpathcp1
------------

v3->v4:
	dropped the dependence of used_bytes from the ioctl
	kernel, Instead used the get_df to calculate the
	used space.
	dropped the function device_list_add_from_kernel
	to update the original device_list_add instead
	I have my own print and device filters, this way I
	can add the group profile information in the show
	output.
v2->v3:
	Do the stuffs without adding new ioctl
	new dependencies: this patch also depends on
	path 9/13 to 12/13 also sent here.
v1->v2:
	code optimized to remove redundancy

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

merg

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-filesystem.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 159 insertions(+), 7 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 5f8c258..a028e1d 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -22,6 +22,9 @@
 #include <errno.h>
 #include <uuid/uuid.h>
 #include <ctype.h>
+#include <mntent.h>
+#include <fcntl.h>
+#include <linux/limits.h>
 
 #include "kerncompat.h"
 #include "ctree.h"
@@ -256,8 +259,129 @@ static void print_one_uuid(struct btrfs_fs_devices *fs_devices)
 	printf("\n");
 }
 
+/* adds up all the used spaces as reported by the space info ioctl
+ */
+static u64 cal_used_bytes(struct btrfs_ioctl_space_args *si)
+{
+	u64 ret = 0;
+	int i;
+	for (i = 0; i < si->total_spaces; i++)
+		ret += si->spaces[i].used_bytes;
+	return ret;
+}
+
+static int print_one_fs(struct btrfs_ioctl_fs_info_args *fi,
+		struct btrfs_ioctl_dev_info_args *di_n,
+		struct btrfs_ioctl_space_args *si_n, char *label, char *path)
+{
+	int i;
+	char uuidbuf[37];
+	char *sz1;
+	char *sz2;
+	struct btrfs_ioctl_dev_info_args *di = di_n;
+	u64 flags;
+
+	uuid_unparse(fi->fsid, uuidbuf);
+	printf("Label: %s  uuid: %s mounted: %s\n",
+		strlen(label)?label:"none", uuidbuf, path);
+	printf("\tGroup profile:");
+	for (i = si_n->total_spaces - 1; i >= 0; i--) {
+		flags = si_n->spaces[i].flags;
+		if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
+			continue;
+		printf(" %s: %s", group_type_str(flags),
+					group_profile_str(flags));
+		printf(" ");
+	}
+	printf("\n");
+
+	sz1 = pretty_sizes(cal_used_bytes(si_n));
+	printf("\tTotal devices %llu FS bytes used %s\n",
+				fi->num_devices, sz1);
+	free(sz1);
+
+	for (i = 0; i < fi->num_devices; i++) {
+		di = (struct btrfs_ioctl_dev_info_args *)&di_n[i];
+		sz1 = pretty_sizes(di->total_bytes);
+		sz2 = pretty_sizes(di->bytes_used);
+		printf("\tdevid    %llu size %s used %s path %s\n",
+			di->devid, sz1, sz2, di->path);
+		free(sz1);
+		free(sz2);
+	}
+
+	printf("\n");
+	return 0;
+}
+
+/* This function checks if the given input parameter is
+ * an uuid or a path
+ * return -1: some error in the given input
+ * return 0: unknow input
+ * return 1: given input is uuid
+ * return 2: given input is path
+ */
+static int check_arg_type(char *input, u8 *processed)
+{
+	int ret = 0;
+	if (!uuid_parse(input, processed))
+		ret = 1;
+	else if (realpath(input, (char *)processed))
+		ret = 2;
+	return ret;
+}
+
+
+static int btrfs_scan_kernel(void *input, int type)
+{
+	int ret = 0, fd;
+	FILE *f;
+	struct mntent *mnt;
+	struct btrfs_ioctl_fs_info_args fi;
+	struct btrfs_ioctl_dev_info_args *di = NULL;
+	struct btrfs_ioctl_space_args *si;
+	char label[BTRFS_LABEL_SIZE];
+
+	if ((f = setmntent ("/proc/mounts", "r")) == NULL)
+		return -errno;
+
+	while ((mnt = getmntent (f)) != NULL) {
+		if (strcmp(mnt->mnt_type, "btrfs"))
+			continue;
+		ret = get_fs_info(mnt->mnt_dir, &fi, &di);
+		if (ret)
+			return ret;
+
+		switch (type) {
+		case 0:
+			break;
+		case 1:
+			if (uuid_compare(fi.fsid, (u8 *)input))
+				continue;
+			break;
+		case 2:
+			if (strcmp(input, mnt->mnt_dir))
+				continue;
+			break;
+		default:
+			break;
+		}
+
+		fd = open(mnt->mnt_dir, O_RDONLY);
+		if (fd > 0 && !get_df(fd, &si)) {
+			get_label_mounted(mnt->mnt_dir, label);
+			print_one_fs(&fi, di, si, label, mnt->mnt_dir);
+			free(si);
+		}
+		if (fd > 0)
+			close(fd);
+		free(di);
+	}
+	return ret;
+}
+
 static const char * const cmd_show_usage[] = {
-	"btrfs filesystem show [--all-devices|--mapper|<uuid>]",
+	"btrfs filesystem show [--all-devices|--mapper|--kernel|<uuid>]",
 	"Show the structure of a filesystem",
 	"If no argument is given, structure of all present filesystems is shown.",
 	NULL
@@ -269,9 +393,10 @@ static int cmd_show(int argc, char **argv)
 	struct btrfs_fs_devices *fs_devices;
 	struct list_head *cur_uuid;
 	char *search = 0;
-	int ret;
+	int ret = 0;
 	int where = BTRFS_SCAN_PROC;
 	int searchstart = 1;
+	u8 processed[PATH_MAX];
 
 	if (argc > 1 && !strcmp(argv[1],"--all-devices")) {
 		where = BTRFS_SCAN_DEV;
@@ -279,15 +404,42 @@ static int cmd_show(int argc, char **argv)
 	} else if (argc > 1 && !strcmp(argv[1],"--mapper")) {
 		where = BTRFS_SCAN_MAPPER;
 		searchstart += 1;
+	} else if (argc > 1 && !strcmp(argv[1],"--kernel")) {
+		where = 0;
+		searchstart += 1;
 	}
 
-	if (check_argc_max(argc, searchstart + 1))
-		usage(cmd_show_usage);
+	if (!where) {
+		if (! (searchstart < argc))
+			ret = btrfs_scan_kernel(NULL, 0);
 
-	ret = scan_for_btrfs(where, 0);
+		while (searchstart < argc) {
+			ret = check_arg_type(argv[searchstart], processed);
+			if (ret < 0) {
+				fprintf(stderr, "ERROR at the input %s\n",
+							argv[searchstart]);
+				return 1;
+			}
+			if (!ret) {
+				fprintf(stderr, "ERROR unknown %s\n",
+					argv[searchstart]);
+				return 1;
+			}
 
-	if (ret){
-		fprintf(stderr, "ERROR: error %d while scanning\n", ret);
+			ret = btrfs_scan_kernel(processed, ret);
+			if (ret)
+				break;
+			searchstart++;
+		}
+		if (ret)
+			fprintf(stderr, "ERROR: failed to obtain one or more FS %d\n",
+				ret);
+		return ret;
+	}
+
+	ret = scan_for_btrfs(where, 0);
+	if (ret) {
+		fprintf(stderr, "ERROR: %d while scanning\n", ret);
 		return 18;
 	}
 	
-- 
1.8.1.227.g44fe835


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

end of thread, other threads:[~2013-06-25  8:46 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-21  7:58 [PATCH 00/13] Introduce show --kernel Anand Jain
2013-06-21  7:58 ` [PATCH 09/13] btrfs-progs: function to release a specific fsid from the list Anand Jain
2013-06-21  7:58 ` [PATCH 10/13] btrfs-progs: move out print in cmd_df to another function Anand Jain
2013-06-21  7:58 ` [PATCH 11/13] btrfs-progs: get string for the group profile and type Anand Jain
2013-06-21  7:58 ` [PATCH 12/13] btrfs-progs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl Anand Jain
2013-06-25  8:39   ` Anand Jain
2013-06-21  7:58 ` [PATCH 13/13 v3] btrfs-progs: introduce btrfs filesystem show --kernel Anand Jain
2013-06-25  8:44   ` [PATCH 12/12 v4] " Anand Jain
2013-06-25  8:50   ` Anand Jain

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).