ctree.c 59.2 KB
Newer Older
C
Chris Mason 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Copyright (C) 2007 Oracle.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License v2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

19 20
#include "ctree.h"
#include "disk-io.h"
21
#include "transaction.h"
22

23 24 25
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
26 27
		      *root, struct btrfs_key *ins_key,
		      struct btrfs_path *path, int data_size);
28
static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
29
			  *root, struct buffer_head *dst, struct buffer_head
30 31
			  *src);
static int balance_node_right(struct btrfs_trans_handle *trans, struct
C
Chris Mason 已提交
32 33
			      btrfs_root *root, struct buffer_head *dst_buf,
			      struct buffer_head *src_buf);
34 35
static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path, int level, int slot);
36

C
Chris Mason 已提交
37
inline void btrfs_init_path(struct btrfs_path *p)
C
Chris Mason 已提交
38
{
C
Chris Mason 已提交
39
	memset(p, 0, sizeof(*p));
C
Chris Mason 已提交
40 41
}

C
Chris Mason 已提交
42
struct btrfs_path *btrfs_alloc_path(void)
C
Chris Mason 已提交
43
{
C
Chris Mason 已提交
44 45 46 47 48
	struct btrfs_path *path;
	path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
	if (path)
		btrfs_init_path(path);
	return path;
C
Chris Mason 已提交
49 50
}

C
Chris Mason 已提交
51
void btrfs_free_path(struct btrfs_path *p)
52
{
C
Chris Mason 已提交
53 54
	btrfs_release_path(NULL, p);
	kmem_cache_free(btrfs_path_cachep, p);
55 56
}

C
Chris Mason 已提交
57
void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
58 59
{
	int i;
C
Chris Mason 已提交
60
	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
61 62
		if (!p->nodes[i])
			break;
C
Chris Mason 已提交
63
		btrfs_block_release(root, p->nodes[i]);
64
	}
C
Chris Mason 已提交
65
	memset(p, 0, sizeof(*p));
66 67
}

68
static int __btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
69 70
			   *root, struct buffer_head *buf, struct buffer_head
			   *parent, int parent_slot, struct buffer_head
71
			   **cow_ret, u64 search_start, u64 empty_size)
C
Chris Mason 已提交
72
{
C
Chris Mason 已提交
73 74
	struct buffer_head *cow;
	struct btrfs_node *cow_node;
75 76
	int ret = 0;
	int different_trans = 0;
C
Chris Mason 已提交
77

78
	WARN_ON(root->ref_cows && trans->transid != root->last_trans);
C
Chris Mason 已提交
79
	WARN_ON(!buffer_uptodate(buf));
80
	cow = btrfs_alloc_free_block(trans, root, search_start, empty_size);
81 82
	if (IS_ERR(cow))
		return PTR_ERR(cow);
83

C
Chris Mason 已提交
84
	cow_node = btrfs_buffer_node(cow);
C
Chris Mason 已提交
85 86
	if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
		WARN_ON(1);
87

C
Chris Mason 已提交
88
	memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
89
	btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow));
90
	btrfs_set_header_generation(&cow_node->header, trans->transid);
91
	btrfs_set_header_owner(&cow_node->header, root->root_key.objectid);
92 93 94 95 96 97 98 99 100 101 102 103 104

	WARN_ON(btrfs_header_generation(btrfs_buffer_header(buf)) >
		trans->transid);
	if (btrfs_header_generation(btrfs_buffer_header(buf)) !=
				    trans->transid) {
		different_trans = 1;
		ret = btrfs_inc_ref(trans, root, buf);
		if (ret)
			return ret;
	} else {
		clean_tree_block(trans, root, buf);
	}

C
Chris Mason 已提交
105 106
	if (buf == root->node) {
		root->node = cow;
C
Chris Mason 已提交
107
		get_bh(cow);
C
Chris Mason 已提交
108
		if (buf != root->commit_root) {
109
			btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
C
Chris Mason 已提交
110
		}
C
Chris Mason 已提交
111
		btrfs_block_release(root, buf);
C
Chris Mason 已提交
112
	} else {
C
Chris Mason 已提交
113
		btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
114
					bh_blocknr(cow));
C
Chris Mason 已提交
115
		btrfs_mark_buffer_dirty(parent);
116 117
		WARN_ON(btrfs_header_generation(btrfs_buffer_header(parent)) !=
				    trans->transid);
118
		btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
C
Chris Mason 已提交
119
	}
C
Chris Mason 已提交
120
	btrfs_block_release(root, buf);
C
Chris Mason 已提交
121
	btrfs_mark_buffer_dirty(cow);
C
Chris Mason 已提交
122
	*cow_ret = cow;
C
Chris Mason 已提交
123 124 125
	return 0;
}

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
			   *root, struct buffer_head *buf, struct buffer_head
			   *parent, int parent_slot, struct buffer_head
			   **cow_ret)
{
	u64 search_start;
	if (trans->transaction != root->fs_info->running_transaction) {
		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
		       root->fs_info->running_transaction->transid);
		WARN_ON(1);
	}
	if (trans->transid != root->fs_info->generation) {
		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
		       root->fs_info->generation);
		WARN_ON(1);
	}
	if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
				    trans->transid) {
		*cow_ret = buf;
		return 0;
	}

	search_start = bh_blocknr(buf) & ~((u64)65535);
	return __btrfs_cow_block(trans, root, buf, parent,
				 parent_slot, cow_ret, search_start, 0);
}

static int close_blocks(u64 blocknr, u64 other)
{
	if (blocknr < other && other - blocknr < 8)
		return 1;
	if (blocknr > other && blocknr - other < 8)
		return 1;
	return 0;
}

int btrfs_realloc_node(struct btrfs_trans_handle *trans,
		       struct btrfs_root *root, struct buffer_head *parent,
164
		       int cache_only, u64 *last_ret)
165 166 167 168 169
{
	struct btrfs_node *parent_node;
	struct buffer_head *cur_bh;
	struct buffer_head *tmp_bh;
	u64 blocknr;
170 171
	u64 search_start = *last_ret;
	u64 last_block = 0;
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
	u64 other;
	u32 parent_nritems;
	int start_slot;
	int end_slot;
	int i;
	int err = 0;

	if (trans->transaction != root->fs_info->running_transaction) {
		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
		       root->fs_info->running_transaction->transid);
		WARN_ON(1);
	}
	if (trans->transid != root->fs_info->generation) {
		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
		       root->fs_info->generation);
		WARN_ON(1);
	}
	parent_node = btrfs_buffer_node(parent);
	parent_nritems = btrfs_header_nritems(&parent_node->header);

	start_slot = 0;
	end_slot = parent_nritems;

	if (parent_nritems == 1)
		return 0;

	for (i = start_slot; i < end_slot; i++) {
		int close = 1;
		blocknr = btrfs_node_blockptr(parent_node, i);
201 202
		if (last_block == 0)
			last_block = blocknr;
203 204 205 206 207 208 209 210
		if (i > 0) {
			other = btrfs_node_blockptr(parent_node, i - 1);
			close = close_blocks(blocknr, other);
		}
		if (close && i < end_slot - 1) {
			other = btrfs_node_blockptr(parent_node, i + 1);
			close = close_blocks(blocknr, other);
		}
211 212
		if (close) {
			last_block = blocknr;
213
			continue;
214
		}
215 216 217 218 219 220 221 222 223 224 225

		cur_bh = btrfs_find_tree_block(root, blocknr);
		if (!cur_bh || !buffer_uptodate(cur_bh) ||
		    buffer_locked(cur_bh)) {
			if (cache_only) {
				brelse(cur_bh);
				continue;
			}
			brelse(cur_bh);
			cur_bh = read_tree_block(root, blocknr);
		}
226 227 228
		if (search_start == 0)
			search_start = last_block & ~((u64)65535);

229 230 231 232 233 234 235 236 237 238 239
		err = __btrfs_cow_block(trans, root, cur_bh, parent, i,
					&tmp_bh, search_start,
					min(8, end_slot - i));
		if (err)
			break;
		search_start = bh_blocknr(tmp_bh);
		brelse(tmp_bh);
	}
	return err;
}

C
Chris Mason 已提交
240 241 242 243 244
/*
 * 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 已提交
245 246
static inline unsigned int leaf_data_end(struct btrfs_root *root,
					 struct btrfs_leaf *leaf)
247
{
248
	u32 nr = btrfs_header_nritems(&leaf->header);
249
	if (nr == 0)
C
Chris Mason 已提交
250
		return BTRFS_LEAF_DATA_SIZE(root);
C
Chris Mason 已提交
251
	return btrfs_item_offset(leaf->items + nr - 1);
252 253
}

C
Chris Mason 已提交
254 255 256
/*
 * compare two keys in a memcmp fashion
 */
C
Chris Mason 已提交
257
static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
258
{
C
Chris Mason 已提交
259 260 261 262 263
	struct btrfs_key k1;

	btrfs_disk_key_to_cpu(&k1, disk);

	if (k1.objectid > k2->objectid)
264
		return 1;
C
Chris Mason 已提交
265
	if (k1.objectid < k2->objectid)
266
		return -1;
C
Chris Mason 已提交
267 268 269 270
	if (k1.flags > k2->flags)
		return 1;
	if (k1.flags < k2->flags)
		return -1;
271 272 273 274
	if (k1.offset > k2->offset)
		return 1;
	if (k1.offset < k2->offset)
		return -1;
275 276
	return 0;
}
C
Chris Mason 已提交
277

