ctree.c 60.1 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
	struct btrfs_path *path;
	path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
46
	if (path) {
C
Chris Mason 已提交
47
		btrfs_init_path(path);
48 49
		path->reada = 1;
	}
C
Chris Mason 已提交
50
	return path;
C
Chris Mason 已提交
51 52
}

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

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

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

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

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

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

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

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;
}

164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
static int should_defrag_leaf(struct buffer_head *bh)
{
	struct btrfs_leaf *leaf = btrfs_buffer_leaf(bh);
	struct btrfs_disk_key *key;
	u32 nritems;

	if (buffer_defrag(bh))
		return 1;

	nritems = btrfs_header_nritems(&leaf->header);
	if (nritems == 0)
		return 0;

	key = &leaf->items[0].key;
	if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY)
		return 1;

	key = &leaf->items[nritems-1].key;
	if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY)
		return 1;
	if (nritems > 4) {
		key = &leaf->items[nritems/2].key;
		if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY)
			return 1;
	}
	return 0;
}

192 193
int btrfs_realloc_node(struct btrfs_trans_handle *trans,
		       struct btrfs_root *root, struct buffer_head *parent,
194
		       int cache_only, u64 *last_ret)
195 196 197 198 199
{
	struct btrfs_node *parent_node;
	struct buffer_head *cur_bh;
	struct buffer_head *tmp_bh;
	u64 blocknr;
200 201
	u64 search_start = *last_ret;
	u64 last_block = 0;
202 203 204 205 206 207
	u64 other;
	u32 parent_nritems;
	int start_slot;
	int end_slot;
	int i;
	int err = 0;
208
	int parent_level;
209 210 211 212 213 214 215 216 217 218 219

	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);
	}
220 221 222
	if (buffer_defrag_done(parent))
		return 0;

223 224
	parent_node = btrfs_buffer_node(parent);
	parent_nritems = btrfs_header_nritems(&parent_node->header);
225
	parent_level = btrfs_header_level(&parent_node->header);
226 227 228 229 230 231 232 233 234 235

	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);
236 237
		if (last_block == 0)
			last_block = blocknr;
238 239 240 241 242 243 244 245
		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);
		}
246 247
		if (close) {
			last_block = blocknr;
248
			continue;
249
		}
250 251 252

		cur_bh = btrfs_find_tree_block(root, blocknr);
		if (!cur_bh || !buffer_uptodate(cur_bh) ||
253 254 255
		    buffer_locked(cur_bh) ||
		    (parent_level != 1 && !buffer_defrag(cur_bh)) ||
		    (parent_level == 1 && !should_defrag_leaf(cur_bh))) {
256 257 258 259
			if (cache_only) {
				brelse(cur_bh);
				continue;
			}
260 261 262 263 264
			if (!cur_bh || !buffer_uptodate(cur_bh) ||
			    buffer_locked(cur_bh)) {
				brelse(cur_bh);
				cur_bh = read_tree_block(root, blocknr);
			}
265
		}
266 267 268
		if (search_start == 0)
			search_start = last_block & ~((u64)65535);

269 270 271
		err = __btrfs_cow_block(trans, root, cur_bh, parent, i,
					&tmp_bh, search_start,
					min(8, end_slot - i));
Y
Yan 已提交
272 273
		if (err) {
			brelse(cur_bh);
274
			break;
Y
Yan 已提交
275
		}
276
		search_start = bh_blocknr(tmp_bh);
277 278 279
		*last_ret = search_start;
		if (parent_level == 1)
			clear_buffer_defrag(tmp_bh);
280
		set_buffer_defrag_done(tmp_bh);
281 282 283 284 285
		brelse(tmp_bh);
	}
	return err;
}

C
Chris Mason 已提交
286 287 288 289 290
/*
 * 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 已提交
291 292
static inline unsigned int leaf_data_end(struct btrfs_root *root,
					 struct btrfs_leaf *leaf)
293
{
294
	u32 nr = btrfs_header_nritems(&leaf->header);
295
	if (nr == 0)
C
Chris Mason 已提交
296
		return BTRFS_LEAF_DATA_SIZE(root);
C
Chris Mason 已提交
297
	return btrfs_item_offset(leaf->items + nr - 1);
298 299
}

C
Chris Mason 已提交
300 301 302
/*
 * compare two keys in a memcmp fashion
 */
C
Chris Mason 已提交
303
static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
304
{
C
Chris Mason 已提交
305 306 307 308 309
	struct btrfs_key k1;

	btrfs_disk_key_to_cpu(&k1, disk);

	if (k1.objectid > k2->objectid)
310
		return 1;
C
Chris Mason 已提交
311
	if (k1.objectid < k2->objectid)
312
		return -1;
C
Chris Mason 已提交
313 314 315 316
	if (k1.flags > k2->flags)
		return 1;
	if (k1.flags < k2->flags)
		return -1;
317 318 319 320
	if (k1.offset > k2->offset)
		return 1;
	if (k1.offset < k2->offset)
		return -1;
321 322
	return 0;
}
C
Chris Mason 已提交
323

C
Chris Mason 已提交
324 325
static int check_node(struct btrfs_root *root, struct btrfs_path *path,
		      int level)
C
Chris Mason 已提交
326
{
C
Chris Mason 已提交
327
	struct btrfs_node *parent = NULL;
C
Chris Mason 已提交
328
	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
C
Chris Mason 已提交
329
	int parent_slot;
330 331
	int slot;
	struct btrfs_key cpukey;
332
	u32 nritems = btrfs_header_nritems(&node->header);
C
Chris Mason 已提交
333 334

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

337
	slot = path->slots[level];
338
	BUG_ON(!buffer_uptodate(path->nodes[level]));
339 340
	BUG_ON(nritems == 0);
	if (parent) {
C
Chris Mason 已提交
341
		struct btrfs_disk_key *parent_key;
A
Aneesh 已提交
342 343

		parent_slot = path->slots[level + 1];
C
Chris Mason 已提交
344 345
		parent_key = &parent->ptrs[parent_slot].key;
		BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
C
Chris Mason 已提交
346
			      sizeof(struct btrfs_disk_key)));
347
		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
348
		       btrfs_header_blocknr(&node->header));
C
Chris Mason 已提交
349
	}
C
Chris Mason 已提交
350
	BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
351 352 353 354 355 356 357
	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 已提交
358 359 360 361
	}
	return 0;
}

C
Chris Mason 已提交
362 363
static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
		      int level)
C
Chris Mason 已提交
364
{
C
Chris Mason 已提交
365
	struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]);
C
Chris Mason 已提交
366
	struct btrfs_node *parent = NULL;
C
Chris Mason 已提交
367
	int parent_slot;
368 369 370
	int slot = path->slots[0];
	struct btrfs_key cpukey;

371
	u32 nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
372 373

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

C
Chris Mason 已提交
376
	BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
377 378 379 380 381

	if (nritems == 0)
		return 0;

	if (parent) {
C
Chris Mason 已提交
382
		struct btrfs_disk_key *parent_key;
A
Aneesh 已提交
383 384

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

C
Chris Mason 已提交
387
		BUG_ON(memcmp(parent_key, &leaf->items[0].key,
C
Chris Mason 已提交
388
		       sizeof(struct btrfs_disk_key)));
389
		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
390
		       btrfs_header_blocknr(&leaf->header));
C
Chris Mason 已提交
391
	}
392 393 394 395 396 397 398 399 400 401 402
	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 已提交
403
	}
404 405
	BUG_ON(btrfs_item_offset(leaf->items) +
	       btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root));
C
Chris Mason 已提交
406 407 408
	return 0;
}

C
Chris Mason 已提交
409 410
static int check_block(struct btrfs_root *root, struct btrfs_path *path,
			int level)
C
Chris Mason 已提交
411
{
C
Chris Mason 已提交
412 413 414 415
	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 已提交
416
	if (level == 0)
C
Chris Mason 已提交
417 418
		return check_leaf(root, path, level);
	return check_node(root, path, level);
C
Chris Mason 已提交
419 420
}

