ctree.c 47.6 KB
Newer Older
1
#include <linux/module.h>
2 3
#include "ctree.h"
#include "disk-io.h"
4
#include "transaction.h"
5

6 7 8
static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_path *path, int level);
static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
9 10
		      *root, struct btrfs_key *ins_key,
		      struct btrfs_path *path, int data_size);
11
static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
12
			  *root, struct buffer_head *dst, struct buffer_head
13 14
			  *src);
static int balance_node_right(struct btrfs_trans_handle *trans, struct
C
Chris Mason 已提交
15 16
			      btrfs_root *root, struct buffer_head *dst_buf,
			      struct buffer_head *src_buf);
17 18
static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path, int level, int slot);
19

C
Chris Mason 已提交
20
inline void btrfs_init_path(struct btrfs_path *p)
C
Chris Mason 已提交
21
{
C
Chris Mason 已提交
22
	memset(p, 0, sizeof(*p));
C
Chris Mason 已提交
23 24
}

C
Chris Mason 已提交
25
struct btrfs_path *btrfs_alloc_path(void)
C
Chris Mason 已提交
26
{
C
Chris Mason 已提交
27 28 29 30 31
	struct btrfs_path *path;
	path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
	if (path)
		btrfs_init_path(path);
	return path;
C
Chris Mason 已提交
32 33
}

C
Chris Mason 已提交
34
void btrfs_free_path(struct btrfs_path *p)
35
{
C
Chris Mason 已提交
36 37
	btrfs_release_path(NULL, p);
	kmem_cache_free(btrfs_path_cachep, p);
38 39
}

C
Chris Mason 已提交
40
void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
41 42
{
	int i;
C
Chris Mason 已提交
43
	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
44 45
		if (!p->nodes[i])
			break;
C
Chris Mason 已提交
46
		btrfs_block_release(root, p->nodes[i]);
47
	}
C
Chris Mason 已提交
48
	memset(p, 0, sizeof(*p));
49 50
}

51
static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
52 53
			   *root, struct buffer_head *buf, struct buffer_head
			   *parent, int parent_slot, struct buffer_head
54
			   **cow_ret)
C
Chris Mason 已提交
55
{
C
Chris Mason 已提交
56 57
	struct buffer_head *cow;
	struct btrfs_node *cow_node;
C
Chris Mason 已提交
58

59 60
	if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
				    trans->transid) {
C
Chris Mason 已提交
61 62 63
		*cow_ret = buf;
		return 0;
	}
64
	cow = btrfs_alloc_free_block(trans, root);
C
Chris Mason 已提交
65
	cow_node = btrfs_buffer_node(cow);
C
Chris Mason 已提交
66 67
	if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
		WARN_ON(1);
C
Chris Mason 已提交
68
	memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
69
	btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow));
70
	btrfs_set_header_generation(&cow_node->header, trans->transid);
71
	btrfs_inc_ref(trans, root, buf);
C
Chris Mason 已提交
72 73
	if (buf == root->node) {
		root->node = cow;
C
Chris Mason 已提交
74
		get_bh(cow);
C
Chris Mason 已提交
75
		if (buf != root->commit_root) {
76
			btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
C
Chris Mason 已提交
77
		}
C
Chris Mason 已提交
78
		btrfs_block_release(root, buf);
C
Chris Mason 已提交
79
	} else {
C
Chris Mason 已提交
80
		btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
81
					bh_blocknr(cow));
C
Chris Mason 已提交
82
		btrfs_mark_buffer_dirty(parent);
83
		btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
C
Chris Mason 已提交
84
	}
C
Chris Mason 已提交
85
	btrfs_block_release(root, buf);
C
Chris Mason 已提交
86
	mark_buffer_dirty(cow);
C
Chris Mason 已提交
87
	*cow_ret = cow;
C
Chris Mason 已提交
88 89 90
	return 0;
}

C
Chris Mason 已提交
91 92 93 94 95
/*
 * The leaf data grows from end-to-front in the node.
 * this returns the address of the start of the last item,
 * which is the stop of the leaf data stack
 */
C
Chris Mason 已提交
96 97
static inline unsigned int leaf_data_end(struct btrfs_root *root,
					 struct btrfs_leaf *leaf)
98
{
99
	u32 nr = btrfs_header_nritems(&leaf->header);
100
	if (nr == 0)
C
Chris Mason 已提交
101
		return BTRFS_LEAF_DATA_SIZE(root);
C
Chris Mason 已提交
102
	return btrfs_item_offset(leaf->items + nr - 1);
103 104
}

C
Chris Mason 已提交
105 106 107
/*
 * compare two keys in a memcmp fashion
 */
C
Chris Mason 已提交
108
static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
109
{
C
Chris Mason 已提交
110 111 112 113 114
	struct btrfs_key k1;

	btrfs_disk_key_to_cpu(&k1, disk);

	if (k1.objectid > k2->objectid)
115
		return 1;
C
Chris Mason 已提交
116
	if (k1.objectid < k2->objectid)
117
		return -1;
118 119 120 121
	if (k1.offset > k2->offset)
		return 1;
	if (k1.offset < k2->offset)
		return -1;
C
Chris Mason 已提交
122 123 124 125
	if (k1.flags > k2->flags)
		return 1;
	if (k1.flags < k2->flags)
		return -1;
126 127
	return 0;
}
C
Chris Mason 已提交
128

C
Chris Mason 已提交
129 130
static int check_node(struct btrfs_root *root, struct btrfs_path *path,
		      int level)
C
Chris Mason 已提交
131 132
{
	int i;
C
Chris Mason 已提交
133
	struct btrfs_node *parent = NULL;
C
Chris Mason 已提交
134
	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
C
Chris Mason 已提交
135
	int parent_slot;
136
	u32 nritems = btrfs_header_nritems(&node->header);
C
Chris Mason 已提交
137 138

	if (path->nodes[level + 1])
C
Chris Mason 已提交
139
		parent = btrfs_buffer_node(path->nodes[level + 1]);
C
Chris Mason 已提交
140
	parent_slot = path->slots[level + 1];
141 142
	BUG_ON(nritems == 0);
	if (parent) {
C
Chris Mason 已提交
143
		struct btrfs_disk_key *parent_key;
C
Chris Mason 已提交
144 145
		parent_key = &parent->ptrs[parent_slot].key;
		BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
C
Chris Mason 已提交
146
			      sizeof(struct btrfs_disk_key)));
147
		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
148
		       btrfs_header_blocknr(&node->header));
C
Chris Mason 已提交
149
	}
C
Chris Mason 已提交
150
	BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
151
	for (i = 0; nritems > 1 && i < nritems - 2; i++) {
C
Chris Mason 已提交
152
		struct btrfs_key cpukey;
C
Chris Mason 已提交
153 154
		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[i + 1].key);
		BUG_ON(comp_keys(&node->ptrs[i].key, &cpukey) >= 0);
C
Chris Mason 已提交
155 156 157 158
	}
	return 0;
}

C
Chris Mason 已提交
159 160
static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
		      int level)
C
Chris Mason 已提交
161 162
{
	int i;
C
Chris Mason 已提交
163
	struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]);
C
Chris Mason 已提交
164
	struct btrfs_node *parent = NULL;
C
Chris Mason 已提交
165
	int parent_slot;
166
	u32 nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
167 168

	if (path->nodes[level + 1])
C
Chris Mason 已提交
169
		parent = btrfs_buffer_node(path->nodes[level + 1]);
C
Chris Mason 已提交
170
	parent_slot = path->slots[level + 1];
C
Chris Mason 已提交
171
	BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
172 173 174 175 176

	if (nritems == 0)
		return 0;

	if (parent) {
C
Chris Mason 已提交
177
		struct btrfs_disk_key *parent_key;
C
Chris Mason 已提交
178
		parent_key = &parent->ptrs[parent_slot].key;
C
Chris Mason 已提交
179
		BUG_ON(memcmp(parent_key, &leaf->items[0].key,
C
Chris Mason 已提交
180
		       sizeof(struct btrfs_disk_key)));
181
		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
182
		       btrfs_header_blocknr(&leaf->header));
C
Chris Mason 已提交
183
	}
184
	for (i = 0; nritems > 1 && i < nritems - 2; i++) {
C
Chris Mason 已提交
185 186
		struct btrfs_key cpukey;
		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[i + 1].key);
C
Chris Mason 已提交
187
		BUG_ON(comp_keys(&leaf->items[i].key,
C
Chris Mason 已提交
188
		                 &cpukey) >= 0);
C
Chris Mason 已提交
189 190
		BUG_ON(btrfs_item_offset(leaf->items + i) !=
			btrfs_item_end(leaf->items + i + 1));
C
Chris Mason 已提交
191
		if (i == 0) {
C
Chris Mason 已提交
192 193
			BUG_ON(btrfs_item_offset(leaf->items + i) +
			       btrfs_item_size(leaf->items + i) !=
C
Chris Mason 已提交
194
			       BTRFS_LEAF_DATA_SIZE(root));
C
Chris Mason 已提交
195 196 197 198 199
		}
	}
	return 0;
}

C
Chris Mason 已提交
200 201
static int check_block(struct btrfs_root *root, struct btrfs_path *path,
			int level)
