diff options
author | David Sterba <dsterba@suse.com> | 2016-10-31 13:56:28 +0100 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-11-09 13:47:29 +0100 |
commit | d4aa2bc07e8d0ed3fb5b87c67ae2f2228178de82 (patch) | |
tree | daf814bbf3e4bdf12dde3636488930cc3ccb14ae /btrfs-list.c | |
parent | eb28e2fcaebb304db06c9d6c873b722f3324cdef (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.c | 37 |
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; |