Zhong, Xin
2011-Jul-12 02:48 UTC
[PATCH V3] Btrfs-progs: add "btrfs subvolume get-default" subcommand
Add subcommand to get the default subvolume of btrfs filesystem
V2->V3:
* add man page
* based on http://git.darksatanic.net/repo/btrfs-progs-unstable.git
integration-20110705
Reviewed-by: Andreas Philipp <philipp.andreas@gmail.com>
Reviewed-by: Goffredo Baroncelli <kreijack@libero.it>
Reported-by: Yang, Yi <yi.y.yang@intel.com>
Signed-off-by: Zhong, Xin <xin.zhong@intel.com>
---
btrfs-list.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
btrfs.c | 3 ++
btrfs_cmds.c | 31 ++++++++++++++++++++++++++++-
btrfs_cmds.h | 3 +-
man/btrfs.8.in | 7 ++++++
5 files changed, 98 insertions(+), 4 deletions(-)
diff --git a/btrfs-list.c b/btrfs-list.c
index 07b179a..016d09c 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -560,7 +560,7 @@ build:
return full;
}
-int list_subvols(int fd, int print_parent)
+int list_subvols(int fd, int print_parent, int get_default)
{
struct root_lookup root_lookup;
struct rb_node *n;
@@ -569,10 +569,12 @@ int list_subvols(int fd, int print_parent)
struct btrfs_ioctl_search_key *sk = &args.key;
struct btrfs_ioctl_search_header *sh;
struct btrfs_root_ref *ref;
+ struct btrfs_dir_item *di;
unsigned long off = 0;
int name_len;
char *name;
u64 dir_id;
+ u64 subvol_id = 0;
int i;
int e;
@@ -672,6 +674,52 @@ int list_subvols(int fd, int print_parent)
n = rb_next(n);
}
+ memset(&args, 0, sizeof(args));
+
+ /* search in the tree of tree roots */
+ sk->tree_id = BTRFS_ROOT_TREE_OBJECTID;
+
+ /* search dir item */
+ sk->max_type = BTRFS_DIR_ITEM_KEY;
+ sk->min_type = BTRFS_DIR_ITEM_KEY;
+
+ sk->max_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
+ sk->min_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
+ sk->max_offset = (u64)-1;
+ sk->max_transid = (u64)-1;
+
+ /* just a big number, doesn''t matter much */
+ sk->nr_items = 4096;
+
+ /* try to get the objectid of default subvolume */
+ if (get_default) {
+ ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
+ if (ret < 0) {
+ fprintf(stderr, "ERROR: can''t perform the search\n");
+ return ret;
+ }
+
+ off = 0;
+ /* go through each item to find dir item named "default" */
+ for (i = 0; i < sk->nr_items; i++) {
+ sh = (struct btrfs_ioctl_search_header *)(args.buf +
+ off);
+ off += sizeof(*sh);
+ if (sh->type == BTRFS_DIR_ITEM_KEY) {
+ di = (struct btrfs_dir_item *)(args.buf + off);
+ name_len = le16_to_cpu(di->name_len);
+ name = (char *)di + sizeof(struct btrfs_dir_item);
+ if (!strncmp("default", name, name_len)) {
+ subvol_id = btrfs_disk_key_objectid(
+ &di->location);
+ break;
+ }
+ }
+
+ off += sh->len;
+ }
+ }
+
/* now that we have all the subvol-relative paths filled in,
* we have to string the subvols together so that we can get
* a path all the way back to the FS root
@@ -680,7 +728,13 @@ int list_subvols(int fd, int print_parent)
while (n) {
struct root_info *entry;
entry = rb_entry(n, struct root_info, rb_node);
- resolve_root(&root_lookup, entry, print_parent);
+ if (!get_default)
+ resolve_root(&root_lookup, entry, print_parent);
+ /* we only want the default subvolume */
+ else if (subvol_id == entry->root_id)
+ resolve_root(&root_lookup, entry, print_parent);
+ else if (subvol_id == 0)
+ break;
n = rb_prev(n);
}
diff --git a/btrfs.c b/btrfs.c
index 67d6f6f..1af8360 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -94,6 +94,9 @@ static struct Command commands[] = {
"-l len defragment only up to len bytes\n"
"-t size minimal size of file to be considered for
defragmenting\n"
},
+ { do_get_default_subvol, 1, "subvolume get-default",
"<path>\n"
+ "Get the default subvolume of a filesystem."
+ },
{ do_fssync, 1,
"filesystem sync", "<path>\n"
"Force a sync on the filesystem <path>.",
diff --git a/btrfs_cmds.c b/btrfs_cmds.c
index 0612f34..e151c25 100644
--- a/btrfs_cmds.c
+++ b/btrfs_cmds.c
@@ -340,7 +340,7 @@ int do_subvol_list(int argc, char **argv)
fprintf(stderr, "ERROR: can''t access
''%s''\n", subvol);
return 12;
}
- ret = list_subvols(fd, print_parent);
+ ret = list_subvols(fd, print_parent, 0);
if (ret)
return 19;
return 0;
@@ -1443,6 +1443,35 @@ int do_change_label(int nargs, char **argv)
}
+int do_get_default_subvol(int nargs, char **argv)
+{
+ int fd;
+ int ret;
+ char *subvol;
+
+ subvol = argv[1];
+
+ ret = test_issubvolume(subvol);
+ if (ret < 0) {
+ fprintf(stderr, "ERROR: error accessing ''%s''\n",
subvol);
+ return 12;
+ }
+ if (!ret) {
+ fprintf(stderr, "ERROR: ''%s'' is not a
subvolume\n", subvol);
+ return 13;
+ }
+
+ fd = open_file_or_dir(subvol);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: can''t access
''%s''\n", subvol);
+ return 12;
+ }
+ ret = list_subvols(fd, 0, 1);
+ if (ret)
+ return 19;
+ return 0;
+}
+
int do_df_filesystem(int nargs, char **argv)
{
struct btrfs_ioctl_space_args *sargs;
diff --git a/btrfs_cmds.h b/btrfs_cmds.h
index 83faa5b..d983588 100644
--- a/btrfs_cmds.h
+++ b/btrfs_cmds.h
@@ -34,7 +34,8 @@ int do_scan(int nargs, char **argv);
int do_resize(int nargs, char **argv);
int do_subvol_list(int nargs, char **argv);
int do_set_default_subvol(int nargs, char **argv);
-int list_subvols(int fd, int print_parent);
+int do_get_default_subvol(int nargs, char **argv);
+int list_subvols(int fd, int print_parent, int get_default);
int do_df_filesystem(int nargs, char **argv);
int find_updated_files(int fd, u64 root_id, u64 oldest_gen);
int do_find_newer(int argc, char **argv);
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 84a60cd..61ce0df 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -15,6 +15,8 @@ btrfs \- control a btrfs filesystem
.PP
\fBbtrfs\fP \fBsubvolume set-default\fP\fI <id> <path>\fP
.PP
+\fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
+.PP
\fBbtrfs\fP \fBfilesystem sync\fP\fI <path> \fP
.PP
\fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max
<filesystem>\fP
@@ -126,6 +128,11 @@ Set the subvolume of the filesystem \fI<path>\fR
which is mounted as
is returned by the \fBsubvolume list\fR command.
.TP
+\fBsubvolume get-default\fR\fI <path>\fR
+Get the default subvolume of the filesystem \fI<path>\fR. The output
format
+is similar to \fBsubvolume list\fR command.
+.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>...]
Defragment file data and/or directory metadata. To defragment all files in a
--
1.7.0.4
--
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
David Sterba
2011-Aug-04 19:27 UTC
Re: [PATCH V3] Btrfs-progs: add "btrfs subvolume get-default" subcommand
Hi, please move the help text for ''get-default'' right after ''set-default'', it''s logical and currently it''s very easy to miss it (it took me a few seconds to locate it event if I knew it''s there :) thanks, david On Tue, Jul 12, 2011 at 10:48:37AM +0800, Zhong, Xin wrote:> diff --git a/btrfs.c b/btrfs.c > index 67d6f6f..1af8360 100644 > --- a/btrfs.c > +++ b/btrfs.c@@ -78,6 +78,9 @@ static struct Command commands[] = { "as default.", NULL },> + { do_get_default_subvol, 1, "subvolume get-default", "<path>\n" > + "Get the default subvolume of a filesystem." > + },{ do_find_newer, 2, "subvolume find-new", "<path> <last_gen>\n" "List the recently modified files in a filesystem.", NULL> diff --git a/btrfs_cmds.c b/btrfs_cmds.c > ...-- 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