C
Chris Mason 已提交
421 422 423 424 425 426 427 428 429
/*
 * 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 已提交
430
static int generic_bin_search(char *p, int item_size, struct btrfs_key *key,
431 432 433 434 435 436
		       int max, int *slot)
{
	int low = 0;
	int high = max;
	int mid;
	int ret;
C
Chris Mason 已提交
437
	struct btrfs_disk_key *tmp;
438 439 440

	while(low < high) {
		mid = (low + high) / 2;
C
Chris Mason 已提交
441
		tmp = (struct btrfs_disk_key *)(p + mid * item_size);
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
		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 已提交
457 458 459 460
/*
 * simple bin_search frontend that does the right thing for
 * leaves vs nodes
 */
C
Chris Mason 已提交
461
static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
462
{
463
	if (btrfs_is_leaf(c)) {
C
Chris Mason 已提交
464
		struct btrfs_leaf *l = (struct btrfs_leaf *)c;
C
Chris Mason 已提交
465 466
		return generic_bin_search((void *)l->items,
					  sizeof(struct btrfs_item),
467 468
					  key, btrfs_header_nritems(&c->header),
					  slot);
469
	} else {
C
Chris Mason 已提交
470 471
		return generic_bin_search((void *)c->ptrs,
					  sizeof(struct btrfs_key_ptr),
472 473
					  key, btrfs_header_nritems(&c->header),
					  slot);
474 475 476 477
	}
	return -1;
}

C
Chris Mason 已提交
478 479
static struct buffer_head *read_node_slot(struct btrfs_root *root,
				   struct buffer_head *parent_buf,
480 481
				   int slot)
{
C
Chris Mason 已提交
482
	struct btrfs_node *node = btrfs_buffer_node(parent_buf);
483 484
	if (slot < 0)
		return NULL;
485
	if (slot >= btrfs_header_nritems(&node->header))
486
		return NULL;
487
	return read_tree_block(root, btrfs_node_blockptr(node, slot));
488 489
}

490 491
static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
			 *root, struct btrfs_path *path, int level)
492
{
C
Chris Mason 已提交
493 494 495 496
	struct buffer_head *right_buf;
	struct buffer_head *mid_buf;
	struct buffer_head *left_buf;
	struct buffer_head *parent_buf = NULL;
C
Chris Mason 已提交
497 498 499 500
	struct btrfs_node *right = NULL;
	struct btrfs_node *mid;
	struct btrfs_node *left = NULL;
	struct btrfs_node *parent = NULL;
501 502 503 504
	int ret = 0;
	int wret;
	int pslot;
	int orig_slot = path->slots[level];
505
	int err_on_enospc = 0;
506
	u64 orig_ptr;
507 508 509 510 511

	if (level == 0)
		return 0;

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

C
Chris Mason 已提交
515
	if (level < BTRFS_MAX_LEVEL - 1)
516 517 518
		parent_buf = path->nodes[level + 1];
	pslot = path->slots[level + 1];

C
Chris Mason 已提交
519 520 521 522
	/*
	 * deal with the case where there is only one pointer in the root
	 * by promoting the node below to a root
	 */
523
	if (!parent_buf) {
C
Chris Mason 已提交
524
		struct buffer_head *child;
525
		u64 blocknr = bh_blocknr(mid_buf);
526

527
		if (btrfs_header_nritems(&mid->header) != 1)
528 529 530 531 532 533 534
			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 已提交
535 536
		clean_tree_block(trans, root, mid_buf);
		wait_on_buffer(mid_buf);
537
		/* once for the path */
C
Chris Mason 已提交
538
		btrfs_block_release(root, mid_buf);
539
		/* once for the root ptr */
C
Chris Mason 已提交
540
		btrfs_block_release(root, mid_buf);
541
		return btrfs_free_extent(trans, root, blocknr, 1, 1);
542
	}
C
Chris Mason 已提交
543
	parent = btrfs_buffer_node(parent_buf);
544

C
Chris Mason 已提交
545 546
	if (btrfs_header_nritems(&mid->header) >
	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
547 548
		return 0;

549 550 551
	if (btrfs_header_nritems(&mid->header) < 2)
		err_on_enospc = 1;

552 553
	left_buf = read_node_slot(root, parent_buf, pslot - 1);
	if (left_buf) {
554 555 556 557 558 559
		wret = btrfs_cow_block(trans, root, left_buf,
				       parent_buf, pslot - 1, &left_buf);
		if (wret) {
			ret = wret;
			goto enospc;
		}
560 561 562 563 564 565 566 567 568 569 570 571 572
	}
	right_buf = read_node_slot(root, parent_buf, pslot + 1);
	if (right_buf) {
		wret = btrfs_cow_block(trans, root, right_buf,
				       parent_buf, pslot + 1, &right_buf);
		if (wret) {
			ret = wret;
			goto enospc;
		}
	}

	/* first, try to make some room in the middle buffer */
	if (left_buf) {
C
Chris Mason 已提交
573
		left = btrfs_buffer_node(left_buf);
574
		orig_slot += btrfs_header_nritems(&left->header);
575
		wret = push_node_left(trans, root, left_buf, mid_buf);
576 577
		if (wret < 0)
			ret = wret;
578 579
		if (btrfs_header_nritems(&mid->header) < 2)
			err_on_enospc = 1;
580
	}
581 582 583 584

	/*
	 * then try to empty the right most buffer into the middle
	 */
585
	if (right_buf) {
C
Chris Mason 已提交
586
		right = btrfs_buffer_node(right_buf);
587
		wret = push_node_left(trans, root, mid_buf, right_buf);
588
		if (wret < 0 && wret != -ENOSPC)
589
			ret = wret;
590
		if (btrfs_header_nritems(&right->header) == 0) {
591
			u64 blocknr = bh_blocknr(right_buf);
592
			clean_tree_block(trans, root, right_buf);
C
Chris Mason 已提交
593 594
			wait_on_buffer(right_buf);
			btrfs_block_release(root, right_buf);
595 596
			right_buf = NULL;
			right = NULL;
597 598
			wret = del_ptr(trans, root, path, level + 1, pslot +
				       1);
599 600
			if (wret)
				ret = wret;
601
			wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
602 603 604
			if (wret)
				ret = wret;
		} else {
C
Chris Mason 已提交
605 606 607 608 609
			btrfs_memcpy(root, parent,
				     &parent->ptrs[pslot + 1].key,
				     &right->ptrs[0].key,
				     sizeof(struct btrfs_disk_key));
			btrfs_mark_buffer_dirty(parent_buf);
610 611
		}
	}
612
	if (btrfs_header_nritems(&mid->header) == 1) {
613 614 615 616 617 618 619 620 621 622
		/*
		 * 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);
623
		wret = balance_node_right(trans, root, mid_buf, left_buf);
624
		if (wret < 0) {
625
			ret = wret;
626 627
			goto enospc;
		}
628 629
		BUG_ON(wret == 1);
	}
630
	if (btrfs_header_nritems(&mid->header) == 0) {
631
		/* we've managed to empty the middle node, drop it */
632
		u64 blocknr = bh_blocknr(mid_buf);
633
		clean_tree_block(trans, root, mid_buf);
C
Chris Mason 已提交
634 635
		wait_on_buffer(mid_buf);
		btrfs_block_release(root, mid_buf);
636 637
		mid_buf = NULL;
		mid = NULL;
638
		wret = del_ptr(trans, root, path, level + 1, pslot);
639 640
		if (wret)
			ret = wret;
641
		wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
642 643
		if (wret)
			ret = wret;
644 645
	} else {
		/* update the parent key to reflect our changes */
C
Chris Mason 已提交
646 647 648 649
		btrfs_memcpy(root, parent,
			     &parent->ptrs[pslot].key, &mid->ptrs[0].key,
			     sizeof(struct btrfs_disk_key));
		btrfs_mark_buffer_dirty(parent_buf);
650
	}
651

652
	/* update the path */
653
	if (left_buf) {
654
		if (btrfs_header_nritems(&left->header) > orig_slot) {
C
Chris Mason 已提交
655
			get_bh(left_buf);
656 657 658 659
			path->nodes[level] = left_buf;
			path->slots[level + 1] -= 1;
			path->slots[level] = orig_slot;
			if (mid_buf)
C
Chris Mason 已提交
660
				btrfs_block_release(root, mid_buf);
661
		} else {
662
			orig_slot -= btrfs_header_nritems(&left->header);
663 664 665
			path->slots[level] = orig_slot;
		}
	}
666
	/* double check we haven't messed things up */
C
Chris Mason 已提交
667
	check_block(root, path, level);
C
Chris Mason 已提交
668 669 670
	if (orig_ptr !=
	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
				path->slots[level]))
671
		BUG();
672
enospc:
673
	if (right_buf)
C
Chris Mason 已提交
674
		btrfs_block_release(root, right_buf);
675
	if (left_buf)
C
Chris Mason 已提交
676
		btrfs_block_release(root, left_buf);
677 678 679
	return ret;
}

