From: Anand jain <Anand.Jain@oracle.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 5/5] Btrfs-progs: Add -x option to btrfs subvol list to display snapshots in tree format
Date: Sat, 15 Dec 2012 19:52:08 +0800 [thread overview]
Message-ID: <1355572328-32281-6-git-send-email-Anand.Jain@oracle.com> (raw)
In-Reply-To: <1355572328-32281-1-git-send-email-Anand.Jain@oracle.com>
From: Anand Jain <anand.jain@oracle.com>
This will add new option -x to the btrfs subvol list
sub-command to display the snapshots under its parent subvol
with appropriate indentation.
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
btrfs-list.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmds-subvolume.c | 6 ++-
man/btrfs.8.in | 4 +-
3 files changed, 143 insertions(+), 2 deletions(-)
diff --git a/btrfs-list.c b/btrfs-list.c
index 571efd0..43c279c 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -150,6 +150,11 @@ struct {
},
};
+struct str_print {
+ char path[BTRFS_PATH_NAME_MAX];
+ char otime[256];
+};
+
static btrfs_list_filter_func all_filter_funcs[];
static btrfs_list_comp_func all_comp_funcs[];
@@ -1414,6 +1419,133 @@ static void print_single_volume_info_default(struct root_info *subv)
printf("\n");
}
+static void print_single_volume_info_tree(struct root_info *subv,
+ struct str_print *sp)
+{
+ char tstr[256];
+
+ sprintf(sp->path, "%s", subv->full_path);
+ if (subv->otime)
+ strftime(tstr, 256, "%X %d-%m-%Y", localtime(&subv->otime));
+ else
+ strcpy(tstr, "-");
+ sprintf(sp->otime, "%s", tstr);
+}
+
+int snapshot_is_orphan(struct root_lookup *root_tree, void *uuid)
+{
+ struct rb_node *n;
+ struct root_info *entry;
+
+ n = rb_first(&root_tree->root);
+ while (n) {
+ entry = rb_entry(n, struct root_info, sort_node);
+ if ( ! uuid_compare(entry->uuid, uuid)) {
+ return 0;
+ }
+ n = rb_next(n);
+ }
+ return 1;
+}
+
+void * print_snapshots_of(struct root_lookup *root_tree, void *uuid,
+ int indent, struct str_print *sp)
+{
+ struct rb_node *n;
+ struct root_info *entry;
+ int i = indent;
+ char ispace[BTRFS_PATH_NAME_MAX + 256];
+ char *ispacep = ispace;
+
+ n = rb_first(&root_tree->root);
+ while (n) {
+ entry = rb_entry(n, struct root_info, sort_node);
+ if ( ! uuid_compare(entry->puuid, uuid)) {
+ while(i--) {
+ sprintf(ispacep,"%s"," ");
+ ispacep++;
+ }
+ print_single_volume_info_tree(entry, sp);
+ strcat(ispace, sp->path);
+ strcpy(sp->path, ispace);
+ sp++;
+ sp = (struct str_print *) print_snapshots_of(root_tree,
+ entry->uuid, indent+1, sp);
+ }
+ i = indent;
+ n = rb_next(n);
+ }
+ return sp;
+}
+
+void print_subvol_tree(struct root_lookup *root_tree)
+{
+ struct rb_node *n;
+ struct root_info *entry;
+ int listlen = 0;
+ int max_slen = 0;
+ int pad;
+ int stmp;
+ int i;
+ struct str_print *head;
+ struct str_print *cur;
+
+ n = rb_first(&root_tree->root);
+ while (n) {
+ listlen++;
+ n = rb_next(n);
+ }
+ head = (struct str_print *) malloc(sizeof(struct str_print)*listlen);
+ memset(head, 0, sizeof(struct str_print)*listlen);
+
+ cur = head;
+ n = rb_first(&root_tree->root);
+ while (n) {
+ entry = rb_entry(n, struct root_info, sort_node);
+ if ( uuid_is_null(entry->puuid)) {
+ print_single_volume_info_tree(entry, cur);
+ cur++;
+ cur = (struct str_print *) print_snapshots_of(root_tree,
+ entry->uuid, 1, cur);
+ }
+ n = rb_next(n);
+ }
+ n = rb_first(&root_tree->root);
+ while (n) {
+ entry = rb_entry(n, struct root_info, sort_node);
+ if ( !uuid_is_null(entry->puuid)
+ && snapshot_is_orphan(root_tree, entry->puuid)) {
+ print_single_volume_info_tree(entry, cur);
+ cur++;
+ cur = (struct str_print *) print_snapshots_of(root_tree,
+ entry->uuid, 1, cur);
+ }
+ n = rb_next(n);
+ }
+ //BUG_ON(cur != (head + (sizeof(struct str_print) * listlen)));
+
+ cur = head;
+ for (i=0; i < listlen; i++) {
+ stmp = strlen(cur->path);
+ if (stmp > max_slen)
+ max_slen = stmp;
+ cur++;
+ }
+
+ cur = head;
+ for (i=0; i < listlen; i++) {
+ printf("%s", cur->path);
+ pad = max_slen - strlen(cur->path) + 1;
+ while(pad--)
+ printf("%s"," ");
+ printf("%s"," ");
+ printf("%s", cur->otime);
+ printf("\n");
+ cur++;
+ }
+ free(head);
+}
+
static void print_all_volume_info_tab_head()
{
int i;
@@ -1467,6 +1599,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
n = rb_next(n);
}
break;
+ case 2: // tree format
+ print_subvol_tree(sorted_tree);
+ break;
default:
printf("ERROR: default switch print_all_volume_info\n");
return;
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index 411a5de..4f2704f 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -281,6 +281,7 @@ static const char * const cmd_subvol_list_usage[] = {
"-u print the uuid of subvolumes (and snapshots)",
"-q print the parent uuid of snapshots",
"-t print the result as a table",
+ "-x print the result as a tree",
"-s list snapshots only in the filesystem",
"-r list readonly subvolumes (including snapshots)",
"-g [+|-]value",
@@ -319,7 +320,7 @@ static int cmd_subvol_list(int argc, char **argv)
optind = 1;
while(1) {
c = getopt_long(argc, argv,
- "apsuqrg:c:t", long_options, NULL);
+ "apsuqrg:c:tx", long_options, NULL);
if (c < 0)
break;
@@ -333,6 +334,9 @@ static int cmd_subvol_list(int argc, char **argv)
case 't':
layout = 1;
break;
+ case 'x':
+ layout = 2;
+ break;
case 's':
btrfs_list_setup_filter(&filter_set,
BTRFS_LIST_FILTER_SNAPSHOT_ONLY,
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 9222580..1bb0415 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -11,7 +11,7 @@ btrfs \- control a btrfs filesystem
.PP
\fBbtrfs\fP \fBsubvolume create\fP\fI [<dest>/]<name>\fP
.PP
-\fBbtrfs\fP \fBsubvolume list\fP\fI [-aprts] [-g [+|-]value] [-c [+|-]value] [--rootid=rootid,gen,ogen,path] <path>\fP
+\fBbtrfs\fP \fBsubvolume list\fP\fI [-aprtxs] [-g [+|-]value] [-c [+|-]value] [--rootid=rootid,gen,ogen,path] <path>\fP
.PP
\fBbtrfs\fP \fBsubvolume set-default\fP\fI <id> <path>\fP
.PP
@@ -124,6 +124,8 @@ and top level. The parent's ID may be used at mount time via the
\fB-t\fP print the result as a table.
+\fB-x\fP print the result as a tree.
+
\fB-a\fP print all the subvolumes in the filesystem.
\fB-r\fP only readonly subvolumes in the filesystem wille be listed.
--
1.7.1
prev parent reply other threads:[~2012-12-15 11:46 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-15 11:52 [PATCH 0/5] add tree format display for btrfs subvol list subcommand Anand jain
2012-12-15 11:52 ` [PATCH 1/5] Btrfs-progs: add parent uuid for snapshots Anand jain
2012-12-15 11:52 ` [PATCH 2/5] Btrfs-progs: maintain similar case in heading prefix Anand jain
2012-12-15 11:52 ` [PATCH 3/5] Btrfs-progs: Move printing outside of btrfs_list_subvols Anand jain
2012-12-15 11:52 ` [PATCH 4/5] Btrfs-progs: make provision to print subvol list tree format Anand jain
2012-12-15 11:52 ` Anand jain [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1355572328-32281-6-git-send-email-Anand.Jain@oracle.com \
--to=anand.jain@oracle.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).