C
Chris Mason 已提交
278 279
static int check_node(struct btrfs_root *root, struct btrfs_path *path,
		      int level)
C
Chris Mason 已提交
280
{
C
Chris Mason 已提交
281
	struct btrfs_node *parent = NULL;
C
Chris Mason 已提交
282
	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
C
Chris Mason 已提交
283
	int parent_slot;
284 285
	int slot;
	struct btrfs_key cpukey;
286
	u32 nritems = btrfs_header_nritems(&node->header);
C
Chris Mason 已提交
287 288

	if (path->nodes[level + 1])
C
Chris Mason 已提交
289
		parent = btrfs_buffer_node(path->nodes[level + 1]);
A
Aneesh 已提交
290

291
	slot = path->slots[level];
292 293
	BUG_ON(nritems == 0);
	if (parent) {
C
Chris Mason 已提交
294
		struct btrfs_disk_key *parent_key;
A
Aneesh 已提交
295 296

		parent_slot = path->slots[level + 1];
C
Chris Mason 已提交
297 298
		parent_key = &parent->ptrs[parent_slot].key;
		BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
C
Chris Mason 已提交
299
			      sizeof(struct btrfs_disk_key)));
300
		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
301
		       btrfs_header_blocknr(&node->header));
C
Chris Mason 已提交
302
	}
C
Chris Mason 已提交
303
	BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
304 305 306 307 308 309 310
	if (slot != 0) {
		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key);
		BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0);
	}
	if (slot < nritems - 1) {
		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key);
		BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0);
C
Chris Mason 已提交
311 312 313 314
	}
	return 0;
}

C
Chris Mason 已提交
315 316
static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
		      int level)
C
Chris Mason 已提交
317
{
C
Chris Mason 已提交
318
	struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]);
C
Chris Mason 已提交
319
	struct btrfs_node *parent = NULL;
C
Chris Mason 已提交
320
	int parent_slot;
321 322 323
	int slot = path->slots[0];
	struct btrfs_key cpukey;

324
	u32 nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
325 326

	if (path->nodes[level + 1])
C
Chris Mason 已提交
327
		parent = btrfs_buffer_node(path->nodes[level + 1]);
A
Aneesh 已提交
328

C
Chris Mason 已提交
329
	BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
330 331 332 333 334

	if (nritems == 0)
		return 0;

	if (parent) {
C
Chris Mason 已提交
335
		struct btrfs_disk_key *parent_key;
A
Aneesh 已提交
336 337

		parent_slot = path->slots[level + 1];
C
Chris Mason 已提交
338
		parent_key = &parent->ptrs[parent_slot].key;
339

C
Chris Mason 已提交
340
		BUG_ON(memcmp(parent_key, &leaf->items[0].key,
C
Chris Mason 已提交
341
		       sizeof(struct btrfs_disk_key)));
342
		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
343
		       btrfs_header_blocknr(&leaf->header));
C
Chris Mason 已提交
344
	}
345 346 347 348 349 350 351 352 353 354 355
	if (slot != 0) {
		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key);
		BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0);
		BUG_ON(btrfs_item_offset(leaf->items + slot - 1) !=
			btrfs_item_end(leaf->items + slot));
	}
	if (slot < nritems - 1) {
		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key);
		BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0);
		BUG_ON(btrfs_item_offset(leaf->items + slot) !=
			btrfs_item_end(leaf->items + slot + 1));
C
Chris Mason 已提交
356
	}
357 358
	BUG_ON(btrfs_item_offset(leaf->items) +
	       btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root));
C
Chris Mason 已提交
359 360 361
	return 0;
}

C
Chris Mason 已提交
362 363
static int check_block(struct btrfs_root *root, struct btrfs_path *path,
			int level)
C
Chris Mason 已提交
364
{
C
Chris Mason 已提交
365 366 367 368
	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 已提交
369
	if (level == 0)
C
Chris Mason 已提交
370 371
		return check_leaf(root, path, level);
	return check_node(root, path, level);
C
Chris Mason 已提交
372 373
}

C
Chris Mason 已提交
374 375 376 377 378 379 380 381 382
/*
 * 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 已提交
383
static int generic_bin_search(char *p, int item_size, struct btrfs_key *key,
384 385 386 387 388 389
		       int max, int *slot)
{
	int low = 0;
	int high = max;
	int mid;
	int ret;
C
Chris Mason 已提交
390
	struct btrfs_disk_key *tmp;
391 392 393

	while(low < high) {
		mid = (low + high) / 2;
C
Chris Mason 已提交
394
		tmp = (struct btrfs_disk_key *)(p + mid * item_size);
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
		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 已提交
410 411 412 413
/*
 * simple bin_search frontend that does the right thing for
 * leaves vs nodes
 */
C
Chris Mason 已提交
414
static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
415
{
416
	if (btrfs_is_leaf(c)) {
C
Chris Mason 已提交
417
		struct btrfs_leaf *l = (struct btrfs_leaf *)c;
C
Chris Mason 已提交
418 419
		return generic_bin_search((void *)l->items,
					  sizeof(struct btrfs_item),
420 421
					  key, btrfs_header_nritems(&c->header),
					  slot);
422
	} else {
C
Chris Mason 已提交
423 424
		return generic_bin_search((void *)c->ptrs,
					  sizeof(struct btrfs_key_ptr),
425 426
					  key, btrfs_header_nritems(&c->header),
					  slot);
427 428 429 430
	}
	return -1;
}

C
Chris Mason 已提交
431 432
static struct buffer_head *read_node_slot(struct btrfs_root *root,
				   struct buffer_head *parent_buf,
433 434
				   int slot)
{
C
Chris Mason 已提交
435
	struct btrfs_node *node = btrfs_buffer_node(parent_buf);
436 437
	if (slot < 0)
		return NULL;
438
	if (slot >= btrfs_header_nritems(&node->header))
439
		return NULL;
440
	return read_tree_block(root, btrfs_node_blockptr(node, slot));
441 442
}

443 444
static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
			 *root, struct btrfs_path *path, int level)
445
{
C
Chris Mason 已提交
446 447 448 449
	struct buffer_head *right_buf;
	struct buffer_head *mid_buf;
	struct buffer_head *left_buf;
	struct buffer_head *parent_buf = NULL;
C
Chris Mason 已提交
450 451 452 453
	struct btrfs_node *right = NULL;
	struct btrfs_node *mid;
	struct btrfs_node *left = NULL;
	struct btrfs_node *parent = NULL;
454 455 456 457
	int ret = 0;
	int wret;
	int pslot;
	int orig_slot = path->slots[level];
458
	int err_on_enospc = 0;
459
	u64 orig_ptr;
460 461 462 463 464

	if (level == 0)
		return 0;

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

C
Chris Mason 已提交
468
	if (level < BTRFS_MAX_LEVEL - 1)
469 470 471
		parent_buf = path->nodes[level + 1];
	pslot = path->slots[level + 1];

C
Chris Mason 已提交
472 473 474 475
	/*
	 * deal with the case where there is only one pointer in the root
	 * by promoting the node below to a root
	 */
476
	if (!parent_buf) {
C
Chris Mason 已提交
477
		struct buffer_head *child;
478
		u64 blocknr = bh_blocknr(mid_buf);
479

480
		if (btrfs_header_nritems(&mid->header) != 1)
481 482 483 484 485 486 487
			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 已提交
488 489
		clean_tree_block(trans, root, mid_buf);
		wait_on_buffer(mid_buf);
490
		/* once for the path */
C
Chris Mason 已提交
491
		btrfs_block_release(root, mid_buf);
492
		/* once for the root ptr */
C
Chris Mason 已提交
493
		btrfs_block_release(root, mid_buf);
494
		return btrfs_free_extent(trans, root, blocknr, 1, 1);
495
	}
C
Chris Mason 已提交
496
	parent = btrfs_buffer_node(parent_buf);
497

C
Chris Mason 已提交
498 499
	if (btrfs_header_nritems(&mid->header) >
	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
500 501
		return 0;

502 503 504
	if (btrfs_header_nritems(&mid->header) < 2)
		err_on_enospc = 1;

505 506
	left_buf = read_node_slot(root, parent_buf, pslot - 1);
	right_buf = read_node_slot(root, parent_buf, pslot + 1);
507 508

	/* first, try to make some room in the middle buffer */
509
	if (left_buf) {
510 511 512 513 514 515
		wret = btrfs_cow_block(trans, root, left_buf,
				       parent_buf, pslot - 1, &left_buf);
		if (wret) {
			ret = wret;
			goto enospc;
		}
C
Chris Mason 已提交
516
		left = btrfs_buffer_node(left_buf);
517
		orig_slot += btrfs_header_nritems(&left->header);
518
		wret = push_node_left(trans, root, left_buf, mid_buf);
519 520
		if (wret < 0)
			ret = wret;
521 522
		if (btrfs_header_nritems(&mid->header) < 2)
			err_on_enospc = 1;
523
	}
524 525 526 527

	/*
	 * then try to empty the right most buffer into the middle
	 */
528
	if (right_buf) {
529 530 531 532 533 534 535
		wret = btrfs_cow_block(trans, root, right_buf,
				       parent_buf, pslot + 1, &right_buf);
		if (wret) {
			ret = wret;
			goto enospc;
		}

C
Chris Mason 已提交
536
		right = btrfs_buffer_node(right_buf);
537
		wret = push_node_left(trans, root, mid_buf, right_buf);
538
		if (wret < 0 && wret != -ENOSPC)
539
			ret = wret;
540
		if (btrfs_header_nritems(&right->header) == 0) {
541
			u64 blocknr = bh_blocknr(right_buf);
542
			clean_tree_block(trans, root, right_buf);
C
Chris Mason 已提交
543 544
			wait_on_buffer(right_buf);
			btrfs_block_release(root, right_buf);
545 546
			right_buf = NULL;
			right = NULL;
547 548
			wret = del_ptr(trans, root, path, level + 1, pslot +
				       1);
549 550
			if (wret)
				ret = wret;
551
			wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
552 553 554
			if (wret)
				ret = wret;
		} else {
C
Chris Mason 已提交
555 556 557 558 559
			btrfs_memcpy(root, parent,
				     &parent->ptrs[pslot + 1].key,
				     &right->ptrs[0].key,
				     sizeof(struct btrfs_disk_key));
			btrfs_mark_buffer_dirty(parent_buf);
560 561
		}
	}
562
	if (btrfs_header_nritems(&mid->header) == 1) {
563 564 565 566 567 568 569 570 571 572
		/*
		 * 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);
573
		wret = balance_node_right(trans, root, mid_buf, left_buf);
574
		if (wret < 0) {
575
			ret = wret;
576 577
			goto enospc;
		}
578 579
		BUG_ON(wret == 1);
	}
580
	if (btrfs_header_nritems(&mid->header) == 0) {
581
		/* we've managed to empty the middle node, drop it */
582
		u64 blocknr = bh_blocknr(mid_buf);
583
		clean_tree_block(trans, root, mid_buf);
C
Chris Mason 已提交
584 585
		wait_on_buffer(mid_buf);
		btrfs_block_release(root, mid_buf);
586 587
		mid_buf = NULL;
		mid = NULL;
588
		wret = del_ptr(trans, root, path, level + 1, pslot);
589 590
		if (wret)
			ret = wret;
591
		wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
592 593
		if (wret)
			ret = wret;
594 595
	} else {
		/* update the parent key to reflect our changes */
C
Chris Mason 已提交
596 597 598 599
		btrfs_memcpy(root, parent,
			     &parent->ptrs[pslot].key, &mid->ptrs[0].key,
			     sizeof(struct btrfs_disk_key));
		btrfs_mark_buffer_dirty(parent_buf);
600
	}
601

602
	/* update the path */
603
	if (left_buf) {
604
		if (btrfs_header_nritems(&left->header) > orig_slot) {
C
Chris Mason 已提交
605
			get_bh(left_buf);
606 607 608 609
			path->nodes[level] = left_buf;
			path->slots[level + 1] -= 1;
			path->slots[level] = orig_slot;
			if (mid_buf)
C
Chris Mason 已提交
610
				btrfs_block_release(root, mid_buf);
611
		} else {
612
			orig_slot -= btrfs_header_nritems(&left->header);
613 614 615
			path->slots[level] = orig_slot;
		}
	}
616
	/* double check we haven't messed things up */
C
Chris Mason 已提交
617
	check_block(root, path, level);
C
Chris Mason 已提交
618 619 620
	if (orig_ptr !=
	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
				path->slots[level]))
621
		BUG();
622
enospc:
623
	if (right_buf)
C
Chris Mason 已提交
624
		btrfs_block_release(root, right_buf);
625
	if (left_buf)
C
Chris Mason 已提交
626
		btrfs_block_release(root, left_buf);
627 628 629
	return ret;
}