680 681 682 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 715 716 717 718 719 720
/* 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 已提交
721 722 723
		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
			wret = 1;
		} else {
724 725 726 727 728 729 730 731 732
			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 已提交
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 758 759 760 761 762 763 764
		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 已提交
765
		u32 right_nr;
766
		right = btrfs_buffer_node(right_buf);
C
Chris Mason 已提交
767 768 769 770
		right_nr = btrfs_header_nritems(&right->header);
		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
			wret = 1;
		} else {
771 772 773 774 775 776 777 778 779 780
			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 已提交
781
		}
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807
		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;
}

808 809 810 811
/*
 * readahead one full node of leaves
 */
static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
812
			     int level, int slot)
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
{
	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;

828 829 830 831
	if (level == 0)
		return;

	if (!path->nodes[level])
832 833
		return;

834
	node = btrfs_buffer_node(path->nodes[level]);
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861
	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);
862
			if (path->reada == 1 && nread > 16)
863
				continue;
864
			if (close_blocks(cluster_start, blocknr)) {
865 866 867 868 869 870 871
				readahead_tree_block(root, blocknr);
				nread++;
				cluster_start = blocknr;
			}
		}
	}
}
C
Chris Mason 已提交
872 873 874 875 876 877
/*
 * 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 已提交
878 879
 * be inserted, and 1 is returned.  If there are other errors during the
 * search a negative error number is returned.
C
Chris Mason 已提交
880 881 882 883
 *
 * 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 已提交
884
 */
885 886 887
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)
888
{
C
Chris Mason 已提交
889
	struct buffer_head *b;
C
Chris Mason 已提交
890
	struct btrfs_node *c;
891
	u64 blocknr;
892 893 894
	int slot;
	int ret;
	int level;
895
	int should_reada = p->reada;
896 897
	u8 lowest_level = 0;

898 899
	lowest_level = p->lowest_level;
	WARN_ON(lowest_level && ins_len);
C
Chris Mason 已提交
900 901
	WARN_ON(p->nodes[0] != NULL);
	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
902 903
again:
	b = root->node;
C
Chris Mason 已提交
904
	get_bh(b);
905
	while (b) {
C
Chris Mason 已提交
906 907
		c = btrfs_buffer_node(b);
		level = btrfs_header_level(&c->header);
C
Chris Mason 已提交
908 909
		if (cow) {
			int wret;
C
Chris Mason 已提交
910 911 912
			wret = btrfs_cow_block(trans, root, b,
					       p->nodes[level + 1],
					       p->slots[level + 1],
Y
Yan 已提交
913
					       &b);
914
			if (wret) {
Y
Yan 已提交
915
				btrfs_block_release(root, b);
916 917
				return wret;
			}
C
Chris Mason 已提交
918
			c = btrfs_buffer_node(b);
C
Chris Mason 已提交
919 920
		}
		BUG_ON(!cow && ins_len);
C
Chris Mason 已提交
921 922 923
		if (level != btrfs_header_level(&c->header))
			WARN_ON(1);
		level = btrfs_header_level(&c->header);
924
		p->nodes[level] = b;
C
Chris Mason 已提交
925
		ret = check_block(root, p, level);
C
Chris Mason 已提交
926 927
		if (ret)
			return -1;
928
		ret = bin_search(c, key, &slot);
929
		if (!btrfs_is_leaf(c)) {
930 931 932
			if (ret && slot > 0)
				slot -= 1;
			p->slots[level] = slot;
933 934
			if (ins_len > 0 && btrfs_header_nritems(&c->header) >=
			    BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
935
				int sret = split_node(trans, root, p, level);
C
Chris Mason 已提交
936 937 938 939
				BUG_ON(sret > 0);
				if (sret)
					return sret;
				b = p->nodes[level];
C
Chris Mason 已提交
940
				c = btrfs_buffer_node(b);
C
Chris Mason 已提交
941
				slot = p->slots[level];
942
			} else if (ins_len < 0) {
943 944
				int sret = balance_level(trans, root, p,
							 level);
945 946 947 948 949
				if (sret)
					return sret;
				b = p->nodes[level];
				if (!b)
					goto again;
C
Chris Mason 已提交
950
				c = btrfs_buffer_node(b);
951
				slot = p->slots[level];
952
				BUG_ON(btrfs_header_nritems(&c->header) == 1);
C
Chris Mason 已提交
953
			}
954 955 956
			/* this is only true while dropping a snapshot */
			if (level == lowest_level)
				break;
957
			blocknr = btrfs_node_blockptr(c, slot);
958 959
			if (should_reada)
				reada_for_search(root, p, level, slot);
960
			b = read_tree_block(root, btrfs_node_blockptr(c, slot));
961

962
		} else {
C
Chris Mason 已提交
963
			struct btrfs_leaf *l = (struct btrfs_leaf *)c;
964
			p->slots[level] = slot;
C
Chris Mason 已提交
965
			if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
C
Chris Mason 已提交
966
			    sizeof(struct btrfs_item) + ins_len) {
967 968
				int sret = split_leaf(trans, root, key,
						      p, ins_len);
C
Chris Mason 已提交
969 970 971 972
				BUG_ON(sret > 0);
				if (sret)
					return sret;
			}
973 974 975
			return ret;
		}
	}
C
Chris Mason 已提交
976
	return 1;
977 978
}

C
Chris Mason 已提交
979 980 981 982 983 984
/*
 * 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 已提交
985 986 987
 *
 * 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 已提交
988
 */
989 990 991
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)
992 993
{
	int i;
C
Chris Mason 已提交
994
	int ret = 0;
C
Chris Mason 已提交
995 996
	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
		struct btrfs_node *t;
997
		int tslot = path->slots[i];
998
		if (!path->nodes[i])
999
			break;
C
Chris Mason 已提交
1000
		t = btrfs_buffer_node(path->nodes[i]);
C
Chris Mason 已提交
1001 1002
		btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key));
		btrfs_mark_buffer_dirty(path->nodes[i]);
1003 1004 1005
		if (tslot != 0)
			break;
	}
C
Chris Mason 已提交
1006
	return ret;
1007 1008
}

C
Chris Mason 已提交
1009 1010
/*
 * try to push data from one node into the next node left in the
1011
 * tree.
C
Chris Mason 已提交
1012 1013 1014
 *
 * 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 已提交
1015
 */
1016
static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
1017 1018
			  *root, struct buffer_head *dst_buf, struct
			  buffer_head *src_buf)
1019
{
C
Chris Mason 已提交
1020 1021
	struct btrfs_node *src = btrfs_buffer_node(src_buf);
	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
1022
	int push_items = 0;
1023 1024
	int src_nritems;
	int dst_nritems;
C
Chris Mason 已提交
1025
	int ret = 0;
1026

1027 1028
	src_nritems = btrfs_header_nritems(&src->header);
	dst_nritems = btrfs_header_nritems(&dst->header);
C
Chris Mason 已提交
1029
	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
1030

1031
	if (push_items <= 0) {
1032
		return 1;
1033
	}
1034

1035
	if (src_nritems < push_items)
1036 1037
		push_items = src_nritems;

C
Chris Mason 已提交
1038 1039
	btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs,
		     push_items * sizeof(struct btrfs_key_ptr));
1040
	if (push_items < src_nritems) {
C
Chris Mason 已提交
1041
		btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items,
C
Chris Mason 已提交
1042
			(src_nritems - push_items) *
C
Chris Mason 已提交
1043
			sizeof(struct btrfs_key_ptr));
1044
	}
1045 1046
	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