C
Chris Mason 已提交
202
{
C
Chris Mason 已提交
203 204 205 206
	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
	if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid,
		   sizeof(node->header.fsid)))
		BUG();
C
Chris Mason 已提交
207
	if (level == 0)
C
Chris Mason 已提交
208 209
		return check_leaf(root, path, level);
	return check_node(root, path, level);
C
Chris Mason 已提交
210 211
}

C
Chris Mason 已提交
212 213 214 215 216 217 218 219 220
/*
 * search for key in the array p.  items p are item_size apart
 * and there are 'max' items in p
 * the slot in the array is returned via slot, and it points to
 * the place where you would insert key if it is not found in
 * the array.
 *
 * slot may point to max if the key is bigger than all of the keys
 */
C
Chris Mason 已提交
221
static int generic_bin_search(char *p, int item_size, struct btrfs_key *key,
222 223 224 225 226 227
		       int max, int *slot)
{
	int low = 0;
	int high = max;
	int mid;
	int ret;
C
Chris Mason 已提交
228
	struct btrfs_disk_key *tmp;
229 230 231

	while(low < high) {
		mid = (low + high) / 2;
C
Chris Mason 已提交
232
		tmp = (struct btrfs_disk_key *)(p + mid * item_size);
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
		ret = comp_keys(tmp, key);

		if (ret < 0)
			low = mid + 1;
		else if (ret > 0)
			high = mid;
		else {
			*slot = mid;
			return 0;
		}
	}
	*slot = low;
	return 1;
}

C
Chris Mason 已提交
248 249 250 251
/*
 * simple bin_search frontend that does the right thing for
 * leaves vs nodes
 */
C
Chris Mason 已提交
252
static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
253
{
254
	if (btrfs_is_leaf(c)) {
C
Chris Mason 已提交
255
		struct btrfs_leaf *l = (struct btrfs_leaf *)c;
C
Chris Mason 已提交
256 257
		return generic_bin_search((void *)l->items,
					  sizeof(struct btrfs_item),
258 259
					  key, btrfs_header_nritems(&c->header),
					  slot);
260
	} else {
C
Chris Mason 已提交
261 262
		return generic_bin_search((void *)c->ptrs,
					  sizeof(struct btrfs_key_ptr),
263 264
					  key, btrfs_header_nritems(&c->header),
					  slot);
265 266 267 268
	}
	return -1;
}

C
Chris Mason 已提交
269 270
static struct buffer_head *read_node_slot(struct btrfs_root *root,
				   struct buffer_head *parent_buf,
271 272
				   int slot)
{
C
Chris Mason 已提交
273
	struct btrfs_node *node = btrfs_buffer_node(parent_buf);
274 275
	if (slot < 0)
		return NULL;
276
	if (slot >= btrfs_header_nritems(&node->header))
277
		return NULL;
278
	return read_tree_block(root, btrfs_node_blockptr(node, slot));
279 280
}

281 282
static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
			 *root, struct btrfs_path *path, int level)
283
{
C
Chris Mason 已提交
284 285 286 287
	struct buffer_head *right_buf;
	struct buffer_head *mid_buf;
	struct buffer_head *left_buf;
	struct buffer_head *parent_buf = NULL;
C
Chris Mason 已提交
288 289 290 291
	struct btrfs_node *right = NULL;
	struct btrfs_node *mid;
	struct btrfs_node *left = NULL;
	struct btrfs_node *parent = NULL;
292 293 294 295
	int ret = 0;
	int wret;
	int pslot;
	int orig_slot = path->slots[level];
296
	u64 orig_ptr;
297 298 299 300 301

	if (level == 0)
		return 0;

	mid_buf = path->nodes[level];
C
Chris Mason 已提交
302
	mid = btrfs_buffer_node(mid_buf);
303
	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
304

C
Chris Mason 已提交
305
	if (level < BTRFS_MAX_LEVEL - 1)
306 307 308
		parent_buf = path->nodes[level + 1];
	pslot = path->slots[level + 1];

C
Chris Mason 已提交
309 310 311 312
	/*
	 * deal with the case where there is only one pointer in the root
	 * by promoting the node below to a root
	 */
313
	if (!parent_buf) {
C
Chris Mason 已提交
314
		struct buffer_head *child;
315
		u64 blocknr = bh_blocknr(mid_buf);
316

317
		if (btrfs_header_nritems(&mid->header) != 1)
318 319 320 321 322 323 324
			return 0;

		/* promote the child to a root */
		child = read_node_slot(root, mid_buf, 0);
		BUG_ON(!child);
		root->node = child;
		path->nodes[level] = NULL;
C
Chris Mason 已提交
325 326
		clean_tree_block(trans, root, mid_buf);
		wait_on_buffer(mid_buf);
327
		/* once for the path */
C
Chris Mason 已提交
328
		btrfs_block_release(root, mid_buf);
329
		/* once for the root ptr */
C
Chris Mason 已提交
330
		btrfs_block_release(root, mid_buf);
331
		return btrfs_free_extent(trans, root, blocknr, 1, 1);
332
	}
C
Chris Mason 已提交
333
	parent = btrfs_buffer_node(parent_buf);
334

C
Chris Mason 已提交
335 336
	if (btrfs_header_nritems(&mid->header) >
	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
337 338 339 340
		return 0;

	left_buf = read_node_slot(root, parent_buf, pslot - 1);
	right_buf = read_node_slot(root, parent_buf, pslot + 1);
341 342

	/* first, try to make some room in the middle buffer */
343
	if (left_buf) {
344 345
		btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1,
				&left_buf);
C
Chris Mason 已提交
346
		left = btrfs_buffer_node(left_buf);
347
		orig_slot += btrfs_header_nritems(&left->header);
348
		wret = push_node_left(trans, root, left_buf, mid_buf);
349 350
		if (wret < 0)
			ret = wret;
351
	}
352 353 354 355

	/*
	 * then try to empty the right most buffer into the middle
	 */
356
	if (right_buf) {
357 358
		btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1,
				&right_buf);
C
Chris Mason 已提交
359
		right = btrfs_buffer_node(right_buf);
360
		wret = push_node_left(trans, root, mid_buf, right_buf);
361 362
		if (wret < 0)
			ret = wret;
363
		if (btrfs_header_nritems(&right->header) == 0) {
364
			u64 blocknr = bh_blocknr(right_buf);
365
			clean_tree_block(trans, root, right_buf);
C
Chris Mason 已提交
366 367
			wait_on_buffer(right_buf);
			btrfs_block_release(root, right_buf);
368 369
			right_buf = NULL;
			right = NULL;
370 371
			wret = del_ptr(trans, root, path, level + 1, pslot +
				       1);
372 373
			if (wret)
				ret = wret;
374
			wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
375 376 377
			if (wret)
				ret = wret;
		} else {
C
Chris Mason 已提交
378 379 380 381 382
			btrfs_memcpy(root, parent,
				     &parent->ptrs[pslot + 1].key,
				     &right->ptrs[0].key,
				     sizeof(struct btrfs_disk_key));
			btrfs_mark_buffer_dirty(parent_buf);
383 384
		}
	}
385
	if (btrfs_header_nritems(&mid->header) == 1) {
386 387 388 389 390 391 392 393 394 395
		/*
		 * we're not allowed to leave a node with one item in the
		 * tree during a delete.  A deletion from lower in the tree
		 * could try to delete the only pointer in this node.
		 * So, pull some keys from the left.
		 * There has to be a left pointer at this point because
		 * otherwise we would have pulled some pointers from the
		 * right
		 */
		BUG_ON(!left_buf);
396
		wret = balance_node_right(trans, root, mid_buf, left_buf);
397 398 399 400
		if (wret < 0)
			ret = wret;
		BUG_ON(wret == 1);
	}
401
	if (btrfs_header_nritems(&mid->header) == 0) {
402
		/* we've managed to empty the middle node, drop it */
403
		u64 blocknr = bh_blocknr(mid_buf);
404
		clean_tree_block(trans, root, mid_buf);
C
Chris Mason 已提交
405 406
		wait_on_buffer(mid_buf);
		btrfs_block_release(root, mid_buf);
407 408
		mid_buf = NULL;
		mid = NULL;
409
		wret = del_ptr(trans, root, path, level + 1, pslot);
410 411
		if (wret)
			ret = wret;
412
		wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
413 414
		if (wret)
			ret = wret;
415 416
	} else {
		/* update the parent key to reflect our changes */
C
Chris Mason 已提交
417 418 419 420
		btrfs_memcpy(root, parent,
			     &parent->ptrs[pslot].key, &mid->ptrs[0].key,
			     sizeof(struct btrfs_disk_key));
		btrfs_mark_buffer_dirty(parent_buf);
421
	}
422

423
	/* update the path */
424
	if (left_buf) {
425
		if (btrfs_header_nritems(&left->header) > orig_slot) {
C
Chris Mason 已提交
426
			get_bh(left_buf);
427 428 429 430
			path->nodes[level] = left_buf;
			path->slots[level + 1] -= 1;
			path->slots[level] = orig_slot;
			if (mid_buf)
C
Chris Mason 已提交
431
				btrfs_block_release(root, mid_buf);
432
		} else {
433
			orig_slot -= btrfs_header_nritems(&left->header);
434 435 436
			path->slots[level] = orig_slot;
		}
	}
