2 * BTRFS filesystem implementation for U-Boot
4 * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
6 * SPDX-License-Identifier: GPL-2.0+
12 static int get_subvol_name(u64 subvolid
, char *name
, int max_len
)
14 struct btrfs_root_ref rref
;
15 struct btrfs_inode_ref iref
;
16 struct btrfs_root root
;
18 char tmp
[max(BTRFS_VOL_NAME_MAX
, BTRFS_NAME_MAX
)];
21 ptr
= name
+ max_len
- 1;
24 while (subvolid
!= BTRFS_FS_TREE_OBJECTID
) {
25 subvolid
= btrfs_lookup_root_ref(subvolid
, &rref
, tmp
);
27 if (subvolid
== -1ULL)
30 ptr
-= rref
.name_len
+ 1;
34 memcpy(ptr
+ 1, tmp
, rref
.name_len
);
37 if (btrfs_find_root(subvolid
, &root
, NULL
))
42 while (dir
!= BTRFS_FIRST_FREE_OBJECTID
) {
43 dir
= btrfs_lookup_inode_ref(&root
, dir
, &iref
, tmp
);
48 ptr
-= iref
.name_len
+ 1;
52 memcpy(ptr
+ 1, tmp
, iref
.name_len
);
57 if (ptr
== name
+ max_len
- 1) {
61 memmove(name
, ptr
, name
+ max_len
- ptr
);
67 printf("%s: subvolume name too long\n", __func__
);
71 u64
btrfs_get_default_subvol_objectid(void)
73 struct btrfs_dir_item item
;
75 if (btrfs_lookup_dir_item(&btrfs_info
.tree_root
,
76 btrfs_info
.sb
.root_dir_objectid
, "default", 7,
78 return BTRFS_FS_TREE_OBJECTID
;
79 return item
.location
.objectid
;
82 static void list_subvols(u64 tree
, char *nameptr
, int max_name_len
, int level
)
84 struct btrfs_key key
, *found_key
;
85 struct btrfs_path path
;
86 struct btrfs_root_ref
*ref
;
90 key
.type
= BTRFS_ROOT_REF_KEY
;
93 if (btrfs_search_tree(&btrfs_info
.tree_root
, &key
, &path
))
97 found_key
= btrfs_path_leaf_key(&path
);
98 if (btrfs_comp_keys_type(&key
, found_key
))
101 ref
= btrfs_path_item_ptr(&path
, struct btrfs_root_ref
);
102 btrfs_root_ref_to_cpu(ref
);
104 printf("ID %llu parent %llu name ", found_key
->offset
, tree
);
105 if (nameptr
&& !get_subvol_name(found_key
->offset
, nameptr
,
107 printf("%s\n", nameptr
);
109 printf("%.*s\n", (int) ref
->name_len
,
110 (const char *) (ref
+ 1));
113 list_subvols(found_key
->offset
, nameptr
, max_name_len
,
116 printf("%s: Too much recursion, maybe skipping some "
117 "subvolumes\n", __func__
);
118 } while (!(res
= btrfs_next_slot(&path
)));
120 btrfs_free_path(&path
);
123 void btrfs_list_subvols(void)
125 char *nameptr
= malloc(4096);
127 list_subvols(BTRFS_FS_TREE_OBJECTID
, nameptr
, nameptr
? 4096 : 0, 40);