xref: /openbmc/u-boot/fs/btrfs/root.c (revision 21a14fac)
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