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 220 221

	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);
222
	parent_level = btrfs_header_level(&parent_node->header);
223 224 225 226 227 228 229 230 231 232

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

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

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

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

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

	btrfs_disk_key_to_cpu(&k1, disk);

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

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

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

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

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

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

367
	u32 nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
368 369

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

C
Chris Mason 已提交
372
	BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
373 374 375 376 377

	if (nritems == 0)
		return 0;

	if (parent) {
C
Chris Mason 已提交
378
		struct btrfs_disk_key *parent_key;
A
Aneesh 已提交
379 380

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

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

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

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

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

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

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

	if (level == 0)
		return 0;

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

C
Chris Mason 已提交
511
	if (level < BTRFS_MAX_LEVEL - 1)
512 513 514
		parent_buf = path->nodes[level + 1];
	pslot = path->slots[level + 1];

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

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

C
Chris Mason 已提交
541 542
	if (btrfs_header_nritems(&mid->header) >
	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
543 544
		return 0;

545 546 547
	if (btrfs_header_nritems(&mid->header) < 2)
		err_on_enospc = 1;

548 549
	left_buf = read_node_slot(root, parent_buf, pslot - 1);
	if (left_buf) {
550 551 552 553 554 555
		wret = btrfs_cow_block(trans, root, left_buf,
				       parent_buf, pslot - 1, &left_buf);
		if (wret) {
			ret = wret;
			goto enospc;
		}
556 557 558 559 560 561 562 563 564 565 566 567 568
	}
	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 已提交
569
		left = btrfs_buffer_node(left_buf);
570
		orig_slot += btrfs_header_nritems(&left->header);
571
		wret = push_node_left(trans, root, left_buf, mid_buf);
572 573
		if (wret < 0)
			ret = wret;
574 575
		if (btrfs_header_nritems(&mid->header) < 2)
			err_on_enospc = 1;
576
	}
577 578 579 580

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

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

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

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

824 825 826 827
	if (level == 0)
		return;

	if (!path->nodes[level])
828 829
		return;

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

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

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

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

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

1023 1024
	src_nritems = btrfs_header_nritems(&src->header);
	dst_nritems = btrfs_header_nritems(&dst->header);
C
Chris Mason 已提交
1025
	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
1026

1027
	if (push_items <= 0) {
1028
		return 1;
1029
	}
1030

1031
	if (src_nritems < push_items)
1032 1033
		push_items = src_nritems;

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

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

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

1081 1082 1083
	if (max_push < push_items)
		push_items = max_push;

C
Chris Mason 已提交
1084 1085 1086 1087 1088 1089
	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));
1090

1091 1092
	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
1093

C
Chris Mason 已提交
1094 1095
	btrfs_mark_buffer_dirty(src_buf);
	btrfs_mark_buffer_dirty(dst_buf);
C
Chris Mason 已提交
1096
	return ret;
1097 1098
}

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

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

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

C
Chris Mason 已提交
1138
	btrfs_mark_buffer_dirty(t);
1139

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

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

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

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

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

1226
	c_nritems = btrfs_header_nritems(&c->header);
1227
	split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr, 0);
1228 1229 1230
	if (IS_ERR(split_buffer))
		return PTR_ERR(split_buffer);

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

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

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

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

	if (!nr)
		return 0;
C
Chris Mason 已提交
1278 1279 1280
	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;
1281
	WARN_ON(data_len < 0);
1282 1283 1284
	return data_len;
}

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

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

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

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

C
Chris Mason 已提交
1408 1409
	btrfs_mark_buffer_dirty(left_buf);
	btrfs_mark_buffer_dirty(right_buf);
1410

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

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

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

	/* cow and double check */
1466 1467 1468
	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 已提交
1469
		btrfs_block_release(root, t);
1470 1471
		return 1;
	}
C
Chris Mason 已提交
1472
	left = btrfs_buffer_leaf(t);
C
Chris Mason 已提交
1473
	free_space = btrfs_leaf_free_space(root, left);
C
Chris Mason 已提交
1474
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1475
		btrfs_block_release(root, t);
C
Chris Mason 已提交
1476 1477 1478
		return 1;
	}

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

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

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

1538
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1539 1540 1541
		btrfs_set_item_offset(right->items + i, push_space -
				      btrfs_item_size(right->items + i));
		push_space = btrfs_item_offset(right->items + i);
1542
	}
1543

C
Chris Mason 已提交
1544 1545
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(right_buf);
1546

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

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

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

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

	/* did the pushes work? */
C
Chris Mason 已提交
1606 1607
	if (btrfs_leaf_free_space(root, l) >=
	    sizeof(struct btrfs_item) + data_size)
C
Chris Mason 已提交
1608 1609
		return 0;

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

1619
	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0);
1620 1621 1622
	if (IS_ERR(right_buffer))
		return PTR_ERR(right_buffer);

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

C
Chris Mason 已提交
1692
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1693
		u32 ioff = btrfs_item_offset(right->items + i);
C
Chris Mason 已提交
1694 1695
		btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
	}
C
Chris Mason 已提交
1696

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

	if (!double_split)
		return ret;
1718
	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr, 0);
1719 1720 1721
	if (IS_ERR(right_buffer))
		return PTR_ERR(right_buffer);

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

C
Chris Mason 已提交
1751 1752 1753 1754 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
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;
}

1807 1808 1809 1810 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
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 已提交
1861 1862 1863 1864
/*
 * 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.
 */
1865 1866 1867
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)
1868
{
C
Chris Mason 已提交
1869
	int ret = 0;
1870
	int slot;
1871
	int slot_orig;
C
Chris Mason 已提交
1872
	struct btrfs_leaf *leaf;
C
Chris Mason 已提交
1873
	struct buffer_head *leaf_buf;
1874
	u32 nritems;
1875
	unsigned int data_end;
C
Chris Mason 已提交
1876 1877 1878
	struct btrfs_disk_key disk_key;

	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1879

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

1890 1891
	slot_orig = path->slots[0];
	leaf_buf = path->nodes[0];
C
Chris Mason 已提交
1892
	leaf = btrfs_buffer_leaf(leaf_buf);
C
Chris Mason 已提交
1893

1894
	nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
1895
	data_end = leaf_data_end(root, leaf);
1896

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

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

		/* shift the items */
C
Chris Mason 已提交
1918 1919 1920
		btrfs_memmove(root, leaf, leaf->items + slot + 1,
			      leaf->items + slot,
			      (nritems - slot) * sizeof(struct btrfs_item));
1921 1922

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

	ret = 0;
1937
	if (slot == 0)
1938
		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
C
Chris Mason 已提交
1939

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

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

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

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

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

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

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

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

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

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