mirror of
https://github.com/relalis/macos-btrfs.git
synced 2026-02-04 05:35:46 +00:00
Tree root operations for root_tree and chunk_tree
This commit is contained in:
@@ -1,18 +1,19 @@
|
||||
KMOD = btrfs
|
||||
SRCS = vnode_if.h btrfs.c btrfs_kmod.c
|
||||
SRCS = vnode_if.h btrfs.c btrfs_tree.c btrfs_kmod.c
|
||||
MACHINE_ARCH = amd64
|
||||
MACHINE = amd64
|
||||
LDFLAGS = -m elf_x86_64
|
||||
CFLAGS = --target=x86_64-freebsd -I../include
|
||||
CC = clang
|
||||
LD = ld.lld
|
||||
OBJCOPY = llvm-objcopy
|
||||
CC = clang-14
|
||||
LD = ld.lld-14
|
||||
OBJCOPY = llvm-objcopy-14
|
||||
|
||||
.if ${.MAKE.OS} == "Linux"
|
||||
# `xargs` on Linux doesn't support '-J' (a FreeBSD extension), which results in error
|
||||
EXPORT_SYMS = YES
|
||||
# Debian clang 14.0.6 breaks fstack-protector, this is a temp workaround
|
||||
CFLAGS += -DLINUX_CROSS_BUILD
|
||||
# __stack_chk_guard is just breaking randomly on clang. Adding O2 for some
|
||||
# absurd reason fixes linking.
|
||||
CFLAGS += -DLINUX_CROSS_BUILD -O2
|
||||
.endif
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
||||
@@ -24,14 +24,16 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _BTRFS_TREE_OPS_H
|
||||
#define _BTRFS_TREE_OPS_H
|
||||
#ifndef _BTRFS_H
|
||||
#define _BTRFS_H
|
||||
|
||||
#include <sys/tree.h>
|
||||
#include "btrfs_mount.h"
|
||||
|
||||
int btrfs_lookup_dir_item(struct btrfsmount_internal *bmp, struct btrfs_dir_item *dir_result, const char *name, int name_len);
|
||||
|
||||
// bo_ - Block operations
|
||||
// bc_ - BTRFS Cache
|
||||
|
||||
int bo_read_key_into_buf(struct vnode *devvp, struct btrfs_key key, struct btrfs_sys_chunks *cache_head, uint8_t *dest);
|
||||
struct b_chunk_list *bc_find_key_in_cache(struct btrfs_key key, struct btrfs_sys_chunks *head);
|
||||
struct b_chunk_list *bc_find_logical_in_cache(uint64_t logical_addr, struct btrfs_sys_chunks *head);
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
|
||||
#include "btrfs_mount.h"
|
||||
#include "btrfs.h"
|
||||
#include "btrfs_tree.h"
|
||||
|
||||
#ifdef LINUX_CROSS_BUILD
|
||||
// clang on debian breaks fstack-protector as of 14.0.6
|
||||
@@ -306,7 +307,12 @@ static int mount_btrfs_filesystem(struct vnode *odevvp, struct mount *mp) {
|
||||
|
||||
// store superblock in the in-memory structure
|
||||
bmp->pm_superblock = *prim_sblock;
|
||||
|
||||
|
||||
bmp->pm_fsinfo.chunk_root = NULL;
|
||||
bmp->pm_fsinfo.tree_root = NULL;
|
||||
bmp->pm_fsinfo.fs_root = NULL;
|
||||
bmp->pm_fsinfo.extent_root = NULL;
|
||||
|
||||
brelse(bp);
|
||||
|
||||
LIST_INIT(&bmp->pm_backing_dev_bootstrap);
|
||||
@@ -345,24 +351,52 @@ static int mount_btrfs_filesystem(struct vnode *odevvp, struct mount *mp) {
|
||||
if(tmp_chunk_entry == NULL)
|
||||
goto error_exit;
|
||||
|
||||
// - Read chunk tree root
|
||||
// - Read the root tree root (requires chunk tree for logical->physical mapping)
|
||||
// - Read FS root to begin traversal
|
||||
uint8_t *temp_buf = malloc(tmp_chunk_entry->chunk_item.size, M_BTRFSMOUNT, M_WAITOK | M_ZERO);
|
||||
bmp->pm_fsinfo.chunk_root = malloc(tmp_chunk_entry->chunk_item.size, M_BTRFSMOUNT, M_WAITOK | M_ZERO);
|
||||
|
||||
error = bo_read_key_into_buf(devvp, tmp_chunk_entry->key, &bmp->pm_backing_dev_bootstrap, temp_buf);
|
||||
error = bo_read_key_into_buf(devvp, tmp_chunk_entry->key, &bmp->pm_backing_dev_bootstrap, bmp->pm_fsinfo.chunk_root);
|
||||
if(error)
|
||||
goto error_exit;
|
||||
|
||||
/*
|
||||
struct btrfs_tree_header *head = (struct btrfs_tree_header *)temp_buf;
|
||||
uprintf("addr %lu num items %u level %d\n", head->address, head->num_items, head->level);
|
||||
uint8_t *tst = (temp_buf + sizeof(struct btrfs_tree_header));
|
||||
for(int i = 0; i < head->num_items; ++i) {
|
||||
struct btrfs_tree_header head = BTRFSHEADER(bmp->pm_fsinfo.chunk_root);
|
||||
uint8_t *tst = BTRFSDATABUF(bmp->pm_fsinfo.chunk_root);
|
||||
for(int i = 0; i < head.num_items; ++i) {
|
||||
struct btrfs_leaf_node *to_dump_item = (struct btrfs_leaf_node *) (tst + (i * (sizeof(struct btrfs_leaf_node))));
|
||||
uprintf("\n[ key = {obj_id=%lu obj_type=0x%X off=%lu} ]\n", to_dump_item->key.obj_id, to_dump_item->key.obj_type, to_dump_item->key.offset);
|
||||
switch(to_dump_item->key.obj_type) {
|
||||
case TYPE_CHUNK_ITEM: {
|
||||
struct btrfs_chunk_item *tmp_chnk = (struct btrfs_chunk_item *)(tst + to_dump_item->offset);
|
||||
for(int j = 0; j < tmp_chnk->num_stripes; ++j) {
|
||||
// We're skipping all chunks past the first.
|
||||
// Stripes after the first are for RAID setups, which we don't support
|
||||
if(j > 0)
|
||||
continue;
|
||||
struct btrfs_chunk_item_stripe *tmp_stripe = (struct btrfs_chunk_item_stripe *)(tst + to_dump_item->offset + sizeof(struct btrfs_chunk_item));
|
||||
if(!bc_add_to_chunk_cache(to_dump_item->key, *tmp_chnk, *tmp_stripe, &bmp->pm_backing_dev_bootstrap)) {
|
||||
uprintf("Overlap in chunk cache %lu %X\n", to_dump_item->key.obj_id, to_dump_item->key.obj_type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
tmp_chunk_entry = bc_find_logical_in_cache(bmp->pm_superblock.root_tree_addr, &bmp->pm_backing_dev_bootstrap);
|
||||
// if we cannot read the root tree, we cannot continue
|
||||
if(tmp_chunk_entry == NULL)
|
||||
goto error_exit;
|
||||
|
||||
bmp->pm_fsinfo.tree_root = malloc(tmp_chunk_entry->chunk_item.size, M_BTRFSMOUNT, M_WAITOK | M_ZERO);
|
||||
|
||||
error = bo_read_key_into_buf(devvp, tmp_chunk_entry->key, &bmp->pm_backing_dev_bootstrap, bmp->pm_fsinfo.tree_root);
|
||||
if(error)
|
||||
goto error_exit;
|
||||
|
||||
head = BTRFSHEADER(bmp->pm_fsinfo.tree_root);
|
||||
uprintf("TREE ROOT addr %lu num items %u level %d\n", head.address, head.num_items, head.level);
|
||||
|
||||
// assign our internal structure to mp
|
||||
bmp->pm_devvp = devvp;
|
||||
bmp->pm_odevvp = odevvp;
|
||||
@@ -370,7 +404,6 @@ static int mount_btrfs_filesystem(struct vnode *odevvp, struct mount *mp) {
|
||||
|
||||
mp->mnt_data = bmp;
|
||||
|
||||
free(temp_buf, M_BTRFSMOUNT);
|
||||
return(0);
|
||||
|
||||
error_exit:
|
||||
@@ -397,6 +430,7 @@ error_exit:
|
||||
}
|
||||
|
||||
static int btrfs_unmount(struct mount *mp, int mntflags) {
|
||||
uprintf("[BTRFS] Unmount called\n");
|
||||
int error;
|
||||
struct btrfsmount_internal *bmp;
|
||||
|
||||
@@ -416,6 +450,10 @@ static int btrfs_unmount(struct mount *mp, int mntflags) {
|
||||
dev_rel(bmp->pm_dev);
|
||||
|
||||
bc_free_cache_list(&bmp->pm_backing_dev_bootstrap);
|
||||
if(bmp->pm_fsinfo.chunk_root != NULL)
|
||||
free(bmp->pm_fsinfo.chunk_root, M_BTRFSMOUNT);
|
||||
if(bmp->pm_fsinfo.tree_root != NULL)
|
||||
free(bmp->pm_fsinfo.tree_root, M_BTRFSMOUNT);
|
||||
|
||||
lockdestroy(&bmp->pm_btrfslock);
|
||||
free(bmp, M_BTRFSMOUNT);
|
||||
@@ -426,6 +464,7 @@ static int btrfs_unmount(struct mount *mp, int mntflags) {
|
||||
static int btrfs_root(struct mount *mp, int flags, struct vnode **vpp) {
|
||||
// struct btrfsmount_internal *bmp = VFSTOBTRFS(mp);
|
||||
// return(bmp->pm_superblock.leaf_size);
|
||||
uprintf("[BTRFS] btrfs_root called\n");
|
||||
|
||||
// After mount is called, this function is called. We're returning an error to kill the process
|
||||
// for testing purposes
|
||||
|
||||
@@ -48,16 +48,16 @@ struct b_chunk_list {
|
||||
// Linux kernel has a helpful struct (btrfs/fs.h) that holds pointers to all the roots
|
||||
// we will encounter. Seems like a good idea to me.
|
||||
struct btrfs_fs_info {
|
||||
struct btrfs_root *tree_root;
|
||||
struct btrfs_root *chunk_root;
|
||||
struct btrfs_root *fs_root;
|
||||
struct btrfs_root *extent_root;
|
||||
uint8_t *tree_root;
|
||||
uint8_t *chunk_root;
|
||||
uint8_t *fs_root;
|
||||
uint8_t *extent_root;
|
||||
};
|
||||
|
||||
// RB root item
|
||||
//@todo: implement btrfs_root struct methods to hold RB roots
|
||||
struct btrfs_root {
|
||||
RB_ENTRY(btrfs_root) rb_node;
|
||||
// RB_ENTRY(btrfs_root) rb_node;
|
||||
|
||||
struct btrfs_root_item root_item;
|
||||
struct btrfs_key root_key;
|
||||
|
||||
47
kernel/freebsd/btrfs_tree.c
Normal file
47
kernel/freebsd/btrfs_tree.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2024, Yehia Hafez
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/buf.h>
|
||||
#include "btrfs_tree.h"
|
||||
|
||||
int bt_search_by_key(struct btrfs_key in, struct vnode *devvp, struct btrfs_sys_chunks *cache_head, uint8_t *tree_root, void *dest) {
|
||||
struct btrfs_tree_header t_header = BTRFSHEADER(tree_root);
|
||||
if(t_header.level == 1) {
|
||||
uprintf("node\n");
|
||||
} else {
|
||||
uprintf("leaf\n");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int bt_walk_leaves(struct btrfs_sys_chunks *head) {
|
||||
|
||||
return(0);
|
||||
}
|
||||
38
kernel/freebsd/btrfs_tree.h
Normal file
38
kernel/freebsd/btrfs_tree.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Copyright (c) 2024, Yehia Hafez
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _BTRFS_TREE_H
|
||||
#define _BTRFS_TREE_H
|
||||
|
||||
#include "btrfs_mount.h"
|
||||
|
||||
#define BTRFSHEADER(x) *((struct btrfs_tree_header *) x)
|
||||
#define BTRFSDATABUF(x) (x + sizeof(struct btrfs_tree_header))
|
||||
|
||||
int bt_search_by_key(struct btrfs_key in, struct vnode *devvp, struct btrfs_sys_chunks *cache_head, uint8_t *tree_root, void *dest);
|
||||
int bt_walk_leaves(struct btrfs_sys_chunks *head);
|
||||
|
||||
#endif //_BTRFS_TREE_H
|
||||
@@ -536,7 +536,7 @@ typedef struct INODE_ITEM {
|
||||
@field stime Timestamp for stransid.
|
||||
@field rtime Timestamp for rtransid.
|
||||
@field reserved For future expansion
|
||||
@discussion This structure holds defines the the root of a btree. It is associated with the ROOT_ITEM type. This structure is never used outside of this item.
|
||||
@discussion This structure holds defines the root of a btree. It is associated with the ROOT_ITEM type. This structure is never used outside of this item.
|
||||
*/
|
||||
struct btrfs_root_item {
|
||||
btrfs_inode_item inode;
|
||||
|
||||
Reference in New Issue
Block a user