ctree.h 5.6 KB
Newer Older
1 2 3
#ifndef __CTREE__
#define __CTREE__

4 5
#include "list.h"

6
#define CTREE_BLOCKSIZE 1024
7

8 9 10 11 12 13 14 15 16 17
/*
 * the key defines the order in the tree, and so it also defines (optimal)
 * block layout.  objectid corresonds to the inode number.  The flags
 * tells us things about the object, and is a kind of stream selector.
 * so for a given inode, keys with flags of 1 might refer to the inode
 * data, flags of 2 may point to file data in the btree and flags == 3
 * may point to extents.
 *
 * offset is the starting byte offset for this key in the stream.
 */
18 19 20 21 22 23
struct key {
	u64 objectid;
	u32 flags;
	u64 offset;
} __attribute__ ((__packed__));

24 25 26
/*
 * every tree block (leaf or node) starts with this header.
 */
27 28
struct header {
	u64 fsid[2]; /* FS specific uuid */
29 30
	u64 blocknr; /* which block this node is supposed to live in */
	u64 parentid; /* objectid of the tree root */
31 32 33 34
	u32 csum;
	u32 ham;
	u16 nritems;
	u16 flags;
35
	/* generation flags to be added */
36 37
} __attribute__ ((__packed__));

38
#define MAX_LEVEL 8
39 40 41 42
#define NODEPTRS_PER_BLOCK ((CTREE_BLOCKSIZE - sizeof(struct header)) / \
			    (sizeof(struct key) + sizeof(u64)))

struct tree_buffer;
43

44 45 46 47 48
/*
 * in ram representation of the tree.  extent_root is used for all allocations
 * and for the extent tree extent_root root.  current_insert is used
 * only for the extent tree.
 */
49 50
struct ctree_root {
	struct tree_buffer *node;
51
	struct tree_buffer *commit_root;
52
	struct ctree_root *extent_root;
53
	struct key current_insert;
54
	struct key last_insert;
55 56
	int fp;
	struct radix_tree_root cache_radix;
57
	struct radix_tree_root pinned_radix;
58 59 60
	struct list_head trans;
	struct list_head cache;
	int cache_size;
61 62
};

63 64 65
/*
 * describes a tree on disk
 */
66 67 68 69
struct ctree_root_info {
	u64 fsid[2]; /* FS specific uuid */
	u64 blocknr; /* blocknr of this block */
	u64 objectid; /* inode number of this root */
70
	u64 tree_root; /* the tree root block */
71 72 73 74 75
	u32 csum;
	u32 ham;
	u64 snapuuid[2]; /* root specific uuid */
} __attribute__ ((__packed__));

76 77 78 79
/*
 * the super block basically lists the main trees of the FS
 * it currently lacks any block count etc etc
 */
C
Chris Mason 已提交
80 81 82 83 84
struct ctree_super_block {
	struct ctree_root_info root_info;
	struct ctree_root_info extent_info;
} __attribute__ ((__packed__));

85 86 87 88 89
/*
 * A leaf is full of items.  The exact type of item is defined by
 * the key flags parameter.  offset and size tell us where to find
 * the item in the leaf (relative to the start of the data area)
 */
90 91 92 93 94 95
struct item {
	struct key key;
	u16 offset;
	u16 size;
} __attribute__ ((__packed__));

96 97 98 99 100 101 102
/*
 * leaves have an item area and a data area:
 * [item0, item1....itemN] [free space] [dataN...data1, data0]
 *
 * The data is separate from the items to get the keys closer together
 * during searches.
 */
103 104 105 106 107 108 109 110 111
#define LEAF_DATA_SIZE (CTREE_BLOCKSIZE - sizeof(struct header))
struct leaf {
	struct header header;
	union {
		struct item items[LEAF_DATA_SIZE/sizeof(struct item)];
		u8 data[CTREE_BLOCKSIZE-sizeof(struct header)];
	};
} __attribute__ ((__packed__));

112 113 114 115
/*
 * all non-leaf blocks are nodes, they hold only keys and pointers to
 * other blocks
 */
116 117 118 119 120 121
struct node {
	struct header header;
	struct key keys[NODEPTRS_PER_BLOCK];
	u64 blockptrs[NODEPTRS_PER_BLOCK];
} __attribute__ ((__packed__));

122 123 124 125
/*
 * items in the extent btree are used to record the objectid of the
 * owner of the block and the number of references
 */
126 127 128 129 130
struct extent_item {
	u32 refs;
	u64 owner;
} __attribute__ ((__packed__));

131 132 133 134 135 136 137 138
/*
 * ctree_paths remember the path taken from the root down to the leaf.
 * level 0 is always the leaf, and nodes[1...MAX_LEVEL] will point
 * to any other levels that are present.
 *
 * The slots array records the index of the item or block pointer
 * used while walking the tree.
 */
139 140 141 142
struct ctree_path {
	struct tree_buffer *nodes[MAX_LEVEL];
	int slots[MAX_LEVEL];
};
C
Chris Mason 已提交
143

144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
static inline u64 btrfs_header_blocknr(struct header *h)
{
	return h->blocknr;
}

static inline void btrfs_set_header_blocknr(struct header *h, u64 blocknr)
{
	h->blocknr = blocknr;
}

static inline u64 btrfs_header_parentid(struct header *h)
{
	return h->parentid;
}

static inline void btrfs_set_header_parentid(struct header *h, u64 parentid)
{
	h->parentid = parentid;
}

static inline u32 btrfs_header_nritems(struct header *h)
{
	return h->nritems;
}

static inline void btrfs_set_header_nritems(struct header *h, u32 val)
{
	h->nritems = val;
}

static inline u32 btrfs_header_flags(struct header *h)
{
	return h->flags;
}

static inline void btrfs_set_header_flags(struct header *h, u32 val)
{
	h->flags = val;
}

static inline int btrfs_header_level(struct header *h)
{
	return btrfs_header_flags(h) & (MAX_LEVEL - 1);
}

static inline void btrfs_set_header_level(struct header *h, int level)
{
	u32 flags;
	BUG_ON(level > MAX_LEVEL);
	flags = btrfs_header_flags(h) & ~(MAX_LEVEL - 1);
	btrfs_set_header_flags(h, flags | level);
}

static inline int btrfs_is_leaf(struct node *n)
{
	return (btrfs_header_level(&n->header) == 0);
}

C
Chris Mason 已提交
202
struct tree_buffer *alloc_free_block(struct ctree_root *root);
C
Chris Mason 已提交
203
int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf);
C
Chris Mason 已提交
204
int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks);
C
Chris Mason 已提交
205
int search_slot(struct ctree_root *root, struct key *key, struct ctree_path *p, int ins_len, int cow);
C
Chris Mason 已提交
206 207 208 209 210 211
void release_path(struct ctree_root *root, struct ctree_path *p);
void init_path(struct ctree_path *p);
int del_item(struct ctree_root *root, struct ctree_path *path);
int insert_item(struct ctree_root *root, struct key *key, void *data, int data_size);
int next_leaf(struct ctree_root *root, struct ctree_path *path);
int leaf_free_space(struct leaf *leaf);
212 213
int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap);
int btrfs_finish_extent_commit(struct ctree_root *root);
214
#endif