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

4
#include "list.h"
C
Chris Mason 已提交
5
#include "kerncompat.h"
6

7
#define CTREE_BLOCKSIZE 1024
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.
C
Chris Mason 已提交
18 19 20 21
 *
 * btrfs_disk_key is in disk byte order.  struct btrfs_key is always
 * in cpu native order.  Otherwise they are identical and their sizes
 * should be the same (ie both packed)
22
 */
C
Chris Mason 已提交
23 24 25 26 27 28 29
struct btrfs_disk_key {
	__le64 objectid;
	__le32 flags;
	__le64 offset;
} __attribute__ ((__packed__));

struct btrfs_key {
30 31 32 33 34
	u64 objectid;
	u32 flags;
	u64 offset;
} __attribute__ ((__packed__));

35 36 37
/*
 * every tree block (leaf or node) starts with this header.
 */
38 39 40 41 42 43 44 45
struct btrfs_header {
	__le64 fsid[2]; /* FS specific uuid */
	__le64 blocknr; /* which block this node is supposed to live in */
	__le64 parentid; /* objectid of the tree root */
	__le32 csum;
	__le32 ham;
	__le16 nritems;
	__le16 flags;
46
	/* generation flags to be added */
47 48
} __attribute__ ((__packed__));

49
#define MAX_LEVEL 8
50
#define NODEPTRS_PER_BLOCK ((CTREE_BLOCKSIZE - sizeof(struct btrfs_header)) / \
C
Chris Mason 已提交
51
			    (sizeof(struct btrfs_disk_key) + sizeof(u64)))
52 53

struct tree_buffer;
54

55 56 57 58 59
/*
 * 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.
 */
60 61
struct ctree_root {
	struct tree_buffer *node;
62
	struct tree_buffer *commit_root;
63
	struct ctree_root *extent_root;
C
Chris Mason 已提交
64 65
	struct btrfs_key current_insert;
	struct btrfs_key last_insert;
66 67
	int fp;
	struct radix_tree_root cache_radix;
68
	struct radix_tree_root pinned_radix;
69 70 71
	struct list_head trans;
	struct list_head cache;
	int cache_size;
72 73
};

74 75 76
/*
 * describes a tree on disk
 */
77 78 79 80
struct ctree_root_info {
	u64 fsid[2]; /* FS specific uuid */
	u64 blocknr; /* blocknr of this block */
	u64 objectid; /* inode number of this root */
81
	u64 tree_root; /* the tree root block */
82 83 84 85 86
	u32 csum;
	u32 ham;
	u64 snapuuid[2]; /* root specific uuid */
} __attribute__ ((__packed__));

87 88 89 90
/*
 * the super block basically lists the main trees of the FS
 * it currently lacks any block count etc etc
 */
C
Chris Mason 已提交
91 92 93 94 95
struct ctree_super_block {
	struct ctree_root_info root_info;
	struct ctree_root_info extent_info;
} __attribute__ ((__packed__));

96 97 98 99 100
/*
 * 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)
 */
101
struct item {
C
Chris Mason 已提交
102
	struct btrfs_disk_key key;
103 104 105 106
	u16 offset;
	u16 size;
} __attribute__ ((__packed__));

107 108 109 110 111 112 113
/*
 * 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.
 */
114
#define LEAF_DATA_SIZE (CTREE_BLOCKSIZE - sizeof(struct btrfs_header))
115
struct leaf {
116
	struct btrfs_header header;
117 118
	union {
		struct item items[LEAF_DATA_SIZE/sizeof(struct item)];
119
		u8 data[CTREE_BLOCKSIZE-sizeof(struct btrfs_header)];
120 121 122
	};
} __attribute__ ((__packed__));

123 124 125 126
/*
 * all non-leaf blocks are nodes, they hold only keys and pointers to
 * other blocks
 */
127
struct node {
128
	struct btrfs_header header;
C
Chris Mason 已提交
129
	struct btrfs_disk_key keys[NODEPTRS_PER_BLOCK];
130 131 132
	u64 blockptrs[NODEPTRS_PER_BLOCK];
} __attribute__ ((__packed__));

133 134 135 136
/*
 * items in the extent btree are used to record the objectid of the
 * owner of the block and the number of references
 */
