xref: /openbmc/u-boot/fs/btrfs/root.c (revision e8f80a5a)
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 
read_root_item(struct btrfs_path * p,struct btrfs_root_item * item)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 
btrfs_find_root(u64 objectid,struct btrfs_root * root,struct btrfs_root_item * root_item)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 
btrfs_lookup_root_ref(u64 subvolid,struct btrfs_root_ref * refp,char * name)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