630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
/* returns zero if the push worked, non-zero otherwise */
static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
				struct btrfs_root *root,
				struct btrfs_path *path, int level)
{
	struct buffer_head *right_buf;
	struct buffer_head *mid_buf;
	struct buffer_head *left_buf;
	struct buffer_head *parent_buf = NULL;
	struct btrfs_node *right = NULL;
	struct btrfs_node *mid;
	struct btrfs_node *left = NULL;
	struct btrfs_node *parent = NULL;
	int ret = 0;
	int wret;
	int pslot;
	int orig_slot = path->slots[level];
	u64 orig_ptr;

	if (level == 0)
		return 1;

	mid_buf = path->nodes[level];
	mid = btrfs_buffer_node(mid_buf);
	orig_ptr = btrfs_node_blockptr(mid, orig_slot);

	if (level < BTRFS_MAX_LEVEL - 1)
		parent_buf = path->nodes[level + 1];
	pslot = path->slots[level + 1];

	if (!parent_buf)
		return 1;
	parent = btrfs_buffer_node(parent_buf);

	left_buf = read_node_slot(root, parent_buf, pslot - 1);

	/* first, try to make some room in the middle buffer */
	if (left_buf) {
		u32 left_nr;
		left = btrfs_buffer_node(left_buf);
		left_nr = btrfs_header_nritems(&left->header);
C
Chris Mason 已提交
671 672 673
		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
			wret = 1;
		} else {
674 675 676 677 678 679 680 681 682
			ret = btrfs_cow_block(trans, root, left_buf, parent_buf,
					      pslot - 1, &left_buf);
			if (ret)
				wret = 1;
			else {
				left = btrfs_buffer_node(left_buf);
				wret = push_node_left(trans, root,
						      left_buf, mid_buf);
			}
C
Chris Mason 已提交
683
		}
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
		if (wret < 0)
			ret = wret;
		if (wret == 0) {
			orig_slot += left_nr;
			btrfs_memcpy(root, parent,
				     &parent->ptrs[pslot].key,
				     &mid->ptrs[0].key,
				     sizeof(struct btrfs_disk_key));
			btrfs_mark_buffer_dirty(parent_buf);
			if (btrfs_header_nritems(&left->header) > orig_slot) {
				path->nodes[level] = left_buf;
				path->slots[level + 1] -= 1;
				path->slots[level] = orig_slot;
				btrfs_block_release(root, mid_buf);
			} else {
				orig_slot -=
					btrfs_header_nritems(&left->header);
				path->slots[level] = orig_slot;
				btrfs_block_release(root, left_buf);
			}
			check_node(root, path, level);
			return 0;
		}
		btrfs_block_release(root, left_buf);
	}
	right_buf = read_node_slot(root, parent_buf, pslot + 1);

	/*
	 * then try to empty the right most buffer into the middle
	 */
	if (right_buf) {
C
Chris Mason 已提交
715
		u32 right_nr;
716
		right = btrfs_buffer_node(right_buf);
C
Chris Mason 已提交
717 718 719 720
		right_nr = btrfs_header_nritems(&right->header);
		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
			wret = 1;
		} else {
721 722 723 724 725 726 727 728 729 730
			ret = btrfs_cow_block(trans, root, right_buf,
					      parent_buf, pslot + 1,
					      &right_buf);
			if (ret)
				wret = 1;
			else {
				right = btrfs_buffer_node(right_buf);
				wret = balance_node_right(trans, root,
							  right_buf, mid_buf);
			}
C
Chris Mason 已提交
731
		}
732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
		if (wret < 0)
			ret = wret;
		if (wret == 0) {
			btrfs_memcpy(root, parent,
				     &parent->ptrs[pslot + 1].key,
				     &right->ptrs[0].key,
				     sizeof(struct btrfs_disk_key));
			btrfs_mark_buffer_dirty(parent_buf);
			if (btrfs_header_nritems(&mid->header) <= orig_slot) {
				path->nodes[level] = right_buf;
				path->slots[level + 1] += 1;
				path->slots[level] = orig_slot -
					btrfs_header_nritems(&mid->header);
				btrfs_block_release(root, mid_buf);
			} else {
				btrfs_block_release(root, right_buf);
			}
			check_node(root, path, level);
			return 0;
		}
		btrfs_block_release(root, right_buf);
	}
	check_node(root, path, level);
	return 1;
}

758 759 760 761
/*
 * readahead one full node of leaves
 */
static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
762
			     int level, int slot)
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
{
	struct btrfs_node *node;
	int i;
	u32 nritems;
	u64 item_objectid;
	u64 blocknr;
	u64 search;
	u64 cluster_start;
	int ret;
	int nread = 0;
	int direction = path->reada;
	struct radix_tree_root found;
	unsigned long gang[8];
	struct buffer_head *bh;

778 779 780 781
	if (level == 0)
		return;

	if (!path->nodes[level])
782 783
		return;

784
	node = btrfs_buffer_node(path->nodes[level]);
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811
	search = btrfs_node_blockptr(node, slot);
	bh = btrfs_find_tree_block(root, search);
	if (bh) {
		brelse(bh);
		return;
	}

	init_bit_radix(&found);
	nritems = btrfs_header_nritems(&node->header);
	for (i = slot; i < nritems; i++) {
		item_objectid = btrfs_disk_key_objectid(&node->ptrs[i].key);
		blocknr = btrfs_node_blockptr(node, i);
		set_radix_bit(&found, blocknr);
	}
	if (direction > 0) {
		cluster_start = search - 4;
		if (cluster_start > search)
			cluster_start = 0;
	} else
		cluster_start = search + 4;
	while(1) {
		ret = find_first_radix_bit(&found, gang, 0, ARRAY_SIZE(gang));
		if (!ret)
			break;
		for (i = 0; i < ret; i++) {
			blocknr = gang[i];
			clear_radix_bit(&found, blocknr);
812
			if (nread > 32)
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
				continue;
			if (direction > 0 && cluster_start <= blocknr &&
			    cluster_start + 8 > blocknr) {
				cluster_start = blocknr;
				readahead_tree_block(root, blocknr);
				nread++;
			} else if (direction < 0 && cluster_start >= blocknr &&
				   blocknr + 8 > cluster_start) {
				cluster_start = blocknr;
				readahead_tree_block(root, blocknr);
				nread++;
			}
		}
	}
}
C
Chris Mason 已提交
828 829 830 831 832 833
/*
 * 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 已提交
834 835
 * be inserted, and 1 is returned.  If there are other errors during the
 * search a negative error number is returned.
C
Chris Mason 已提交
836 837 838 839
 *
 * 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 已提交
840
 */
