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