blob: c405813b69229a9fe712339430392adbc6d4d164 [file] [log] [blame]
Marek BehĂșn21a14fa2017-09-03 17:00:28 +02001/*
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
11static 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
35int 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
59u64 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;
89out:
90 btrfs_free_path(&path);
91 return res;
92}
93