841 842 843
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)
844
{
C
Chris Mason 已提交
845 846
	struct buffer_head *b;
	struct buffer_head *cow_buf;
C
Chris Mason 已提交
847
	struct btrfs_node *c;
848
	u64 blocknr;
849 850 851
	int slot;
	int ret;
	int level;
852
	int should_reada = p->reada;
853 854
	u8 lowest_level = 0;

855 856
	lowest_level = p->lowest_level;
	WARN_ON(lowest_level && ins_len);
C
Chris Mason 已提交
857 858
	WARN_ON(p->nodes[0] != NULL);
	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
859 860
again:
	b = root->node;
C
Chris Mason 已提交
861
	get_bh(b);
862
	while (b) {
C
Chris Mason 已提交
863 864
		c = btrfs_buffer_node(b);
		level = btrfs_header_level(&c->header);
C
Chris Mason 已提交
865 866
		if (cow) {
			int wret;
C
Chris Mason 已提交
867 868 869
			wret = btrfs_cow_block(trans, root, b,
					       p->nodes[level + 1],
					       p->slots[level + 1],
870
					       &cow_buf);
871 872 873 874
			if (wret) {
				btrfs_block_release(root, cow_buf);
				return wret;
			}
C
Chris Mason 已提交
875
			b = cow_buf;
C
Chris Mason 已提交
876
			c = btrfs_buffer_node(b);
C
Chris Mason 已提交
877 878
		}
		BUG_ON(!cow && ins_len);
C
Chris Mason 已提交
879 880 881
		if (level != btrfs_header_level(&c->header))
			WARN_ON(1);
		level = btrfs_header_level(&c->header);
882
		p->nodes[level] = b;
C
Chris Mason 已提交
883
		ret = check_block(root, p, level);
C
Chris Mason 已提交
884 885
		if (ret)
			return -1;
886
		ret = bin_search(c, key, &slot);
887
		if (!btrfs_is_leaf(c)) {
888 889 890
			if (ret && slot > 0)
				slot -= 1;
			p->slots[level] = slot;
891 892
			if (ins_len > 0 && btrfs_header_nritems(&c->header) >=
			    BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
893
				int sret = split_node(trans, root, p, level);
C
Chris Mason 已提交
894 895 896 897
				BUG_ON(sret > 0);
				if (sret)
					return sret;
				b = p->nodes[level];
C
Chris Mason 已提交
898
				c = btrfs_buffer_node(b);
C
Chris Mason 已提交
899
				slot = p->slots[level];
900
			} else if (ins_len < 0) {
901 902
				int sret = balance_level(trans, root, p,
							 level);
903 904 905 906 907
				if (sret)
					return sret;
				b = p->nodes[level];
				if (!b)
					goto again;
C
Chris Mason 已提交
908
				c = btrfs_buffer_node(b);
909
				slot = p->slots[level];
910
				BUG_ON(btrfs_header_nritems(&c->header) == 1);
C
Chris Mason 已提交
911
			}
912 913 914
			/* this is only true while dropping a snapshot */
			if (level == lowest_level)
				break;
915
			blocknr = btrfs_node_blockptr(c, slot);
916 917
			if (should_reada)
				reada_for_search(root, p, level, slot);
918
			b = read_tree_block(root, btrfs_node_blockptr(c, slot));
919

920
		} else {
C
Chris Mason 已提交
921
			struct btrfs_leaf *l = (struct btrfs_leaf *)c;
922
			p->slots[level] = slot;
C
Chris Mason 已提交
923
			if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
C
Chris Mason 已提交
924
			    sizeof(struct btrfs_item) + ins_len) {
925 926
				int sret = split_leaf(trans, root, key,
						      p, ins_len);
C
Chris Mason 已提交
927 928 929 930
				BUG_ON(sret > 0);
				if (sret)
					return sret;
			}
931 932 933
			return ret;
		}
	}
C
Chris Mason 已提交
934
	return 1;
935 936
}

C
Chris Mason 已提交
937 938 939 940 941 942
/*
 * 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 已提交
943 944 945
 *
 * 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 已提交
946
 */
947 948 949
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)
950 951
{
	int i;
C
Chris Mason 已提交
952
	int ret = 0;
C
Chris Mason 已提交
953 954
	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
		struct btrfs_node *t;
955
		int tslot = path->slots[i];
956
		if (!path->nodes[i])
957
			break;
C
Chris Mason 已提交
958
		t = btrfs_buffer_node(path->nodes[i]);
C
Chris Mason 已提交
959 960
		btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key));
		btrfs_mark_buffer_dirty(path->nodes[i]);
961 962 963
		if (tslot != 0)
			break;
	}
C
Chris Mason 已提交
964
	return ret;
965 966
}

C
Chris Mason 已提交
967 968
/*
 * try to push data from one node into the next node left in the
969
 * tree.
C
Chris Mason 已提交
970 971 972
 *
 * 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 已提交
973
 */
974
static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
975 976
			  *root, struct buffer_head *dst_buf, struct
			  buffer_head *src_buf)
977
{
C
Chris Mason 已提交
978 979
	struct btrfs_node *src = btrfs_buffer_node(src_buf);
	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
980
	int push_items = 0;
981 982
	int src_nritems;
	int dst_nritems;
C
Chris Mason 已提交
983
	int ret = 0;
984

985 986
	src_nritems = btrfs_header_nritems(&src->header);
	dst_nritems = btrfs_header_nritems(&dst->header);
C
Chris Mason 已提交
987
	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
988

989
	if (push_items <= 0) {
990
		return 1;
991
	}
992

993
	if (src_nritems < push_items)
994 995
		push_items = src_nritems;

C
Chris Mason 已提交
996 997
	btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs,
		     push_items * sizeof(struct btrfs_key_ptr));
998
	if (push_items < src_nritems) {
C
Chris Mason 已提交
999
		btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items,
C
Chris Mason 已提交
1000
			(src_nritems - push_items) *
C
Chris Mason 已提交
1001
			sizeof(struct btrfs_key_ptr));
1002
	}
1003 1004
	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
C
Chris Mason 已提交
1005 1006
	btrfs_mark_buffer_dirty(src_buf);
	btrfs_mark_buffer_dirty(dst_buf);
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
	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
 */
1019
static int balance_node_right(struct btrfs_trans_handle *trans, struct
C
Chris Mason 已提交
1020 1021
			      btrfs_root *root, struct buffer_head *dst_buf,
			      struct buffer_head *src_buf)
1022
{
C
Chris Mason 已提交
1023 1024
	struct btrfs_node *src = btrfs_buffer_node(src_buf);
	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
1025 1026 1027 1028 1029 1030
	int push_items = 0;
	int max_push;
	int src_nritems;
	int dst_nritems;
	int ret = 0;

1031 1032
	src_nritems = btrfs_header_nritems(&src->header);
	dst_nritems = btrfs_header_nritems(&dst->header);
C
Chris Mason 已提交
1033
	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
	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 已提交
1045 1046 1047 1048 1049 1050
	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));
1051

1052 1053
	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
1054

C
Chris Mason 已提交
1055 1056
	btrfs_mark_buffer_dirty(src_buf);
	btrfs_mark_buffer_dirty(dst_buf);
C
Chris Mason 已提交
1057
	return ret;
1058 1059
}

C
Chris Mason 已提交
1060 1061 1062 1063
/*
 * 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 已提交
1064 1065
 *
 * returns zero on success or < 0 on failure.
C
Chris Mason 已提交
1066
 */
1067 1068
static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
			   *root, struct btrfs_path *path, int level)
C
Chris Mason 已提交
1069
{
C
Chris Mason 已提交
1070
	struct buffer_head *t;
C
Chris Mason 已提交
1071 1072
	struct btrfs_node *lower;
	struct btrfs_node *c;
C
Chris Mason 已提交
1073
	struct btrfs_disk_key *lower_key;
C
Chris Mason 已提交
1074 1075 1076 1077

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

1078
	t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr, 0);
1079 1080
	if (IS_ERR(t))
		return PTR_ERR(t);
C
Chris Mason 已提交
1081
	c = btrfs_buffer_node(t);
C
Chris Mason 已提交
1082
	memset(c, 0, root->blocksize);
1083 1084
	btrfs_set_header_nritems(&c->header, 1);
	btrfs_set_header_level(&c->header, level);
1085
	btrfs_set_header_blocknr(&c->header, bh_blocknr(t));
1086
	btrfs_set_header_generation(&c->header, trans->transid);
1087
	btrfs_set_header_owner(&c->header, root->root_key.objectid);
C
Chris Mason 已提交
1088
	lower = btrfs_buffer_node(path->nodes[level-1]);
C
Chris Mason 已提交
1089 1090
	memcpy(c->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(c->header.fsid));
1091
	if (btrfs_is_leaf(lower))
C
Chris Mason 已提交
1092
		lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
C
Chris Mason 已提交
1093
	else
C
Chris Mason 已提交
1094
		lower_key = &lower->ptrs[0].key;
C
Chris Mason 已提交
1095 1096
	btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key,
		     sizeof(struct btrfs_disk_key));
1097
	btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1]));
1098

C
Chris Mason 已提交
1099
	btrfs_mark_buffer_dirty(t);