C
Chris Mason 已提交
1047 1048
	btrfs_mark_buffer_dirty(src_buf);
	btrfs_mark_buffer_dirty(dst_buf);
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
	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
 */
1061
static int balance_node_right(struct btrfs_trans_handle *trans, struct
C
Chris Mason 已提交
1062 1063
			      btrfs_root *root, struct buffer_head *dst_buf,
			      struct buffer_head *src_buf)
1064
{
C
Chris Mason 已提交
1065 1066
	struct btrfs_node *src = btrfs_buffer_node(src_buf);
	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
1067 1068 1069 1070 1071 1072
	int push_items = 0;
	int max_push;
	int src_nritems;
	int dst_nritems;
	int ret = 0;

1073 1074
	src_nritems = btrfs_header_nritems(&src->header);
	dst_nritems = btrfs_header_nritems(&dst->header);
C
Chris Mason 已提交
1075
	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
1076 1077 1078 1079 1080 1081
	if (push_items <= 0) {
		return 1;
	}

	max_push = src_nritems / 2 + 1;
	/* don't try to empty the node */
Y
Yan 已提交
1082
	if (max_push >= src_nritems)
1083
		return 1;
Y
Yan 已提交
1084

1085 1086 1087
	if (max_push < push_items)
		push_items = max_push;

C
Chris Mason 已提交
1088 1089 1090 1091 1092 1093
	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));
1094

1095 1096
	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
1097

C
Chris Mason 已提交
1098 1099
	btrfs_mark_buffer_dirty(src_buf);
	btrfs_mark_buffer_dirty(dst_buf);
C
Chris Mason 已提交
1100
	return ret;
1101 1102
}

C
Chris Mason 已提交
1103 1104 1105 1106
/*
 * 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 已提交
1107 1108
 *
 * returns zero on success or < 0 on failure.
C
Chris Mason 已提交
1109
 */
1110 1111
static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
			   *root, struct btrfs_path *path, int level)
C
Chris Mason 已提交
1112
{
C
Chris Mason 已提交
1113
	struct buffer_head *t;
C
Chris Mason 已提交
1114 1115
	struct btrfs_node *lower;
	struct btrfs_node *c;
C
Chris Mason 已提交
1116
	struct btrfs_disk_key *lower_key;
C
Chris Mason 已提交
1117 1118 1119 1120

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

1121
	t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr, 0);
1122 1123
	if (IS_ERR(t))
		return PTR_ERR(t);
C
Chris Mason 已提交
1124
	c = btrfs_buffer_node(t);
C
Chris Mason 已提交
1125
	memset(c, 0, root->blocksize);
1126 1127
	btrfs_set_header_nritems(&c->header, 1);
	btrfs_set_header_level(&c->header, level);
1128
	btrfs_set_header_blocknr(&c->header, bh_blocknr(t));
1129
	btrfs_set_header_generation(&c->header, trans->transid);
1130
	btrfs_set_header_owner(&c->header, root->root_key.objectid);
C
Chris Mason 已提交
1131
	lower = btrfs_buffer_node(path->nodes[level-1]);
C
Chris Mason 已提交
1132 1133
	memcpy(c->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(c->header.fsid));
1134
	if (btrfs_is_leaf(lower))
C
Chris Mason 已提交
1135
		lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
C
Chris Mason 已提交
1136
	else
C
Chris Mason 已提交
1137
		lower_key = &lower->ptrs[0].key;
C
Chris Mason 已提交
1138 1139
	btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key,
		     sizeof(struct btrfs_disk_key));
1140
	btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1]));
1141

C
Chris Mason 已提交
1142
	btrfs_mark_buffer_dirty(t);
1143

C
Chris Mason 已提交
1144
	/* the super has an extra ref to root->node */
C
Chris Mason 已提交
1145
	btrfs_block_release(root, root->node);
C
Chris Mason 已提交
1146
	root->node = t;
C
Chris Mason 已提交
1147
	get_bh(t);
C
Chris Mason 已提交
1148 1149 1150 1151 1152
	path->nodes[level] = t;
	path->slots[level] = 0;
	return 0;
}

C
Chris Mason 已提交
1153 1154 1155
/*
 * worker function to insert a single pointer in a node.
 * the node should have enough room for the pointer already
C
Chris Mason 已提交
1156
 *
C
Chris Mason 已提交
1157 1158
 * slot and level indicate where you want the key to go, and
 * blocknr is the block the key points to.
C
Chris Mason 已提交
1159 1160
 *
 * returns zero on success and < 0 on any error
C
Chris Mason 已提交
1161
 */
1162 1163 1164
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 已提交
1165
{
C
Chris Mason 已提交
1166
	struct btrfs_node *lower;
C
Chris Mason 已提交
1167
	int nritems;
C
Chris Mason 已提交
1168 1169

	BUG_ON(!path->nodes[level]);
C
Chris Mason 已提交
1170
	lower = btrfs_buffer_node(path->nodes[level]);
1171
	nritems = btrfs_header_nritems(&lower->header);
C
Chris Mason 已提交
1172 1173
	if (slot > nritems)
		BUG();
C
Chris Mason 已提交
1174
	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
C
Chris Mason 已提交
1175 1176
		BUG();
	if (slot != nritems) {
C
Chris Mason 已提交
1177 1178 1179
		btrfs_memmove(root, lower, lower->ptrs + slot + 1,
			      lower->ptrs + slot,
			      (nritems - slot) * sizeof(struct btrfs_key_ptr));
C
Chris Mason 已提交
1180
	}
C
Chris Mason 已提交
1181 1182
	btrfs_memcpy(root, lower, &lower->ptrs[slot].key,
		     key, sizeof(struct btrfs_disk_key));
1183
	btrfs_set_node_blockptr(lower, slot, blocknr);
1184
	btrfs_set_header_nritems(&lower->header, nritems + 1);
C
Chris Mason 已提交
1185
	btrfs_mark_buffer_dirty(path->nodes[level]);
1186
	check_node(root, path, level);
C
Chris Mason 已提交
1187 1188 1189
	return 0;
}

C
Chris Mason 已提交
1190 1191 1192 1193 1194 1195
/*
 * 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 已提交
1196 1197
 *
 * returns 0 on success and < 0 on failure
C
Chris Mason 已提交
1198
 */
1199 1200
static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_path *path, int level)
1201
{
C
Chris Mason 已提交
1202
	struct buffer_head *t;
C
Chris Mason 已提交
1203
	struct btrfs_node *c;
C
Chris Mason 已提交
1204
	struct buffer_head *split_buffer;
C
Chris Mason 已提交
1205
	struct btrfs_node *split;
1206
	int mid;
C
Chris Mason 已提交
1207
	int ret;
C
Chris Mason 已提交
1208
	int wret;
1209
	u32 c_nritems;
1210

C
Chris Mason 已提交
1211
	t = path->nodes[level];
C
Chris Mason 已提交
1212
	c = btrfs_buffer_node(t);
C
Chris Mason 已提交
1213 1214
	if (t == root->node) {
		/* trying to split the root, lets make a new one */
1215
		ret = insert_new_root(trans, root, path, level + 1);
C
Chris Mason 已提交
1216 1217
		if (ret)
			return ret;
1218 1219 1220 1221 1222 1223 1224 1225
	} 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;
1226 1227
		if (ret < 0)
			return ret;
1228
	}
1229

1230
	c_nritems = btrfs_header_nritems(&c->header);
1231
	split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr, 0);
1232 1233 1234
	if (IS_ERR(split_buffer))
		return PTR_ERR(split_buffer);

C
Chris Mason 已提交
1235
	split = btrfs_buffer_node(split_buffer);
1236
	btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
1237
	btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
1238
	btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer));
1239
	btrfs_set_header_generation(&split->header, trans->transid);
1240
	btrfs_set_header_owner(&split->header, root->root_key.objectid);
C
Chris Mason 已提交
1241 1242
	memcpy(split->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(split->header.fsid));
1243
	mid = (c_nritems + 1) / 2;
