All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] add show sub-command for btrfs subvol cli
@ 2013-01-23  8:12 ` Anand Jain
  2013-01-23  8:12   ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
                     ` (27 more replies)
  0 siblings, 28 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

David, Gene

Please accept this patch set which is on top of
  git://repo.or.cz/btrfs-progs-unstable/devel.git for-chris

to add 'show' sub-command feature for the btrfs subvol cli
as in an example below..

eg:
btrfs su list /mnt
ID 256 gen 54 top level 5 path sv1
ID 278 gen 56 top level 5 path sv1/snap1
ID 279 gen 54 top level 5 path sv2
ID 280 gen 41 top level 5 path sv2/snap1

btrfs su show /mnt/sv1
/mnt/sv1
	Name: 			sv1
	uuid: 			3a914db2-8a40-1e49-9382-126c595e9abf
	Parent uuid: 		-
	Creation time: 		2013-01-10 12:16:18
	Object ID: 		256
	Generation (Gen): 	54
	Gen at creation: 	5
	Parent: 		5
	Top Level: 		5
	Snapshot(s):
				snap1
				<FS_TREE>/sv2/snap_sv1

Anand Jain (10):
  Btrfs-progs: move open_file_or_dir() to utils.c
  Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  Btrfs-progs: add parent uuid for snapshots
  Btrfs-progs: move struct root_info to btrfs-list.h
  Btrfs-progs: add function btrfs_get_subvol to get root_info of a
    subvol
  Btrfs-progs: add method to filter snapshots by parent uuid
  Btrfs-progs: put find_mount_root() in commands.h
  Btrfs-progs: make printing subvol extensible to newer layouts
  Btrfs-progs: make get_subvol_name non cmds-send specific
  Btrfs-progs: add show subcommand to subvol cli

 Makefile         |   4 +-
 btrfs-list.c     | 190 +++++++++++++++++++++++++++++++++-------------------
 btrfs-list.h     |  58 +++++++++++++++-
 btrfsctl.c       |   7 +-
 cmds-balance.c   |   1 +
 cmds-inspect.c   |   1 +
 cmds-qgroup.c    |   1 +
 cmds-quota.c     |   1 +
 cmds-send.c      |  12 ++--
 cmds-subvolume.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 commands.h       |   7 +-
 common.c         |  46 -------------
 man/btrfs.8.in   |   6 ++
 utils.c          |  30 ++++++++-
 utils.h          |   3 +
 15 files changed, 428 insertions(+), 139 deletions(-)
 delete mode 100644 common.c

-- 
1.8.1.227.g44fe835


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

* [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-24  4:39     ` Eric Sandeen
  2013-01-23  8:12   ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
                     ` (26 subsequent siblings)
  27 siblings, 1 reply; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

The definition of the function open_file_or_dir() is moved from common.c
to utils.c in order to be able to share some common code between scrub
and the device stats in the following step. That common code uses
open_file_or_dir(). Since open_file_or_dir() makes use of the function
dirfd(3), the required XOPEN version was raised from 6 to 7.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Original-Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
 Makefile         |  4 ++--
 btrfsctl.c       |  7 ++++---
 cmds-balance.c   |  1 +
 cmds-inspect.c   |  1 +
 cmds-qgroup.c    |  1 +
 cmds-quota.c     |  1 +
 cmds-subvolume.c |  1 +
 commands.h       |  3 ---
 common.c         | 46 ----------------------------------------------
 utils.c          | 30 ++++++++++++++++++++++++++++--
 utils.h          |  3 +++
 11 files changed, 42 insertions(+), 56 deletions(-)
 delete mode 100644 common.c

diff --git a/Makefile b/Makefile
index 4894903..8576d90 100644
--- a/Makefile
+++ b/Makefile
@@ -41,8 +41,8 @@ all: version $(progs) manpages
 version:
 	bash version.sh
 
-btrfs: $(objects) btrfs.o help.o common.o $(cmds_objects)
-	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o common.o $(cmds_objects) \
+btrfs: $(objects) btrfs.o help.o $(cmds_objects)
+	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o $(cmds_objects) \
 		$(objects) $(LDFLAGS) $(LIBS) -lpthread
 
 calc-size: $(objects) calc-size.o
diff --git a/btrfsctl.c b/btrfsctl.c
index 518684c..049a5f3 100644
--- a/btrfsctl.c
+++ b/btrfsctl.c
@@ -63,7 +63,7 @@ static void print_usage(void)
 	exit(1);
 }
 
-static int open_file_or_dir(const char *fname)
+static int btrfsctl_open_file_or_dir(const char *fname)
 {
 	int ret;
 	struct stat st;
@@ -91,6 +91,7 @@ static int open_file_or_dir(const char *fname)
 	}
 	return fd;
 }
+
 int main(int ac, char **av)
 {
 	char *fname = NULL;
@@ -128,7 +129,7 @@ int main(int ac, char **av)
 			snap_location = strdup(fullpath);
 			snap_location = dirname(snap_location);
 
-			snap_fd = open_file_or_dir(snap_location);
+			snap_fd = btrfsctl_open_file_or_dir(snap_location);
 
 			name = strdup(fullpath);
 			name = basename(name);
@@ -238,7 +239,7 @@ int main(int ac, char **av)
 		}
 		name = fname;
 	 } else {
-		fd = open_file_or_dir(fname);
+		fd = btrfsctl_open_file_or_dir(fname);
 	 }
 
 	if (name) {
diff --git a/cmds-balance.c b/cmds-balance.c
index 38a7426..6268b61 100644
--- a/cmds-balance.c
+++ b/cmds-balance.c
@@ -28,6 +28,7 @@
 #include "volumes.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const balance_cmd_group_usage[] = {
 	"btrfs [filesystem] balance <command> [options] <path>",
diff --git a/cmds-inspect.c b/cmds-inspect.c
index edabff5..79e069b 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -22,6 +22,7 @@
 
 #include "kerncompat.h"
 #include "ioctl.h"
+#include "utils.h"
 
 #include "commands.h"
 #include "btrfs-list.h"
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 1525c11..cafc284 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -24,6 +24,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const qgroup_cmd_group_usage[] = {
 	"btrfs qgroup <command> [options] <path>",
diff --git a/cmds-quota.c b/cmds-quota.c
index cf9ad97..8481514 100644
--- a/cmds-quota.c
+++ b/cmds-quota.c
@@ -23,6 +23,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const quota_cmd_group_usage[] = {
 	"btrfs quota <command> [options] <path>",
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index ac39f7b..e3cdb1e 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -32,6 +32,7 @@
 #include "ctree.h"
 #include "commands.h"
 #include "btrfs-list.h"
+#include "utils.h"
 
 static const char * const subvolume_cmd_group_usage[] = {
 	"btrfs subvolume <command> <args>",
diff --git a/commands.h b/commands.h
index bb6d2dd..8114a73 100644
--- a/commands.h
+++ b/commands.h
@@ -79,9 +79,6 @@ void help_ambiguous_token(const char *arg, const struct cmd_group *grp);
 
 void help_command_group(const struct cmd_group *grp, int argc, char **argv);
 
-/* common.c */
-int open_file_or_dir(const char *fname);
-
 extern const struct cmd_group subvolume_cmd_group;
 extern const struct cmd_group filesystem_cmd_group;
 extern const struct cmd_group balance_cmd_group;
diff --git a/common.c b/common.c
deleted file mode 100644
index 03f6570..0000000
--- a/common.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-
-int open_file_or_dir(const char *fname)
-{
-	int ret;
-	struct stat st;
-	DIR *dirstream;
-	int fd;
-
-	ret = stat(fname, &st);
-	if (ret < 0) {
-		return -1;
-	}
-	if (S_ISDIR(st.st_mode)) {
-		dirstream = opendir(fname);
-		if (!dirstream) {
-			return -2;
-		}
-		fd = dirfd(dirstream);
-	} else {
-		fd = open(fname, O_RDWR);
-	}
-	if (fd < 0) {
-		return -3;
-	}
-	return fd;
-}
diff --git a/utils.c b/utils.c
index 205e667..774f81d 100644
--- a/utils.c
+++ b/utils.c
@@ -16,8 +16,9 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#define _XOPEN_SOURCE 600
-#define __USE_XOPEN2K
+#define _XOPEN_SOURCE 700
+#define __USE_XOPEN2K8
+#define __XOPEN2K8 /* due to an error in dirent.h, to get dirfd() */
 #include <stdio.h>
 #include <stdlib.h>
 #ifndef __CHECKER__
@@ -1220,3 +1221,28 @@ scan_again:
 	return 0;
 }
 
+int open_file_or_dir(const char *fname)
+{
+	int ret;
+	struct stat st;
+	DIR *dirstream;
+	int fd;
+
+	ret = stat(fname, &st);
+	if (ret < 0) {
+		return -1;
+	}
+	if (S_ISDIR(st.st_mode)) {
+		dirstream = opendir(fname);
+		if (!dirstream) {
+			return -2;
+		}
+		fd = dirfd(dirstream);
+	} else {
+		fd = open(fname, O_RDWR);
+	}
+	if (fd < 0) {
+		return -3;
+	}
+	return fd;
+}
diff --git a/utils.h b/utils.h
index 3a0368b..6975f10 100644
--- a/utils.h
+++ b/utils.h
@@ -19,6 +19,8 @@
 #ifndef __UTILS__
 #define __UTILS__
 
+#include "ctree.h"
+
 #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024)
 
 int make_btrfs(int fd, const char *device, const char *label,
@@ -46,4 +48,5 @@ int check_label(char *input);
 int get_mountpt(char *dev, char *mntpt, size_t size);
 
 int btrfs_scan_block_devices(int run_ioctl);
+int open_file_or_dir(const char *fname);
 #endif
-- 
1.8.1.227.g44fe835


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

* [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
  2013-01-23  8:12   ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-23  8:12   ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
                     ` (25 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

To improve the code reuse its better to have btrfs_list_subvols
just return list of subvols witout printing

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 28 ++++++++++++++++++----------
 btrfs-list.h     |  2 +-
 cmds-subvolume.c |  4 ++--
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index e5f0f96..b656286 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1441,15 +1441,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 	}
 }
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
-		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 {
-	struct root_lookup root_lookup;
-	struct root_lookup root_sort;
 	int ret;
 
-	ret = __list_subvol_search(fd, &root_lookup);
+	ret = __list_subvol_search(fd, root_lookup);
 	if (ret) {
 		fprintf(stderr, "ERROR: can't perform the search - %s\n",
 				strerror(errno));
@@ -1460,16 +1456,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
 	 * now we have an rbtree full of root_info objects, but we need to fill
 	 * in their path names within the subvol that is referencing each one.
 	 */
-	ret = __list_subvol_fill_paths(fd, &root_lookup);
-	if (ret < 0)
-		return ret;
+	ret = __list_subvol_fill_paths(fd, root_lookup);
+	return ret;
+}
 
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
+		       struct btrfs_list_comparer_set *comp_set,
+		       int is_tab_result)
+{
+	struct root_lookup root_lookup;
+	struct root_lookup root_sort;
+	int ret;
+
+	ret = btrfs_list_subvols(fd, &root_lookup);
+	if (ret)
+		return ret;
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
 	print_all_volume_info(&root_sort, is_tab_result);
 	__free_all_subvolumn(&root_lookup);
-	return ret;
+
+	return 0;
 }
 
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
diff --git a/btrfs-list.h b/btrfs-list.h
index cde4b3c..71fe0f3 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 			      enum btrfs_list_comp_enum comparer,
 			      int is_descending);
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
 			int is_tab_result);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index e3cdb1e..c35dff7 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
+	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				is_tab_result);
 	if (ret)
 		return 19;
@@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
  2013-01-23  8:12   ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
  2013-01-23  8:12   ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-23  8:12   ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
                     ` (24 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 32 +++++++++++++++++++++++++++-----
 btrfs-list.h     |  1 +
 cmds-subvolume.c |  6 +++++-
 3 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index b656286..cc065e9 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -80,6 +80,7 @@ struct root_info {
 	time_t otime;
 
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	/* path from the subvol we live in to this root, including the
 	 * root's name.  This is null until we do the extra lookup ioctl.
@@ -128,6 +129,11 @@ struct {
 		.need_print	= 0,
 	},
 	{
+		.name		= "parent UUID",
+		.column_name	= "Parent UUID",
+		.need_print	= 0,
+	},
+	{
 		.name		= "uuid",
 		.column_name	= "UUID",
 		.need_print	= 0,
@@ -435,7 +441,7 @@ static struct root_info *root_tree_search(struct root_lookup *root_tree,
 static int update_root(struct root_lookup *root_lookup,
 		       u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		       u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		       time_t ot, void *uuid)
+		       time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 
@@ -472,6 +478,8 @@ static int update_root(struct root_lookup *root_lookup,
 		ri->otime = ot;
 	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
 
 	return 0;
 }
@@ -489,17 +497,18 @@ static int update_root(struct root_lookup *root_lookup,
  * gen: the current generation of the root
  * ot: the original time(create time) of the root
  * uuid: uuid of the root
+ * puuid: uuid of the root parent if any
  */
 static int add_root(struct root_lookup *root_lookup,
 		    u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		    u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		    time_t ot, void *uuid)
+		    time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 	int ret;
 
 	ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
-			  dir_id, name, name_len, ogen, gen, ot, uuid);
+			  dir_id, name, name_len, ogen, gen, ot, uuid, puuid);
 	if (!ret)
 		return 0;
 
@@ -540,6 +549,9 @@ static int add_root(struct root_lookup *root_lookup,
 	if (uuid) 
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
 
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
+
 	ret = root_tree_insert(root_lookup, ri);
 	if (ret) {
 		printf("failed to insert tree %llu\n", (unsigned long long)root_id);
@@ -1022,6 +1034,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 	int i;
 	time_t t;
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	root_lookup_init(root_lookup);
 	memset(&args, 0, sizeof(args));
@@ -1075,7 +1088,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 
 				add_root(root_lookup, sh->objectid, sh->offset,
 					 0, 0, dir_id, name, name_len, 0, 0, 0,
-					 NULL);
+					 NULL, NULL);
 			} else if (sh->type == BTRFS_ROOT_ITEM_KEY) {
 				ri = (struct btrfs_root_item *)(args.buf + off);
 				gen = btrfs_root_generation(ri);
@@ -1085,15 +1098,17 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 					t = ri->otime.sec;
 					ogen = btrfs_root_otransid(ri);
 					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
+					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
 				} else {
 					t = 0;
 					ogen = 0;
 					memset(uuid, 0, BTRFS_UUID_SIZE);
+					memset(puuid, 0, BTRFS_UUID_SIZE);
 				}
 
 				add_root(root_lookup, sh->objectid, 0,
 					 sh->offset, flags, 0, NULL, 0, ogen,
-					 gen, t, uuid);
+					 gen, t, uuid, puuid);
 			}
 
 			off += sh->len;
@@ -1347,6 +1362,13 @@ static void print_subvolume_column(struct root_info *subv,
 			uuid_unparse(subv->uuid, uuidparse);
 		printf("%s", uuidparse);
 		break;
+	case BTRFS_LIST_PUUID:
+		if (uuid_is_null(subv->puuid))
+			strcpy(uuidparse, "-");
+		else
+			uuid_unparse(subv->puuid, uuidparse);
+		printf("%s", uuidparse);
+		break;
 	case BTRFS_LIST_PATH:
 		BUG_ON(!subv->full_path);
 		printf("%s", subv->full_path);
diff --git a/btrfs-list.h b/btrfs-list.h
index 71fe0f3..855e73d 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -53,6 +53,7 @@ enum btrfs_list_column_enum {
 	BTRFS_LIST_PARENT,
 	BTRFS_LIST_TOP_LEVEL,
 	BTRFS_LIST_OTIME,
+	BTRFS_LIST_PUUID,
 	BTRFS_LIST_UUID,
 	BTRFS_LIST_PATH,
 	BTRFS_LIST_ALL,
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index c35dff7..ee36463 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -280,6 +280,7 @@ static const char * const cmd_subvol_list_usage[] = {
 	"-p           print parent ID",
 	"-a           print all the subvolumes in the filesystem.",
 	"-u           print the uuid of subvolumes (and snapshots)",
+	"-q           print the parent uuid of snapshots",
 	"-t           print the result as a table",
 	"-s           list snapshots only in the filesystem",
 	"-r           list readonly subvolumes (including snapshots)",
@@ -319,7 +320,7 @@ static int cmd_subvol_list(int argc, char **argv)
 	optind = 1;
 	while(1) {
 		c = getopt_long(argc, argv,
-				    "apsurg:c:t", long_options, NULL);
+				    "apsuqrg:c:t", long_options, NULL);
 		if (c < 0)
 			break;
 
@@ -343,6 +344,9 @@ static int cmd_subvol_list(int argc, char **argv)
 		case 'u':
 			btrfs_list_setup_print_column(BTRFS_LIST_UUID);
 			break;
+		case 'q':
+			btrfs_list_setup_print_column(BTRFS_LIST_PUUID);
+			break;
 		case 'r':
 			flags |= BTRFS_ROOT_SUBVOL_RDONLY;
 			break;
-- 
1.8.1.227.g44fe835


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

* [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (2 preceding siblings ...)
  2013-01-23  8:12   ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-23  8:12   ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
                     ` (23 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

As we would add more ways to list and manage the subvols
and snapshots, its better if we have struct root_info
defined in the header file.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 47 -----------------------------------------------
 btrfs-list.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index cc065e9..1851f3e 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -46,53 +46,6 @@ struct root_lookup {
 	struct rb_root root;
 };
 
-/*
- * one of these for each root we find.
- */
-struct root_info {
-	struct rb_node rb_node;
-	struct rb_node sort_node;
-
-	/* this root's id */
-	u64 root_id;
-
-	/* equal the offset of the root's key */
-	u64 root_offset;
-
-	/* flags of the root */
-	u64 flags;
-
-	/* the id of the root that references this one */
-	u64 ref_tree;
-
-	/* the dir id we're in from ref_tree */
-	u64 dir_id;
-
-	u64 top_id;
-
-	/* generation when the root is created or last updated */
-	u64 gen;
-
-	/* creation generation of this root in sec*/
-	u64 ogen;
-
-	/* creation time of this root in sec*/
-	time_t otime;
-
-	u8 uuid[BTRFS_UUID_SIZE];
-	u8 puuid[BTRFS_UUID_SIZE];
-
-	/* path from the subvol we live in to this root, including the
-	 * root's name.  This is null until we do the extra lookup ioctl.
-	 */
-	char *path;
-
-	/* the name of this root in the directory it lives in */
-	char *name;
-
-	char *full_path;
-};
-
 struct {
 	char	*name;
 	char	*column_name;
diff --git a/btrfs-list.h b/btrfs-list.h
index 855e73d..3b7b680 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,7 +18,52 @@
 
 #include "kerncompat.h"
 
-struct root_info;
+/*
+ * one of these for each root we find.
+ */
+struct root_info {
+	struct rb_node rb_node;
+	struct rb_node sort_node;
+
+	/* this root's id */
+	u64 root_id;
+
+	/* equal the offset of the root's key */
+	u64 root_offset;
+
+	/* flags of the root */
+	u64 flags;
+
+	/* the id of the root that references this one */
+	u64 ref_tree;
+
+	/* the dir id we're in from ref_tree */
+	u64 dir_id;
+
+	u64 top_id;
+
+	/* generation when the root is created or last updated */
+	u64 gen;
+
+	/* creation generation of this root in sec*/
+	u64 ogen;
+
+	/* creation time of this root in sec*/
+	time_t otime;
+
+	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
+
+	/* path from the subvol we live in to this root, including the
+	 * root's name.  This is null until we do the extra lookup ioctl.
+	 */
+	char *path;
+
+	/* the name of this root in the directory it lives in */
+	char *name;
+
+	char *full_path;
+};
 
 typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
 typedef int (*btrfs_list_comp_func)(struct root_info *, struct root_info *,
-- 
1.8.1.227.g44fe835


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

* [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (3 preceding siblings ...)
  2013-01-23  8:12   ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-24  4:49     ` Eric Sandeen
  2013-01-23  8:12   ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
                     ` (22 subsequent siblings)
  27 siblings, 1 reply; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

We need a function which can get the root_info of a given
subvol. This is in preparation to add support for the show
sub-cli.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
 btrfs-list.h |  1 +
 2 files changed, 39 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 1851f3e..ec64a36 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1455,6 +1455,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	return 0;
 }
 
+int btrfs_get_subvol(int fd, struct root_info *the_ri)
+{
+	int ret = -1;
+	struct root_lookup rl;
+	struct rb_node *rbn;
+	struct root_info *ri;
+	u64 root_id = btrfs_list_get_path_rootid(fd);
+
+	if (btrfs_list_subvols(fd, &rl))
+		return 13;
+
+	rbn = rb_first(&rl.root);
+	while(rbn) {
+		ri = rb_entry(rbn, struct root_info, rb_node);
+		resolve_root(&rl, ri, root_id);
+		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
+			memcpy(the_ri, ri, offsetof(struct root_info, path));
+			if (ri->path)
+				the_ri->path = strdup(ri->path);
+			else
+				the_ri->path = NULL;
+			if (ri->name)
+				the_ri->name = strdup(ri->name);
+			else
+				the_ri->name = NULL;
+			if (ri->full_path)
+				the_ri->full_path = strdup(ri->full_path);
+			else
+				the_ri->name = NULL;
+			ret = 0;
+			break;
+		}
+		rbn = rb_next(rbn);
+	}
+	__free_all_subvolumn(&rl);
+	return ret;
+}
+
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 			    struct btrfs_file_extent_item *item,
 			    u64 found_gen, u64 *cache_dirid,
diff --git a/btrfs-list.h b/btrfs-list.h
index 3b7b680..580d4d1 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
 u64 btrfs_list_get_path_rootid(int fd);
+int btrfs_get_subvol(int fd, struct root_info *the_ri);
-- 
1.8.1.227.g44fe835


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

* [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (4 preceding siblings ...)
  2013-01-23  8:12   ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-23  8:12   ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
                     ` (21 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 6 ++++++
 btrfs-list.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index ec64a36..f5958cf 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1144,6 +1144,11 @@ static int filter_topid_equal(struct root_info *ri, u64 data)
 	return ri->top_id == data;
 }
 
+static int filter_by_parent(struct root_info *ri, u64 data)
+{
+	return !uuid_compare(ri->puuid, (u8 *)data);
+}
+
 static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_ROOTID]		= filter_by_rootid,
 	[BTRFS_LIST_FILTER_SNAPSHOT_ONLY]	= filter_snapshot,
@@ -1155,6 +1160,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_CGEN_LESS]		= filter_cgen_less,
 	[BTRFS_LIST_FILTER_CGEN_EQUAL]          = filter_cgen_equal,
 	[BTRFS_LIST_FILTER_TOPID_EQUAL]		= filter_topid_equal,
+	[BTRFS_LIST_FILTER_BY_PARENT]		= filter_by_parent,
 };
 
 struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
diff --git a/btrfs-list.h b/btrfs-list.h
index 580d4d1..cde7a3f 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -117,6 +117,7 @@ enum btrfs_list_filter_enum {
 	BTRFS_LIST_FILTER_CGEN_LESS,
 	BTRFS_LIST_FILTER_CGEN_MORE,
 	BTRFS_LIST_FILTER_TOPID_EQUAL,
+	BTRFS_LIST_FILTER_BY_PARENT,
 	BTRFS_LIST_FILTER_MAX,
 };
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (5 preceding siblings ...)
  2013-01-23  8:12   ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-23  8:12   ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
                     ` (20 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

A useful function need to define it in a header file.

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

diff --git a/commands.h b/commands.h
index 8114a73..9b77f3e 100644
--- a/commands.h
+++ b/commands.h
@@ -103,3 +103,6 @@ int cmd_qgroup(int argc, char **argv);
 
 /* subvolume exported functions */
 int test_issubvolume(char *path);
+
+/* send.c */
+int find_mount_root(const char *path, char **mount_root);
-- 
1.8.1.227.g44fe835


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

* [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (6 preceding siblings ...)
  2013-01-23  8:12   ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-23  8:12   ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
                     ` (19 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Currently you can print subvol in a list or table format.
This patch will provide a way to extend this to other formats
like the upcoming raw format.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 26 +++++++++++++++-----------
 btrfs-list.h     |  3 +++
 cmds-subvolume.c | 23 ++++++++++++++++++++---
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index f5958cf..71f7239 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -54,12 +54,12 @@ struct {
 	{
 		.name		= "ID",
 		.column_name	= "ID",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "gen",
 		.column_name	= "Gen",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "cgen",
@@ -74,7 +74,7 @@ struct {
 	{
 		.name		= "top level",
 		.column_name	= "Top Level",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "otime",
@@ -94,7 +94,7 @@ struct {
 	{
 		.name		= "path",
 		.column_name	= "Path",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= NULL,
@@ -1403,21 +1403,25 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int is_tab_result)
+				  int layout)
 {
 	struct rb_node *n;
 	struct root_info *entry;
 
-	if (is_tab_result)
+	if (layout == BTRFS_LIST_LAYOUT_TABLE)
 		print_all_volume_info_tab_head();
 
 	n = rb_first(&sorted_tree->root);
 	while (n) {
 		entry = rb_entry(n, struct root_info, sort_node);
-		if (is_tab_result)
-			print_single_volume_info_table(entry);
-		else
+		switch (layout) {
+		case BTRFS_LIST_LAYOUT_DEFAULT:
 			print_single_volume_info_default(entry);
+			break;
+		case BTRFS_LIST_LAYOUT_TABLE:
+			print_single_volume_info_table(entry);
+			break;
+		}
 		n = rb_next(n);
 	}
 }
@@ -1443,7 +1447,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+		       int layout)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1455,7 +1459,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, is_tab_result);
+	print_all_volume_info(&root_sort, layout);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index cde7a3f..5b60068 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,6 +18,9 @@
 
 #include "kerncompat.h"
 
+#define BTRFS_LIST_LAYOUT_DEFAULT	0
+#define BTRFS_LIST_LAYOUT_TABLE	1
+
 /*
  * one of these for each root we find.
  */
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index ee36463..dd677f7 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -410,8 +410,18 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				is_tab_result);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	if (is_tab_result)
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_TABLE);
+	else
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
@@ -617,7 +627,14 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
+		BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (7 preceding siblings ...)
  2013-01-23  8:12   ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-23  8:12   ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
                     ` (18 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

get_subvol_name can be used other than the just with in cmds-send.c
so this patch will make it possible with out changing the original
intentions.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-send.c | 12 ++++++------
 commands.h  |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/cmds-send.c b/cmds-send.c
index 9b47e70..beebac9 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -331,12 +331,12 @@ out:
 	return ret;
 }
 
-static const char *get_subvol_name(struct btrfs_send *s, const char *full_path)
+char *get_subvol_name(char *mnt, char *full_path)
 {
-	int len = strlen(s->root_path);
+	int len = strlen(mnt);
 	if (!len)
 		return full_path;
-	if (s->root_path[len - 1] != '/')
+	if (mnt[len - 1] != '/')
 		len += 1;
 
 	return full_path + len;
@@ -445,7 +445,7 @@ int cmd_send_start(int argc, char **argv)
 			if (ret < 0)
 				goto out;
 
-			ret = get_root_id(&send, get_subvol_name(&send, subvol),
+			ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 					&root_id);
 			if (ret < 0) {
 				fprintf(stderr, "ERROR: could not resolve "
@@ -506,7 +506,7 @@ int cmd_send_start(int argc, char **argv)
 
 	if (snapshot_parent != NULL) {
 		ret = get_root_id(&send,
-				get_subvol_name(&send, snapshot_parent),
+				get_subvol_name(send.root_path, snapshot_parent),
 				&parent_root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
@@ -565,7 +565,7 @@ int cmd_send_start(int argc, char **argv)
 			goto out;
 		}
 
-		ret = get_root_id(&send, get_subvol_name(&send, subvol),
+		ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 				&root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
diff --git a/commands.h b/commands.h
index 9b77f3e..631fb6b 100644
--- a/commands.h
+++ b/commands.h
@@ -106,3 +106,4 @@ int test_issubvolume(char *path);
 
 /* send.c */
 int find_mount_root(const char *path, char **mount_root);
+char *get_subvol_name(char *mnt, char *full_path);
-- 
1.8.1.227.g44fe835


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

* [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (8 preceding siblings ...)
  2013-01-23  8:12   ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
@ 2013-01-23  8:12   ` Anand Jain
  2013-01-24  5:06     ` Eric Sandeen
  2013-01-23 21:57   ` [PATCH 00/10] add show sub-command for btrfs " Gene Czarcinski
                     ` (17 subsequent siblings)
  27 siblings, 1 reply; 131+ messages in thread
From: Anand Jain @ 2013-01-23  8:12 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

This adds show sub-command to the btrfs subvol cli
to display detailed inforamtion of the given subvol
or snapshot.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     |  25 +++++++-
 btrfs-list.h     |   3 +-
 cmds-subvolume.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 man/btrfs.8.in   |   6 ++
 4 files changed, 203 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 71f7239..5be3ed9 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1337,6 +1337,22 @@ static void print_subvolume_column(struct root_info *subv,
 	}
 }
 
+static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_LIST_ALL; i++) {
+		if (!btrfs_list_columns[i].need_print)
+			continue;
+
+		if(raw_prefix);
+			printf("%s",raw_prefix);
+
+		print_subvolume_column(subv, i);
+	}
+	printf("\n");
+}
+
 static void print_single_volume_info_table(struct root_info *subv)
 {
 	int i;
@@ -1403,7 +1419,7 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int layout)
+				  int layout, char *raw_prefix)
 {
 	struct rb_node *n;
 	struct root_info *entry;
@@ -1421,6 +1437,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 		case BTRFS_LIST_LAYOUT_TABLE:
 			print_single_volume_info_table(entry);
 			break;
+		case BTRFS_LIST_LAYOUT_RAW:
+			print_single_volume_info_raw(entry, raw_prefix);
+			break;
 		}
 		n = rb_next(n);
 	}
@@ -1447,7 +1466,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int layout)
+		       int layout, char *raw_prefix)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1459,7 +1478,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, layout);
+	print_all_volume_info(&root_sort, layout, raw_prefix);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index 5b60068..09d35f7 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -20,6 +20,7 @@
 
 #define BTRFS_LIST_LAYOUT_DEFAULT	0
 #define BTRFS_LIST_LAYOUT_TABLE	1
+#define BTRFS_LIST_LAYOUT_RAW		2
 
 /*
  * one of these for each root we find.
@@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-			int is_tab_result);
+			int layout, char *raw_prefix);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index dd677f7..7e5e28c 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -24,6 +24,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
+#include <uuid/uuid.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
 
 	if (is_tab_result)
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_TABLE);
+				BTRFS_LIST_LAYOUT_TABLE, NULL);
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_DEFAULT);
+				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
-		BTRFS_LIST_LAYOUT_DEFAULT);
+		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -721,6 +722,174 @@ static int cmd_find_new(int argc, char **argv)
 	return 0;
 }
 
+static const char * const cmd_subvol_show_usage[] = {
+	"btrfs subvolume show <subvol-path>",
+	"Show more information of the subvolume",
+	NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+	struct root_info get_ri;
+	struct btrfs_list_filter_set *filter_set;
+	char tstr[256];
+	char uuidparse[37];
+	char *fullpath, *svpath, *mnt = NULL;
+	char raw_prefix[] = "\t\t\t\t";
+	u64 sv_id, mntid;
+	int fd, mntfd;
+	int ret;
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_subvol_show_usage);
+
+	fullpath = realpath(argv[1],0);
+	if(!fullpath) {
+		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
+			argv[1], strerror(errno));
+		return 1;
+	}
+	ret = test_issubvolume(fullpath);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
+		free(fullpath);
+		return 1;
+	}
+	if (!ret) {
+		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
+		free(fullpath);
+		return 1;
+	}
+
+	ret = find_mount_root(fullpath, &mnt);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
+				"%s\n", fullpath, strerror(-ret));
+		free(fullpath);
+		return 1;
+	}
+
+	svpath = get_subvol_name(mnt, fullpath);
+
+	fd = open_file_or_dir(fullpath);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
+		free(mnt);
+		free(fullpath);
+		return 1;
+	}
+	sv_id = btrfs_list_get_path_rootid(fd);
+
+	mntfd = open_file_or_dir(mnt);
+	if (mntfd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
+		close(fd);
+		free(mnt);
+		free(fullpath);
+		return 1;
+	}
+	mntid = btrfs_list_get_path_rootid(mntfd);
+
+	if (sv_id == 5) {
+		printf("%s is btrfs root\n", fullpath);
+		close(fd);
+		close(mntfd);
+		free(mnt);
+		free(fullpath);
+		return 1;
+	}
+
+	memset(&get_ri, 0, sizeof(get_ri));
+	get_ri.root_id = sv_id;
+
+	if (btrfs_get_subvol(mntfd, &get_ri)) {
+		fprintf(stderr, "ERROR: can't find '%s'\n",
+			svpath);
+		close(fd);
+		close(mntfd);
+		free(fullpath);
+		free(mnt);
+		return 1;
+	}
+
+	/* print the info */
+	printf("%s", fullpath);
+	printf("\n");
+
+	printf("\t");
+	printf("Name: \t\t\t%s", get_ri.name);
+	printf("\n");
+
+	if (uuid_is_null(get_ri.uuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.uuid, uuidparse);
+	printf("\t");
+	printf("uuid: \t\t\t%s", uuidparse);
+	printf("\n");
+
+        if (uuid_is_null(get_ri.puuid))
+                strcpy(uuidparse, "-");
+        else
+                uuid_unparse(get_ri.puuid, uuidparse);
+	printf("\t");
+	printf("Parent uuid: \t\t%s", uuidparse);
+	printf("\n");
+
+	if (get_ri.otime)
+		strftime(tstr, 256, "%Y-%m-%d %X",
+			 localtime(&get_ri.otime));
+	else
+		strcpy(tstr, "-");
+	printf("\t");
+	printf("Creation time: \t\t%s", tstr);
+	printf("\n");
+
+	printf("\t");
+	printf("Object ID: \t\t%llu", get_ri.root_id);
+	printf("\n");
+
+	printf("\t");
+	printf("Generation (Gen): \t%llu", get_ri.gen);
+	printf("\n");
+
+	printf("\t");
+	printf("Gen at creation: \t%llu", get_ri.ogen);
+	printf("\n");
+
+	printf("\t");
+	printf("Parent: \t\t%llu", get_ri.ref_tree);
+	printf("\n");
+
+	printf("\t");
+	printf("Top Level: \t\t%llu", get_ri.top_id);
+	printf("\n");
+
+	/* print the snapshots of the given subvol if any*/
+	printf("\t");
+	printf("Snapshot(s):\n");
+	filter_set = btrfs_list_alloc_filter_set();
+	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
+				get_ri.uuid);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
+			raw_prefix);
+
+	/* clean up */
+	if (get_ri.path)
+		free(get_ri.path);
+	if (get_ri.name)
+		free(get_ri.name);
+	if (get_ri.full_path)
+		free(get_ri.full_path);
+
+	close(fd);
+	close(mntfd);
+	free(mnt);
+	free(fullpath);
+	return 0;
+}
+
 const struct cmd_group subvolume_cmd_group = {
 	subvolume_cmd_group_usage, NULL, {
 		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -732,6 +901,7 @@ const struct cmd_group subvolume_cmd_group = {
 		{ "set-default", cmd_subvol_set_default,
 			cmd_subvol_set_default_usage, NULL, 0 },
 		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
+		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
 	}
 };
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 9222580..57c25b0 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
 .PP
+\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
 [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
 [<\fIfile\fR>|<\fIdir\fR>...]
@@ -160,6 +162,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
 is similar to \fBsubvolume list\fR command.
 .TP
 
+\fBsubvolume show\fR\fI <path>\fR
+Show information of a given subvolume in the \fI<path>\fR.
+.TP
+
 \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
 [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
 
-- 
1.8.1.227.g44fe835


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

* Re: [PATCH 00/10] add show sub-command for btrfs subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (9 preceding siblings ...)
  2013-01-23  8:12   ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
@ 2013-01-23 21:57   ` Gene Czarcinski
  2013-01-24  4:11     ` Anand Jain
  2013-01-24 20:52   ` Gene Czarcinski
                     ` (16 subsequent siblings)
  27 siblings, 1 reply; 131+ messages in thread
From: Gene Czarcinski @ 2013-01-23 21:57 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba

On 01/23/2013 03:12 AM, Anand Jain wrote:
> David, Gene
>
> Please accept this patch set which is on top of
>    git://repo.or.cz/btrfs-progs-unstable/devel.git for-chris
Oops.  I am sorry to rain on your parade but the patches need another 
rebasing.  The ones in "for-chris" are the original set of patches David 
pulled together.  The bigger list is in the "integration-20130121" 
branch and your current version does not apply.

However, you may want to wait a bit as David has a few more patches he  
is working on.  Also, one of the new (not in for-chris) patches has a 
conflict with another patch in the first set.

Gene
>
> to add 'show' sub-command feature for the btrfs subvol cli
> as in an example below..
>
> eg:
> btrfs su list /mnt
> ID 256 gen 54 top level 5 path sv1
> ID 278 gen 56 top level 5 path sv1/snap1
> ID 279 gen 54 top level 5 path sv2
> ID 280 gen 41 top level 5 path sv2/snap1
>
> btrfs su show /mnt/sv1
> /mnt/sv1
> 	Name: 			sv1
> 	uuid: 			3a914db2-8a40-1e49-9382-126c595e9abf
> 	Parent uuid: 		-
> 	Creation time: 		2013-01-10 12:16:18
> 	Object ID: 		256
> 	Generation (Gen): 	54
> 	Gen at creation: 	5
> 	Parent: 		5
> 	Top Level: 		5
> 	Snapshot(s):
> 				snap1
> 				<FS_TREE>/sv2/snap_sv1
>
> Anand Jain (10):
>    Btrfs-progs: move open_file_or_dir() to utils.c
>    Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
>    Btrfs-progs: add parent uuid for snapshots
>    Btrfs-progs: move struct root_info to btrfs-list.h
>    Btrfs-progs: add function btrfs_get_subvol to get root_info of a
>      subvol
>    Btrfs-progs: add method to filter snapshots by parent uuid
>    Btrfs-progs: put find_mount_root() in commands.h
>    Btrfs-progs: make printing subvol extensible to newer layouts
>    Btrfs-progs: make get_subvol_name non cmds-send specific
>    Btrfs-progs: add show subcommand to subvol cli
>
>   Makefile         |   4 +-
>   btrfs-list.c     | 190 +++++++++++++++++++++++++++++++++-------------------
>   btrfs-list.h     |  58 +++++++++++++++-
>   btrfsctl.c       |   7 +-
>   cmds-balance.c   |   1 +
>   cmds-inspect.c   |   1 +
>   cmds-qgroup.c    |   1 +
>   cmds-quota.c     |   1 +
>   cmds-send.c      |  12 ++--
>   cmds-subvolume.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
>   commands.h       |   7 +-
>   common.c         |  46 -------------
>   man/btrfs.8.in   |   6 ++
>   utils.c          |  30 ++++++++-
>   utils.h          |   3 +
>   15 files changed, 428 insertions(+), 139 deletions(-)
>   delete mode 100644 common.c
>


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

* Re: [PATCH 00/10] add show sub-command for btrfs subvol cli
  2013-01-23 21:57   ` [PATCH 00/10] add show sub-command for btrfs " Gene Czarcinski
@ 2013-01-24  4:11     ` Anand Jain
  0 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-24  4:11 UTC (permalink / raw)
  To: Gene Czarcinski; +Cc: linux-btrfs, dsterba



> However, you may want to wait a bit as David has a few more patches he
> is working on.  Also, one of the new (not in for-chris) patches has a
> conflict with another patch in the first set.

  Pls let me know when David's repo is ready for the rebase
  so that I can resolve conflicts with this patch-set.

-Anand

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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-23  8:12   ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
@ 2013-01-24  4:39     ` Eric Sandeen
  2013-01-24  9:23       ` Stefan Behrens
  2013-01-25  9:21       ` Anand Jain
  0 siblings, 2 replies; 131+ messages in thread
From: Eric Sandeen @ 2013-01-24  4:39 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba, gene

On 1/23/13 2:12 AM, Anand Jain wrote:
> The definition of the function open_file_or_dir() is moved from common.c
> to utils.c in order to be able to share some common code between scrub
> and the device stats in the following step. That common code uses
> open_file_or_dir(). Since open_file_or_dir() makes use of the function
> dirfd(3), the required XOPEN version was raised from 6 to 7.
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> Original-Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>

Cool, I had this on my stack too.  But can you maybe remove the
nonsensical return values, and instead of renaming & keeping the btrfsctl.c
copy, why not just use a common copy in utils.c?  It'd just be 2 checks
for fd < 0 in the btrfsctl callers.

Thanks,
-Eric

> ---
>  Makefile         |  4 ++--
>  btrfsctl.c       |  7 ++++---
>  cmds-balance.c   |  1 +
>  cmds-inspect.c   |  1 +
>  cmds-qgroup.c    |  1 +
>  cmds-quota.c     |  1 +
>  cmds-subvolume.c |  1 +
>  commands.h       |  3 ---
>  common.c         | 46 ----------------------------------------------
>  utils.c          | 30 ++++++++++++++++++++++++++++--
>  utils.h          |  3 +++
>  11 files changed, 42 insertions(+), 56 deletions(-)
>  delete mode 100644 common.c
> 
> diff --git a/Makefile b/Makefile
> index 4894903..8576d90 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -41,8 +41,8 @@ all: version $(progs) manpages
>  version:
>  	bash version.sh
>  
> -btrfs: $(objects) btrfs.o help.o common.o $(cmds_objects)
> -	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o common.o $(cmds_objects) \
> +btrfs: $(objects) btrfs.o help.o $(cmds_objects)
> +	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o $(cmds_objects) \
>  		$(objects) $(LDFLAGS) $(LIBS) -lpthread
>  
>  calc-size: $(objects) calc-size.o
> diff --git a/btrfsctl.c b/btrfsctl.c
> index 518684c..049a5f3 100644
> --- a/btrfsctl.c
> +++ b/btrfsctl.c
> @@ -63,7 +63,7 @@ static void print_usage(void)
>  	exit(1);
>  }
>  
> -static int open_file_or_dir(const char *fname)
> +static int btrfsctl_open_file_or_dir(const char *fname)
>  {
>  	int ret;
>  	struct stat st;
> @@ -91,6 +91,7 @@ static int open_file_or_dir(const char *fname)
>  	}
>  	return fd;
>  }
> +
>  int main(int ac, char **av)
>  {
>  	char *fname = NULL;
> @@ -128,7 +129,7 @@ int main(int ac, char **av)
>  			snap_location = strdup(fullpath);
>  			snap_location = dirname(snap_location);
>  
> -			snap_fd = open_file_or_dir(snap_location);
> +			snap_fd = btrfsctl_open_file_or_dir(snap_location);
>  
>  			name = strdup(fullpath);
>  			name = basename(name);
> @@ -238,7 +239,7 @@ int main(int ac, char **av)
>  		}
>  		name = fname;
>  	 } else {
> -		fd = open_file_or_dir(fname);
> +		fd = btrfsctl_open_file_or_dir(fname);
>  	 }
>  
>  	if (name) {
> diff --git a/cmds-balance.c b/cmds-balance.c
> index 38a7426..6268b61 100644
> --- a/cmds-balance.c
> +++ b/cmds-balance.c
> @@ -28,6 +28,7 @@
>  #include "volumes.h"
>  
>  #include "commands.h"
> +#include "utils.h"
>  
>  static const char * const balance_cmd_group_usage[] = {
>  	"btrfs [filesystem] balance <command> [options] <path>",
> diff --git a/cmds-inspect.c b/cmds-inspect.c
> index edabff5..79e069b 100644
> --- a/cmds-inspect.c
> +++ b/cmds-inspect.c
> @@ -22,6 +22,7 @@
>  
>  #include "kerncompat.h"
>  #include "ioctl.h"
> +#include "utils.h"
>  
>  #include "commands.h"
>  #include "btrfs-list.h"
> diff --git a/cmds-qgroup.c b/cmds-qgroup.c
> index 1525c11..cafc284 100644
> --- a/cmds-qgroup.c
> +++ b/cmds-qgroup.c
> @@ -24,6 +24,7 @@
>  #include "ioctl.h"
>  
>  #include "commands.h"
> +#include "utils.h"
>  
>  static const char * const qgroup_cmd_group_usage[] = {
>  	"btrfs qgroup <command> [options] <path>",
> diff --git a/cmds-quota.c b/cmds-quota.c
> index cf9ad97..8481514 100644
> --- a/cmds-quota.c
> +++ b/cmds-quota.c
> @@ -23,6 +23,7 @@
>  #include "ioctl.h"
>  
>  #include "commands.h"
> +#include "utils.h"
>  
>  static const char * const quota_cmd_group_usage[] = {
>  	"btrfs quota <command> [options] <path>",
> diff --git a/cmds-subvolume.c b/cmds-subvolume.c
> index ac39f7b..e3cdb1e 100644
> --- a/cmds-subvolume.c
> +++ b/cmds-subvolume.c
> @@ -32,6 +32,7 @@
>  #include "ctree.h"
>  #include "commands.h"
>  #include "btrfs-list.h"
> +#include "utils.h"
>  
>  static const char * const subvolume_cmd_group_usage[] = {
>  	"btrfs subvolume <command> <args>",
> diff --git a/commands.h b/commands.h
> index bb6d2dd..8114a73 100644
> --- a/commands.h
> +++ b/commands.h
> @@ -79,9 +79,6 @@ void help_ambiguous_token(const char *arg, const struct cmd_group *grp);
>  
>  void help_command_group(const struct cmd_group *grp, int argc, char **argv);
>  
> -/* common.c */
> -int open_file_or_dir(const char *fname);
> -
>  extern const struct cmd_group subvolume_cmd_group;
>  extern const struct cmd_group filesystem_cmd_group;
>  extern const struct cmd_group balance_cmd_group;
> diff --git a/common.c b/common.c
> deleted file mode 100644
> index 03f6570..0000000
> --- a/common.c
> +++ /dev/null
> @@ -1,46 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public
> - * License v2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public
> - * License along with this program; if not, write to the
> - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> - * Boston, MA 021110-1307, USA.
> - */
> -
> -#include <sys/types.h>
> -#include <sys/stat.h>
> -#include <dirent.h>
> -#include <fcntl.h>
> -
> -int open_file_or_dir(const char *fname)
> -{
> -	int ret;
> -	struct stat st;
> -	DIR *dirstream;
> -	int fd;
> -
> -	ret = stat(fname, &st);
> -	if (ret < 0) {
> -		return -1;
> -	}
> -	if (S_ISDIR(st.st_mode)) {
> -		dirstream = opendir(fname);
> -		if (!dirstream) {
> -			return -2;
> -		}
> -		fd = dirfd(dirstream);
> -	} else {
> -		fd = open(fname, O_RDWR);
> -	}
> -	if (fd < 0) {
> -		return -3;
> -	}
> -	return fd;
> -}
> diff --git a/utils.c b/utils.c
> index 205e667..774f81d 100644
> --- a/utils.c
> +++ b/utils.c
> @@ -16,8 +16,9 @@
>   * Boston, MA 021110-1307, USA.
>   */
>  
> -#define _XOPEN_SOURCE 600
> -#define __USE_XOPEN2K
> +#define _XOPEN_SOURCE 700
> +#define __USE_XOPEN2K8
> +#define __XOPEN2K8 /* due to an error in dirent.h, to get dirfd() */
>  #include <stdio.h>
>  #include <stdlib.h>
>  #ifndef __CHECKER__
> @@ -1220,3 +1221,28 @@ scan_again:
>  	return 0;
>  }
>  
> +int open_file_or_dir(const char *fname)
> +{
> +	int ret;
> +	struct stat st;
> +	DIR *dirstream;
> +	int fd;
> +
> +	ret = stat(fname, &st);
> +	if (ret < 0) {
> +		return -1;
> +	}
> +	if (S_ISDIR(st.st_mode)) {
> +		dirstream = opendir(fname);
> +		if (!dirstream) {
> +			return -2;
> +		}
> +		fd = dirfd(dirstream);
> +	} else {
> +		fd = open(fname, O_RDWR);
> +	}
> +	if (fd < 0) {
> +		return -3;
> +	}
> +	return fd;
> +}
> diff --git a/utils.h b/utils.h
> index 3a0368b..6975f10 100644
> --- a/utils.h
> +++ b/utils.h
> @@ -19,6 +19,8 @@
>  #ifndef __UTILS__
>  #define __UTILS__
>  
> +#include "ctree.h"
> +
>  #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024)
>  
>  int make_btrfs(int fd, const char *device, const char *label,
> @@ -46,4 +48,5 @@ int check_label(char *input);
>  int get_mountpt(char *dev, char *mntpt, size_t size);
>  
>  int btrfs_scan_block_devices(int run_ioctl);
> +int open_file_or_dir(const char *fname);
>  #endif
> 


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

* Re: [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-23  8:12   ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-01-24  4:49     ` Eric Sandeen
  2013-01-25  9:20       ` Anand Jain
  0 siblings, 1 reply; 131+ messages in thread
From: Eric Sandeen @ 2013-01-24  4:49 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba, gene

On 1/23/13 2:12 AM, Anand Jain wrote:
> We need a function which can get the root_info of a given
> subvol. This is in preparation to add support for the show
> sub-cli.
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
>  btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
>  btrfs-list.h |  1 +
>  2 files changed, 39 insertions(+)
> 
> diff --git a/btrfs-list.c b/btrfs-list.c
> index 1851f3e..ec64a36 100644
> --- a/btrfs-list.c
> +++ b/btrfs-list.c
> @@ -1455,6 +1455,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  	return 0;
>  }
>  
> +int btrfs_get_subvol(int fd, struct root_info *the_ri)
> +{
> +	int ret = -1;
> +	struct root_lookup rl;
> +	struct rb_node *rbn;
> +	struct root_info *ri;
> +	u64 root_id = btrfs_list_get_path_rootid(fd);
> +
> +	if (btrfs_list_subvols(fd, &rl))
> +		return 13;

Unless there is an ongoing plan to actually do something with these
magical returns, can we maybe just be normal about error return values
in new code?

The caller you add only cares about 0 or not, right?  Or is there some other
purpose for "13" I'm not aware of?

Thanks,
-Eric

> +	rbn = rb_first(&rl.root);
> +	while(rbn) {
> +		ri = rb_entry(rbn, struct root_info, rb_node);
> +		resolve_root(&rl, ri, root_id);
> +		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
> +			memcpy(the_ri, ri, offsetof(struct root_info, path));
> +			if (ri->path)
> +				the_ri->path = strdup(ri->path);
> +			else
> +				the_ri->path = NULL;
> +			if (ri->name)
> +				the_ri->name = strdup(ri->name);
> +			else
> +				the_ri->name = NULL;
> +			if (ri->full_path)
> +				the_ri->full_path = strdup(ri->full_path);
> +			else
> +				the_ri->name = NULL;
> +			ret = 0;
> +			break;
> +		}
> +		rbn = rb_next(rbn);
> +	}
> +	__free_all_subvolumn(&rl);
> +	return ret;
> +}
> +
>  static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
>  			    struct btrfs_file_extent_item *item,
>  			    u64 found_gen, u64 *cache_dirid,
> diff --git a/btrfs-list.h b/btrfs-list.h
> index 3b7b680..580d4d1 100644
> --- a/btrfs-list.h
> +++ b/btrfs-list.h
> @@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
>  int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
>  char *btrfs_list_path_for_root(int fd, u64 root);
>  u64 btrfs_list_get_path_rootid(int fd);
> +int btrfs_get_subvol(int fd, struct root_info *the_ri);
> 


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

* Re: [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-23  8:12   ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
@ 2013-01-24  5:06     ` Eric Sandeen
  2013-01-24 19:42       ` Zach Brown
  2013-01-25  9:24       ` Anand Jain
  0 siblings, 2 replies; 131+ messages in thread
From: Eric Sandeen @ 2013-01-24  5:06 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba, gene

On 1/23/13 2:12 AM, Anand Jain wrote:
> This adds show sub-command to the btrfs subvol cli
> to display detailed inforamtion of the given subvol
> or snapshot.

Couple things below.

> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
>  btrfs-list.c     |  25 +++++++-
>  btrfs-list.h     |   3 +-
>  cmds-subvolume.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  man/btrfs.8.in   |   6 ++
>  4 files changed, 203 insertions(+), 7 deletions(-)
> 
> diff --git a/btrfs-list.c b/btrfs-list.c
> index 71f7239..5be3ed9 100644
> --- a/btrfs-list.c
> +++ b/btrfs-list.c
> @@ -1337,6 +1337,22 @@ static void print_subvolume_column(struct root_info *subv,
>  	}
>  }
>  
> +static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
> +{
> +	int i;
> +
> +	for (i = 0; i < BTRFS_LIST_ALL; i++) {
> +		if (!btrfs_list_columns[i].need_print)
> +			continue;
> +
> +		if(raw_prefix);

That semicolon will eventually make you sad, I bet.  ;)
And while you're at it, please add the space after "if?"

> +			printf("%s",raw_prefix);
> +
> +		print_subvolume_column(subv, i);
> +	}
> +	printf("\n");
> +}
> +
>  static void print_single_volume_info_table(struct root_info *subv)
>  {
>  	int i;
> @@ -1403,7 +1419,7 @@ static void print_all_volume_info_tab_head()
>  }
>  
>  static void print_all_volume_info(struct root_lookup *sorted_tree,
> -				  int layout)
> +				  int layout, char *raw_prefix)
>  {
>  	struct rb_node *n;
>  	struct root_info *entry;
> @@ -1421,6 +1437,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
>  		case BTRFS_LIST_LAYOUT_TABLE:
>  			print_single_volume_info_table(entry);
>  			break;
> +		case BTRFS_LIST_LAYOUT_RAW:
> +			print_single_volume_info_raw(entry, raw_prefix);
> +			break;
>  		}
>  		n = rb_next(n);
>  	}
> @@ -1447,7 +1466,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
>  
>  int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  		       struct btrfs_list_comparer_set *comp_set,
> -		       int layout)
> +		       int layout, char *raw_prefix)
>  {
>  	struct root_lookup root_lookup;
>  	struct root_lookup root_sort;
> @@ -1459,7 +1478,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
>  				 comp_set, fd);
>  
> -	print_all_volume_info(&root_sort, layout);
> +	print_all_volume_info(&root_sort, layout, raw_prefix);
>  	__free_all_subvolumn(&root_lookup);
>  
>  	return 0;
> diff --git a/btrfs-list.h b/btrfs-list.h
> index 5b60068..09d35f7 100644
> --- a/btrfs-list.h
> +++ b/btrfs-list.h
> @@ -20,6 +20,7 @@
>  
>  #define BTRFS_LIST_LAYOUT_DEFAULT	0
>  #define BTRFS_LIST_LAYOUT_TABLE	1
> +#define BTRFS_LIST_LAYOUT_RAW		2
>  
>  /*
>   * one of these for each root we find.
> @@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
>  
>  int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  		       struct btrfs_list_comparer_set *comp_set,
> -			int is_tab_result);
> +			int layout, char *raw_prefix);
>  int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
>  int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
>  char *btrfs_list_path_for_root(int fd, u64 root);
> diff --git a/cmds-subvolume.c b/cmds-subvolume.c
> index dd677f7..7e5e28c 100644
> --- a/cmds-subvolume.c
> +++ b/cmds-subvolume.c
> @@ -24,6 +24,7 @@
>  #include <libgen.h>
>  #include <limits.h>
>  #include <getopt.h>
> +#include <uuid/uuid.h>
>  
>  #include "kerncompat.h"
>  #include "ioctl.h"
> @@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
>  
>  	if (is_tab_result)
>  		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
> -				BTRFS_LIST_LAYOUT_TABLE);
> +				BTRFS_LIST_LAYOUT_TABLE, NULL);
>  	else
>  		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
> -				BTRFS_LIST_LAYOUT_DEFAULT);
> +				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
>  	if (ret)
>  		return 19;
>  	return 0;
> @@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
>  	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
>  
>  	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
> -		BTRFS_LIST_LAYOUT_DEFAULT);
> +		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
>  	if (ret)
>  		return 19;
>  	return 0;
> @@ -721,6 +722,174 @@ static int cmd_find_new(int argc, char **argv)
>  	return 0;
>  }
>  
> +static const char * const cmd_subvol_show_usage[] = {
> +	"btrfs subvolume show <subvol-path>",
> +	"Show more information of the subvolume",
> +	NULL
> +};
> +
> +static int cmd_subvol_show(int argc, char **argv)
> +{
> +	struct root_info get_ri;
> +	struct btrfs_list_filter_set *filter_set;
> +	char tstr[256];
> +	char uuidparse[37];
> +	char *fullpath, *svpath, *mnt = NULL;
> +	char raw_prefix[] = "\t\t\t\t";
> +	u64 sv_id, mntid;
> +	int fd, mntfd;
> +	int ret;
> +
> +	if (check_argc_exact(argc, 2))
> +		usage(cmd_subvol_show_usage);
> +
> +	fullpath = realpath(argv[1],0);
> +	if(!fullpath) {

ideally "if (!fullpath)" with the space...

> +		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
> +			argv[1], strerror(errno));
> +		return 1;
> +	}
> +	ret = test_issubvolume(fullpath);
> +	if (ret < 0) {
> +		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
> +		free(fullpath);
> +		return 1;
> +	}
> +	if (!ret) {
> +		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
> +		free(fullpath);
> +		return 1;
> +	}
> +
> +	ret = find_mount_root(fullpath, &mnt);
> +	if (ret < 0) {
> +		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
> +				"%s\n", fullpath, strerror(-ret));
> +		free(fullpath);
> +		return 1;
> +	}
> +
> +	svpath = get_subvol_name(mnt, fullpath);
> +
> +	fd = open_file_or_dir(fullpath);
> +	if (fd < 0) {
> +		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
> +		free(mnt);
> +		free(fullpath);
> +		return 1;
> +	}
> +	sv_id = btrfs_list_get_path_rootid(fd);

This could fail, right?

> +	mntfd = open_file_or_dir(mnt);
> +	if (mntfd < 0) {
> +		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
> +		close(fd);
> +		free(mnt);
> +		free(fullpath);
> +		return 1;
> +	}
> +	mntid = btrfs_list_get_path_rootid(mntfd);
> +
> +	if (sv_id == 5) {
> +		printf("%s is btrfs root\n", fullpath);
> +		close(fd);
> +		close(mntfd);
> +		free(mnt);
> +		free(fullpath);
> +		return 1;

Just wondering, at this point might a "goto out;" be cleaner error
handling?  Every error case is getting longer ;)

> +	}
> +
> +	memset(&get_ri, 0, sizeof(get_ri));
> +	get_ri.root_id = sv_id;
> +
> +	if (btrfs_get_subvol(mntfd, &get_ri)) {
> +		fprintf(stderr, "ERROR: can't find '%s'\n",
> +			svpath);
> +		close(fd);
> +		close(mntfd);
> +		free(fullpath);
> +		free(mnt);
> +		return 1;
> +	}
> +
> +	/* print the info */
> +	printf("%s", fullpath);
> +	printf("\n");

maybe   printf("%s\n", fullpath); ?

> +
> +	printf("\t");
> +	printf("Name: \t\t\t%s", get_ri.name);
> +	printf("\n");

and printf("\tName: \t\t\t%s\n", get_ri.name);
etc -
or is there some reason for the single-char-printfs?

> +
> +	if (uuid_is_null(get_ri.uuid))
> +		strcpy(uuidparse, "-");
> +	else
> +		uuid_unparse(get_ri.uuid, uuidparse);
> +	printf("\t");
> +	printf("uuid: \t\t\t%s", uuidparse);
> +	printf("\n");
> +
> +        if (uuid_is_null(get_ri.puuid))
> +                strcpy(uuidparse, "-");
> +        else
> +                uuid_unparse(get_ri.puuid, uuidparse);

s/tabs/spaces/ here?

> +	printf("\t");
> +	printf("Parent uuid: \t\t%s", uuidparse);
> +	printf("\n");
> +
> +	if (get_ri.otime)
> +		strftime(tstr, 256, "%Y-%m-%d %X",
> +			 localtime(&get_ri.otime));
> +	else
> +		strcpy(tstr, "-");
> +	printf("\t");
> +	printf("Creation time: \t\t%s", tstr);
> +	printf("\n");
> +
> +	printf("\t");
> +	printf("Object ID: \t\t%llu", get_ri.root_id);
> +	printf("\n");
> +
> +	printf("\t");
> +	printf("Generation (Gen): \t%llu", get_ri.gen);
> +	printf("\n");
> +
> +	printf("\t");
> +	printf("Gen at creation: \t%llu", get_ri.ogen);
> +	printf("\n");
> +
> +	printf("\t");
> +	printf("Parent: \t\t%llu", get_ri.ref_tree);
> +	printf("\n");
> +
> +	printf("\t");
> +	printf("Top Level: \t\t%llu", get_ri.top_id);
> +	printf("\n");
> +
> +	/* print the snapshots of the given subvol if any*/
> +	printf("\t");
> +	printf("Snapshot(s):\n");
> +	filter_set = btrfs_list_alloc_filter_set();
> +	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
> +				get_ri.uuid);
> +	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
> +	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
> +			raw_prefix);
> +
> +	/* clean up */
> +	if (get_ri.path)
> +		free(get_ri.path);
> +	if (get_ri.name)
> +		free(get_ri.name);
> +	if (get_ri.full_path)
> +		free(get_ri.full_path);
> +
> +	close(fd);
> +	close(mntfd);
> +	free(mnt);
> +	free(fullpath);
> +	return 0;
> +}
> +
>  const struct cmd_group subvolume_cmd_group = {
>  	subvolume_cmd_group_usage, NULL, {
>  		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
> @@ -732,6 +901,7 @@ const struct cmd_group subvolume_cmd_group = {
>  		{ "set-default", cmd_subvol_set_default,
>  			cmd_subvol_set_default_usage, NULL, 0 },
>  		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
> +		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
>  		{ 0, 0, 0, 0, 0 }
>  	}
>  };
> diff --git a/man/btrfs.8.in b/man/btrfs.8.in
> index 9222580..57c25b0 100644
> --- a/man/btrfs.8.in
> +++ b/man/btrfs.8.in
> @@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
>  .PP
>  \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
>  .PP
> +\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
> +.PP
>  \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
>  [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
>  [<\fIfile\fR>|<\fIdir\fR>...]
> @@ -160,6 +162,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
>  is similar to \fBsubvolume list\fR command.
>  .TP
>  
> +\fBsubvolume show\fR\fI <path>\fR
> +Show information of a given subvolume in the \fI<path>\fR.
> +.TP
> +
>  \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
>  [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
>  
> 


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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24  4:39     ` Eric Sandeen
@ 2013-01-24  9:23       ` Stefan Behrens
  2013-01-24 17:57         ` Goffredo Baroncelli
  2013-01-25  9:21       ` Anand Jain
  1 sibling, 1 reply; 131+ messages in thread
From: Stefan Behrens @ 2013-01-24  9:23 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Anand Jain, linux-btrfs, dsterba, gene

On Wed, 23 Jan 2013 22:39:29 -0600, Eric Sandeen wrote:
> instead of renaming & keeping the btrfsctl.c copy

There is a new momentum to improve the Btrfs-progs quality :)

IMO, one step is to get rid of the legacy tools and sources. It wastes
time to maintain them and these old tools cause confusion. btrfsctl.c,
btrfs-vol.c and btrfs-show.c are not needed anymore. Please correct me
if there are plans to use these old tools in future Linux distributions.
The "btrfs" tool replaces the legacy "btrfsctl", "btrfs-vol" and
"btrfs-show" tools. Below, the usage text of the old tools is quoted.
All these tasks are also offered in the "btrfs" tool, and this tool is
the newer one.

Some time ago I sent a patch to remove these legacy tools from the
default build
<http://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg16919.html>.
We should also remove the sources. Any objections against this?

If we don't have btrfsctl.c anymore, we don't need to worry about
open_file_or_dir() in that file. We could either leave Anand's patch as
it is and afterwards remove btrfsctl.c, or remove the file first and
then the open_file_or_dir() patch can be shrunken.

usage: btrfsctl [ -d file|dir] [ -s snap_name subvol|tree ]
                [-r size] [-A device] [-a] [-c] [-D dir .]
        -d filename: defragments one file
        -d directory: defragments the entire Btree
        -s snap_name dir: creates a new snapshot of dir
        -S subvol_name dir: creates a new subvolume
        -r [+-]size[gkm]: resize the FS by size amount
        -A device: scans the device file for a Btrfs filesystem
        -a: scans all devices for Btrfs filesystems
        -c: forces a single FS sync
        -D: delete snapshot
        -m [tree id] directory: set the default mounted subvolume to the
[tree id] or the directory

usage: btrfs-vol [options] mount_point
        -a device add one device
        -b balance chunks across all devices
        -r device remove one device

usage: btrfs-show [search label or device]


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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24  9:23       ` Stefan Behrens
@ 2013-01-24 17:57         ` Goffredo Baroncelli
  2013-01-24 19:42           ` Eric Sandeen
  0 siblings, 1 reply; 131+ messages in thread
From: Goffredo Baroncelli @ 2013-01-24 17:57 UTC (permalink / raw)
  To: Stefan Behrens; +Cc: Eric Sandeen, Anand Jain, linux-btrfs, dsterba, gene

On 01/24/2013 10:23 AM, Stefan Behrens wrote:
> On Wed, 23 Jan 2013 22:39:29 -0600, Eric Sandeen wrote:
>> instead of renaming&  keeping the btrfsctl.c copy
>
> There is a new momentum to improve the Btrfs-progs quality :)
>
> IMO, one step is to get rid of the legacy tools and sources. It wastes
> time to maintain them and these old tools cause confusion. btrfsctl.c,
> btrfs-vol.c and btrfs-show.c are not needed anymore. Please correct me
> if there are plans to use these old tools in future Linux distributions.
> The "btrfs" tool replaces the legacy "btrfsctl", "btrfs-vol" and
> "btrfs-show" tools. Below, the usage text of the old tools is quoted.
> All these tasks are also offered in the "btrfs" tool, and this tool is
> the newer one.

I fully agree: btrfsctl, btrfs-vol, btrfs-show are perfectly replaced by 
by btrfs. Moreover time to time the patches are more complex than the 
needing because exists these "legacy" programs.

I checked the debian package, and to me seems that there is no need of 
{btrfsctl,btrfs-vol,btrfs-show}

BR
Goffredo

-- 
gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5

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

* Re: [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-24  5:06     ` Eric Sandeen
@ 2013-01-24 19:42       ` Zach Brown
  2013-01-24 23:14         ` Chris Mason
  2013-01-25  9:24       ` Anand Jain
  1 sibling, 1 reply; 131+ messages in thread
From: Zach Brown @ 2013-01-24 19:42 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: Anand Jain, linux-btrfs, dsterba, gene


> > +	if (sv_id == 5) {
> > +		printf("%s is btrfs root\n", fullpath);
> > +		close(fd);
> > +		close(mntfd);
> > +		free(mnt);
> > +		free(fullpath);
> > +		return 1;
> 
> Just wondering, at this point might a "goto out;" be cleaner error
> handling?  Every error case is getting longer ;)

No wondering needed!  This pattern is a source of bugs.  I'm hitting
cases in the static analysis reports of people adding return paths
without recognizing the pile of state they're expected to cleanup.

Use safe unwinding in one exit path at the end, please.  It's less
maddening to audit and less likely to fail over time.

- z

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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24 17:57         ` Goffredo Baroncelli
@ 2013-01-24 19:42           ` Eric Sandeen
  2013-01-24 22:09             ` Goffredo Baroncelli
  2013-01-25 15:19             ` Eric Sandeen
  0 siblings, 2 replies; 131+ messages in thread
From: Eric Sandeen @ 2013-01-24 19:42 UTC (permalink / raw)
  To: kreijack
  Cc: Goffredo Baroncelli, Stefan Behrens, Anand Jain, linux-btrfs,
	dsterba, gene

On 1/24/13 11:57 AM, Goffredo Baroncelli wrote:
> On 01/24/2013 10:23 AM, Stefan Behrens wrote:
>> On Wed, 23 Jan 2013 22:39:29 -0600, Eric Sandeen wrote:
>>> instead of renaming&  keeping the btrfsctl.c copy
>>
>> There is a new momentum to improve the Btrfs-progs quality :)
>>
>> IMO, one step is to get rid of the legacy tools and sources. It wastes
>> time to maintain them and these old tools cause confusion. btrfsctl.c,
>> btrfs-vol.c and btrfs-show.c are not needed anymore. Please correct me
>> if there are plans to use these old tools in future Linux distributions.
>> The "btrfs" tool replaces the legacy "btrfsctl", "btrfs-vol" and
>> "btrfs-show" tools. Below, the usage text of the old tools is quoted.
>> All these tasks are also offered in the "btrfs" tool, and this tool is
>> the newer one.
> 
> I fully agree: btrfsctl, btrfs-vol, btrfs-show are perfectly replaced by by btrfs. Moreover time to time the patches are more complex than the needing because exists these "legacy" programs.
> 
> I checked the debian package, and to me seems that there is no need of {btrfsctl,btrfs-vol,btrfs-show}

Hm, they are shipped in the Fedora package.

For backwards compat, could those be turned into shell scripts which invoke the btrfs tool?

-Eric

> BR
> Goffredo
> 


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

* Re: [PATCH 00/10] add show sub-command for btrfs subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (10 preceding siblings ...)
  2013-01-23 21:57   ` [PATCH 00/10] add show sub-command for btrfs " Gene Czarcinski
@ 2013-01-24 20:52   ` Gene Czarcinski
  2013-01-25  9:23     ` Anand Jain
  2013-01-25  9:19   ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
                     ` (15 subsequent siblings)
  27 siblings, 1 reply; 131+ messages in thread
From: Gene Czarcinski @ 2013-01-24 20:52 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba

On 01/23/2013 03:12 AM, Anand Jain wrote:
> Please accept this patch set which is on top of
>    git://repo.or.cz/btrfs-progs-unstable/devel.git for-chris
>
> to add 'show' sub-command feature for the btrfs subvol cli
> as in an example below..
OK, in spite of saying that these patches did not apply clean, it was 
not terribly difficult to refit what did not apply.  I did this in two 
steps:

1. I created the equivalent of the for-chris branch.  This did not apply 
clean which surprised me.  However, minor things easily handled manually 
in the first patch for utils.c and utils.h plus btrfs-lists.c in a later 
patch.

2. After creating a new set of patches from the above effort, I then 
moved to my working branch with includes all of the patches in the 
integration-20130121 branch [careful, patch 0023 has a conflict in 
mkfs.c] please others.  This time it was a very small problem in 
cmds-qgroup.c.  I am running it now.

Gene

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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24 19:42           ` Eric Sandeen
@ 2013-01-24 22:09             ` Goffredo Baroncelli
  2013-01-24 22:36               ` Chris Mason
  2013-01-25 16:14               ` Eric Sandeen
  2013-01-25 15:19             ` Eric Sandeen
  1 sibling, 2 replies; 131+ messages in thread
From: Goffredo Baroncelli @ 2013-01-24 22:09 UTC (permalink / raw)
  To: Eric Sandeen
  Cc: kreijack, Goffredo Baroncelli, Stefan Behrens, Anand Jain,
	linux-btrfs, dsterba, gene

On 01/24/2013 08:42 PM, Eric Sandeen wrote:
> On 1/24/13 11:57 AM, Goffredo Baroncelli wrote:
>> On 01/24/2013 10:23 AM, Stefan Behrens wrote:
>>> On Wed, 23 Jan 2013 22:39:29 -0600, Eric Sandeen wrote:
>>>> instead of renaming&   keeping the btrfsctl.c copy
>>>
>>> There is a new momentum to improve the Btrfs-progs quality :)
>>>
>>> IMO, one step is to get rid of the legacy tools and sources. It
>>> wastes time to maintain them and these old tools cause confusion.
>>> btrfsctl.c, btrfs-vol.c and btrfs-show.c are not needed anymore.
>>> Please correct me if there are plans to use these old tools in
>>> future Linux distributions. The "btrfs" tool replaces the legacy
>>> "btrfsctl", "btrfs-vol" and "btrfs-show" tools. Below, the usage
>>> text of the old tools is quoted. All these tasks are also offered
>>> in the "btrfs" tool, and this tool is the newer one.
>>
>> I fully agree: btrfsctl, btrfs-vol, btrfs-show are perfectly
>> replaced by by btrfs. Moreover time to time the patches are more
>> complex than the needing because exists these "legacy" programs.
>>
>> I checked the debian package, and to me seems that there is no need
>> of {btrfsctl,btrfs-vol,btrfs-show}
>
> Hm, they are shipped in the Fedora package.

The same is true for the debian package, but are these used in Fedora ?

>
> For backwards compat, could those be turned into shell scripts which
> invoke the btrfs tool?

I don't see any gain to maintains a script bash (which has to be written 
from scratch) instead of maintains the current C code.

These programs were deprecated two years ago [1]. If some distribution 
need them, could maintain them as separate patch. But I think that the 
mainstream should remove.



>
> -Eric
>
>> BR Goffredo
>>
>
>


[1] $ git log 002d021c^..002d021c
commit 002d021c5f2d838394e850e304546ffad283518a
Author: Goffredo Baroncelli <kreijack@libero.it>
Date:   Sun Dec 5 17:47:36 2010 +0000

     Deprecate btrfsctl, btrfs-show, btrfs-vol

     Hi all,

     the patch below deprecates the following programs

     * btrfsctl
     * btrfs-vol
     * btrfs-show

     the reason is simple, these programs are superseded by the btrfs 
utility,
     both in terms of documentation, usability and bug. The goal is to avoid
     to duplicate codes and avoid update two programs.

     The patch adds a warning in the man pages, in the INSTALL file and 
in the
     programs.
[...]

-- 
gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5

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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24 22:09             ` Goffredo Baroncelli
@ 2013-01-24 22:36               ` Chris Mason
  2013-01-24 22:49                 ` David Sterba
  2013-01-24 22:52                 ` Avi Miller
  2013-01-25 16:14               ` Eric Sandeen
  1 sibling, 2 replies; 131+ messages in thread
From: Chris Mason @ 2013-01-24 22:36 UTC (permalink / raw)
  To: kreijack
  Cc: Eric Sandeen, Goffredo Baroncelli, Stefan Behrens, Anand Jain,
	linux-btrfs, dsterba, gene

On Thu, Jan 24, 2013 at 03:09:53PM -0700, Goffredo Baroncelli wrote:
> On 01/24/2013 08:42 PM, Eric Sandeen wrote:
> > On 1/24/13 11:57 AM, Goffredo Baroncelli wrote:
> >> On 01/24/2013 10:23 AM, Stefan Behrens wrote:
> >>> On Wed, 23 Jan 2013 22:39:29 -0600, Eric Sandeen wrote:
> >>>> instead of renaming&   keeping the btrfsctl.c copy
> >>>
> >>> There is a new momentum to improve the Btrfs-progs quality :)
> >>>
> >>> IMO, one step is to get rid of the legacy tools and sources. It
> >>> wastes time to maintain them and these old tools cause confusion.
> >>> btrfsctl.c, btrfs-vol.c and btrfs-show.c are not needed anymore.
> >>> Please correct me if there are plans to use these old tools in
> >>> future Linux distributions. The "btrfs" tool replaces the legacy
> >>> "btrfsctl", "btrfs-vol" and "btrfs-show" tools. Below, the usage
> >>> text of the old tools is quoted. All these tasks are also offered
> >>> in the "btrfs" tool, and this tool is the newer one.
> >>
> >> I fully agree: btrfsctl, btrfs-vol, btrfs-show are perfectly
> >> replaced by by btrfs. Moreover time to time the patches are more
> >> complex than the needing because exists these "legacy" programs.
> >>
> >> I checked the debian package, and to me seems that there is no need
> >> of {btrfsctl,btrfs-vol,btrfs-show}
> >
> > Hm, they are shipped in the Fedora package.
> 
> The same is true for the debian package, but are these used in Fedora ?
> 
> >
> > For backwards compat, could those be turned into shell scripts which
> > invoke the btrfs tool?
> 
> I don't see any gain to maintains a script bash (which has to be written 
> from scratch) instead of maintains the current C code.
> 
> These programs were deprecated two years ago [1]. If some distribution 
> need them, could maintain them as separate patch. But I think that the 
> mainstream should remove.

I'd say that if SuSE or oracle depend on them we keep them.  Otherwise,
I'm fine with removing them or just making the 3 line bash script.

-chris


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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24 22:36               ` Chris Mason
@ 2013-01-24 22:49                 ` David Sterba
  2013-01-24 22:52                 ` Avi Miller
  1 sibling, 0 replies; 131+ messages in thread
From: David Sterba @ 2013-01-24 22:49 UTC (permalink / raw)
  To: Chris Mason, kreijack, Eric Sandeen, Goffredo Baroncelli,
	Stefan Behrens, Anand Jain, linux-btrfs, dsterba, gene

On Thu, Jan 24, 2013 at 05:36:52PM -0500, Chris Mason wrote:
> On Thu, Jan 24, 2013 at 03:09:53PM -0700, Goffredo Baroncelli wrote:
> > The same is true for the debian package, but are these used in Fedora ?
> > > For backwards compat, could those be turned into shell scripts which
> > > invoke the btrfs tool?
> > 
> > I don't see any gain to maintains a script bash (which has to be written 
> > from scratch) instead of maintains the current C code.
> > 
> > These programs were deprecated two years ago [1]. If some distribution 
> > need them, could maintain them as separate patch. But I think that the 
> > mainstream should remove.
> 
> I'd say that if SuSE or oracle depend on them we keep them.  Otherwise,
> I'm fine with removing them or just making the 3 line bash script.

I wanted to remove them once from our packages, but some tool uses them.
I'm fine with replacing them with a shellscript, this is just a
syntactic conversion from btrfsctl style to the subcommands.


david

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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24 22:36               ` Chris Mason
  2013-01-24 22:49                 ` David Sterba
@ 2013-01-24 22:52                 ` Avi Miller
  1 sibling, 0 replies; 131+ messages in thread
From: Avi Miller @ 2013-01-24 22:52 UTC (permalink / raw)
  To: Chris Mason
  Cc: kreijack, Eric Sandeen, Goffredo Baroncelli, Stefan Behrens,
	Anand Jain, linux-btrfs, dsterba, gene

Hey Chris,

On 25/01/2013, at 9:36 AM, Chris Mason <chris.mason@fusionio.com> wrote:

> I'd say that if SuSE or oracle depend on them we keep them.  Otherwise,
> I'm fine with removing them or just making the 3 line bash script.


You can take this as an official response from Oracle: we don't need/want the old tools. :) All of our documentation uses the unified binary.

Thanks,
Avi

--
Oracle <http://www.oracle.com>
Avi Miller | Principal Program Manager | +61 (412) 229 687
Oracle Linux and Virtualization
417 St Kilda Road, Melbourne, Victoria 3004 Australia


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

* Re: [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-24 19:42       ` Zach Brown
@ 2013-01-24 23:14         ` Chris Mason
  2013-01-24 23:24           ` Zach Brown
  0 siblings, 1 reply; 131+ messages in thread
From: Chris Mason @ 2013-01-24 23:14 UTC (permalink / raw)
  To: Zach Brown; +Cc: Eric Sandeen, Anand Jain, linux-btrfs, dsterba, gene

On Thu, Jan 24, 2013 at 12:42:38PM -0700, Zach Brown wrote:
> 
> > > +	if (sv_id == 5) {
> > > +		printf("%s is btrfs root\n", fullpath);
> > > +		close(fd);
> > > +		close(mntfd);
> > > +		free(mnt);
> > > +		free(fullpath);
> > > +		return 1;
> > 
> > Just wondering, at this point might a "goto out;" be cleaner error
> > handling?  Every error case is getting longer ;)
> 
> No wondering needed!  This pattern is a source of bugs.  I'm hitting
> cases in the static analysis reports of people adding return paths
> without recognizing the pile of state they're expected to cleanup.
> 
> Use safe unwinding in one exit path at the end, please.  It's less
> maddening to audit and less likely to fail over time.

Really, goto is your friend ;)

-chris


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

* Re: [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-24 23:14         ` Chris Mason
@ 2013-01-24 23:24           ` Zach Brown
  0 siblings, 0 replies; 131+ messages in thread
From: Zach Brown @ 2013-01-24 23:24 UTC (permalink / raw)
  To: Chris Mason, Eric Sandeen, Anand Jain, linux-btrfs, dsterba, gene

> > Use safe unwinding in one exit path at the end, please.  It's less
> > maddening to audit and less likely to fail over time.
> 
> Really, goto is your friend ;)

I'm not going to use the word frenemy.  I'm just not :).

- z

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

* [PATCH 00/10 V2] add show sub-command for btrfs subvol cli
@ 2013-01-25  9:19 Anand Jain
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
  0 siblings, 1 reply; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Here is the V2 of this patch-set, kindly review and accept.

v1->v2:
 . 2nd attempt to Rebase to 
	git://repo.or.cz/btrfs-progs-unstable/devel.git for-chris
 and
 . Accepts Eric's review comments.

Thanks

Anand Jain (10):
  Btrfs-progs: move open_file_or_dir() to utils.c
  Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  Btrfs-progs: add parent uuid for snapshots
  Btrfs-progs: move struct root_info to btrfs-list.h
  Btrfs-progs: add function btrfs_get_subvol to get root_info of a
    subvol
  Btrfs-progs: add method to filter snapshots by parent uuid
  Btrfs-progs: put find_mount_root() in commands.h
  Btrfs-progs: make printing subvol extensible to newer layouts
  Btrfs-progs: make get_subvol_name non cmds-send specific
  Btrfs-progs: add show subcommand to subvol cli

 Makefile         |   4 +-
 btrfs-list.c     | 192 +++++++++++++++++++++++++++++++++--------------------
 btrfs-list.h     |  58 +++++++++++++++-
 btrfsctl.c       |   7 +-
 cmds-balance.c   |   1 +
 cmds-inspect.c   |   1 +
 cmds-qgroup.c    |   1 +
 cmds-quota.c     |   1 +
 cmds-send.c      |  12 ++--
 cmds-subvolume.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 commands.h       |   7 +-
 common.c         |  46 -------------
 man/btrfs.8.in   |   6 ++
 utils.c          |  30 ++++++++-
 utils.h          |   5 +-
 15 files changed, 425 insertions(+), 142 deletions(-)
 delete mode 100644 common.c

-- 
1.8.1.227.g44fe835


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

* [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (11 preceding siblings ...)
  2013-01-24 20:52   ` Gene Czarcinski
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:19   ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
                     ` (14 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

The definition of the function open_file_or_dir() is moved from common.c
to utils.c in order to be able to share some common code between scrub
and the device stats in the following step. That common code uses
open_file_or_dir(). Since open_file_or_dir() makes use of the function
dirfd(3), the required XOPEN version was raised from 6 to 7.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Original-Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
 Makefile         |  4 ++--
 btrfsctl.c       |  7 ++++---
 cmds-balance.c   |  1 +
 cmds-inspect.c   |  1 +
 cmds-qgroup.c    |  1 +
 cmds-quota.c     |  1 +
 cmds-subvolume.c |  1 +
 commands.h       |  3 ---
 common.c         | 46 ----------------------------------------------
 utils.c          | 30 ++++++++++++++++++++++++++++--
 utils.h          |  5 +++--
 11 files changed, 42 insertions(+), 58 deletions(-)
 delete mode 100644 common.c

diff --git a/Makefile b/Makefile
index 4894903..8576d90 100644
--- a/Makefile
+++ b/Makefile
@@ -41,8 +41,8 @@ all: version $(progs) manpages
 version:
 	bash version.sh
 
-btrfs: $(objects) btrfs.o help.o common.o $(cmds_objects)
-	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o common.o $(cmds_objects) \
+btrfs: $(objects) btrfs.o help.o $(cmds_objects)
+	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o $(cmds_objects) \
 		$(objects) $(LDFLAGS) $(LIBS) -lpthread
 
 calc-size: $(objects) calc-size.o
diff --git a/btrfsctl.c b/btrfsctl.c
index 518684c..049a5f3 100644
--- a/btrfsctl.c
+++ b/btrfsctl.c
@@ -63,7 +63,7 @@ static void print_usage(void)
 	exit(1);
 }
 
-static int open_file_or_dir(const char *fname)
+static int btrfsctl_open_file_or_dir(const char *fname)
 {
 	int ret;
 	struct stat st;
@@ -91,6 +91,7 @@ static int open_file_or_dir(const char *fname)
 	}
 	return fd;
 }
+
 int main(int ac, char **av)
 {
 	char *fname = NULL;
@@ -128,7 +129,7 @@ int main(int ac, char **av)
 			snap_location = strdup(fullpath);
 			snap_location = dirname(snap_location);
 
-			snap_fd = open_file_or_dir(snap_location);
+			snap_fd = btrfsctl_open_file_or_dir(snap_location);
 
 			name = strdup(fullpath);
 			name = basename(name);
@@ -238,7 +239,7 @@ int main(int ac, char **av)
 		}
 		name = fname;
 	 } else {
-		fd = open_file_or_dir(fname);
+		fd = btrfsctl_open_file_or_dir(fname);
 	 }
 
 	if (name) {
diff --git a/cmds-balance.c b/cmds-balance.c
index 38a7426..6268b61 100644
--- a/cmds-balance.c
+++ b/cmds-balance.c
@@ -28,6 +28,7 @@
 #include "volumes.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const balance_cmd_group_usage[] = {
 	"btrfs [filesystem] balance <command> [options] <path>",
diff --git a/cmds-inspect.c b/cmds-inspect.c
index 25b83d2..f10bf55 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -23,6 +23,7 @@
 
 #include "kerncompat.h"
 #include "ioctl.h"
+#include "utils.h"
 
 #include "commands.h"
 #include "btrfs-list.h"
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 1525c11..cafc284 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -24,6 +24,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const qgroup_cmd_group_usage[] = {
 	"btrfs qgroup <command> [options] <path>",
diff --git a/cmds-quota.c b/cmds-quota.c
index cf9ad97..8481514 100644
--- a/cmds-quota.c
+++ b/cmds-quota.c
@@ -23,6 +23,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const quota_cmd_group_usage[] = {
 	"btrfs quota <command> [options] <path>",
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index ac39f7b..e3cdb1e 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -32,6 +32,7 @@
 #include "ctree.h"
 #include "commands.h"
 #include "btrfs-list.h"
+#include "utils.h"
 
 static const char * const subvolume_cmd_group_usage[] = {
 	"btrfs subvolume <command> <args>",
diff --git a/commands.h b/commands.h
index bb6d2dd..8114a73 100644
--- a/commands.h
+++ b/commands.h
@@ -79,9 +79,6 @@ void help_ambiguous_token(const char *arg, const struct cmd_group *grp);
 
 void help_command_group(const struct cmd_group *grp, int argc, char **argv);
 
-/* common.c */
-int open_file_or_dir(const char *fname);
-
 extern const struct cmd_group subvolume_cmd_group;
 extern const struct cmd_group filesystem_cmd_group;
 extern const struct cmd_group balance_cmd_group;
diff --git a/common.c b/common.c
deleted file mode 100644
index 03f6570..0000000
--- a/common.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-
-int open_file_or_dir(const char *fname)
-{
-	int ret;
-	struct stat st;
-	DIR *dirstream;
-	int fd;
-
-	ret = stat(fname, &st);
-	if (ret < 0) {
-		return -1;
-	}
-	if (S_ISDIR(st.st_mode)) {
-		dirstream = opendir(fname);
-		if (!dirstream) {
-			return -2;
-		}
-		fd = dirfd(dirstream);
-	} else {
-		fd = open(fname, O_RDWR);
-	}
-	if (fd < 0) {
-		return -3;
-	}
-	return fd;
-}
diff --git a/utils.c b/utils.c
index 938f9a5..78530e1 100644
--- a/utils.c
+++ b/utils.c
@@ -16,8 +16,9 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#define _XOPEN_SOURCE 600
-#define __USE_XOPEN2K
+#define _XOPEN_SOURCE 700
+#define __USE_XOPEN2K8
+#define __XOPEN2K8 /* due to an error in dirent.h, to get dirfd() */
 #include <stdio.h>
 #include <stdlib.h>
 #ifndef __CHECKER__
@@ -1268,3 +1269,28 @@ u64 parse_size(char *s)
 	return strtoull(s, NULL, 10) * mult;
 }
 
+int open_file_or_dir(const char *fname)
+{
+	int ret;
+	struct stat st;
+	DIR *dirstream;
+	int fd;
+
+	ret = stat(fname, &st);
+	if (ret < 0) {
+		return -1;
+	}
+	if (S_ISDIR(st.st_mode)) {
+		dirstream = opendir(fname);
+		if (!dirstream) {
+			return -2;
+		}
+		fd = dirfd(dirstream);
+	} else {
+		fd = open(fname, O_RDWR);
+	}
+	if (fd < 0) {
+		return -3;
+	}
+	return fd;
+}
diff --git a/utils.h b/utils.h
index 714fd7a..ed43e84 100644
--- a/utils.h
+++ b/utils.h
@@ -19,6 +19,8 @@
 #ifndef __UTILS__
 #define __UTILS__
 
+#include "ctree.h"
+
 #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024)
 
 int make_btrfs(int fd, const char *device, const char *label,
@@ -44,8 +46,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
 char *pretty_sizes(u64 size);
 int check_label(char *input);
 int get_mountpt(char *dev, char *mntpt, size_t size);
-
 int btrfs_scan_block_devices(int run_ioctl);
-
 u64 parse_size(char *s);
+int open_file_or_dir(const char *fname);
 #endif
-- 
1.8.1.227.g44fe835


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

* [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (12 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:19   ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
                     ` (13 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

To improve the code reuse its better to have btrfs_list_subvols
just return list of subvols witout printing

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 28 ++++++++++++++++++----------
 btrfs-list.h     |  2 +-
 cmds-subvolume.c |  4 ++--
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index cb42fbc..b404e1d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1439,15 +1439,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 	}
 }
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
-		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 {
-	struct root_lookup root_lookup;
-	struct root_lookup root_sort;
 	int ret;
 
-	ret = __list_subvol_search(fd, &root_lookup);
+	ret = __list_subvol_search(fd, root_lookup);
 	if (ret) {
 		fprintf(stderr, "ERROR: can't perform the search - %s\n",
 				strerror(errno));
@@ -1458,16 +1454,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
 	 * now we have an rbtree full of root_info objects, but we need to fill
 	 * in their path names within the subvol that is referencing each one.
 	 */
-	ret = __list_subvol_fill_paths(fd, &root_lookup);
-	if (ret < 0)
-		return ret;
+	ret = __list_subvol_fill_paths(fd, root_lookup);
+	return ret;
+}
 
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
+		       struct btrfs_list_comparer_set *comp_set,
+		       int is_tab_result)
+{
+	struct root_lookup root_lookup;
+	struct root_lookup root_sort;
+	int ret;
+
+	ret = btrfs_list_subvols(fd, &root_lookup);
+	if (ret)
+		return ret;
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
 	print_all_volume_info(&root_sort, is_tab_result);
 	__free_all_subvolumn(&root_lookup);
-	return ret;
+
+	return 0;
 }
 
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
diff --git a/btrfs-list.h b/btrfs-list.h
index cde4b3c..71fe0f3 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 			      enum btrfs_list_comp_enum comparer,
 			      int is_descending);
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
 			int is_tab_result);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index e3cdb1e..c35dff7 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
+	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				is_tab_result);
 	if (ret)
 		return 19;
@@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (13 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:19   ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
                     ` (12 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 34 ++++++++++++++++++++++++++++------
 btrfs-list.h     |  1 +
 cmds-subvolume.c |  6 +++++-
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index b404e1d..13a365d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -80,6 +80,7 @@ struct root_info {
 	time_t otime;
 
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	/* path from the subvol we live in to this root, including the
 	 * root's name.  This is null until we do the extra lookup ioctl.
@@ -128,6 +129,11 @@ struct {
 		.need_print	= 0,
 	},
 	{
+		.name		= "parent_uuid",
+		.column_name	= "Parent UUID",
+		.need_print	= 0,
+	},
+	{
 		.name		= "uuid",
 		.column_name	= "UUID",
 		.need_print	= 0,
@@ -435,7 +441,7 @@ static struct root_info *root_tree_search(struct root_lookup *root_tree,
 static int update_root(struct root_lookup *root_lookup,
 		       u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		       u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		       time_t ot, void *uuid)
+		       time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 
@@ -472,6 +478,8 @@ static int update_root(struct root_lookup *root_lookup,
 		ri->otime = ot;
 	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
 
 	return 0;
 }
@@ -489,17 +497,18 @@ static int update_root(struct root_lookup *root_lookup,
  * gen: the current generation of the root
  * ot: the original time(create time) of the root
  * uuid: uuid of the root
+ * puuid: uuid of the root parent if any
  */
 static int add_root(struct root_lookup *root_lookup,
 		    u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		    u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		    time_t ot, void *uuid)
+		    time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 	int ret;
 
 	ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
-			  dir_id, name, name_len, ogen, gen, ot, uuid);
+			  dir_id, name, name_len, ogen, gen, ot, uuid, puuid);
 	if (!ret)
 		return 0;
 
@@ -537,9 +546,12 @@ static int add_root(struct root_lookup *root_lookup,
 	if (ot)
 		ri->otime = ot;
 
-	if (uuid) 
+	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
 
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
+
 	ret = root_tree_insert(root_lookup, ri);
 	if (ret) {
 		printf("failed to insert tree %llu\n", (unsigned long long)root_id);
@@ -1021,6 +1033,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 	int i;
 	time_t t;
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	root_lookup_init(root_lookup);
 	memset(&args, 0, sizeof(args));
@@ -1073,7 +1086,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 
 				add_root(root_lookup, sh.objectid, sh.offset,
 					 0, 0, dir_id, name, name_len, 0, 0, 0,
-					 NULL);
+					 NULL, NULL);
 			} else if (sh.type == BTRFS_ROOT_ITEM_KEY) {
 				ri = (struct btrfs_root_item *)(args.buf + off);
 				gen = btrfs_root_generation(ri);
@@ -1083,15 +1096,17 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 					t = ri->otime.sec;
 					ogen = btrfs_root_otransid(ri);
 					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
+					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
 				} else {
 					t = 0;
 					ogen = 0;
 					memset(uuid, 0, BTRFS_UUID_SIZE);
+					memset(puuid, 0, BTRFS_UUID_SIZE);
 				}
 
 				add_root(root_lookup, sh.objectid, 0,
 					 sh.offset, flags, 0, NULL, 0, ogen,
-					 gen, t, uuid);
+					 gen, t, uuid, puuid);
 			}
 
 			off += sh.len;
@@ -1345,6 +1360,13 @@ static void print_subvolume_column(struct root_info *subv,
 			uuid_unparse(subv->uuid, uuidparse);
 		printf("%s", uuidparse);
 		break;
+	case BTRFS_LIST_PUUID:
+		if (uuid_is_null(subv->puuid))
+			strcpy(uuidparse, "-");
+		else
+			uuid_unparse(subv->puuid, uuidparse);
+		printf("%s", uuidparse);
+		break;
 	case BTRFS_LIST_PATH:
 		BUG_ON(!subv->full_path);
 		printf("%s", subv->full_path);
diff --git a/btrfs-list.h b/btrfs-list.h
index 71fe0f3..855e73d 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -53,6 +53,7 @@ enum btrfs_list_column_enum {
 	BTRFS_LIST_PARENT,
 	BTRFS_LIST_TOP_LEVEL,
 	BTRFS_LIST_OTIME,
+	BTRFS_LIST_PUUID,
 	BTRFS_LIST_UUID,
 	BTRFS_LIST_PATH,
 	BTRFS_LIST_ALL,
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index c35dff7..a1e6893 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -280,6 +280,7 @@ static const char * const cmd_subvol_list_usage[] = {
 	"-p           print parent ID",
 	"-a           print all the subvolumes in the filesystem.",
 	"-u           print the uuid of subvolumes (and snapshots)",
+	"-q           print the parent uuid of the snapshots",
 	"-t           print the result as a table",
 	"-s           list snapshots only in the filesystem",
 	"-r           list readonly subvolumes (including snapshots)",
@@ -319,7 +320,7 @@ static int cmd_subvol_list(int argc, char **argv)
 	optind = 1;
 	while(1) {
 		c = getopt_long(argc, argv,
-				    "apsurg:c:t", long_options, NULL);
+				    "apsuqrg:c:t", long_options, NULL);
 		if (c < 0)
 			break;
 
@@ -343,6 +344,9 @@ static int cmd_subvol_list(int argc, char **argv)
 		case 'u':
 			btrfs_list_setup_print_column(BTRFS_LIST_UUID);
 			break;
+		case 'q':
+			btrfs_list_setup_print_column(BTRFS_LIST_PUUID);
+			break;
 		case 'r':
 			flags |= BTRFS_ROOT_SUBVOL_RDONLY;
 			break;
-- 
1.8.1.227.g44fe835


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

* [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (14 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:19   ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
                     ` (11 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

As we would add more ways to list and manage the subvols
and snapshots, its better if we have struct root_info
defined in the header file.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 47 -----------------------------------------------
 btrfs-list.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 13a365d..909d814 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -46,53 +46,6 @@ struct root_lookup {
 	struct rb_root root;
 };
 
-/*
- * one of these for each root we find.
- */
-struct root_info {
-	struct rb_node rb_node;
-	struct rb_node sort_node;
-
-	/* this root's id */
-	u64 root_id;
-
-	/* equal the offset of the root's key */
-	u64 root_offset;
-
-	/* flags of the root */
-	u64 flags;
-
-	/* the id of the root that references this one */
-	u64 ref_tree;
-
-	/* the dir id we're in from ref_tree */
-	u64 dir_id;
-
-	u64 top_id;
-
-	/* generation when the root is created or last updated */
-	u64 gen;
-
-	/* creation generation of this root in sec*/
-	u64 ogen;
-
-	/* creation time of this root in sec*/
-	time_t otime;
-
-	u8 uuid[BTRFS_UUID_SIZE];
-	u8 puuid[BTRFS_UUID_SIZE];
-
-	/* path from the subvol we live in to this root, including the
-	 * root's name.  This is null until we do the extra lookup ioctl.
-	 */
-	char *path;
-
-	/* the name of this root in the directory it lives in */
-	char *name;
-
-	char *full_path;
-};
-
 struct {
 	char	*name;
 	char	*column_name;
diff --git a/btrfs-list.h b/btrfs-list.h
index 855e73d..3b7b680 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,7 +18,52 @@
 
 #include "kerncompat.h"
 
-struct root_info;
+/*
+ * one of these for each root we find.
+ */
+struct root_info {
+	struct rb_node rb_node;
+	struct rb_node sort_node;
+
+	/* this root's id */
+	u64 root_id;
+
+	/* equal the offset of the root's key */
+	u64 root_offset;
+
+	/* flags of the root */
+	u64 flags;
+
+	/* the id of the root that references this one */
+	u64 ref_tree;
+
+	/* the dir id we're in from ref_tree */
+	u64 dir_id;
+
+	u64 top_id;
+
+	/* generation when the root is created or last updated */
+	u64 gen;
+
+	/* creation generation of this root in sec*/
+	u64 ogen;
+
+	/* creation time of this root in sec*/
+	time_t otime;
+
+	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
+
+	/* path from the subvol we live in to this root, including the
+	 * root's name.  This is null until we do the extra lookup ioctl.
+	 */
+	char *path;
+
+	/* the name of this root in the directory it lives in */
+	char *name;
+
+	char *full_path;
+};
 
 typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
 typedef int (*btrfs_list_comp_func)(struct root_info *, struct root_info *,
-- 
1.8.1.227.g44fe835


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

* [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (15 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:19   ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
                     ` (10 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

We need a function which can get the root_info of a given
subvol. This is in preparation to add support for the show
sub-cli.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
 btrfs-list.h |  1 +
 2 files changed, 39 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 909d814..0ee13b6 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1453,6 +1453,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	return 0;
 }
 
+int btrfs_get_subvol(int fd, struct root_info *the_ri)
+{
+	int ret = -1;
+	struct root_lookup rl;
+	struct rb_node *rbn;
+	struct root_info *ri;
+	u64 root_id = btrfs_list_get_path_rootid(fd);
+
+	if (btrfs_list_subvols(fd, &rl))
+		return 1;
+
+	rbn = rb_first(&rl.root);
+	while(rbn) {
+		ri = rb_entry(rbn, struct root_info, rb_node);
+		resolve_root(&rl, ri, root_id);
+		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
+			memcpy(the_ri, ri, offsetof(struct root_info, path));
+			if (ri->path)
+				the_ri->path = strdup(ri->path);
+			else
+				the_ri->path = NULL;
+			if (ri->name)
+				the_ri->name = strdup(ri->name);
+			else
+				the_ri->name = NULL;
+			if (ri->full_path)
+				the_ri->full_path = strdup(ri->full_path);
+			else
+				the_ri->name = NULL;
+			ret = 0;
+			break;
+		}
+		rbn = rb_next(rbn);
+	}
+	__free_all_subvolumn(&rl);
+	return ret;
+}
+
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 			    struct btrfs_file_extent_item *item,
 			    u64 found_gen, u64 *cache_dirid,
diff --git a/btrfs-list.h b/btrfs-list.h
index 3b7b680..580d4d1 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
 u64 btrfs_list_get_path_rootid(int fd);
+int btrfs_get_subvol(int fd, struct root_info *the_ri);
-- 
1.8.1.227.g44fe835


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

* [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (16 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:19   ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
                     ` (9 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 6 ++++++
 btrfs-list.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 0ee13b6..9c84ecb 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1142,6 +1142,11 @@ static int filter_topid_equal(struct root_info *ri, u64 data)
 	return ri->top_id == data;
 }
 
+static int filter_by_parent(struct root_info *ri, u64 data)
+{
+	return !uuid_compare(ri->puuid, (u8 *)data);
+}
+
 static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_ROOTID]		= filter_by_rootid,
 	[BTRFS_LIST_FILTER_SNAPSHOT_ONLY]	= filter_snapshot,
@@ -1153,6 +1158,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_CGEN_LESS]		= filter_cgen_less,
 	[BTRFS_LIST_FILTER_CGEN_EQUAL]          = filter_cgen_equal,
 	[BTRFS_LIST_FILTER_TOPID_EQUAL]		= filter_topid_equal,
+	[BTRFS_LIST_FILTER_BY_PARENT]		= filter_by_parent,
 };
 
 struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
diff --git a/btrfs-list.h b/btrfs-list.h
index 580d4d1..cde7a3f 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -117,6 +117,7 @@ enum btrfs_list_filter_enum {
 	BTRFS_LIST_FILTER_CGEN_LESS,
 	BTRFS_LIST_FILTER_CGEN_MORE,
 	BTRFS_LIST_FILTER_TOPID_EQUAL,
+	BTRFS_LIST_FILTER_BY_PARENT,
 	BTRFS_LIST_FILTER_MAX,
 };
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (17 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:19   ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
                     ` (8 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

A useful function need to define it in a header file.

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

diff --git a/commands.h b/commands.h
index 8114a73..9b77f3e 100644
--- a/commands.h
+++ b/commands.h
@@ -103,3 +103,6 @@ int cmd_qgroup(int argc, char **argv);
 
 /* subvolume exported functions */
 int test_issubvolume(char *path);
+
+/* send.c */
+int find_mount_root(const char *path, char **mount_root);
-- 
1.8.1.227.g44fe835


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

* [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (18 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:19   ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
                     ` (7 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Currently you can print subvol in a list or table format.
This patch will provide a way to extend this to other formats
like the upcoming raw format.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 26 +++++++++++++++-----------
 btrfs-list.h     |  3 +++
 cmds-subvolume.c | 23 ++++++++++++++++++++---
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 9c84ecb..656de10 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -54,12 +54,12 @@ struct {
 	{
 		.name		= "ID",
 		.column_name	= "ID",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "gen",
 		.column_name	= "Gen",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "cgen",
@@ -74,7 +74,7 @@ struct {
 	{
 		.name		= "top level",
 		.column_name	= "Top Level",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "otime",
@@ -94,7 +94,7 @@ struct {
 	{
 		.name		= "path",
 		.column_name	= "Path",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= NULL,
@@ -1401,21 +1401,25 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int is_tab_result)
+				  int layout)
 {
 	struct rb_node *n;
 	struct root_info *entry;
 
-	if (is_tab_result)
+	if (layout == BTRFS_LIST_LAYOUT_TABLE)
 		print_all_volume_info_tab_head();
 
 	n = rb_first(&sorted_tree->root);
 	while (n) {
 		entry = rb_entry(n, struct root_info, sort_node);
-		if (is_tab_result)
-			print_single_volume_info_table(entry);
-		else
+		switch (layout) {
+		case BTRFS_LIST_LAYOUT_DEFAULT:
 			print_single_volume_info_default(entry);
+			break;
+		case BTRFS_LIST_LAYOUT_TABLE:
+			print_single_volume_info_table(entry);
+			break;
+		}
 		n = rb_next(n);
 	}
 }
@@ -1441,7 +1445,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+		       int layout)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1453,7 +1457,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, is_tab_result);
+	print_all_volume_info(&root_sort, layout);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index cde7a3f..5b60068 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,6 +18,9 @@
 
 #include "kerncompat.h"
 
+#define BTRFS_LIST_LAYOUT_DEFAULT	0
+#define BTRFS_LIST_LAYOUT_TABLE	1
+
 /*
  * one of these for each root we find.
  */
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index a1e6893..bb9629f 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -410,8 +410,18 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				is_tab_result);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	if (is_tab_result)
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_TABLE);
+	else
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
@@ -617,7 +627,14 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
+		BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (19 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:19   ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
                     ` (6 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

get_subvol_name can be used other than the just with in cmds-send.c
so this patch will make it possible with out changing the original
intentions.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-send.c | 12 ++++++------
 commands.h  |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/cmds-send.c b/cmds-send.c
index ac1d3cf..0416b79 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -333,12 +333,12 @@ out:
 	return ret;
 }
 
-static const char *get_subvol_name(struct btrfs_send *s, const char *full_path)
+char *get_subvol_name(char *mnt, char *full_path)
 {
-	int len = strlen(s->root_path);
+	int len = strlen(mnt);
 	if (!len)
 		return full_path;
-	if (s->root_path[len - 1] != '/')
+	if (mnt[len - 1] != '/')
 		len += 1;
 
 	return full_path + len;
@@ -452,7 +452,7 @@ int cmd_send_start(int argc, char **argv)
 			if (ret < 0)
 				goto out;
 
-			ret = get_root_id(&send, get_subvol_name(&send, subvol),
+			ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 					&root_id);
 			if (ret < 0) {
 				fprintf(stderr, "ERROR: could not resolve "
@@ -513,7 +513,7 @@ int cmd_send_start(int argc, char **argv)
 
 	if (snapshot_parent != NULL) {
 		ret = get_root_id(&send,
-				get_subvol_name(&send, snapshot_parent),
+				get_subvol_name(send.root_path, snapshot_parent),
 				&parent_root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
@@ -572,7 +572,7 @@ int cmd_send_start(int argc, char **argv)
 			goto out;
 		}
 
-		ret = get_root_id(&send, get_subvol_name(&send, subvol),
+		ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 				&root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
diff --git a/commands.h b/commands.h
index 9b77f3e..631fb6b 100644
--- a/commands.h
+++ b/commands.h
@@ -106,3 +106,4 @@ int test_issubvolume(char *path);
 
 /* send.c */
 int find_mount_root(const char *path, char **mount_root);
+char *get_subvol_name(char *mnt, char *full_path);
-- 
1.8.1.227.g44fe835


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

* [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (20 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
@ 2013-01-25  9:19   ` Anand Jain
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
                     ` (5 subsequent siblings)
  27 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:19 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

This adds show sub-command to the btrfs subvol cli
to display detailed inforamtion of the given subvol
or snapshot.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     |  25 +++++++-
 btrfs-list.h     |   3 +-
 cmds-subvolume.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 man/btrfs.8.in   |   6 ++
 4 files changed, 199 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 656de10..1915ece 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1335,6 +1335,22 @@ static void print_subvolume_column(struct root_info *subv,
 	}
 }
 
+static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_LIST_ALL; i++) {
+		if (!btrfs_list_columns[i].need_print)
+			continue;
+
+		if (raw_prefix)
+			printf("%s",raw_prefix);
+
+		print_subvolume_column(subv, i);
+	}
+	printf("\n");
+}
+
 static void print_single_volume_info_table(struct root_info *subv)
 {
 	int i;
@@ -1401,7 +1417,7 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int layout)
+				  int layout, char *raw_prefix)
 {
 	struct rb_node *n;
 	struct root_info *entry;
@@ -1419,6 +1435,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 		case BTRFS_LIST_LAYOUT_TABLE:
 			print_single_volume_info_table(entry);
 			break;
+		case BTRFS_LIST_LAYOUT_RAW:
+			print_single_volume_info_raw(entry, raw_prefix);
+			break;
 		}
 		n = rb_next(n);
 	}
@@ -1445,7 +1464,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int layout)
+		       int layout, char *raw_prefix)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1457,7 +1476,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, layout);
+	print_all_volume_info(&root_sort, layout, raw_prefix);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index 5b60068..09d35f7 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -20,6 +20,7 @@
 
 #define BTRFS_LIST_LAYOUT_DEFAULT	0
 #define BTRFS_LIST_LAYOUT_TABLE	1
+#define BTRFS_LIST_LAYOUT_RAW		2
 
 /*
  * one of these for each root we find.
@@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-			int is_tab_result);
+			int layout, char *raw_prefix);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index bb9629f..ad6afbc 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -24,6 +24,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
+#include <uuid/uuid.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
 
 	if (is_tab_result)
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_TABLE);
+				BTRFS_LIST_LAYOUT_TABLE, NULL);
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_DEFAULT);
+				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
-		BTRFS_LIST_LAYOUT_DEFAULT);
+		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -721,6 +722,170 @@ static int cmd_find_new(int argc, char **argv)
 	return 0;
 }
 
+static const char * const cmd_subvol_show_usage[] = {
+	"btrfs subvolume show <subvol-path>",
+	"Show more information of the subvolume",
+	NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+	struct root_info get_ri;
+	struct btrfs_list_filter_set *filter_set;
+	char tstr[256];
+	char uuidparse[37];
+	char *fullpath, *svpath, *mnt = NULL;
+	char raw_prefix[] = "\t\t\t\t";
+	u64 sv_id, mntid;
+	int fd, mntfd;
+	int ret;
+	int clean = 0;
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_subvol_show_usage);
+
+	fullpath = realpath(argv[1],0);
+	if (!fullpath) {
+		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
+			argv[1], strerror(errno));
+		return 1;
+	}
+	clean++;
+
+	ret = test_issubvolume(fullpath);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
+		ret = 1;
+		goto out;
+	}
+	if (!ret) {
+		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
+		ret = 1;
+		goto out;
+	}
+
+	ret = find_mount_root(fullpath, &mnt);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
+				"%s\n", fullpath, strerror(-ret));
+		ret = 1;
+		goto out;
+	}
+	clean++;
+
+	svpath = get_subvol_name(mnt, fullpath);
+
+	fd = open_file_or_dir(fullpath);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
+		ret = 1;
+		goto out;
+	}
+	clean++;
+
+	sv_id = btrfs_list_get_path_rootid(fd);
+	if (sv_id < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
+			fullpath);
+		ret = 1;
+		goto out;
+	}
+
+	mntfd = open_file_or_dir(mnt);
+	if (mntfd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
+		ret = 1;
+		goto out;
+	}
+	clean++;
+
+	mntid = btrfs_list_get_path_rootid(mntfd);
+	if (mntid < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
+		ret = 1;
+		goto out;
+	}
+
+	if (sv_id == 5) {
+		printf("%s is btrfs root\n", fullpath);
+		ret = 1;
+		goto out;
+	}
+
+	memset(&get_ri, 0, sizeof(get_ri));
+	get_ri.root_id = sv_id;
+
+	if (btrfs_get_subvol(mntfd, &get_ri)) {
+		fprintf(stderr, "ERROR: can't find '%s'\n",
+			svpath);
+		ret = 1;
+		goto out;
+	}
+
+	ret = 0;
+	/* print the info */
+	printf("%s\n", fullpath);
+	printf("\tName: \t\t\t%s\n", get_ri.name);
+
+	if (uuid_is_null(get_ri.uuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.uuid, uuidparse);
+	printf("\tuuid: \t\t\t%s\n", uuidparse);
+
+	if (uuid_is_null(get_ri.puuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.puuid, uuidparse);
+	printf("\tParent uuid: \t\t%s\n", uuidparse);
+
+	if (get_ri.otime)
+		strftime(tstr, 256, "%Y-%m-%d %X",
+			 localtime(&get_ri.otime));
+	else
+		strcpy(tstr, "-");
+	printf("\tCreation time: \t\t%s\n", tstr);
+
+	printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
+	printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
+	printf("\tGen at creation: \t%llu\n", get_ri.ogen);
+	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
+	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
+
+	/* print the snapshots of the given subvol if any*/
+	printf("\tSnapshot(s):\n");
+	filter_set = btrfs_list_alloc_filter_set();
+	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
+				get_ri.uuid);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
+			raw_prefix);
+
+	/* clean up */
+	if (get_ri.path)
+		free(get_ri.path);
+	if (get_ri.name)
+		free(get_ri.name);
+	if (get_ri.full_path)
+		free(get_ri.full_path);
+
+out:
+	switch (clean) {
+	case 4:
+		close(mntfd);
+	case 3:
+		close(fd);
+	case 2:
+		free(mnt);
+	case 1:
+		free(fullpath);
+		break;
+	default:
+		BUG();
+	}
+	return ret;
+}
+
 const struct cmd_group subvolume_cmd_group = {
 	subvolume_cmd_group_usage, NULL, {
 		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -732,6 +897,7 @@ const struct cmd_group subvolume_cmd_group = {
 		{ "set-default", cmd_subvol_set_default,
 			cmd_subvol_set_default_usage, NULL, 0 },
 		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
+		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
 	}
 };
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index d20e332..0008a06 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
 .PP
+\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
 [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
 [<\fIfile\fR>|<\fIdir\fR>...]
@@ -158,6 +160,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
 is similar to \fBsubvolume list\fR command.
 .TP
 
+\fBsubvolume show\fR\fI <path>\fR
+Show information of a given subvolume in the \fI<path>\fR.
+.TP
+
 \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
 [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
 
-- 
1.8.1.227.g44fe835


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

* Re: [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-24  4:49     ` Eric Sandeen
@ 2013-01-25  9:20       ` Anand Jain
  0 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:20 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-btrfs, dsterba, gene



On 01/24/2013 12:49 PM, Eric Sandeen wrote:
> On 1/23/13 2:12 AM, Anand Jain wrote:
>> We need a function which can get the root_info of a given
>> subvol. This is in preparation to add support for the show
>> sub-cli.
>>
>> Signed-off-by: Anand Jain <anand.jain@oracle.com>
>> ---
>>   btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
>>   btrfs-list.h |  1 +
>>   2 files changed, 39 insertions(+)
>>
>> diff --git a/btrfs-list.c b/btrfs-list.c
>> index 1851f3e..ec64a36 100644
>> --- a/btrfs-list.c
>> +++ b/btrfs-list.c
>> @@ -1455,6 +1455,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>>   	return 0;
>>   }
>>
>> +int btrfs_get_subvol(int fd, struct root_info *the_ri)
>> +{
>> +	int ret = -1;
>> +	struct root_lookup rl;
>> +	struct rb_node *rbn;
>> +	struct root_info *ri;
>> +	u64 root_id = btrfs_list_get_path_rootid(fd);
>> +
>> +	if (btrfs_list_subvols(fd, &rl))
>> +		return 13;
>
> Unless there is an ongoing plan to actually do something with these
> magical returns, can we maybe just be normal about error return values
> in new code?
>
> The caller you add only cares about 0 or not, right?  Or is there some other
> purpose for "13" I'm not aware of?
>
> Thanks,
> -Eric

  It was as in the original return value. But I think
  its time we fix this. now. accepted.

Thanks, Anand

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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24  4:39     ` Eric Sandeen
  2013-01-24  9:23       ` Stefan Behrens
@ 2013-01-25  9:21       ` Anand Jain
  1 sibling, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:21 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-btrfs, dsterba, gene



> Cool, I had this on my stack too.  But can you maybe remove the
> nonsensical return values, and instead of renaming & keeping the btrfsctl.c
> copy, why not just use a common copy in utils.c?  It'd just be 2 checks
> for fd < 0 in the btrfsctl callers.

  Thanks for the comments Eric. Though I agree, but it deviates
  from the purpose of this patch-set. It could be taken as a
  separate patch.

Anand

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

* Re: [PATCH 00/10] add show sub-command for btrfs subvol cli
  2013-01-24 20:52   ` Gene Czarcinski
@ 2013-01-25  9:23     ` Anand Jain
  0 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:23 UTC (permalink / raw)
  To: Gene Czarcinski; +Cc: linux-btrfs, dsterba




> OK, in spite of saying that these patches did not apply clean, it was
> not terribly difficult to refit what did not apply.  I did this in two
> steps:
>
> 1. I created the equivalent of the for-chris branch.  This did not apply
> clean which surprised me.

  Yes I see it. Not sure where I went wrong, sorry about that,
  now I have sent V2 of this patch set which also includes
  Erics comments.

>  However, minor things easily handled manually
> in the first patch for utils.c and utils.h plus btrfs-lists.c in a later
> patch.
>
> 2. After creating a new set of patches from the above effort, I then
> moved to my working branch with includes all of the patches in the
> integration-20130121 branch [careful, patch 0023 has a conflict in
> mkfs.c] please others.  This time it was a very small problem in
> cmds-qgroup.c.  I am running it now.
>
> Gene

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

* Re: [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-24  5:06     ` Eric Sandeen
  2013-01-24 19:42       ` Zach Brown
@ 2013-01-25  9:24       ` Anand Jain
  1 sibling, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:24 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-btrfs, dsterba, gene



Eric. All accepted. Thanks for the review.

Anand

On 01/24/2013 01:06 PM, Eric Sandeen wrote:
> On 1/23/13 2:12 AM, Anand Jain wrote:
>> This adds show sub-command to the btrfs subvol cli
>> to display detailed inforamtion of the given subvol
>> or snapshot.
>
> Couple things below.
>
>> Signed-off-by: Anand Jain <anand.jain@oracle.com>
>> ---
>>   btrfs-list.c     |  25 +++++++-
>>   btrfs-list.h     |   3 +-
>>   cmds-subvolume.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>   man/btrfs.8.in   |   6 ++
>>   4 files changed, 203 insertions(+), 7 deletions(-)
>>
>> diff --git a/btrfs-list.c b/btrfs-list.c
>> index 71f7239..5be3ed9 100644
>> --- a/btrfs-list.c
>> +++ b/btrfs-list.c
>> @@ -1337,6 +1337,22 @@ static void print_subvolume_column(struct root_info *subv,
>>   	}
>>   }
>>
>> +static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i < BTRFS_LIST_ALL; i++) {
>> +		if (!btrfs_list_columns[i].need_print)
>> +			continue;
>> +
>> +		if(raw_prefix);
>
> That semicolon will eventually make you sad, I bet.  ;)
> And while you're at it, please add the space after "if?"
>
>> +			printf("%s",raw_prefix);
>> +
>> +		print_subvolume_column(subv, i);
>> +	}
>> +	printf("\n");
>> +}
>> +
>>   static void print_single_volume_info_table(struct root_info *subv)
>>   {
>>   	int i;
>> @@ -1403,7 +1419,7 @@ static void print_all_volume_info_tab_head()
>>   }
>>
>>   static void print_all_volume_info(struct root_lookup *sorted_tree,
>> -				  int layout)
>> +				  int layout, char *raw_prefix)
>>   {
>>   	struct rb_node *n;
>>   	struct root_info *entry;
>> @@ -1421,6 +1437,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
>>   		case BTRFS_LIST_LAYOUT_TABLE:
>>   			print_single_volume_info_table(entry);
>>   			break;
>> +		case BTRFS_LIST_LAYOUT_RAW:
>> +			print_single_volume_info_raw(entry, raw_prefix);
>> +			break;
>>   		}
>>   		n = rb_next(n);
>>   	}
>> @@ -1447,7 +1466,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
>>
>>   int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>>   		       struct btrfs_list_comparer_set *comp_set,
>> -		       int layout)
>> +		       int layout, char *raw_prefix)
>>   {
>>   	struct root_lookup root_lookup;
>>   	struct root_lookup root_sort;
>> @@ -1459,7 +1478,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>>   	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
>>   				 comp_set, fd);
>>
>> -	print_all_volume_info(&root_sort, layout);
>> +	print_all_volume_info(&root_sort, layout, raw_prefix);
>>   	__free_all_subvolumn(&root_lookup);
>>
>>   	return 0;
>> diff --git a/btrfs-list.h b/btrfs-list.h
>> index 5b60068..09d35f7 100644
>> --- a/btrfs-list.h
>> +++ b/btrfs-list.h
>> @@ -20,6 +20,7 @@
>>
>>   #define BTRFS_LIST_LAYOUT_DEFAULT	0
>>   #define BTRFS_LIST_LAYOUT_TABLE	1
>> +#define BTRFS_LIST_LAYOUT_RAW		2
>>
>>   /*
>>    * one of these for each root we find.
>> @@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
>>
>>   int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>>   		       struct btrfs_list_comparer_set *comp_set,
>> -			int is_tab_result);
>> +			int layout, char *raw_prefix);
>>   int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
>>   int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
>>   char *btrfs_list_path_for_root(int fd, u64 root);
>> diff --git a/cmds-subvolume.c b/cmds-subvolume.c
>> index dd677f7..7e5e28c 100644
>> --- a/cmds-subvolume.c
>> +++ b/cmds-subvolume.c
>> @@ -24,6 +24,7 @@
>>   #include <libgen.h>
>>   #include <limits.h>
>>   #include <getopt.h>
>> +#include <uuid/uuid.h>
>>
>>   #include "kerncompat.h"
>>   #include "ioctl.h"
>> @@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
>>
>>   	if (is_tab_result)
>>   		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
>> -				BTRFS_LIST_LAYOUT_TABLE);
>> +				BTRFS_LIST_LAYOUT_TABLE, NULL);
>>   	else
>>   		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
>> -				BTRFS_LIST_LAYOUT_DEFAULT);
>> +				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
>>   	if (ret)
>>   		return 19;
>>   	return 0;
>> @@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
>>   	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
>>
>>   	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
>> -		BTRFS_LIST_LAYOUT_DEFAULT);
>> +		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
>>   	if (ret)
>>   		return 19;
>>   	return 0;
>> @@ -721,6 +722,174 @@ static int cmd_find_new(int argc, char **argv)
>>   	return 0;
>>   }
>>
>> +static const char * const cmd_subvol_show_usage[] = {
>> +	"btrfs subvolume show <subvol-path>",
>> +	"Show more information of the subvolume",
>> +	NULL
>> +};
>> +
>> +static int cmd_subvol_show(int argc, char **argv)
>> +{
>> +	struct root_info get_ri;
>> +	struct btrfs_list_filter_set *filter_set;
>> +	char tstr[256];
>> +	char uuidparse[37];
>> +	char *fullpath, *svpath, *mnt = NULL;
>> +	char raw_prefix[] = "\t\t\t\t";
>> +	u64 sv_id, mntid;
>> +	int fd, mntfd;
>> +	int ret;
>> +
>> +	if (check_argc_exact(argc, 2))
>> +		usage(cmd_subvol_show_usage);
>> +
>> +	fullpath = realpath(argv[1],0);
>> +	if(!fullpath) {
>
> ideally "if (!fullpath)" with the space...
>
>> +		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
>> +			argv[1], strerror(errno));
>> +		return 1;
>> +	}
>> +	ret = test_issubvolume(fullpath);
>> +	if (ret < 0) {
>> +		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
>> +		free(fullpath);
>> +		return 1;
>> +	}
>> +	if (!ret) {
>> +		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
>> +		free(fullpath);
>> +		return 1;
>> +	}
>> +
>> +	ret = find_mount_root(fullpath, &mnt);
>> +	if (ret < 0) {
>> +		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
>> +				"%s\n", fullpath, strerror(-ret));
>> +		free(fullpath);
>> +		return 1;
>> +	}
>> +
>> +	svpath = get_subvol_name(mnt, fullpath);
>> +
>> +	fd = open_file_or_dir(fullpath);
>> +	if (fd < 0) {
>> +		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
>> +		free(mnt);
>> +		free(fullpath);
>> +		return 1;
>> +	}
>> +	sv_id = btrfs_list_get_path_rootid(fd);
>
> This could fail, right?
>
>> +	mntfd = open_file_or_dir(mnt);
>> +	if (mntfd < 0) {
>> +		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
>> +		close(fd);
>> +		free(mnt);
>> +		free(fullpath);
>> +		return 1;
>> +	}
>> +	mntid = btrfs_list_get_path_rootid(mntfd);
>> +
>> +	if (sv_id == 5) {
>> +		printf("%s is btrfs root\n", fullpath);
>> +		close(fd);
>> +		close(mntfd);
>> +		free(mnt);
>> +		free(fullpath);
>> +		return 1;
>
> Just wondering, at this point might a "goto out;" be cleaner error
> handling?  Every error case is getting longer ;)
>
>> +	}
>> +
>> +	memset(&get_ri, 0, sizeof(get_ri));
>> +	get_ri.root_id = sv_id;
>> +
>> +	if (btrfs_get_subvol(mntfd, &get_ri)) {
>> +		fprintf(stderr, "ERROR: can't find '%s'\n",
>> +			svpath);
>> +		close(fd);
>> +		close(mntfd);
>> +		free(fullpath);
>> +		free(mnt);
>> +		return 1;
>> +	}
>> +
>> +	/* print the info */
>> +	printf("%s", fullpath);
>> +	printf("\n");
>
> maybe   printf("%s\n", fullpath); ?
>
>> +
>> +	printf("\t");
>> +	printf("Name: \t\t\t%s", get_ri.name);
>> +	printf("\n");
>
> and printf("\tName: \t\t\t%s\n", get_ri.name);
> etc -
> or is there some reason for the single-char-printfs?
>
>> +
>> +	if (uuid_is_null(get_ri.uuid))
>> +		strcpy(uuidparse, "-");
>> +	else
>> +		uuid_unparse(get_ri.uuid, uuidparse);
>> +	printf("\t");
>> +	printf("uuid: \t\t\t%s", uuidparse);
>> +	printf("\n");
>> +
>> +        if (uuid_is_null(get_ri.puuid))
>> +                strcpy(uuidparse, "-");
>> +        else
>> +                uuid_unparse(get_ri.puuid, uuidparse);
>
> s/tabs/spaces/ here?
>
>> +	printf("\t");
>> +	printf("Parent uuid: \t\t%s", uuidparse);
>> +	printf("\n");
>> +
>> +	if (get_ri.otime)
>> +		strftime(tstr, 256, "%Y-%m-%d %X",
>> +			 localtime(&get_ri.otime));
>> +	else
>> +		strcpy(tstr, "-");
>> +	printf("\t");
>> +	printf("Creation time: \t\t%s", tstr);
>> +	printf("\n");
>> +
>> +	printf("\t");
>> +	printf("Object ID: \t\t%llu", get_ri.root_id);
>> +	printf("\n");
>> +
>> +	printf("\t");
>> +	printf("Generation (Gen): \t%llu", get_ri.gen);
>> +	printf("\n");
>> +
>> +	printf("\t");
>> +	printf("Gen at creation: \t%llu", get_ri.ogen);
>> +	printf("\n");
>> +
>> +	printf("\t");
>> +	printf("Parent: \t\t%llu", get_ri.ref_tree);
>> +	printf("\n");
>> +
>> +	printf("\t");
>> +	printf("Top Level: \t\t%llu", get_ri.top_id);
>> +	printf("\n");
>> +
>> +	/* print the snapshots of the given subvol if any*/
>> +	printf("\t");
>> +	printf("Snapshot(s):\n");
>> +	filter_set = btrfs_list_alloc_filter_set();
>> +	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
>> +				get_ri.uuid);
>> +	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
>> +	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
>> +			raw_prefix);
>> +
>> +	/* clean up */
>> +	if (get_ri.path)
>> +		free(get_ri.path);
>> +	if (get_ri.name)
>> +		free(get_ri.name);
>> +	if (get_ri.full_path)
>> +		free(get_ri.full_path);
>> +
>> +	close(fd);
>> +	close(mntfd);
>> +	free(mnt);
>> +	free(fullpath);
>> +	return 0;
>> +}
>> +
>>   const struct cmd_group subvolume_cmd_group = {
>>   	subvolume_cmd_group_usage, NULL, {
>>   		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
>> @@ -732,6 +901,7 @@ const struct cmd_group subvolume_cmd_group = {
>>   		{ "set-default", cmd_subvol_set_default,
>>   			cmd_subvol_set_default_usage, NULL, 0 },
>>   		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
>> +		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
>>   		{ 0, 0, 0, 0, 0 }
>>   	}
>>   };
>> diff --git a/man/btrfs.8.in b/man/btrfs.8.in
>> index 9222580..57c25b0 100644
>> --- a/man/btrfs.8.in
>> +++ b/man/btrfs.8.in
>> @@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
>>   .PP
>>   \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
>>   .PP
>> +\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
>> +.PP
>>   \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
>>   [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
>>   [<\fIfile\fR>|<\fIdir\fR>...]
>> @@ -160,6 +162,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
>>   is similar to \fBsubvolume list\fR command.
>>   .TP
>>
>> +\fBsubvolume show\fR\fI <path>\fR
>> +Show information of a given subvolume in the \fI<path>\fR.
>> +.TP
>> +
>>   \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
>>   [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
>>
>>
>
> --
> 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-info.html
>

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

* [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (21 preceding siblings ...)
  2013-01-25  9:19   ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
@ 2013-01-25  9:30   ` Anand Jain
  2013-01-25  9:30     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
                       ` (9 more replies)
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
                     ` (4 subsequent siblings)
  27 siblings, 10 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Here is the V2 of this patch-set, kindly review and accept.

v1->v2:
 . 2nd attempt to Rebase to
        git://repo.or.cz/btrfs-progs-unstable/devel.git for-chris
 and
 . Accepts Eric's review comments.

Thanks

Anand Jain (10):
  Btrfs-progs: move open_file_or_dir() to utils.c
  Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  Btrfs-progs: add parent uuid for snapshots
  Btrfs-progs: move struct root_info to btrfs-list.h
  Btrfs-progs: add function btrfs_get_subvol to get root_info of a
    subvol
  Btrfs-progs: add method to filter snapshots by parent uuid
  Btrfs-progs: put find_mount_root() in commands.h
  Btrfs-progs: make printing subvol extensible to newer layouts
  Btrfs-progs: make get_subvol_name non cmds-send specific
  Btrfs-progs: add show subcommand to subvol cli

 Makefile         |   4 +-
 btrfs-list.c     | 192 +++++++++++++++++++++++++++++++++--------------------
 btrfs-list.h     |  58 +++++++++++++++-
 btrfsctl.c       |   7 +-
 cmds-balance.c   |   1 +
 cmds-inspect.c   |   1 +
 cmds-qgroup.c    |   1 +
 cmds-quota.c     |   1 +
 cmds-send.c      |  12 ++--
 cmds-subvolume.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 commands.h       |   7 +-
 common.c         |  46 -------------
 man/btrfs.8.in   |   6 ++
 utils.c          |  30 ++++++++-
 utils.h          |   5 +-
 15 files changed, 425 insertions(+), 142 deletions(-)
 delete mode 100644 common.c

-- 
1.8.1.227.g44fe835


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

* [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25  9:30     ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

The definition of the function open_file_or_dir() is moved from common.c
to utils.c in order to be able to share some common code between scrub
and the device stats in the following step. That common code uses
open_file_or_dir(). Since open_file_or_dir() makes use of the function
dirfd(3), the required XOPEN version was raised from 6 to 7.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Original-Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
 Makefile         |  4 ++--
 btrfsctl.c       |  7 ++++---
 cmds-balance.c   |  1 +
 cmds-inspect.c   |  1 +
 cmds-qgroup.c    |  1 +
 cmds-quota.c     |  1 +
 cmds-subvolume.c |  1 +
 commands.h       |  3 ---
 common.c         | 46 ----------------------------------------------
 utils.c          | 30 ++++++++++++++++++++++++++++--
 utils.h          |  5 +++--
 11 files changed, 42 insertions(+), 58 deletions(-)
 delete mode 100644 common.c

diff --git a/Makefile b/Makefile
index 4894903..8576d90 100644
--- a/Makefile
+++ b/Makefile
@@ -41,8 +41,8 @@ all: version $(progs) manpages
 version:
 	bash version.sh
 
-btrfs: $(objects) btrfs.o help.o common.o $(cmds_objects)
-	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o common.o $(cmds_objects) \
+btrfs: $(objects) btrfs.o help.o $(cmds_objects)
+	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o $(cmds_objects) \
 		$(objects) $(LDFLAGS) $(LIBS) -lpthread
 
 calc-size: $(objects) calc-size.o
diff --git a/btrfsctl.c b/btrfsctl.c
index 518684c..049a5f3 100644
--- a/btrfsctl.c
+++ b/btrfsctl.c
@@ -63,7 +63,7 @@ static void print_usage(void)
 	exit(1);
 }
 
-static int open_file_or_dir(const char *fname)
+static int btrfsctl_open_file_or_dir(const char *fname)
 {
 	int ret;
 	struct stat st;
@@ -91,6 +91,7 @@ static int open_file_or_dir(const char *fname)
 	}
 	return fd;
 }
+
 int main(int ac, char **av)
 {
 	char *fname = NULL;
@@ -128,7 +129,7 @@ int main(int ac, char **av)
 			snap_location = strdup(fullpath);
 			snap_location = dirname(snap_location);
 
-			snap_fd = open_file_or_dir(snap_location);
+			snap_fd = btrfsctl_open_file_or_dir(snap_location);
 
 			name = strdup(fullpath);
 			name = basename(name);
@@ -238,7 +239,7 @@ int main(int ac, char **av)
 		}
 		name = fname;
 	 } else {
-		fd = open_file_or_dir(fname);
+		fd = btrfsctl_open_file_or_dir(fname);
 	 }
 
 	if (name) {
diff --git a/cmds-balance.c b/cmds-balance.c
index 38a7426..6268b61 100644
--- a/cmds-balance.c
+++ b/cmds-balance.c
@@ -28,6 +28,7 @@
 #include "volumes.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const balance_cmd_group_usage[] = {
 	"btrfs [filesystem] balance <command> [options] <path>",
diff --git a/cmds-inspect.c b/cmds-inspect.c
index 25b83d2..f10bf55 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -23,6 +23,7 @@
 
 #include "kerncompat.h"
 #include "ioctl.h"
+#include "utils.h"
 
 #include "commands.h"
 #include "btrfs-list.h"
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 1525c11..cafc284 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -24,6 +24,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const qgroup_cmd_group_usage[] = {
 	"btrfs qgroup <command> [options] <path>",
diff --git a/cmds-quota.c b/cmds-quota.c
index cf9ad97..8481514 100644
--- a/cmds-quota.c
+++ b/cmds-quota.c
@@ -23,6 +23,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const quota_cmd_group_usage[] = {
 	"btrfs quota <command> [options] <path>",
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index ac39f7b..e3cdb1e 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -32,6 +32,7 @@
 #include "ctree.h"
 #include "commands.h"
 #include "btrfs-list.h"
+#include "utils.h"
 
 static const char * const subvolume_cmd_group_usage[] = {
 	"btrfs subvolume <command> <args>",
diff --git a/commands.h b/commands.h
index bb6d2dd..8114a73 100644
--- a/commands.h
+++ b/commands.h
@@ -79,9 +79,6 @@ void help_ambiguous_token(const char *arg, const struct cmd_group *grp);
 
 void help_command_group(const struct cmd_group *grp, int argc, char **argv);
 
-/* common.c */
-int open_file_or_dir(const char *fname);
-
 extern const struct cmd_group subvolume_cmd_group;
 extern const struct cmd_group filesystem_cmd_group;
 extern const struct cmd_group balance_cmd_group;
diff --git a/common.c b/common.c
deleted file mode 100644
index 03f6570..0000000
--- a/common.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-
-int open_file_or_dir(const char *fname)
-{
-	int ret;
-	struct stat st;
-	DIR *dirstream;
-	int fd;
-
-	ret = stat(fname, &st);
-	if (ret < 0) {
-		return -1;
-	}
-	if (S_ISDIR(st.st_mode)) {
-		dirstream = opendir(fname);
-		if (!dirstream) {
-			return -2;
-		}
-		fd = dirfd(dirstream);
-	} else {
-		fd = open(fname, O_RDWR);
-	}
-	if (fd < 0) {
-		return -3;
-	}
-	return fd;
-}
diff --git a/utils.c b/utils.c
index 938f9a5..78530e1 100644
--- a/utils.c
+++ b/utils.c
@@ -16,8 +16,9 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#define _XOPEN_SOURCE 600
-#define __USE_XOPEN2K
+#define _XOPEN_SOURCE 700
+#define __USE_XOPEN2K8
+#define __XOPEN2K8 /* due to an error in dirent.h, to get dirfd() */
 #include <stdio.h>
 #include <stdlib.h>
 #ifndef __CHECKER__
@@ -1268,3 +1269,28 @@ u64 parse_size(char *s)
 	return strtoull(s, NULL, 10) * mult;
 }
 
+int open_file_or_dir(const char *fname)
+{
+	int ret;
+	struct stat st;
+	DIR *dirstream;
+	int fd;
+
+	ret = stat(fname, &st);
+	if (ret < 0) {
+		return -1;
+	}
+	if (S_ISDIR(st.st_mode)) {
+		dirstream = opendir(fname);
+		if (!dirstream) {
+			return -2;
+		}
+		fd = dirfd(dirstream);
+	} else {
+		fd = open(fname, O_RDWR);
+	}
+	if (fd < 0) {
+		return -3;
+	}
+	return fd;
+}
diff --git a/utils.h b/utils.h
index 714fd7a..ed43e84 100644
--- a/utils.h
+++ b/utils.h
@@ -19,6 +19,8 @@
 #ifndef __UTILS__
 #define __UTILS__
 
+#include "ctree.h"
+
 #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024)
 
 int make_btrfs(int fd, const char *device, const char *label,
@@ -44,8 +46,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
 char *pretty_sizes(u64 size);
 int check_label(char *input);
 int get_mountpt(char *dev, char *mntpt, size_t size);
-
 int btrfs_scan_block_devices(int run_ioctl);
-
 u64 parse_size(char *s);
+int open_file_or_dir(const char *fname);
 #endif
-- 
1.8.1.227.g44fe835


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

* [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
  2013-01-25  9:30     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25  9:30     ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
                       ` (7 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

To improve the code reuse its better to have btrfs_list_subvols
just return list of subvols witout printing

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 28 ++++++++++++++++++----------
 btrfs-list.h     |  2 +-
 cmds-subvolume.c |  4 ++--
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index cb42fbc..b404e1d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1439,15 +1439,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 	}
 }
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
-		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 {
-	struct root_lookup root_lookup;
-	struct root_lookup root_sort;
 	int ret;
 
-	ret = __list_subvol_search(fd, &root_lookup);
+	ret = __list_subvol_search(fd, root_lookup);
 	if (ret) {
 		fprintf(stderr, "ERROR: can't perform the search - %s\n",
 				strerror(errno));
@@ -1458,16 +1454,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
 	 * now we have an rbtree full of root_info objects, but we need to fill
 	 * in their path names within the subvol that is referencing each one.
 	 */
-	ret = __list_subvol_fill_paths(fd, &root_lookup);
-	if (ret < 0)
-		return ret;
+	ret = __list_subvol_fill_paths(fd, root_lookup);
+	return ret;
+}
 
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
+		       struct btrfs_list_comparer_set *comp_set,
+		       int is_tab_result)
+{
+	struct root_lookup root_lookup;
+	struct root_lookup root_sort;
+	int ret;
+
+	ret = btrfs_list_subvols(fd, &root_lookup);
+	if (ret)
+		return ret;
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
 	print_all_volume_info(&root_sort, is_tab_result);
 	__free_all_subvolumn(&root_lookup);
-	return ret;
+
+	return 0;
 }
 
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
diff --git a/btrfs-list.h b/btrfs-list.h
index cde4b3c..71fe0f3 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 			      enum btrfs_list_comp_enum comparer,
 			      int is_descending);
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
 			int is_tab_result);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index e3cdb1e..c35dff7 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
+	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				is_tab_result);
 	if (ret)
 		return 19;
@@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
  2013-01-25  9:30     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
  2013-01-25  9:30     ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25  9:30     ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
                       ` (6 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 34 ++++++++++++++++++++++++++++------
 btrfs-list.h     |  1 +
 cmds-subvolume.c |  6 +++++-
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index b404e1d..13a365d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -80,6 +80,7 @@ struct root_info {
 	time_t otime;
 
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	/* path from the subvol we live in to this root, including the
 	 * root's name.  This is null until we do the extra lookup ioctl.
@@ -128,6 +129,11 @@ struct {
 		.need_print	= 0,
 	},
 	{
+		.name		= "parent_uuid",
+		.column_name	= "Parent UUID",
+		.need_print	= 0,
+	},
+	{
 		.name		= "uuid",
 		.column_name	= "UUID",
 		.need_print	= 0,
@@ -435,7 +441,7 @@ static struct root_info *root_tree_search(struct root_lookup *root_tree,
 static int update_root(struct root_lookup *root_lookup,
 		       u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		       u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		       time_t ot, void *uuid)
+		       time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 
@@ -472,6 +478,8 @@ static int update_root(struct root_lookup *root_lookup,
 		ri->otime = ot;
 	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
 
 	return 0;
 }
@@ -489,17 +497,18 @@ static int update_root(struct root_lookup *root_lookup,
  * gen: the current generation of the root
  * ot: the original time(create time) of the root
  * uuid: uuid of the root
+ * puuid: uuid of the root parent if any
  */
 static int add_root(struct root_lookup *root_lookup,
 		    u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		    u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		    time_t ot, void *uuid)
+		    time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 	int ret;
 
 	ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
-			  dir_id, name, name_len, ogen, gen, ot, uuid);
+			  dir_id, name, name_len, ogen, gen, ot, uuid, puuid);
 	if (!ret)
 		return 0;
 
@@ -537,9 +546,12 @@ static int add_root(struct root_lookup *root_lookup,
 	if (ot)
 		ri->otime = ot;
 
-	if (uuid) 
+	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
 
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
+
 	ret = root_tree_insert(root_lookup, ri);
 	if (ret) {
 		printf("failed to insert tree %llu\n", (unsigned long long)root_id);
@@ -1021,6 +1033,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 	int i;
 	time_t t;
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	root_lookup_init(root_lookup);
 	memset(&args, 0, sizeof(args));
@@ -1073,7 +1086,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 
 				add_root(root_lookup, sh.objectid, sh.offset,
 					 0, 0, dir_id, name, name_len, 0, 0, 0,
-					 NULL);
+					 NULL, NULL);
 			} else if (sh.type == BTRFS_ROOT_ITEM_KEY) {
 				ri = (struct btrfs_root_item *)(args.buf + off);
 				gen = btrfs_root_generation(ri);
@@ -1083,15 +1096,17 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 					t = ri->otime.sec;
 					ogen = btrfs_root_otransid(ri);
 					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
+					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
 				} else {
 					t = 0;
 					ogen = 0;
 					memset(uuid, 0, BTRFS_UUID_SIZE);
+					memset(puuid, 0, BTRFS_UUID_SIZE);
 				}
 
 				add_root(root_lookup, sh.objectid, 0,
 					 sh.offset, flags, 0, NULL, 0, ogen,
-					 gen, t, uuid);
+					 gen, t, uuid, puuid);
 			}
 
 			off += sh.len;
@@ -1345,6 +1360,13 @@ static void print_subvolume_column(struct root_info *subv,
 			uuid_unparse(subv->uuid, uuidparse);
 		printf("%s", uuidparse);
 		break;
+	case BTRFS_LIST_PUUID:
+		if (uuid_is_null(subv->puuid))
+			strcpy(uuidparse, "-");
+		else
+			uuid_unparse(subv->puuid, uuidparse);
+		printf("%s", uuidparse);
+		break;
 	case BTRFS_LIST_PATH:
 		BUG_ON(!subv->full_path);
 		printf("%s", subv->full_path);
diff --git a/btrfs-list.h b/btrfs-list.h
index 71fe0f3..855e73d 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -53,6 +53,7 @@ enum btrfs_list_column_enum {
 	BTRFS_LIST_PARENT,
 	BTRFS_LIST_TOP_LEVEL,
 	BTRFS_LIST_OTIME,
+	BTRFS_LIST_PUUID,
 	BTRFS_LIST_UUID,
 	BTRFS_LIST_PATH,
 	BTRFS_LIST_ALL,
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index c35dff7..a1e6893 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -280,6 +280,7 @@ static const char * const cmd_subvol_list_usage[] = {
 	"-p           print parent ID",
 	"-a           print all the subvolumes in the filesystem.",
 	"-u           print the uuid of subvolumes (and snapshots)",
+	"-q           print the parent uuid of the snapshots",
 	"-t           print the result as a table",
 	"-s           list snapshots only in the filesystem",
 	"-r           list readonly subvolumes (including snapshots)",
@@ -319,7 +320,7 @@ static int cmd_subvol_list(int argc, char **argv)
 	optind = 1;
 	while(1) {
 		c = getopt_long(argc, argv,
-				    "apsurg:c:t", long_options, NULL);
+				    "apsuqrg:c:t", long_options, NULL);
 		if (c < 0)
 			break;
 
@@ -343,6 +344,9 @@ static int cmd_subvol_list(int argc, char **argv)
 		case 'u':
 			btrfs_list_setup_print_column(BTRFS_LIST_UUID);
 			break;
+		case 'q':
+			btrfs_list_setup_print_column(BTRFS_LIST_PUUID);
+			break;
 		case 'r':
 			flags |= BTRFS_ROOT_SUBVOL_RDONLY;
 			break;
-- 
1.8.1.227.g44fe835


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

* [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
                       ` (2 preceding siblings ...)
  2013-01-25  9:30     ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25  9:30     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
                       ` (5 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

As we would add more ways to list and manage the subvols
and snapshots, its better if we have struct root_info
defined in the header file.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 47 -----------------------------------------------
 btrfs-list.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 13a365d..909d814 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -46,53 +46,6 @@ struct root_lookup {
 	struct rb_root root;
 };
 
-/*
- * one of these for each root we find.
- */
-struct root_info {
-	struct rb_node rb_node;
-	struct rb_node sort_node;
-
-	/* this root's id */
-	u64 root_id;
-
-	/* equal the offset of the root's key */
-	u64 root_offset;
-
-	/* flags of the root */
-	u64 flags;
-
-	/* the id of the root that references this one */
-	u64 ref_tree;
-
-	/* the dir id we're in from ref_tree */
-	u64 dir_id;
-
-	u64 top_id;
-
-	/* generation when the root is created or last updated */
-	u64 gen;
-
-	/* creation generation of this root in sec*/
-	u64 ogen;
-
-	/* creation time of this root in sec*/
-	time_t otime;
-
-	u8 uuid[BTRFS_UUID_SIZE];
-	u8 puuid[BTRFS_UUID_SIZE];
-
-	/* path from the subvol we live in to this root, including the
-	 * root's name.  This is null until we do the extra lookup ioctl.
-	 */
-	char *path;
-
-	/* the name of this root in the directory it lives in */
-	char *name;
-
-	char *full_path;
-};
-
 struct {
 	char	*name;
 	char	*column_name;
diff --git a/btrfs-list.h b/btrfs-list.h
index 855e73d..3b7b680 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,7 +18,52 @@
 
 #include "kerncompat.h"
 
-struct root_info;
+/*
+ * one of these for each root we find.
+ */
+struct root_info {
+	struct rb_node rb_node;
+	struct rb_node sort_node;
+
+	/* this root's id */
+	u64 root_id;
+
+	/* equal the offset of the root's key */
+	u64 root_offset;
+
+	/* flags of the root */
+	u64 flags;
+
+	/* the id of the root that references this one */
+	u64 ref_tree;
+
+	/* the dir id we're in from ref_tree */
+	u64 dir_id;
+
+	u64 top_id;
+
+	/* generation when the root is created or last updated */
+	u64 gen;
+
+	/* creation generation of this root in sec*/
+	u64 ogen;
+
+	/* creation time of this root in sec*/
+	time_t otime;
+
+	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
+
+	/* path from the subvol we live in to this root, including the
+	 * root's name.  This is null until we do the extra lookup ioctl.
+	 */
+	char *path;
+
+	/* the name of this root in the directory it lives in */
+	char *name;
+
+	char *full_path;
+};
 
 typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
 typedef int (*btrfs_list_comp_func)(struct root_info *, struct root_info *,
-- 
1.8.1.227.g44fe835


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

* [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
                       ` (3 preceding siblings ...)
  2013-01-25  9:30     ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25  9:30     ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
                       ` (4 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

We need a function which can get the root_info of a given
subvol. This is in preparation to add support for the show
sub-cli.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
 btrfs-list.h |  1 +
 2 files changed, 39 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 909d814..0ee13b6 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1453,6 +1453,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	return 0;
 }
 
+int btrfs_get_subvol(int fd, struct root_info *the_ri)
+{
+	int ret = -1;
+	struct root_lookup rl;
+	struct rb_node *rbn;
+	struct root_info *ri;
+	u64 root_id = btrfs_list_get_path_rootid(fd);
+
+	if (btrfs_list_subvols(fd, &rl))
+		return 1;
+
+	rbn = rb_first(&rl.root);
+	while(rbn) {
+		ri = rb_entry(rbn, struct root_info, rb_node);
+		resolve_root(&rl, ri, root_id);
+		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
+			memcpy(the_ri, ri, offsetof(struct root_info, path));
+			if (ri->path)
+				the_ri->path = strdup(ri->path);
+			else
+				the_ri->path = NULL;
+			if (ri->name)
+				the_ri->name = strdup(ri->name);
+			else
+				the_ri->name = NULL;
+			if (ri->full_path)
+				the_ri->full_path = strdup(ri->full_path);
+			else
+				the_ri->name = NULL;
+			ret = 0;
+			break;
+		}
+		rbn = rb_next(rbn);
+	}
+	__free_all_subvolumn(&rl);
+	return ret;
+}
+
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 			    struct btrfs_file_extent_item *item,
 			    u64 found_gen, u64 *cache_dirid,
diff --git a/btrfs-list.h b/btrfs-list.h
index 3b7b680..580d4d1 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
 u64 btrfs_list_get_path_rootid(int fd);
+int btrfs_get_subvol(int fd, struct root_info *the_ri);
-- 
1.8.1.227.g44fe835


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

* [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
                       ` (4 preceding siblings ...)
  2013-01-25  9:30     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25  9:30     ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
                       ` (3 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 6 ++++++
 btrfs-list.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 0ee13b6..9c84ecb 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1142,6 +1142,11 @@ static int filter_topid_equal(struct root_info *ri, u64 data)
 	return ri->top_id == data;
 }
 
+static int filter_by_parent(struct root_info *ri, u64 data)
+{
+	return !uuid_compare(ri->puuid, (u8 *)data);
+}
+
 static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_ROOTID]		= filter_by_rootid,
 	[BTRFS_LIST_FILTER_SNAPSHOT_ONLY]	= filter_snapshot,
@@ -1153,6 +1158,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_CGEN_LESS]		= filter_cgen_less,
 	[BTRFS_LIST_FILTER_CGEN_EQUAL]          = filter_cgen_equal,
 	[BTRFS_LIST_FILTER_TOPID_EQUAL]		= filter_topid_equal,
+	[BTRFS_LIST_FILTER_BY_PARENT]		= filter_by_parent,
 };
 
 struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
diff --git a/btrfs-list.h b/btrfs-list.h
index 580d4d1..cde7a3f 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -117,6 +117,7 @@ enum btrfs_list_filter_enum {
 	BTRFS_LIST_FILTER_CGEN_LESS,
 	BTRFS_LIST_FILTER_CGEN_MORE,
 	BTRFS_LIST_FILTER_TOPID_EQUAL,
+	BTRFS_LIST_FILTER_BY_PARENT,
 	BTRFS_LIST_FILTER_MAX,
 };
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
                       ` (5 preceding siblings ...)
  2013-01-25  9:30     ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25  9:30     ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
                       ` (2 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

A useful function need to define it in a header file.

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

diff --git a/commands.h b/commands.h
index 8114a73..9b77f3e 100644
--- a/commands.h
+++ b/commands.h
@@ -103,3 +103,6 @@ int cmd_qgroup(int argc, char **argv);
 
 /* subvolume exported functions */
 int test_issubvolume(char *path);
+
+/* send.c */
+int find_mount_root(const char *path, char **mount_root);
-- 
1.8.1.227.g44fe835


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

* [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
                       ` (6 preceding siblings ...)
  2013-01-25  9:30     ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25  9:30     ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
  2013-01-25  9:30     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

Currently you can print subvol in a list or table format.
This patch will provide a way to extend this to other formats
like the upcoming raw format.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 26 +++++++++++++++-----------
 btrfs-list.h     |  3 +++
 cmds-subvolume.c | 23 ++++++++++++++++++++---
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 9c84ecb..656de10 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -54,12 +54,12 @@ struct {
 	{
 		.name		= "ID",
 		.column_name	= "ID",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "gen",
 		.column_name	= "Gen",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "cgen",
@@ -74,7 +74,7 @@ struct {
 	{
 		.name		= "top level",
 		.column_name	= "Top Level",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "otime",
@@ -94,7 +94,7 @@ struct {
 	{
 		.name		= "path",
 		.column_name	= "Path",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= NULL,
@@ -1401,21 +1401,25 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int is_tab_result)
+				  int layout)
 {
 	struct rb_node *n;
 	struct root_info *entry;
 
-	if (is_tab_result)
+	if (layout == BTRFS_LIST_LAYOUT_TABLE)
 		print_all_volume_info_tab_head();
 
 	n = rb_first(&sorted_tree->root);
 	while (n) {
 		entry = rb_entry(n, struct root_info, sort_node);
-		if (is_tab_result)
-			print_single_volume_info_table(entry);
-		else
+		switch (layout) {
+		case BTRFS_LIST_LAYOUT_DEFAULT:
 			print_single_volume_info_default(entry);
+			break;
+		case BTRFS_LIST_LAYOUT_TABLE:
+			print_single_volume_info_table(entry);
+			break;
+		}
 		n = rb_next(n);
 	}
 }
@@ -1441,7 +1445,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+		       int layout)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1453,7 +1457,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, is_tab_result);
+	print_all_volume_info(&root_sort, layout);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index cde7a3f..5b60068 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,6 +18,9 @@
 
 #include "kerncompat.h"
 
+#define BTRFS_LIST_LAYOUT_DEFAULT	0
+#define BTRFS_LIST_LAYOUT_TABLE	1
+
 /*
  * one of these for each root we find.
  */
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index a1e6893..bb9629f 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -410,8 +410,18 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				is_tab_result);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	if (is_tab_result)
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_TABLE);
+	else
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
@@ -617,7 +627,14 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
+		BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
                       ` (7 preceding siblings ...)
  2013-01-25  9:30     ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25  9:30     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

get_subvol_name can be used other than the just with in cmds-send.c
so this patch will make it possible with out changing the original
intentions.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-send.c | 12 ++++++------
 commands.h  |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/cmds-send.c b/cmds-send.c
index ac1d3cf..0416b79 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -333,12 +333,12 @@ out:
 	return ret;
 }
 
-static const char *get_subvol_name(struct btrfs_send *s, const char *full_path)
+char *get_subvol_name(char *mnt, char *full_path)
 {
-	int len = strlen(s->root_path);
+	int len = strlen(mnt);
 	if (!len)
 		return full_path;
-	if (s->root_path[len - 1] != '/')
+	if (mnt[len - 1] != '/')
 		len += 1;
 
 	return full_path + len;
@@ -452,7 +452,7 @@ int cmd_send_start(int argc, char **argv)
 			if (ret < 0)
 				goto out;
 
-			ret = get_root_id(&send, get_subvol_name(&send, subvol),
+			ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 					&root_id);
 			if (ret < 0) {
 				fprintf(stderr, "ERROR: could not resolve "
@@ -513,7 +513,7 @@ int cmd_send_start(int argc, char **argv)
 
 	if (snapshot_parent != NULL) {
 		ret = get_root_id(&send,
-				get_subvol_name(&send, snapshot_parent),
+				get_subvol_name(send.root_path, snapshot_parent),
 				&parent_root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
@@ -572,7 +572,7 @@ int cmd_send_start(int argc, char **argv)
 			goto out;
 		}
 
-		ret = get_root_id(&send, get_subvol_name(&send, subvol),
+		ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 				&root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
diff --git a/commands.h b/commands.h
index 9b77f3e..631fb6b 100644
--- a/commands.h
+++ b/commands.h
@@ -106,3 +106,4 @@ int test_issubvolume(char *path);
 
 /* send.c */
 int find_mount_root(const char *path, char **mount_root);
+char *get_subvol_name(char *mnt, char *full_path);
-- 
1.8.1.227.g44fe835


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

* [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
                       ` (8 preceding siblings ...)
  2013-01-25  9:30     ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
@ 2013-01-25  9:30     ` Anand Jain
  2013-01-25 10:07       ` Stefan Behrens
  9 siblings, 1 reply; 131+ messages in thread
From: Anand Jain @ 2013-01-25  9:30 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene; +Cc: Anand Jain

This adds show sub-command to the btrfs subvol cli
to display detailed inforamtion of the given subvol
or snapshot.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     |  25 +++++++-
 btrfs-list.h     |   3 +-
 cmds-subvolume.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 man/btrfs.8.in   |   6 ++
 4 files changed, 199 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 656de10..1915ece 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1335,6 +1335,22 @@ static void print_subvolume_column(struct root_info *subv,
 	}
 }
 
+static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_LIST_ALL; i++) {
+		if (!btrfs_list_columns[i].need_print)
+			continue;
+
+		if (raw_prefix)
+			printf("%s",raw_prefix);
+
+		print_subvolume_column(subv, i);
+	}
+	printf("\n");
+}
+
 static void print_single_volume_info_table(struct root_info *subv)
 {
 	int i;
@@ -1401,7 +1417,7 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int layout)
+				  int layout, char *raw_prefix)
 {
 	struct rb_node *n;
 	struct root_info *entry;
@@ -1419,6 +1435,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 		case BTRFS_LIST_LAYOUT_TABLE:
 			print_single_volume_info_table(entry);
 			break;
+		case BTRFS_LIST_LAYOUT_RAW:
+			print_single_volume_info_raw(entry, raw_prefix);
+			break;
 		}
 		n = rb_next(n);
 	}
@@ -1445,7 +1464,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int layout)
+		       int layout, char *raw_prefix)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1457,7 +1476,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, layout);
+	print_all_volume_info(&root_sort, layout, raw_prefix);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index 5b60068..09d35f7 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -20,6 +20,7 @@
 
 #define BTRFS_LIST_LAYOUT_DEFAULT	0
 #define BTRFS_LIST_LAYOUT_TABLE	1
+#define BTRFS_LIST_LAYOUT_RAW		2
 
 /*
  * one of these for each root we find.
@@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-			int is_tab_result);
+			int layout, char *raw_prefix);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index bb9629f..ad6afbc 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -24,6 +24,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
+#include <uuid/uuid.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
 
 	if (is_tab_result)
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_TABLE);
+				BTRFS_LIST_LAYOUT_TABLE, NULL);
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_DEFAULT);
+				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
-		BTRFS_LIST_LAYOUT_DEFAULT);
+		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -721,6 +722,170 @@ static int cmd_find_new(int argc, char **argv)
 	return 0;
 }
 
+static const char * const cmd_subvol_show_usage[] = {
+	"btrfs subvolume show <subvol-path>",
+	"Show more information of the subvolume",
+	NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+	struct root_info get_ri;
+	struct btrfs_list_filter_set *filter_set;
+	char tstr[256];
+	char uuidparse[37];
+	char *fullpath, *svpath, *mnt = NULL;
+	char raw_prefix[] = "\t\t\t\t";
+	u64 sv_id, mntid;
+	int fd, mntfd;
+	int ret;
+	int clean = 0;
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_subvol_show_usage);
+
+	fullpath = realpath(argv[1],0);
+	if (!fullpath) {
+		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
+			argv[1], strerror(errno));
+		return 1;
+	}
+	clean++;
+
+	ret = test_issubvolume(fullpath);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
+		ret = 1;
+		goto out;
+	}
+	if (!ret) {
+		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
+		ret = 1;
+		goto out;
+	}
+
+	ret = find_mount_root(fullpath, &mnt);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
+				"%s\n", fullpath, strerror(-ret));
+		ret = 1;
+		goto out;
+	}
+	clean++;
+
+	svpath = get_subvol_name(mnt, fullpath);
+
+	fd = open_file_or_dir(fullpath);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
+		ret = 1;
+		goto out;
+	}
+	clean++;
+
+	sv_id = btrfs_list_get_path_rootid(fd);
+	if (sv_id < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
+			fullpath);
+		ret = 1;
+		goto out;
+	}
+
+	mntfd = open_file_or_dir(mnt);
+	if (mntfd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
+		ret = 1;
+		goto out;
+	}
+	clean++;
+
+	mntid = btrfs_list_get_path_rootid(mntfd);
+	if (mntid < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
+		ret = 1;
+		goto out;
+	}
+
+	if (sv_id == 5) {
+		printf("%s is btrfs root\n", fullpath);
+		ret = 1;
+		goto out;
+	}
+
+	memset(&get_ri, 0, sizeof(get_ri));
+	get_ri.root_id = sv_id;
+
+	if (btrfs_get_subvol(mntfd, &get_ri)) {
+		fprintf(stderr, "ERROR: can't find '%s'\n",
+			svpath);
+		ret = 1;
+		goto out;
+	}
+
+	ret = 0;
+	/* print the info */
+	printf("%s\n", fullpath);
+	printf("\tName: \t\t\t%s\n", get_ri.name);
+
+	if (uuid_is_null(get_ri.uuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.uuid, uuidparse);
+	printf("\tuuid: \t\t\t%s\n", uuidparse);
+
+	if (uuid_is_null(get_ri.puuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.puuid, uuidparse);
+	printf("\tParent uuid: \t\t%s\n", uuidparse);
+
+	if (get_ri.otime)
+		strftime(tstr, 256, "%Y-%m-%d %X",
+			 localtime(&get_ri.otime));
+	else
+		strcpy(tstr, "-");
+	printf("\tCreation time: \t\t%s\n", tstr);
+
+	printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
+	printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
+	printf("\tGen at creation: \t%llu\n", get_ri.ogen);
+	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
+	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
+
+	/* print the snapshots of the given subvol if any*/
+	printf("\tSnapshot(s):\n");
+	filter_set = btrfs_list_alloc_filter_set();
+	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
+				get_ri.uuid);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
+			raw_prefix);
+
+	/* clean up */
+	if (get_ri.path)
+		free(get_ri.path);
+	if (get_ri.name)
+		free(get_ri.name);
+	if (get_ri.full_path)
+		free(get_ri.full_path);
+
+out:
+	switch (clean) {
+	case 4:
+		close(mntfd);
+	case 3:
+		close(fd);
+	case 2:
+		free(mnt);
+	case 1:
+		free(fullpath);
+		break;
+	default:
+		BUG();
+	}
+	return ret;
+}
+
 const struct cmd_group subvolume_cmd_group = {
 	subvolume_cmd_group_usage, NULL, {
 		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -732,6 +897,7 @@ const struct cmd_group subvolume_cmd_group = {
 		{ "set-default", cmd_subvol_set_default,
 			cmd_subvol_set_default_usage, NULL, 0 },
 		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
+		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
 	}
 };
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index d20e332..0008a06 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
 .PP
+\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
 [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
 [<\fIfile\fR>|<\fIdir\fR>...]
@@ -158,6 +160,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
 is similar to \fBsubvolume list\fR command.
 .TP
 
+\fBsubvolume show\fR\fI <path>\fR
+Show information of a given subvolume in the \fI<path>\fR.
+.TP
+
 \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
 [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
 
-- 
1.8.1.227.g44fe835


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

* Re: [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-25  9:30     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
@ 2013-01-25 10:07       ` Stefan Behrens
  2013-01-28  5:26         ` Anand Jain
  0 siblings, 1 reply; 131+ messages in thread
From: Stefan Behrens @ 2013-01-25 10:07 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba, gene

On Fri, 25 Jan 2013 17:30:39 +0800, Anand Jain wrote:
> This adds show sub-command to the btrfs subvol cli
> to display detailed inforamtion of the given subvol
> or snapshot.
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
>  btrfs-list.c     |  25 +++++++-
>  btrfs-list.h     |   3 +-
>  cmds-subvolume.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  man/btrfs.8.in   |   6 ++
>  4 files changed, 199 insertions(+), 7 deletions(-)
> 
> diff --git a/btrfs-list.c b/btrfs-list.c
> index 656de10..1915ece 100644
> --- a/btrfs-list.c
> +++ b/btrfs-list.c
> @@ -1335,6 +1335,22 @@ static void print_subvolume_column(struct root_info *subv,
>  	}
>  }
>  
> +static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
> +{
> +	int i;
> +
> +	for (i = 0; i < BTRFS_LIST_ALL; i++) {
> +		if (!btrfs_list_columns[i].need_print)
> +			continue;
> +
> +		if (raw_prefix)
> +			printf("%s",raw_prefix);
> +
> +		print_subvolume_column(subv, i);
> +	}
> +	printf("\n");
> +}
> +
>  static void print_single_volume_info_table(struct root_info *subv)
>  {
>  	int i;
> @@ -1401,7 +1417,7 @@ static void print_all_volume_info_tab_head()
>  }
>  
>  static void print_all_volume_info(struct root_lookup *sorted_tree,
> -				  int layout)
> +				  int layout, char *raw_prefix)
>  {
>  	struct rb_node *n;
>  	struct root_info *entry;
> @@ -1419,6 +1435,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
>  		case BTRFS_LIST_LAYOUT_TABLE:
>  			print_single_volume_info_table(entry);
>  			break;
> +		case BTRFS_LIST_LAYOUT_RAW:
> +			print_single_volume_info_raw(entry, raw_prefix);
> +			break;
>  		}
>  		n = rb_next(n);
>  	}
> @@ -1445,7 +1464,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
>  
>  int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  		       struct btrfs_list_comparer_set *comp_set,
> -		       int layout)
> +		       int layout, char *raw_prefix)
>  {
>  	struct root_lookup root_lookup;
>  	struct root_lookup root_sort;
> @@ -1457,7 +1476,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
>  				 comp_set, fd);
>  
> -	print_all_volume_info(&root_sort, layout);
> +	print_all_volume_info(&root_sort, layout, raw_prefix);
>  	__free_all_subvolumn(&root_lookup);
>  
>  	return 0;
> diff --git a/btrfs-list.h b/btrfs-list.h
> index 5b60068..09d35f7 100644
> --- a/btrfs-list.h
> +++ b/btrfs-list.h
> @@ -20,6 +20,7 @@
>  
>  #define BTRFS_LIST_LAYOUT_DEFAULT	0
>  #define BTRFS_LIST_LAYOUT_TABLE	1
> +#define BTRFS_LIST_LAYOUT_RAW		2
>  
>  /*
>   * one of these for each root we find.
> @@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
>  
>  int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  		       struct btrfs_list_comparer_set *comp_set,
> -			int is_tab_result);
> +			int layout, char *raw_prefix);
>  int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
>  int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
>  char *btrfs_list_path_for_root(int fd, u64 root);
> diff --git a/cmds-subvolume.c b/cmds-subvolume.c
> index bb9629f..ad6afbc 100644
> --- a/cmds-subvolume.c
> +++ b/cmds-subvolume.c
> @@ -24,6 +24,7 @@
>  #include <libgen.h>
>  #include <limits.h>
>  #include <getopt.h>
> +#include <uuid/uuid.h>
>  
>  #include "kerncompat.h"
>  #include "ioctl.h"
> @@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
>  
>  	if (is_tab_result)
>  		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
> -				BTRFS_LIST_LAYOUT_TABLE);
> +				BTRFS_LIST_LAYOUT_TABLE, NULL);
>  	else
>  		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
> -				BTRFS_LIST_LAYOUT_DEFAULT);
> +				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
>  	if (ret)
>  		return 19;
>  	return 0;
> @@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
>  	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
>  
>  	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
> -		BTRFS_LIST_LAYOUT_DEFAULT);
> +		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
>  	if (ret)
>  		return 19;
>  	return 0;
> @@ -721,6 +722,170 @@ static int cmd_find_new(int argc, char **argv)
>  	return 0;
>  }
>  
> +static const char * const cmd_subvol_show_usage[] = {
> +	"btrfs subvolume show <subvol-path>",
> +	"Show more information of the subvolume",
> +	NULL
> +};
> +
> +static int cmd_subvol_show(int argc, char **argv)
> +{
> +	struct root_info get_ri;
> +	struct btrfs_list_filter_set *filter_set;
> +	char tstr[256];
> +	char uuidparse[37];
> +	char *fullpath, *svpath, *mnt = NULL;
> +	char raw_prefix[] = "\t\t\t\t";
> +	u64 sv_id, mntid;
> +	int fd, mntfd;
> +	int ret;
> +	int clean = 0;
> +
> +	if (check_argc_exact(argc, 2))
> +		usage(cmd_subvol_show_usage);
> +
> +	fullpath = realpath(argv[1],0);
> +	if (!fullpath) {
> +		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
> +			argv[1], strerror(errno));
> +		return 1;
> +	}
> +	clean++;
> +
> +	ret = test_issubvolume(fullpath);
> +	if (ret < 0) {
> +		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
> +		ret = 1;
> +		goto out;
> +	}
> +	if (!ret) {
> +		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
> +		ret = 1;
> +		goto out;
> +	}
> +
> +	ret = find_mount_root(fullpath, &mnt);
> +	if (ret < 0) {
> +		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
> +				"%s\n", fullpath, strerror(-ret));
> +		ret = 1;
> +		goto out;
> +	}
> +	clean++;
> +
> +	svpath = get_subvol_name(mnt, fullpath);
> +
> +	fd = open_file_or_dir(fullpath);
> +	if (fd < 0) {
> +		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
> +		ret = 1;
> +		goto out;
> +	}
> +	clean++;
> +
> +	sv_id = btrfs_list_get_path_rootid(fd);
> +	if (sv_id < 0) {
> +		fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
> +			fullpath);
> +		ret = 1;
> +		goto out;
> +	}
> +
> +	mntfd = open_file_or_dir(mnt);
> +	if (mntfd < 0) {
> +		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
> +		ret = 1;
> +		goto out;
> +	}
> +	clean++;
> +
> +	mntid = btrfs_list_get_path_rootid(mntfd);
> +	if (mntid < 0) {
> +		fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
> +		ret = 1;
> +		goto out;
> +	}
> +
> +	if (sv_id == 5) {

if (sv_id == BTRFS_FS_TREE_OBJECTID) {

> +		printf("%s is btrfs root\n", fullpath);
> +		ret = 1;
> +		goto out;
> +	}
> +
> +	memset(&get_ri, 0, sizeof(get_ri));
> +	get_ri.root_id = sv_id;
> +
> +	if (btrfs_get_subvol(mntfd, &get_ri)) {
> +		fprintf(stderr, "ERROR: can't find '%s'\n",
> +			svpath);
> +		ret = 1;
> +		goto out;
> +	}
> +
> +	ret = 0;
> +	/* print the info */
> +	printf("%s\n", fullpath);
> +	printf("\tName: \t\t\t%s\n", get_ri.name);
> +
> +	if (uuid_is_null(get_ri.uuid))
> +		strcpy(uuidparse, "-");
> +	else
> +		uuid_unparse(get_ri.uuid, uuidparse);
> +	printf("\tuuid: \t\t\t%s\n", uuidparse);
> +
> +	if (uuid_is_null(get_ri.puuid))
> +		strcpy(uuidparse, "-");
> +	else
> +		uuid_unparse(get_ri.puuid, uuidparse);
> +	printf("\tParent uuid: \t\t%s\n", uuidparse);
> +
> +	if (get_ri.otime)
> +		strftime(tstr, 256, "%Y-%m-%d %X",
> +			 localtime(&get_ri.otime));
> +	else
> +		strcpy(tstr, "-");
> +	printf("\tCreation time: \t\t%s\n", tstr);
> +
> +	printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
> +	printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
> +	printf("\tGen at creation: \t%llu\n", get_ri.ogen);
> +	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
> +	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
> +
> +	/* print the snapshots of the given subvol if any*/
> +	printf("\tSnapshot(s):\n");
> +	filter_set = btrfs_list_alloc_filter_set();
> +	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
> +				get_ri.uuid);
> +	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
> +	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
> +			raw_prefix);
> +
> +	/* clean up */
> +	if (get_ri.path)
> +		free(get_ri.path);
> +	if (get_ri.name)
> +		free(get_ri.name);
> +	if (get_ri.full_path)
> +		free(get_ri.full_path);
> +
> +out:
> +	switch (clean) {
> +	case 4:
> +		close(mntfd);
> +	case 3:
> +		close(fd);
> +	case 2:
> +		free(mnt);
> +	case 1:
> +		free(fullpath);
> +		break;
> +	default:
> +		BUG();
> +	}

The common way to handle it is:
static int cmd_subvol_show(int argc, char **argv)
{
	int mntfd = -1;
	int fd = -1;
	char *mnt = NULL;
	char *fullpath = NULL;

	... everywhere, in case of errors, just goto out;

	mntfd = open...();
	if (mntfd < 0) {
		fprintf...
		goto out;
	}

out:
	if (mntfd >= 0)
		close(mntfd);
	if (fd >= 0)
		close(fd);
	free(mnt);
	free(fullpath);
	return ret;
}

Wherever an error happens inside the function, just goto out. When the
char pointers are not yet allocated, they are still NULL and thus
ignored by free(). If open() failed or the files are not yet opened, the
descriptors are still -1 and close() is not called.

It's basically impossible to add errors if you do it like this :)

> +	return ret;
> +}
> +
>  const struct cmd_group subvolume_cmd_group = {
>  	subvolume_cmd_group_usage, NULL, {
>  		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
> @@ -732,6 +897,7 @@ const struct cmd_group subvolume_cmd_group = {
>  		{ "set-default", cmd_subvol_set_default,
>  			cmd_subvol_set_default_usage, NULL, 0 },
>  		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
> +		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
>  		{ 0, 0, 0, 0, 0 }
>  	}
>  };
> diff --git a/man/btrfs.8.in b/man/btrfs.8.in
> index d20e332..0008a06 100644
> --- a/man/btrfs.8.in
> +++ b/man/btrfs.8.in
> @@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
>  .PP
>  \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
>  .PP
> +\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
> +.PP
>  \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
>  [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
>  [<\fIfile\fR>|<\fIdir\fR>...]
> @@ -158,6 +160,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
>  is similar to \fBsubvolume list\fR command.
>  .TP
>  
> +\fBsubvolume show\fR\fI <path>\fR
> +Show information of a given subvolume in the \fI<path>\fR.
> +.TP
> +
>  \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
>  [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
>  
> 


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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24 19:42           ` Eric Sandeen
  2013-01-24 22:09             ` Goffredo Baroncelli
@ 2013-01-25 15:19             ` Eric Sandeen
  1 sibling, 0 replies; 131+ messages in thread
From: Eric Sandeen @ 2013-01-25 15:19 UTC (permalink / raw)
  To: kreijack
  Cc: Goffredo Baroncelli, Stefan Behrens, Anand Jain, linux-btrfs,
	dsterba, gene

On 1/24/13 1:42 PM, Eric Sandeen wrote:
> On 1/24/13 11:57 AM, Goffredo Baroncelli wrote:
>> On 01/24/2013 10:23 AM, Stefan Behrens wrote:
>>> On Wed, 23 Jan 2013 22:39:29 -0600, Eric Sandeen wrote:
>>>> instead of renaming&  keeping the btrfsctl.c copy
>>>
>>> There is a new momentum to improve the Btrfs-progs quality :)
>>>
>>> IMO, one step is to get rid of the legacy tools and sources. It wastes
>>> time to maintain them and these old tools cause confusion. btrfsctl.c,
>>> btrfs-vol.c and btrfs-show.c are not needed anymore. Please correct me
>>> if there are plans to use these old tools in future Linux distributions.
>>> The "btrfs" tool replaces the legacy "btrfsctl", "btrfs-vol" and
>>> "btrfs-show" tools. Below, the usage text of the old tools is quoted.
>>> All these tasks are also offered in the "btrfs" tool, and this tool is
>>> the newer one.
>>
>> I fully agree: btrfsctl, btrfs-vol, btrfs-show are perfectly replaced by by btrfs. Moreover time to time the patches are more complex than the needing because exists these "legacy" programs.
>>
>> I checked the debian package, and to me seems that there is no need of {btrfsctl,btrfs-vol,btrfs-show}
> 
> Hm, they are shipped in the Fedora package.
> 
> For backwards compat, could those be turned into shell scripts which invoke the btrfs tool?

Turns out anaconda is using btrfsctl for resizing:

class BTRFS(FS):
...
    _resizefs = "btrfsctl"
...
    @property
    def resizeArgs(self):
        argv = ["-r", "%dm" % (self.targetSize,), self.device]
        return argv

but that should be trivial to replace w/ 

    btrfs filesystem resize [devid:][+/-]<newsize>[gkm]|[devid:]max <path>

I'll ping the anaconda guys, don't let this use stop you :)

-Eric



 
> -Eric



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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-24 22:09             ` Goffredo Baroncelli
  2013-01-24 22:36               ` Chris Mason
@ 2013-01-25 16:14               ` Eric Sandeen
  2013-01-25 16:48                 ` Hugo Mills
  1 sibling, 1 reply; 131+ messages in thread
From: Eric Sandeen @ 2013-01-25 16:14 UTC (permalink / raw)
  To: kreijack
  Cc: Goffredo Baroncelli, Goffredo Baroncelli, Stefan Behrens,
	Anand Jain, linux-btrfs, dsterba, gene

On 1/24/13 4:09 PM, Goffredo Baroncelli wrote:
> On 01/24/2013 08:42 PM, Eric Sandeen wrote:
>> On 1/24/13 11:57 AM, Goffredo Baroncelli wrote:
>>> On 01/24/2013 10:23 AM, Stefan Behrens wrote:
>>>> On Wed, 23 Jan 2013 22:39:29 -0600, Eric Sandeen wrote:
>>>>> instead of renaming&   keeping the btrfsctl.c copy
>>>>
>>>> There is a new momentum to improve the Btrfs-progs quality :)
>>>>
>>>> IMO, one step is to get rid of the legacy tools and sources. It
>>>> wastes time to maintain them and these old tools cause confusion.
>>>> btrfsctl.c, btrfs-vol.c and btrfs-show.c are not needed anymore.
>>>> Please correct me if there are plans to use these old tools in
>>>> future Linux distributions. The "btrfs" tool replaces the legacy
>>>> "btrfsctl", "btrfs-vol" and "btrfs-show" tools. Below, the usage
>>>> text of the old tools is quoted. All these tasks are also offered
>>>> in the "btrfs" tool, and this tool is the newer one.
>>>
>>> I fully agree: btrfsctl, btrfs-vol, btrfs-show are perfectly
>>> replaced by by btrfs. Moreover time to time the patches are more
>>> complex than the needing because exists these "legacy" programs.
>>>
>>> I checked the debian package, and to me seems that there is no need
>>> of {btrfsctl,btrfs-vol,btrfs-show}
>>
>> Hm, they are shipped in the Fedora package.
> 
> The same is true for the debian package, but are these used in Fedora ?
> 
>>
>> For backwards compat, could those be turned into shell scripts which
>> invoke the btrfs tool?
> 
> I don't see any gain to maintains a script bash (which has to be
> written from scratch) instead of maintains the current C code.

It should be a trivial bash script to convert the calls, and it should
require very little maintenance.  Much less than the hundreds of lines
of duplicated C code, I think.

If nobody needs them, though, no reason for even a bash script.

David, Suse may be using them now, but probably can adapt?
Anaconda said it could drop the use of btrfsctl.  :)

-Eric



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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-25 16:14               ` Eric Sandeen
@ 2013-01-25 16:48                 ` Hugo Mills
  2013-01-25 18:47                   ` Gene Czarcinski
  0 siblings, 1 reply; 131+ messages in thread
From: Hugo Mills @ 2013-01-25 16:48 UTC (permalink / raw)
  To: Eric Sandeen
  Cc: kreijack, Goffredo Baroncelli, Goffredo Baroncelli,
	Stefan Behrens, Anand Jain, linux-btrfs, dsterba, gene

[-- Attachment #1: Type: text/plain, Size: 2976 bytes --]

On Fri, Jan 25, 2013 at 10:14:06AM -0600, Eric Sandeen wrote:
> On 1/24/13 4:09 PM, Goffredo Baroncelli wrote:
> > On 01/24/2013 08:42 PM, Eric Sandeen wrote:
> >> On 1/24/13 11:57 AM, Goffredo Baroncelli wrote:
> >>> On 01/24/2013 10:23 AM, Stefan Behrens wrote:
> >>>> On Wed, 23 Jan 2013 22:39:29 -0600, Eric Sandeen wrote:
> >>>>> instead of renaming&   keeping the btrfsctl.c copy
> >>>>
> >>>> There is a new momentum to improve the Btrfs-progs quality :)
> >>>>
> >>>> IMO, one step is to get rid of the legacy tools and sources. It
> >>>> wastes time to maintain them and these old tools cause confusion.
> >>>> btrfsctl.c, btrfs-vol.c and btrfs-show.c are not needed anymore.
> >>>> Please correct me if there are plans to use these old tools in
> >>>> future Linux distributions. The "btrfs" tool replaces the legacy
> >>>> "btrfsctl", "btrfs-vol" and "btrfs-show" tools. Below, the usage
> >>>> text of the old tools is quoted. All these tasks are also offered
> >>>> in the "btrfs" tool, and this tool is the newer one.
> >>>
> >>> I fully agree: btrfsctl, btrfs-vol, btrfs-show are perfectly
> >>> replaced by by btrfs. Moreover time to time the patches are more
> >>> complex than the needing because exists these "legacy" programs.
> >>>
> >>> I checked the debian package, and to me seems that there is no need
> >>> of {btrfsctl,btrfs-vol,btrfs-show}
> >>
> >> Hm, they are shipped in the Fedora package.
> > 
> > The same is true for the debian package, but are these used in Fedora ?
> > 
> >>
> >> For backwards compat, could those be turned into shell scripts which
> >> invoke the btrfs tool?
> > 
> > I don't see any gain to maintains a script bash (which has to be
> > written from scratch) instead of maintains the current C code.
> 
> It should be a trivial bash script to convert the calls, and it should
> require very little maintenance.  Much less than the hundreds of lines
> of duplicated C code, I think.
> 
> If nobody needs them, though, no reason for even a bash script.
> 
> David, Suse may be using them now, but probably can adapt?
> Anaconda said it could drop the use of btrfsctl.  :)

   I've just asked someone I know at Canonical, and he says there's no
use of these tools in the Ubuntu installer. (Disclaimer: it's not
entirely his area, and there's probably other places to look, like
udev rules, but on a cursory glance, it should be OK).

   I've also checked with the Debian installer people, and they're not
using the deprecated tools either. Further, these searches:

http://codesearch.debian.net/search?q=btrfs-show
http://codesearch.debian.net/search?q=btrfs-vol
http://codesearch.debian.net/search?q=btrfsctl

suggest that there's very little impact over the rest of the system as
well.

   Hugo.

-- 
=== Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk ===
  PGP key: 515C238D from wwwkeys.eu.pgp.net or http://www.carfax.org.uk
                --- If it ain't broke,  hit it again. ---                

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-25 16:48                 ` Hugo Mills
@ 2013-01-25 18:47                   ` Gene Czarcinski
  2013-01-28  3:12                     ` Anand Jain
  0 siblings, 1 reply; 131+ messages in thread
From: Gene Czarcinski @ 2013-01-25 18:47 UTC (permalink / raw)
  To: Hugo Mills, Eric Sandeen, kreijack, Goffredo Baroncelli,
	Goffredo Baroncelli, Stefan Behrens, Anand Jain, linux-btrfs,
	dsterba

On 01/25/2013 11:48 AM, Hugo Mills wrote:
> On Fri, Jan 25, 2013 at 10:14:06AM -0600, Eric Sandeen wrote:
>> On 1/24/13 4:09 PM, Goffredo Baroncelli wrote:
>>> On 01/24/2013 08:42 PM, Eric Sandeen wrote:
>>>> On 1/24/13 11:57 AM, Goffredo Baroncelli wrote:
>>>>> On 01/24/2013 10:23 AM, Stefan Behrens wrote:
>>>>>> On Wed, 23 Jan 2013 22:39:29 -0600, Eric Sandeen wrote:
>>>>>>> instead of renaming&   keeping the btrfsctl.c copy
>>>>>> There is a new momentum to improve the Btrfs-progs quality :)
>>>>>>
>>>>>> IMO, one step is to get rid of the legacy tools and sources. It
>>>>>> wastes time to maintain them and these old tools cause confusion.
>>>>>> btrfsctl.c, btrfs-vol.c and btrfs-show.c are not needed anymore.
>>>>>> Please correct me if there are plans to use these old tools in
>>>>>> future Linux distributions. The "btrfs" tool replaces the legacy
>>>>>> "btrfsctl", "btrfs-vol" and "btrfs-show" tools. Below, the usage
>>>>>> text of the old tools is quoted. All these tasks are also offered
>>>>>> in the "btrfs" tool, and this tool is the newer one.
>>>>> I fully agree: btrfsctl, btrfs-vol, btrfs-show are perfectly
>>>>> replaced by by btrfs. Moreover time to time the patches are more
>>>>> complex than the needing because exists these "legacy" programs.
>>>>>
>>>>> I checked the debian package, and to me seems that there is no need
>>>>> of {btrfsctl,btrfs-vol,btrfs-show}
>>>> Hm, they are shipped in the Fedora package.
>>> The same is true for the debian package, but are these used in Fedora ?
>>>
>>>> For backwards compat, could those be turned into shell scripts which
>>>> invoke the btrfs tool?
>>> I don't see any gain to maintains a script bash (which has to be
>>> written from scratch) instead of maintains the current C code.
>> It should be a trivial bash script to convert the calls, and it should
>> require very little maintenance.  Much less than the hundreds of lines
>> of duplicated C code, I think.
>>
>> If nobody needs them, though, no reason for even a bash script.
>>
>> David, Suse may be using them now, but probably can adapt?
>> Anaconda said it could drop the use of btrfsctl.  :)
>     I've just asked someone I know at Canonical, and he says there's no
> use of these tools in the Ubuntu installer. (Disclaimer: it's not
> entirely his area, and there's probably other places to look, like
> udev rules, but on a cursory glance, it should be OK).
>
>     I've also checked with the Debian installer people, and they're not
> using the deprecated tools either. Further, these searches:
>
> http://codesearch.debian.net/search?q=btrfs-show
> http://codesearch.debian.net/search?q=btrfs-vol
> http://codesearch.debian.net/search?q=btrfsctl
>
> suggest that there's very little impact over the rest of the system as
> well.
>
>     Hugo.
>
I took a look at Stefan's patch to Makefile and only the building and 
installation of the legacy apps has been eliminated.

This is a good first step so that if someone does need one of these 
apps, they can still be made.  Then, at some later time, remove the 
targets in Makefile and delete the source files.

Or, do it all now? [my preference]

Comments?

Gene

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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-25 18:47                   ` Gene Czarcinski
@ 2013-01-28  3:12                     ` Anand Jain
  0 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  3:12 UTC (permalink / raw)
  To: Gene Czarcinski
  Cc: Hugo Mills, Eric Sandeen, kreijack, Goffredo Baroncelli,
	Goffredo Baroncelli, Stefan Behrens, linux-btrfs, dsterba



  Good to have the old src-code removed as well.

  yum snapshot plugin is out of btrfsctl.
   http://lists.baseurl.org/pipermail/yum-devel/2012-July/009396.html

Thanks, Anand

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

* [PATCH 00/10 v3] add show sub-command for btrfs subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (22 preceding siblings ...)
  2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
@ 2013-01-28  4:10   ` Anand Jain
  2013-01-28  4:10     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
                       ` (10 more replies)
  2013-01-28  5:22   ` [RESEND] " Anand Jain
                     ` (3 subsequent siblings)
  27 siblings, 11 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Here is the v3 of this patch-set, kindly review and accept.

v2->v3:
 . Accepts review comments from Eric.

Anand Jain (10):
  Btrfs-progs: move open_file_or_dir() to utils.c
  Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  Btrfs-progs: add parent uuid for snapshots
  Btrfs-progs: move struct root_info to btrfs-list.h
  Btrfs-progs: add function btrfs_get_subvol to get root_info of a
    subvol
  Btrfs-progs: add method to filter snapshots by parent uuid
  Btrfs-progs: put find_mount_root() in commands.h
  Btrfs-progs: make printing subvol extensible to newer layouts
  Btrfs-progs: make get_subvol_name non cmds-send specific
  Btrfs-progs: add show subcommand to subvol cli

 Makefile         |   4 +-
 btrfs-list.c     | 192 +++++++++++++++++++++++++++++++++++--------------------
 btrfs-list.h     |  58 ++++++++++++++++-
 btrfsctl.c       |   7 +-
 cmds-balance.c   |   1 +
 cmds-inspect.c   |   1 +
 cmds-qgroup.c    |   1 +
 cmds-quota.c     |   1 +
 cmds-send.c      |  12 ++--
 cmds-subvolume.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++--
 commands.h       |   7 +-
 common.c         |  46 -------------
 man/btrfs.8.in   |   6 ++
 utils.c          |  30 ++++++++-
 utils.h          |   5 +-
 15 files changed, 408 insertions(+), 142 deletions(-)
 delete mode 100644 common.c

-- 
1.8.1.227.g44fe835

--
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] 131+ messages in thread

* [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  4:10     ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
                       ` (9 subsequent siblings)
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

The definition of the function open_file_or_dir() is moved from common.c
to utils.c in order to be able to share some common code between scrub
and the device stats in the following step. That common code uses
open_file_or_dir(). Since open_file_or_dir() makes use of the function
dirfd(3), the required XOPEN version was raised from 6 to 7.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Original-Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
 Makefile         |  4 ++--
 btrfsctl.c       |  7 ++++---
 cmds-balance.c   |  1 +
 cmds-inspect.c   |  1 +
 cmds-qgroup.c    |  1 +
 cmds-quota.c     |  1 +
 cmds-subvolume.c |  1 +
 commands.h       |  3 ---
 common.c         | 46 ----------------------------------------------
 utils.c          | 30 ++++++++++++++++++++++++++++--
 utils.h          |  5 +++--
 11 files changed, 42 insertions(+), 58 deletions(-)
 delete mode 100644 common.c

diff --git a/Makefile b/Makefile
index 4894903..8576d90 100644
--- a/Makefile
+++ b/Makefile
@@ -41,8 +41,8 @@ all: version $(progs) manpages
 version:
 	bash version.sh
 
-btrfs: $(objects) btrfs.o help.o common.o $(cmds_objects)
-	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o common.o $(cmds_objects) \
+btrfs: $(objects) btrfs.o help.o $(cmds_objects)
+	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o $(cmds_objects) \
 		$(objects) $(LDFLAGS) $(LIBS) -lpthread
 
 calc-size: $(objects) calc-size.o
diff --git a/btrfsctl.c b/btrfsctl.c
index 518684c..049a5f3 100644
--- a/btrfsctl.c
+++ b/btrfsctl.c
@@ -63,7 +63,7 @@ static void print_usage(void)
 	exit(1);
 }
 
-static int open_file_or_dir(const char *fname)
+static int btrfsctl_open_file_or_dir(const char *fname)
 {
 	int ret;
 	struct stat st;
@@ -91,6 +91,7 @@ static int open_file_or_dir(const char *fname)
 	}
 	return fd;
 }
+
 int main(int ac, char **av)
 {
 	char *fname = NULL;
@@ -128,7 +129,7 @@ int main(int ac, char **av)
 			snap_location = strdup(fullpath);
 			snap_location = dirname(snap_location);
 
-			snap_fd = open_file_or_dir(snap_location);
+			snap_fd = btrfsctl_open_file_or_dir(snap_location);
 
 			name = strdup(fullpath);
 			name = basename(name);
@@ -238,7 +239,7 @@ int main(int ac, char **av)
 		}
 		name = fname;
 	 } else {
-		fd = open_file_or_dir(fname);
+		fd = btrfsctl_open_file_or_dir(fname);
 	 }
 
 	if (name) {
diff --git a/cmds-balance.c b/cmds-balance.c
index 38a7426..6268b61 100644
--- a/cmds-balance.c
+++ b/cmds-balance.c
@@ -28,6 +28,7 @@
 #include "volumes.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const balance_cmd_group_usage[] = {
 	"btrfs [filesystem] balance <command> [options] <path>",
diff --git a/cmds-inspect.c b/cmds-inspect.c
index 25b83d2..f10bf55 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -23,6 +23,7 @@
 
 #include "kerncompat.h"
 #include "ioctl.h"
+#include "utils.h"
 
 #include "commands.h"
 #include "btrfs-list.h"
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 1525c11..cafc284 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -24,6 +24,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const qgroup_cmd_group_usage[] = {
 	"btrfs qgroup <command> [options] <path>",
diff --git a/cmds-quota.c b/cmds-quota.c
index cf9ad97..8481514 100644
--- a/cmds-quota.c
+++ b/cmds-quota.c
@@ -23,6 +23,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const quota_cmd_group_usage[] = {
 	"btrfs quota <command> [options] <path>",
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index ac39f7b..e3cdb1e 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -32,6 +32,7 @@
 #include "ctree.h"
 #include "commands.h"
 #include "btrfs-list.h"
+#include "utils.h"
 
 static const char * const subvolume_cmd_group_usage[] = {
 	"btrfs subvolume <command> <args>",
diff --git a/commands.h b/commands.h
index bb6d2dd..8114a73 100644
--- a/commands.h
+++ b/commands.h
@@ -79,9 +79,6 @@ void help_ambiguous_token(const char *arg, const struct cmd_group *grp);
 
 void help_command_group(const struct cmd_group *grp, int argc, char **argv);
 
-/* common.c */
-int open_file_or_dir(const char *fname);
-
 extern const struct cmd_group subvolume_cmd_group;
 extern const struct cmd_group filesystem_cmd_group;
 extern const struct cmd_group balance_cmd_group;
diff --git a/common.c b/common.c
deleted file mode 100644
index 03f6570..0000000
--- a/common.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-
-int open_file_or_dir(const char *fname)
-{
-	int ret;
-	struct stat st;
-	DIR *dirstream;
-	int fd;
-
-	ret = stat(fname, &st);
-	if (ret < 0) {
-		return -1;
-	}
-	if (S_ISDIR(st.st_mode)) {
-		dirstream = opendir(fname);
-		if (!dirstream) {
-			return -2;
-		}
-		fd = dirfd(dirstream);
-	} else {
-		fd = open(fname, O_RDWR);
-	}
-	if (fd < 0) {
-		return -3;
-	}
-	return fd;
-}
diff --git a/utils.c b/utils.c
index 938f9a5..78530e1 100644
--- a/utils.c
+++ b/utils.c
@@ -16,8 +16,9 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#define _XOPEN_SOURCE 600
-#define __USE_XOPEN2K
+#define _XOPEN_SOURCE 700
+#define __USE_XOPEN2K8
+#define __XOPEN2K8 /* due to an error in dirent.h, to get dirfd() */
 #include <stdio.h>
 #include <stdlib.h>
 #ifndef __CHECKER__
@@ -1268,3 +1269,28 @@ u64 parse_size(char *s)
 	return strtoull(s, NULL, 10) * mult;
 }
 
+int open_file_or_dir(const char *fname)
+{
+	int ret;
+	struct stat st;
+	DIR *dirstream;
+	int fd;
+
+	ret = stat(fname, &st);
+	if (ret < 0) {
+		return -1;
+	}
+	if (S_ISDIR(st.st_mode)) {
+		dirstream = opendir(fname);
+		if (!dirstream) {
+			return -2;
+		}
+		fd = dirfd(dirstream);
+	} else {
+		fd = open(fname, O_RDWR);
+	}
+	if (fd < 0) {
+		return -3;
+	}
+	return fd;
+}
diff --git a/utils.h b/utils.h
index 714fd7a..ed43e84 100644
--- a/utils.h
+++ b/utils.h
@@ -19,6 +19,8 @@
 #ifndef __UTILS__
 #define __UTILS__
 
+#include "ctree.h"
+
 #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024)
 
 int make_btrfs(int fd, const char *device, const char *label,
@@ -44,8 +46,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
 char *pretty_sizes(u64 size);
 int check_label(char *input);
 int get_mountpt(char *dev, char *mntpt, size_t size);
-
 int btrfs_scan_block_devices(int run_ioctl);
-
 u64 parse_size(char *s);
+int open_file_or_dir(const char *fname);
 #endif
-- 
1.8.1.227.g44fe835


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

* [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
  2013-01-28  4:10     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  4:10     ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
                       ` (8 subsequent siblings)
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

To improve the code reuse its better to have btrfs_list_subvols
just return list of subvols witout printing

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 28 ++++++++++++++++++----------
 btrfs-list.h     |  2 +-
 cmds-subvolume.c |  4 ++--
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index cb42fbc..b404e1d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1439,15 +1439,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 	}
 }
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
-		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 {
-	struct root_lookup root_lookup;
-	struct root_lookup root_sort;
 	int ret;
 
-	ret = __list_subvol_search(fd, &root_lookup);
+	ret = __list_subvol_search(fd, root_lookup);
 	if (ret) {
 		fprintf(stderr, "ERROR: can't perform the search - %s\n",
 				strerror(errno));
@@ -1458,16 +1454,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
 	 * now we have an rbtree full of root_info objects, but we need to fill
 	 * in their path names within the subvol that is referencing each one.
 	 */
-	ret = __list_subvol_fill_paths(fd, &root_lookup);
-	if (ret < 0)
-		return ret;
+	ret = __list_subvol_fill_paths(fd, root_lookup);
+	return ret;
+}
 
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
+		       struct btrfs_list_comparer_set *comp_set,
+		       int is_tab_result)
+{
+	struct root_lookup root_lookup;
+	struct root_lookup root_sort;
+	int ret;
+
+	ret = btrfs_list_subvols(fd, &root_lookup);
+	if (ret)
+		return ret;
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
 	print_all_volume_info(&root_sort, is_tab_result);
 	__free_all_subvolumn(&root_lookup);
-	return ret;
+
+	return 0;
 }
 
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
diff --git a/btrfs-list.h b/btrfs-list.h
index cde4b3c..71fe0f3 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 			      enum btrfs_list_comp_enum comparer,
 			      int is_descending);
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
 			int is_tab_result);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index e3cdb1e..c35dff7 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
+	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				is_tab_result);
 	if (ret)
 		return 19;
@@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
  2013-01-28  4:10     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
  2013-01-28  4:10     ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  4:10     ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
                       ` (7 subsequent siblings)
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 34 ++++++++++++++++++++++++++++------
 btrfs-list.h     |  1 +
 cmds-subvolume.c |  6 +++++-
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index b404e1d..13a365d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -80,6 +80,7 @@ struct root_info {
 	time_t otime;
 
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	/* path from the subvol we live in to this root, including the
 	 * root's name.  This is null until we do the extra lookup ioctl.
@@ -128,6 +129,11 @@ struct {
 		.need_print	= 0,
 	},
 	{
+		.name		= "parent_uuid",
+		.column_name	= "Parent UUID",
+		.need_print	= 0,
+	},
+	{
 		.name		= "uuid",
 		.column_name	= "UUID",
 		.need_print	= 0,
@@ -435,7 +441,7 @@ static struct root_info *root_tree_search(struct root_lookup *root_tree,
 static int update_root(struct root_lookup *root_lookup,
 		       u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		       u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		       time_t ot, void *uuid)
+		       time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 
@@ -472,6 +478,8 @@ static int update_root(struct root_lookup *root_lookup,
 		ri->otime = ot;
 	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
 
 	return 0;
 }
@@ -489,17 +497,18 @@ static int update_root(struct root_lookup *root_lookup,
  * gen: the current generation of the root
  * ot: the original time(create time) of the root
  * uuid: uuid of the root
+ * puuid: uuid of the root parent if any
  */
 static int add_root(struct root_lookup *root_lookup,
 		    u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		    u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		    time_t ot, void *uuid)
+		    time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 	int ret;
 
 	ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
-			  dir_id, name, name_len, ogen, gen, ot, uuid);
+			  dir_id, name, name_len, ogen, gen, ot, uuid, puuid);
 	if (!ret)
 		return 0;
 
@@ -537,9 +546,12 @@ static int add_root(struct root_lookup *root_lookup,
 	if (ot)
 		ri->otime = ot;
 
-	if (uuid) 
+	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
 
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
+
 	ret = root_tree_insert(root_lookup, ri);
 	if (ret) {
 		printf("failed to insert tree %llu\n", (unsigned long long)root_id);
@@ -1021,6 +1033,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 	int i;
 	time_t t;
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	root_lookup_init(root_lookup);
 	memset(&args, 0, sizeof(args));
@@ -1073,7 +1086,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 
 				add_root(root_lookup, sh.objectid, sh.offset,
 					 0, 0, dir_id, name, name_len, 0, 0, 0,
-					 NULL);
+					 NULL, NULL);
 			} else if (sh.type == BTRFS_ROOT_ITEM_KEY) {
 				ri = (struct btrfs_root_item *)(args.buf + off);
 				gen = btrfs_root_generation(ri);
@@ -1083,15 +1096,17 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 					t = ri->otime.sec;
 					ogen = btrfs_root_otransid(ri);
 					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
+					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
 				} else {
 					t = 0;
 					ogen = 0;
 					memset(uuid, 0, BTRFS_UUID_SIZE);
+					memset(puuid, 0, BTRFS_UUID_SIZE);
 				}
 
 				add_root(root_lookup, sh.objectid, 0,
 					 sh.offset, flags, 0, NULL, 0, ogen,
-					 gen, t, uuid);
+					 gen, t, uuid, puuid);
 			}
 
 			off += sh.len;
@@ -1345,6 +1360,13 @@ static void print_subvolume_column(struct root_info *subv,
 			uuid_unparse(subv->uuid, uuidparse);
 		printf("%s", uuidparse);
 		break;
+	case BTRFS_LIST_PUUID:
+		if (uuid_is_null(subv->puuid))
+			strcpy(uuidparse, "-");
+		else
+			uuid_unparse(subv->puuid, uuidparse);
+		printf("%s", uuidparse);
+		break;
 	case BTRFS_LIST_PATH:
 		BUG_ON(!subv->full_path);
 		printf("%s", subv->full_path);
diff --git a/btrfs-list.h b/btrfs-list.h
index 71fe0f3..855e73d 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -53,6 +53,7 @@ enum btrfs_list_column_enum {
 	BTRFS_LIST_PARENT,
 	BTRFS_LIST_TOP_LEVEL,
 	BTRFS_LIST_OTIME,
+	BTRFS_LIST_PUUID,
 	BTRFS_LIST_UUID,
 	BTRFS_LIST_PATH,
 	BTRFS_LIST_ALL,
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index c35dff7..a1e6893 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -280,6 +280,7 @@ static const char * const cmd_subvol_list_usage[] = {
 	"-p           print parent ID",
 	"-a           print all the subvolumes in the filesystem.",
 	"-u           print the uuid of subvolumes (and snapshots)",
+	"-q           print the parent uuid of the snapshots",
 	"-t           print the result as a table",
 	"-s           list snapshots only in the filesystem",
 	"-r           list readonly subvolumes (including snapshots)",
@@ -319,7 +320,7 @@ static int cmd_subvol_list(int argc, char **argv)
 	optind = 1;
 	while(1) {
 		c = getopt_long(argc, argv,
-				    "apsurg:c:t", long_options, NULL);
+				    "apsuqrg:c:t", long_options, NULL);
 		if (c < 0)
 			break;
 
@@ -343,6 +344,9 @@ static int cmd_subvol_list(int argc, char **argv)
 		case 'u':
 			btrfs_list_setup_print_column(BTRFS_LIST_UUID);
 			break;
+		case 'q':
+			btrfs_list_setup_print_column(BTRFS_LIST_PUUID);
+			break;
 		case 'r':
 			flags |= BTRFS_ROOT_SUBVOL_RDONLY;
 			break;
-- 
1.8.1.227.g44fe835


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

* [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
                       ` (2 preceding siblings ...)
  2013-01-28  4:10     ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  4:10     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
                       ` (6 subsequent siblings)
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

As we would add more ways to list and manage the subvols
and snapshots, its better if we have struct root_info
defined in the header file.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 47 -----------------------------------------------
 btrfs-list.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 13a365d..909d814 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -46,53 +46,6 @@ struct root_lookup {
 	struct rb_root root;
 };
 
-/*
- * one of these for each root we find.
- */
-struct root_info {
-	struct rb_node rb_node;
-	struct rb_node sort_node;
-
-	/* this root's id */
-	u64 root_id;
-
-	/* equal the offset of the root's key */
-	u64 root_offset;
-
-	/* flags of the root */
-	u64 flags;
-
-	/* the id of the root that references this one */
-	u64 ref_tree;
-
-	/* the dir id we're in from ref_tree */
-	u64 dir_id;
-
-	u64 top_id;
-
-	/* generation when the root is created or last updated */
-	u64 gen;
-
-	/* creation generation of this root in sec*/
-	u64 ogen;
-
-	/* creation time of this root in sec*/
-	time_t otime;
-
-	u8 uuid[BTRFS_UUID_SIZE];
-	u8 puuid[BTRFS_UUID_SIZE];
-
-	/* path from the subvol we live in to this root, including the
-	 * root's name.  This is null until we do the extra lookup ioctl.
-	 */
-	char *path;
-
-	/* the name of this root in the directory it lives in */
-	char *name;
-
-	char *full_path;
-};
-
 struct {
 	char	*name;
 	char	*column_name;
diff --git a/btrfs-list.h b/btrfs-list.h
index 855e73d..3b7b680 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,7 +18,52 @@
 
 #include "kerncompat.h"
 
-struct root_info;
+/*
+ * one of these for each root we find.
+ */
+struct root_info {
+	struct rb_node rb_node;
+	struct rb_node sort_node;
+
+	/* this root's id */
+	u64 root_id;
+
+	/* equal the offset of the root's key */
+	u64 root_offset;
+
+	/* flags of the root */
+	u64 flags;
+
+	/* the id of the root that references this one */
+	u64 ref_tree;
+
+	/* the dir id we're in from ref_tree */
+	u64 dir_id;
+
+	u64 top_id;
+
+	/* generation when the root is created or last updated */
+	u64 gen;
+
+	/* creation generation of this root in sec*/
+	u64 ogen;
+
+	/* creation time of this root in sec*/
+	time_t otime;
+
+	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
+
+	/* path from the subvol we live in to this root, including the
+	 * root's name.  This is null until we do the extra lookup ioctl.
+	 */
+	char *path;
+
+	/* the name of this root in the directory it lives in */
+	char *name;
+
+	char *full_path;
+};
 
 typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
 typedef int (*btrfs_list_comp_func)(struct root_info *, struct root_info *,
-- 
1.8.1.227.g44fe835


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

* [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
                       ` (3 preceding siblings ...)
  2013-01-28  4:10     ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  4:10     ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
                       ` (5 subsequent siblings)
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

We need a function which can get the root_info of a given
subvol. This is in preparation to add support for the show
sub-cli.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
 btrfs-list.h |  1 +
 2 files changed, 39 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 909d814..0ee13b6 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1453,6 +1453,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	return 0;
 }
 
+int btrfs_get_subvol(int fd, struct root_info *the_ri)
+{
+	int ret = -1;
+	struct root_lookup rl;
+	struct rb_node *rbn;
+	struct root_info *ri;
+	u64 root_id = btrfs_list_get_path_rootid(fd);
+
+	if (btrfs_list_subvols(fd, &rl))
+		return 1;
+
+	rbn = rb_first(&rl.root);
+	while(rbn) {
+		ri = rb_entry(rbn, struct root_info, rb_node);
+		resolve_root(&rl, ri, root_id);
+		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
+			memcpy(the_ri, ri, offsetof(struct root_info, path));
+			if (ri->path)
+				the_ri->path = strdup(ri->path);
+			else
+				the_ri->path = NULL;
+			if (ri->name)
+				the_ri->name = strdup(ri->name);
+			else
+				the_ri->name = NULL;
+			if (ri->full_path)
+				the_ri->full_path = strdup(ri->full_path);
+			else
+				the_ri->name = NULL;
+			ret = 0;
+			break;
+		}
+		rbn = rb_next(rbn);
+	}
+	__free_all_subvolumn(&rl);
+	return ret;
+}
+
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 			    struct btrfs_file_extent_item *item,
 			    u64 found_gen, u64 *cache_dirid,
diff --git a/btrfs-list.h b/btrfs-list.h
index 3b7b680..580d4d1 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
 u64 btrfs_list_get_path_rootid(int fd);
+int btrfs_get_subvol(int fd, struct root_info *the_ri);
-- 
1.8.1.227.g44fe835


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

* [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
                       ` (4 preceding siblings ...)
  2013-01-28  4:10     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  4:10     ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
                       ` (4 subsequent siblings)
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 6 ++++++
 btrfs-list.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 0ee13b6..9c84ecb 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1142,6 +1142,11 @@ static int filter_topid_equal(struct root_info *ri, u64 data)
 	return ri->top_id == data;
 }
 
+static int filter_by_parent(struct root_info *ri, u64 data)
+{
+	return !uuid_compare(ri->puuid, (u8 *)data);
+}
+
 static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_ROOTID]		= filter_by_rootid,
 	[BTRFS_LIST_FILTER_SNAPSHOT_ONLY]	= filter_snapshot,
@@ -1153,6 +1158,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_CGEN_LESS]		= filter_cgen_less,
 	[BTRFS_LIST_FILTER_CGEN_EQUAL]          = filter_cgen_equal,
 	[BTRFS_LIST_FILTER_TOPID_EQUAL]		= filter_topid_equal,
+	[BTRFS_LIST_FILTER_BY_PARENT]		= filter_by_parent,
 };
 
 struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
diff --git a/btrfs-list.h b/btrfs-list.h
index 580d4d1..cde7a3f 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -117,6 +117,7 @@ enum btrfs_list_filter_enum {
 	BTRFS_LIST_FILTER_CGEN_LESS,
 	BTRFS_LIST_FILTER_CGEN_MORE,
 	BTRFS_LIST_FILTER_TOPID_EQUAL,
+	BTRFS_LIST_FILTER_BY_PARENT,
 	BTRFS_LIST_FILTER_MAX,
 };
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
                       ` (5 preceding siblings ...)
  2013-01-28  4:10     ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  4:10     ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
                       ` (3 subsequent siblings)
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

A useful function need to define it in a header file.

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

diff --git a/commands.h b/commands.h
index 8114a73..9b77f3e 100644
--- a/commands.h
+++ b/commands.h
@@ -103,3 +103,6 @@ int cmd_qgroup(int argc, char **argv);
 
 /* subvolume exported functions */
 int test_issubvolume(char *path);
+
+/* send.c */
+int find_mount_root(const char *path, char **mount_root);
-- 
1.8.1.227.g44fe835


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

* [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
                       ` (6 preceding siblings ...)
  2013-01-28  4:10     ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  4:10     ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
                       ` (2 subsequent siblings)
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Currently you can print subvol in a list or table format.
This patch will provide a way to extend this to other formats
like the upcoming raw format.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 26 +++++++++++++++-----------
 btrfs-list.h     |  3 +++
 cmds-subvolume.c | 23 ++++++++++++++++++++---
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 9c84ecb..656de10 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -54,12 +54,12 @@ struct {
 	{
 		.name		= "ID",
 		.column_name	= "ID",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "gen",
 		.column_name	= "Gen",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "cgen",
@@ -74,7 +74,7 @@ struct {
 	{
 		.name		= "top level",
 		.column_name	= "Top Level",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "otime",
@@ -94,7 +94,7 @@ struct {
 	{
 		.name		= "path",
 		.column_name	= "Path",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= NULL,
@@ -1401,21 +1401,25 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int is_tab_result)
+				  int layout)
 {
 	struct rb_node *n;
 	struct root_info *entry;
 
-	if (is_tab_result)
+	if (layout == BTRFS_LIST_LAYOUT_TABLE)
 		print_all_volume_info_tab_head();
 
 	n = rb_first(&sorted_tree->root);
 	while (n) {
 		entry = rb_entry(n, struct root_info, sort_node);
-		if (is_tab_result)
-			print_single_volume_info_table(entry);
-		else
+		switch (layout) {
+		case BTRFS_LIST_LAYOUT_DEFAULT:
 			print_single_volume_info_default(entry);
+			break;
+		case BTRFS_LIST_LAYOUT_TABLE:
+			print_single_volume_info_table(entry);
+			break;
+		}
 		n = rb_next(n);
 	}
 }
@@ -1441,7 +1445,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+		       int layout)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1453,7 +1457,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, is_tab_result);
+	print_all_volume_info(&root_sort, layout);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index cde7a3f..5b60068 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,6 +18,9 @@
 
 #include "kerncompat.h"
 
+#define BTRFS_LIST_LAYOUT_DEFAULT	0
+#define BTRFS_LIST_LAYOUT_TABLE	1
+
 /*
  * one of these for each root we find.
  */
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index a1e6893..bb9629f 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -410,8 +410,18 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				is_tab_result);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	if (is_tab_result)
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_TABLE);
+	else
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
@@ -617,7 +627,14 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
+		BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
                       ` (7 preceding siblings ...)
  2013-01-28  4:10     ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  4:10     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
  2013-01-28  5:29     ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

get_subvol_name can be used other than the just with in cmds-send.c
so this patch will make it possible with out changing the original
intentions.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-send.c | 12 ++++++------
 commands.h  |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/cmds-send.c b/cmds-send.c
index ac1d3cf..0416b79 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -333,12 +333,12 @@ out:
 	return ret;
 }
 
-static const char *get_subvol_name(struct btrfs_send *s, const char *full_path)
+char *get_subvol_name(char *mnt, char *full_path)
 {
-	int len = strlen(s->root_path);
+	int len = strlen(mnt);
 	if (!len)
 		return full_path;
-	if (s->root_path[len - 1] != '/')
+	if (mnt[len - 1] != '/')
 		len += 1;
 
 	return full_path + len;
@@ -452,7 +452,7 @@ int cmd_send_start(int argc, char **argv)
 			if (ret < 0)
 				goto out;
 
-			ret = get_root_id(&send, get_subvol_name(&send, subvol),
+			ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 					&root_id);
 			if (ret < 0) {
 				fprintf(stderr, "ERROR: could not resolve "
@@ -513,7 +513,7 @@ int cmd_send_start(int argc, char **argv)
 
 	if (snapshot_parent != NULL) {
 		ret = get_root_id(&send,
-				get_subvol_name(&send, snapshot_parent),
+				get_subvol_name(send.root_path, snapshot_parent),
 				&parent_root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
@@ -572,7 +572,7 @@ int cmd_send_start(int argc, char **argv)
 			goto out;
 		}
 
-		ret = get_root_id(&send, get_subvol_name(&send, subvol),
+		ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 				&root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
diff --git a/commands.h b/commands.h
index 9b77f3e..631fb6b 100644
--- a/commands.h
+++ b/commands.h
@@ -106,3 +106,4 @@ int test_issubvolume(char *path);
 
 /* send.c */
 int find_mount_root(const char *path, char **mount_root);
+char *get_subvol_name(char *mnt, char *full_path);
-- 
1.8.1.227.g44fe835


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

* [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
                       ` (8 preceding siblings ...)
  2013-01-28  4:10     ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
@ 2013-01-28  4:10     ` Anand Jain
  2013-01-28  5:29     ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  4:10 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

This adds show sub-command to the btrfs subvol cli
to display detailed inforamtion of the given subvol
or snapshot.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     |  25 +++++++--
 btrfs-list.h     |   3 +-
 cmds-subvolume.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 man/btrfs.8.in   |   6 +++
 4 files changed, 182 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 656de10..1915ece 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1335,6 +1335,22 @@ static void print_subvolume_column(struct root_info *subv,
 	}
 }
 
+static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_LIST_ALL; i++) {
+		if (!btrfs_list_columns[i].need_print)
+			continue;
+
+		if (raw_prefix)
+			printf("%s",raw_prefix);
+
+		print_subvolume_column(subv, i);
+	}
+	printf("\n");
+}
+
 static void print_single_volume_info_table(struct root_info *subv)
 {
 	int i;
@@ -1401,7 +1417,7 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int layout)
+				  int layout, char *raw_prefix)
 {
 	struct rb_node *n;
 	struct root_info *entry;
@@ -1419,6 +1435,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 		case BTRFS_LIST_LAYOUT_TABLE:
 			print_single_volume_info_table(entry);
 			break;
+		case BTRFS_LIST_LAYOUT_RAW:
+			print_single_volume_info_raw(entry, raw_prefix);
+			break;
 		}
 		n = rb_next(n);
 	}
@@ -1445,7 +1464,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int layout)
+		       int layout, char *raw_prefix)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1457,7 +1476,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, layout);
+	print_all_volume_info(&root_sort, layout, raw_prefix);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index 5b60068..09d35f7 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -20,6 +20,7 @@
 
 #define BTRFS_LIST_LAYOUT_DEFAULT	0
 #define BTRFS_LIST_LAYOUT_TABLE	1
+#define BTRFS_LIST_LAYOUT_RAW		2
 
 /*
  * one of these for each root we find.
@@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-			int is_tab_result);
+			int layout, char *raw_prefix);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index bb9629f..6a14c4c 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -24,6 +24,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
+#include <uuid/uuid.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
 
 	if (is_tab_result)
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_TABLE);
+				BTRFS_LIST_LAYOUT_TABLE, NULL);
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_DEFAULT);
+				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
-		BTRFS_LIST_LAYOUT_DEFAULT);
+		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -721,6 +722,153 @@ static int cmd_find_new(int argc, char **argv)
 	return 0;
 }
 
+static const char * const cmd_subvol_show_usage[] = {
+	"btrfs subvolume show <subvol-path>",
+	"Show more information of the subvolume",
+	NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+	struct root_info get_ri;
+	struct btrfs_list_filter_set *filter_set;
+	char tstr[256];
+	char uuidparse[37];
+	char *fullpath = NULL, *svpath = NULL, *mnt = NULL;
+	char raw_prefix[] = "\t\t\t\t";
+	u64 sv_id, mntid;
+	int fd = -1, mntfd = -1;
+	int ret = -1;
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_subvol_show_usage);
+
+	fullpath = realpath(argv[1], 0);
+	if (!fullpath) {
+		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
+			argv[1], strerror(errno));
+		goto out;
+	}
+
+	ret = test_issubvolume(fullpath);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
+		goto out;
+	}
+	if (!ret) {
+		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
+		ret = -1;
+		goto out;
+	}
+
+	ret = find_mount_root(fullpath, &mnt);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
+				"%s\n", fullpath, strerror(-ret));
+		goto out;
+	}
+	ret = -1;
+	svpath = get_subvol_name(mnt, fullpath);
+
+	fd = open_file_or_dir(fullpath);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
+		goto out;
+	}
+
+	sv_id = btrfs_list_get_path_rootid(fd);
+	if (sv_id < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
+			fullpath);
+		goto out;
+	}
+
+	mntfd = open_file_or_dir(mnt);
+	if (mntfd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
+		goto out;
+	}
+
+	mntid = btrfs_list_get_path_rootid(mntfd);
+	if (mntid < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
+		goto out;
+	}
+
+	if (sv_id == BTRFS_FS_TREE_OBJECTID) {
+		printf("%s is btrfs root\n", fullpath);
+		goto out;
+	}
+
+	memset(&get_ri, 0, sizeof(get_ri));
+	get_ri.root_id = sv_id;
+
+	if (btrfs_get_subvol(mntfd, &get_ri)) {
+		fprintf(stderr, "ERROR: can't find '%s'\n",
+			svpath);
+		goto out;
+	}
+
+	ret = 0;
+	/* print the info */
+	printf("%s\n", fullpath);
+	printf("\tName: \t\t\t%s\n", get_ri.name);
+
+	if (uuid_is_null(get_ri.uuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.uuid, uuidparse);
+	printf("\tuuid: \t\t\t%s\n", uuidparse);
+
+	if (uuid_is_null(get_ri.puuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.puuid, uuidparse);
+	printf("\tParent uuid: \t\t%s\n", uuidparse);
+
+	if (get_ri.otime)
+		strftime(tstr, 256, "%Y-%m-%d %X",
+			 localtime(&get_ri.otime));
+	else
+		strcpy(tstr, "-");
+	printf("\tCreation time: \t\t%s\n", tstr);
+
+	printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
+	printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
+	printf("\tGen at creation: \t%llu\n", get_ri.ogen);
+	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
+	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
+
+	/* print the snapshots of the given subvol if any*/
+	printf("\tSnapshot(s):\n");
+	filter_set = btrfs_list_alloc_filter_set();
+	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
+				get_ri.uuid);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
+			raw_prefix);
+
+	/* clean up */
+	if (get_ri.path)
+		free(get_ri.path);
+	if (get_ri.name)
+		free(get_ri.name);
+	if (get_ri.full_path)
+		free(get_ri.full_path);
+
+out:
+	if (mntfd >= 0)
+		close(mntfd);
+	if (fd >= 0)
+		close(fd);
+	if (mnt)
+		free(mnt);
+	if (fullpath)
+		free(fullpath);
+
+	return ret;
+}
+
 const struct cmd_group subvolume_cmd_group = {
 	subvolume_cmd_group_usage, NULL, {
 		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -732,6 +880,7 @@ const struct cmd_group subvolume_cmd_group = {
 		{ "set-default", cmd_subvol_set_default,
 			cmd_subvol_set_default_usage, NULL, 0 },
 		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
+		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
 	}
 };
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index d20e332..0008a06 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
 .PP
+\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
 [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
 [<\fIfile\fR>|<\fIdir\fR>...]
@@ -158,6 +160,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
 is similar to \fBsubvolume list\fR command.
 .TP
 
+\fBsubvolume show\fR\fI <path>\fR
+Show information of a given subvolume in the \fI<path>\fR.
+.TP
+
 \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
 [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
 
-- 
1.8.1.227.g44fe835


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

* [RESEND] [PATCH 00/10 v3] add show sub-command for btrfs subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (23 preceding siblings ...)
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
@ 2013-01-28  5:22   ` Anand Jain
  2013-01-28  5:22     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
                       ` (9 more replies)
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                     ` (2 subsequent siblings)
  27 siblings, 10 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

(resent, fixed git in-reply-to and v2->v3: change log
sorry about that).

----
Here is the v3 of this patch-set, kindly review and accept.

v2->v3:
 . Accepts review comments from Stefan

Anand Jain (10):
  Btrfs-progs: move open_file_or_dir() to utils.c
  Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  Btrfs-progs: add parent uuid for snapshots
  Btrfs-progs: move struct root_info to btrfs-list.h
  Btrfs-progs: add function btrfs_get_subvol to get root_info of a
    subvol
  Btrfs-progs: add method to filter snapshots by parent uuid
  Btrfs-progs: put find_mount_root() in commands.h
  Btrfs-progs: make printing subvol extensible to newer layouts
  Btrfs-progs: make get_subvol_name non cmds-send specific
  Btrfs-progs: add show subcommand to subvol cli

 Makefile         |   4 +-
 btrfs-list.c     | 192 +++++++++++++++++++++++++++++++++++--------------------
 btrfs-list.h     |  58 ++++++++++++++++-
 btrfsctl.c       |   7 +-
 cmds-balance.c   |   1 +
 cmds-inspect.c   |   1 +
 cmds-qgroup.c    |   1 +
 cmds-quota.c     |   1 +
 cmds-send.c      |  12 ++--
 cmds-subvolume.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++--
 commands.h       |   7 +-
 common.c         |  46 -------------
 man/btrfs.8.in   |   6 ++
 utils.c          |  30 ++++++++-
 utils.h          |   5 +-
 15 files changed, 408 insertions(+), 142 deletions(-)
 delete mode 100644 common.c

-- 
1.8.1.227.g44fe835

--
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] 131+ messages in thread

* [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-28  5:22   ` [RESEND] " Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  2013-01-28 18:08       ` David Sterba
  2013-01-28  5:22     ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
                       ` (8 subsequent siblings)
  9 siblings, 1 reply; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

The definition of the function open_file_or_dir() is moved from common.c
to utils.c in order to be able to share some common code between scrub
and the device stats in the following step. That common code uses
open_file_or_dir(). Since open_file_or_dir() makes use of the function
dirfd(3), the required XOPEN version was raised from 6 to 7.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Original-Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
 Makefile         |  4 ++--
 btrfsctl.c       |  7 ++++---
 cmds-balance.c   |  1 +
 cmds-inspect.c   |  1 +
 cmds-qgroup.c    |  1 +
 cmds-quota.c     |  1 +
 cmds-subvolume.c |  1 +
 commands.h       |  3 ---
 common.c         | 46 ----------------------------------------------
 utils.c          | 30 ++++++++++++++++++++++++++++--
 utils.h          |  5 +++--
 11 files changed, 42 insertions(+), 58 deletions(-)
 delete mode 100644 common.c

diff --git a/Makefile b/Makefile
index 4894903..8576d90 100644
--- a/Makefile
+++ b/Makefile
@@ -41,8 +41,8 @@ all: version $(progs) manpages
 version:
 	bash version.sh
 
-btrfs: $(objects) btrfs.o help.o common.o $(cmds_objects)
-	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o common.o $(cmds_objects) \
+btrfs: $(objects) btrfs.o help.o $(cmds_objects)
+	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o $(cmds_objects) \
 		$(objects) $(LDFLAGS) $(LIBS) -lpthread
 
 calc-size: $(objects) calc-size.o
diff --git a/btrfsctl.c b/btrfsctl.c
index 518684c..049a5f3 100644
--- a/btrfsctl.c
+++ b/btrfsctl.c
@@ -63,7 +63,7 @@ static void print_usage(void)
 	exit(1);
 }
 
-static int open_file_or_dir(const char *fname)
+static int btrfsctl_open_file_or_dir(const char *fname)
 {
 	int ret;
 	struct stat st;
@@ -91,6 +91,7 @@ static int open_file_or_dir(const char *fname)
 	}
 	return fd;
 }
+
 int main(int ac, char **av)
 {
 	char *fname = NULL;
@@ -128,7 +129,7 @@ int main(int ac, char **av)
 			snap_location = strdup(fullpath);
 			snap_location = dirname(snap_location);
 
-			snap_fd = open_file_or_dir(snap_location);
+			snap_fd = btrfsctl_open_file_or_dir(snap_location);
 
 			name = strdup(fullpath);
 			name = basename(name);
@@ -238,7 +239,7 @@ int main(int ac, char **av)
 		}
 		name = fname;
 	 } else {
-		fd = open_file_or_dir(fname);
+		fd = btrfsctl_open_file_or_dir(fname);
 	 }
 
 	if (name) {
diff --git a/cmds-balance.c b/cmds-balance.c
index 38a7426..6268b61 100644
--- a/cmds-balance.c
+++ b/cmds-balance.c
@@ -28,6 +28,7 @@
 #include "volumes.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const balance_cmd_group_usage[] = {
 	"btrfs [filesystem] balance <command> [options] <path>",
diff --git a/cmds-inspect.c b/cmds-inspect.c
index 25b83d2..f10bf55 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -23,6 +23,7 @@
 
 #include "kerncompat.h"
 #include "ioctl.h"
+#include "utils.h"
 
 #include "commands.h"
 #include "btrfs-list.h"
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 1525c11..cafc284 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -24,6 +24,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const qgroup_cmd_group_usage[] = {
 	"btrfs qgroup <command> [options] <path>",
diff --git a/cmds-quota.c b/cmds-quota.c
index cf9ad97..8481514 100644
--- a/cmds-quota.c
+++ b/cmds-quota.c
@@ -23,6 +23,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const quota_cmd_group_usage[] = {
 	"btrfs quota <command> [options] <path>",
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index ac39f7b..e3cdb1e 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -32,6 +32,7 @@
 #include "ctree.h"
 #include "commands.h"
 #include "btrfs-list.h"
+#include "utils.h"
 
 static const char * const subvolume_cmd_group_usage[] = {
 	"btrfs subvolume <command> <args>",
diff --git a/commands.h b/commands.h
index bb6d2dd..8114a73 100644
--- a/commands.h
+++ b/commands.h
@@ -79,9 +79,6 @@ void help_ambiguous_token(const char *arg, const struct cmd_group *grp);
 
 void help_command_group(const struct cmd_group *grp, int argc, char **argv);
 
-/* common.c */
-int open_file_or_dir(const char *fname);
-
 extern const struct cmd_group subvolume_cmd_group;
 extern const struct cmd_group filesystem_cmd_group;
 extern const struct cmd_group balance_cmd_group;
diff --git a/common.c b/common.c
deleted file mode 100644
index 03f6570..0000000
--- a/common.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-
-int open_file_or_dir(const char *fname)
-{
-	int ret;
-	struct stat st;
-	DIR *dirstream;
-	int fd;
-
-	ret = stat(fname, &st);
-	if (ret < 0) {
-		return -1;
-	}
-	if (S_ISDIR(st.st_mode)) {
-		dirstream = opendir(fname);
-		if (!dirstream) {
-			return -2;
-		}
-		fd = dirfd(dirstream);
-	} else {
-		fd = open(fname, O_RDWR);
-	}
-	if (fd < 0) {
-		return -3;
-	}
-	return fd;
-}
diff --git a/utils.c b/utils.c
index 938f9a5..78530e1 100644
--- a/utils.c
+++ b/utils.c
@@ -16,8 +16,9 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#define _XOPEN_SOURCE 600
-#define __USE_XOPEN2K
+#define _XOPEN_SOURCE 700
+#define __USE_XOPEN2K8
+#define __XOPEN2K8 /* due to an error in dirent.h, to get dirfd() */
 #include <stdio.h>
 #include <stdlib.h>
 #ifndef __CHECKER__
@@ -1268,3 +1269,28 @@ u64 parse_size(char *s)
 	return strtoull(s, NULL, 10) * mult;
 }
 
+int open_file_or_dir(const char *fname)
+{
+	int ret;
+	struct stat st;
+	DIR *dirstream;
+	int fd;
+
+	ret = stat(fname, &st);
+	if (ret < 0) {
+		return -1;
+	}
+	if (S_ISDIR(st.st_mode)) {
+		dirstream = opendir(fname);
+		if (!dirstream) {
+			return -2;
+		}
+		fd = dirfd(dirstream);
+	} else {
+		fd = open(fname, O_RDWR);
+	}
+	if (fd < 0) {
+		return -3;
+	}
+	return fd;
+}
diff --git a/utils.h b/utils.h
index 714fd7a..ed43e84 100644
--- a/utils.h
+++ b/utils.h
@@ -19,6 +19,8 @@
 #ifndef __UTILS__
 #define __UTILS__
 
+#include "ctree.h"
+
 #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024)
 
 int make_btrfs(int fd, const char *device, const char *label,
@@ -44,8 +46,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
 char *pretty_sizes(u64 size);
 int check_label(char *input);
 int get_mountpt(char *dev, char *mntpt, size_t size);
-
 int btrfs_scan_block_devices(int run_ioctl);
-
 u64 parse_size(char *s);
+int open_file_or_dir(const char *fname);
 #endif
-- 
1.8.1.227.g44fe835


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

* [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-01-28  5:22   ` [RESEND] " Anand Jain
  2013-01-28  5:22     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  2013-01-28  5:22     ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
                       ` (7 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

To improve the code reuse its better to have btrfs_list_subvols
just return list of subvols witout printing

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 28 ++++++++++++++++++----------
 btrfs-list.h     |  2 +-
 cmds-subvolume.c |  4 ++--
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index cb42fbc..b404e1d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1439,15 +1439,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 	}
 }
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
-		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 {
-	struct root_lookup root_lookup;
-	struct root_lookup root_sort;
 	int ret;
 
-	ret = __list_subvol_search(fd, &root_lookup);
+	ret = __list_subvol_search(fd, root_lookup);
 	if (ret) {
 		fprintf(stderr, "ERROR: can't perform the search - %s\n",
 				strerror(errno));
@@ -1458,16 +1454,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
 	 * now we have an rbtree full of root_info objects, but we need to fill
 	 * in their path names within the subvol that is referencing each one.
 	 */
-	ret = __list_subvol_fill_paths(fd, &root_lookup);
-	if (ret < 0)
-		return ret;
+	ret = __list_subvol_fill_paths(fd, root_lookup);
+	return ret;
+}
 
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
+		       struct btrfs_list_comparer_set *comp_set,
+		       int is_tab_result)
+{
+	struct root_lookup root_lookup;
+	struct root_lookup root_sort;
+	int ret;
+
+	ret = btrfs_list_subvols(fd, &root_lookup);
+	if (ret)
+		return ret;
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
 	print_all_volume_info(&root_sort, is_tab_result);
 	__free_all_subvolumn(&root_lookup);
-	return ret;
+
+	return 0;
 }
 
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
diff --git a/btrfs-list.h b/btrfs-list.h
index cde4b3c..71fe0f3 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 			      enum btrfs_list_comp_enum comparer,
 			      int is_descending);
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
 			int is_tab_result);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index e3cdb1e..c35dff7 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
+	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				is_tab_result);
 	if (ret)
 		return 19;
@@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots
  2013-01-28  5:22   ` [RESEND] " Anand Jain
  2013-01-28  5:22     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
  2013-01-28  5:22     ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  2013-01-28  5:22     ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
                       ` (6 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 34 ++++++++++++++++++++++++++++------
 btrfs-list.h     |  1 +
 cmds-subvolume.c |  6 +++++-
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index b404e1d..13a365d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -80,6 +80,7 @@ struct root_info {
 	time_t otime;
 
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	/* path from the subvol we live in to this root, including the
 	 * root's name.  This is null until we do the extra lookup ioctl.
@@ -128,6 +129,11 @@ struct {
 		.need_print	= 0,
 	},
 	{
+		.name		= "parent_uuid",
+		.column_name	= "Parent UUID",
+		.need_print	= 0,
+	},
+	{
 		.name		= "uuid",
 		.column_name	= "UUID",
 		.need_print	= 0,
@@ -435,7 +441,7 @@ static struct root_info *root_tree_search(struct root_lookup *root_tree,
 static int update_root(struct root_lookup *root_lookup,
 		       u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		       u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		       time_t ot, void *uuid)
+		       time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 
@@ -472,6 +478,8 @@ static int update_root(struct root_lookup *root_lookup,
 		ri->otime = ot;
 	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
 
 	return 0;
 }
@@ -489,17 +497,18 @@ static int update_root(struct root_lookup *root_lookup,
  * gen: the current generation of the root
  * ot: the original time(create time) of the root
  * uuid: uuid of the root
+ * puuid: uuid of the root parent if any
  */
 static int add_root(struct root_lookup *root_lookup,
 		    u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		    u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		    time_t ot, void *uuid)
+		    time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 	int ret;
 
 	ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
-			  dir_id, name, name_len, ogen, gen, ot, uuid);
+			  dir_id, name, name_len, ogen, gen, ot, uuid, puuid);
 	if (!ret)
 		return 0;
 
@@ -537,9 +546,12 @@ static int add_root(struct root_lookup *root_lookup,
 	if (ot)
 		ri->otime = ot;
 
-	if (uuid) 
+	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
 
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
+
 	ret = root_tree_insert(root_lookup, ri);
 	if (ret) {
 		printf("failed to insert tree %llu\n", (unsigned long long)root_id);
@@ -1021,6 +1033,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 	int i;
 	time_t t;
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	root_lookup_init(root_lookup);
 	memset(&args, 0, sizeof(args));
@@ -1073,7 +1086,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 
 				add_root(root_lookup, sh.objectid, sh.offset,
 					 0, 0, dir_id, name, name_len, 0, 0, 0,
-					 NULL);
+					 NULL, NULL);
 			} else if (sh.type == BTRFS_ROOT_ITEM_KEY) {
 				ri = (struct btrfs_root_item *)(args.buf + off);
 				gen = btrfs_root_generation(ri);
@@ -1083,15 +1096,17 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 					t = ri->otime.sec;
 					ogen = btrfs_root_otransid(ri);
 					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
+					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
 				} else {
 					t = 0;
 					ogen = 0;
 					memset(uuid, 0, BTRFS_UUID_SIZE);
+					memset(puuid, 0, BTRFS_UUID_SIZE);
 				}
 
 				add_root(root_lookup, sh.objectid, 0,
 					 sh.offset, flags, 0, NULL, 0, ogen,
-					 gen, t, uuid);
+					 gen, t, uuid, puuid);
 			}
 
 			off += sh.len;
@@ -1345,6 +1360,13 @@ static void print_subvolume_column(struct root_info *subv,
 			uuid_unparse(subv->uuid, uuidparse);
 		printf("%s", uuidparse);
 		break;
+	case BTRFS_LIST_PUUID:
+		if (uuid_is_null(subv->puuid))
+			strcpy(uuidparse, "-");
+		else
+			uuid_unparse(subv->puuid, uuidparse);
+		printf("%s", uuidparse);
+		break;
 	case BTRFS_LIST_PATH:
 		BUG_ON(!subv->full_path);
 		printf("%s", subv->full_path);
diff --git a/btrfs-list.h b/btrfs-list.h
index 71fe0f3..855e73d 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -53,6 +53,7 @@ enum btrfs_list_column_enum {
 	BTRFS_LIST_PARENT,
 	BTRFS_LIST_TOP_LEVEL,
 	BTRFS_LIST_OTIME,
+	BTRFS_LIST_PUUID,
 	BTRFS_LIST_UUID,
 	BTRFS_LIST_PATH,
 	BTRFS_LIST_ALL,
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index c35dff7..a1e6893 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -280,6 +280,7 @@ static const char * const cmd_subvol_list_usage[] = {
 	"-p           print parent ID",
 	"-a           print all the subvolumes in the filesystem.",
 	"-u           print the uuid of subvolumes (and snapshots)",
+	"-q           print the parent uuid of the snapshots",
 	"-t           print the result as a table",
 	"-s           list snapshots only in the filesystem",
 	"-r           list readonly subvolumes (including snapshots)",
@@ -319,7 +320,7 @@ static int cmd_subvol_list(int argc, char **argv)
 	optind = 1;
 	while(1) {
 		c = getopt_long(argc, argv,
-				    "apsurg:c:t", long_options, NULL);
+				    "apsuqrg:c:t", long_options, NULL);
 		if (c < 0)
 			break;
 
@@ -343,6 +344,9 @@ static int cmd_subvol_list(int argc, char **argv)
 		case 'u':
 			btrfs_list_setup_print_column(BTRFS_LIST_UUID);
 			break;
+		case 'q':
+			btrfs_list_setup_print_column(BTRFS_LIST_PUUID);
+			break;
 		case 'r':
 			flags |= BTRFS_ROOT_SUBVOL_RDONLY;
 			break;
-- 
1.8.1.227.g44fe835


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

* [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h
  2013-01-28  5:22   ` [RESEND] " Anand Jain
                       ` (2 preceding siblings ...)
  2013-01-28  5:22     ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  2013-01-28  5:22     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
                       ` (5 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

As we would add more ways to list and manage the subvols
and snapshots, its better if we have struct root_info
defined in the header file.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 47 -----------------------------------------------
 btrfs-list.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 13a365d..909d814 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -46,53 +46,6 @@ struct root_lookup {
 	struct rb_root root;
 };
 
-/*
- * one of these for each root we find.
- */
-struct root_info {
-	struct rb_node rb_node;
-	struct rb_node sort_node;
-
-	/* this root's id */
-	u64 root_id;
-
-	/* equal the offset of the root's key */
-	u64 root_offset;
-
-	/* flags of the root */
-	u64 flags;
-
-	/* the id of the root that references this one */
-	u64 ref_tree;
-
-	/* the dir id we're in from ref_tree */
-	u64 dir_id;
-
-	u64 top_id;
-
-	/* generation when the root is created or last updated */
-	u64 gen;
-
-	/* creation generation of this root in sec*/
-	u64 ogen;
-
-	/* creation time of this root in sec*/
-	time_t otime;
-
-	u8 uuid[BTRFS_UUID_SIZE];
-	u8 puuid[BTRFS_UUID_SIZE];
-
-	/* path from the subvol we live in to this root, including the
-	 * root's name.  This is null until we do the extra lookup ioctl.
-	 */
-	char *path;
-
-	/* the name of this root in the directory it lives in */
-	char *name;
-
-	char *full_path;
-};
-
 struct {
 	char	*name;
 	char	*column_name;
diff --git a/btrfs-list.h b/btrfs-list.h
index 855e73d..3b7b680 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,7 +18,52 @@
 
 #include "kerncompat.h"
 
-struct root_info;
+/*
+ * one of these for each root we find.
+ */
+struct root_info {
+	struct rb_node rb_node;
+	struct rb_node sort_node;
+
+	/* this root's id */
+	u64 root_id;
+
+	/* equal the offset of the root's key */
+	u64 root_offset;
+
+	/* flags of the root */
+	u64 flags;
+
+	/* the id of the root that references this one */
+	u64 ref_tree;
+
+	/* the dir id we're in from ref_tree */
+	u64 dir_id;
+
+	u64 top_id;
+
+	/* generation when the root is created or last updated */
+	u64 gen;
+
+	/* creation generation of this root in sec*/
+	u64 ogen;
+
+	/* creation time of this root in sec*/
+	time_t otime;
+
+	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
+
+	/* path from the subvol we live in to this root, including the
+	 * root's name.  This is null until we do the extra lookup ioctl.
+	 */
+	char *path;
+
+	/* the name of this root in the directory it lives in */
+	char *name;
+
+	char *full_path;
+};
 
 typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
 typedef int (*btrfs_list_comp_func)(struct root_info *, struct root_info *,
-- 
1.8.1.227.g44fe835


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

* [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-28  5:22   ` [RESEND] " Anand Jain
                       ` (3 preceding siblings ...)
  2013-01-28  5:22     ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  2013-01-29  4:42       ` Wang Shilong
  2013-01-28  5:22     ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
                       ` (4 subsequent siblings)
  9 siblings, 1 reply; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

We need a function which can get the root_info of a given
subvol. This is in preparation to add support for the show
sub-cli.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
 btrfs-list.h |  1 +
 2 files changed, 39 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 909d814..0ee13b6 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1453,6 +1453,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	return 0;
 }
 
+int btrfs_get_subvol(int fd, struct root_info *the_ri)
+{
+	int ret = -1;
+	struct root_lookup rl;
+	struct rb_node *rbn;
+	struct root_info *ri;
+	u64 root_id = btrfs_list_get_path_rootid(fd);
+
+	if (btrfs_list_subvols(fd, &rl))
+		return 1;
+
+	rbn = rb_first(&rl.root);
+	while(rbn) {
+		ri = rb_entry(rbn, struct root_info, rb_node);
+		resolve_root(&rl, ri, root_id);
+		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
+			memcpy(the_ri, ri, offsetof(struct root_info, path));
+			if (ri->path)
+				the_ri->path = strdup(ri->path);
+			else
+				the_ri->path = NULL;
+			if (ri->name)
+				the_ri->name = strdup(ri->name);
+			else
+				the_ri->name = NULL;
+			if (ri->full_path)
+				the_ri->full_path = strdup(ri->full_path);
+			else
+				the_ri->name = NULL;
+			ret = 0;
+			break;
+		}
+		rbn = rb_next(rbn);
+	}
+	__free_all_subvolumn(&rl);
+	return ret;
+}
+
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 			    struct btrfs_file_extent_item *item,
 			    u64 found_gen, u64 *cache_dirid,
diff --git a/btrfs-list.h b/btrfs-list.h
index 3b7b680..580d4d1 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
 u64 btrfs_list_get_path_rootid(int fd);
+int btrfs_get_subvol(int fd, struct root_info *the_ri);
-- 
1.8.1.227.g44fe835


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

* [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid
  2013-01-28  5:22   ` [RESEND] " Anand Jain
                       ` (4 preceding siblings ...)
  2013-01-28  5:22     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  2013-01-28  5:22     ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
                       ` (3 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 6 ++++++
 btrfs-list.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 0ee13b6..9c84ecb 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1142,6 +1142,11 @@ static int filter_topid_equal(struct root_info *ri, u64 data)
 	return ri->top_id == data;
 }
 
+static int filter_by_parent(struct root_info *ri, u64 data)
+{
+	return !uuid_compare(ri->puuid, (u8 *)data);
+}
+
 static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_ROOTID]		= filter_by_rootid,
 	[BTRFS_LIST_FILTER_SNAPSHOT_ONLY]	= filter_snapshot,
@@ -1153,6 +1158,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_CGEN_LESS]		= filter_cgen_less,
 	[BTRFS_LIST_FILTER_CGEN_EQUAL]          = filter_cgen_equal,
 	[BTRFS_LIST_FILTER_TOPID_EQUAL]		= filter_topid_equal,
+	[BTRFS_LIST_FILTER_BY_PARENT]		= filter_by_parent,
 };
 
 struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
diff --git a/btrfs-list.h b/btrfs-list.h
index 580d4d1..cde7a3f 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -117,6 +117,7 @@ enum btrfs_list_filter_enum {
 	BTRFS_LIST_FILTER_CGEN_LESS,
 	BTRFS_LIST_FILTER_CGEN_MORE,
 	BTRFS_LIST_FILTER_TOPID_EQUAL,
+	BTRFS_LIST_FILTER_BY_PARENT,
 	BTRFS_LIST_FILTER_MAX,
 };
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h
  2013-01-28  5:22   ` [RESEND] " Anand Jain
                       ` (5 preceding siblings ...)
  2013-01-28  5:22     ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  2013-01-28  5:22     ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
                       ` (2 subsequent siblings)
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

A useful function need to define it in a header file.

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

diff --git a/commands.h b/commands.h
index 8114a73..9b77f3e 100644
--- a/commands.h
+++ b/commands.h
@@ -103,3 +103,6 @@ int cmd_qgroup(int argc, char **argv);
 
 /* subvolume exported functions */
 int test_issubvolume(char *path);
+
+/* send.c */
+int find_mount_root(const char *path, char **mount_root);
-- 
1.8.1.227.g44fe835


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

* [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts
  2013-01-28  5:22   ` [RESEND] " Anand Jain
                       ` (6 preceding siblings ...)
  2013-01-28  5:22     ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  2013-01-28  5:22     ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
  2013-01-28  5:22     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Currently you can print subvol in a list or table format.
This patch will provide a way to extend this to other formats
like the upcoming raw format.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 26 +++++++++++++++-----------
 btrfs-list.h     |  3 +++
 cmds-subvolume.c | 23 ++++++++++++++++++++---
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 9c84ecb..656de10 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -54,12 +54,12 @@ struct {
 	{
 		.name		= "ID",
 		.column_name	= "ID",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "gen",
 		.column_name	= "Gen",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "cgen",
@@ -74,7 +74,7 @@ struct {
 	{
 		.name		= "top level",
 		.column_name	= "Top Level",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "otime",
@@ -94,7 +94,7 @@ struct {
 	{
 		.name		= "path",
 		.column_name	= "Path",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= NULL,
@@ -1401,21 +1401,25 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int is_tab_result)
+				  int layout)
 {
 	struct rb_node *n;
 	struct root_info *entry;
 
-	if (is_tab_result)
+	if (layout == BTRFS_LIST_LAYOUT_TABLE)
 		print_all_volume_info_tab_head();
 
 	n = rb_first(&sorted_tree->root);
 	while (n) {
 		entry = rb_entry(n, struct root_info, sort_node);
-		if (is_tab_result)
-			print_single_volume_info_table(entry);
-		else
+		switch (layout) {
+		case BTRFS_LIST_LAYOUT_DEFAULT:
 			print_single_volume_info_default(entry);
+			break;
+		case BTRFS_LIST_LAYOUT_TABLE:
+			print_single_volume_info_table(entry);
+			break;
+		}
 		n = rb_next(n);
 	}
 }
@@ -1441,7 +1445,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+		       int layout)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1453,7 +1457,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, is_tab_result);
+	print_all_volume_info(&root_sort, layout);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index cde7a3f..5b60068 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,6 +18,9 @@
 
 #include "kerncompat.h"
 
+#define BTRFS_LIST_LAYOUT_DEFAULT	0
+#define BTRFS_LIST_LAYOUT_TABLE	1
+
 /*
  * one of these for each root we find.
  */
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index a1e6893..bb9629f 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -410,8 +410,18 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				is_tab_result);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	if (is_tab_result)
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_TABLE);
+	else
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
@@ -617,7 +627,14 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
+		BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific
  2013-01-28  5:22   ` [RESEND] " Anand Jain
                       ` (7 preceding siblings ...)
  2013-01-28  5:22     ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  2013-01-28  5:22     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

get_subvol_name can be used other than the just with in cmds-send.c
so this patch will make it possible with out changing the original
intentions.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-send.c | 12 ++++++------
 commands.h  |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/cmds-send.c b/cmds-send.c
index ac1d3cf..0416b79 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -333,12 +333,12 @@ out:
 	return ret;
 }
 
-static const char *get_subvol_name(struct btrfs_send *s, const char *full_path)
+char *get_subvol_name(char *mnt, char *full_path)
 {
-	int len = strlen(s->root_path);
+	int len = strlen(mnt);
 	if (!len)
 		return full_path;
-	if (s->root_path[len - 1] != '/')
+	if (mnt[len - 1] != '/')
 		len += 1;
 
 	return full_path + len;
@@ -452,7 +452,7 @@ int cmd_send_start(int argc, char **argv)
 			if (ret < 0)
 				goto out;
 
-			ret = get_root_id(&send, get_subvol_name(&send, subvol),
+			ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 					&root_id);
 			if (ret < 0) {
 				fprintf(stderr, "ERROR: could not resolve "
@@ -513,7 +513,7 @@ int cmd_send_start(int argc, char **argv)
 
 	if (snapshot_parent != NULL) {
 		ret = get_root_id(&send,
-				get_subvol_name(&send, snapshot_parent),
+				get_subvol_name(send.root_path, snapshot_parent),
 				&parent_root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
@@ -572,7 +572,7 @@ int cmd_send_start(int argc, char **argv)
 			goto out;
 		}
 
-		ret = get_root_id(&send, get_subvol_name(&send, subvol),
+		ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 				&root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
diff --git a/commands.h b/commands.h
index 9b77f3e..631fb6b 100644
--- a/commands.h
+++ b/commands.h
@@ -106,3 +106,4 @@ int test_issubvolume(char *path);
 
 /* send.c */
 int find_mount_root(const char *path, char **mount_root);
+char *get_subvol_name(char *mnt, char *full_path);
-- 
1.8.1.227.g44fe835


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

* [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-28  5:22   ` [RESEND] " Anand Jain
                       ` (8 preceding siblings ...)
  2013-01-28  5:22     ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
@ 2013-01-28  5:22     ` Anand Jain
  9 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:22 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

This adds show sub-command to the btrfs subvol cli
to display detailed inforamtion of the given subvol
or snapshot.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     |  25 +++++++--
 btrfs-list.h     |   3 +-
 cmds-subvolume.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 man/btrfs.8.in   |   6 +++
 4 files changed, 182 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 656de10..1915ece 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1335,6 +1335,22 @@ static void print_subvolume_column(struct root_info *subv,
 	}
 }
 
+static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_LIST_ALL; i++) {
+		if (!btrfs_list_columns[i].need_print)
+			continue;
+
+		if (raw_prefix)
+			printf("%s",raw_prefix);
+
+		print_subvolume_column(subv, i);
+	}
+	printf("\n");
+}
+
 static void print_single_volume_info_table(struct root_info *subv)
 {
 	int i;
@@ -1401,7 +1417,7 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int layout)
+				  int layout, char *raw_prefix)
 {
 	struct rb_node *n;
 	struct root_info *entry;
@@ -1419,6 +1435,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 		case BTRFS_LIST_LAYOUT_TABLE:
 			print_single_volume_info_table(entry);
 			break;
+		case BTRFS_LIST_LAYOUT_RAW:
+			print_single_volume_info_raw(entry, raw_prefix);
+			break;
 		}
 		n = rb_next(n);
 	}
@@ -1445,7 +1464,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int layout)
+		       int layout, char *raw_prefix)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1457,7 +1476,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, layout);
+	print_all_volume_info(&root_sort, layout, raw_prefix);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index 5b60068..09d35f7 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -20,6 +20,7 @@
 
 #define BTRFS_LIST_LAYOUT_DEFAULT	0
 #define BTRFS_LIST_LAYOUT_TABLE	1
+#define BTRFS_LIST_LAYOUT_RAW		2
 
 /*
  * one of these for each root we find.
@@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-			int is_tab_result);
+			int layout, char *raw_prefix);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index bb9629f..6a14c4c 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -24,6 +24,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
+#include <uuid/uuid.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
 
 	if (is_tab_result)
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_TABLE);
+				BTRFS_LIST_LAYOUT_TABLE, NULL);
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_DEFAULT);
+				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
-		BTRFS_LIST_LAYOUT_DEFAULT);
+		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -721,6 +722,153 @@ static int cmd_find_new(int argc, char **argv)
 	return 0;
 }
 
+static const char * const cmd_subvol_show_usage[] = {
+	"btrfs subvolume show <subvol-path>",
+	"Show more information of the subvolume",
+	NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+	struct root_info get_ri;
+	struct btrfs_list_filter_set *filter_set;
+	char tstr[256];
+	char uuidparse[37];
+	char *fullpath = NULL, *svpath = NULL, *mnt = NULL;
+	char raw_prefix[] = "\t\t\t\t";
+	u64 sv_id, mntid;
+	int fd = -1, mntfd = -1;
+	int ret = -1;
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_subvol_show_usage);
+
+	fullpath = realpath(argv[1], 0);
+	if (!fullpath) {
+		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
+			argv[1], strerror(errno));
+		goto out;
+	}
+
+	ret = test_issubvolume(fullpath);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
+		goto out;
+	}
+	if (!ret) {
+		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
+		ret = -1;
+		goto out;
+	}
+
+	ret = find_mount_root(fullpath, &mnt);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
+				"%s\n", fullpath, strerror(-ret));
+		goto out;
+	}
+	ret = -1;
+	svpath = get_subvol_name(mnt, fullpath);
+
+	fd = open_file_or_dir(fullpath);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
+		goto out;
+	}
+
+	sv_id = btrfs_list_get_path_rootid(fd);
+	if (sv_id < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
+			fullpath);
+		goto out;
+	}
+
+	mntfd = open_file_or_dir(mnt);
+	if (mntfd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
+		goto out;
+	}
+
+	mntid = btrfs_list_get_path_rootid(mntfd);
+	if (mntid < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
+		goto out;
+	}
+
+	if (sv_id == BTRFS_FS_TREE_OBJECTID) {
+		printf("%s is btrfs root\n", fullpath);
+		goto out;
+	}
+
+	memset(&get_ri, 0, sizeof(get_ri));
+	get_ri.root_id = sv_id;
+
+	if (btrfs_get_subvol(mntfd, &get_ri)) {
+		fprintf(stderr, "ERROR: can't find '%s'\n",
+			svpath);
+		goto out;
+	}
+
+	ret = 0;
+	/* print the info */
+	printf("%s\n", fullpath);
+	printf("\tName: \t\t\t%s\n", get_ri.name);
+
+	if (uuid_is_null(get_ri.uuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.uuid, uuidparse);
+	printf("\tuuid: \t\t\t%s\n", uuidparse);
+
+	if (uuid_is_null(get_ri.puuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.puuid, uuidparse);
+	printf("\tParent uuid: \t\t%s\n", uuidparse);
+
+	if (get_ri.otime)
+		strftime(tstr, 256, "%Y-%m-%d %X",
+			 localtime(&get_ri.otime));
+	else
+		strcpy(tstr, "-");
+	printf("\tCreation time: \t\t%s\n", tstr);
+
+	printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
+	printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
+	printf("\tGen at creation: \t%llu\n", get_ri.ogen);
+	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
+	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
+
+	/* print the snapshots of the given subvol if any*/
+	printf("\tSnapshot(s):\n");
+	filter_set = btrfs_list_alloc_filter_set();
+	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
+				get_ri.uuid);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
+			raw_prefix);
+
+	/* clean up */
+	if (get_ri.path)
+		free(get_ri.path);
+	if (get_ri.name)
+		free(get_ri.name);
+	if (get_ri.full_path)
+		free(get_ri.full_path);
+
+out:
+	if (mntfd >= 0)
+		close(mntfd);
+	if (fd >= 0)
+		close(fd);
+	if (mnt)
+		free(mnt);
+	if (fullpath)
+		free(fullpath);
+
+	return ret;
+}
+
 const struct cmd_group subvolume_cmd_group = {
 	subvolume_cmd_group_usage, NULL, {
 		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -732,6 +880,7 @@ const struct cmd_group subvolume_cmd_group = {
 		{ "set-default", cmd_subvol_set_default,
 			cmd_subvol_set_default_usage, NULL, 0 },
 		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
+		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
 	}
 };
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index d20e332..0008a06 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
 .PP
+\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
 [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
 [<\fIfile\fR>|<\fIdir\fR>...]
@@ -158,6 +160,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
 is similar to \fBsubvolume list\fR command.
 .TP
 
+\fBsubvolume show\fR\fI <path>\fR
+Show information of a given subvolume in the \fI<path>\fR.
+.TP
+
 \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
 [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
 
-- 
1.8.1.227.g44fe835


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

* Re: [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli
  2013-01-25 10:07       ` Stefan Behrens
@ 2013-01-28  5:26         ` Anand Jain
  0 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:26 UTC (permalink / raw)
  To: Stefan Behrens; +Cc: linux-btrfs, dsterba, gene



Stefan,

  Thanks for the review.

> if (sv_id == BTRFS_FS_TREE_OBJECTID) {

oh yes.

> The common way to handle it is:
> static int cmd_subvol_show(int argc, char **argv)
> {
> 	int mntfd = -1;
> 	int fd = -1;
> 	char *mnt = NULL;
> 	char *fullpath = NULL;
>
> 	... everywhere, in case of errors, just goto out;
>
> 	mntfd = open...();
> 	if (mntfd < 0) {
> 		fprintf...
> 		goto out;
> 	}
>
> out:
> 	if (mntfd >= 0)
> 		close(mntfd);
> 	if (fd >= 0)
> 		close(fd);
> 	free(mnt);
> 	free(fullpath);
> 	return ret;
> }
>
> Wherever an error happens inside the function, just goto out. When the
> char pointers are not yet allocated, they are still NULL and thus
> ignored by free(). If open() failed or the files are not yet opened, the
> descriptors are still -1 and close() is not called.
>
> It's basically impossible to add errors if you do it like this :)
>

Looks cleaner. will get this.

Anand

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

* Re: [PATCH 00/10 v3] add show sub-command for btrfs subvol cli
  2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
                       ` (9 preceding siblings ...)
  2013-01-28  4:10     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
@ 2013-01-28  5:29     ` Anand Jain
  10 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-28  5:29 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba, gene



  sorry missed some git cli option and late noticed error in the
  change-log, Pls. ignore this thread and ref to the email thread
  with the subject:

  [RESEND] [PATCH 00/10 v3] add show sub-command for btrfs subvol cli

-Anand

On 01/28/2013 12:10 PM, Anand Jain wrote:
> Here is the v3 of this patch-set, kindly review and accept.
>
> v2->v3:
>   . Accepts review comments from Eric.
>
> Anand Jain (10):
>    Btrfs-progs: move open_file_or_dir() to utils.c
>    Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
>    Btrfs-progs: add parent uuid for snapshots
>    Btrfs-progs: move struct root_info to btrfs-list.h
>    Btrfs-progs: add function btrfs_get_subvol to get root_info of a
>      subvol
>    Btrfs-progs: add method to filter snapshots by parent uuid
>    Btrfs-progs: put find_mount_root() in commands.h
>    Btrfs-progs: make printing subvol extensible to newer layouts
>    Btrfs-progs: make get_subvol_name non cmds-send specific
>    Btrfs-progs: add show subcommand to subvol cli
>
>   Makefile         |   4 +-
>   btrfs-list.c     | 192 +++++++++++++++++++++++++++++++++++--------------------
>   btrfs-list.h     |  58 ++++++++++++++++-
>   btrfsctl.c       |   7 +-
>   cmds-balance.c   |   1 +
>   cmds-inspect.c   |   1 +
>   cmds-qgroup.c    |   1 +
>   cmds-quota.c     |   1 +
>   cmds-send.c      |  12 ++--
>   cmds-subvolume.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++--
>   commands.h       |   7 +-
>   common.c         |  46 -------------
>   man/btrfs.8.in   |   6 ++
>   utils.c          |  30 ++++++++-
>   utils.h          |   5 +-
>   15 files changed, 408 insertions(+), 142 deletions(-)
>   delete mode 100644 common.c
>

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

* Re: [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-29  4:42       ` Wang Shilong
@ 2013-01-28 18:04         ` David Sterba
  2013-01-29  6:59           ` Anand Jain
  0 siblings, 1 reply; 131+ messages in thread
From: David Sterba @ 2013-01-28 18:04 UTC (permalink / raw)
  To: Wang Shilong; +Cc: Anand Jain, linux-btrfs, dsterba, gene, miaox

On Mon, Jan 28, 2013 at 08:42:06PM -0800, Wang Shilong wrote:
> > +	rbn = rb_first(&rl.root);
> > +	while(rbn) {
> > +		ri = rb_entry(rbn, struct root_info, rb_node);
> > +		resolve_root(&rl, ri, root_id);
>      
>   Here subvolume/snapshot deletion may happen,add a check here...
>   if resolve_root return -ENOENT..it means deletion happens...
> 
>   ret = reslove_root(&rl, ri, root_id);
>   if (ret)
>       goto again;
> 
[...]
>                    
>  again???
> > +		rbn = rb_next(rbn);
> > +	}

Then it looks like a for (...) { } pattern with 'continue' instead of
'goto'.

david

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

* Re: [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-28  5:22     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
@ 2013-01-28 18:08       ` David Sterba
  0 siblings, 0 replies; 131+ messages in thread
From: David Sterba @ 2013-01-28 18:08 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba, gene

On Mon, Jan 28, 2013 at 01:22:30PM +0800, Anand Jain wrote:
> The definition of the function open_file_or_dir() is moved from common.c
> to utils.c in order to be able to share some common code between scrub
> and the device stats in the following step. That common code uses
> open_file_or_dir(). Since open_file_or_dir() makes use of the function
> dirfd(3), the required XOPEN version was raised from 6 to 7.
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> Original-Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>

I'm taking this one preemptively because Stefan's dev-stats also depend
on it.

Please address Wang Shilong's comment in 05/10. Unless there are
objections against adding this new subcommand, I'll add it to
upcomming integration branches.


david

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

* Re: [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-28  5:22     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-01-29  4:42       ` Wang Shilong
  2013-01-28 18:04         ` David Sterba
  0 siblings, 1 reply; 131+ messages in thread
From: Wang Shilong @ 2013-01-29  4:42 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba, gene, miaox

Hi,
> We need a function which can get the root_info of a given
> subvol. This is in preparation to add support for the show
> sub-cli.
>
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
>  btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
>  btrfs-list.h |  1 +
>  2 files changed, 39 insertions(+)
>
> diff --git a/btrfs-list.c b/btrfs-list.c
> index 909d814..0ee13b6 100644
> --- a/btrfs-list.c
> +++ b/btrfs-list.c
> @@ -1453,6 +1453,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  	return 0;
>  }
>  
> +int btrfs_get_subvol(int fd, struct root_info *the_ri)
> +{
> +	int ret = -1;
> +	struct root_lookup rl;
> +	struct rb_node *rbn;
> +	struct root_info *ri;
> +	u64 root_id = btrfs_list_get_path_rootid(fd);
> +
> +	if (btrfs_list_subvols(fd, &rl))
> +		return 1;
> +
> +	rbn = rb_first(&rl.root);
> +	while(rbn) {
> +		ri = rb_entry(rbn, struct root_info, rb_node);
> +		resolve_root(&rl, ri, root_id);
     
  Here subvolume/snapshot deletion may happen,add a check here...
  if resolve_root return -ENOENT..it means deletion happens...

  ret = reslove_root(&rl, ri, root_id);
  if (ret)
      goto again;

                   
> +		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
> +			memcpy(the_ri, ri, offsetof(struct root_info, path));
> +			if (ri->path)
> +				the_ri->path = strdup(ri->path);
> +			else
> +				the_ri->path = NULL;
> +			if (ri->name)
> +				the_ri->name = strdup(ri->name);
> +			else
> +				the_ri->name = NULL;
> +			if (ri->full_path)
> +				the_ri->full_path = strdup(ri->full_path);
> +			else
> +				the_ri->name = NULL;
> +			ret = 0;
> +			break;
> +		}
 again:
> +		rbn = rb_next(rbn);
> +	}
> +	__free_all_subvolumn(&rl);
> +	return ret;
> +}
> +
>  static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
>  			    struct btrfs_file_extent_item *item,
>  			    u64 found_gen, u64 *cache_dirid,
> diff --git a/btrfs-list.h b/btrfs-list.h
> index 3b7b680..580d4d1 100644
> --- a/btrfs-list.h
> +++ b/btrfs-list.h
> @@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
>  int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
>  char *btrfs_list_path_for_root(int fd, u64 root);
>  u64 btrfs_list_get_path_rootid(int fd);
> +int btrfs_get_subvol(int fd, struct root_info *the_ri);


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

* [PATCH 00/12 v4] add show sub-command for btrfs subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (24 preceding siblings ...)
  2013-01-28  5:22   ` [RESEND] " Anand Jain
@ 2013-01-29  6:48   ` Anand Jain
  2013-01-29  6:48     ` [PATCH 01/12] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
                       ` (11 more replies)
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
  27 siblings, 12 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Here is the v4 of this patch-set, kindly review and accept.

v3->v4:
 . Included a patch from Wang Shilong
 . Added the changes to be inline with the above patch

Anand Jain (11):
  Btrfs-progs: move open_file_or_dir() to utils.c
  Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  Btrfs-progs: add parent uuid for snapshots
  Btrfs-progs: move struct root_info to btrfs-list.h
  Btrfs-progs: add function btrfs_get_subvol to get root_info of a
    subvol
  Btrfs-progs: add method to filter snapshots by parent uuid
  Btrfs-progs: put find_mount_root() in commands.h
  Btrfs-progs: make printing subvol extensible to newer layouts
  Btrfs-progs: make get_subvol_name non cmds-send specific
  Btrfs-progs: add show subcommand to subvol cli
  Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root
    ret changes

Wang Shilong (1):
  Btrfs-progs: filter the deleted subvolumes when listing snapshots

 Makefile         |   4 +-
 btrfs-list.c     | 239 ++++++++++++++++++++++++++++++++++++-------------------
 btrfs-list.h     |  58 +++++++++++++-
 btrfsctl.c       |   7 +-
 cmds-balance.c   |   1 +
 cmds-inspect.c   |   1 +
 cmds-qgroup.c    |   1 +
 cmds-quota.c     |   1 +
 cmds-send.c      |  12 +--
 cmds-subvolume.c | 179 ++++++++++++++++++++++++++++++++++++++++-
 commands.h       |   7 +-
 common.c         |  46 -----------
 man/btrfs.8.in   |   6 ++
 utils.c          |  30 ++++++-
 utils.h          |   5 +-
 15 files changed, 445 insertions(+), 152 deletions(-)
 delete mode 100644 common.c

-- 
1.8.1.227.g44fe835


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

* [PATCH 01/12] Btrfs-progs: move open_file_or_dir() to utils.c
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-29  6:48     ` [PATCH 02/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
                       ` (10 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

The definition of the function open_file_or_dir() is moved from common.c
to utils.c in order to be able to share some common code between scrub
and the device stats in the following step. That common code uses
open_file_or_dir(). Since open_file_or_dir() makes use of the function
dirfd(3), the required XOPEN version was raised from 6 to 7.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Original-Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
 Makefile         |  4 ++--
 btrfsctl.c       |  7 ++++---
 cmds-balance.c   |  1 +
 cmds-inspect.c   |  1 +
 cmds-qgroup.c    |  1 +
 cmds-quota.c     |  1 +
 cmds-subvolume.c |  1 +
 commands.h       |  3 ---
 common.c         | 46 ----------------------------------------------
 utils.c          | 30 ++++++++++++++++++++++++++++--
 utils.h          |  5 +++--
 11 files changed, 42 insertions(+), 58 deletions(-)
 delete mode 100644 common.c

diff --git a/Makefile b/Makefile
index 4894903..8576d90 100644
--- a/Makefile
+++ b/Makefile
@@ -41,8 +41,8 @@ all: version $(progs) manpages
 version:
 	bash version.sh
 
-btrfs: $(objects) btrfs.o help.o common.o $(cmds_objects)
-	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o common.o $(cmds_objects) \
+btrfs: $(objects) btrfs.o help.o $(cmds_objects)
+	$(CC) $(CFLAGS) -o btrfs btrfs.o help.o $(cmds_objects) \
 		$(objects) $(LDFLAGS) $(LIBS) -lpthread
 
 calc-size: $(objects) calc-size.o
diff --git a/btrfsctl.c b/btrfsctl.c
index 518684c..049a5f3 100644
--- a/btrfsctl.c
+++ b/btrfsctl.c
@@ -63,7 +63,7 @@ static void print_usage(void)
 	exit(1);
 }
 
-static int open_file_or_dir(const char *fname)
+static int btrfsctl_open_file_or_dir(const char *fname)
 {
 	int ret;
 	struct stat st;
@@ -91,6 +91,7 @@ static int open_file_or_dir(const char *fname)
 	}
 	return fd;
 }
+
 int main(int ac, char **av)
 {
 	char *fname = NULL;
@@ -128,7 +129,7 @@ int main(int ac, char **av)
 			snap_location = strdup(fullpath);
 			snap_location = dirname(snap_location);
 
-			snap_fd = open_file_or_dir(snap_location);
+			snap_fd = btrfsctl_open_file_or_dir(snap_location);
 
 			name = strdup(fullpath);
 			name = basename(name);
@@ -238,7 +239,7 @@ int main(int ac, char **av)
 		}
 		name = fname;
 	 } else {
-		fd = open_file_or_dir(fname);
+		fd = btrfsctl_open_file_or_dir(fname);
 	 }
 
 	if (name) {
diff --git a/cmds-balance.c b/cmds-balance.c
index 38a7426..6268b61 100644
--- a/cmds-balance.c
+++ b/cmds-balance.c
@@ -28,6 +28,7 @@
 #include "volumes.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const balance_cmd_group_usage[] = {
 	"btrfs [filesystem] balance <command> [options] <path>",
diff --git a/cmds-inspect.c b/cmds-inspect.c
index 25b83d2..f10bf55 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -23,6 +23,7 @@
 
 #include "kerncompat.h"
 #include "ioctl.h"
+#include "utils.h"
 
 #include "commands.h"
 #include "btrfs-list.h"
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 1525c11..cafc284 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -24,6 +24,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const qgroup_cmd_group_usage[] = {
 	"btrfs qgroup <command> [options] <path>",
diff --git a/cmds-quota.c b/cmds-quota.c
index cf9ad97..8481514 100644
--- a/cmds-quota.c
+++ b/cmds-quota.c
@@ -23,6 +23,7 @@
 #include "ioctl.h"
 
 #include "commands.h"
+#include "utils.h"
 
 static const char * const quota_cmd_group_usage[] = {
 	"btrfs quota <command> [options] <path>",
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index ac39f7b..e3cdb1e 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -32,6 +32,7 @@
 #include "ctree.h"
 #include "commands.h"
 #include "btrfs-list.h"
+#include "utils.h"
 
 static const char * const subvolume_cmd_group_usage[] = {
 	"btrfs subvolume <command> <args>",
diff --git a/commands.h b/commands.h
index bb6d2dd..8114a73 100644
--- a/commands.h
+++ b/commands.h
@@ -79,9 +79,6 @@ void help_ambiguous_token(const char *arg, const struct cmd_group *grp);
 
 void help_command_group(const struct cmd_group *grp, int argc, char **argv);
 
-/* common.c */
-int open_file_or_dir(const char *fname);
-
 extern const struct cmd_group subvolume_cmd_group;
 extern const struct cmd_group filesystem_cmd_group;
 extern const struct cmd_group balance_cmd_group;
diff --git a/common.c b/common.c
deleted file mode 100644
index 03f6570..0000000
--- a/common.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-
-int open_file_or_dir(const char *fname)
-{
-	int ret;
-	struct stat st;
-	DIR *dirstream;
-	int fd;
-
-	ret = stat(fname, &st);
-	if (ret < 0) {
-		return -1;
-	}
-	if (S_ISDIR(st.st_mode)) {
-		dirstream = opendir(fname);
-		if (!dirstream) {
-			return -2;
-		}
-		fd = dirfd(dirstream);
-	} else {
-		fd = open(fname, O_RDWR);
-	}
-	if (fd < 0) {
-		return -3;
-	}
-	return fd;
-}
diff --git a/utils.c b/utils.c
index 938f9a5..78530e1 100644
--- a/utils.c
+++ b/utils.c
@@ -16,8 +16,9 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#define _XOPEN_SOURCE 600
-#define __USE_XOPEN2K
+#define _XOPEN_SOURCE 700
+#define __USE_XOPEN2K8
+#define __XOPEN2K8 /* due to an error in dirent.h, to get dirfd() */
 #include <stdio.h>
 #include <stdlib.h>
 #ifndef __CHECKER__
@@ -1268,3 +1269,28 @@ u64 parse_size(char *s)
 	return strtoull(s, NULL, 10) * mult;
 }
 
+int open_file_or_dir(const char *fname)
+{
+	int ret;
+	struct stat st;
+	DIR *dirstream;
+	int fd;
+
+	ret = stat(fname, &st);
+	if (ret < 0) {
+		return -1;
+	}
+	if (S_ISDIR(st.st_mode)) {
+		dirstream = opendir(fname);
+		if (!dirstream) {
+			return -2;
+		}
+		fd = dirfd(dirstream);
+	} else {
+		fd = open(fname, O_RDWR);
+	}
+	if (fd < 0) {
+		return -3;
+	}
+	return fd;
+}
diff --git a/utils.h b/utils.h
index 714fd7a..ed43e84 100644
--- a/utils.h
+++ b/utils.h
@@ -19,6 +19,8 @@
 #ifndef __UTILS__
 #define __UTILS__
 
+#include "ctree.h"
+
 #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024)
 
 int make_btrfs(int fd, const char *device, const char *label,
@@ -44,8 +46,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
 char *pretty_sizes(u64 size);
 int check_label(char *input);
 int get_mountpt(char *dev, char *mntpt, size_t size);
-
 int btrfs_scan_block_devices(int run_ioctl);
-
 u64 parse_size(char *s);
+int open_file_or_dir(const char *fname);
 #endif
-- 
1.8.1.227.g44fe835


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

* [PATCH 02/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
  2013-01-29  6:48     ` [PATCH 01/12] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-30  3:27       ` Wang Shilong
  2013-01-29  6:48     ` [PATCH 03/12] Btrfs-progs: add parent uuid for snapshots Anand Jain
                       ` (9 subsequent siblings)
  11 siblings, 1 reply; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

To improve the code reuse its better to have btrfs_list_subvols
just return list of subvols witout printing

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 28 ++++++++++++++++++----------
 btrfs-list.h     |  2 +-
 cmds-subvolume.c |  4 ++--
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index cb42fbc..b404e1d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1439,15 +1439,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 	}
 }
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
-		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 {
-	struct root_lookup root_lookup;
-	struct root_lookup root_sort;
 	int ret;
 
-	ret = __list_subvol_search(fd, &root_lookup);
+	ret = __list_subvol_search(fd, root_lookup);
 	if (ret) {
 		fprintf(stderr, "ERROR: can't perform the search - %s\n",
 				strerror(errno));
@@ -1458,16 +1454,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
 	 * now we have an rbtree full of root_info objects, but we need to fill
 	 * in their path names within the subvol that is referencing each one.
 	 */
-	ret = __list_subvol_fill_paths(fd, &root_lookup);
-	if (ret < 0)
-		return ret;
+	ret = __list_subvol_fill_paths(fd, root_lookup);
+	return ret;
+}
 
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
+		       struct btrfs_list_comparer_set *comp_set,
+		       int is_tab_result)
+{
+	struct root_lookup root_lookup;
+	struct root_lookup root_sort;
+	int ret;
+
+	ret = btrfs_list_subvols(fd, &root_lookup);
+	if (ret)
+		return ret;
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
 	print_all_volume_info(&root_sort, is_tab_result);
 	__free_all_subvolumn(&root_lookup);
-	return ret;
+
+	return 0;
 }
 
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
diff --git a/btrfs-list.h b/btrfs-list.h
index cde4b3c..71fe0f3 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 			      enum btrfs_list_comp_enum comparer,
 			      int is_descending);
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
 			int is_tab_result);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index e3cdb1e..c35dff7 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
+	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				is_tab_result);
 	if (ret)
 		return 19;
@@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 03/12] Btrfs-progs: add parent uuid for snapshots
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
  2013-01-29  6:48     ` [PATCH 01/12] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
  2013-01-29  6:48     ` [PATCH 02/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-29  6:48     ` [PATCH 04/12] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
                       ` (8 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 34 ++++++++++++++++++++++++++++------
 btrfs-list.h     |  1 +
 cmds-subvolume.c |  6 +++++-
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index b404e1d..13a365d 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -80,6 +80,7 @@ struct root_info {
 	time_t otime;
 
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	/* path from the subvol we live in to this root, including the
 	 * root's name.  This is null until we do the extra lookup ioctl.
@@ -128,6 +129,11 @@ struct {
 		.need_print	= 0,
 	},
 	{
+		.name		= "parent_uuid",
+		.column_name	= "Parent UUID",
+		.need_print	= 0,
+	},
+	{
 		.name		= "uuid",
 		.column_name	= "UUID",
 		.need_print	= 0,
@@ -435,7 +441,7 @@ static struct root_info *root_tree_search(struct root_lookup *root_tree,
 static int update_root(struct root_lookup *root_lookup,
 		       u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		       u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		       time_t ot, void *uuid)
+		       time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 
@@ -472,6 +478,8 @@ static int update_root(struct root_lookup *root_lookup,
 		ri->otime = ot;
 	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
 
 	return 0;
 }
@@ -489,17 +497,18 @@ static int update_root(struct root_lookup *root_lookup,
  * gen: the current generation of the root
  * ot: the original time(create time) of the root
  * uuid: uuid of the root
+ * puuid: uuid of the root parent if any
  */
 static int add_root(struct root_lookup *root_lookup,
 		    u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		    u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		    time_t ot, void *uuid)
+		    time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 	int ret;
 
 	ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
-			  dir_id, name, name_len, ogen, gen, ot, uuid);
+			  dir_id, name, name_len, ogen, gen, ot, uuid, puuid);
 	if (!ret)
 		return 0;
 
@@ -537,9 +546,12 @@ static int add_root(struct root_lookup *root_lookup,
 	if (ot)
 		ri->otime = ot;
 
-	if (uuid) 
+	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
 
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
+
 	ret = root_tree_insert(root_lookup, ri);
 	if (ret) {
 		printf("failed to insert tree %llu\n", (unsigned long long)root_id);
@@ -1021,6 +1033,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 	int i;
 	time_t t;
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	root_lookup_init(root_lookup);
 	memset(&args, 0, sizeof(args));
@@ -1073,7 +1086,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 
 				add_root(root_lookup, sh.objectid, sh.offset,
 					 0, 0, dir_id, name, name_len, 0, 0, 0,
-					 NULL);
+					 NULL, NULL);
 			} else if (sh.type == BTRFS_ROOT_ITEM_KEY) {
 				ri = (struct btrfs_root_item *)(args.buf + off);
 				gen = btrfs_root_generation(ri);
@@ -1083,15 +1096,17 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 					t = ri->otime.sec;
 					ogen = btrfs_root_otransid(ri);
 					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
+					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
 				} else {
 					t = 0;
 					ogen = 0;
 					memset(uuid, 0, BTRFS_UUID_SIZE);
+					memset(puuid, 0, BTRFS_UUID_SIZE);
 				}
 
 				add_root(root_lookup, sh.objectid, 0,
 					 sh.offset, flags, 0, NULL, 0, ogen,
-					 gen, t, uuid);
+					 gen, t, uuid, puuid);
 			}
 
 			off += sh.len;
@@ -1345,6 +1360,13 @@ static void print_subvolume_column(struct root_info *subv,
 			uuid_unparse(subv->uuid, uuidparse);
 		printf("%s", uuidparse);
 		break;
+	case BTRFS_LIST_PUUID:
+		if (uuid_is_null(subv->puuid))
+			strcpy(uuidparse, "-");
+		else
+			uuid_unparse(subv->puuid, uuidparse);
+		printf("%s", uuidparse);
+		break;
 	case BTRFS_LIST_PATH:
 		BUG_ON(!subv->full_path);
 		printf("%s", subv->full_path);
diff --git a/btrfs-list.h b/btrfs-list.h
index 71fe0f3..855e73d 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -53,6 +53,7 @@ enum btrfs_list_column_enum {
 	BTRFS_LIST_PARENT,
 	BTRFS_LIST_TOP_LEVEL,
 	BTRFS_LIST_OTIME,
+	BTRFS_LIST_PUUID,
 	BTRFS_LIST_UUID,
 	BTRFS_LIST_PATH,
 	BTRFS_LIST_ALL,
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index c35dff7..a1e6893 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -280,6 +280,7 @@ static const char * const cmd_subvol_list_usage[] = {
 	"-p           print parent ID",
 	"-a           print all the subvolumes in the filesystem.",
 	"-u           print the uuid of subvolumes (and snapshots)",
+	"-q           print the parent uuid of the snapshots",
 	"-t           print the result as a table",
 	"-s           list snapshots only in the filesystem",
 	"-r           list readonly subvolumes (including snapshots)",
@@ -319,7 +320,7 @@ static int cmd_subvol_list(int argc, char **argv)
 	optind = 1;
 	while(1) {
 		c = getopt_long(argc, argv,
-				    "apsurg:c:t", long_options, NULL);
+				    "apsuqrg:c:t", long_options, NULL);
 		if (c < 0)
 			break;
 
@@ -343,6 +344,9 @@ static int cmd_subvol_list(int argc, char **argv)
 		case 'u':
 			btrfs_list_setup_print_column(BTRFS_LIST_UUID);
 			break;
+		case 'q':
+			btrfs_list_setup_print_column(BTRFS_LIST_PUUID);
+			break;
 		case 'r':
 			flags |= BTRFS_ROOT_SUBVOL_RDONLY;
 			break;
-- 
1.8.1.227.g44fe835


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

* [PATCH 04/12] Btrfs-progs: move struct root_info to btrfs-list.h
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                       ` (2 preceding siblings ...)
  2013-01-29  6:48     ` [PATCH 03/12] Btrfs-progs: add parent uuid for snapshots Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-29  6:48     ` [PATCH 05/12] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
                       ` (7 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

As we would add more ways to list and manage the subvols
and snapshots, its better if we have struct root_info
defined in the header file.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 47 -----------------------------------------------
 btrfs-list.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 13a365d..909d814 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -46,53 +46,6 @@ struct root_lookup {
 	struct rb_root root;
 };
 
-/*
- * one of these for each root we find.
- */
-struct root_info {
-	struct rb_node rb_node;
-	struct rb_node sort_node;
-
-	/* this root's id */
-	u64 root_id;
-
-	/* equal the offset of the root's key */
-	u64 root_offset;
-
-	/* flags of the root */
-	u64 flags;
-
-	/* the id of the root that references this one */
-	u64 ref_tree;
-
-	/* the dir id we're in from ref_tree */
-	u64 dir_id;
-
-	u64 top_id;
-
-	/* generation when the root is created or last updated */
-	u64 gen;
-
-	/* creation generation of this root in sec*/
-	u64 ogen;
-
-	/* creation time of this root in sec*/
-	time_t otime;
-
-	u8 uuid[BTRFS_UUID_SIZE];
-	u8 puuid[BTRFS_UUID_SIZE];
-
-	/* path from the subvol we live in to this root, including the
-	 * root's name.  This is null until we do the extra lookup ioctl.
-	 */
-	char *path;
-
-	/* the name of this root in the directory it lives in */
-	char *name;
-
-	char *full_path;
-};
-
 struct {
 	char	*name;
 	char	*column_name;
diff --git a/btrfs-list.h b/btrfs-list.h
index 855e73d..3b7b680 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,7 +18,52 @@
 
 #include "kerncompat.h"
 
-struct root_info;
+/*
+ * one of these for each root we find.
+ */
+struct root_info {
+	struct rb_node rb_node;
+	struct rb_node sort_node;
+
+	/* this root's id */
+	u64 root_id;
+
+	/* equal the offset of the root's key */
+	u64 root_offset;
+
+	/* flags of the root */
+	u64 flags;
+
+	/* the id of the root that references this one */
+	u64 ref_tree;
+
+	/* the dir id we're in from ref_tree */
+	u64 dir_id;
+
+	u64 top_id;
+
+	/* generation when the root is created or last updated */
+	u64 gen;
+
+	/* creation generation of this root in sec*/
+	u64 ogen;
+
+	/* creation time of this root in sec*/
+	time_t otime;
+
+	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
+
+	/* path from the subvol we live in to this root, including the
+	 * root's name.  This is null until we do the extra lookup ioctl.
+	 */
+	char *path;
+
+	/* the name of this root in the directory it lives in */
+	char *name;
+
+	char *full_path;
+};
 
 typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
 typedef int (*btrfs_list_comp_func)(struct root_info *, struct root_info *,
-- 
1.8.1.227.g44fe835


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

* [PATCH 05/12] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                       ` (3 preceding siblings ...)
  2013-01-29  6:48     ` [PATCH 04/12] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-29  6:48     ` [PATCH 06/12] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
                       ` (6 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

We need a function which can get the root_info of a given
subvol. This is in preparation to add support for the show
sub-cli.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
 btrfs-list.h |  1 +
 2 files changed, 39 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 909d814..0ee13b6 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1453,6 +1453,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	return 0;
 }
 
+int btrfs_get_subvol(int fd, struct root_info *the_ri)
+{
+	int ret = -1;
+	struct root_lookup rl;
+	struct rb_node *rbn;
+	struct root_info *ri;
+	u64 root_id = btrfs_list_get_path_rootid(fd);
+
+	if (btrfs_list_subvols(fd, &rl))
+		return 1;
+
+	rbn = rb_first(&rl.root);
+	while(rbn) {
+		ri = rb_entry(rbn, struct root_info, rb_node);
+		resolve_root(&rl, ri, root_id);
+		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
+			memcpy(the_ri, ri, offsetof(struct root_info, path));
+			if (ri->path)
+				the_ri->path = strdup(ri->path);
+			else
+				the_ri->path = NULL;
+			if (ri->name)
+				the_ri->name = strdup(ri->name);
+			else
+				the_ri->name = NULL;
+			if (ri->full_path)
+				the_ri->full_path = strdup(ri->full_path);
+			else
+				the_ri->name = NULL;
+			ret = 0;
+			break;
+		}
+		rbn = rb_next(rbn);
+	}
+	__free_all_subvolumn(&rl);
+	return ret;
+}
+
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 			    struct btrfs_file_extent_item *item,
 			    u64 found_gen, u64 *cache_dirid,
diff --git a/btrfs-list.h b/btrfs-list.h
index 3b7b680..580d4d1 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
 u64 btrfs_list_get_path_rootid(int fd);
+int btrfs_get_subvol(int fd, struct root_info *the_ri);
-- 
1.8.1.227.g44fe835


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

* [PATCH 06/12] Btrfs-progs: add method to filter snapshots by parent uuid
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                       ` (4 preceding siblings ...)
  2013-01-29  6:48     ` [PATCH 05/12] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-29  6:48     ` [PATCH 07/12] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
                       ` (5 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 6 ++++++
 btrfs-list.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 0ee13b6..9c84ecb 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1142,6 +1142,11 @@ static int filter_topid_equal(struct root_info *ri, u64 data)
 	return ri->top_id == data;
 }
 
+static int filter_by_parent(struct root_info *ri, u64 data)
+{
+	return !uuid_compare(ri->puuid, (u8 *)data);
+}
+
 static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_ROOTID]		= filter_by_rootid,
 	[BTRFS_LIST_FILTER_SNAPSHOT_ONLY]	= filter_snapshot,
@@ -1153,6 +1158,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_CGEN_LESS]		= filter_cgen_less,
 	[BTRFS_LIST_FILTER_CGEN_EQUAL]          = filter_cgen_equal,
 	[BTRFS_LIST_FILTER_TOPID_EQUAL]		= filter_topid_equal,
+	[BTRFS_LIST_FILTER_BY_PARENT]		= filter_by_parent,
 };
 
 struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
diff --git a/btrfs-list.h b/btrfs-list.h
index 580d4d1..cde7a3f 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -117,6 +117,7 @@ enum btrfs_list_filter_enum {
 	BTRFS_LIST_FILTER_CGEN_LESS,
 	BTRFS_LIST_FILTER_CGEN_MORE,
 	BTRFS_LIST_FILTER_TOPID_EQUAL,
+	BTRFS_LIST_FILTER_BY_PARENT,
 	BTRFS_LIST_FILTER_MAX,
 };
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 07/12] Btrfs-progs: put find_mount_root() in commands.h
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                       ` (5 preceding siblings ...)
  2013-01-29  6:48     ` [PATCH 06/12] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-29  6:48     ` [PATCH 08/12] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
                       ` (4 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

A useful function need to define it in a header file.

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

diff --git a/commands.h b/commands.h
index 8114a73..9b77f3e 100644
--- a/commands.h
+++ b/commands.h
@@ -103,3 +103,6 @@ int cmd_qgroup(int argc, char **argv);
 
 /* subvolume exported functions */
 int test_issubvolume(char *path);
+
+/* send.c */
+int find_mount_root(const char *path, char **mount_root);
-- 
1.8.1.227.g44fe835


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

* [PATCH 08/12] Btrfs-progs: make printing subvol extensible to newer layouts
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                       ` (6 preceding siblings ...)
  2013-01-29  6:48     ` [PATCH 07/12] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-29  6:48     ` [PATCH 09/12] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
                       ` (3 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Currently you can print subvol in a list or table format.
This patch will provide a way to extend this to other formats
like the upcoming raw format.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 26 +++++++++++++++-----------
 btrfs-list.h     |  3 +++
 cmds-subvolume.c | 23 ++++++++++++++++++++---
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 9c84ecb..656de10 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -54,12 +54,12 @@ struct {
 	{
 		.name		= "ID",
 		.column_name	= "ID",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "gen",
 		.column_name	= "Gen",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "cgen",
@@ -74,7 +74,7 @@ struct {
 	{
 		.name		= "top level",
 		.column_name	= "Top Level",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "otime",
@@ -94,7 +94,7 @@ struct {
 	{
 		.name		= "path",
 		.column_name	= "Path",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= NULL,
@@ -1401,21 +1401,25 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int is_tab_result)
+				  int layout)
 {
 	struct rb_node *n;
 	struct root_info *entry;
 
-	if (is_tab_result)
+	if (layout == BTRFS_LIST_LAYOUT_TABLE)
 		print_all_volume_info_tab_head();
 
 	n = rb_first(&sorted_tree->root);
 	while (n) {
 		entry = rb_entry(n, struct root_info, sort_node);
-		if (is_tab_result)
-			print_single_volume_info_table(entry);
-		else
+		switch (layout) {
+		case BTRFS_LIST_LAYOUT_DEFAULT:
 			print_single_volume_info_default(entry);
+			break;
+		case BTRFS_LIST_LAYOUT_TABLE:
+			print_single_volume_info_table(entry);
+			break;
+		}
 		n = rb_next(n);
 	}
 }
@@ -1441,7 +1445,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+		       int layout)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1453,7 +1457,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, is_tab_result);
+	print_all_volume_info(&root_sort, layout);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index cde7a3f..5b60068 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,6 +18,9 @@
 
 #include "kerncompat.h"
 
+#define BTRFS_LIST_LAYOUT_DEFAULT	0
+#define BTRFS_LIST_LAYOUT_TABLE	1
+
 /*
  * one of these for each root we find.
  */
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index a1e6893..bb9629f 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -410,8 +410,18 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				is_tab_result);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	if (is_tab_result)
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_TABLE);
+	else
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
@@ -617,7 +627,14 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
+		BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 09/12] Btrfs-progs: make get_subvol_name non cmds-send specific
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                       ` (7 preceding siblings ...)
  2013-01-29  6:48     ` [PATCH 08/12] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-29  6:48     ` [PATCH 10/12] Btrfs-progs: add show subcommand to subvol cli Anand Jain
                       ` (2 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

get_subvol_name can be used other than the just with in cmds-send.c
so this patch will make it possible with out changing the original
intentions.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-send.c | 12 ++++++------
 commands.h  |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/cmds-send.c b/cmds-send.c
index ac1d3cf..0416b79 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -333,12 +333,12 @@ out:
 	return ret;
 }
 
-static const char *get_subvol_name(struct btrfs_send *s, const char *full_path)
+char *get_subvol_name(char *mnt, char *full_path)
 {
-	int len = strlen(s->root_path);
+	int len = strlen(mnt);
 	if (!len)
 		return full_path;
-	if (s->root_path[len - 1] != '/')
+	if (mnt[len - 1] != '/')
 		len += 1;
 
 	return full_path + len;
@@ -452,7 +452,7 @@ int cmd_send_start(int argc, char **argv)
 			if (ret < 0)
 				goto out;
 
-			ret = get_root_id(&send, get_subvol_name(&send, subvol),
+			ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 					&root_id);
 			if (ret < 0) {
 				fprintf(stderr, "ERROR: could not resolve "
@@ -513,7 +513,7 @@ int cmd_send_start(int argc, char **argv)
 
 	if (snapshot_parent != NULL) {
 		ret = get_root_id(&send,
-				get_subvol_name(&send, snapshot_parent),
+				get_subvol_name(send.root_path, snapshot_parent),
 				&parent_root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
@@ -572,7 +572,7 @@ int cmd_send_start(int argc, char **argv)
 			goto out;
 		}
 
-		ret = get_root_id(&send, get_subvol_name(&send, subvol),
+		ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 				&root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
diff --git a/commands.h b/commands.h
index 9b77f3e..631fb6b 100644
--- a/commands.h
+++ b/commands.h
@@ -106,3 +106,4 @@ int test_issubvolume(char *path);
 
 /* send.c */
 int find_mount_root(const char *path, char **mount_root);
+char *get_subvol_name(char *mnt, char *full_path);
-- 
1.8.1.227.g44fe835


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

* [PATCH 10/12] Btrfs-progs: add show subcommand to subvol cli
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                       ` (8 preceding siblings ...)
  2013-01-29  6:48     ` [PATCH 09/12] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
@ 2013-01-29  6:48     ` Anand Jain
  2013-01-30 10:32       ` Wang Shilong
  2013-01-29  6:49     ` [PATCH 11/12] Btrfs-progs: filter the deleted subvolumes when listing snapshots Anand Jain
  2013-01-29  6:49     ` [PATCH 12/12] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes Anand Jain
  11 siblings, 1 reply; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:48 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

This adds show sub-command to the btrfs subvol cli
to display detailed inforamtion of the given subvol
or snapshot.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     |  25 +++++++--
 btrfs-list.h     |   3 +-
 cmds-subvolume.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 man/btrfs.8.in   |   6 +++
 4 files changed, 182 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 656de10..1915ece 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1335,6 +1335,22 @@ static void print_subvolume_column(struct root_info *subv,
 	}
 }
 
+static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_LIST_ALL; i++) {
+		if (!btrfs_list_columns[i].need_print)
+			continue;
+
+		if (raw_prefix)
+			printf("%s",raw_prefix);
+
+		print_subvolume_column(subv, i);
+	}
+	printf("\n");
+}
+
 static void print_single_volume_info_table(struct root_info *subv)
 {
 	int i;
@@ -1401,7 +1417,7 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int layout)
+				  int layout, char *raw_prefix)
 {
 	struct rb_node *n;
 	struct root_info *entry;
@@ -1419,6 +1435,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 		case BTRFS_LIST_LAYOUT_TABLE:
 			print_single_volume_info_table(entry);
 			break;
+		case BTRFS_LIST_LAYOUT_RAW:
+			print_single_volume_info_raw(entry, raw_prefix);
+			break;
 		}
 		n = rb_next(n);
 	}
@@ -1445,7 +1464,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int layout)
+		       int layout, char *raw_prefix)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1457,7 +1476,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, layout);
+	print_all_volume_info(&root_sort, layout, raw_prefix);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index 5b60068..09d35f7 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -20,6 +20,7 @@
 
 #define BTRFS_LIST_LAYOUT_DEFAULT	0
 #define BTRFS_LIST_LAYOUT_TABLE	1
+#define BTRFS_LIST_LAYOUT_RAW		2
 
 /*
  * one of these for each root we find.
@@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-			int is_tab_result);
+			int layout, char *raw_prefix);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index bb9629f..6a14c4c 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -24,6 +24,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
+#include <uuid/uuid.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
 
 	if (is_tab_result)
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_TABLE);
+				BTRFS_LIST_LAYOUT_TABLE, NULL);
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_DEFAULT);
+				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
-		BTRFS_LIST_LAYOUT_DEFAULT);
+		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -721,6 +722,153 @@ static int cmd_find_new(int argc, char **argv)
 	return 0;
 }
 
+static const char * const cmd_subvol_show_usage[] = {
+	"btrfs subvolume show <subvol-path>",
+	"Show more information of the subvolume",
+	NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+	struct root_info get_ri;
+	struct btrfs_list_filter_set *filter_set;
+	char tstr[256];
+	char uuidparse[37];
+	char *fullpath = NULL, *svpath = NULL, *mnt = NULL;
+	char raw_prefix[] = "\t\t\t\t";
+	u64 sv_id, mntid;
+	int fd = -1, mntfd = -1;
+	int ret = -1;
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_subvol_show_usage);
+
+	fullpath = realpath(argv[1], 0);
+	if (!fullpath) {
+		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
+			argv[1], strerror(errno));
+		goto out;
+	}
+
+	ret = test_issubvolume(fullpath);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
+		goto out;
+	}
+	if (!ret) {
+		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
+		ret = -1;
+		goto out;
+	}
+
+	ret = find_mount_root(fullpath, &mnt);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
+				"%s\n", fullpath, strerror(-ret));
+		goto out;
+	}
+	ret = -1;
+	svpath = get_subvol_name(mnt, fullpath);
+
+	fd = open_file_or_dir(fullpath);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
+		goto out;
+	}
+
+	sv_id = btrfs_list_get_path_rootid(fd);
+	if (sv_id < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
+			fullpath);
+		goto out;
+	}
+
+	mntfd = open_file_or_dir(mnt);
+	if (mntfd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
+		goto out;
+	}
+
+	mntid = btrfs_list_get_path_rootid(mntfd);
+	if (mntid < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
+		goto out;
+	}
+
+	if (sv_id == BTRFS_FS_TREE_OBJECTID) {
+		printf("%s is btrfs root\n", fullpath);
+		goto out;
+	}
+
+	memset(&get_ri, 0, sizeof(get_ri));
+	get_ri.root_id = sv_id;
+
+	if (btrfs_get_subvol(mntfd, &get_ri)) {
+		fprintf(stderr, "ERROR: can't find '%s'\n",
+			svpath);
+		goto out;
+	}
+
+	ret = 0;
+	/* print the info */
+	printf("%s\n", fullpath);
+	printf("\tName: \t\t\t%s\n", get_ri.name);
+
+	if (uuid_is_null(get_ri.uuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.uuid, uuidparse);
+	printf("\tuuid: \t\t\t%s\n", uuidparse);
+
+	if (uuid_is_null(get_ri.puuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.puuid, uuidparse);
+	printf("\tParent uuid: \t\t%s\n", uuidparse);
+
+	if (get_ri.otime)
+		strftime(tstr, 256, "%Y-%m-%d %X",
+			 localtime(&get_ri.otime));
+	else
+		strcpy(tstr, "-");
+	printf("\tCreation time: \t\t%s\n", tstr);
+
+	printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
+	printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
+	printf("\tGen at creation: \t%llu\n", get_ri.ogen);
+	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
+	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
+
+	/* print the snapshots of the given subvol if any*/
+	printf("\tSnapshot(s):\n");
+	filter_set = btrfs_list_alloc_filter_set();
+	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
+				get_ri.uuid);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
+			raw_prefix);
+
+	/* clean up */
+	if (get_ri.path)
+		free(get_ri.path);
+	if (get_ri.name)
+		free(get_ri.name);
+	if (get_ri.full_path)
+		free(get_ri.full_path);
+
+out:
+	if (mntfd >= 0)
+		close(mntfd);
+	if (fd >= 0)
+		close(fd);
+	if (mnt)
+		free(mnt);
+	if (fullpath)
+		free(fullpath);
+
+	return ret;
+}
+
 const struct cmd_group subvolume_cmd_group = {
 	subvolume_cmd_group_usage, NULL, {
 		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -732,6 +880,7 @@ const struct cmd_group subvolume_cmd_group = {
 		{ "set-default", cmd_subvol_set_default,
 			cmd_subvol_set_default_usage, NULL, 0 },
 		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
+		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
 	}
 };
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index d20e332..0008a06 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
 .PP
+\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
 [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
 [<\fIfile\fR>|<\fIdir\fR>...]
@@ -158,6 +160,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
 is similar to \fBsubvolume list\fR command.
 .TP
 
+\fBsubvolume show\fR\fI <path>\fR
+Show information of a given subvolume in the \fI<path>\fR.
+.TP
+
 \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
 [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 11/12] Btrfs-progs: filter the deleted subvolumes when listing snapshots
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                       ` (9 preceding siblings ...)
  2013-01-29  6:48     ` [PATCH 10/12] Btrfs-progs: add show subcommand to subvol cli Anand Jain
@ 2013-01-29  6:49     ` Anand Jain
  2013-01-29  6:49     ` [PATCH 12/12] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes Anand Jain
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:49 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

From: Wang Shilong <wangsl-fnst@cn.fujistu.com>

btrfs snapshot list command will stop by the deleted subvolumes.

The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
   but ROOT_ITEM still exists. The command will fail to fill the path of
   the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
   Fs tree
     |->subv0
	  |->subv1

   We may fill the path of subv1 firstly, after that, some user deletes subv1
   and subv0, and then we fill the path of subv0. The command will fail to
   fill the path of subv0 because we can not get path of subv0. And the command
   also will fail to make the full path of subv1 because we don't have the path
   of subv0.

Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.

For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.

Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 1915ece..db3665c 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -564,6 +564,12 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri,
 	while (1) {
 		char *tmp;
 		u64 next;
+		/*
+		* ref_tree = 0 indicates the subvolumes
+		* has been deleted.
+		*/
+		if (!found->ref_tree)
+			return -ENOENT;
 		int add_len = strlen(found->path);
 
 		/* room for / and for null */
@@ -592,6 +598,10 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri,
 			break;
 		}
 
+		/*
+		* if the ref_tree = BTRFS_FS_TREE_OBJECTID,
+		* we are at the top
+		*/
 		if (next == BTRFS_FS_TREE_OBJECTID) {
 			char p[] = "<FS_TREE>";
 			add_len = strlen(p);
@@ -607,14 +617,12 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri,
 		}
 
 		/*
-		 * if the ref_tree wasn't in our tree of roots, we're
-		 * at the top
-		 */
+		* if the ref_tree wasn't in our tree of roots, the
+		* subvolume was deleted.
+		*/
 		found = root_tree_search(rl, next);
-		if (!found) {
-			ri->top_id = next;
-			break;
-		}
+		if (!found)
+			return -ENOENT;
 	}
 
 	ri->full_path = full_path;
@@ -637,6 +645,9 @@ static int lookup_ino_path(int fd, struct root_info *ri)
 	if (ri->path)
 		return 0;
 
+	if (!ri->ref_tree)
+		return -ENOENT;
+
 	memset(&args, 0, sizeof(args));
 	args.treeid = ri->ref_tree;
 	args.objectid = ri->dir_id;
@@ -644,6 +655,10 @@ static int lookup_ino_path(int fd, struct root_info *ri)
 	ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
 	e = errno;
 	if (ret) {
+		if (e == ENOENT) {
+			ri->ref_tree = 0;
+			return -ENOENT;
+		}
 		fprintf(stderr, "ERROR: Failed to lookup path for root %llu - %s\n",
 			(unsigned long long)ri->ref_tree,
 			strerror(e));
@@ -1254,10 +1269,13 @@ static void __filter_and_sort_subvol(struct root_lookup *all_subvols,
 	while (n) {
 		entry = rb_entry(n, struct root_info, rb_node);
 
-		resolve_root(all_subvols, entry, top_id);
+		ret = resolve_root(all_subvols, entry, top_id);
+		if (ret == -ENOENT)
+			goto skip;
 		ret = filter_root(entry, filter_set);
 		if (ret)
 			sort_tree_insert(sort_tree, entry, comp_set);
+skip:
 		n = rb_prev(n);
 	}
 }
@@ -1272,7 +1290,7 @@ static int __list_subvol_fill_paths(int fd, struct root_lookup *root_lookup)
 		int ret;
 		entry = rb_entry(n, struct root_info, rb_node);
 		ret = lookup_ino_path(fd, entry);
-		if(ret < 0)
+		if (ret && ret != -ENOENT)
 			return ret;
 		n = rb_next(n);
 	}
@@ -1720,7 +1738,11 @@ char *btrfs_list_path_for_root(int fd, u64 root)
 		struct root_info *entry;
 
 		entry = rb_entry(n, struct root_info, rb_node);
-		resolve_root(&root_lookup, entry, top_id);
+		ret = resolve_root(&root_lookup, entry, top_id);
+		if (ret == -ENOENT && entry->root_id == root) {
+			ret_path = NULL;
+			break;
+		}
 		if (entry->root_id == root) {
 			ret_path = entry->full_path;
 			entry->full_path = NULL;
-- 
1.8.1.227.g44fe835


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

* [PATCH 12/12] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
                       ` (10 preceding siblings ...)
  2013-01-29  6:49     ` [PATCH 11/12] Btrfs-progs: filter the deleted subvolumes when listing snapshots Anand Jain
@ 2013-01-29  6:49     ` Anand Jain
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:49 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index db3665c..0cc368c 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1502,19 +1502,24 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 
 int btrfs_get_subvol(int fd, struct root_info *the_ri)
 {
-	int ret = -1;
+	int ret = 1, rr;
 	struct root_lookup rl;
 	struct rb_node *rbn;
 	struct root_info *ri;
 	u64 root_id = btrfs_list_get_path_rootid(fd);
 
 	if (btrfs_list_subvols(fd, &rl))
-		return 1;
+		return ret;
 
 	rbn = rb_first(&rl.root);
 	while(rbn) {
 		ri = rb_entry(rbn, struct root_info, rb_node);
-		resolve_root(&rl, ri, root_id);
+		rr = resolve_root(&rl, ri, root_id);
+		if (rr == -ENOENT) {
+			ret = -ENOENT;
+			rbn = rb_next(rbn);
+			continue;
+		}
 		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
 			memcpy(the_ri, ri, offsetof(struct root_info, path));
 			if (ri->path)
-- 
1.8.1.227.g44fe835


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

* Re: [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-28 18:04         ` David Sterba
@ 2013-01-29  6:59           ` Anand Jain
  0 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-29  6:59 UTC (permalink / raw)
  To: Wang Shilong; +Cc: linux-btrfs, dsterba, gene, miaox



  here the code is correct, this base does not have

   [PATCH] Btrfs-progs: filter the deleted subvolumes when listing snapshots

  which introduced -ENOENT as a return for the resolve_root.

  however since we should have that. I have integrated, and
  made corresponding changes in the btrfs_get_subvol. Kindly
  find V4.

Thanks, Anand


On 01/29/2013 02:04 AM, David Sterba wrote:
> On Mon, Jan 28, 2013 at 08:42:06PM -0800, Wang Shilong wrote:
>>> +	rbn = rb_first(&rl.root);
>>> +	while(rbn) {
>>> +		ri = rb_entry(rbn, struct root_info, rb_node);
>>> +		resolve_root(&rl, ri, root_id);
>>
>>    Here subvolume/snapshot deletion may happen,add a check here...
>>    if resolve_root return -ENOENT..it means deletion happens...
>>
>>    ret = reslove_root(&rl, ri, root_id);
>>    if (ret)
>>        goto again;
>>
> [...]
>>
>>   again???
>>> +		rbn = rb_next(rbn);
>>> +	}
>
> Then it looks like a for (...) { } pattern with 'continue' instead of
> 'goto'.
>
> david

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

* Re: [PATCH 02/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-01-29  6:48     ` [PATCH 02/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
@ 2013-01-30  3:27       ` Wang Shilong
  2013-01-30  9:57         ` Anand Jain
  0 siblings, 1 reply; 131+ messages in thread
From: Wang Shilong @ 2013-01-30  3:27 UTC (permalink / raw)
  To: Anand Jain; +Cc: dsterba, gene, linux-btrfs

Hi,
> To improve the code reuse its better to have btrfs_list_subvols
> just return list of subvols witout printing
>
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
>  btrfs-list.c     | 28 ++++++++++++++++++----------
>  btrfs-list.h     |  2 +-
>  cmds-subvolume.c |  4 ++--
>  3 files changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/btrfs-list.c b/btrfs-list.c
> index cb42fbc..b404e1d 100644
> --- a/btrfs-list.c
> +++ b/btrfs-list.c
> @@ -1439,15 +1439,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
>  	}
>  }
>  
> -int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
> -		       struct btrfs_list_comparer_set *comp_set,
> -		       int is_tab_result)
> +int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
>  {
> -	struct root_lookup root_lookup;
> -	struct root_lookup root_sort;
>  	int ret;
>  
> -	ret = __list_subvol_search(fd, &root_lookup);
> +	ret = __list_subvol_search(fd, root_lookup);
>  	if (ret) {
>  		fprintf(stderr, "ERROR: can't perform the search - %s\n",
>  				strerror(errno));
> @@ -1458,16 +1454,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
>  	 * now we have an rbtree full of root_info objects, but we need to fill
>  	 * in their path names within the subvol that is referencing each one.
>  	 */
> -	ret = __list_subvol_fill_paths(fd, &root_lookup);
> -	if (ret < 0)
> -		return ret;
> +	ret = __list_subvol_fill_paths(fd, root_lookup);
> +	return ret;
> +}
>  
> +int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
> +		       struct btrfs_list_comparer_set *comp_set,
> +		       int is_tab_result)
> +{
> +	struct root_lookup root_lookup;
> +	struct root_lookup root_sort;
> +	int ret;
> +
> +	ret = btrfs_list_subvols(fd, &root_lookup);
> +	if (ret)
> +		return ret;
>  	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
>  				 comp_set, fd);
>  
>  	print_all_volume_info(&root_sort, is_tab_result);
>  	__free_all_subvolumn(&root_lookup);
    Here we forget to free filter and comp_set before..i hope you can add it to your patchset..
    Maybe you can have patch 13...

    if (filter_set)
        btrfs_list_free_filter_set(filter_set);
    if (comp_set)
        btrfs_list_free_comparer_set(comp_set);

    Thanks,
    Wang
> -	return ret;
> +
> +	return 0;
>  }
>  
>  static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
> diff --git a/btrfs-list.h b/btrfs-list.h
> index cde4b3c..71fe0f3 100644
> --- a/btrfs-list.h
> +++ b/btrfs-list.h
> @@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
>  			      enum btrfs_list_comp_enum comparer,
>  			      int is_descending);
>  
> -int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
> +int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  		       struct btrfs_list_comparer_set *comp_set,
>  			int is_tab_result);
>  int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
> diff --git a/cmds-subvolume.c b/cmds-subvolume.c
> index e3cdb1e..c35dff7 100644
> --- a/cmds-subvolume.c
> +++ b/cmds-subvolume.c
> @@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
>  					BTRFS_LIST_FILTER_TOPID_EQUAL,
>  					top_id);
>  
> -	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
> +	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
>  				is_tab_result);
>  	if (ret)
>  		return 19;
> @@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
>  	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
>  				default_id);
>  
> -	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
> +	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
>  	if (ret)
>  		return 19;
>  	return 0;


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

* [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (25 preceding siblings ...)
  2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
@ 2013-01-30  9:56   ` Anand Jain
  2013-01-30  9:56     ` [PATCH 01/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
                       ` (11 more replies)
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
  27 siblings, 12 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

David,

 Please find this patch-set rebased with your integration-20130130 branch.

v4->v5:
	Fix a memory leak in the original code ref Patch 12/12
	Fix the compiler warning in the patch 9/12

Anand Jain (11):
  Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  Btrfs-progs: add parent uuid for snapshots
  Btrfs-progs: move struct root_info to btrfs-list.h
  Btrfs-progs: add function btrfs_get_subvol to get root_info of a
    subvol
  Btrfs-progs: add method to filter snapshots by parent uuid
  Btrfs-progs: put find_mount_root() in commands.h
  Btrfs-progs: make printing subvol extensible to newer layouts
  Btrfs-progs: make get_subvol_name non cmds-send specific
  Btrfs-progs: add show subcommand to subvol cli
  Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root
    ret changes
  Btrfs-progs: Fix a small memory leak in managing the btrfs list filter

Wang Shilong (1):
  Btrfs-progs: filter the deleted subvolumes when listing snapshots

 btrfs-list.c     | 239 ++++++++++++++++++++++++++++++++++++-------------------
 btrfs-list.h     |  58 +++++++++++++-
 cmds-send.c      |  12 +--
 cmds-subvolume.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 commands.h       |   4 +
 man/btrfs.8.in   |   6 ++
 6 files changed, 443 insertions(+), 111 deletions(-)

-- 
1.8.1.227.g44fe835


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

* [PATCH 01/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 02/12] Btrfs-progs: add parent uuid for snapshots Anand Jain
                       ` (10 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

To improve the code reuse its better to have btrfs_list_subvols
just return list of subvols witout printing

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 28 ++++++++++++++++++----------
 btrfs-list.h     |  2 +-
 cmds-subvolume.c |  4 ++--
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index e09ee2d..ab42a33 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1440,15 +1440,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 	}
 }
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
-		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 {
-	struct root_lookup root_lookup;
-	struct root_lookup root_sort;
 	int ret;
 
-	ret = __list_subvol_search(fd, &root_lookup);
+	ret = __list_subvol_search(fd, root_lookup);
 	if (ret) {
 		fprintf(stderr, "ERROR: can't perform the search - %s\n",
 				strerror(errno));
@@ -1459,16 +1455,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
 	 * now we have an rbtree full of root_info objects, but we need to fill
 	 * in their path names within the subvol that is referencing each one.
 	 */
-	ret = __list_subvol_fill_paths(fd, &root_lookup);
-	if (ret < 0)
-		return ret;
+	ret = __list_subvol_fill_paths(fd, root_lookup);
+	return ret;
+}
 
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
+		       struct btrfs_list_comparer_set *comp_set,
+		       int is_tab_result)
+{
+	struct root_lookup root_lookup;
+	struct root_lookup root_sort;
+	int ret;
+
+	ret = btrfs_list_subvols(fd, &root_lookup);
+	if (ret)
+		return ret;
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
 	print_all_volume_info(&root_sort, is_tab_result);
 	__free_all_subvolumn(&root_lookup);
-	return ret;
+
+	return 0;
 }
 
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
diff --git a/btrfs-list.h b/btrfs-list.h
index cde4b3c..71fe0f3 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 			      enum btrfs_list_comp_enum comparer,
 			      int is_descending);
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
 			int is_tab_result);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index e3cdb1e..c35dff7 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
+	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				is_tab_result);
 	if (ret)
 		return 19;
@@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 02/12] Btrfs-progs: add parent uuid for snapshots
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
  2013-01-30  9:56     ` [PATCH 01/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 03/12] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
                       ` (9 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 34 ++++++++++++++++++++++++++++------
 btrfs-list.h     |  1 +
 cmds-subvolume.c |  6 +++++-
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index ab42a33..03a0d02 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -80,6 +80,7 @@ struct root_info {
 	time_t otime;
 
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	/* path from the subvol we live in to this root, including the
 	 * root's name.  This is null until we do the extra lookup ioctl.
@@ -128,6 +129,11 @@ struct {
 		.need_print	= 0,
 	},
 	{
+		.name		= "parent_uuid",
+		.column_name	= "Parent UUID",
+		.need_print	= 0,
+	},
+	{
 		.name		= "uuid",
 		.column_name	= "UUID",
 		.need_print	= 0,
@@ -435,7 +441,7 @@ static struct root_info *root_tree_search(struct root_lookup *root_tree,
 static int update_root(struct root_lookup *root_lookup,
 		       u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		       u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		       time_t ot, void *uuid)
+		       time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 
@@ -472,6 +478,8 @@ static int update_root(struct root_lookup *root_lookup,
 		ri->otime = ot;
 	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
 
 	return 0;
 }
@@ -489,17 +497,18 @@ static int update_root(struct root_lookup *root_lookup,
  * gen: the current generation of the root
  * ot: the original time(create time) of the root
  * uuid: uuid of the root
+ * puuid: uuid of the root parent if any
  */
 static int add_root(struct root_lookup *root_lookup,
 		    u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		    u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		    time_t ot, void *uuid)
+		    time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 	int ret;
 
 	ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
-			  dir_id, name, name_len, ogen, gen, ot, uuid);
+			  dir_id, name, name_len, ogen, gen, ot, uuid, puuid);
 	if (!ret)
 		return 0;
 
@@ -537,9 +546,12 @@ static int add_root(struct root_lookup *root_lookup,
 	if (ot)
 		ri->otime = ot;
 
-	if (uuid) 
+	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
 
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
+
 	ret = root_tree_insert(root_lookup, ri);
 	if (ret) {
 		printf("failed to insert tree %llu\n", (unsigned long long)root_id);
@@ -1022,6 +1034,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 	int i;
 	time_t t;
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	root_lookup_init(root_lookup);
 	memset(&args, 0, sizeof(args));
@@ -1074,7 +1087,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 
 				add_root(root_lookup, sh.objectid, sh.offset,
 					 0, 0, dir_id, name, name_len, 0, 0, 0,
-					 NULL);
+					 NULL, NULL);
 			} else if (sh.type == BTRFS_ROOT_ITEM_KEY) {
 				ri = (struct btrfs_root_item *)(args.buf + off);
 				gen = btrfs_root_generation(ri);
@@ -1084,15 +1097,17 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 					t = ri->otime.sec;
 					ogen = btrfs_root_otransid(ri);
 					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
+					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
 				} else {
 					t = 0;
 					ogen = 0;
 					memset(uuid, 0, BTRFS_UUID_SIZE);
+					memset(puuid, 0, BTRFS_UUID_SIZE);
 				}
 
 				add_root(root_lookup, sh.objectid, 0,
 					 sh.offset, flags, 0, NULL, 0, ogen,
-					 gen, t, uuid);
+					 gen, t, uuid, puuid);
 			}
 
 			off += sh.len;
@@ -1346,6 +1361,13 @@ static void print_subvolume_column(struct root_info *subv,
 			uuid_unparse(subv->uuid, uuidparse);
 		printf("%s", uuidparse);
 		break;
+	case BTRFS_LIST_PUUID:
+		if (uuid_is_null(subv->puuid))
+			strcpy(uuidparse, "-");
+		else
+			uuid_unparse(subv->puuid, uuidparse);
+		printf("%s", uuidparse);
+		break;
 	case BTRFS_LIST_PATH:
 		BUG_ON(!subv->full_path);
 		printf("%s", subv->full_path);
diff --git a/btrfs-list.h b/btrfs-list.h
index 71fe0f3..855e73d 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -53,6 +53,7 @@ enum btrfs_list_column_enum {
 	BTRFS_LIST_PARENT,
 	BTRFS_LIST_TOP_LEVEL,
 	BTRFS_LIST_OTIME,
+	BTRFS_LIST_PUUID,
 	BTRFS_LIST_UUID,
 	BTRFS_LIST_PATH,
 	BTRFS_LIST_ALL,
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index c35dff7..a1e6893 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -280,6 +280,7 @@ static const char * const cmd_subvol_list_usage[] = {
 	"-p           print parent ID",
 	"-a           print all the subvolumes in the filesystem.",
 	"-u           print the uuid of subvolumes (and snapshots)",
+	"-q           print the parent uuid of the snapshots",
 	"-t           print the result as a table",
 	"-s           list snapshots only in the filesystem",
 	"-r           list readonly subvolumes (including snapshots)",
@@ -319,7 +320,7 @@ static int cmd_subvol_list(int argc, char **argv)
 	optind = 1;
 	while(1) {
 		c = getopt_long(argc, argv,
-				    "apsurg:c:t", long_options, NULL);
+				    "apsuqrg:c:t", long_options, NULL);
 		if (c < 0)
 			break;
 
@@ -343,6 +344,9 @@ static int cmd_subvol_list(int argc, char **argv)
 		case 'u':
 			btrfs_list_setup_print_column(BTRFS_LIST_UUID);
 			break;
+		case 'q':
+			btrfs_list_setup_print_column(BTRFS_LIST_PUUID);
+			break;
 		case 'r':
 			flags |= BTRFS_ROOT_SUBVOL_RDONLY;
 			break;
-- 
1.8.1.227.g44fe835


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

* [PATCH 03/12] Btrfs-progs: move struct root_info to btrfs-list.h
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
  2013-01-30  9:56     ` [PATCH 01/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
  2013-01-30  9:56     ` [PATCH 02/12] Btrfs-progs: add parent uuid for snapshots Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 04/12] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
                       ` (8 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

As we would add more ways to list and manage the subvols
and snapshots, its better if we have struct root_info
defined in the header file.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 47 -----------------------------------------------
 btrfs-list.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 03a0d02..f41c008 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -46,53 +46,6 @@ struct root_lookup {
 	struct rb_root root;
 };
 
-/*
- * one of these for each root we find.
- */
-struct root_info {
-	struct rb_node rb_node;
-	struct rb_node sort_node;
-
-	/* this root's id */
-	u64 root_id;
-
-	/* equal the offset of the root's key */
-	u64 root_offset;
-
-	/* flags of the root */
-	u64 flags;
-
-	/* the id of the root that references this one */
-	u64 ref_tree;
-
-	/* the dir id we're in from ref_tree */
-	u64 dir_id;
-
-	u64 top_id;
-
-	/* generation when the root is created or last updated */
-	u64 gen;
-
-	/* creation generation of this root in sec*/
-	u64 ogen;
-
-	/* creation time of this root in sec*/
-	time_t otime;
-
-	u8 uuid[BTRFS_UUID_SIZE];
-	u8 puuid[BTRFS_UUID_SIZE];
-
-	/* path from the subvol we live in to this root, including the
-	 * root's name.  This is null until we do the extra lookup ioctl.
-	 */
-	char *path;
-
-	/* the name of this root in the directory it lives in */
-	char *name;
-
-	char *full_path;
-};
-
 struct {
 	char	*name;
 	char	*column_name;
diff --git a/btrfs-list.h b/btrfs-list.h
index 855e73d..3b7b680 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,7 +18,52 @@
 
 #include "kerncompat.h"
 
-struct root_info;
+/*
+ * one of these for each root we find.
+ */
+struct root_info {
+	struct rb_node rb_node;
+	struct rb_node sort_node;
+
+	/* this root's id */
+	u64 root_id;
+
+	/* equal the offset of the root's key */
+	u64 root_offset;
+
+	/* flags of the root */
+	u64 flags;
+
+	/* the id of the root that references this one */
+	u64 ref_tree;
+
+	/* the dir id we're in from ref_tree */
+	u64 dir_id;
+
+	u64 top_id;
+
+	/* generation when the root is created or last updated */
+	u64 gen;
+
+	/* creation generation of this root in sec*/
+	u64 ogen;
+
+	/* creation time of this root in sec*/
+	time_t otime;
+
+	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
+
+	/* path from the subvol we live in to this root, including the
+	 * root's name.  This is null until we do the extra lookup ioctl.
+	 */
+	char *path;
+
+	/* the name of this root in the directory it lives in */
+	char *name;
+
+	char *full_path;
+};
 
 typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
 typedef int (*btrfs_list_comp_func)(struct root_info *, struct root_info *,
-- 
1.8.1.227.g44fe835


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

* [PATCH 04/12] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (2 preceding siblings ...)
  2013-01-30  9:56     ` [PATCH 03/12] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 05/12] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
                       ` (7 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

We need a function which can get the root_info of a given
subvol. This is in preparation to add support for the show
sub-cli.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
 btrfs-list.h |  1 +
 2 files changed, 39 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index f41c008..0e4b3eb 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1454,6 +1454,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	return 0;
 }
 
+int btrfs_get_subvol(int fd, struct root_info *the_ri)
+{
+	int ret = -1;
+	struct root_lookup rl;
+	struct rb_node *rbn;
+	struct root_info *ri;
+	u64 root_id = btrfs_list_get_path_rootid(fd);
+
+	if (btrfs_list_subvols(fd, &rl))
+		return 1;
+
+	rbn = rb_first(&rl.root);
+	while(rbn) {
+		ri = rb_entry(rbn, struct root_info, rb_node);
+		resolve_root(&rl, ri, root_id);
+		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
+			memcpy(the_ri, ri, offsetof(struct root_info, path));
+			if (ri->path)
+				the_ri->path = strdup(ri->path);
+			else
+				the_ri->path = NULL;
+			if (ri->name)
+				the_ri->name = strdup(ri->name);
+			else
+				the_ri->name = NULL;
+			if (ri->full_path)
+				the_ri->full_path = strdup(ri->full_path);
+			else
+				the_ri->name = NULL;
+			ret = 0;
+			break;
+		}
+		rbn = rb_next(rbn);
+	}
+	__free_all_subvolumn(&rl);
+	return ret;
+}
+
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 			    struct btrfs_file_extent_item *item,
 			    u64 found_gen, u64 *cache_dirid,
diff --git a/btrfs-list.h b/btrfs-list.h
index 3b7b680..580d4d1 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
 u64 btrfs_list_get_path_rootid(int fd);
+int btrfs_get_subvol(int fd, struct root_info *the_ri);
-- 
1.8.1.227.g44fe835


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

* [PATCH 05/12] Btrfs-progs: add method to filter snapshots by parent uuid
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (3 preceding siblings ...)
  2013-01-30  9:56     ` [PATCH 04/12] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 06/12] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
                       ` (6 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 6 ++++++
 btrfs-list.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 0e4b3eb..93d167e 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1143,6 +1143,11 @@ static int filter_topid_equal(struct root_info *ri, u64 data)
 	return ri->top_id == data;
 }
 
+static int filter_by_parent(struct root_info *ri, u64 data)
+{
+	return !uuid_compare(ri->puuid, (u8 *)data);
+}
+
 static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_ROOTID]		= filter_by_rootid,
 	[BTRFS_LIST_FILTER_SNAPSHOT_ONLY]	= filter_snapshot,
@@ -1154,6 +1159,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_CGEN_LESS]		= filter_cgen_less,
 	[BTRFS_LIST_FILTER_CGEN_EQUAL]          = filter_cgen_equal,
 	[BTRFS_LIST_FILTER_TOPID_EQUAL]		= filter_topid_equal,
+	[BTRFS_LIST_FILTER_BY_PARENT]		= filter_by_parent,
 };
 
 struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
diff --git a/btrfs-list.h b/btrfs-list.h
index 580d4d1..cde7a3f 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -117,6 +117,7 @@ enum btrfs_list_filter_enum {
 	BTRFS_LIST_FILTER_CGEN_LESS,
 	BTRFS_LIST_FILTER_CGEN_MORE,
 	BTRFS_LIST_FILTER_TOPID_EQUAL,
+	BTRFS_LIST_FILTER_BY_PARENT,
 	BTRFS_LIST_FILTER_MAX,
 };
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 06/12] Btrfs-progs: put find_mount_root() in commands.h
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (4 preceding siblings ...)
  2013-01-30  9:56     ` [PATCH 05/12] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 07/12] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
                       ` (5 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

A useful function need to define it in a header file.

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

diff --git a/commands.h b/commands.h
index 61d74d7..1dd6180 100644
--- a/commands.h
+++ b/commands.h
@@ -105,3 +105,6 @@ int cmd_replace(int argc, char **argv);
 
 /* subvolume exported functions */
 int test_issubvolume(char *path);
+
+/* send.c */
+int find_mount_root(const char *path, char **mount_root);
-- 
1.8.1.227.g44fe835


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

* [PATCH 07/12] Btrfs-progs: make printing subvol extensible to newer layouts
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (5 preceding siblings ...)
  2013-01-30  9:56     ` [PATCH 06/12] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 08/12] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
                       ` (4 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Currently you can print subvol in a list or table format.
This patch will provide a way to extend this to other formats
like the upcoming raw format.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 26 +++++++++++++++-----------
 btrfs-list.h     |  3 +++
 cmds-subvolume.c | 23 ++++++++++++++++++++---
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 93d167e..20b84ab 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -54,12 +54,12 @@ struct {
 	{
 		.name		= "ID",
 		.column_name	= "ID",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "gen",
 		.column_name	= "Gen",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "cgen",
@@ -74,7 +74,7 @@ struct {
 	{
 		.name		= "top level",
 		.column_name	= "Top Level",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "otime",
@@ -94,7 +94,7 @@ struct {
 	{
 		.name		= "path",
 		.column_name	= "Path",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= NULL,
@@ -1402,21 +1402,25 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int is_tab_result)
+				  int layout)
 {
 	struct rb_node *n;
 	struct root_info *entry;
 
-	if (is_tab_result)
+	if (layout == BTRFS_LIST_LAYOUT_TABLE)
 		print_all_volume_info_tab_head();
 
 	n = rb_first(&sorted_tree->root);
 	while (n) {
 		entry = rb_entry(n, struct root_info, sort_node);
-		if (is_tab_result)
-			print_single_volume_info_table(entry);
-		else
+		switch (layout) {
+		case BTRFS_LIST_LAYOUT_DEFAULT:
 			print_single_volume_info_default(entry);
+			break;
+		case BTRFS_LIST_LAYOUT_TABLE:
+			print_single_volume_info_table(entry);
+			break;
+		}
 		n = rb_next(n);
 	}
 }
@@ -1442,7 +1446,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+		       int layout)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1454,7 +1458,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, is_tab_result);
+	print_all_volume_info(&root_sort, layout);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index cde7a3f..5b60068 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,6 +18,9 @@
 
 #include "kerncompat.h"
 
+#define BTRFS_LIST_LAYOUT_DEFAULT	0
+#define BTRFS_LIST_LAYOUT_TABLE	1
+
 /*
  * one of these for each root we find.
  */
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index a1e6893..bb9629f 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -410,8 +410,18 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				is_tab_result);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	if (is_tab_result)
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_TABLE);
+	else
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
@@ -617,7 +627,14 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
+		BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 08/12] Btrfs-progs: make get_subvol_name non cmds-send specific
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (6 preceding siblings ...)
  2013-01-30  9:56     ` [PATCH 07/12] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 09/12] Btrfs-progs: add show subcommand to subvol cli Anand Jain
                       ` (3 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

get_subvol_name can be used other than the just with in cmds-send.c
so this patch will make it possible with out changing the original
intentions.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-send.c | 12 ++++++------
 commands.h  |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/cmds-send.c b/cmds-send.c
index 4a8478d..0ec63a0 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -334,12 +334,12 @@ out:
 	return ret;
 }
 
-static const char *get_subvol_name(struct btrfs_send *s, const char *full_path)
+char *get_subvol_name(char *mnt, char *full_path)
 {
-	int len = strlen(s->root_path);
+	int len = strlen(mnt);
 	if (!len)
 		return full_path;
-	if (s->root_path[len - 1] != '/')
+	if (mnt[len - 1] != '/')
 		len += 1;
 
 	return full_path + len;
@@ -454,7 +454,7 @@ int cmd_send_start(int argc, char **argv)
 			if (ret < 0)
 				goto out;
 
-			ret = get_root_id(&send, get_subvol_name(&send, subvol),
+			ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 					&root_id);
 			if (ret < 0) {
 				fprintf(stderr, "ERROR: could not resolve "
@@ -524,7 +524,7 @@ int cmd_send_start(int argc, char **argv)
 
 	if (snapshot_parent != NULL) {
 		ret = get_root_id(&send,
-				get_subvol_name(&send, snapshot_parent),
+				get_subvol_name(send.root_path, snapshot_parent),
 				&parent_root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
@@ -583,7 +583,7 @@ int cmd_send_start(int argc, char **argv)
 			goto out;
 		}
 
-		ret = get_root_id(&send, get_subvol_name(&send, subvol),
+		ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 				&root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
diff --git a/commands.h b/commands.h
index 1dd6180..ce0f3b9 100644
--- a/commands.h
+++ b/commands.h
@@ -108,3 +108,4 @@ int test_issubvolume(char *path);
 
 /* send.c */
 int find_mount_root(const char *path, char **mount_root);
+char *get_subvol_name(char *mnt, char *full_path);
-- 
1.8.1.227.g44fe835


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

* [PATCH 09/12] Btrfs-progs: add show subcommand to subvol cli
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (7 preceding siblings ...)
  2013-01-30  9:56     ` [PATCH 08/12] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 10/12] Btrfs-progs: filter the deleted subvolumes when listing snapshots Anand Jain
                       ` (2 subsequent siblings)
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

This adds show sub-command to the btrfs subvol cli
to display detailed inforamtion of the given subvol
or snapshot.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     |  25 +++++++--
 btrfs-list.h     |   3 +-
 cmds-subvolume.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 man/btrfs.8.in   |   6 +++
 4 files changed, 182 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 20b84ab..545aa15 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1336,6 +1336,22 @@ static void print_subvolume_column(struct root_info *subv,
 	}
 }
 
+static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_LIST_ALL; i++) {
+		if (!btrfs_list_columns[i].need_print)
+			continue;
+
+		if (raw_prefix)
+			printf("%s",raw_prefix);
+
+		print_subvolume_column(subv, i);
+	}
+	printf("\n");
+}
+
 static void print_single_volume_info_table(struct root_info *subv)
 {
 	int i;
@@ -1402,7 +1418,7 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int layout)
+				  int layout, char *raw_prefix)
 {
 	struct rb_node *n;
 	struct root_info *entry;
@@ -1420,6 +1436,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 		case BTRFS_LIST_LAYOUT_TABLE:
 			print_single_volume_info_table(entry);
 			break;
+		case BTRFS_LIST_LAYOUT_RAW:
+			print_single_volume_info_raw(entry, raw_prefix);
+			break;
 		}
 		n = rb_next(n);
 	}
@@ -1446,7 +1465,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int layout)
+		       int layout, char *raw_prefix)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1458,7 +1477,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, layout);
+	print_all_volume_info(&root_sort, layout, raw_prefix);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index 5b60068..09d35f7 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -20,6 +20,7 @@
 
 #define BTRFS_LIST_LAYOUT_DEFAULT	0
 #define BTRFS_LIST_LAYOUT_TABLE	1
+#define BTRFS_LIST_LAYOUT_RAW		2
 
 /*
  * one of these for each root we find.
@@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-			int is_tab_result);
+			int layout, char *raw_prefix);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index bb9629f..9f1d2a4 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -24,6 +24,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
+#include <uuid/uuid.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
 
 	if (is_tab_result)
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_TABLE);
+				BTRFS_LIST_LAYOUT_TABLE, NULL);
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_DEFAULT);
+				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
-		BTRFS_LIST_LAYOUT_DEFAULT);
+		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -721,6 +722,153 @@ static int cmd_find_new(int argc, char **argv)
 	return 0;
 }
 
+static const char * const cmd_subvol_show_usage[] = {
+	"btrfs subvolume show <subvol-path>",
+	"Show more information of the subvolume",
+	NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+	struct root_info get_ri;
+	struct btrfs_list_filter_set *filter_set;
+	char tstr[256];
+	char uuidparse[37];
+	char *fullpath = NULL, *svpath = NULL, *mnt = NULL;
+	char raw_prefix[] = "\t\t\t\t";
+	u64 sv_id, mntid;
+	int fd = -1, mntfd = -1;
+	int ret = -1;
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_subvol_show_usage);
+
+	fullpath = realpath(argv[1], 0);
+	if (!fullpath) {
+		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
+			argv[1], strerror(errno));
+		goto out;
+	}
+
+	ret = test_issubvolume(fullpath);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
+		goto out;
+	}
+	if (!ret) {
+		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
+		ret = -1;
+		goto out;
+	}
+
+	ret = find_mount_root(fullpath, &mnt);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
+				"%s\n", fullpath, strerror(-ret));
+		goto out;
+	}
+	ret = -1;
+	svpath = get_subvol_name(mnt, fullpath);
+
+	fd = open_file_or_dir(fullpath);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
+		goto out;
+	}
+
+	sv_id = btrfs_list_get_path_rootid(fd);
+	if (sv_id < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
+			fullpath);
+		goto out;
+	}
+
+	mntfd = open_file_or_dir(mnt);
+	if (mntfd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
+		goto out;
+	}
+
+	mntid = btrfs_list_get_path_rootid(mntfd);
+	if (mntid < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
+		goto out;
+	}
+
+	if (sv_id == BTRFS_FS_TREE_OBJECTID) {
+		printf("%s is btrfs root\n", fullpath);
+		goto out;
+	}
+
+	memset(&get_ri, 0, sizeof(get_ri));
+	get_ri.root_id = sv_id;
+
+	if (btrfs_get_subvol(mntfd, &get_ri)) {
+		fprintf(stderr, "ERROR: can't find '%s'\n",
+			svpath);
+		goto out;
+	}
+
+	ret = 0;
+	/* print the info */
+	printf("%s\n", fullpath);
+	printf("\tName: \t\t\t%s\n", get_ri.name);
+
+	if (uuid_is_null(get_ri.uuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.uuid, uuidparse);
+	printf("\tuuid: \t\t\t%s\n", uuidparse);
+
+	if (uuid_is_null(get_ri.puuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.puuid, uuidparse);
+	printf("\tParent uuid: \t\t%s\n", uuidparse);
+
+	if (get_ri.otime)
+		strftime(tstr, 256, "%Y-%m-%d %X",
+			 localtime(&get_ri.otime));
+	else
+		strcpy(tstr, "-");
+	printf("\tCreation time: \t\t%s\n", tstr);
+
+	printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
+	printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
+	printf("\tGen at creation: \t%llu\n", get_ri.ogen);
+	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
+	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
+
+	/* print the snapshots of the given subvol if any*/
+	printf("\tSnapshot(s):\n");
+	filter_set = btrfs_list_alloc_filter_set();
+	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
+				(u64)get_ri.uuid);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
+			raw_prefix);
+
+	/* clean up */
+	if (get_ri.path)
+		free(get_ri.path);
+	if (get_ri.name)
+		free(get_ri.name);
+	if (get_ri.full_path)
+		free(get_ri.full_path);
+
+out:
+	if (mntfd >= 0)
+		close(mntfd);
+	if (fd >= 0)
+		close(fd);
+	if (mnt)
+		free(mnt);
+	if (fullpath)
+		free(fullpath);
+
+	return ret;
+}
+
 const struct cmd_group subvolume_cmd_group = {
 	subvolume_cmd_group_usage, NULL, {
 		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -732,6 +880,7 @@ const struct cmd_group subvolume_cmd_group = {
 		{ "set-default", cmd_subvol_set_default,
 			cmd_subvol_set_default_usage, NULL, 0 },
 		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
+		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
 	}
 };
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 5f017f8..c8fdc15 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
 .PP
+\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
 [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
 [<\fIfile\fR>|<\fIdir\fR>...]
@@ -166,6 +168,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
 is similar to \fBsubvolume list\fR command.
 .TP
 
+\fBsubvolume show\fR\fI <path>\fR
+Show information of a given subvolume in the \fI<path>\fR.
+.TP
+
 \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
 [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 10/12] Btrfs-progs: filter the deleted subvolumes when listing snapshots
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (8 preceding siblings ...)
  2013-01-30  9:56     ` [PATCH 09/12] Btrfs-progs: add show subcommand to subvol cli Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 11/12] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes Anand Jain
  2013-01-30  9:56     ` [PATCH 12/12] Btrfs-progs: Fix a small memory leak in managing the btrfs list filter Anand Jain
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

From: Wang Shilong <wangsl-fnst@cn.fujistu.com>

btrfs snapshot list command will stop by the deleted subvolumes.

The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
   but ROOT_ITEM still exists. The command will fail to fill the path of
   the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
   Fs tree
     |->subv0
	  |->subv1

   We may fill the path of subv1 firstly, after that, some user deletes subv1
   and subv0, and then we fill the path of subv0. The command will fail to
   fill the path of subv0 because we can not get path of subv0. And the command
   also will fail to make the full path of subv1 because we don't have the path
   of subv0.

Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.

For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.

Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 545aa15..69ee3e7 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -564,6 +564,12 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri,
 	while (1) {
 		char *tmp;
 		u64 next;
+		/*
+		* ref_tree = 0 indicates the subvolumes
+		* has been deleted.
+		*/
+		if (!found->ref_tree)
+			return -ENOENT;
 		int add_len = strlen(found->path);
 
 		/* room for / and for null */
@@ -592,6 +598,10 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri,
 			break;
 		}
 
+		/*
+		* if the ref_tree = BTRFS_FS_TREE_OBJECTID,
+		* we are at the top
+		*/
 		if (next == BTRFS_FS_TREE_OBJECTID) {
 			char p[] = "<FS_TREE>";
 			add_len = strlen(p);
@@ -608,14 +618,12 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri,
 		}
 
 		/*
-		 * if the ref_tree wasn't in our tree of roots, we're
-		 * at the top
-		 */
+		* if the ref_tree wasn't in our tree of roots, the
+		* subvolume was deleted.
+		*/
 		found = root_tree_search(rl, next);
-		if (!found) {
-			ri->top_id = next;
-			break;
-		}
+		if (!found)
+			return -ENOENT;
 	}
 
 	ri->full_path = full_path;
@@ -638,6 +646,9 @@ static int lookup_ino_path(int fd, struct root_info *ri)
 	if (ri->path)
 		return 0;
 
+	if (!ri->ref_tree)
+		return -ENOENT;
+
 	memset(&args, 0, sizeof(args));
 	args.treeid = ri->ref_tree;
 	args.objectid = ri->dir_id;
@@ -645,6 +656,10 @@ static int lookup_ino_path(int fd, struct root_info *ri)
 	ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
 	e = errno;
 	if (ret) {
+		if (e == ENOENT) {
+			ri->ref_tree = 0;
+			return -ENOENT;
+		}
 		fprintf(stderr, "ERROR: Failed to lookup path for root %llu - %s\n",
 			(unsigned long long)ri->ref_tree,
 			strerror(e));
@@ -1255,10 +1270,13 @@ static void __filter_and_sort_subvol(struct root_lookup *all_subvols,
 	while (n) {
 		entry = rb_entry(n, struct root_info, rb_node);
 
-		resolve_root(all_subvols, entry, top_id);
+		ret = resolve_root(all_subvols, entry, top_id);
+		if (ret == -ENOENT)
+			goto skip;
 		ret = filter_root(entry, filter_set);
 		if (ret)
 			sort_tree_insert(sort_tree, entry, comp_set);
+skip:
 		n = rb_prev(n);
 	}
 }
@@ -1273,7 +1291,7 @@ static int __list_subvol_fill_paths(int fd, struct root_lookup *root_lookup)
 		int ret;
 		entry = rb_entry(n, struct root_info, rb_node);
 		ret = lookup_ino_path(fd, entry);
-		if(ret < 0)
+		if (ret && ret != -ENOENT)
 			return ret;
 		n = rb_next(n);
 	}
@@ -1721,7 +1739,11 @@ char *btrfs_list_path_for_root(int fd, u64 root)
 		struct root_info *entry;
 
 		entry = rb_entry(n, struct root_info, rb_node);
-		resolve_root(&root_lookup, entry, top_id);
+		ret = resolve_root(&root_lookup, entry, top_id);
+		if (ret == -ENOENT && entry->root_id == root) {
+			ret_path = NULL;
+			break;
+		}
 		if (entry->root_id == root) {
 			ret_path = entry->full_path;
 			entry->full_path = NULL;
-- 
1.8.1.227.g44fe835


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

* [PATCH 11/12] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (9 preceding siblings ...)
  2013-01-30  9:56     ` [PATCH 10/12] Btrfs-progs: filter the deleted subvolumes when listing snapshots Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  2013-01-30  9:56     ` [PATCH 12/12] Btrfs-progs: Fix a small memory leak in managing the btrfs list filter Anand Jain
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 69ee3e7..eadfba4 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1503,19 +1503,24 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 
 int btrfs_get_subvol(int fd, struct root_info *the_ri)
 {
-	int ret = -1;
+	int ret = 1, rr;
 	struct root_lookup rl;
 	struct rb_node *rbn;
 	struct root_info *ri;
 	u64 root_id = btrfs_list_get_path_rootid(fd);
 
 	if (btrfs_list_subvols(fd, &rl))
-		return 1;
+		return ret;
 
 	rbn = rb_first(&rl.root);
 	while(rbn) {
 		ri = rb_entry(rbn, struct root_info, rb_node);
-		resolve_root(&rl, ri, root_id);
+		rr = resolve_root(&rl, ri, root_id);
+		if (rr == -ENOENT) {
+			ret = -ENOENT;
+			rbn = rb_next(rbn);
+			continue;
+		}
 		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
 			memcpy(the_ri, ri, offsetof(struct root_info, path));
 			if (ri->path)
-- 
1.8.1.227.g44fe835


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

* [PATCH 12/12] Btrfs-progs: Fix a small memory leak in managing the btrfs list filter
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (10 preceding siblings ...)
  2013-01-30  9:56     ` [PATCH 11/12] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes Anand Jain
@ 2013-01-30  9:56     ` Anand Jain
  11 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-subvolume.c | 57 +++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index 9f1d2a4..5e51a26 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -303,9 +303,9 @@ static int cmd_subvol_list(int argc, char **argv)
 	struct btrfs_list_filter_set *filter_set;
 	struct btrfs_list_comparer_set *comparer_set;
 	u64 flags = 0;
-	int fd;
+	int fd = -1;
 	u64 top_id;
-	int ret;
+	int ret = -1, uerr = 0;
 	int c;
 	char *subvol;
 	int is_tab_result = 0;
@@ -356,8 +356,10 @@ static int cmd_subvol_list(int argc, char **argv)
 			ret = btrfs_list_parse_filter_string(optarg,
 							&filter_set,
 							BTRFS_LIST_FILTER_GEN);
-			if (ret)
-				usage(cmd_subvol_list_usage);
+			if (ret) {
+				uerr = 1;
+				goto out;
+			}
 			break;
 
 		case 'c':
@@ -365,18 +367,23 @@ static int cmd_subvol_list(int argc, char **argv)
 			ret = btrfs_list_parse_filter_string(optarg,
 							&filter_set,
 							BTRFS_LIST_FILTER_CGEN);
-			if (ret)
-				usage(cmd_subvol_list_usage);
+			if (ret) {
+				uerr = 1;
+				goto out;
+			}
 			break;
 		case 'S':
 			ret = btrfs_list_parse_sort_string(optarg,
 							   &comparer_set);
-			if (ret)
-				usage(cmd_subvol_list_usage);
+			if (ret) {
+				uerr = 1;
+				goto out;
+			}
 			break;
 
 		default:
-			usage(cmd_subvol_list_usage);
+			uerr = 1;
+			goto out;
 		}
 	}
 
@@ -384,25 +391,29 @@ static int cmd_subvol_list(int argc, char **argv)
 		btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_FLAGS,
 					flags);
 
-	if (check_argc_exact(argc - optind, 1))
-		usage(cmd_subvol_list_usage);
+	if (check_argc_exact(argc - optind, 1)) {
+		uerr = 1;
+		goto out;
+	}
 
 	subvol = argv[optind];
 
 	ret = test_issubvolume(subvol);
 	if (ret < 0) {
 		fprintf(stderr, "ERROR: error accessing '%s'\n", subvol);
-		return 12;
+		goto out;
 	}
 	if (!ret) {
 		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", subvol);
-		return 13;
+		ret = -1;
+		goto out;
 	}
 
 	fd = open_file_or_dir(subvol);
 	if (fd < 0) {
+		ret = -1;
 		fprintf(stderr, "ERROR: can't access '%s'\n", subvol);
-		return 12;
+		goto out;
 	}
 
 	top_id = btrfs_list_get_path_rootid(fd);
@@ -423,9 +434,16 @@ static int cmd_subvol_list(int argc, char **argv)
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
-	if (ret)
-		return 19;
-	return 0;
+
+out:
+	if (filter_set)
+		btrfs_list_free_filter_set(filter_set);
+	if (comparer_set)
+		btrfs_list_free_comparer_set(comparer_set);
+	if (uerr)
+		usage(cmd_subvol_list_usage);
+
+	return ret;
 }
 
 static const char * const cmd_snapshot_usage[] = {
@@ -636,6 +654,9 @@ static int cmd_subvol_get_default(int argc, char **argv)
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
 		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
+
+	if (filter_set)
+		btrfs_list_free_filter_set(filter_set);
 	if (ret)
 		return 19;
 	return 0;
@@ -855,6 +876,8 @@ static int cmd_subvol_show(int argc, char **argv)
 		free(get_ri.name);
 	if (get_ri.full_path)
 		free(get_ri.full_path);
+	if (filter_set)
+		btrfs_list_free_filter_set(filter_set);
 
 out:
 	if (mntfd >= 0)
-- 
1.8.1.227.g44fe835


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

* Re: [PATCH 02/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-01-30  3:27       ` Wang Shilong
@ 2013-01-30  9:57         ` Anand Jain
  0 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-30  9:57 UTC (permalink / raw)
  To: Wang Shilong; +Cc: dsterba, gene, linux-btrfs



Thanks for the review. Comments accepted. V5 sent out.

Anand


On 01/30/2013 11:27 AM, Wang Shilong wrote:
> Hi,
>> To improve the code reuse its better to have btrfs_list_subvols
>> just return list of subvols witout printing
>>
>> Signed-off-by: Anand Jain <anand.jain@oracle.com>
>> ---
>>   btrfs-list.c     | 28 ++++++++++++++++++----------
>>   btrfs-list.h     |  2 +-
>>   cmds-subvolume.c |  4 ++--
>>   3 files changed, 21 insertions(+), 13 deletions(-)
>>
>> diff --git a/btrfs-list.c b/btrfs-list.c
>> index cb42fbc..b404e1d 100644
>> --- a/btrfs-list.c
>> +++ b/btrfs-list.c
>> @@ -1439,15 +1439,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
>>   	}
>>   }
>>
>> -int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
>> -		       struct btrfs_list_comparer_set *comp_set,
>> -		       int is_tab_result)
>> +int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
>>   {
>> -	struct root_lookup root_lookup;
>> -	struct root_lookup root_sort;
>>   	int ret;
>>
>> -	ret = __list_subvol_search(fd, &root_lookup);
>> +	ret = __list_subvol_search(fd, root_lookup);
>>   	if (ret) {
>>   		fprintf(stderr, "ERROR: can't perform the search - %s\n",
>>   				strerror(errno));
>> @@ -1458,16 +1454,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
>>   	 * now we have an rbtree full of root_info objects, but we need to fill
>>   	 * in their path names within the subvol that is referencing each one.
>>   	 */
>> -	ret = __list_subvol_fill_paths(fd, &root_lookup);
>> -	if (ret < 0)
>> -		return ret;
>> +	ret = __list_subvol_fill_paths(fd, root_lookup);
>> +	return ret;
>> +}
>>
>> +int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>> +		       struct btrfs_list_comparer_set *comp_set,
>> +		       int is_tab_result)
>> +{
>> +	struct root_lookup root_lookup;
>> +	struct root_lookup root_sort;
>> +	int ret;
>> +
>> +	ret = btrfs_list_subvols(fd, &root_lookup);
>> +	if (ret)
>> +		return ret;
>>   	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
>>   				 comp_set, fd);
>>
>>   	print_all_volume_info(&root_sort, is_tab_result);
>>   	__free_all_subvolumn(&root_lookup);
>      Here we forget to free filter and comp_set before..i hope you can add it to your patchset..
>      Maybe you can have patch 13...
>
>      if (filter_set)
>          btrfs_list_free_filter_set(filter_set);
>      if (comp_set)
>          btrfs_list_free_comparer_set(comp_set);
>
>      Thanks,
>      Wang
>> -	return ret;
>> +
>> +	return 0;
>>   }
>>
>>   static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
>> diff --git a/btrfs-list.h b/btrfs-list.h
>> index cde4b3c..71fe0f3 100644
>> --- a/btrfs-list.h
>> +++ b/btrfs-list.h
>> @@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
>>   			      enum btrfs_list_comp_enum comparer,
>>   			      int is_descending);
>>
>> -int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
>> +int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>>   		       struct btrfs_list_comparer_set *comp_set,
>>   			int is_tab_result);
>>   int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
>> diff --git a/cmds-subvolume.c b/cmds-subvolume.c
>> index e3cdb1e..c35dff7 100644
>> --- a/cmds-subvolume.c
>> +++ b/cmds-subvolume.c
>> @@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
>>   					BTRFS_LIST_FILTER_TOPID_EQUAL,
>>   					top_id);
>>
>> -	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
>> +	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
>>   				is_tab_result);
>>   	if (ret)
>>   		return 19;
>> @@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
>>   	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
>>   				default_id);
>>
>> -	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
>> +	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
>>   	if (ret)
>>   		return 19;
>>   	return 0;
>
> --
> 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-info.html
>
--
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] 131+ messages in thread

* Re: [PATCH 10/12] Btrfs-progs: add show subcommand to subvol cli
  2013-01-29  6:48     ` [PATCH 10/12] Btrfs-progs: add show subcommand to subvol cli Anand Jain
@ 2013-01-30 10:32       ` Wang Shilong
  2013-01-31  3:13         ` Anand Jain
  0 siblings, 1 reply; 131+ messages in thread
From: Wang Shilong @ 2013-01-30 10:32 UTC (permalink / raw)
  To: Anand Jain; +Cc: dsterba, gene, linux-btrfs

Hi,
> This adds show sub-command to the btrfs subvol cli
> to display detailed inforamtion of the given subvol
> or snapshot.
>
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
>  btrfs-list.c     |  25 +++++++--
>  btrfs-list.h     |   3 +-
>  cmds-subvolume.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  man/btrfs.8.in   |   6 +++
>  4 files changed, 182 insertions(+), 7 deletions(-)
>
> diff --git a/btrfs-list.c b/btrfs-list.c
> index 656de10..1915ece 100644
> --- a/btrfs-list.c
> +++ b/btrfs-list.c
> @@ -1335,6 +1335,22 @@ static void print_subvolume_column(struct root_info *subv,
>  	}
>  }
>  
> +static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
> +{
> +	int i;
> +
> +	for (i = 0; i < BTRFS_LIST_ALL; i++) {
> +		if (!btrfs_list_columns[i].need_print)
> +			continue;
> +
> +		if (raw_prefix)
> +			printf("%s",raw_prefix);
> +
> +		print_subvolume_column(subv, i);
> +	}
> +	printf("\n");
> +}
> +
>  static void print_single_volume_info_table(struct root_info *subv)
>  {
>  	int i;
> @@ -1401,7 +1417,7 @@ static void print_all_volume_info_tab_head()
>  }
>  
>  static void print_all_volume_info(struct root_lookup *sorted_tree,
> -				  int layout)
> +				  int layout, char *raw_prefix)
>  {
>  	struct rb_node *n;
>  	struct root_info *entry;
> @@ -1419,6 +1435,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
>  		case BTRFS_LIST_LAYOUT_TABLE:
>  			print_single_volume_info_table(entry);
>  			break;
> +		case BTRFS_LIST_LAYOUT_RAW:
> +			print_single_volume_info_raw(entry, raw_prefix);
> +			break;
>  		}
>  		n = rb_next(n);
>  	}
> @@ -1445,7 +1464,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
>  
>  int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  		       struct btrfs_list_comparer_set *comp_set,
> -		       int layout)
> +		       int layout, char *raw_prefix)
>  {
>  	struct root_lookup root_lookup;
>  	struct root_lookup root_sort;
> @@ -1457,7 +1476,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
>  				 comp_set, fd);
>  
> -	print_all_volume_info(&root_sort, layout);
> +	print_all_volume_info(&root_sort, layout, raw_prefix);
>  	__free_all_subvolumn(&root_lookup);
>  
>  	return 0;
> diff --git a/btrfs-list.h b/btrfs-list.h
> index 5b60068..09d35f7 100644
> --- a/btrfs-list.h
> +++ b/btrfs-list.h
> @@ -20,6 +20,7 @@
>  
>  #define BTRFS_LIST_LAYOUT_DEFAULT	0
>  #define BTRFS_LIST_LAYOUT_TABLE	1
> +#define BTRFS_LIST_LAYOUT_RAW		2
>  
>  /*
>   * one of these for each root we find.
> @@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
>  
>  int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
>  		       struct btrfs_list_comparer_set *comp_set,
> -			int is_tab_result);
> +			int layout, char *raw_prefix);
>  int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
>  int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
>  char *btrfs_list_path_for_root(int fd, u64 root);
> diff --git a/cmds-subvolume.c b/cmds-subvolume.c
> index bb9629f..6a14c4c 100644
> --- a/cmds-subvolume.c
> +++ b/cmds-subvolume.c
> @@ -24,6 +24,7 @@
>  #include <libgen.h>
>  #include <limits.h>
>  #include <getopt.h>
> +#include <uuid/uuid.h>
>  
>  #include "kerncompat.h"
>  #include "ioctl.h"
> @@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
>  
>  	if (is_tab_result)
>  		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
> -				BTRFS_LIST_LAYOUT_TABLE);
> +				BTRFS_LIST_LAYOUT_TABLE, NULL);
>  	else
>  		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
> -				BTRFS_LIST_LAYOUT_DEFAULT);
> +				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
>  	if (ret)
>  		return 19;
>  	return 0;
> @@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
>  	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
>  
>  	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
> -		BTRFS_LIST_LAYOUT_DEFAULT);
> +		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
>  	if (ret)
>  		return 19;
>  	return 0;
> @@ -721,6 +722,153 @@ static int cmd_find_new(int argc, char **argv)
>  	return 0;
>  }
>  
> +static const char * const cmd_subvol_show_usage[] = {
> +	"btrfs subvolume show <subvol-path>",
> +	"Show more information of the subvolume",
> +	NULL
> +};
> +
> +static int cmd_subvol_show(int argc, char **argv)
> +{
> +	struct root_info get_ri;
> +	struct btrfs_list_filter_set *filter_set;
> +	char tstr[256];
> +	char uuidparse[37];
> +	char *fullpath = NULL, *svpath = NULL, *mnt = NULL;
> +	char raw_prefix[] = "\t\t\t\t";
> +	u64 sv_id, mntid;
> +	int fd = -1, mntfd = -1;
> +	int ret = -1;
> +
> +	if (check_argc_exact(argc, 2))
> +		usage(cmd_subvol_show_usage);
> +
> +	fullpath = realpath(argv[1], 0);
> +	if (!fullpath) {
> +		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
> +			argv[1], strerror(errno));
> +		goto out;
> +	}
> +
> +	ret = test_issubvolume(fullpath);
> +	if (ret < 0) {
> +		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
> +		goto out;
> +	}
> +	if (!ret) {
> +		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	ret = find_mount_root(fullpath, &mnt);
> +	if (ret < 0) {
> +		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
> +				"%s\n", fullpath, strerror(-ret));
> +		goto out;
> +	}
> +	ret = -1;
> +	svpath = get_subvol_name(mnt, fullpath);
> +
> +	fd = open_file_or_dir(fullpath);
> +	if (fd < 0) {
> +		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
> +		goto out;
> +	}
> +
> +	sv_id = btrfs_list_get_path_rootid(fd);
> +	if (sv_id < 0) {
> +		fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
> +			fullpath);
> +		goto out;
> +	}
> +
> +	mntfd = open_file_or_dir(mnt);
> +	if (mntfd < 0) {
> +		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
> +		goto out;
> +	}
> +
> +	mntid = btrfs_list_get_path_rootid(mntfd);
> +	if (mntid < 0) {
> +		fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
> +		goto out;
> +	}
> +
> +	if (sv_id == BTRFS_FS_TREE_OBJECTID) {
> +		printf("%s is btrfs root\n", fullpath);
> +		goto out;
> +	}
> +
> +	memset(&get_ri, 0, sizeof(get_ri));
> +	get_ri.root_id = sv_id;
> +
> +	if (btrfs_get_subvol(mntfd, &get_ri)) {
> +		fprintf(stderr, "ERROR: can't find '%s'\n",
> +			svpath);
> +		goto out;
> +	}
> +
> +	ret = 0;
> +	/* print the info */
    I think it will be better if you can move the following
    printing to a function..it will make the code more clear and
    readable..

    Thanks,
    Wang
> +	printf("%s\n", fullpath);
> +	printf("\tName: \t\t\t%s\n", get_ri.name);
> +
> +	if (uuid_is_null(get_ri.uuid))
> +		strcpy(uuidparse, "-");
> +	else
> +		uuid_unparse(get_ri.uuid, uuidparse);
> +	printf("\tuuid: \t\t\t%s\n", uuidparse);
> +
> +	if (uuid_is_null(get_ri.puuid))
> +		strcpy(uuidparse, "-");
> +	else
> +		uuid_unparse(get_ri.puuid, uuidparse);
> +	printf("\tParent uuid: \t\t%s\n", uuidparse);
> +
> +	if (get_ri.otime)
> +		strftime(tstr, 256, "%Y-%m-%d %X",
> +			 localtime(&get_ri.otime));
> +	else
> +		strcpy(tstr, "-");
> +	printf("\tCreation time: \t\t%s\n", tstr);
> +
> +	printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
> +	printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
> +	printf("\tGen at creation: \t%llu\n", get_ri.ogen);
> +	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
> +	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
> +
> +	/* print the snapshots of the given subvol if any*/
> +	printf("\tSnapshot(s):\n");
> +	filter_set = btrfs_list_alloc_filter_set();
> +	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
> +				get_ri.uuid);
> +	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
> +	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
> +			raw_prefix);
> +
> +	/* clean up */
> +	if (get_ri.path)
> +		free(get_ri.path);
> +	if (get_ri.name)
> +		free(get_ri.name);
> +	if (get_ri.full_path)
> +		free(get_ri.full_path);
> +
> +out:
> +	if (mntfd >= 0)
> +		close(mntfd);
> +	if (fd >= 0)
> +		close(fd);
> +	if (mnt)
> +		free(mnt);
> +	if (fullpath)
> +		free(fullpath);
> +
> +	return ret;
> +}
> +
>  const struct cmd_group subvolume_cmd_group = {
>  	subvolume_cmd_group_usage, NULL, {
>  		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
> @@ -732,6 +880,7 @@ const struct cmd_group subvolume_cmd_group = {
>  		{ "set-default", cmd_subvol_set_default,
>  			cmd_subvol_set_default_usage, NULL, 0 },
>  		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
> +		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
>  		{ 0, 0, 0, 0, 0 }
>  	}
>  };
> diff --git a/man/btrfs.8.in b/man/btrfs.8.in
> index d20e332..0008a06 100644
> --- a/man/btrfs.8.in
> +++ b/man/btrfs.8.in
> @@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
>  .PP
>  \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
>  .PP
> +\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
> +.PP
>  \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
>  [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
>  [<\fIfile\fR>|<\fIdir\fR>...]
> @@ -158,6 +160,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
>  is similar to \fBsubvolume list\fR command.
>  .TP
>  
> +\fBsubvolume show\fR\fI <path>\fR
> +Show information of a given subvolume in the \fI<path>\fR.
> +.TP
> +
>  \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
>  [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
>  


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

* Re: [PATCH 10/12] Btrfs-progs: add show subcommand to subvol cli
  2013-01-30 10:32       ` Wang Shilong
@ 2013-01-31  3:13         ` Anand Jain
  0 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-01-31  3:13 UTC (permalink / raw)
  To: Wang Shilong; +Cc: dsterba, gene, linux-btrfs


Wang,

>> +	ret = 0;
>> +	/* print the info */
>      I think it will be better if you can move the following
>      printing to a function..it will make the code more clear and
>      readable..

  Thanks for looking into this. However IMO there is no need
  "as of now".  This can be taken when there is more reasonable
  need. I hope you would agree with me.

-Anand

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

* [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli
  2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
                     ` (26 preceding siblings ...)
  2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
@ 2013-02-01  7:56   ` Anand Jain
  2013-02-01  7:56     ` [PATCH 01/13] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
                       ` (12 more replies)
  27 siblings, 13 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

David,

 Please find this v6 show patch-set for your integration-20130130 branch.

v5->v6:
	added
	[PATCH 13/13] Btrfs-progs: add subvol flags to print

Anand Jain (12):
  Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  Btrfs-progs: add parent uuid for snapshots
  Btrfs-progs: move struct root_info to btrfs-list.h
  Btrfs-progs: add function btrfs_get_subvol to get root_info of a
    subvol
  Btrfs-progs: add method to filter snapshots by parent uuid
  Btrfs-progs: put find_mount_root() in commands.h
  Btrfs-progs: make printing subvol extensible to newer layouts
  Btrfs-progs: make get_subvol_name non cmds-send specific
  Btrfs-progs: add show subcommand to subvol cli
  Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root
    ret changes
  Btrfs-progs: Fix a small memory leak in managing the btrfs list filter
  Btrfs-progs: add subvol flags to print

Wang Shilong (1):
  Btrfs-progs: filter the deleted subvolumes when listing snapshots

 btrfs-list.c     | 239 +++++++++++++++++++++++++++++++++++-------------------
 btrfs-list.h     |  58 +++++++++++++-
 cmds-send.c      |  12 +--
 cmds-subvolume.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 commands.h       |   4 +
 man/btrfs.8.in   |   6 ++
 6 files changed, 448 insertions(+), 111 deletions(-)

-- 
1.8.1.227.g44fe835


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

* [PATCH 01/13] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 02/13] Btrfs-progs: add parent uuid for snapshots Anand Jain
                       ` (11 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

To improve the code reuse its better to have btrfs_list_subvols
just return list of subvols witout printing

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 28 ++++++++++++++++++----------
 btrfs-list.h     |  2 +-
 cmds-subvolume.c |  4 ++--
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index e09ee2d..ab42a33 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1440,15 +1440,11 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 	}
 }
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
-		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 {
-	struct root_lookup root_lookup;
-	struct root_lookup root_sort;
 	int ret;
 
-	ret = __list_subvol_search(fd, &root_lookup);
+	ret = __list_subvol_search(fd, root_lookup);
 	if (ret) {
 		fprintf(stderr, "ERROR: can't perform the search - %s\n",
 				strerror(errno));
@@ -1459,16 +1455,28 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
 	 * now we have an rbtree full of root_info objects, but we need to fill
 	 * in their path names within the subvol that is referencing each one.
 	 */
-	ret = __list_subvol_fill_paths(fd, &root_lookup);
-	if (ret < 0)
-		return ret;
+	ret = __list_subvol_fill_paths(fd, root_lookup);
+	return ret;
+}
 
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
+		       struct btrfs_list_comparer_set *comp_set,
+		       int is_tab_result)
+{
+	struct root_lookup root_lookup;
+	struct root_lookup root_sort;
+	int ret;
+
+	ret = btrfs_list_subvols(fd, &root_lookup);
+	if (ret)
+		return ret;
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
 	print_all_volume_info(&root_sort, is_tab_result);
 	__free_all_subvolumn(&root_lookup);
-	return ret;
+
+	return 0;
 }
 
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
diff --git a/btrfs-list.h b/btrfs-list.h
index cde4b3c..71fe0f3 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -98,7 +98,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 			      enum btrfs_list_comp_enum comparer,
 			      int is_descending);
 
-int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set,
+int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
 			int is_tab_result);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index e3cdb1e..c35dff7 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -406,7 +406,7 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, comparer_set,
+	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				is_tab_result);
 	if (ret)
 		return 19;
@@ -613,7 +613,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols(fd, filter_set, NULL, 0);
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 02/13] Btrfs-progs: add parent uuid for snapshots
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
  2013-02-01  7:56     ` [PATCH 01/13] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 03/13] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
                       ` (10 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 34 ++++++++++++++++++++++++++++------
 btrfs-list.h     |  1 +
 cmds-subvolume.c |  6 +++++-
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index ab42a33..03a0d02 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -80,6 +80,7 @@ struct root_info {
 	time_t otime;
 
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	/* path from the subvol we live in to this root, including the
 	 * root's name.  This is null until we do the extra lookup ioctl.
@@ -128,6 +129,11 @@ struct {
 		.need_print	= 0,
 	},
 	{
+		.name		= "parent_uuid",
+		.column_name	= "Parent UUID",
+		.need_print	= 0,
+	},
+	{
 		.name		= "uuid",
 		.column_name	= "UUID",
 		.need_print	= 0,
@@ -435,7 +441,7 @@ static struct root_info *root_tree_search(struct root_lookup *root_tree,
 static int update_root(struct root_lookup *root_lookup,
 		       u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		       u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		       time_t ot, void *uuid)
+		       time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 
@@ -472,6 +478,8 @@ static int update_root(struct root_lookup *root_lookup,
 		ri->otime = ot;
 	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
 
 	return 0;
 }
@@ -489,17 +497,18 @@ static int update_root(struct root_lookup *root_lookup,
  * gen: the current generation of the root
  * ot: the original time(create time) of the root
  * uuid: uuid of the root
+ * puuid: uuid of the root parent if any
  */
 static int add_root(struct root_lookup *root_lookup,
 		    u64 root_id, u64 ref_tree, u64 root_offset, u64 flags,
 		    u64 dir_id, char *name, int name_len, u64 ogen, u64 gen,
-		    time_t ot, void *uuid)
+		    time_t ot, void *uuid, void *puuid)
 {
 	struct root_info *ri;
 	int ret;
 
 	ret = update_root(root_lookup, root_id, ref_tree, root_offset, flags,
-			  dir_id, name, name_len, ogen, gen, ot, uuid);
+			  dir_id, name, name_len, ogen, gen, ot, uuid, puuid);
 	if (!ret)
 		return 0;
 
@@ -537,9 +546,12 @@ static int add_root(struct root_lookup *root_lookup,
 	if (ot)
 		ri->otime = ot;
 
-	if (uuid) 
+	if (uuid)
 		memcpy(&ri->uuid, uuid, BTRFS_UUID_SIZE);
 
+	if (puuid)
+		memcpy(&ri->puuid, puuid, BTRFS_UUID_SIZE);
+
 	ret = root_tree_insert(root_lookup, ri);
 	if (ret) {
 		printf("failed to insert tree %llu\n", (unsigned long long)root_id);
@@ -1022,6 +1034,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 	int i;
 	time_t t;
 	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
 
 	root_lookup_init(root_lookup);
 	memset(&args, 0, sizeof(args));
@@ -1074,7 +1087,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 
 				add_root(root_lookup, sh.objectid, sh.offset,
 					 0, 0, dir_id, name, name_len, 0, 0, 0,
-					 NULL);
+					 NULL, NULL);
 			} else if (sh.type == BTRFS_ROOT_ITEM_KEY) {
 				ri = (struct btrfs_root_item *)(args.buf + off);
 				gen = btrfs_root_generation(ri);
@@ -1084,15 +1097,17 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup)
 					t = ri->otime.sec;
 					ogen = btrfs_root_otransid(ri);
 					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
+					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
 				} else {
 					t = 0;
 					ogen = 0;
 					memset(uuid, 0, BTRFS_UUID_SIZE);
+					memset(puuid, 0, BTRFS_UUID_SIZE);
 				}
 
 				add_root(root_lookup, sh.objectid, 0,
 					 sh.offset, flags, 0, NULL, 0, ogen,
-					 gen, t, uuid);
+					 gen, t, uuid, puuid);
 			}
 
 			off += sh.len;
@@ -1346,6 +1361,13 @@ static void print_subvolume_column(struct root_info *subv,
 			uuid_unparse(subv->uuid, uuidparse);
 		printf("%s", uuidparse);
 		break;
+	case BTRFS_LIST_PUUID:
+		if (uuid_is_null(subv->puuid))
+			strcpy(uuidparse, "-");
+		else
+			uuid_unparse(subv->puuid, uuidparse);
+		printf("%s", uuidparse);
+		break;
 	case BTRFS_LIST_PATH:
 		BUG_ON(!subv->full_path);
 		printf("%s", subv->full_path);
diff --git a/btrfs-list.h b/btrfs-list.h
index 71fe0f3..855e73d 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -53,6 +53,7 @@ enum btrfs_list_column_enum {
 	BTRFS_LIST_PARENT,
 	BTRFS_LIST_TOP_LEVEL,
 	BTRFS_LIST_OTIME,
+	BTRFS_LIST_PUUID,
 	BTRFS_LIST_UUID,
 	BTRFS_LIST_PATH,
 	BTRFS_LIST_ALL,
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index c35dff7..a1e6893 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -280,6 +280,7 @@ static const char * const cmd_subvol_list_usage[] = {
 	"-p           print parent ID",
 	"-a           print all the subvolumes in the filesystem.",
 	"-u           print the uuid of subvolumes (and snapshots)",
+	"-q           print the parent uuid of the snapshots",
 	"-t           print the result as a table",
 	"-s           list snapshots only in the filesystem",
 	"-r           list readonly subvolumes (including snapshots)",
@@ -319,7 +320,7 @@ static int cmd_subvol_list(int argc, char **argv)
 	optind = 1;
 	while(1) {
 		c = getopt_long(argc, argv,
-				    "apsurg:c:t", long_options, NULL);
+				    "apsuqrg:c:t", long_options, NULL);
 		if (c < 0)
 			break;
 
@@ -343,6 +344,9 @@ static int cmd_subvol_list(int argc, char **argv)
 		case 'u':
 			btrfs_list_setup_print_column(BTRFS_LIST_UUID);
 			break;
+		case 'q':
+			btrfs_list_setup_print_column(BTRFS_LIST_PUUID);
+			break;
 		case 'r':
 			flags |= BTRFS_ROOT_SUBVOL_RDONLY;
 			break;
-- 
1.8.1.227.g44fe835


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

* [PATCH 03/13] Btrfs-progs: move struct root_info to btrfs-list.h
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
  2013-02-01  7:56     ` [PATCH 01/13] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
  2013-02-01  7:56     ` [PATCH 02/13] Btrfs-progs: add parent uuid for snapshots Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 04/13] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
                       ` (9 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

As we would add more ways to list and manage the subvols
and snapshots, its better if we have struct root_info
defined in the header file.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 47 -----------------------------------------------
 btrfs-list.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 03a0d02..f41c008 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -46,53 +46,6 @@ struct root_lookup {
 	struct rb_root root;
 };
 
-/*
- * one of these for each root we find.
- */
-struct root_info {
-	struct rb_node rb_node;
-	struct rb_node sort_node;
-
-	/* this root's id */
-	u64 root_id;
-
-	/* equal the offset of the root's key */
-	u64 root_offset;
-
-	/* flags of the root */
-	u64 flags;
-
-	/* the id of the root that references this one */
-	u64 ref_tree;
-
-	/* the dir id we're in from ref_tree */
-	u64 dir_id;
-
-	u64 top_id;
-
-	/* generation when the root is created or last updated */
-	u64 gen;
-
-	/* creation generation of this root in sec*/
-	u64 ogen;
-
-	/* creation time of this root in sec*/
-	time_t otime;
-
-	u8 uuid[BTRFS_UUID_SIZE];
-	u8 puuid[BTRFS_UUID_SIZE];
-
-	/* path from the subvol we live in to this root, including the
-	 * root's name.  This is null until we do the extra lookup ioctl.
-	 */
-	char *path;
-
-	/* the name of this root in the directory it lives in */
-	char *name;
-
-	char *full_path;
-};
-
 struct {
 	char	*name;
 	char	*column_name;
diff --git a/btrfs-list.h b/btrfs-list.h
index 855e73d..3b7b680 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,7 +18,52 @@
 
 #include "kerncompat.h"
 
-struct root_info;
+/*
+ * one of these for each root we find.
+ */
+struct root_info {
+	struct rb_node rb_node;
+	struct rb_node sort_node;
+
+	/* this root's id */
+	u64 root_id;
+
+	/* equal the offset of the root's key */
+	u64 root_offset;
+
+	/* flags of the root */
+	u64 flags;
+
+	/* the id of the root that references this one */
+	u64 ref_tree;
+
+	/* the dir id we're in from ref_tree */
+	u64 dir_id;
+
+	u64 top_id;
+
+	/* generation when the root is created or last updated */
+	u64 gen;
+
+	/* creation generation of this root in sec*/
+	u64 ogen;
+
+	/* creation time of this root in sec*/
+	time_t otime;
+
+	u8 uuid[BTRFS_UUID_SIZE];
+	u8 puuid[BTRFS_UUID_SIZE];
+
+	/* path from the subvol we live in to this root, including the
+	 * root's name.  This is null until we do the extra lookup ioctl.
+	 */
+	char *path;
+
+	/* the name of this root in the directory it lives in */
+	char *name;
+
+	char *full_path;
+};
 
 typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
 typedef int (*btrfs_list_comp_func)(struct root_info *, struct root_info *,
-- 
1.8.1.227.g44fe835


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

* [PATCH 04/13] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (2 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 03/13] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 05/13] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
                       ` (8 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

We need a function which can get the root_info of a given
subvol. This is in preparation to add support for the show
sub-cli.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 38 ++++++++++++++++++++++++++++++++++++++
 btrfs-list.h |  1 +
 2 files changed, 39 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index f41c008..0e4b3eb 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1454,6 +1454,44 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	return 0;
 }
 
+int btrfs_get_subvol(int fd, struct root_info *the_ri)
+{
+	int ret = -1;
+	struct root_lookup rl;
+	struct rb_node *rbn;
+	struct root_info *ri;
+	u64 root_id = btrfs_list_get_path_rootid(fd);
+
+	if (btrfs_list_subvols(fd, &rl))
+		return 1;
+
+	rbn = rb_first(&rl.root);
+	while(rbn) {
+		ri = rb_entry(rbn, struct root_info, rb_node);
+		resolve_root(&rl, ri, root_id);
+		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
+			memcpy(the_ri, ri, offsetof(struct root_info, path));
+			if (ri->path)
+				the_ri->path = strdup(ri->path);
+			else
+				the_ri->path = NULL;
+			if (ri->name)
+				the_ri->name = strdup(ri->name);
+			else
+				the_ri->name = NULL;
+			if (ri->full_path)
+				the_ri->full_path = strdup(ri->full_path);
+			else
+				the_ri->name = NULL;
+			ret = 0;
+			break;
+		}
+		rbn = rb_next(rbn);
+	}
+	__free_all_subvolumn(&rl);
+	return ret;
+}
+
 static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 			    struct btrfs_file_extent_item *item,
 			    u64 found_gen, u64 *cache_dirid,
diff --git a/btrfs-list.h b/btrfs-list.h
index 3b7b680..580d4d1 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -151,3 +151,4 @@ int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
 u64 btrfs_list_get_path_rootid(int fd);
+int btrfs_get_subvol(int fd, struct root_info *the_ri);
-- 
1.8.1.227.g44fe835


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

* [PATCH 05/13] Btrfs-progs: add method to filter snapshots by parent uuid
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (3 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 04/13] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 06/13] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
                       ` (7 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 6 ++++++
 btrfs-list.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/btrfs-list.c b/btrfs-list.c
index 0e4b3eb..93d167e 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1143,6 +1143,11 @@ static int filter_topid_equal(struct root_info *ri, u64 data)
 	return ri->top_id == data;
 }
 
+static int filter_by_parent(struct root_info *ri, u64 data)
+{
+	return !uuid_compare(ri->puuid, (u8 *)data);
+}
+
 static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_ROOTID]		= filter_by_rootid,
 	[BTRFS_LIST_FILTER_SNAPSHOT_ONLY]	= filter_snapshot,
@@ -1154,6 +1159,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
 	[BTRFS_LIST_FILTER_CGEN_LESS]		= filter_cgen_less,
 	[BTRFS_LIST_FILTER_CGEN_EQUAL]          = filter_cgen_equal,
 	[BTRFS_LIST_FILTER_TOPID_EQUAL]		= filter_topid_equal,
+	[BTRFS_LIST_FILTER_BY_PARENT]		= filter_by_parent,
 };
 
 struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
diff --git a/btrfs-list.h b/btrfs-list.h
index 580d4d1..cde7a3f 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -117,6 +117,7 @@ enum btrfs_list_filter_enum {
 	BTRFS_LIST_FILTER_CGEN_LESS,
 	BTRFS_LIST_FILTER_CGEN_MORE,
 	BTRFS_LIST_FILTER_TOPID_EQUAL,
+	BTRFS_LIST_FILTER_BY_PARENT,
 	BTRFS_LIST_FILTER_MAX,
 };
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 06/13] Btrfs-progs: put find_mount_root() in commands.h
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (4 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 05/13] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 07/13] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
                       ` (6 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

A useful function need to define it in a header file.

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

diff --git a/commands.h b/commands.h
index 61d74d7..1dd6180 100644
--- a/commands.h
+++ b/commands.h
@@ -105,3 +105,6 @@ int cmd_replace(int argc, char **argv);
 
 /* subvolume exported functions */
 int test_issubvolume(char *path);
+
+/* send.c */
+int find_mount_root(const char *path, char **mount_root);
-- 
1.8.1.227.g44fe835


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

* [PATCH 07/13] Btrfs-progs: make printing subvol extensible to newer layouts
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (5 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 06/13] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 08/13] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
                       ` (5 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Currently you can print subvol in a list or table format.
This patch will provide a way to extend this to other formats
like the upcoming raw format.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     | 26 +++++++++++++++-----------
 btrfs-list.h     |  3 +++
 cmds-subvolume.c | 23 ++++++++++++++++++++---
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 93d167e..20b84ab 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -54,12 +54,12 @@ struct {
 	{
 		.name		= "ID",
 		.column_name	= "ID",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "gen",
 		.column_name	= "Gen",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "cgen",
@@ -74,7 +74,7 @@ struct {
 	{
 		.name		= "top level",
 		.column_name	= "Top Level",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= "otime",
@@ -94,7 +94,7 @@ struct {
 	{
 		.name		= "path",
 		.column_name	= "Path",
-		.need_print	= 1,
+		.need_print	= 0,
 	},
 	{
 		.name		= NULL,
@@ -1402,21 +1402,25 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int is_tab_result)
+				  int layout)
 {
 	struct rb_node *n;
 	struct root_info *entry;
 
-	if (is_tab_result)
+	if (layout == BTRFS_LIST_LAYOUT_TABLE)
 		print_all_volume_info_tab_head();
 
 	n = rb_first(&sorted_tree->root);
 	while (n) {
 		entry = rb_entry(n, struct root_info, sort_node);
-		if (is_tab_result)
-			print_single_volume_info_table(entry);
-		else
+		switch (layout) {
+		case BTRFS_LIST_LAYOUT_DEFAULT:
 			print_single_volume_info_default(entry);
+			break;
+		case BTRFS_LIST_LAYOUT_TABLE:
+			print_single_volume_info_table(entry);
+			break;
+		}
 		n = rb_next(n);
 	}
 }
@@ -1442,7 +1446,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int is_tab_result)
+		       int layout)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1454,7 +1458,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, is_tab_result);
+	print_all_volume_info(&root_sort, layout);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index cde7a3f..5b60068 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -18,6 +18,9 @@
 
 #include "kerncompat.h"
 
+#define BTRFS_LIST_LAYOUT_DEFAULT	0
+#define BTRFS_LIST_LAYOUT_TABLE	1
+
 /*
  * one of these for each root we find.
  */
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index a1e6893..bb9629f 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -410,8 +410,18 @@ static int cmd_subvol_list(int argc, char **argv)
 					BTRFS_LIST_FILTER_TOPID_EQUAL,
 					top_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				is_tab_result);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	if (is_tab_result)
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_TABLE);
+	else
+		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
+				BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
@@ -617,7 +627,14 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
 				default_id);
 
-	ret = btrfs_list_subvols_print(fd, filter_set, NULL, 0);
+	/* by default we shall print the following columns*/
+	btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
+	btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
+	btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+
+	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
+		BTRFS_LIST_LAYOUT_DEFAULT);
 	if (ret)
 		return 19;
 	return 0;
-- 
1.8.1.227.g44fe835


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

* [PATCH 08/13] Btrfs-progs: make get_subvol_name non cmds-send specific
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (6 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 07/13] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 09/13] Btrfs-progs: add show subcommand to subvol cli Anand Jain
                       ` (4 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

get_subvol_name can be used other than the just with in cmds-send.c
so this patch will make it possible with out changing the original
intentions.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-send.c | 12 ++++++------
 commands.h  |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/cmds-send.c b/cmds-send.c
index 4a8478d..0ec63a0 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -334,12 +334,12 @@ out:
 	return ret;
 }
 
-static const char *get_subvol_name(struct btrfs_send *s, const char *full_path)
+char *get_subvol_name(char *mnt, char *full_path)
 {
-	int len = strlen(s->root_path);
+	int len = strlen(mnt);
 	if (!len)
 		return full_path;
-	if (s->root_path[len - 1] != '/')
+	if (mnt[len - 1] != '/')
 		len += 1;
 
 	return full_path + len;
@@ -454,7 +454,7 @@ int cmd_send_start(int argc, char **argv)
 			if (ret < 0)
 				goto out;
 
-			ret = get_root_id(&send, get_subvol_name(&send, subvol),
+			ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 					&root_id);
 			if (ret < 0) {
 				fprintf(stderr, "ERROR: could not resolve "
@@ -524,7 +524,7 @@ int cmd_send_start(int argc, char **argv)
 
 	if (snapshot_parent != NULL) {
 		ret = get_root_id(&send,
-				get_subvol_name(&send, snapshot_parent),
+				get_subvol_name(send.root_path, snapshot_parent),
 				&parent_root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
@@ -583,7 +583,7 @@ int cmd_send_start(int argc, char **argv)
 			goto out;
 		}
 
-		ret = get_root_id(&send, get_subvol_name(&send, subvol),
+		ret = get_root_id(&send, get_subvol_name(send.root_path, subvol),
 				&root_id);
 		if (ret < 0) {
 			fprintf(stderr, "ERROR: could not resolve root_id "
diff --git a/commands.h b/commands.h
index 1dd6180..ce0f3b9 100644
--- a/commands.h
+++ b/commands.h
@@ -108,3 +108,4 @@ int test_issubvolume(char *path);
 
 /* send.c */
 int find_mount_root(const char *path, char **mount_root);
+char *get_subvol_name(char *mnt, char *full_path);
-- 
1.8.1.227.g44fe835


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

* [PATCH 09/13] Btrfs-progs: add show subcommand to subvol cli
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (7 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 08/13] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 10/13] Btrfs-progs: filter the deleted subvolumes when listing snapshots Anand Jain
                       ` (3 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

This adds show sub-command to the btrfs subvol cli
to display detailed inforamtion of the given subvol
or snapshot.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     |  25 +++++++--
 btrfs-list.h     |   3 +-
 cmds-subvolume.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 man/btrfs.8.in   |   6 +++
 4 files changed, 182 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 20b84ab..545aa15 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1336,6 +1336,22 @@ static void print_subvolume_column(struct root_info *subv,
 	}
 }
 
+static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_LIST_ALL; i++) {
+		if (!btrfs_list_columns[i].need_print)
+			continue;
+
+		if (raw_prefix)
+			printf("%s",raw_prefix);
+
+		print_subvolume_column(subv, i);
+	}
+	printf("\n");
+}
+
 static void print_single_volume_info_table(struct root_info *subv)
 {
 	int i;
@@ -1402,7 +1418,7 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int layout)
+				  int layout, char *raw_prefix)
 {
 	struct rb_node *n;
 	struct root_info *entry;
@@ -1420,6 +1436,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 		case BTRFS_LIST_LAYOUT_TABLE:
 			print_single_volume_info_table(entry);
 			break;
+		case BTRFS_LIST_LAYOUT_RAW:
+			print_single_volume_info_raw(entry, raw_prefix);
+			break;
 		}
 		n = rb_next(n);
 	}
@@ -1446,7 +1465,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int layout)
+		       int layout, char *raw_prefix)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1458,7 +1477,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, layout);
+	print_all_volume_info(&root_sort, layout, raw_prefix);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index 5b60068..09d35f7 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -20,6 +20,7 @@
 
 #define BTRFS_LIST_LAYOUT_DEFAULT	0
 #define BTRFS_LIST_LAYOUT_TABLE	1
+#define BTRFS_LIST_LAYOUT_RAW		2
 
 /*
  * one of these for each root we find.
@@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-			int is_tab_result);
+			int layout, char *raw_prefix);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index bb9629f..9f1d2a4 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -24,6 +24,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
+#include <uuid/uuid.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
 
 	if (is_tab_result)
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_TABLE);
+				BTRFS_LIST_LAYOUT_TABLE, NULL);
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_DEFAULT);
+				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
-		BTRFS_LIST_LAYOUT_DEFAULT);
+		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -721,6 +722,153 @@ static int cmd_find_new(int argc, char **argv)
 	return 0;
 }
 
+static const char * const cmd_subvol_show_usage[] = {
+	"btrfs subvolume show <subvol-path>",
+	"Show more information of the subvolume",
+	NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+	struct root_info get_ri;
+	struct btrfs_list_filter_set *filter_set;
+	char tstr[256];
+	char uuidparse[37];
+	char *fullpath = NULL, *svpath = NULL, *mnt = NULL;
+	char raw_prefix[] = "\t\t\t\t";
+	u64 sv_id, mntid;
+	int fd = -1, mntfd = -1;
+	int ret = -1;
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_subvol_show_usage);
+
+	fullpath = realpath(argv[1], 0);
+	if (!fullpath) {
+		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
+			argv[1], strerror(errno));
+		goto out;
+	}
+
+	ret = test_issubvolume(fullpath);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
+		goto out;
+	}
+	if (!ret) {
+		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
+		ret = -1;
+		goto out;
+	}
+
+	ret = find_mount_root(fullpath, &mnt);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
+				"%s\n", fullpath, strerror(-ret));
+		goto out;
+	}
+	ret = -1;
+	svpath = get_subvol_name(mnt, fullpath);
+
+	fd = open_file_or_dir(fullpath);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
+		goto out;
+	}
+
+	sv_id = btrfs_list_get_path_rootid(fd);
+	if (sv_id < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
+			fullpath);
+		goto out;
+	}
+
+	mntfd = open_file_or_dir(mnt);
+	if (mntfd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
+		goto out;
+	}
+
+	mntid = btrfs_list_get_path_rootid(mntfd);
+	if (mntid < 0) {
+		fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
+		goto out;
+	}
+
+	if (sv_id == BTRFS_FS_TREE_OBJECTID) {
+		printf("%s is btrfs root\n", fullpath);
+		goto out;
+	}
+
+	memset(&get_ri, 0, sizeof(get_ri));
+	get_ri.root_id = sv_id;
+
+	if (btrfs_get_subvol(mntfd, &get_ri)) {
+		fprintf(stderr, "ERROR: can't find '%s'\n",
+			svpath);
+		goto out;
+	}
+
+	ret = 0;
+	/* print the info */
+	printf("%s\n", fullpath);
+	printf("\tName: \t\t\t%s\n", get_ri.name);
+
+	if (uuid_is_null(get_ri.uuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.uuid, uuidparse);
+	printf("\tuuid: \t\t\t%s\n", uuidparse);
+
+	if (uuid_is_null(get_ri.puuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.puuid, uuidparse);
+	printf("\tParent uuid: \t\t%s\n", uuidparse);
+
+	if (get_ri.otime)
+		strftime(tstr, 256, "%Y-%m-%d %X",
+			 localtime(&get_ri.otime));
+	else
+		strcpy(tstr, "-");
+	printf("\tCreation time: \t\t%s\n", tstr);
+
+	printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
+	printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
+	printf("\tGen at creation: \t%llu\n", get_ri.ogen);
+	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
+	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
+
+	/* print the snapshots of the given subvol if any*/
+	printf("\tSnapshot(s):\n");
+	filter_set = btrfs_list_alloc_filter_set();
+	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
+				(u64)get_ri.uuid);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
+			raw_prefix);
+
+	/* clean up */
+	if (get_ri.path)
+		free(get_ri.path);
+	if (get_ri.name)
+		free(get_ri.name);
+	if (get_ri.full_path)
+		free(get_ri.full_path);
+
+out:
+	if (mntfd >= 0)
+		close(mntfd);
+	if (fd >= 0)
+		close(fd);
+	if (mnt)
+		free(mnt);
+	if (fullpath)
+		free(fullpath);
+
+	return ret;
+}
+
 const struct cmd_group subvolume_cmd_group = {
 	subvolume_cmd_group_usage, NULL, {
 		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -732,6 +880,7 @@ const struct cmd_group subvolume_cmd_group = {
 		{ "set-default", cmd_subvol_set_default,
 			cmd_subvol_set_default_usage, NULL, 0 },
 		{ "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
+		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
 	}
 };
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 5f017f8..c8fdc15 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
 .PP
+\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
 [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
 [<\fIfile\fR>|<\fIdir\fR>...]
@@ -166,6 +168,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
 is similar to \fBsubvolume list\fR command.
 .TP
 
+\fBsubvolume show\fR\fI <path>\fR
+Show information of a given subvolume in the \fI<path>\fR.
+.TP
+
 \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
 [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
 
-- 
1.8.1.227.g44fe835


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

* [PATCH 10/13] Btrfs-progs: filter the deleted subvolumes when listing snapshots
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (8 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 09/13] Btrfs-progs: add show subcommand to subvol cli Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 11/13] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes Anand Jain
                       ` (2 subsequent siblings)
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

From: Wang Shilong <wangsl-fnst@cn.fujistu.com>

btrfs snapshot list command will stop by the deleted subvolumes.

The problem may happen by two ways:
1. a subvolume deletion is not commited, that is ROOT_BACKREF has been deleted,
   but ROOT_ITEM still exists. The command will fail to fill the path of
   the deleted subvolumes because we can not get the parent fs/file tree.
2. a subvolume is possibly deleted when we fill the path, For example,
   Fs tree
     |->subv0
	  |->subv1

   We may fill the path of subv1 firstly, after that, some user deletes subv1
   and subv0, and then we fill the path of subv0. The command will fail to
   fill the path of subv0 because we can not get path of subv0. And the command
   also will fail to make the full path of subv1 because we don't have the path
   of subv0.

Since these subvolumes have been deleted, we should filter them. This patch
fixed the above problem by this way.

For the 1st case, ->ref_tree of the deleted subvolumes are 0.
For the 2nd case, if we found the error number that ioctl() returns is ENOENT,
we will set ->ref_tree to 0.
And when we make the full path of the subvolumes, we will check ->ref_tree of
them and their parent. If someone's ->ref_tree or its parent's ->ref_tree is 0,
we will filter it.

Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 545aa15..69ee3e7 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -564,6 +564,12 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri,
 	while (1) {
 		char *tmp;
 		u64 next;
+		/*
+		* ref_tree = 0 indicates the subvolumes
+		* has been deleted.
+		*/
+		if (!found->ref_tree)
+			return -ENOENT;
 		int add_len = strlen(found->path);
 
 		/* room for / and for null */
@@ -592,6 +598,10 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri,
 			break;
 		}
 
+		/*
+		* if the ref_tree = BTRFS_FS_TREE_OBJECTID,
+		* we are at the top
+		*/
 		if (next == BTRFS_FS_TREE_OBJECTID) {
 			char p[] = "<FS_TREE>";
 			add_len = strlen(p);
@@ -608,14 +618,12 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri,
 		}
 
 		/*
-		 * if the ref_tree wasn't in our tree of roots, we're
-		 * at the top
-		 */
+		* if the ref_tree wasn't in our tree of roots, the
+		* subvolume was deleted.
+		*/
 		found = root_tree_search(rl, next);
-		if (!found) {
-			ri->top_id = next;
-			break;
-		}
+		if (!found)
+			return -ENOENT;
 	}
 
 	ri->full_path = full_path;
@@ -638,6 +646,9 @@ static int lookup_ino_path(int fd, struct root_info *ri)
 	if (ri->path)
 		return 0;
 
+	if (!ri->ref_tree)
+		return -ENOENT;
+
 	memset(&args, 0, sizeof(args));
 	args.treeid = ri->ref_tree;
 	args.objectid = ri->dir_id;
@@ -645,6 +656,10 @@ static int lookup_ino_path(int fd, struct root_info *ri)
 	ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
 	e = errno;
 	if (ret) {
+		if (e == ENOENT) {
+			ri->ref_tree = 0;
+			return -ENOENT;
+		}
 		fprintf(stderr, "ERROR: Failed to lookup path for root %llu - %s\n",
 			(unsigned long long)ri->ref_tree,
 			strerror(e));
@@ -1255,10 +1270,13 @@ static void __filter_and_sort_subvol(struct root_lookup *all_subvols,
 	while (n) {
 		entry = rb_entry(n, struct root_info, rb_node);
 
-		resolve_root(all_subvols, entry, top_id);
+		ret = resolve_root(all_subvols, entry, top_id);
+		if (ret == -ENOENT)
+			goto skip;
 		ret = filter_root(entry, filter_set);
 		if (ret)
 			sort_tree_insert(sort_tree, entry, comp_set);
+skip:
 		n = rb_prev(n);
 	}
 }
@@ -1273,7 +1291,7 @@ static int __list_subvol_fill_paths(int fd, struct root_lookup *root_lookup)
 		int ret;
 		entry = rb_entry(n, struct root_info, rb_node);
 		ret = lookup_ino_path(fd, entry);
-		if(ret < 0)
+		if (ret && ret != -ENOENT)
 			return ret;
 		n = rb_next(n);
 	}
@@ -1721,7 +1739,11 @@ char *btrfs_list_path_for_root(int fd, u64 root)
 		struct root_info *entry;
 
 		entry = rb_entry(n, struct root_info, rb_node);
-		resolve_root(&root_lookup, entry, top_id);
+		ret = resolve_root(&root_lookup, entry, top_id);
+		if (ret == -ENOENT && entry->root_id == root) {
+			ret_path = NULL;
+			break;
+		}
 		if (entry->root_id == root) {
 			ret_path = entry->full_path;
 			entry->full_path = NULL;
-- 
1.8.1.227.g44fe835


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

* [PATCH 11/13] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (9 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 10/13] Btrfs-progs: filter the deleted subvolumes when listing snapshots Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 12/13] Btrfs-progs: Fix a small memory leak in managing the btrfs list filter Anand Jain
  2013-02-01  7:56     ` [PATCH 13/13] Btrfs-progs: add subvol flags to print Anand Jain
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 69ee3e7..eadfba4 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1503,19 +1503,24 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 
 int btrfs_get_subvol(int fd, struct root_info *the_ri)
 {
-	int ret = -1;
+	int ret = 1, rr;
 	struct root_lookup rl;
 	struct rb_node *rbn;
 	struct root_info *ri;
 	u64 root_id = btrfs_list_get_path_rootid(fd);
 
 	if (btrfs_list_subvols(fd, &rl))
-		return 1;
+		return ret;
 
 	rbn = rb_first(&rl.root);
 	while(rbn) {
 		ri = rb_entry(rbn, struct root_info, rb_node);
-		resolve_root(&rl, ri, root_id);
+		rr = resolve_root(&rl, ri, root_id);
+		if (rr == -ENOENT) {
+			ret = -ENOENT;
+			rbn = rb_next(rbn);
+			continue;
+		}
 		if (!comp_entry_with_rootid(the_ri, ri, 0)) {
 			memcpy(the_ri, ri, offsetof(struct root_info, path));
 			if (ri->path)
-- 
1.8.1.227.g44fe835


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

* [PATCH 12/13] Btrfs-progs: Fix a small memory leak in managing the btrfs list filter
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (10 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 11/13] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  2013-02-01  7:56     ` [PATCH 13/13] Btrfs-progs: add subvol flags to print Anand Jain
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-subvolume.c | 57 +++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index 9f1d2a4..5e51a26 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -303,9 +303,9 @@ static int cmd_subvol_list(int argc, char **argv)
 	struct btrfs_list_filter_set *filter_set;
 	struct btrfs_list_comparer_set *comparer_set;
 	u64 flags = 0;
-	int fd;
+	int fd = -1;
 	u64 top_id;
-	int ret;
+	int ret = -1, uerr = 0;
 	int c;
 	char *subvol;
 	int is_tab_result = 0;
@@ -356,8 +356,10 @@ static int cmd_subvol_list(int argc, char **argv)
 			ret = btrfs_list_parse_filter_string(optarg,
 							&filter_set,
 							BTRFS_LIST_FILTER_GEN);
-			if (ret)
-				usage(cmd_subvol_list_usage);
+			if (ret) {
+				uerr = 1;
+				goto out;
+			}
 			break;
 
 		case 'c':
@@ -365,18 +367,23 @@ static int cmd_subvol_list(int argc, char **argv)
 			ret = btrfs_list_parse_filter_string(optarg,
 							&filter_set,
 							BTRFS_LIST_FILTER_CGEN);
-			if (ret)
-				usage(cmd_subvol_list_usage);
+			if (ret) {
+				uerr = 1;
+				goto out;
+			}
 			break;
 		case 'S':
 			ret = btrfs_list_parse_sort_string(optarg,
 							   &comparer_set);
-			if (ret)
-				usage(cmd_subvol_list_usage);
+			if (ret) {
+				uerr = 1;
+				goto out;
+			}
 			break;
 
 		default:
-			usage(cmd_subvol_list_usage);
+			uerr = 1;
+			goto out;
 		}
 	}
 
@@ -384,25 +391,29 @@ static int cmd_subvol_list(int argc, char **argv)
 		btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_FLAGS,
 					flags);
 
-	if (check_argc_exact(argc - optind, 1))
-		usage(cmd_subvol_list_usage);
+	if (check_argc_exact(argc - optind, 1)) {
+		uerr = 1;
+		goto out;
+	}
 
 	subvol = argv[optind];
 
 	ret = test_issubvolume(subvol);
 	if (ret < 0) {
 		fprintf(stderr, "ERROR: error accessing '%s'\n", subvol);
-		return 12;
+		goto out;
 	}
 	if (!ret) {
 		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", subvol);
-		return 13;
+		ret = -1;
+		goto out;
 	}
 
 	fd = open_file_or_dir(subvol);
 	if (fd < 0) {
+		ret = -1;
 		fprintf(stderr, "ERROR: can't access '%s'\n", subvol);
-		return 12;
+		goto out;
 	}
 
 	top_id = btrfs_list_get_path_rootid(fd);
@@ -423,9 +434,16 @@ static int cmd_subvol_list(int argc, char **argv)
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
 				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
-	if (ret)
-		return 19;
-	return 0;
+
+out:
+	if (filter_set)
+		btrfs_list_free_filter_set(filter_set);
+	if (comparer_set)
+		btrfs_list_free_comparer_set(comparer_set);
+	if (uerr)
+		usage(cmd_subvol_list_usage);
+
+	return ret;
 }
 
 static const char * const cmd_snapshot_usage[] = {
@@ -636,6 +654,9 @@ static int cmd_subvol_get_default(int argc, char **argv)
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
 		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
+
+	if (filter_set)
+		btrfs_list_free_filter_set(filter_set);
 	if (ret)
 		return 19;
 	return 0;
@@ -855,6 +876,8 @@ static int cmd_subvol_show(int argc, char **argv)
 		free(get_ri.name);
 	if (get_ri.full_path)
 		free(get_ri.full_path);
+	if (filter_set)
+		btrfs_list_free_filter_set(filter_set);
 
 out:
 	if (mntfd >= 0)
-- 
1.8.1.227.g44fe835


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

* [PATCH 13/13] Btrfs-progs: add subvol flags to print
  2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
                       ` (11 preceding siblings ...)
  2013-02-01  7:56     ` [PATCH 12/13] Btrfs-progs: Fix a small memory leak in managing the btrfs list filter Anand Jain
@ 2013-02-01  7:56     ` Anand Jain
  12 siblings, 0 replies; 131+ messages in thread
From: Anand Jain @ 2013-02-01  7:56 UTC (permalink / raw)
  To: linux-btrfs, dsterba, gene

This patch adds the flags row which as of now will show if the
subvol/snapshot is readonly.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-subvolume.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index 5e51a26..c14e878 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -860,6 +860,11 @@ static int cmd_subvol_show(int argc, char **argv)
 	printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
 	printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
 
+	if (get_ri.flags & BTRFS_ROOT_SUBVOL_RDONLY)
+		printf("\tFlags: \t\t\treadonly\n");
+	else
+		printf("\tFlags: \t\t\t-\n");
+
 	/* print the snapshots of the given subvol if any*/
 	printf("\tSnapshot(s):\n");
 	filter_set = btrfs_list_alloc_filter_set();
-- 
1.8.1.227.g44fe835


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

end of thread, other threads:[~2013-02-01  7:58 UTC | newest]

Thread overview: 131+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-25  9:19 [PATCH 00/10 V2] add show sub-command for btrfs subvol cli Anand Jain
2013-01-23  8:12 ` [PATCH 00/10] " Anand Jain
2013-01-23  8:12   ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
2013-01-24  4:39     ` Eric Sandeen
2013-01-24  9:23       ` Stefan Behrens
2013-01-24 17:57         ` Goffredo Baroncelli
2013-01-24 19:42           ` Eric Sandeen
2013-01-24 22:09             ` Goffredo Baroncelli
2013-01-24 22:36               ` Chris Mason
2013-01-24 22:49                 ` David Sterba
2013-01-24 22:52                 ` Avi Miller
2013-01-25 16:14               ` Eric Sandeen
2013-01-25 16:48                 ` Hugo Mills
2013-01-25 18:47                   ` Gene Czarcinski
2013-01-28  3:12                     ` Anand Jain
2013-01-25 15:19             ` Eric Sandeen
2013-01-25  9:21       ` Anand Jain
2013-01-23  8:12   ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
2013-01-23  8:12   ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
2013-01-23  8:12   ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
2013-01-23  8:12   ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
2013-01-24  4:49     ` Eric Sandeen
2013-01-25  9:20       ` Anand Jain
2013-01-23  8:12   ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
2013-01-23  8:12   ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
2013-01-23  8:12   ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
2013-01-23  8:12   ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
2013-01-23  8:12   ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
2013-01-24  5:06     ` Eric Sandeen
2013-01-24 19:42       ` Zach Brown
2013-01-24 23:14         ` Chris Mason
2013-01-24 23:24           ` Zach Brown
2013-01-25  9:24       ` Anand Jain
2013-01-23 21:57   ` [PATCH 00/10] add show sub-command for btrfs " Gene Czarcinski
2013-01-24  4:11     ` Anand Jain
2013-01-24 20:52   ` Gene Czarcinski
2013-01-25  9:23     ` Anand Jain
2013-01-25  9:19   ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
2013-01-25  9:19   ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
2013-01-25  9:19   ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
2013-01-25  9:19   ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
2013-01-25  9:19   ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
2013-01-25  9:19   ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
2013-01-25  9:19   ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
2013-01-25  9:19   ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
2013-01-25  9:19   ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
2013-01-25  9:19   ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
2013-01-25  9:30   ` [RESEND] [PATCH 00/10 V2] add show sub-command for btrfs " Anand Jain
2013-01-25  9:30     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
2013-01-25  9:30     ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
2013-01-25  9:30     ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
2013-01-25  9:30     ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
2013-01-25  9:30     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
2013-01-25  9:30     ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
2013-01-25  9:30     ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
2013-01-25  9:30     ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
2013-01-25  9:30     ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
2013-01-25  9:30     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
2013-01-25 10:07       ` Stefan Behrens
2013-01-28  5:26         ` Anand Jain
2013-01-28  4:10   ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
2013-01-28  4:10     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
2013-01-28  4:10     ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
2013-01-28  4:10     ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
2013-01-28  4:10     ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
2013-01-28  4:10     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
2013-01-28  4:10     ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
2013-01-28  4:10     ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
2013-01-28  4:10     ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
2013-01-28  4:10     ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
2013-01-28  4:10     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
2013-01-28  5:29     ` [PATCH 00/10 v3] add show sub-command for btrfs " Anand Jain
2013-01-28  5:22   ` [RESEND] " Anand Jain
2013-01-28  5:22     ` [PATCH 01/10] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
2013-01-28 18:08       ` David Sterba
2013-01-28  5:22     ` [PATCH 02/10] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
2013-01-28  5:22     ` [PATCH 03/10] Btrfs-progs: add parent uuid for snapshots Anand Jain
2013-01-28  5:22     ` [PATCH 04/10] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
2013-01-28  5:22     ` [PATCH 05/10] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
2013-01-29  4:42       ` Wang Shilong
2013-01-28 18:04         ` David Sterba
2013-01-29  6:59           ` Anand Jain
2013-01-28  5:22     ` [PATCH 06/10] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
2013-01-28  5:22     ` [PATCH 07/10] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
2013-01-28  5:22     ` [PATCH 08/10] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
2013-01-28  5:22     ` [PATCH 09/10] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
2013-01-28  5:22     ` [PATCH 10/10] Btrfs-progs: add show subcommand to subvol cli Anand Jain
2013-01-29  6:48   ` [PATCH 00/12 v4] add show sub-command for btrfs " Anand Jain
2013-01-29  6:48     ` [PATCH 01/12] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
2013-01-29  6:48     ` [PATCH 02/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
2013-01-30  3:27       ` Wang Shilong
2013-01-30  9:57         ` Anand Jain
2013-01-29  6:48     ` [PATCH 03/12] Btrfs-progs: add parent uuid for snapshots Anand Jain
2013-01-29  6:48     ` [PATCH 04/12] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
2013-01-29  6:48     ` [PATCH 05/12] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
2013-01-29  6:48     ` [PATCH 06/12] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
2013-01-29  6:48     ` [PATCH 07/12] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
2013-01-29  6:48     ` [PATCH 08/12] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
2013-01-29  6:48     ` [PATCH 09/12] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
2013-01-29  6:48     ` [PATCH 10/12] Btrfs-progs: add show subcommand to subvol cli Anand Jain
2013-01-30 10:32       ` Wang Shilong
2013-01-31  3:13         ` Anand Jain
2013-01-29  6:49     ` [PATCH 11/12] Btrfs-progs: filter the deleted subvolumes when listing snapshots Anand Jain
2013-01-29  6:49     ` [PATCH 12/12] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes Anand Jain
2013-01-30  9:56   ` [PATCH 00/12 v5] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
2013-01-30  9:56     ` [PATCH 01/12] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
2013-01-30  9:56     ` [PATCH 02/12] Btrfs-progs: add parent uuid for snapshots Anand Jain
2013-01-30  9:56     ` [PATCH 03/12] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
2013-01-30  9:56     ` [PATCH 04/12] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
2013-01-30  9:56     ` [PATCH 05/12] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
2013-01-30  9:56     ` [PATCH 06/12] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
2013-01-30  9:56     ` [PATCH 07/12] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
2013-01-30  9:56     ` [PATCH 08/12] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
2013-01-30  9:56     ` [PATCH 09/12] Btrfs-progs: add show subcommand to subvol cli Anand Jain
2013-01-30  9:56     ` [PATCH 10/12] Btrfs-progs: filter the deleted subvolumes when listing snapshots Anand Jain
2013-01-30  9:56     ` [PATCH 11/12] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes Anand Jain
2013-01-30  9:56     ` [PATCH 12/12] Btrfs-progs: Fix a small memory leak in managing the btrfs list filter Anand Jain
2013-02-01  7:56   ` [PATCH 00/13 v6] Btrfs-progs: add show sub-command for btrfs subvol cli Anand Jain
2013-02-01  7:56     ` [PATCH 01/13] Btrfs-progs: move printing subvol list outside of btrfs_list_subvols Anand Jain
2013-02-01  7:56     ` [PATCH 02/13] Btrfs-progs: add parent uuid for snapshots Anand Jain
2013-02-01  7:56     ` [PATCH 03/13] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
2013-02-01  7:56     ` [PATCH 04/13] Btrfs-progs: add function btrfs_get_subvol to get root_info of a subvol Anand Jain
2013-02-01  7:56     ` [PATCH 05/13] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
2013-02-01  7:56     ` [PATCH 06/13] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
2013-02-01  7:56     ` [PATCH 07/13] Btrfs-progs: make printing subvol extensible to newer layouts Anand Jain
2013-02-01  7:56     ` [PATCH 08/13] Btrfs-progs: make get_subvol_name non cmds-send specific Anand Jain
2013-02-01  7:56     ` [PATCH 09/13] Btrfs-progs: add show subcommand to subvol cli Anand Jain
2013-02-01  7:56     ` [PATCH 10/13] Btrfs-progs: filter the deleted subvolumes when listing snapshots Anand Jain
2013-02-01  7:56     ` [PATCH 11/13] Btrfs-progs: update btrfs_get_subvol to be inline with resolve_root ret changes Anand Jain
2013-02-01  7:56     ` [PATCH 12/13] Btrfs-progs: Fix a small memory leak in managing the btrfs list filter Anand Jain
2013-02-01  7:56     ` [PATCH 13/13] Btrfs-progs: add subvol flags to print 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.