1100

C
Chris Mason 已提交
1101
	/* the super has an extra ref to root->node */
C
Chris Mason 已提交
1102
	btrfs_block_release(root, root->node);
C
Chris Mason 已提交
1103
	root->node = t;
C
Chris Mason 已提交
1104
	get_bh(t);
C
Chris Mason 已提交
1105 1106 1107 1108 1109
	path->nodes[level] = t;
	path->slots[level] = 0;
	return 0;
}

C
Chris Mason 已提交
1110 1111 1112
/*
 * worker function to insert a single pointer in a node.
 * the node should have enough room for the pointer already
C
Chris Mason 已提交
1113
 *
C
Chris Mason 已提交
1114 1115
 * slot and level indicate where you want the key to go, and
 * blocknr is the block the key points to.
C
Chris Mason 已提交
1116 1117
 *
 * returns zero on success and < 0 on any error
C
Chris Mason 已提交
1118
 */
1119 1120 1121
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 已提交
1122
{
C
Chris Mason 已提交
1123
	struct btrfs_node *lower;
C
Chris Mason 已提交
1124
	int nritems;
C
Chris Mason 已提交
1125 1126

	BUG_ON(!path->nodes[level]);
C
Chris Mason 已提交
1127
	lower = btrfs_buffer_node(path->nodes[level]);
1128
	nritems = btrfs_header_nritems(&lower->header);
C
Chris Mason 已提交
1129 1130
	if (slot > nritems)
		BUG();
C
Chris Mason 已提交
1131
	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
C
Chris Mason 已提交
1132 1133
		BUG();
	if (slot != nritems) {
C
Chris Mason 已提交
1134 1135 1136
		btrfs_memmove(root, lower, lower->ptrs + slot + 1,
			      lower->ptrs + slot,
			      (nritems - slot) * sizeof(struct btrfs_key_ptr));
C
Chris Mason 已提交
1137
	}
C
Chris Mason 已提交
1138 1139
	btrfs_memcpy(root, lower, &lower->ptrs[slot].key,
		     key, sizeof(struct btrfs_disk_key));
1140
	btrfs_set_node_blockptr(lower, slot, blocknr);
1141
	btrfs_set_header_nritems(&lower->header, nritems + 1);
C
Chris Mason 已提交
1142
	btrfs_mark_buffer_dirty(path->nodes[level]);
1143
	check_node(root, path, level);
C
Chris Mason 已提交
1144 1145 1146
	return 0;
}

C
Chris Mason 已提交
1147 1148 1149 1150 1151 1152
/*
 * 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 已提交
1153 1154
 *
 * returns 0 on success and < 0 on failure
C
Chris Mason 已提交
1155
 */
1156 1157
static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_path *path, int level)
1158
{
C
Chris Mason 已提交
1159
	struct buffer_head *t;
C
Chris Mason 已提交
1160
	struct btrfs_node *c;
C
Chris Mason 已提交
1161
	struct buffer_head *split_buffer;
C
Chris Mason 已提交
1162
	struct btrfs_node *split;
1163
	int mid;
C
Chris Mason 已提交
1164
	int ret;
C
Chris Mason 已提交
1165
	int wret;
1166
	u32 c_nritems;
1167

C
Chris Mason 已提交
1168
	t = path->nodes[level];
C
Chris Mason 已提交
1169
	c = btrfs_buffer_node(t);
C
Chris Mason 已提交
1170 1171
	if (t == root->node) {
		/* trying to split the root, lets make a new one */
1172
		ret = insert_new_root(trans, root, path, level + 1);
C
Chris Mason 已提交
1173 1174
		if (ret)
			return ret;
1175 1176 1177 1178 1179 1180 1181 1182
	} else {
		ret = push_nodes_for_insert(trans, root, path, level);
		t = path->nodes[level];
		c = btrfs_buffer_node(t);
		if (!ret &&
		    btrfs_header_nritems(&c->header) <
		    BTRFS_NODEPTRS_PER_BLOCK(root) - 1)
			return 0;
1183 1184
		if (ret < 0)
			return ret;
1185
	}
1186

1187
	c_nritems = btrfs_header_nritems(&c->header);
1188
	split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr, 0);
1189 1190 1191
	if (IS_ERR(split_buffer))
		return PTR_ERR(split_buffer);

C
Chris Mason 已提交
1192
	split = btrfs_buffer_node(split_buffer);
1193
	btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
1194
	btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
1195
	btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer));
1196
	btrfs_set_header_generation(&split->header, trans->transid);
1197
	btrfs_set_header_owner(&split->header, root->root_key.objectid);
C
Chris Mason 已提交
1198 1199
	memcpy(split->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(split->header.fsid));
1200
	mid = (c_nritems + 1) / 2;
C
Chris Mason 已提交
1201 1202
	btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid,
		     (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
1203 1204
	btrfs_set_header_nritems(&split->header, c_nritems - mid);
	btrfs_set_header_nritems(&c->header, mid);
C
Chris Mason 已提交
1205 1206
	ret = 0;

C
Chris Mason 已提交
1207 1208
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(split_buffer);
1209
	wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
1210
			  bh_blocknr(split_buffer), path->slots[level + 1] + 1,
C
Chris Mason 已提交
1211
			  level + 1);
C
Chris Mason 已提交
1212 1213 1214
	if (wret)
		ret = wret;

C
Chris Mason 已提交
1215
	if (path->slots[level] >= mid) {
C
Chris Mason 已提交
1216
		path->slots[level] -= mid;
C
Chris Mason 已提交
1217
		btrfs_block_release(root, t);
C
Chris Mason 已提交
1218 1219 1220
		path->nodes[level] = split_buffer;
		path->slots[level + 1] += 1;
	} else {
C
Chris Mason 已提交
1221
		btrfs_block_release(root, split_buffer);
1222
	}
C
Chris Mason 已提交
1223
	return ret;
1224 1225
}

C
Chris Mason 已提交
1226 1227 1228 1229 1230
/*
 * 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 已提交
1231
static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
1232 1233
{
	int data_len;
1234 1235
	int nritems = btrfs_header_nritems(&l->header);
	int end = min(nritems, start + nr) - 1;
1236 1237 1238

	if (!nr)
		return 0;
C
Chris Mason 已提交
1239 1240 1241
	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;
1242
	WARN_ON(data_len < 0);
1243 1244 1245
	return data_len;
}

1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
/*
 * 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 已提交
1257 1258 1259
/*
 * 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 已提交
1260 1261 1262
 *
 * 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 已提交
1263
 */
1264 1265
static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
			   *root, struct btrfs_path *path, int data_size)
C
Chris Mason 已提交
1266
{
C
Chris Mason 已提交
1267 1268
	struct buffer_head *left_buf = path->nodes[0];
	struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf);
C
Chris Mason 已提交
1269
	struct btrfs_leaf *right;
C
Chris Mason 已提交
1270 1271 1272
	struct buffer_head *right_buf;
	struct buffer_head *upper;
	struct btrfs_node *upper_node;
C
Chris Mason 已提交
1273 1274 1275 1276 1277
	int slot;
	int i;
	int free_space;
	int push_space = 0;
	int push_items = 0;
C
Chris Mason 已提交
1278
	struct btrfs_item *item;
1279 1280
	u32 left_nritems;
	u32 right_nritems;
1281
	int ret;
C
Chris Mason 已提交
1282 1283 1284 1285 1286 1287

	slot = path->slots[1];
	if (!path->nodes[1]) {
		return 1;
	}
	upper = path->nodes[1];
C
Chris Mason 已提交
1288 1289
	upper_node = btrfs_buffer_node(upper);
	if (slot >= btrfs_header_nritems(&upper_node->header) - 1) {
C
Chris Mason 已提交
1290 1291
		return 1;
	}
C
Chris Mason 已提交
1292 1293 1294
	right_buf = read_tree_block(root,
		    btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1));
	right = btrfs_buffer_leaf(right_buf);
C
Chris Mason 已提交
1295
	free_space = btrfs_leaf_free_space(root, right);
C
Chris Mason 已提交
1296
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1297
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1298 1299
		return 1;
	}
C
Chris Mason 已提交
1300
	/* cow and double check */
1301 1302 1303 1304 1305 1306
	ret = btrfs_cow_block(trans, root, right_buf, upper,
			      slot + 1, &right_buf);
	if (ret) {
		btrfs_block_release(root, right_buf);
		return 1;
	}
C
Chris Mason 已提交
1307
	right = btrfs_buffer_leaf(right_buf);
C
Chris Mason 已提交
1308
	free_space = btrfs_leaf_free_space(root, right);
C
Chris Mason 已提交
1309
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1310
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1311 1312 1313
		return 1;
	}

1314
	left_nritems = btrfs_header_nritems(&left->header);
1315 1316 1317 1318 1319
	if (left_nritems == 0) {
		btrfs_block_release(root, right_buf);
		return 1;
	}
	for (i = left_nritems - 1; i >= 1; i--) {
C
Chris Mason 已提交
1320 1321 1322
		item = left->items + i;
		if (path->slots[0] == i)
			push_space += data_size + sizeof(*item);
C
Chris Mason 已提交
1323 1324
		if (btrfs_item_size(item) + sizeof(*item) + push_space >
		    free_space)
C
Chris Mason 已提交
1325 1326
			break;
		push_items++;
C
Chris Mason 已提交
1327
		push_space += btrfs_item_size(item) + sizeof(*item);
C
Chris Mason 已提交
1328 1329
	}
	if (push_items == 0) {
C
Chris Mason 已提交
1330
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1331 1332
		return 1;
	}