137 138 139 140 141
struct extent_item {
	u32 refs;
	u64 owner;
} __attribute__ ((__packed__));

142 143 144 145 146 147 148 149
/*
 * 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.
 */
150 151 152 153
struct ctree_path {
	struct tree_buffer *nodes[MAX_LEVEL];
	int slots[MAX_LEVEL];
};
C
Chris Mason 已提交
154

C
Chris Mason 已提交
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 202 203
static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu,
					 struct btrfs_disk_key *disk)
{
	cpu->offset = le64_to_cpu(disk->offset);
	cpu->flags = le32_to_cpu(disk->flags);
	cpu->objectid = le64_to_cpu(disk->objectid);
}

static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk,
					 struct btrfs_key *cpu)
{
	disk->offset = cpu_to_le64(cpu->offset);
	disk->flags = cpu_to_le32(cpu->flags);
	disk->objectid = cpu_to_le64(cpu->objectid);
}

static inline u64 btrfs_key_objectid(struct btrfs_disk_key *disk)
{
	return le64_to_cpu(disk->objectid);
}

static inline void btrfs_set_key_objectid(struct btrfs_disk_key *disk,
					  u64 val)
{
	disk->objectid = cpu_to_le64(val);
}

static inline u64 btrfs_key_offset(struct btrfs_disk_key *disk)
{
	return le64_to_cpu(disk->offset);
}

static inline void btrfs_set_key_offset(struct btrfs_disk_key *disk,
					  u64 val)
{
	disk->offset = cpu_to_le64(val);
}

static inline u32 btrfs_key_flags(struct btrfs_disk_key *disk)
{
	return le32_to_cpu(disk->flags);
}

static inline void btrfs_set_key_flags(struct btrfs_disk_key *disk,
					  u32 val)
{
	disk->flags = cpu_to_le32(val);
}

204
static inline u64 btrfs_header_blocknr(struct btrfs_header *h)
205
{
206
	return le64_to_cpu(h->blocknr);
207 208
}

209
static inline void btrfs_set_header_blocknr(struct btrfs_header *h, u64 blocknr)
210
{
211
	h->blocknr = cpu_to_le64(blocknr);
212 213
}

214
static inline u64 btrfs_header_parentid(struct btrfs_header *h)
215
{
216
	return le64_to_cpu(h->parentid);
217 218
}

219 220
static inline void btrfs_set_header_parentid(struct btrfs_header *h,
					     u64 parentid)
221
{
222
	h->parentid = cpu_to_le64(parentid);
223 224
}

225
static inline u16 btrfs_header_nritems(struct btrfs_header *h)
226
{
227
	return le16_to_cpu(h->nritems);
228 229
}

230
static inline void btrfs_set_header_nritems(struct btrfs_header *h, u16 val)
231
{
232
	h->nritems = cpu_to_le16(val);
233 234
}

235
static inline u16 btrfs_header_flags(struct btrfs_header *h)
236
{
237
	return le16_to_cpu(h->flags);
238 239
}

240
static inline void btrfs_set_header_flags(struct btrfs_header *h, u16 val)
241
{
242
	h->flags = cpu_to_le16(val);
243 244
}

245
static inline int btrfs_header_level(struct btrfs_header *h)
246 247 248 249
{
	return btrfs_header_flags(h) & (MAX_LEVEL - 1);
}

250
static inline void btrfs_set_header_level(struct btrfs_header *h, int level)
251
{
252
	u16 flags;
253 254 255 256 257 258 259 260 261 262
	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 已提交
263
struct tree_buffer *alloc_free_block(struct ctree_root *root);
C
Chris Mason 已提交
264
int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf);
C
Chris Mason 已提交
265
int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks);
C
Chris Mason 已提交
266 267
int search_slot(struct ctree_root *root, struct btrfs_key *key,
		struct ctree_path *p, int ins_len, int cow);
C
Chris Mason 已提交
268 269 270
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);
C
Chris Mason 已提交
271 272
int insert_item(struct ctree_root *root, struct btrfs_key *key,
		void *data, int data_size);
C
Chris Mason 已提交
273 274
int next_leaf(struct ctree_root *root, struct ctree_path *path);
int leaf_free_space(struct leaf *leaf);
275 276
int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap);
int btrfs_finish_extent_commit(struct ctree_root *root);
277
#endif