C
Chris Mason 已提交
1244 1245
	btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid,
		     (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
1246 1247
	btrfs_set_header_nritems(&split->header, c_nritems - mid);
	btrfs_set_header_nritems(&c->header, mid);
C
Chris Mason 已提交
1248 1249
	ret = 0;

C
Chris Mason 已提交
1250 1251
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(split_buffer);
1252
	wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
1253
			  bh_blocknr(split_buffer), path->slots[level + 1] + 1,
C
Chris Mason 已提交
1254
			  level + 1);
C
Chris Mason 已提交
1255 1256 1257
	if (wret)
		ret = wret;

C
Chris Mason 已提交
1258
	if (path->slots[level] >= mid) {
C
Chris Mason 已提交
1259
		path->slots[level] -= mid;
C
Chris Mason 已提交
1260
		btrfs_block_release(root, t);
C
Chris Mason 已提交
1261 1262 1263
		path->nodes[level] = split_buffer;
		path->slots[level + 1] += 1;
	} else {
C
Chris Mason 已提交
1264
		btrfs_block_release(root, split_buffer);
1265
	}
C
Chris Mason 已提交
1266
	return ret;
1267 1268
}

C
Chris Mason 已提交
1269 1270 1271 1272 1273
/*
 * 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 已提交
1274
static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
1275 1276
{
	int data_len;
1277 1278
	int nritems = btrfs_header_nritems(&l->header);
	int end = min(nritems, start + nr) - 1;
1279 1280 1281

	if (!nr)
		return 0;
C
Chris Mason 已提交
1282 1283 1284
	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;
1285
	WARN_ON(data_len < 0);
1286 1287 1288
	return data_len;
}

1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
/*
 * 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 已提交
1300 1301 1302
/*
 * 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 已提交
1303 1304 1305
 *
 * 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 已提交
1306
 */
1307 1308
static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
			   *root, struct btrfs_path *path, int data_size)
C
Chris Mason 已提交
1309
{
C
Chris Mason 已提交
1310 1311
	struct buffer_head *left_buf = path->nodes[0];
	struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf);
C
Chris Mason 已提交
1312
	struct btrfs_leaf *right;
C
Chris Mason 已提交
1313 1314 1315
	struct buffer_head *right_buf;
	struct buffer_head *upper;
	struct btrfs_node *upper_node;
C
Chris Mason 已提交
1316 1317 1318 1319 1320
	int slot;
	int i;
	int free_space;
	int push_space = 0;
	int push_items = 0;
C
Chris Mason 已提交
1321
	struct btrfs_item *item;
1322 1323
	u32 left_nritems;
	u32 right_nritems;
1324
	int ret;
C
Chris Mason 已提交
1325 1326 1327 1328 1329 1330

	slot = path->slots[1];
	if (!path->nodes[1]) {
		return 1;
	}
	upper = path->nodes[1];
C
Chris Mason 已提交
1331 1332
	upper_node = btrfs_buffer_node(upper);
	if (slot >= btrfs_header_nritems(&upper_node->header) - 1) {
C
Chris Mason 已提交
1333 1334
		return 1;
	}
C
Chris Mason 已提交
1335 1336 1337
	right_buf = read_tree_block(root,
		    btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1));
	right = btrfs_buffer_leaf(right_buf);
C
Chris Mason 已提交
1338
	free_space = btrfs_leaf_free_space(root, right);
C
Chris Mason 已提交
1339
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1340
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1341 1342
		return 1;
	}
C
Chris Mason 已提交
1343
	/* cow and double check */
1344 1345 1346 1347 1348 1349
	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 已提交
1350
	right = btrfs_buffer_leaf(right_buf);
C
Chris Mason 已提交
1351
	free_space = btrfs_leaf_free_space(root, right);
C
Chris Mason 已提交
1352
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1353
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1354 1355 1356
		return 1;
	}

1357
	left_nritems = btrfs_header_nritems(&left->header);
1358 1359 1360 1361 1362
	if (left_nritems == 0) {
		btrfs_block_release(root, right_buf);
		return 1;
	}
	for (i = left_nritems - 1; i >= 1; i--) {
C
Chris Mason 已提交
1363 1364 1365
		item = left->items + i;
		if (path->slots[0] == i)
			push_space += data_size + sizeof(*item);
C
Chris Mason 已提交
1366 1367
		if (btrfs_item_size(item) + sizeof(*item) + push_space >
		    free_space)
C
Chris Mason 已提交
1368 1369
			break;
		push_items++;
C
Chris Mason 已提交
1370
		push_space += btrfs_item_size(item) + sizeof(*item);
C
Chris Mason 已提交
1371 1372
	}
	if (push_items == 0) {
C
Chris Mason 已提交
1373
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1374 1375
		return 1;
	}
1376 1377
	if (push_items == left_nritems)
		WARN_ON(1);
1378
	right_nritems = btrfs_header_nritems(&right->header);
C
Chris Mason 已提交
1379
	/* push left to right */
C
Chris Mason 已提交
1380
	push_space = btrfs_item_end(left->items + left_nritems - push_items);
C
Chris Mason 已提交
1381
	push_space -= leaf_data_end(root, left);
C
Chris Mason 已提交
1382
	/* make room in the right data area */
C
Chris Mason 已提交
1383 1384 1385 1386 1387
	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 已提交
1388
	/* copy from the left data area */
C
Chris Mason 已提交
1389 1390 1391 1392 1393
	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 已提交
1394
		right_nritems * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1395
	/* copy the items from left to right */
C
Chris Mason 已提交
1396 1397 1398
	btrfs_memcpy(root, right, right->items, left->items +
		     left_nritems - push_items,
		     push_items * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1399 1400

	/* update the item pointers */
1401 1402
	right_nritems += push_items;
	btrfs_set_header_nritems(&right->header, right_nritems);
C
Chris Mason 已提交
1403
	push_space = BTRFS_LEAF_DATA_SIZE(root);
1404
	for (i = 0; i < right_nritems; i++) {
C
Chris Mason 已提交
1405 1406 1407
		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 已提交
1408
	}
1409 1410
	left_nritems -= push_items;
	btrfs_set_header_nritems(&left->header, left_nritems);
C
Chris Mason 已提交
1411

C
Chris Mason 已提交
1412 1413
	btrfs_mark_buffer_dirty(left_buf);
	btrfs_mark_buffer_dirty(right_buf);
1414

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

C
Chris Mason 已提交
1419
	/* then fixup the leaf pointer in the path */
1420 1421
	if (path->slots[0] >= left_nritems) {
		path->slots[0] -= left_nritems;
C
Chris Mason 已提交
1422
		btrfs_block_release(root, path->nodes[0]);
C
Chris Mason 已提交
1423 1424 1425
		path->nodes[0] = right_buf;
		path->slots[1] += 1;
	} else {
C
Chris Mason 已提交
1426
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1427
	}
1428 1429
	if (path->nodes[1])
		check_node(root, path, 1);
C
Chris Mason 已提交
1430 1431
	return 0;
}
C
Chris Mason 已提交
1432 1433 1434 1435
/*
 * 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
 */
1436 1437
static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
			  *root, struct btrfs_path *path, int data_size)
1438
{
C
Chris Mason 已提交
1439 1440 1441
	struct buffer_head *right_buf = path->nodes[0];
	struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf);
	struct buffer_head *t;
C
Chris Mason 已提交
1442
	struct btrfs_leaf *left;
1443 1444 1445 1446 1447
	int slot;
	int i;
	int free_space;
	int push_space = 0;
	int push_items = 0;
C
Chris Mason 已提交
1448
	struct btrfs_item *item;
1449
	u32 old_left_nritems;
C
Chris Mason 已提交
1450 1451
	int ret = 0;
	int wret;
1452 1453 1454 1455 1456 1457 1458 1459

	slot = path->slots[1];
	if (slot == 0) {
		return 1;
	}
	if (!path->nodes[1]) {
		return 1;
	}
C
Chris Mason 已提交
1460 1461 1462
	t = read_tree_block(root,
	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1));
	left = btrfs_buffer_leaf(t);
C
Chris Mason 已提交
1463
	free_space = btrfs_leaf_free_space(root, left);
C
Chris Mason 已提交
1464
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1465
		btrfs_block_release(root, t);
1466 1467
		return 1;
	}
C
Chris Mason 已提交
1468 1469

	/* cow and double check */
