]>
Commit | Line | Data |
---|---|---|
21a14fac MB |
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 |