blob: a424966df61e6528f9542ac7b2d26d7618c6b704 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Marek Behún21a14fa2017-09-03 17:00:28 +02002/*
3 * BTRFS filesystem implementation for U-Boot
4 *
5 * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
Marek Behún21a14fa2017-09-03 17:00:28 +02006 */
7
8#include "btrfs.h"
9
Qu Wenruo33966de2020-06-24 18:02:56 +020010static void read_root_item(struct __btrfs_path *p, struct btrfs_root_item *item)
Marek Behún21a14fa2017-09-03 17:00:28 +020011{
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
Qu Wenruo207011b2020-06-24 18:02:57 +020034int btrfs_find_root(u64 objectid, struct __btrfs_root *root,
Marek Behún21a14fa2017-09-03 17:00:28 +020035 struct btrfs_root_item *root_item)
36{
Qu Wenruo33966de2020-06-24 18:02:56 +020037 struct __btrfs_path path;
Marek Behún21a14fa2017-09-03 17:00:28 +020038 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
Qu Wenruo33966de2020-06-24 18:02:56 +020054 __btrfs_free_path(&path);
Marek Behún21a14fa2017-09-03 17:00:28 +020055 return 0;
56}
57
58u64 btrfs_lookup_root_ref(u64 subvolid, struct btrfs_root_ref *refp, char *name)
59{
Qu Wenruo33966de2020-06-24 18:02:56 +020060 struct __btrfs_path path;
Marek Behún21a14fa2017-09-03 17:00:28 +020061 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) {
Qu Wenruo3b4b40c2020-06-24 18:02:47 +020078 if (ref->name_len > BTRFS_NAME_LEN) {
Marek Behún21a14fa2017-09-03 17:00:28 +020079 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;
88out:
Qu Wenruo33966de2020-06-24 18:02:56 +020089 __btrfs_free_path(&path);
Marek Behún21a14fa2017-09-03 17:00:28 +020090 return res;
91}
92