mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
1.9 KiB
92 lines
1.9 KiB
// SPDX-License-Identifier: GPL-2.0+ |
|
/* |
|
* BTRFS filesystem implementation for U-Boot |
|
* |
|
* 2017 Marek Behun, CZ.NIC, [email protected] |
|
*/ |
|
|
|
#include "btrfs.h" |
|
|
|
static void read_root_item(struct btrfs_path *p, struct btrfs_root_item *item) |
|
{ |
|
u32 len; |
|
int reset = 0; |
|
|
|
len = btrfs_path_item_size(p); |
|
memcpy(item, btrfs_path_item_ptr(p, struct btrfs_root_item), len); |
|
btrfs_root_item_to_cpu(item); |
|
|
|
if (len < sizeof(*item)) |
|
reset = 1; |
|
if (!reset && item->generation != item->generation_v2) { |
|
if (item->generation_v2 != 0) |
|
printf("%s: generation != generation_v2 in root item", |
|
__func__); |
|
reset = 1; |
|
} |
|
if (reset) { |
|
memset(&item->generation_v2, 0, |
|
sizeof(*item) - offsetof(struct btrfs_root_item, |
|
generation_v2)); |
|
} |
|
} |
|
|
|
int btrfs_find_root(u64 objectid, struct btrfs_root *root, |
|
struct btrfs_root_item *root_item) |
|
{ |
|
struct btrfs_path path; |
|
struct btrfs_root_item my_root_item; |
|
|
|
if (!btrfs_search_tree_key_type(&btrfs_info.tree_root, objectid, |
|
BTRFS_ROOT_ITEM_KEY, &path)) |
|
return -1; |
|
|
|
if (!root_item) |
|
root_item = &my_root_item; |
|
read_root_item(&path, root_item); |
|
|
|
if (root) { |
|
root->objectid = objectid; |
|
root->bytenr = root_item->bytenr; |
|
root->root_dirid = root_item->root_dirid; |
|
} |
|
|
|
btrfs_free_path(&path); |
|
return 0; |
|
} |
|
|
|
u64 btrfs_lookup_root_ref(u64 subvolid, struct btrfs_root_ref *refp, char *name) |
|
{ |
|
struct btrfs_path path; |
|
struct btrfs_key *key; |
|
struct btrfs_root_ref *ref; |
|
u64 res = -1ULL; |
|
|
|
key = btrfs_search_tree_key_type(&btrfs_info.tree_root, subvolid, |
|
BTRFS_ROOT_BACKREF_KEY, &path); |
|
|
|
if (!key) |
|
return -1ULL; |
|
|
|
ref = btrfs_path_item_ptr(&path, struct btrfs_root_ref); |
|
btrfs_root_ref_to_cpu(ref); |
|
|
|
if (refp) |
|
*refp = *ref; |
|
|
|
if (name) { |
|
if (ref->name_len > BTRFS_VOL_NAME_MAX) { |
|
printf("%s: volume name too long: %u\n", __func__, |
|
ref->name_len); |
|
goto out; |
|
} |
|
|
|
memcpy(name, ref + 1, ref->name_len); |
|
} |
|
|
|
res = key->offset; |
|
out: |
|
btrfs_free_path(&path); |
|
return res; |
|
} |
|
|
|
|