437
	/* double check we haven't messed things up */
C
Chris Mason 已提交
438
	check_block(root, path, level);
C
Chris Mason 已提交
439 440 441
	if (orig_ptr !=
	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
				path->slots[level]))
442
		BUG();
443 444

	if (right_buf)
C
Chris Mason 已提交
445
		btrfs_block_release(root, right_buf);
446
	if (left_buf)
C
Chris Mason 已提交
447
		btrfs_block_release(root, left_buf);
448 449 450
	return ret;
}

C
Chris Mason 已提交
451 452 453 454 455 456
/*
 * look for key in the tree.  path is filled in with nodes along the way
 * if key is found, we return zero and you can find the item in the leaf
 * level of the path (level 0)
 *
 * If the key isn't found, the path points to the slot where it should
C
Chris Mason 已提交
457 458
 * be inserted, and 1 is returned.  If there are other errors during the
 * search a negative error number is returned.
C
Chris Mason 已提交
459 460 461 462
 *
 * if ins_len > 0, nodes and leaves will be split as we walk down the
 * tree.  if ins_len < 0, nodes will be merged as we walk down the tree (if
 * possible)
C
Chris Mason 已提交
463
 */
464 465 466
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_key *key, struct btrfs_path *p, int
		      ins_len, int cow)
467
{
C
Chris Mason 已提交
468 469
	struct buffer_head *b;
	struct buffer_head *cow_buf;
C
Chris Mason 已提交
470
	struct btrfs_node *c;
471 472 473
	int slot;
	int ret;
	int level;
C
Chris Mason 已提交
474

C
Chris Mason 已提交
475 476
	WARN_ON(p->nodes[0] != NULL);
	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
477 478
again:
	b = root->node;
C
Chris Mason 已提交
479
	get_bh(b);
480
	while (b) {
C
Chris Mason 已提交
481 482
		c = btrfs_buffer_node(b);
		level = btrfs_header_level(&c->header);
C
Chris Mason 已提交
483 484
		if (cow) {
			int wret;
C
Chris Mason 已提交
485 486 487
			wret = btrfs_cow_block(trans, root, b,
					       p->nodes[level + 1],
					       p->slots[level + 1],
488
					       &cow_buf);
C
Chris Mason 已提交
489
			b = cow_buf;
C
Chris Mason 已提交
490
			c = btrfs_buffer_node(b);
C
Chris Mason 已提交
491 492
		}
		BUG_ON(!cow && ins_len);
C
Chris Mason 已提交
493 494 495
		if (level != btrfs_header_level(&c->header))
			WARN_ON(1);
		level = btrfs_header_level(&c->header);
496
		p->nodes[level] = b;
C
Chris Mason 已提交
497
		ret = check_block(root, p, level);
C
Chris Mason 已提交
498 499
		if (ret)
			return -1;
500
		ret = bin_search(c, key, &slot);
501
		if (!btrfs_is_leaf(c)) {
502 503 504
			if (ret && slot > 0)
				slot -= 1;
			p->slots[level] = slot;
505 506
			if (ins_len > 0 && btrfs_header_nritems(&c->header) >=
			    BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
507
				int sret = split_node(trans, root, p, level);
C
Chris Mason 已提交
508 509 510 511
				BUG_ON(sret > 0);
				if (sret)
					return sret;
				b = p->nodes[level];
C
Chris Mason 已提交
512
				c = btrfs_buffer_node(b);
C
Chris Mason 已提交
513
				slot = p->slots[level];
514
			} else if (ins_len < 0) {
515 516
				int sret = balance_level(trans, root, p,
							 level);
517 518 519 520 521
				if (sret)
					return sret;
				b = p->nodes[level];
				if (!b)
					goto again;
C
Chris Mason 已提交
522
				c = btrfs_buffer_node(b);
523
				slot = p->slots[level];
524
				BUG_ON(btrfs_header_nritems(&c->header) == 1);
C
Chris Mason 已提交
525
			}
526
			b = read_tree_block(root, btrfs_node_blockptr(c, slot));
527
		} else {
C
Chris Mason 已提交
528
			struct btrfs_leaf *l = (struct btrfs_leaf *)c;
529
			p->slots[level] = slot;
C
Chris Mason 已提交
530
			if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
C
Chris Mason 已提交
531
			    sizeof(struct btrfs_item) + ins_len) {
532 533
				int sret = split_leaf(trans, root, key,
						      p, ins_len);
C
Chris Mason 已提交
534 535 536 537
				BUG_ON(sret > 0);
				if (sret)
					return sret;
			}
538 539 540
			return ret;
		}
	}
C
Chris Mason 已提交
541
	return 1;
542 543
}

C
Chris Mason 已提交
544 545 546 547 548 549
/*
 * adjust the pointers going up the tree, starting at level
 * making sure the right key of each node is points to 'key'.
 * This is used after shifting pointers to the left, so it stops
 * fixing up pointers when a given leaf/node is not in slot 0 of the
 * higher levels
C
Chris Mason 已提交
550 551 552
 *
 * If this fails to write a tree block, it returns -1, but continues
 * fixing up the blocks in ram so the tree is consistent.
C
Chris Mason 已提交
553
 */
554 555 556
static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
			  *root, struct btrfs_path *path, struct btrfs_disk_key
			  *key, int level)
557 558
{
	int i;
C
Chris Mason 已提交
559
	int ret = 0;
C
Chris Mason 已提交
560 561
	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
		struct btrfs_node *t;
562
		int tslot = path->slots[i];
563
		if (!path->nodes[i])
564
			break;
C
Chris Mason 已提交
565
		t = btrfs_buffer_node(path->nodes[i]);
C
Chris Mason 已提交
566 567
		btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key));
		btrfs_mark_buffer_dirty(path->nodes[i]);
568 569 570
		if (tslot != 0)
			break;
	}
C
Chris Mason 已提交
571
	return ret;
572 573
}

C
Chris Mason 已提交
574 575
/*
 * try to push data from one node into the next node left in the
576
 * tree.
C
Chris Mason 已提交
577 578 579
 *
 * returns 0 if some ptrs were pushed left, < 0 if there was some horrible
 * error, and > 0 if there was no room in the left hand block.
C
Chris Mason 已提交
580
 */
581
static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
582 583
			  *root, struct buffer_head *dst_buf, struct
			  buffer_head *src_buf)
584
{
C
Chris Mason 已提交
585 586
	struct btrfs_node *src = btrfs_buffer_node(src_buf);
	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
587
	int push_items = 0;
588 589
	int src_nritems;
	int dst_nritems;
C
Chris Mason 已提交
590
	int ret = 0;
591

592 593
	src_nritems = btrfs_header_nritems(&src->header);
	dst_nritems = btrfs_header_nritems(&dst->header);
C
Chris Mason 已提交
594
	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
595
	if (push_items <= 0) {
596
		return 1;
597
	}
598

599
	if (src_nritems < push_items)
600 601
		push_items = src_nritems;

C
Chris Mason 已提交
602 603
	btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs,
		     push_items * sizeof(struct btrfs_key_ptr));
604
	if (push_items < src_nritems) {
C
Chris Mason 已提交
605
		btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items,
C
Chris Mason 已提交
606
			(src_nritems - push_items) *
C
Chris Mason 已提交
607
			sizeof(struct btrfs_key_ptr));
608
	}
609 610
	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
C
Chris Mason 已提交
611 612
	btrfs_mark_buffer_dirty(src_buf);
	btrfs_mark_buffer_dirty(dst_buf);
613 614 615 616 617 618 619 620 621 622 623 624
	return ret;
}

/*
 * try to push data from one node into the next node right in the
 * tree.
 *
 * returns 0 if some ptrs were pushed, < 0 if there was some horrible
 * error, and > 0 if there was no room in the right hand block.
 *
 * this will  only push up to 1/2 the contents of the left node over
 */
625
static int balance_node_right(struct btrfs_trans_handle *trans, struct
C
Chris Mason 已提交
626 627
			      btrfs_root *root, struct buffer_head *dst_buf,
			      struct buffer_head *src_buf)
628
{
C
Chris Mason 已提交
629 630
	struct btrfs_node *src = btrfs_buffer_node(src_buf);
	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
631 632 633 634 635 636
	int push_items = 0;
	int max_push;
	int src_nritems;
	int dst_nritems;
	int ret = 0;

637 638
	src_nritems = btrfs_header_nritems(&src->header);
	dst_nritems = btrfs_header_nritems(&dst->header);
C
Chris Mason 已提交
639
	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
640 641 642 643 644 645 646 647 648 649 650
	if (push_items <= 0) {
		return 1;
	}

	max_push = src_nritems / 2 + 1;
	/* don't try to empty the node */
	if (max_push > src_nritems)
		return 1;
	if (max_push < push_items)
		push_items = max_push;

C
Chris Mason 已提交
651 652 653 654 655 656
	btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs,
		      dst_nritems * sizeof(struct btrfs_key_ptr));

	btrfs_memcpy(root, dst, dst->ptrs,
		     src->ptrs + src_nritems - push_items,
		     push_items * sizeof(struct btrfs_key_ptr));
