1 /* 2 * BTRFS filesystem implementation for U-Boot 3 * 4 * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include "btrfs.h" 10 11 static void read_root_item(struct btrfs_path *p, struct btrfs_root_item *item) 12 { 13 u32 len; 14 int reset = 0; 15 16 len = btrfs_path_item_size(p); 17 memcpy(item, btrfs_path_item_ptr(p, struct btrfs_root_item), len); 18 btrfs_root_item_to_cpu(item); 19 20 if (len < sizeof(*item)) 21 reset = 1; 22 if (!reset && item->generation != item->generation_v2) { 23 if (item->generation_v2 != 0) 24 printf("%s: generation != generation_v2 in root item", 25 __func__); 26 reset = 1; 27 } 28 if (reset) { 29 memset(&item->generation_v2, 0, 30 sizeof(*item) - offsetof(struct btrfs_root_item, 31 generation_v2)); 32 } 33 } 34 35 int btrfs_find_root(u64 objectid, struct btrfs_root *root, 36 struct btrfs_root_item *root_item) 37 { 38 struct btrfs_path path; 39 struct btrfs_root_item my_root_item; 40 41 if (!btrfs_search_tree_key_type(&btrfs_info.tree_root, objectid, 42 BTRFS_ROOT_ITEM_KEY, &path)) 43 return -1; 44 45 if (!root_item) 46 root_item = &my_root_item; 47 read_root_item(&path, root_item); 48 49 if (root) { 50 root->objectid = objectid; 51 root->bytenr = root_item->bytenr; 52 root->root_dirid = root_item->root_dirid; 53 } 54 55 btrfs_free_path(&path); 56 return 0; 57 } 58 59 u64 btrfs_lookup_root_ref(u64 subvolid, struct btrfs_root_ref *refp, char *name) 60 { 61 struct btrfs_path path; 62 struct btrfs_key *key; 63 struct btrfs_root_ref *ref; 64 u64 res = -1ULL; 65 66 key = btrfs_search_tree_key_type(&btrfs_info.tree_root, subvolid, 67 BTRFS_ROOT_BACKREF_KEY, &path); 68 69 if (!key) 70 return -1ULL; 71 72 ref = btrfs_path_item_ptr(&path, struct btrfs_root_ref); 73 btrfs_root_ref_to_cpu(ref); 74 75 if (refp) 76 *refp = *ref; 77 78 if (name) { 79 if (ref->name_len > BTRFS_VOL_NAME_MAX) { 80 printf("%s: volume name too long: %u\n", __func__, 81 ref->name_len); 82 goto out; 83 } 84 85 memcpy(name, ref + 1, ref->name_len); 86 } 87 88 res = key->offset; 89 out: 90 btrfs_free_path(&path); 91 return res; 92 } 93 94