1470 1471 1472
	ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
	if (ret) {
		/* we hit -ENOSPC, but it isn't fatal here */
Y
Yan 已提交
1473
		btrfs_block_release(root, t);
1474 1475
		return 1;
	}
C
Chris Mason 已提交
1476
	left = btrfs_buffer_leaf(t);
C
Chris Mason 已提交
1477
	free_space = btrfs_leaf_free_space(root, left);
C
Chris Mason 已提交
1478
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1479
		btrfs_block_release(root, t);
C
Chris Mason 已提交
1480 1481 1482
		return 1;
	}

1483 1484 1485 1486 1487 1488
	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++) {
1489 1490 1491
		item = right->items + i;
		if (path->slots[0] == i)
			push_space += data_size + sizeof(*item);
C
Chris Mason 已提交
1492 1493
		if (btrfs_item_size(item) + sizeof(*item) + push_space >
		    free_space)
1494 1495
			break;
		push_items++;
C
Chris Mason 已提交
1496
		push_space += btrfs_item_size(item) + sizeof(*item);
1497 1498
	}
	if (push_items == 0) {
C
Chris Mason 已提交
1499
		btrfs_block_release(root, t);
1500 1501
		return 1;
	}
1502 1503
	if (push_items == btrfs_header_nritems(&right->header))
		WARN_ON(1);
1504
	/* push data from right to left */
C
Chris Mason 已提交
1505 1506 1507
	btrfs_memcpy(root, left, left->items +
		     btrfs_header_nritems(&left->header),
		     right->items, push_items * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1508
	push_space = BTRFS_LEAF_DATA_SIZE(root) -
C
Chris Mason 已提交
1509
		     btrfs_item_offset(right->items + push_items -1);
C
Chris Mason 已提交
1510 1511 1512 1513 1514
	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);
1515
	old_left_nritems = btrfs_header_nritems(&left->header);
1516 1517
	BUG_ON(old_left_nritems < 0);

C
Chris Mason 已提交
1518
	for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
C
Chris Mason 已提交
1519 1520 1521
		u32 ioff = btrfs_item_offset(left->items + i);
		btrfs_set_item_offset(left->items + i, ioff -
				     (BTRFS_LEAF_DATA_SIZE(root) -
C
Chris Mason 已提交
1522 1523
				      btrfs_item_offset(left->items +
						        old_left_nritems - 1)));
1524
	}
1525
	btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
1526 1527

	/* fixup right node */
C
Chris Mason 已提交
1528
	push_space = btrfs_item_offset(right->items + push_items - 1) -
C
Chris Mason 已提交
1529
		     leaf_data_end(root, right);
C
Chris Mason 已提交
1530 1531 1532 1533 1534
	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,
1535
		(btrfs_header_nritems(&right->header) - push_items) *
C
Chris Mason 已提交
1536
		sizeof(struct btrfs_item));
1537 1538 1539
	btrfs_set_header_nritems(&right->header,
				 btrfs_header_nritems(&right->header) -
				 push_items);
C
Chris Mason 已提交
1540
	push_space = BTRFS_LEAF_DATA_SIZE(root);
1541

1542
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1543 1544 1545
		btrfs_set_item_offset(right->items + i, push_space -
				      btrfs_item_size(right->items + i));
		push_space = btrfs_item_offset(right->items + i);
1546
	}
1547

C
Chris Mason 已提交
1548 1549
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(right_buf);
1550

1551
	wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
C
Chris Mason 已提交
1552 1553
	if (wret)
		ret = wret;
1554 1555 1556 1557

	/* then fixup the leaf pointer in the path */
	if (path->slots[0] < push_items) {
		path->slots[0] += old_left_nritems;
C
Chris Mason 已提交
1558
		btrfs_block_release(root, path->nodes[0]);
1559
		path->nodes[0] = t;
1560 1561
		path->slots[1] -= 1;
	} else {
C
Chris Mason 已提交
1562
		btrfs_block_release(root, t);
1563 1564
		path->slots[0] -= push_items;
	}
1565
	BUG_ON(path->slots[0] < 0);
1566 1567
	if (path->nodes[1])
		check_node(root, path, 1);
C
Chris Mason 已提交
1568
	return ret;
1569 1570
}

C
Chris Mason 已提交
1571 1572 1573
/*
 * 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 已提交
1574 1575
 *
 * returns 0 if all went well and < 0 on failure.
C
Chris Mason 已提交
1576
 */
1577
static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1578 1579
		      *root, struct btrfs_key *ins_key,
		      struct btrfs_path *path, int data_size)
1580
{
C
Chris Mason 已提交
1581
	struct buffer_head *l_buf;
C
Chris Mason 已提交
1582
	struct btrfs_leaf *l;
1583
	u32 nritems;
1584 1585
	int mid;
	int slot;
C
Chris Mason 已提交
1586
	struct btrfs_leaf *right;
C
Chris Mason 已提交
1587
	struct buffer_head *right_buffer;
C
Chris Mason 已提交
1588
	int space_needed = data_size + sizeof(struct btrfs_item);
1589 1590 1591
	int data_copy_size;
	int rt_data_off;
	int i;
1592
	int ret = 0;
C
Chris Mason 已提交
1593
	int wret;
1594 1595
	int double_split = 0;
	struct btrfs_disk_key disk_key;
C
Chris Mason 已提交
1596

C
Chris Mason 已提交
1597
	/* first try to make some room by pushing left and right */
1598
	wret = push_leaf_left(trans, root, path, data_size);
C
Chris Mason 已提交
1599 1600 1601
	if (wret < 0)
		return wret;
	if (wret) {
1602
		wret = push_leaf_right(trans, root, path, data_size);
C
Chris Mason 已提交
1603 1604 1605
		if (wret < 0)
			return wret;
	}
C
Chris Mason 已提交
1606
	l_buf = path->nodes[0];
C
Chris Mason 已提交
1607
	l = btrfs_buffer_leaf(l_buf);
C
Chris Mason 已提交
1608 1609

	/* did the pushes work? */
C
Chris Mason 已提交
1610 1611
	if (btrfs_leaf_free_space(root, l) >=
	    sizeof(struct btrfs_item) + data_size)
C
Chris Mason 已提交
1612 1613
		return 0;

C
Chris Mason 已提交
1614
	if (!path->nodes[1]) {
1615
		ret = insert_new_root(trans, root, path, 1);
C
Chris Mason 已提交
1616 1617 1618
		if (ret)
			return ret;
	}
1619
	slot = path->slots[0];
1620
	nritems = btrfs_header_nritems(&l->header);
1621
	mid = (nritems + 1)/ 2;
1622

1623
	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0);
1624 1625 1626
	if (IS_ERR(right_buffer))
		return PTR_ERR(right_buffer);

C
Chris Mason 已提交
1627
	right = btrfs_buffer_leaf(right_buffer);
C
Chris Mason 已提交
1628
	memset(&right->header, 0, sizeof(right->header));
1629
	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1630
	btrfs_set_header_generation(&right->header, trans->transid);
1631
	btrfs_set_header_owner(&right->header, root->root_key.objectid);
1632
	btrfs_set_header_level(&right->header, 0);
C
Chris Mason 已提交
1633 1634
	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(right->header.fsid));
1635 1636 1637 1638 1639 1640 1641 1642 1643
	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,
1644
						  bh_blocknr(right_buffer),
1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
						  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,
1665
						  bh_blocknr(right_buffer),
1666
						  path->slots[1], 1);
1667 1668 1669 1670 1671
				if (wret)
					ret = wret;
				btrfs_block_release(root, path->nodes[0]);
				path->nodes[0] = right_buffer;
				path->slots[0] = 0;
1672 1673 1674 1675 1676 1677
				if (path->slots[1] == 0) {
					wret = fixup_low_keys(trans, root,
					           path, &disk_key, 1);
					if (wret)
						ret = wret;
				}
1678 1679 1680 1681 1682 1683 1684
				return ret;
			}
			mid = slot;
			double_split = 1;
		}
	}
	btrfs_set_header_nritems(&right->header, nritems - mid);
C
Chris Mason 已提交
1685 1686
	data_copy_size = btrfs_item_end(l->items + mid) -
			 leaf_data_end(root, l);