657

658 659
	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
660

C
Chris Mason 已提交
661 662
	btrfs_mark_buffer_dirty(src_buf);
	btrfs_mark_buffer_dirty(dst_buf);
C
Chris Mason 已提交
663
	return ret;
664 665
}

C
Chris Mason 已提交
666 667 668 669
/*
 * helper function to insert a new root level in the tree.
 * A new node is allocated, and a single item is inserted to
 * point to the existing root
C
Chris Mason 已提交
670 671
 *
 * returns zero on success or < 0 on failure.
C
Chris Mason 已提交
672
 */
673 674
static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
			   *root, struct btrfs_path *path, int level)
C
Chris Mason 已提交
675
{
C
Chris Mason 已提交
676
	struct buffer_head *t;
C
Chris Mason 已提交
677 678
	struct btrfs_node *lower;
	struct btrfs_node *c;
C
Chris Mason 已提交
679
	struct btrfs_disk_key *lower_key;
C
Chris Mason 已提交
680 681 682 683

	BUG_ON(path->nodes[level]);
	BUG_ON(path->nodes[level-1] != root->node);

684
	t = btrfs_alloc_free_block(trans, root);
C
Chris Mason 已提交
685
	c = btrfs_buffer_node(t);
C
Chris Mason 已提交
686
	memset(c, 0, root->blocksize);
687 688
	btrfs_set_header_nritems(&c->header, 1);
	btrfs_set_header_level(&c->header, level);
689
	btrfs_set_header_blocknr(&c->header, bh_blocknr(t));
690
	btrfs_set_header_generation(&c->header, trans->transid);
C
Chris Mason 已提交
691
	lower = btrfs_buffer_node(path->nodes[level-1]);
C
Chris Mason 已提交
692 693
	memcpy(c->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(c->header.fsid));
694
	if (btrfs_is_leaf(lower))
C
Chris Mason 已提交
695
		lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
C
Chris Mason 已提交
696
	else
C
Chris Mason 已提交
697
		lower_key = &lower->ptrs[0].key;
C
Chris Mason 已提交
698 699
	btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key,
		     sizeof(struct btrfs_disk_key));
700
	btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1]));
701

C
Chris Mason 已提交
702
	btrfs_mark_buffer_dirty(t);
703

C
Chris Mason 已提交
704
	/* the super has an extra ref to root->node */
C
Chris Mason 已提交
705
	btrfs_block_release(root, root->node);
C
Chris Mason 已提交
706
	root->node = t;
C
Chris Mason 已提交
707
	get_bh(t);
C
Chris Mason 已提交
708 709 710 711 712
	path->nodes[level] = t;
	path->slots[level] = 0;
	return 0;
}

C
Chris Mason 已提交
713 714 715
/*
 * worker function to insert a single pointer in a node.
 * the node should have enough room for the pointer already
C
Chris Mason 已提交
716
 *
C
Chris Mason 已提交
717 718
 * slot and level indicate where you want the key to go, and
 * blocknr is the block the key points to.
C
Chris Mason 已提交
719 720
 *
 * returns zero on success and < 0 on any error
C
Chris Mason 已提交
721
 */
722 723 724
static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_path *path, struct btrfs_disk_key
		      *key, u64 blocknr, int slot, int level)
C
Chris Mason 已提交
725
{
C
Chris Mason 已提交
726
	struct btrfs_node *lower;
C
Chris Mason 已提交
727
	int nritems;
C
Chris Mason 已提交
728 729

	BUG_ON(!path->nodes[level]);
C
Chris Mason 已提交
730
	lower = btrfs_buffer_node(path->nodes[level]);
731
	nritems = btrfs_header_nritems(&lower->header);
C
Chris Mason 已提交
732 733
	if (slot > nritems)
		BUG();
C
Chris Mason 已提交
734
	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
C
Chris Mason 已提交
735 736
		BUG();
	if (slot != nritems) {
C
Chris Mason 已提交
737 738 739
		btrfs_memmove(root, lower, lower->ptrs + slot + 1,
			      lower->ptrs + slot,
			      (nritems - slot) * sizeof(struct btrfs_key_ptr));
C
Chris Mason 已提交
740
	}
C
Chris Mason 已提交
741 742
	btrfs_memcpy(root, lower, &lower->ptrs[slot].key,
		     key, sizeof(struct btrfs_disk_key));
743
	btrfs_set_node_blockptr(lower, slot, blocknr);
744
	btrfs_set_header_nritems(&lower->header, nritems + 1);
C
Chris Mason 已提交
745
	btrfs_mark_buffer_dirty(path->nodes[level]);
C
Chris Mason 已提交
746 747 748
	return 0;
}

C
Chris Mason 已提交
749 750 751 752 753 754
/*
 * split the node at the specified level in path in two.
 * The path is corrected to point to the appropriate node after the split
 *
 * Before splitting this tries to make some room in the node by pushing
 * left and right, if either one works, it returns right away.
C
Chris Mason 已提交
755 756
 *
 * returns 0 on success and < 0 on failure
C
Chris Mason 已提交
757
 */
758 759
static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_path *path, int level)
760
{
C
Chris Mason 已提交
761
	struct buffer_head *t;
C
Chris Mason 已提交
762
	struct btrfs_node *c;
C
Chris Mason 已提交
763
	struct buffer_head *split_buffer;
C
Chris Mason 已提交
764
	struct btrfs_node *split;
765
	int mid;
C
Chris Mason 已提交
766
	int ret;
C
Chris Mason 已提交
767
	int wret;
768
	u32 c_nritems;
769

C
Chris Mason 已提交
770
	t = path->nodes[level];
C
Chris Mason 已提交
771
	c = btrfs_buffer_node(t);
C
Chris Mason 已提交
772 773
	if (t == root->node) {
		/* trying to split the root, lets make a new one */
774
		ret = insert_new_root(trans, root, path, level + 1);
C
Chris Mason 已提交
775 776
		if (ret)
			return ret;
777
	}
778
	c_nritems = btrfs_header_nritems(&c->header);
779
	split_buffer = btrfs_alloc_free_block(trans, root);
C
Chris Mason 已提交
780
	split = btrfs_buffer_node(split_buffer);
781
	btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
782
	btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
783
	btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer));
784
	btrfs_set_header_generation(&split->header, trans->transid);
C
Chris Mason 已提交
785 786
	memcpy(split->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(split->header.fsid));
787
	mid = (c_nritems + 1) / 2;
C
Chris Mason 已提交
788 789
	btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid,
		     (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
790 791
	btrfs_set_header_nritems(&split->header, c_nritems - mid);
	btrfs_set_header_nritems(&c->header, mid);
C
Chris Mason 已提交
792 793
	ret = 0;

C
Chris Mason 已提交
794 795
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(split_buffer);
796
	wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
797
			  bh_blocknr(split_buffer), path->slots[level + 1] + 1,
C
Chris Mason 已提交
798
			  level + 1);
C
Chris Mason 已提交
799 800 801
	if (wret)
		ret = wret;

C
Chris Mason 已提交
802
	if (path->slots[level] >= mid) {
C
Chris Mason 已提交
803
		path->slots[level] -= mid;
C
Chris Mason 已提交
804
		btrfs_block_release(root, t);
C
Chris Mason 已提交
805 806 807
		path->nodes[level] = split_buffer;
		path->slots[level + 1] += 1;
	} else {
C
Chris Mason 已提交
808
		btrfs_block_release(root, split_buffer);
809
	}
C
Chris Mason 已提交
810
	return ret;
811 812
}

C
Chris Mason 已提交
813 814 815 816 817
/*
 * how many bytes are required to store the items in a leaf.  start
 * and nr indicate which items in the leaf to check.  This totals up the
 * space used both by the item structs and the item data
 */
C
Chris Mason 已提交
818
static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
819 820
{
	int data_len;
821 822
	int nritems = btrfs_header_nritems(&l->header);
	int end = min(nritems, start + nr) - 1;
823 824 825

	if (!nr)
		return 0;
C
Chris Mason 已提交
826 827 828
	data_len = btrfs_item_end(l->items + start);
	data_len = data_len - btrfs_item_offset(l->items + end);
	data_len += sizeof(struct btrfs_item) * nr;
829
	WARN_ON(data_len < 0);
830 831 832
	return data_len;
}

833 834 835 836 837 838 839 840 841 842 843
/*
 * The space between the end of the leaf items and
 * the start of the leaf data.  IOW, how much room
 * the leaf has left for both items and data
 */
int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf)
{
	int nritems = btrfs_header_nritems(&leaf->header);
	return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems);
}

C
Chris Mason 已提交
844 845 846
/*
 * push some data in the path leaf to the right, trying to free up at
 * least data_size bytes.  returns zero if the push worked, nonzero otherwise
C
Chris Mason 已提交
847 848 849
 *
 * returns 1 if the push failed because the other node didn't have enough
 * room, 0 if everything worked out and < 0 if there were major errors.
C
Chris Mason 已提交
850
 */
851 852
static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
			   *root, struct btrfs_path *path, int data_size)
