1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 221a14facSMarek Behún /* 321a14facSMarek Behún * BTRFS filesystem implementation for U-Boot 421a14facSMarek Behún * 521a14facSMarek Behún * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz 621a14facSMarek Behún */ 721a14facSMarek Behún 821a14facSMarek Behún #include "btrfs.h" 921a14facSMarek Behún 1021a14facSMarek Behún static void read_root_item(struct btrfs_path *p, struct btrfs_root_item *item) 1121a14facSMarek Behún { 1221a14facSMarek Behún u32 len; 1321a14facSMarek Behún int reset = 0; 1421a14facSMarek Behún 1521a14facSMarek Behún len = btrfs_path_item_size(p); 1621a14facSMarek Behún memcpy(item, btrfs_path_item_ptr(p, struct btrfs_root_item), len); 1721a14facSMarek Behún btrfs_root_item_to_cpu(item); 1821a14facSMarek Behún 1921a14facSMarek Behún if (len < sizeof(*item)) 2021a14facSMarek Behún reset = 1; 2121a14facSMarek Behún if (!reset && item->generation != item->generation_v2) { 2221a14facSMarek Behún if (item->generation_v2 != 0) 2321a14facSMarek Behún printf("%s: generation != generation_v2 in root item", 2421a14facSMarek Behún __func__); 2521a14facSMarek Behún reset = 1; 2621a14facSMarek Behún } 2721a14facSMarek Behún if (reset) { 2821a14facSMarek Behún memset(&item->generation_v2, 0, 2921a14facSMarek Behún sizeof(*item) - offsetof(struct btrfs_root_item, 3021a14facSMarek Behún generation_v2)); 3121a14facSMarek Behún } 3221a14facSMarek Behún } 3321a14facSMarek Behún 3421a14facSMarek Behún int btrfs_find_root(u64 objectid, struct btrfs_root *root, 3521a14facSMarek Behún struct btrfs_root_item *root_item) 3621a14facSMarek Behún { 3721a14facSMarek Behún struct btrfs_path path; 3821a14facSMarek Behún struct btrfs_root_item my_root_item; 3921a14facSMarek Behún 4021a14facSMarek Behún if (!btrfs_search_tree_key_type(&btrfs_info.tree_root, objectid, 4121a14facSMarek Behún BTRFS_ROOT_ITEM_KEY, &path)) 4221a14facSMarek Behún return -1; 4321a14facSMarek Behún 4421a14facSMarek Behún if (!root_item) 4521a14facSMarek Behún root_item = &my_root_item; 4621a14facSMarek Behún read_root_item(&path, root_item); 4721a14facSMarek Behún 4821a14facSMarek Behún if (root) { 4921a14facSMarek Behún root->objectid = objectid; 5021a14facSMarek Behún root->bytenr = root_item->bytenr; 5121a14facSMarek Behún root->root_dirid = root_item->root_dirid; 5221a14facSMarek Behún } 5321a14facSMarek Behún 5421a14facSMarek Behún btrfs_free_path(&path); 5521a14facSMarek Behún return 0; 5621a14facSMarek Behún } 5721a14facSMarek Behún 5821a14facSMarek Behún u64 btrfs_lookup_root_ref(u64 subvolid, struct btrfs_root_ref *refp, char *name) 5921a14facSMarek Behún { 6021a14facSMarek Behún struct btrfs_path path; 6121a14facSMarek Behún struct btrfs_key *key; 6221a14facSMarek Behún struct btrfs_root_ref *ref; 6321a14facSMarek Behún u64 res = -1ULL; 6421a14facSMarek Behún 6521a14facSMarek Behún key = btrfs_search_tree_key_type(&btrfs_info.tree_root, subvolid, 6621a14facSMarek Behún BTRFS_ROOT_BACKREF_KEY, &path); 6721a14facSMarek Behún 6821a14facSMarek Behún if (!key) 6921a14facSMarek Behún return -1ULL; 7021a14facSMarek Behún 7121a14facSMarek Behún ref = btrfs_path_item_ptr(&path, struct btrfs_root_ref); 7221a14facSMarek Behún btrfs_root_ref_to_cpu(ref); 7321a14facSMarek Behún 7421a14facSMarek Behún if (refp) 7521a14facSMarek Behún *refp = *ref; 7621a14facSMarek Behún 7721a14facSMarek Behún if (name) { 7821a14facSMarek Behún if (ref->name_len > BTRFS_VOL_NAME_MAX) { 7921a14facSMarek Behún printf("%s: volume name too long: %u\n", __func__, 8021a14facSMarek Behún ref->name_len); 8121a14facSMarek Behún goto out; 8221a14facSMarek Behún } 8321a14facSMarek Behún 8421a14facSMarek Behún memcpy(name, ref + 1, ref->name_len); 8521a14facSMarek Behún } 8621a14facSMarek Behún 8721a14facSMarek Behún res = key->offset; 8821a14facSMarek Behún out: 8921a14facSMarek Behún btrfs_free_path(&path); 9021a14facSMarek Behún return res; 9121a14facSMarek Behún } 9221a14facSMarek Behún 93