C
Chris Mason 已提交
1687 1688 1689 1690 1691 1692
	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 已提交
1693 1694
	rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
		      btrfs_item_end(l->items + mid);
C
Chris Mason 已提交
1695

C
Chris Mason 已提交
1696
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1697
		u32 ioff = btrfs_item_offset(right->items + i);
C
Chris Mason 已提交
1698 1699
		btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
	}
C
Chris Mason 已提交
1700

1701
	btrfs_set_header_nritems(&l->header, mid);
C
Chris Mason 已提交
1702
	ret = 0;
1703
	wret = insert_ptr(trans, root, path, &right->items[0].key,
1704
			  bh_blocknr(right_buffer), path->slots[1] + 1, 1);
C
Chris Mason 已提交
1705 1706
	if (wret)
		ret = wret;
C
Chris Mason 已提交
1707 1708
	btrfs_mark_buffer_dirty(right_buffer);
	btrfs_mark_buffer_dirty(l_buf);
1709
	BUG_ON(path->slots[0] != slot);
1710
	if (mid <= slot) {
C
Chris Mason 已提交
1711
		btrfs_block_release(root, path->nodes[0]);
1712
		path->nodes[0] = right_buffer;
1713 1714
		path->slots[0] -= mid;
		path->slots[1] += 1;
1715
	} else
C
Chris Mason 已提交
1716
		btrfs_block_release(root, right_buffer);
1717
	BUG_ON(path->slots[0] < 0);
1718
	check_node(root, path, 1);
1719 1720 1721

	if (!double_split)
		return ret;
1722
	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0);
1723 1724 1725
	if (IS_ERR(right_buffer))
		return PTR_ERR(right_buffer);

1726 1727
	right = btrfs_buffer_leaf(right_buffer);
	memset(&right->header, 0, sizeof(right->header));
1728
	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1729
	btrfs_set_header_generation(&right->header, trans->transid);
1730
	btrfs_set_header_owner(&right->header, root->root_key.objectid);
1731
	btrfs_set_header_level(&right->header, 0);
C
Chris Mason 已提交
1732 1733
	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(right->header.fsid));
1734 1735 1736 1737
	btrfs_cpu_key_to_disk(&disk_key, ins_key);
	btrfs_set_header_nritems(&right->header, 0);
	wret = insert_ptr(trans, root, path,
			  &disk_key,
1738
			  bh_blocknr(right_buffer),
1739 1740 1741
			  path->slots[1], 1);
	if (wret)
		ret = wret;
1742 1743 1744 1745 1746
	if (path->slots[1] == 0) {
		wret = fixup_low_keys(trans, root, path, &disk_key, 1);
		if (wret)
			ret = wret;
	}
1747 1748 1749 1750 1751
	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);
1752 1753 1754
	return ret;
}

C
Chris Mason 已提交
1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 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
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;
}

1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864
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 已提交
1865 1866 1867 1868
/*
 * 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.
 */
1869 1870 1871
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)
1872
{
C
Chris Mason 已提交
1873
	int ret = 0;
1874
	int slot;
1875
	int slot_orig;
C
Chris Mason 已提交
1876
	struct btrfs_leaf *leaf;
C
Chris Mason 已提交
1877
	struct buffer_head *leaf_buf;
1878
	u32 nritems;
1879
	unsigned int data_end;
C
Chris Mason 已提交
1880 1881 1882
	struct btrfs_disk_key disk_key;

	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1883

C
Chris Mason 已提交
1884
	/* create a root if there isn't one */
C
Chris Mason 已提交
1885
	if (!root->node)
C
Chris Mason 已提交
1886
		BUG();
1887
	ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
1888
	if (ret == 0) {
1889
		return -EEXIST;
C
Chris Mason 已提交
1890
	}
1891 1892
	if (ret < 0)
		goto out;
1893

1894 1895
	slot_orig = path->slots[0];
	leaf_buf = path->nodes[0];
C
Chris Mason 已提交
1896
	leaf = btrfs_buffer_leaf(leaf_buf);
C
Chris Mason 已提交
1897

1898
	nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
1899
	data_end = leaf_data_end(root, leaf);
1900

C
Chris Mason 已提交
1901
	if (btrfs_leaf_free_space(root, leaf) <
1902
	    sizeof(struct btrfs_item) + data_size) {
1903
		BUG();
1904
	}
1905
	slot = path->slots[0];
1906
	BUG_ON(slot < 0);
1907 1908
	if (slot != nritems) {
		int i;
C
Chris Mason 已提交
1909
		unsigned int old_data = btrfs_item_end(leaf->items + slot);
1910 1911 1912 1913 1914

		/*
		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
		 */
		/* first correct the data pointers */
C
Chris Mason 已提交
1915
		for (i = slot; i < nritems; i++) {
C
Chris Mason 已提交
1916
			u32 ioff = btrfs_item_offset(leaf->items + i);
C
Chris Mason 已提交
1917 1918 1919
			btrfs_set_item_offset(leaf->items + i,
					      ioff - data_size);
		}
1920 1921

		/* shift the items */
C
Chris Mason 已提交
1922 1923 1924
		btrfs_memmove(root, leaf, leaf->items + slot + 1,
			      leaf->items + slot,
			      (nritems - slot) * sizeof(struct btrfs_item));
1925 1926

		/* shift the data */
C
Chris Mason 已提交
1927 1928 1929
		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
			      data_end - data_size, btrfs_leaf_data(leaf) +
			      data_end, old_data - data_end);
1930 1931
		data_end = old_data;
	}
1932
	/* setup the item for the new data */
C
Chris Mason 已提交
1933 1934
	btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key,
		     sizeof(struct btrfs_disk_key));
C
Chris Mason 已提交
1935 1936
	btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
	btrfs_set_item_size(leaf->items + slot, data_size);
1937
	btrfs_set_header_nritems(&leaf->header, nritems + 1);
C
Chris Mason 已提交
1938
	btrfs_mark_buffer_dirty(leaf_buf);
C
Chris Mason 已提交
1939 1940

	ret = 0;
1941
	if (slot == 0)
1942
		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
C
Chris Mason 已提交
1943

C
Chris Mason 已提交
1944
	if (btrfs_leaf_free_space(root, leaf) < 0)
1945
		BUG();
1946
	check_leaf(root, path, 0);
1947
out:
1948 1949 1950 1951 1952 1953 1954
	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.
 */
1955 1956 1957
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_key *cpu_key, void *data, u32
		      data_size)
1958 1959
{
	int ret = 0;
C
Chris Mason 已提交
1960
	struct btrfs_path *path;
1961 1962
	u8 *ptr;

C
Chris Mason 已提交
1963 1964 1965
	path = btrfs_alloc_path();
	BUG_ON(!path);
	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
1966
	if (!ret) {
C
Chris Mason 已提交
1967 1968 1969
		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 已提交
1970
			     ptr, data, data_size);
C
Chris Mason 已提交
1971
		btrfs_mark_buffer_dirty(path->nodes[0]);
1972
	}
C
Chris Mason 已提交
1973
	btrfs_free_path(path);
C
Chris Mason 已提交
1974
	return ret;
1975 1976
}

C
Chris Mason 已提交
1977
/*
C
Chris Mason 已提交
1978
 * delete the pointer from a given node.
C
Chris Mason 已提交
1979 1980 1981 1982 1983
 *
 * 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.
 */
1984 1985
static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path, int level, int slot)
1986
{
C
Chris Mason 已提交
1987
	struct btrfs_node *node;
C
Chris Mason 已提交
1988
	struct buffer_head *parent = path->nodes[level];
1989
	u32 nritems;
C
Chris Mason 已提交
1990
	int ret = 0;
1991
	int wret;
1992

C
Chris Mason 已提交
1993
	node = btrfs_buffer_node(parent);
1994
	nritems = btrfs_header_nritems(&node->header);
1995
	if (slot != nritems -1) {
C
Chris Mason 已提交
1996 1997 1998 1999
		btrfs_memmove(root, node, node->ptrs + slot,
			      node->ptrs + slot + 1,
			      sizeof(struct btrfs_key_ptr) *
			      (nritems - slot - 1));
2000
	}
2001 2002 2003
	nritems--;
	btrfs_set_header_nritems(&node->header, nritems);
	if (nritems == 0 && parent == root->node) {
C
Chris Mason 已提交
2004 2005
		struct btrfs_header *header = btrfs_buffer_header(root->node);
		BUG_ON(btrfs_header_level(header) != 1);
2006
		/* just turn the root into a leaf and break */
C
Chris Mason 已提交
2007
		btrfs_set_header_level(header, 0);
2008
	} else if (slot == 0) {
2009
		wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
C
Chris Mason 已提交
2010
				      level + 1);
C
Chris Mason 已提交
2011 2012
		if (wret)
			ret = wret;
2013
	}
