mirror of
https://xff.cz/git/u-boot/
synced 2025-09-01 08:42:12 +02:00
fs: btrfs: Add single-device read-only BTRFS implementation
This adds the proper implementation for the BTRFS filesystem. The implementation currently supports only read-only mode and the filesystem can be only on a single device. Checksums of data chunks is unimplemented. Compression is implemented (ZLIB + LZO). Signed-off-by: Marek Behun <marek.behun@nic.cz> create mode 100644 fs/btrfs/btrfs.h create mode 100644 fs/btrfs/chunk-map.c create mode 100644 fs/btrfs/compression.c create mode 100644 fs/btrfs/ctree.c create mode 100644 fs/btrfs/dev.c create mode 100644 fs/btrfs/dir-item.c create mode 100644 fs/btrfs/extent-io.c create mode 100644 fs/btrfs/hash.c create mode 100644 fs/btrfs/inode.c create mode 100644 fs/btrfs/root.c create mode 100644 fs/btrfs/subvolume.c create mode 100644 fs/btrfs/super.c
This commit is contained in:
93
fs/btrfs/root.c
Normal file
93
fs/btrfs/root.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* BTRFS filesystem implementation for U-Boot
|
||||
*
|
||||
* 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user