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 269 270 271
		err = __btrfs_cow_block(trans, root, cur_bh, parent, i,
					&tmp_bh, search_start,
					min(8, end_slot - i));
		if (err)
			break;
		search_start = bh_blocknr(tmp_bh);
272 273 274
		*last_ret = search_start;
		if (parent_level == 1)
			clear_buffer_defrag(tmp_bh);
275 276 277 278 279
		brelse(tmp_bh);
	}
	return err;
}

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

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

	btrfs_disk_key_to_cpu(&k1, disk);

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

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

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

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

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

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

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

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

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

	if (nritems == 0)
		return 0;

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

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

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

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

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

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

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

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

	if (level == 0)
		return 0;

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

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

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

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

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

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

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

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

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

674 675 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
/* 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 已提交
715 716 717
		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
			wret = 1;
		} else {
718 719 720 721 722 723 724 725 726
			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 已提交
727
		}
728 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
		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 已提交
759
		u32 right_nr;
760
		right = btrfs_buffer_node(right_buf);
C
Chris Mason 已提交
761 762 763 764
		right_nr = btrfs_header_nritems(&right->header);
		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
			wret = 1;
		} else {
765 766 767 768 769 770 771 772 773 774
			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 已提交
775
		}
776 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
		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;
}

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

822 823 824 825
	if (level == 0)
		return;

	if (!path->nodes[level])
826 827
		return;

828
	node = btrfs_buffer_node(path->nodes[level]);
829 830 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
	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);
856
			if (path->reada == 1 && nread > 16)
857
				continue;
858
			if (close_blocks(cluster_start, blocknr)) {
859 860 861 862 863 864 865
				readahead_tree_block(root, blocknr);
				nread++;
				cluster_start = blocknr;
			}
		}
	}
}
C
Chris Mason 已提交
866 867 868 869 870 871
/*
 * 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 已提交
872 873
 * be inserted, and 1 is returned.  If there are other errors during the
 * search a negative error number is returned.
C
Chris Mason 已提交
874 875 876 877
 *
 * 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 已提交
878
 */
879 880 881
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)
882
{
C
Chris Mason 已提交
883 884
	struct buffer_head *b;
	struct buffer_head *cow_buf;
C
Chris Mason 已提交
885
	struct btrfs_node *c;
886
	u64 blocknr;
887 888 889
	int slot;
	int ret;
	int level;
890
	int should_reada = p->reada;
891 892
	u8 lowest_level = 0;

893 894
	lowest_level = p->lowest_level;
	WARN_ON(lowest_level && ins_len);
C
Chris Mason 已提交
895 896
	WARN_ON(p->nodes[0] != NULL);
	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
897 898
again:
	b = root->node;
C
Chris Mason 已提交
899
	get_bh(b);
900
	while (b) {
C
Chris Mason 已提交
901 902
		c = btrfs_buffer_node(b);
		level = btrfs_header_level(&c->header);
C
Chris Mason 已提交
903 904
		if (cow) {
			int wret;
C
Chris Mason 已提交
905 906 907
			wret = btrfs_cow_block(trans, root, b,
					       p->nodes[level + 1],
					       p->slots[level + 1],
908
					       &cow_buf);
909 910 911 912
			if (wret) {
				btrfs_block_release(root, cow_buf);
				return wret;
			}
C
Chris Mason 已提交
913
			b = cow_buf;
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 1078 1079 1080 1081 1082
	if (push_items <= 0) {
		return 1;
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

C
Chris Mason 已提交
1542 1543
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(right_buf);
1544

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

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

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

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

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

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

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

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

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

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

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

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

C
Chris Mason 已提交
1749 1750 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
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;
}

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

	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1877

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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