1333 1334
	if (push_items == left_nritems)
		WARN_ON(1);
1335
	right_nritems = btrfs_header_nritems(&right->header);
C
Chris Mason 已提交
1336
	/* push left to right */
C
Chris Mason 已提交
1337
	push_space = btrfs_item_end(left->items + left_nritems - push_items);
C
Chris Mason 已提交
1338
	push_space -= leaf_data_end(root, left);
C
Chris Mason 已提交
1339
	/* make room in the right data area */
C
Chris Mason 已提交
1340 1341 1342 1343 1344
	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 已提交
1345
	/* copy from the left data area */
C
Chris Mason 已提交
1346 1347 1348 1349 1350
	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 已提交
1351
		right_nritems * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1352
	/* copy the items from left to right */
C
Chris Mason 已提交
1353 1354 1355
	btrfs_memcpy(root, right, right->items, left->items +
		     left_nritems - push_items,
		     push_items * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1356 1357

	/* update the item pointers */
1358 1359
	right_nritems += push_items;
	btrfs_set_header_nritems(&right->header, right_nritems);
C
Chris Mason 已提交
1360
	push_space = BTRFS_LEAF_DATA_SIZE(root);
1361
	for (i = 0; i < right_nritems; i++) {
C
Chris Mason 已提交
1362 1363 1364
		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 已提交
1365
	}
1366 1367
	left_nritems -= push_items;
	btrfs_set_header_nritems(&left->header, left_nritems);
C
Chris Mason 已提交
1368

C
Chris Mason 已提交
1369 1370
	btrfs_mark_buffer_dirty(left_buf);
	btrfs_mark_buffer_dirty(right_buf);
1371

C
Chris Mason 已提交
1372
	btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key,
C
Chris Mason 已提交
1373
		&right->items[0].key, sizeof(struct btrfs_disk_key));
C
Chris Mason 已提交
1374
	btrfs_mark_buffer_dirty(upper);
C
Chris Mason 已提交
1375

C
Chris Mason 已提交
1376
	/* then fixup the leaf pointer in the path */
1377 1378
	if (path->slots[0] >= left_nritems) {
		path->slots[0] -= left_nritems;
C
Chris Mason 已提交
1379
		btrfs_block_release(root, path->nodes[0]);
C
Chris Mason 已提交
1380 1381 1382
		path->nodes[0] = right_buf;
		path->slots[1] += 1;
	} else {
C
Chris Mason 已提交
1383
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1384
	}
1385 1386
	if (path->nodes[1])
		check_node(root, path, 1);
C
Chris Mason 已提交
1387 1388
	return 0;
}
C
Chris Mason 已提交
1389 1390 1391 1392
/*
 * 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
 */
1393 1394
static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
			  *root, struct btrfs_path *path, int data_size)
1395
{
C
Chris Mason 已提交
1396 1397 1398
	struct buffer_head *right_buf = path->nodes[0];
	struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf);
	struct buffer_head *t;
C
Chris Mason 已提交
1399
	struct btrfs_leaf *left;
1400 1401 1402 1403 1404
	int slot;
	int i;
	int free_space;
	int push_space = 0;
	int push_items = 0;
C
Chris Mason 已提交
1405
	struct btrfs_item *item;
1406
	u32 old_left_nritems;
C
Chris Mason 已提交
1407 1408
	int ret = 0;
	int wret;
1409 1410 1411 1412 1413 1414 1415 1416

	slot = path->slots[1];
	if (slot == 0) {
		return 1;
	}
	if (!path->nodes[1]) {
		return 1;
	}
C
Chris Mason 已提交
1417 1418 1419
	t = read_tree_block(root,
	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1));
	left = btrfs_buffer_leaf(t);
C
Chris Mason 已提交
1420
	free_space = btrfs_leaf_free_space(root, left);
C
Chris Mason 已提交
1421
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1422
		btrfs_block_release(root, t);
1423 1424
		return 1;
	}
C
Chris Mason 已提交
1425 1426

	/* cow and double check */
1427 1428 1429 1430 1431
	ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
	if (ret) {
		/* we hit -ENOSPC, but it isn't fatal here */
		return 1;
	}
C
Chris Mason 已提交
1432
	left = btrfs_buffer_leaf(t);
C
Chris Mason 已提交
1433
	free_space = btrfs_leaf_free_space(root, left);
C
Chris Mason 已提交
1434
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1435
		btrfs_block_release(root, t);
C
Chris Mason 已提交
1436 1437 1438
		return 1;
	}

1439 1440 1441 1442 1443 1444
	if (btrfs_header_nritems(&right->header) == 0) {
		btrfs_block_release(root, t);
		return 1;
	}

	for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) {
1445 1446 1447
		item = right->items + i;
		if (path->slots[0] == i)
			push_space += data_size + sizeof(*item);
C
Chris Mason 已提交
1448 1449
		if (btrfs_item_size(item) + sizeof(*item) + push_space >
		    free_space)
1450 1451
			break;
		push_items++;
C
Chris Mason 已提交
1452
		push_space += btrfs_item_size(item) + sizeof(*item);
1453 1454
	}
	if (push_items == 0) {
C
Chris Mason 已提交
1455
		btrfs_block_release(root, t);
1456 1457
		return 1;
	}
1458 1459
	if (push_items == btrfs_header_nritems(&right->header))
		WARN_ON(1);
1460
	/* push data from right to left */
C
Chris Mason 已提交
1461 1462 1463
	btrfs_memcpy(root, left, left->items +
		     btrfs_header_nritems(&left->header),
		     right->items, push_items * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1464
	push_space = BTRFS_LEAF_DATA_SIZE(root) -
C
Chris Mason 已提交
1465
		     btrfs_item_offset(right->items + push_items -1);
C
Chris Mason 已提交
1466 1467 1468 1469 1470
	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);
1471
	old_left_nritems = btrfs_header_nritems(&left->header);
1472 1473
	BUG_ON(old_left_nritems < 0);

C
Chris Mason 已提交
1474
	for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
C
Chris Mason 已提交
1475 1476 1477
		u32 ioff = btrfs_item_offset(left->items + i);
		btrfs_set_item_offset(left->items + i, ioff -
				     (BTRFS_LEAF_DATA_SIZE(root) -
C
Chris Mason 已提交
1478 1479
				      btrfs_item_offset(left->items +
						        old_left_nritems - 1)));
1480
	}
1481
	btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
1482 1483

	/* fixup right node */
C
Chris Mason 已提交
1484
	push_space = btrfs_item_offset(right->items + push_items - 1) -
C
Chris Mason 已提交
1485
		     leaf_data_end(root, right);
C
Chris Mason 已提交
1486 1487 1488 1489 1490
	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,
1491
		(btrfs_header_nritems(&right->header) - push_items) *
C
Chris Mason 已提交
1492
		sizeof(struct btrfs_item));
1493 1494 1495
	btrfs_set_header_nritems(&right->header,
				 btrfs_header_nritems(&right->header) -
				 push_items);
C
Chris Mason 已提交
1496
	push_space = BTRFS_LEAF_DATA_SIZE(root);
1497

1498
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1499 1500 1501
		btrfs_set_item_offset(right->items + i, push_space -
				      btrfs_item_size(right->items + i));
		push_space = btrfs_item_offset(right->items + i);
1502
	}
1503

C
Chris Mason 已提交
1504 1505
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(right_buf);
1506

1507
	wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
C
Chris Mason 已提交
1508 1509
	if (wret)
		ret = wret;
1510 1511 1512 1513

	/* then fixup the leaf pointer in the path */
	if (path->slots[0] < push_items) {
		path->slots[0] += old_left_nritems;
C
Chris Mason 已提交
1514
		btrfs_block_release(root, path->nodes[0]);
1515
		path->nodes[0] = t;
1516 1517
		path->slots[1] -= 1;
	} else {
C
Chris Mason 已提交
1518
		btrfs_block_release(root, t);
1519 1520
		path->slots[0] -= push_items;
	}
1521
	BUG_ON(path->slots[0] < 0);
1522 1523
	if (path->nodes[1])
		check_node(root, path, 1);
C
Chris Mason 已提交
1524
	return ret;
1525 1526
}

C
Chris Mason 已提交
1527 1528 1529
/*
 * 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 已提交
1530 1531
 *
 * returns 0 if all went well and < 0 on failure.
C
Chris Mason 已提交
1532
 */
1533
static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1534 1535
		      *root, struct btrfs_key *ins_key,
		      struct btrfs_path *path, int data_size)
