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