summaryrefslogtreecommitdiff
path: root/btrfs-list.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2016-10-31 13:56:28 +0100
committerDavid Sterba <dsterba@suse.com>2016-11-09 13:47:29 +0100
commitd4aa2bc07e8d0ed3fb5b87c67ae2f2228178de82 (patch)
treedaf814bbf3e4bdf12dde3636488930cc3ccb14ae /btrfs-list.c
parenteb28e2fcaebb304db06c9d6c873b722f3324cdef (diff)
btrfs-progs: subvol show: print more details about toplevel subvolume
The toplevel subvolume is special and the other listing code leaves it out so we have to add several special cases to handle it. There's no backreference so the path is built artificially. New helper btrfs_get_toplevel_subvol is a reduced version of btrfs_get_subvol. There's some information usually missing for the toplevel subvolume, eg. the uuid or creation info. This has to be fixed on the mkfs side, the other subvolumes are created by kernel. Example: /mnt Name: <FS_TREE> UUID: - Parent UUID: - Received UUID: - Creation time: - Subvolume ID: 5 Generation: 233 Gen at creation: 0 Parent ID: 0 Top level ID: 0 Flags: - Snapshot(s): subv1 Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'btrfs-list.c')
-rw-r--r--btrfs-list.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/btrfs-list.c b/btrfs-list.c
index 8f207b6f..8eec05ea 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -983,7 +983,7 @@ static int list_subvol_search(int fd, struct root_lookup *root_lookup)
/* Search both live and deleted subvolumes */
sk->min_type = BTRFS_ROOT_ITEM_KEY;
sk->max_type = BTRFS_ROOT_BACKREF_KEY;
- sk->min_objectid = BTRFS_FIRST_FREE_OBJECTID;
+ sk->min_objectid = BTRFS_FS_TREE_OBJECTID;
sk->max_objectid = BTRFS_LAST_FREE_OBJECTID;
sk->max_offset = (u64)-1;
sk->max_transid = (u64)-1;
@@ -1014,7 +1014,9 @@ static int list_subvol_search(int fd, struct root_lookup *root_lookup)
add_root_backref(root_lookup, sh.objectid,
sh.offset, dir_id, name,
name_len);
- } else if (sh.type == BTRFS_ROOT_ITEM_KEY) {
+ } else if (sh.type == BTRFS_ROOT_ITEM_KEY &&
+ (sh.objectid >= BTRFS_FIRST_FREE_OBJECTID ||
+ sh.objectid == BTRFS_FS_TREE_OBJECTID)) {
time_t otime;
u8 uuid[BTRFS_UUID_SIZE];
u8 puuid[BTRFS_UUID_SIZE];
@@ -1524,6 +1526,37 @@ static char *strdup_or_null(const char *s)
return strdup(s);
}
+int btrfs_get_toplevel_subvol(int fd, struct root_info *the_ri)
+{
+ int ret;
+ struct root_lookup rl;
+ struct rb_node *rbn;
+ struct root_info *ri;
+ u64 root_id;
+
+ ret = btrfs_list_get_path_rootid(fd, &root_id);
+ if (ret)
+ return ret;
+
+ ret = btrfs_list_subvols(fd, &rl);
+ if (ret)
+ return ret;
+
+ rbn = rb_first(&rl.root);
+ ri = rb_entry(rbn, struct root_info, rb_node);
+
+ if (ri->root_id != BTRFS_FS_TREE_OBJECTID)
+ return -ENOENT;
+
+ memcpy(the_ri, ri, offsetof(struct root_info, path));
+ the_ri->path = strdup_or_null("/");
+ the_ri->name = strdup_or_null("<FS_TREE>");
+ the_ri->full_path = strdup_or_null("/");
+ rb_free_nodes(&rl.root, free_root_info);
+
+ return ret;
+}
+
int btrfs_get_subvol(int fd, struct root_info *the_ri)
{
int ret, rr;