1536
{
C
Chris Mason 已提交
1537
	struct buffer_head *l_buf;
C
Chris Mason 已提交
1538
	struct btrfs_leaf *l;
1539
	u32 nritems;
1540 1541
	int mid;
	int slot;
C
Chris Mason 已提交
1542
	struct btrfs_leaf *right;
C
Chris Mason 已提交
1543
	struct buffer_head *right_buffer;
C
Chris Mason 已提交
1544
	int space_needed = data_size + sizeof(struct btrfs_item);
1545 1546 1547
	int data_copy_size;
	int rt_data_off;
	int i;
1548
	int ret = 0;
C
Chris Mason 已提交
1549
	int wret;
1550 1551
	int double_split = 0;
	struct btrfs_disk_key disk_key;
C
Chris Mason 已提交
1552

C
Chris Mason 已提交
1553
	/* first try to make some room by pushing left and right */
1554
	wret = push_leaf_left(trans, root, path, data_size);
C
Chris Mason 已提交
1555 1556 1557
	if (wret < 0)
		return wret;
	if (wret) {
1558
		wret = push_leaf_right(trans, root, path, data_size);
C
Chris Mason 已提交
1559 1560 1561
		if (wret < 0)
			return wret;
	}
C
Chris Mason 已提交
1562
	l_buf = path->nodes[0];
C
Chris Mason 已提交
1563
	l = btrfs_buffer_leaf(l_buf);
C
Chris Mason 已提交
1564 1565

	/* did the pushes work? */
C
Chris Mason 已提交
1566 1567
	if (btrfs_leaf_free_space(root, l) >=
	    sizeof(struct btrfs_item) + data_size)
C
Chris Mason 已提交
1568 1569
		return 0;

C
Chris Mason 已提交
1570
	if (!path->nodes[1]) {
1571
		ret = insert_new_root(trans, root, path, 1);
C
Chris Mason 已提交
1572 1573 1574
		if (ret)
			return ret;
	}
1575
	slot = path->slots[0];
1576
	nritems = btrfs_header_nritems(&l->header);
1577
	mid = (nritems + 1)/ 2;
1578

1579
	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0);
1580 1581 1582
	if (IS_ERR(right_buffer))
		return PTR_ERR(right_buffer);

C
Chris Mason 已提交
1583
	right = btrfs_buffer_leaf(right_buffer);
C
Chris Mason 已提交
1584
	memset(&right->header, 0, sizeof(right->header));
1585
	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1586
	btrfs_set_header_generation(&right->header, trans->transid);
1587
	btrfs_set_header_owner(&right->header, root->root_key.objectid);
1588
	btrfs_set_header_level(&right->header, 0);
C
Chris Mason 已提交
1589 1590
	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(right->header.fsid));
1591 1592 1593 1594 1595 1596 1597 1598 1599
	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,
1600
						  bh_blocknr(right_buffer),
1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620
						  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,
1621
						  bh_blocknr(right_buffer),
1622
						  path->slots[1], 1);
1623 1624 1625 1626 1627
				if (wret)
					ret = wret;
				btrfs_block_release(root, path->nodes[0]);
				path->nodes[0] = right_buffer;
				path->slots[0] = 0;
1628 1629 1630 1631 1632 1633
				if (path->slots[1] == 0) {
					wret = fixup_low_keys(trans, root,
					           path, &disk_key, 1);
					if (wret)
						ret = wret;
				}
1634 1635 1636 1637 1638 1639 1640
				return ret;
			}
			mid = slot;
			double_split = 1;
		}
	}
	btrfs_set_header_nritems(&right->header, nritems - mid);
C
Chris Mason 已提交
1641 1642
	data_copy_size = btrfs_item_end(l->items + mid) -
			 leaf_data_end(root, l);
C
Chris Mason 已提交
1643 1644 1645 1646 1647 1648
	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 已提交
1649 1650
	rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
		      btrfs_item_end(l->items + mid);
C
Chris Mason 已提交
1651

C
Chris Mason 已提交
1652
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1653
		u32 ioff = btrfs_item_offset(right->items + i);
C
Chris Mason 已提交
1654 1655
		btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
	}
C
Chris Mason 已提交
1656

1657
	btrfs_set_header_nritems(&l->header, mid);
C
Chris Mason 已提交
1658
	ret = 0;
1659
	wret = insert_ptr(trans, root, path, &right->items[0].key,
1660
			  bh_blocknr(right_buffer), path->slots[1] + 1, 1);
C
Chris Mason 已提交
1661 1662
	if (wret)
		ret = wret;
C
Chris Mason 已提交
1663 1664
	btrfs_mark_buffer_dirty(right_buffer);
	btrfs_mark_buffer_dirty(l_buf);
1665
	BUG_ON(path->slots[0] != slot);
1666
	if (mid <= slot) {
C
Chris Mason 已提交
1667
		btrfs_block_release(root, path->nodes[0]);
1668
		path->nodes[0] = right_buffer;
1669 1670
		path->slots[0] -= mid;
		path->slots[1] += 1;
1671
	} else
C
Chris Mason 已提交
1672
		btrfs_block_release(root, right_buffer);
1673
	BUG_ON(path->slots[0] < 0);
1674
	check_node(root, path, 1);
1675 1676 1677

	if (!double_split)
		return ret;
1678
	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0);
1679 1680 1681
	if (IS_ERR(right_buffer))
		return PTR_ERR(right_buffer);

1682 1683
	right = btrfs_buffer_leaf(right_buffer);
	memset(&right->header, 0, sizeof(right->header));
1684
	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1685
	btrfs_set_header_generation(&right->header, trans->transid);
1686
	btrfs_set_header_owner(&right->header, root->root_key.objectid);
1687
	btrfs_set_header_level(&right->header, 0);
C
Chris Mason 已提交
1688 1689
	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(right->header.fsid));
1690 1691 1692 1693
	btrfs_cpu_key_to_disk(&disk_key, ins_key);
	btrfs_set_header_nritems(&right->header, 0);
	wret = insert_ptr(trans, root, path,
			  &disk_key,
1694
			  bh_blocknr(right_buffer),
1695 1696 1697
			  path->slots[1], 1);
	if (wret)
		ret = wret;
1698 1699 1700 1701 1702
	if (path->slots[1] == 0) {
		wret = fixup_low_keys(trans, root, path, &disk_key, 1);
		if (wret)
			ret = wret;
	}
1703 1704 1705 1706 1707
	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);
1708 1709 1710
	return ret;
}

C
Chris Mason 已提交
1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766
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 */
	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;
}

1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820
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 已提交
1821 1822 1823 1824
/*
 * 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.
 */
1825 1826 1827
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)
1828
{
C
Chris Mason 已提交
1829
	int ret = 0;
1830
	int slot;
1831
	int slot_orig;
C
Chris Mason 已提交
1832
	struct btrfs_leaf *leaf;
C
Chris Mason 已提交
1833
	struct buffer_head *leaf_buf;
1834
	u32 nritems;
1835
	unsigned int data_end;
C
Chris Mason 已提交
1836 1837 1838
	struct btrfs_disk_key disk_key;

	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1839

C
Chris Mason 已提交
1840
	/* create a root if there isn't one */
C
Chris Mason 已提交
1841
	if (!root->node)
C
Chris Mason 已提交
1842
		BUG();
1843
	ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
1844
	if (ret == 0) {
1845
		return -EEXIST;
C
Chris Mason 已提交
1846
	}
1847 1848
	if (ret < 0)
		goto out;
1849

1850 1851
	slot_orig = path->slots[0];
	leaf_buf = path->nodes[0];
C
Chris Mason 已提交
1852
	leaf = btrfs_buffer_leaf(leaf_buf);
C
Chris Mason 已提交
1853

1854
	nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
1855
	data_end = leaf_data_end(root, leaf);
1856

C
Chris Mason 已提交
1857
	if (btrfs_leaf_free_space(root, leaf) <
1858
	    sizeof(struct btrfs_item) + data_size) {
1859
		BUG();
1860
	}
1861
	slot = path->slots[0];
1862
	BUG_ON(slot < 0);
1863 1864
	if (slot != nritems) {
		int i;
C
Chris Mason 已提交
1865
		unsigned int old_data = btrfs_item_end(leaf->items + slot);
1866 1867 1868 1869 1870

		/*
		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
		 */
		/* first correct the data pointers */
C
Chris Mason 已提交
1871
		for (i = slot; i < nritems; i++) {
C
Chris Mason 已提交
1872
			u32 ioff = btrfs_item_offset(leaf->items + i);
C
Chris Mason 已提交
1873 1874 1875
			btrfs_set_item_offset(leaf->items + i,
					      ioff - data_size);
		}
1876 1877

		/* shift the items */
C
Chris Mason 已提交
1878 1879 1880
		btrfs_memmove(root, leaf, leaf->items + slot + 1,
			      leaf->items + slot,
			      (nritems - slot) * sizeof(struct btrfs_item));
1881 1882

		/* shift the data */
C
Chris Mason 已提交
1883 1884 1885
		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
			      data_end - data_size, btrfs_leaf_data(leaf) +
			      data_end, old_data - data_end);
1886 1887
		data_end = old_data;
	}
1888
	/* setup the item for the new data */
C
Chris Mason 已提交
1889 1890
	btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key,
		     sizeof(struct btrfs_disk_key));
C
Chris Mason 已提交
1891 1892
	btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
	btrfs_set_item_size(leaf->items + slot, data_size);
1893
	btrfs_set_header_nritems(&leaf->header, nritems + 1);
C
Chris Mason 已提交
1894
	btrfs_mark_buffer_dirty(leaf_buf);
C
Chris Mason 已提交
1895 1896

	ret = 0;
1897
	if (slot == 0)
1898
		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
C
Chris Mason 已提交
1899

C
Chris Mason 已提交
1900
	if (btrfs_leaf_free_space(root, leaf) < 0)
1901
		BUG();
1902
	check_leaf(root, path, 0);
1903
out:
1904 1905 1906 1907 1908 1909 1910
	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.
 */
1911 1912 1913
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_key *cpu_key, void *data, u32
		      data_size)
1914 1915
{
	int ret = 0;
C
Chris Mason 已提交
1916
	struct btrfs_path *path;
1917 1918
	u8 *ptr;

C
Chris Mason 已提交
1919 1920 1921
	path = btrfs_alloc_path();
	BUG_ON(!path);
	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
1922
	if (!ret) {
C
Chris Mason 已提交
1923 1924 1925
		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 已提交
1926
			     ptr, data, data_size);
C
Chris Mason 已提交
1927
		btrfs_mark_buffer_dirty(path->nodes[0]);
1928
	}