C
Chris Mason 已提交
853
{
C
Chris Mason 已提交
854 855
	struct buffer_head *left_buf = path->nodes[0];
	struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf);
C
Chris Mason 已提交
856
	struct btrfs_leaf *right;
C
Chris Mason 已提交
857 858 859
	struct buffer_head *right_buf;
	struct buffer_head *upper;
	struct btrfs_node *upper_node;
C
Chris Mason 已提交
860 861 862 863 864
	int slot;
	int i;
	int free_space;
	int push_space = 0;
	int push_items = 0;
C
Chris Mason 已提交
865
	struct btrfs_item *item;
866 867
	u32 left_nritems;
	u32 right_nritems;
C
Chris Mason 已提交
868 869 870 871 872 873

	slot = path->slots[1];
	if (!path->nodes[1]) {
		return 1;
	}
	upper = path->nodes[1];
C
Chris Mason 已提交
874 875
	upper_node = btrfs_buffer_node(upper);
	if (slot >= btrfs_header_nritems(&upper_node->header) - 1) {
C
Chris Mason 已提交
876 877
		return 1;
	}
C
Chris Mason 已提交
878 879 880
	right_buf = read_tree_block(root,
		    btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1));
	right = btrfs_buffer_leaf(right_buf);
C
Chris Mason 已提交
881
	free_space = btrfs_leaf_free_space(root, right);
C
Chris Mason 已提交
882
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
883
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
884 885
		return 1;
	}
C
Chris Mason 已提交
886
	/* cow and double check */
887
	btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf);
C
Chris Mason 已提交
888
	right = btrfs_buffer_leaf(right_buf);
C
Chris Mason 已提交
889
	free_space = btrfs_leaf_free_space(root, right);
C
Chris Mason 已提交
890
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
891
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
892 893 894
		return 1;
	}

895 896
	left_nritems = btrfs_header_nritems(&left->header);
	for (i = left_nritems - 1; i >= 0; i--) {
C
Chris Mason 已提交
897 898 899
		item = left->items + i;
		if (path->slots[0] == i)
			push_space += data_size + sizeof(*item);
C
Chris Mason 已提交
900 901
		if (btrfs_item_size(item) + sizeof(*item) + push_space >
		    free_space)
C
Chris Mason 已提交
902 903
			break;
		push_items++;
C
Chris Mason 已提交
904
		push_space += btrfs_item_size(item) + sizeof(*item);
C
Chris Mason 已提交
905 906
	}
	if (push_items == 0) {
C
Chris Mason 已提交
907
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
908 909
		return 1;
	}
910
	right_nritems = btrfs_header_nritems(&right->header);
C
Chris Mason 已提交
911
	/* push left to right */
C
Chris Mason 已提交
912
	push_space = btrfs_item_end(left->items + left_nritems - push_items);
C
Chris Mason 已提交
913
	push_space -= leaf_data_end(root, left);
C
Chris Mason 已提交
914
	/* make room in the right data area */
C
Chris Mason 已提交
915 916 917 918 919
	btrfs_memmove(root, right, btrfs_leaf_data(right) +
		      leaf_data_end(root, right) - push_space,
		      btrfs_leaf_data(right) +
		      leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) -
		      leaf_data_end(root, right));
C
Chris Mason 已提交
920
	/* copy from the left data area */
C
Chris Mason 已提交
921 922 923 924 925
	btrfs_memcpy(root, right, btrfs_leaf_data(right) +
		     BTRFS_LEAF_DATA_SIZE(root) - push_space,
		     btrfs_leaf_data(left) + leaf_data_end(root, left),
		     push_space);
	btrfs_memmove(root, right, right->items + push_items, right->items,
C
Chris Mason 已提交
926
		right_nritems * sizeof(struct btrfs_item));
C
Chris Mason 已提交
927
	/* copy the items from left to right */
C
Chris Mason 已提交
928 929 930
	btrfs_memcpy(root, right, right->items, left->items +
		     left_nritems - push_items,
		     push_items * sizeof(struct btrfs_item));
C
Chris Mason 已提交
931 932

	/* update the item pointers */
933 934
	right_nritems += push_items;
	btrfs_set_header_nritems(&right->header, right_nritems);
C
Chris Mason 已提交
935
	push_space = BTRFS_LEAF_DATA_SIZE(root);
936
	for (i = 0; i < right_nritems; i++) {
C
Chris Mason 已提交
937 938 939
		btrfs_set_item_offset(right->items + i, push_space -
				      btrfs_item_size(right->items + i));
		push_space = btrfs_item_offset(right->items + i);
C
Chris Mason 已提交
940
	}
941 942
	left_nritems -= push_items;
	btrfs_set_header_nritems(&left->header, left_nritems);
C
Chris Mason 已提交
943

C
Chris Mason 已提交
944 945 946
	btrfs_mark_buffer_dirty(left_buf);
	btrfs_mark_buffer_dirty(right_buf);
	btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key,
C
Chris Mason 已提交
947
		&right->items[0].key, sizeof(struct btrfs_disk_key));
C
Chris Mason 已提交
948
	btrfs_mark_buffer_dirty(upper);
C
Chris Mason 已提交
949

C
Chris Mason 已提交
950
	/* then fixup the leaf pointer in the path */
951 952
	if (path->slots[0] >= left_nritems) {
		path->slots[0] -= left_nritems;
C
Chris Mason 已提交
953
		btrfs_block_release(root, path->nodes[0]);
C
Chris Mason 已提交
954 955 956
		path->nodes[0] = right_buf;
		path->slots[1] += 1;
	} else {
C
Chris Mason 已提交
957
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
958 959 960
	}
	return 0;
}
C
Chris Mason 已提交
961 962 963 964
/*
 * push some data in the path leaf to the left, trying to free up at
 * least data_size bytes.  returns zero if the push worked, nonzero otherwise
 */
965 966
static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
			  *root, struct btrfs_path *path, int data_size)
967
{
C
Chris Mason 已提交
968 969 970
	struct buffer_head *right_buf = path->nodes[0];
	struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf);
	struct buffer_head *t;
C
Chris Mason 已提交
971
	struct btrfs_leaf *left;
972 973 974 975 976
	int slot;
	int i;
	int free_space;
	int push_space = 0;
	int push_items = 0;
C
Chris Mason 已提交
977
	struct btrfs_item *item;
978
	u32 old_left_nritems;
C
Chris Mason 已提交
979 980
	int ret = 0;
	int wret;
981 982 983 984 985 986 987 988

	slot = path->slots[1];
	if (slot == 0) {
		return 1;
	}
	if (!path->nodes[1]) {
		return 1;
	}
C
Chris Mason 已提交
989 990 991
	t = read_tree_block(root,
	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1));
	left = btrfs_buffer_leaf(t);
C
Chris Mason 已提交
992
	free_space = btrfs_leaf_free_space(root, left);
C
Chris Mason 已提交
993
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
994
		btrfs_block_release(root, t);
995 996
		return 1;
	}
C
Chris Mason 已提交
997 998

	/* cow and double check */
999
	btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
C
Chris Mason 已提交
1000
	left = btrfs_buffer_leaf(t);
C
Chris Mason 已提交
1001
	free_space = btrfs_leaf_free_space(root, left);
C
Chris Mason 已提交
1002
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1003
		btrfs_block_release(root, t);
C
Chris Mason 已提交
1004 1005 1006
		return 1;
	}

1007
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
1008 1009 1010
		item = right->items + i;
		if (path->slots[0] == i)
			push_space += data_size + sizeof(*item);
C
Chris Mason 已提交
1011 1012
		if (btrfs_item_size(item) + sizeof(*item) + push_space >
		    free_space)
1013 1014
			break;
		push_items++;
C
Chris Mason 已提交
1015
		push_space += btrfs_item_size(item) + sizeof(*item);
1016 1017
	}
	if (push_items == 0) {
C
Chris Mason 已提交
1018
		btrfs_block_release(root, t);
1019 1020 1021
		return 1;
	}
	/* push data from right to left */
C
Chris Mason 已提交
1022 1023 1024
	btrfs_memcpy(root, left, left->items +
		     btrfs_header_nritems(&left->header),
		     right->items, push_items * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1025
	push_space = BTRFS_LEAF_DATA_SIZE(root) -
C
Chris Mason 已提交
1026
		     btrfs_item_offset(right->items + push_items -1);
C
Chris Mason 已提交
1027 1028 1029 1030 1031
	btrfs_memcpy(root, left, btrfs_leaf_data(left) +
		     leaf_data_end(root, left) - push_space,
		     btrfs_leaf_data(right) +
		     btrfs_item_offset(right->items + push_items - 1),
		     push_space);
1032
	old_left_nritems = btrfs_header_nritems(&left->header);
1033 1034
	BUG_ON(old_left_nritems < 0);

C
Chris Mason 已提交
1035
	for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
C
Chris Mason 已提交
1036 1037 1038
		u32 ioff = btrfs_item_offset(left->items + i);
		btrfs_set_item_offset(left->items + i, ioff -
				     (BTRFS_LEAF_DATA_SIZE(root) -
C
Chris Mason 已提交
1039 1040
				      btrfs_item_offset(left->items +
						        old_left_nritems - 1)));
1041
	}