C
Chris Mason 已提交
2014
	btrfs_mark_buffer_dirty(parent);
C
Chris Mason 已提交
2015
	return ret;
2016 2017
}

C
Chris Mason 已提交
2018 2019 2020 2021
/*
 * delete the item at the leaf level in path.  If that empties
 * the leaf, remove it from the tree
 */
2022 2023
int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path)
2024 2025
{
	int slot;
C
Chris Mason 已提交
2026
	struct btrfs_leaf *leaf;
C
Chris Mason 已提交
2027
	struct buffer_head *leaf_buf;
2028 2029
	int doff;
	int dsize;
C
Chris Mason 已提交
2030 2031
	int ret = 0;
	int wret;
2032
	u32 nritems;
2033

2034
	leaf_buf = path->nodes[0];
C
Chris Mason 已提交
2035
	leaf = btrfs_buffer_leaf(leaf_buf);
2036
	slot = path->slots[0];
C
Chris Mason 已提交
2037 2038
	doff = btrfs_item_offset(leaf->items + slot);
	dsize = btrfs_item_size(leaf->items + slot);
2039
	nritems = btrfs_header_nritems(&leaf->header);
2040

2041
	if (slot != nritems - 1) {
2042
		int i;
C
Chris Mason 已提交
2043
		int data_end = leaf_data_end(root, leaf);
C
Chris Mason 已提交
2044 2045 2046 2047
		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
			      data_end + dsize,
			      btrfs_leaf_data(leaf) + data_end,
			      doff - data_end);
C
Chris Mason 已提交
2048
		for (i = slot + 1; i < nritems; i++) {
C
Chris Mason 已提交
2049
			u32 ioff = btrfs_item_offset(leaf->items + i);
C
Chris Mason 已提交
2050 2051
			btrfs_set_item_offset(leaf->items + i, ioff + dsize);
		}
C
Chris Mason 已提交
2052 2053 2054 2055
		btrfs_memmove(root, leaf, leaf->items + slot,
			      leaf->items + slot + 1,
			      sizeof(struct btrfs_item) *
			      (nritems - slot - 1));
2056
	}
2057 2058
	btrfs_set_header_nritems(&leaf->header, nritems - 1);
	nritems--;
C
Chris Mason 已提交
2059
	/* delete the leaf if we've emptied it */
2060
	if (nritems == 0) {
2061
		if (leaf_buf == root->node) {
2062
			btrfs_set_header_level(&leaf->header, 0);
2063
		} else {
2064
			clean_tree_block(trans, root, leaf_buf);
C
Chris Mason 已提交
2065
			wait_on_buffer(leaf_buf);
2066
			wret = del_ptr(trans, root, path, 1, path->slots[1]);
C
Chris Mason 已提交
2067 2068
			if (wret)
				ret = wret;
2069
			wret = btrfs_free_extent(trans, root,
2070
						 bh_blocknr(leaf_buf), 1, 1);
C
Chris Mason 已提交
2071 2072
			if (wret)
				ret = wret;
2073
		}
2074
	} else {
2075
		int used = leaf_space_used(leaf, 0, nritems);
C
Chris Mason 已提交
2076
		if (slot == 0) {
2077 2078
			wret = fixup_low_keys(trans, root, path,
					      &leaf->items[0].key, 1);
C
Chris Mason 已提交
2079 2080 2081 2082
			if (wret)
				ret = wret;
		}

C
Chris Mason 已提交
2083
		/* delete the leaf if it is mostly empty */
C
Chris Mason 已提交
2084
		if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
2085 2086 2087 2088
			/* push_leaf_left fixes the path.
			 * make sure the path still points to our leaf
			 * for possible call to del_ptr below
			 */
2089
			slot = path->slots[1];
C
Chris Mason 已提交
2090
			get_bh(leaf_buf);
2091
			wret = push_leaf_left(trans, root, path, 1);
2092
			if (wret < 0 && wret != -ENOSPC)
C
Chris Mason 已提交
2093
				ret = wret;
2094
			if (path->nodes[0] == leaf_buf &&
2095
			    btrfs_header_nritems(&leaf->header)) {
2096
				wret = push_leaf_right(trans, root, path, 1);
2097
				if (wret < 0 && wret != -ENOSPC)
C
Chris Mason 已提交
2098 2099
					ret = wret;
			}
2100
			if (btrfs_header_nritems(&leaf->header) == 0) {
2101
				u64 blocknr = bh_blocknr(leaf_buf);
2102
				clean_tree_block(trans, root, leaf_buf);
C
Chris Mason 已提交
2103
				wait_on_buffer(leaf_buf);
2104
				wret = del_ptr(trans, root, path, 1, slot);
C
Chris Mason 已提交
2105 2106
				if (wret)
					ret = wret;
C
Chris Mason 已提交
2107
				btrfs_block_release(root, leaf_buf);
2108 2109
				wret = btrfs_free_extent(trans, root, blocknr,
							 1, 1);
C
Chris Mason 已提交
2110 2111
				if (wret)
					ret = wret;
C
Chris Mason 已提交
2112
			} else {
C
Chris Mason 已提交
2113
				btrfs_mark_buffer_dirty(leaf_buf);
C
Chris Mason 已提交
2114
				btrfs_block_release(root, leaf_buf);
2115
			}
2116
		} else {
C
Chris Mason 已提交
2117
			btrfs_mark_buffer_dirty(leaf_buf);
2118 2119
		}
	}
C
Chris Mason 已提交
2120
	return ret;
2121 2122
}

C
Chris Mason 已提交
2123 2124
/*
 * walk up the tree as far as required to find the next leaf.
C
Chris Mason 已提交
2125 2126
 * returns 0 if it found something or 1 if there are no greater leaves.
 * returns < 0 on io errors.
C
Chris Mason 已提交
2127
 */
C
Chris Mason 已提交
2128
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
2129 2130 2131 2132
{
	int slot;
	int level = 1;
	u64 blocknr;
C
Chris Mason 已提交
2133 2134 2135
	struct buffer_head *c;
	struct btrfs_node *c_node;
	struct buffer_head *next = NULL;
2136

C
Chris Mason 已提交
2137
	while(level < BTRFS_MAX_LEVEL) {
2138
		if (!path->nodes[level])
C
Chris Mason 已提交
2139
			return 1;
2140 2141
		slot = path->slots[level] + 1;
		c = path->nodes[level];
C
Chris Mason 已提交
2142 2143
		c_node = btrfs_buffer_node(c);
		if (slot >= btrfs_header_nritems(&c_node->header)) {
2144 2145 2146
			level++;
			continue;
		}
C
Chris Mason 已提交
2147
		blocknr = btrfs_node_blockptr(c_node, slot);
C
Chris Mason 已提交
2148
		if (next)
C
Chris Mason 已提交
2149
			btrfs_block_release(root, next);
2150 2151
		if (path->reada)
			reada_for_search(root, path, level, slot);
2152 2153 2154 2155 2156 2157 2158
		next = read_tree_block(root, blocknr);
		break;
	}
	path->slots[level] = slot;
	while(1) {
		level--;
		c = path->nodes[level];
C
Chris Mason 已提交
2159
		btrfs_block_release(root, c);
2160 2161 2162 2163
		path->nodes[level] = next;
		path->slots[level] = 0;
		if (!level)
			break;
2164
		if (path->reada)
Y
Yan 已提交
2165
			reada_for_search(root, path, level, 0);
2166
		next = read_tree_block(root,
C
Chris Mason 已提交
2167
		       btrfs_node_blockptr(btrfs_buffer_node(next), 0));
2168 2169 2170
	}
	return 0;
}