C
Chris Mason 已提交
1929
	btrfs_free_path(path);
C
Chris Mason 已提交
1930
	return ret;
1931 1932
}

C
Chris Mason 已提交
1933
/*
C
Chris Mason 已提交
1934
 * delete the pointer from a given node.
C
Chris Mason 已提交
1935 1936 1937 1938 1939
 *
 * 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.
 */
1940 1941
static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path, int level, int slot)
1942
{
C
Chris Mason 已提交
1943
	struct btrfs_node *node;
C
Chris Mason 已提交
1944
	struct buffer_head *parent = path->nodes[level];
1945
	u32 nritems;
C
Chris Mason 已提交
1946
	int ret = 0;
1947
	int wret;
1948

C
Chris Mason 已提交
1949
	node = btrfs_buffer_node(parent);
1950
	nritems = btrfs_header_nritems(&node->header);
1951
	if (slot != nritems -1) {
C
Chris Mason 已提交
1952 1953 1954 1955
		btrfs_memmove(root, node, node->ptrs + slot,
			      node->ptrs + slot + 1,
			      sizeof(struct btrfs_key_ptr) *
			      (nritems - slot - 1));
1956
	}
1957 1958 1959
	nritems--;
	btrfs_set_header_nritems(&node->header, nritems);
	if (nritems == 0 && parent == root->node) {
C
Chris Mason 已提交
1960 1961
		struct btrfs_header *header = btrfs_buffer_header(root->node);
		BUG_ON(btrfs_header_level(header) != 1);
1962
		/* just turn the root into a leaf and break */
C
Chris Mason 已提交
1963
		btrfs_set_header_level(header, 0);
1964
	} else if (slot == 0) {
1965
		wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
C
Chris Mason 已提交
1966
				      level + 1);
C
Chris Mason 已提交
1967 1968
		if (wret)
			ret = wret;
1969
	}
C
Chris Mason 已提交
1970
	btrfs_mark_buffer_dirty(parent);
C
Chris Mason 已提交
1971
	return ret;
1972 1973
}

C
Chris Mason 已提交
1974 1975 1976 1977
/*
 * delete the item at the leaf level in path.  If that empties
 * the leaf, remove it from the tree
 */
1978 1979
int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path)
1980 1981
{
	int slot;
C
Chris Mason 已提交
1982
	struct btrfs_leaf *leaf;
C
Chris Mason 已提交
1983
	struct buffer_head *leaf_buf;
1984 1985
	int doff;
	int dsize;
C
Chris Mason 已提交
1986 1987
	int ret = 0;
	int wret;
1988
	u32 nritems;
1989

1990
	leaf_buf = path->nodes[0];
C
Chris Mason 已提交
1991
	leaf = btrfs_buffer_leaf(leaf_buf);
1992
	slot = path->slots[0];
C
Chris Mason 已提交
1993 1994
	doff = btrfs_item_offset(leaf->items + slot);
	dsize = btrfs_item_size(leaf->items + slot);
1995
	nritems = btrfs_header_nritems(&leaf->header);
1996

1997
	if (slot != nritems - 1) {
1998
		int i;
C
Chris Mason 已提交
1999
		int data_end = leaf_data_end(root, leaf);
C
Chris Mason 已提交
2000 2001 2002 2003
		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
			      data_end + dsize,
			      btrfs_leaf_data(leaf) + data_end,
			      doff - data_end);
C
Chris Mason 已提交
2004
		for (i = slot + 1; i < nritems; i++) {
C
Chris Mason 已提交
2005
			u32 ioff = btrfs_item_offset(leaf->items + i);
C
Chris Mason 已提交
2006 2007
			btrfs_set_item_offset(leaf->items + i, ioff + dsize);
		}
C
Chris Mason 已提交
2008 2009 2010 2011
		btrfs_memmove(root, leaf, leaf->items + slot,
			      leaf->items + slot + 1,
			      sizeof(struct btrfs_item) *
			      (nritems - slot - 1));
2012
	}
2013 2014
	btrfs_set_header_nritems(&leaf->header, nritems - 1);
	nritems--;
C
Chris Mason 已提交
2015
	/* delete the leaf if we've emptied it */
2016
	if (nritems == 0) {
2017
		if (leaf_buf == root->node) {
2018
			btrfs_set_header_level(&leaf->header, 0);
2019
		} else {
2020
			clean_tree_block(trans, root, leaf_buf);
C
Chris Mason 已提交
2021
			wait_on_buffer(leaf_buf);
2022
			wret = del_ptr(trans, root, path, 1, path->slots[1]);
C
Chris Mason 已提交
2023 2024
			if (wret)
				ret = wret;
2025
			wret = btrfs_free_extent(trans, root,
2026
						 bh_blocknr(leaf_buf), 1, 1);
C
Chris Mason 已提交
2027 2028
			if (wret)
				ret = wret;
2029
		}
2030
	} else {
2031
		int used = leaf_space_used(leaf, 0, nritems);
C
Chris Mason 已提交
2032
		if (slot == 0) {
2033 2034
			wret = fixup_low_keys(trans, root, path,
					      &leaf->items[0].key, 1);
C
Chris Mason 已提交
2035 2036 2037 2038
			if (wret)
				ret = wret;
		}

C
Chris Mason 已提交
2039
		/* delete the leaf if it is mostly empty */
C
Chris Mason 已提交
2040
		if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
2041 2042 2043 2044
			/* push_leaf_left fixes the path.
			 * make sure the path still points to our leaf
			 * for possible call to del_ptr below
			 */
2045
			slot = path->slots[1];
C
Chris Mason 已提交
2046
			get_bh(leaf_buf);
2047
			wret = push_leaf_left(trans, root, path, 1);
2048
			if (wret < 0 && wret != -ENOSPC)
C
Chris Mason 已提交
2049
				ret = wret;
2050
			if (path->nodes[0] == leaf_buf &&
2051
			    btrfs_header_nritems(&leaf->header)) {
2052
				wret = push_leaf_right(trans, root, path, 1);
2053
				if (wret < 0 && wret != -ENOSPC)
C
Chris Mason 已提交
2054 2055
					ret = wret;
			}
2056
			if (btrfs_header_nritems(&leaf->header) == 0) {
2057
				u64 blocknr = bh_blocknr(leaf_buf);
2058
				clean_tree_block(trans, root, leaf_buf);
C
Chris Mason 已提交
2059
				wait_on_buffer(leaf_buf);
2060
				wret = del_ptr(trans, root, path, 1, slot);
C
Chris Mason 已提交
2061 2062
				if (wret)
					ret = wret;
C
Chris Mason 已提交
2063
				btrfs_block_release(root, leaf_buf);
2064 2065
				wret = btrfs_free_extent(trans, root, blocknr,
							 1, 1);
C
Chris Mason 已提交
2066 2067
				if (wret)
					ret = wret;
C
Chris Mason 已提交
2068
			} else {
C
Chris Mason 已提交
2069
				btrfs_mark_buffer_dirty(leaf_buf);
C
Chris Mason 已提交
2070
				btrfs_block_release(root, leaf_buf);
2071
			}
2072
		} else {
C
Chris Mason 已提交
2073
			btrfs_mark_buffer_dirty(leaf_buf);
2074 2075
		}
	}
C
Chris Mason 已提交
2076
	return ret;
2077 2078
}

C
Chris Mason 已提交
2079 2080
/*
 * walk up the tree as far as required to find the next leaf.
C
Chris Mason 已提交
2081 2082
 * returns 0 if it found something or 1 if there are no greater leaves.
 * returns < 0 on io errors.
C
Chris Mason 已提交
2083
 */
C
Chris Mason 已提交
2084
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
2085 2086 2087 2088
{
	int slot;
	int level = 1;
	u64 blocknr;
C
Chris Mason 已提交
2089 2090 2091
	struct buffer_head *c;
	struct btrfs_node *c_node;
	struct buffer_head *next = NULL;
2092

C
Chris Mason 已提交
2093
	while(level < BTRFS_MAX_LEVEL) {
2094
		if (!path->nodes[level])
C
Chris Mason 已提交
2095
			return 1;
2096 2097
		slot = path->slots[level] + 1;
		c = path->nodes[level];
C
Chris Mason 已提交
2098 2099
		c_node = btrfs_buffer_node(c);
		if (slot >= btrfs_header_nritems(&c_node->header)) {
2100 2101 2102
			level++;
			continue;
		}
C
Chris Mason 已提交
2103
		blocknr = btrfs_node_blockptr(c_node, slot);
C
Chris Mason 已提交
2104
		if (next)
C
Chris Mason 已提交
2105
			btrfs_block_release(root, next);
2106 2107
		if (path->reada)
			reada_for_search(root, path, level, slot);
2108 2109 2110 2111 2112 2113 2114
		next = read_tree_block(root, blocknr);
		break;
	}
	path->slots[level] = slot;
	while(1) {
		level--;
		c = path->nodes[level];
C
Chris Mason 已提交
2115
		btrfs_block_release(root, c);
2116 2117 2118 2119
		path->nodes[level] = next;
		path->slots[level] = 0;
		if (!level)
			break;
2120 2121
		if (path->reada)
			reada_for_search(root, path, level, slot);
2122
		next = read_tree_block(root,
C
Chris Mason 已提交
2123
		       btrfs_node_blockptr(btrfs_buffer_node(next), 0));
2124 2125 2126
	}
	return 0;
}