1042
	btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
1043 1044

	/* fixup right node */
C
Chris Mason 已提交
1045
	push_space = btrfs_item_offset(right->items + push_items - 1) -
C
Chris Mason 已提交
1046
		     leaf_data_end(root, right);
C
Chris Mason 已提交
1047 1048 1049 1050 1051
	btrfs_memmove(root, right, btrfs_leaf_data(right) +
		      BTRFS_LEAF_DATA_SIZE(root) - push_space,
		      btrfs_leaf_data(right) +
		      leaf_data_end(root, right), push_space);
	btrfs_memmove(root, right, right->items, right->items + push_items,
1052
		(btrfs_header_nritems(&right->header) - push_items) *
C
Chris Mason 已提交
1053
		sizeof(struct btrfs_item));
1054 1055 1056
	btrfs_set_header_nritems(&right->header,
				 btrfs_header_nritems(&right->header) -
				 push_items);
C
Chris Mason 已提交
1057
	push_space = BTRFS_LEAF_DATA_SIZE(root);
1058

1059
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1060 1061 1062
		btrfs_set_item_offset(right->items + i, push_space -
				      btrfs_item_size(right->items + i));
		push_space = btrfs_item_offset(right->items + i);
1063
	}
1064

C
Chris Mason 已提交
1065 1066
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(right_buf);
1067

1068
	wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
C
Chris Mason 已提交
1069 1070
	if (wret)
		ret = wret;
1071 1072 1073 1074

	/* then fixup the leaf pointer in the path */
	if (path->slots[0] < push_items) {
		path->slots[0] += old_left_nritems;
C
Chris Mason 已提交
1075
		btrfs_block_release(root, path->nodes[0]);
1076
		path->nodes[0] = t;
1077 1078
		path->slots[1] -= 1;
	} else {
C
Chris Mason 已提交
1079
		btrfs_block_release(root, t);
1080 1081
		path->slots[0] -= push_items;
	}
1082
	BUG_ON(path->slots[0] < 0);
C
Chris Mason 已提交
1083
	return ret;
1084 1085
}

C
Chris Mason 已提交
1086 1087 1088
/*
 * split the path's leaf in two, making sure there is at least data_size
 * available for the resulting leaf level of the path.
C
Chris Mason 已提交
1089 1090
 *
 * returns 0 if all went well and < 0 on failure.
C
Chris Mason 已提交
1091
 */
1092
static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1093 1094
		      *root, struct btrfs_key *ins_key,
		      struct btrfs_path *path, int data_size)
1095
{
C
Chris Mason 已提交
1096
	struct buffer_head *l_buf;
C
Chris Mason 已提交
1097
	struct btrfs_leaf *l;
1098
	u32 nritems;
1099 1100
	int mid;
	int slot;
C
Chris Mason 已提交
1101
	struct btrfs_leaf *right;
C
Chris Mason 已提交
1102
	struct buffer_head *right_buffer;
C
Chris Mason 已提交
1103
	int space_needed = data_size + sizeof(struct btrfs_item);
1104 1105 1106
	int data_copy_size;
	int rt_data_off;
	int i;
1107
	int ret = 0;
C
Chris Mason 已提交
1108
	int wret;
1109 1110
	int double_split = 0;
	struct btrfs_disk_key disk_key;
C
Chris Mason 已提交
1111

C
Chris Mason 已提交
1112
	/* first try to make some room by pushing left and right */
1113
	wret = push_leaf_left(trans, root, path, data_size);
C
Chris Mason 已提交
1114 1115 1116
	if (wret < 0)
		return wret;
	if (wret) {
1117
		wret = push_leaf_right(trans, root, path, data_size);
C
Chris Mason 已提交
1118 1119 1120
		if (wret < 0)
			return wret;
	}
C
Chris Mason 已提交
1121
	l_buf = path->nodes[0];
C
Chris Mason 已提交
1122
	l = btrfs_buffer_leaf(l_buf);
C
Chris Mason 已提交
1123 1124

	/* did the pushes work? */
C
Chris Mason 已提交
1125 1126
	if (btrfs_leaf_free_space(root, l) >=
	    sizeof(struct btrfs_item) + data_size)
C
Chris Mason 已提交
1127 1128
		return 0;

C
Chris Mason 已提交
1129
	if (!path->nodes[1]) {
1130
		ret = insert_new_root(trans, root, path, 1);
C
Chris Mason 已提交
1131 1132 1133
		if (ret)
			return ret;
	}
1134
	slot = path->slots[0];
1135
	nritems = btrfs_header_nritems(&l->header);
1136
	mid = (nritems + 1)/ 2;
1137
	right_buffer = btrfs_alloc_free_block(trans, root);
1138
	BUG_ON(!right_buffer);
C
Chris Mason 已提交
1139
	right = btrfs_buffer_leaf(right_buffer);
C
Chris Mason 已提交
1140
	memset(&right->header, 0, sizeof(right->header));
1141
	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1142
	btrfs_set_header_generation(&right->header, trans->transid);
1143
	btrfs_set_header_level(&right->header, 0);
C
Chris Mason 已提交
1144 1145
	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(right->header.fsid));
1146 1147 1148 1149 1150 1151 1152 1153 1154
	if (mid <= slot) {
		if (nritems == 1 ||
		    leaf_space_used(l, mid, nritems - mid) + space_needed >
			BTRFS_LEAF_DATA_SIZE(root)) {
			if (slot >= nritems) {
				btrfs_cpu_key_to_disk(&disk_key, ins_key);
				btrfs_set_header_nritems(&right->header, 0);
				wret = insert_ptr(trans, root, path,
						  &disk_key,
1155
						  bh_blocknr(right_buffer),
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
						  path->slots[1] + 1, 1);
				if (wret)
					ret = wret;
				btrfs_block_release(root, path->nodes[0]);
				path->nodes[0] = right_buffer;
				path->slots[0] = 0;
				path->slots[1] += 1;
				return ret;
			}
			mid = slot;
			double_split = 1;
		}
	} else {
		if (leaf_space_used(l, 0, mid + 1) + space_needed >
			BTRFS_LEAF_DATA_SIZE(root)) {
			if (slot == 0) {
				btrfs_cpu_key_to_disk(&disk_key, ins_key);
				btrfs_set_header_nritems(&right->header, 0);
				wret = insert_ptr(trans, root, path,
						  &disk_key,
1176
						  bh_blocknr(right_buffer),
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
						  path->slots[1] - 1, 1);
				if (wret)
					ret = wret;
				btrfs_block_release(root, path->nodes[0]);
				path->nodes[0] = right_buffer;
				path->slots[0] = 0;
				path->slots[1] -= 1;
				return ret;
			}
			mid = slot;
			double_split = 1;
		}
	}
	btrfs_set_header_nritems(&right->header, nritems - mid);
C
Chris Mason 已提交
1191 1192
	data_copy_size = btrfs_item_end(l->items + mid) -
			 leaf_data_end(root, l);
C
Chris Mason 已提交
1193 1194 1195 1196 1197 1198
	btrfs_memcpy(root, right, right->items, l->items + mid,
		     (nritems - mid) * sizeof(struct btrfs_item));
	btrfs_memcpy(root, right,
		     btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
		     data_copy_size, btrfs_leaf_data(l) +
		     leaf_data_end(root, l), data_copy_size);
C
Chris Mason 已提交
1199 1200
	rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
		      btrfs_item_end(l->items + mid);
C
Chris Mason 已提交
1201

C
Chris Mason 已提交
1202
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1203
		u32 ioff = btrfs_item_offset(right->items + i);
C
Chris Mason 已提交
1204 1205
		btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
	}
C
Chris Mason 已提交
1206

1207
	btrfs_set_header_nritems(&l->header, mid);
C
Chris Mason 已提交
1208
	ret = 0;
1209
	wret = insert_ptr(trans, root, path, &right->items[0].key,
1210
			  bh_blocknr(right_buffer), path->slots[1] + 1, 1);
C
Chris Mason 已提交
1211 1212
	if (wret)
		ret = wret;
C
Chris Mason 已提交
1213 1214
	btrfs_mark_buffer_dirty(right_buffer);
	btrfs_mark_buffer_dirty(l_buf);
1215
	BUG_ON(path->slots[0] != slot);
1216
	if (mid <= slot) {
C
Chris Mason 已提交
1217
		btrfs_block_release(root, path->nodes[0]);
1218
		path->nodes[0] = right_buffer;
1219 1220
		path->slots[0] -= mid;
		path->slots[1] += 1;
1221
	} else
C
Chris Mason 已提交
1222
		btrfs_block_release(root, right_buffer);
1223
	BUG_ON(path->slots[0] < 0);
1224 1225 1226 1227 1228 1229 1230

	if (!double_split)
		return ret;
	right_buffer = btrfs_alloc_free_block(trans, root);
	BUG_ON(!right_buffer);
	right = btrfs_buffer_leaf(right_buffer);
	memset(&right->header, 0, sizeof(right->header));
1231
	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1232 1233
	btrfs_set_header_generation(&right->header, trans->transid);
	btrfs_set_header_level(&right->header, 0);
