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