C
Chris Mason 已提交
1234 1235
	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(right->header.fsid));
1236 1237 1238 1239
	btrfs_cpu_key_to_disk(&disk_key, ins_key);
	btrfs_set_header_nritems(&right->header, 0);
	wret = insert_ptr(trans, root, path,
			  &disk_key,
1240
			  bh_blocknr(right_buffer),
1241 1242 1243 1244 1245 1246 1247 1248
			  path->slots[1], 1);
	if (wret)
		ret = wret;
	btrfs_block_release(root, path->nodes[0]);
	path->nodes[0] = right_buffer;
	path->slots[0] = 0;
	check_node(root, path, 1);
	check_leaf(root, path, 0);
1249 1250 1251
	return ret;
}

C
Chris Mason 已提交
1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308
int btrfs_truncate_item(struct btrfs_trans_handle *trans,
			struct btrfs_root *root,
			struct btrfs_path *path,
			u32 new_size)
{
	int ret = 0;
	int slot;
	int slot_orig;
	struct btrfs_leaf *leaf;
	struct buffer_head *leaf_buf;
	u32 nritems;
	unsigned int data_end;
	unsigned int old_data_start;
	unsigned int old_size;
	unsigned int size_diff;
	int i;

	slot_orig = path->slots[0];
	leaf_buf = path->nodes[0];
	leaf = btrfs_buffer_leaf(leaf_buf);

	nritems = btrfs_header_nritems(&leaf->header);
	data_end = leaf_data_end(root, leaf);

	slot = path->slots[0];
	old_data_start = btrfs_item_offset(leaf->items + slot);
	old_size = btrfs_item_size(leaf->items + slot);
	BUG_ON(old_size <= new_size);
	size_diff = old_size - new_size;

	BUG_ON(slot < 0);
	BUG_ON(slot >= nritems);

	/*
	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
	 */
	/* first correct the data pointers */
	for (i = slot; i < nritems; i++) {
		u32 ioff = btrfs_item_offset(leaf->items + i);
		btrfs_set_item_offset(leaf->items + i,
				      ioff + size_diff);
	}
	/* shift the data */
printk("truncate item, new_size %u old_size %u, diff %u, bufp %p, dst, %p, num %u, old_data_start %u, data_end %u\n", new_size, old_size, size_diff, leaf, btrfs_leaf_data(leaf) + data_end + size_diff, old_data_start-data_end, old_data_start, data_end);
	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
		      data_end + size_diff, btrfs_leaf_data(leaf) +
		      data_end, old_data_start + new_size - data_end);
	btrfs_set_item_size(leaf->items + slot, new_size);
	btrfs_mark_buffer_dirty(leaf_buf);

	ret = 0;
	if (btrfs_leaf_free_space(root, leaf) < 0)
		BUG();
	check_leaf(root, path, 0);
	return ret;
}

1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362
int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_path *path, u32 data_size)
{
	int ret = 0;
	int slot;
	int slot_orig;
	struct btrfs_leaf *leaf;
	struct buffer_head *leaf_buf;
	u32 nritems;
	unsigned int data_end;
	unsigned int old_data;
	unsigned int old_size;
	int i;

	slot_orig = path->slots[0];
	leaf_buf = path->nodes[0];
	leaf = btrfs_buffer_leaf(leaf_buf);

	nritems = btrfs_header_nritems(&leaf->header);
	data_end = leaf_data_end(root, leaf);

	if (btrfs_leaf_free_space(root, leaf) < data_size)
		BUG();
	slot = path->slots[0];
	old_data = btrfs_item_end(leaf->items + slot);

	BUG_ON(slot < 0);
	BUG_ON(slot >= nritems);

	/*
	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
	 */
	/* first correct the data pointers */
	for (i = slot; i < nritems; i++) {
		u32 ioff = btrfs_item_offset(leaf->items + i);
		btrfs_set_item_offset(leaf->items + i,
				      ioff - data_size);
	}
	/* shift the data */
	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
		      data_end - data_size, btrfs_leaf_data(leaf) +
		      data_end, old_data - data_end);
	data_end = old_data;
	old_size = btrfs_item_size(leaf->items + slot);
	btrfs_set_item_size(leaf->items + slot, old_size + data_size);
	btrfs_mark_buffer_dirty(leaf_buf);

	ret = 0;
	if (btrfs_leaf_free_space(root, leaf) < 0)
		BUG();
	check_leaf(root, path, 0);
	return ret;
}

C
Chris Mason 已提交
1363 1364 1365 1366
/*
 * Given a key and some data, insert an item into the tree.
 * This does all the path init required, making room in the tree if needed.
 */
1367 1368 1369
int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
			    *root, struct btrfs_path *path, struct btrfs_key
			    *cpu_key, u32 data_size)
1370
{
C
Chris Mason 已提交
1371
	int ret = 0;
1372
	int slot;
1373
	int slot_orig;
C
Chris Mason 已提交
1374
	struct btrfs_leaf *leaf;
C
Chris Mason 已提交
1375
	struct buffer_head *leaf_buf;
1376
	u32 nritems;
1377
	unsigned int data_end;
C
Chris Mason 已提交
1378 1379 1380
	struct btrfs_disk_key disk_key;

	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1381

C
Chris Mason 已提交
1382
	/* create a root if there isn't one */
C
Chris Mason 已提交
1383
	if (!root->node)
C
Chris Mason 已提交
1384
		BUG();
1385
	ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
1386
	if (ret == 0) {
1387
		return -EEXIST;
C
Chris Mason 已提交
1388
	}
1389 1390
	if (ret < 0)
		goto out;
1391

1392 1393
	slot_orig = path->slots[0];
	leaf_buf = path->nodes[0];
C
Chris Mason 已提交
1394
	leaf = btrfs_buffer_leaf(leaf_buf);
C
Chris Mason 已提交
1395

1396
	nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
1397
	data_end = leaf_data_end(root, leaf);
1398

C
Chris Mason 已提交
1399
	if (btrfs_leaf_free_space(root, leaf) <
1400
	    sizeof(struct btrfs_item) + data_size) {
1401
		BUG();
1402
	}
1403
	slot = path->slots[0];
1404
	BUG_ON(slot < 0);
1405 1406
	if (slot != nritems) {
		int i;
C
Chris Mason 已提交
1407
		unsigned int old_data = btrfs_item_end(leaf->items + slot);
1408 1409 1410 1411 1412

		/*
		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
		 */
		/* first correct the data pointers */
C
Chris Mason 已提交
1413
		for (i = slot; i < nritems; i++) {
C
Chris Mason 已提交
1414
			u32 ioff = btrfs_item_offset(leaf->items + i);
C
Chris Mason 已提交
1415 1416 1417
			btrfs_set_item_offset(leaf->items + i,
					      ioff - data_size);
		}
1418 1419

		/* shift the items */
C
Chris Mason 已提交
1420 1421 1422
		btrfs_memmove(root, leaf, leaf->items + slot + 1,
			      leaf->items + slot,
			      (nritems - slot) * sizeof(struct btrfs_item));
1423 1424

		/* shift the data */
C
Chris Mason 已提交
1425 1426 1427
		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
			      data_end - data_size, btrfs_leaf_data(leaf) +
			      data_end, old_data - data_end);
1428 1429
		data_end = old_data;
	}
1430
	/* setup the item for the new data */
C
Chris Mason 已提交
1431 1432
	btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key,
		     sizeof(struct btrfs_disk_key));
C
Chris Mason 已提交
1433 1434
	btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
	btrfs_set_item_size(leaf->items + slot, data_size);
1435
	btrfs_set_header_nritems(&leaf->header, nritems + 1);
C
Chris Mason 已提交
1436
	btrfs_mark_buffer_dirty(leaf_buf);
C
Chris Mason 已提交
1437 1438

	ret = 0;
1439
	if (slot == 0)
1440
		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
C
Chris Mason 已提交
1441

C
Chris Mason 已提交
1442
	if (btrfs_leaf_free_space(root, leaf) < 0)
1443
		BUG();
1444
	check_leaf(root, path, 0);
1445
out:
1446 1447 1448 1449 1450 1451 1452
	return ret;
}

/*
 * Given a key and some data, insert an item into the tree.
 * This does all the path init required, making room in the tree if needed.
 */
1453 1454 1455
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_key *cpu_key, void *data, u32
		      data_size)
1456 1457
{
	int ret = 0;
C
Chris Mason 已提交
1458
	struct btrfs_path *path;
1459 1460
	u8 *ptr;

C
Chris Mason 已提交
1461 1462 1463 1464
	path = btrfs_alloc_path();
	BUG_ON(!path);
	btrfs_init_path(path);
	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
1465
	if (!ret) {
C
Chris Mason 已提交
1466 1467 1468
		ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
				     path->slots[0], u8);
		btrfs_memcpy(root, path->nodes[0]->b_data,
C
Chris Mason 已提交
1469
			     ptr, data, data_size);
C
Chris Mason 已提交
1470
		btrfs_mark_buffer_dirty(path->nodes[0]);
1471
	}
C
Chris Mason 已提交
1472 1473
	btrfs_release_path(root, path);
	btrfs_free_path(path);
C
Chris Mason 已提交
1474
	return ret;
1475 1476
}

C
Chris Mason 已提交
1477
/*
C
Chris Mason 已提交
1478
 * delete the pointer from a given node.
C
Chris Mason 已提交
1479 1480 1481 1482 1483
 *
 * If the delete empties a node, the node is removed from the tree,
 * continuing all the way the root if required.  The root is converted into
 * a leaf if all the nodes are emptied.
 */
1484 1485
static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path, int level, int slot)
1486
{
C
Chris Mason 已提交
1487
	struct btrfs_node *node;
C
Chris Mason 已提交
1488
	struct buffer_head *parent = path->nodes[level];
1489
	u32 nritems;
C
Chris Mason 已提交
1490
	int ret = 0;
1491
	int wret;
1492

C
Chris Mason 已提交
1493
	node = btrfs_buffer_node(parent);
1494
	nritems = btrfs_header_nritems(&node->header);
1495
	if (slot != nritems -1) {
C
Chris Mason 已提交
1496 1497 1498 1499
		btrfs_memmove(root, node, node->ptrs + slot,
			      node->ptrs + slot + 1,
			      sizeof(struct btrfs_key_ptr) *
			      (nritems - slot - 1));
1500
	}
1501 1502 1503
	nritems--;
	btrfs_set_header_nritems(&node->header, nritems);
	if (nritems == 0 && parent == root->node) {
C
Chris Mason 已提交
1504 1505
		struct btrfs_header *header = btrfs_buffer_header(root->node);
		BUG_ON(btrfs_header_level(header) != 1);
1506
		/* just turn the root into a leaf and break */
C
Chris Mason 已提交
1507
		btrfs_set_header_level(header, 0);
1508
	} else if (slot == 0) {
1509
		wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
C
Chris Mason 已提交
1510
				      level + 1);
C
Chris Mason 已提交
1511 1512
		if (wret)
			ret = wret;
1513
	}
C
Chris Mason 已提交
1514
	btrfs_mark_buffer_dirty(parent);
C
Chris Mason 已提交
1515
	return ret;
1516 1517
}

C
Chris Mason 已提交
1518 1519 1520 1521
/*
 * delete the item at the leaf level in path.  If that empties
 * the leaf, remove it from the tree
 */
1522 1523
int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path)
1524 1525
{
	int slot;
C
Chris Mason 已提交
1526
	struct btrfs_leaf *leaf;
C
Chris Mason 已提交
1527
	struct buffer_head *leaf_buf;
1528 1529
	int doff;
	int dsize;
C
Chris Mason 已提交
1530 1531
	int ret = 0;
	int wret;
1532
	u32 nritems;
1533

1534
	leaf_buf = path->nodes[0];
C
Chris Mason 已提交
1535
	leaf = btrfs_buffer_leaf(leaf_buf);
1536
	slot = path->slots[0];
C
Chris Mason 已提交
1537 1538
	doff = btrfs_item_offset(leaf->items + slot);
	dsize = btrfs_item_size(leaf->items + slot);
1539
	nritems = btrfs_header_nritems(&leaf->header);
1540

1541
	if (slot != nritems - 1) {
1542
		int i;
C
Chris Mason 已提交
1543
		int data_end = leaf_data_end(root, leaf);
C
Chris Mason 已提交
1544 1545 1546 1547
		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
			      data_end + dsize,
			      btrfs_leaf_data(leaf) + data_end,
			      doff - data_end);
C
Chris Mason 已提交
1548
		for (i = slot + 1; i < nritems; i++) {
C
Chris Mason 已提交
1549
			u32 ioff = btrfs_item_offset(leaf->items + i);
C
Chris Mason 已提交
1550 1551
			btrfs_set_item_offset(leaf->items + i, ioff + dsize);
		}
C
Chris Mason 已提交
1552 1553 1554 1555
		btrfs_memmove(root, leaf, leaf->items + slot,
			      leaf->items + slot + 1,
			      sizeof(struct btrfs_item) *
			      (nritems - slot - 1));
1556
	}
1557 1558
	btrfs_set_header_nritems(&leaf->header, nritems - 1);
	nritems--;
C
Chris Mason 已提交
1559
	/* delete the leaf if we've emptied it */
1560
	if (nritems == 0) {
1561
		if (leaf_buf == root->node) {
1562
			btrfs_set_header_level(&leaf->header, 0);
1563
		} else {
1564
			clean_tree_block(trans, root, leaf_buf);
C
Chris Mason 已提交
1565
			wait_on_buffer(leaf_buf);
1566
			wret = del_ptr(trans, root, path, 1, path->slots[1]);
C
Chris Mason 已提交
1567 1568
			if (wret)
				ret = wret;
1569
			wret = btrfs_free_extent(trans, root,
1570
						 bh_blocknr(leaf_buf), 1, 1);
C
Chris Mason 已提交
1571 1572
			if (wret)
				ret = wret;
1573
		}
1574
	} else {
1575
		int used = leaf_space_used(leaf, 0, nritems);
C
Chris Mason 已提交
1576
		if (slot == 0) {
1577 1578
			wret = fixup_low_keys(trans, root, path,
					      &leaf->items[0].key, 1);
C
Chris Mason 已提交
1579 1580 1581 1582
			if (wret)
				ret = wret;
		}

C
Chris Mason 已提交
1583
		/* delete the leaf if it is mostly empty */
C
Chris Mason 已提交
1584
		if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
1585 1586 1587 1588
			/* push_leaf_left fixes the path.
			 * make sure the path still points to our leaf
			 * for possible call to del_ptr below
			 */
1589
			slot = path->slots[1];
C
Chris Mason 已提交
1590
			get_bh(leaf_buf);
1591
			wret = push_leaf_left(trans, root, path, 1);
C
Chris Mason 已提交
1592 1593
			if (wret < 0)
				ret = wret;
1594
			if (path->nodes[0] == leaf_buf &&
1595
			    btrfs_header_nritems(&leaf->header)) {
1596
				wret = push_leaf_right(trans, root, path, 1);
C
Chris Mason 已提交
1597 1598 1599
				if (wret < 0)
					ret = wret;
			}
1600
			if (btrfs_header_nritems(&leaf->header) == 0) {
1601
				u64 blocknr = bh_blocknr(leaf_buf);
1602
				clean_tree_block(trans, root, leaf_buf);
C
Chris Mason 已提交
1603
				wait_on_buffer(leaf_buf);
1604
				wret = del_ptr(trans, root, path, 1, slot);
C
Chris Mason 已提交
1605 1606
				if (wret)
					ret = wret;
C
Chris Mason 已提交
1607
				btrfs_block_release(root, leaf_buf);
1608 1609
				wret = btrfs_free_extent(trans, root, blocknr,
							 1, 1);
C
Chris Mason 已提交
1610 1611
				if (wret)
					ret = wret;
C
Chris Mason 已提交
1612
			} else {
C
Chris Mason 已提交
1613
				btrfs_mark_buffer_dirty(leaf_buf);
C
Chris Mason 已提交
1614
				btrfs_block_release(root, leaf_buf);
1615
			}
1616
		} else {
C
Chris Mason 已提交
1617
			btrfs_mark_buffer_dirty(leaf_buf);
1618 1619
		}
	}
C
Chris Mason 已提交
1620
	return ret;
1621 1622
}

C
Chris Mason 已提交
1623 1624
/*
 * walk up the tree as far as required to find the next leaf.
C
Chris Mason 已提交
1625 1626
 * returns 0 if it found something or 1 if there are no greater leaves.
 * returns < 0 on io errors.
C
Chris Mason 已提交
1627
 */
C
Chris Mason 已提交
1628
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
1629 1630 1631 1632
{
	int slot;
	int level = 1;
	u64 blocknr;
C
Chris Mason 已提交
1633 1634 1635
	struct buffer_head *c;
	struct btrfs_node *c_node;
	struct buffer_head *next = NULL;
1636

C
Chris Mason 已提交
1637
	while(level < BTRFS_MAX_LEVEL) {
1638
		if (!path->nodes[level])
C
Chris Mason 已提交
1639
			return 1;
1640 1641
		slot = path->slots[level] + 1;
		c = path->nodes[level];
C
Chris Mason 已提交
1642 1643
		c_node = btrfs_buffer_node(c);
		if (slot >= btrfs_header_nritems(&c_node->header)) {
1644 1645 1646
			level++;
			continue;
		}
C
Chris Mason 已提交
1647
		blocknr = btrfs_node_blockptr(c_node, slot);
C
Chris Mason 已提交
1648
		if (next)
C
Chris Mason 已提交
1649
			btrfs_block_release(root, next);
1650 1651 1652 1653 1654 1655 1656
		next = read_tree_block(root, blocknr);
		break;
	}
	path->slots[level] = slot;
	while(1) {
		level--;
		c = path->nodes[level];
C
Chris Mason 已提交
1657
		btrfs_block_release(root, c);
1658 1659 1660 1661
		path->nodes[level] = next;
		path->slots[level] = 0;
		if (!level)
			break;
1662
		next = read_tree_block(root,
C
Chris Mason 已提交
1663
		       btrfs_node_blockptr(btrfs_buffer_node(next), 0));
1664 1665 1666
	}
	return 0;
}