ctree.c 52.9 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
#include <linux/module.h>
20 21
#include "ctree.h"
#include "disk-io.h"
22
#include "transaction.h"
23

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

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

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

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

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

69
static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
70 71
			   *root, struct buffer_head *buf, struct buffer_head
			   *parent, int parent_slot, struct buffer_head
72
			   **cow_ret)
C
Chris Mason 已提交
73
{
C
Chris Mason 已提交
74 75
	struct buffer_head *cow;
	struct btrfs_node *cow_node;
C
Chris Mason 已提交
76

77 78
	if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
				    trans->transid) {
C
Chris Mason 已提交
79 80 81
		*cow_ret = buf;
		return 0;
	}
82
	cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr);
C
Chris Mason 已提交
83
	cow_node = btrfs_buffer_node(cow);
C
Chris Mason 已提交
84 85
	if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
		WARN_ON(1);
C
Chris Mason 已提交
86
	memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
87
	btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow));
88
	btrfs_set_header_generation(&cow_node->header, trans->transid);
89
	btrfs_set_header_owner(&cow_node->header, root->root_key.objectid);
90
	btrfs_inc_ref(trans, root, buf);
C
Chris Mason 已提交
91 92
	if (buf == root->node) {
		root->node = cow;
C
Chris Mason 已提交
93
		get_bh(cow);
C
Chris Mason 已提交
94
		if (buf != root->commit_root) {
95
			btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
C
Chris Mason 已提交
96
		}
C
Chris Mason 已提交
97
		btrfs_block_release(root, buf);
C
Chris Mason 已提交
98
	} else {
C
Chris Mason 已提交
99
		btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
100
					bh_blocknr(cow));
C
Chris Mason 已提交
101
		btrfs_mark_buffer_dirty(parent);
102
		btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
C
Chris Mason 已提交
103
	}
C
Chris Mason 已提交
104
	btrfs_block_release(root, buf);
C
Chris Mason 已提交
105
	mark_buffer_dirty(cow);
C
Chris Mason 已提交
106
	*cow_ret = cow;
C
Chris Mason 已提交
107 108 109
	return 0;
}

C
Chris Mason 已提交
110 111 112 113 114
/*
 * 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 已提交
115 116
static inline unsigned int leaf_data_end(struct btrfs_root *root,
					 struct btrfs_leaf *leaf)
117
{
118
	u32 nr = btrfs_header_nritems(&leaf->header);
119
	if (nr == 0)
C
Chris Mason 已提交
120
		return BTRFS_LEAF_DATA_SIZE(root);
C
Chris Mason 已提交
121
	return btrfs_item_offset(leaf->items + nr - 1);
122 123
}

C
Chris Mason 已提交
124 125 126
/*
 * compare two keys in a memcmp fashion
 */
C
Chris Mason 已提交
127
static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
128
{
C
Chris Mason 已提交
129 130 131 132 133
	struct btrfs_key k1;

	btrfs_disk_key_to_cpu(&k1, disk);

	if (k1.objectid > k2->objectid)
134
		return 1;
C
Chris Mason 已提交
135
	if (k1.objectid < k2->objectid)
136
		return -1;
C
Chris Mason 已提交
137 138 139 140
	if (k1.flags > k2->flags)
		return 1;
	if (k1.flags < k2->flags)
		return -1;
141 142 143 144
	if (k1.offset > k2->offset)
		return 1;
	if (k1.offset < k2->offset)
		return -1;
145 146
	return 0;
}
C
Chris Mason 已提交
147

C
Chris Mason 已提交
148 149
static int check_node(struct btrfs_root *root, struct btrfs_path *path,
		      int level)
C
Chris Mason 已提交
150
{
C
Chris Mason 已提交
151
	struct btrfs_node *parent = NULL;
C
Chris Mason 已提交
152
	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
C
Chris Mason 已提交
153
	int parent_slot;
154 155
	int slot;
	struct btrfs_key cpukey;
156
	u32 nritems = btrfs_header_nritems(&node->header);
C
Chris Mason 已提交
157 158

	if (path->nodes[level + 1])
C
Chris Mason 已提交
159
		parent = btrfs_buffer_node(path->nodes[level + 1]);
C
Chris Mason 已提交
160
	parent_slot = path->slots[level + 1];
161
	slot = path->slots[level];
162 163
	BUG_ON(nritems == 0);
	if (parent) {
C
Chris Mason 已提交
164
		struct btrfs_disk_key *parent_key;
C
Chris Mason 已提交
165 166
		parent_key = &parent->ptrs[parent_slot].key;
		BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
C
Chris Mason 已提交
167
			      sizeof(struct btrfs_disk_key)));
168
		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
169
		       btrfs_header_blocknr(&node->header));
C
Chris Mason 已提交
170
	}
C
Chris Mason 已提交
171
	BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
172 173 174 175 176 177 178
	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 已提交
179 180 181 182
	}
	return 0;
}

C
Chris Mason 已提交
183 184
static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
		      int level)
C
Chris Mason 已提交
185
{
C
Chris Mason 已提交
186
	struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]);
C
Chris Mason 已提交
187
	struct btrfs_node *parent = NULL;
C
Chris Mason 已提交
188
	int parent_slot;
189 190 191
	int slot = path->slots[0];
	struct btrfs_key cpukey;

192
	u32 nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
193 194

	if (path->nodes[level + 1])
C
Chris Mason 已提交
195
		parent = btrfs_buffer_node(path->nodes[level + 1]);
C
Chris Mason 已提交
196
	parent_slot = path->slots[level + 1];
C
Chris Mason 已提交
197
	BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
198 199 200 201 202

	if (nritems == 0)
		return 0;

	if (parent) {
C
Chris Mason 已提交
203
		struct btrfs_disk_key *parent_key;
C
Chris Mason 已提交
204
		parent_key = &parent->ptrs[parent_slot].key;
C
Chris Mason 已提交
205
		BUG_ON(memcmp(parent_key, &leaf->items[0].key,
C
Chris Mason 已提交
206
		       sizeof(struct btrfs_disk_key)));
207
		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
208
		       btrfs_header_blocknr(&leaf->header));
C
Chris Mason 已提交
209
	}
210 211 212 213 214 215 216 217 218 219 220
	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 已提交
221
	}
222 223
	BUG_ON(btrfs_item_offset(leaf->items) +
	       btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root));
C
Chris Mason 已提交
224 225 226
	return 0;
}

C
Chris Mason 已提交
227 228
static int check_block(struct btrfs_root *root, struct btrfs_path *path,
			int level)
C
Chris Mason 已提交
229
{
C
Chris Mason 已提交
230 231 232 233
	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 已提交
234
	if (level == 0)
C
Chris Mason 已提交
235 236
		return check_leaf(root, path, level);
	return check_node(root, path, level);
C
Chris Mason 已提交
237 238
}

C
Chris Mason 已提交
239 240 241 242 243 244 245 246 247
/*
 * 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 已提交
248
static int generic_bin_search(char *p, int item_size, struct btrfs_key *key,
249 250 251 252 253 254
		       int max, int *slot)
{
	int low = 0;
	int high = max;
	int mid;
	int ret;
C
Chris Mason 已提交
255
	struct btrfs_disk_key *tmp;
256 257 258

	while(low < high) {
		mid = (low + high) / 2;
C
Chris Mason 已提交
259
		tmp = (struct btrfs_disk_key *)(p + mid * item_size);
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
		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 已提交
275 276 277 278
/*
 * simple bin_search frontend that does the right thing for
 * leaves vs nodes
 */
C
Chris Mason 已提交
279
static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
280
{
281
	if (btrfs_is_leaf(c)) {
C
Chris Mason 已提交
282
		struct btrfs_leaf *l = (struct btrfs_leaf *)c;
C
Chris Mason 已提交
283 284
		return generic_bin_search((void *)l->items,
					  sizeof(struct btrfs_item),
285 286
					  key, btrfs_header_nritems(&c->header),
					  slot);
287
	} else {
C
Chris Mason 已提交
288 289
		return generic_bin_search((void *)c->ptrs,
					  sizeof(struct btrfs_key_ptr),
290 291
					  key, btrfs_header_nritems(&c->header),
					  slot);
292 293 294 295
	}
	return -1;
}

C
Chris Mason 已提交
296 297
static struct buffer_head *read_node_slot(struct btrfs_root *root,
				   struct buffer_head *parent_buf,
298 299
				   int slot)
{
C
Chris Mason 已提交
300
	struct btrfs_node *node = btrfs_buffer_node(parent_buf);
301 302
	if (slot < 0)
		return NULL;
303
	if (slot >= btrfs_header_nritems(&node->header))
304
		return NULL;
305
	return read_tree_block(root, btrfs_node_blockptr(node, slot));
306 307
}

308 309
static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
			 *root, struct btrfs_path *path, int level)
310
{
C
Chris Mason 已提交
311 312 313 314
	struct buffer_head *right_buf;
	struct buffer_head *mid_buf;
	struct buffer_head *left_buf;
	struct buffer_head *parent_buf = NULL;
C
Chris Mason 已提交
315 316 317 318
	struct btrfs_node *right = NULL;
	struct btrfs_node *mid;
	struct btrfs_node *left = NULL;
	struct btrfs_node *parent = NULL;
319 320 321 322
	int ret = 0;
	int wret;
	int pslot;
	int orig_slot = path->slots[level];
323
	u64 orig_ptr;
324 325 326 327 328

	if (level == 0)
		return 0;

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

C
Chris Mason 已提交
332
	if (level < BTRFS_MAX_LEVEL - 1)
333 334 335
		parent_buf = path->nodes[level + 1];
	pslot = path->slots[level + 1];

C
Chris Mason 已提交
336 337 338 339
	/*
	 * deal with the case where there is only one pointer in the root
	 * by promoting the node below to a root
	 */
340
	if (!parent_buf) {
C
Chris Mason 已提交
341
		struct buffer_head *child;
342
		u64 blocknr = bh_blocknr(mid_buf);
343

344
		if (btrfs_header_nritems(&mid->header) != 1)
345 346 347 348 349 350 351
			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 已提交
352 353
		clean_tree_block(trans, root, mid_buf);
		wait_on_buffer(mid_buf);
354
		/* once for the path */
C
Chris Mason 已提交
355
		btrfs_block_release(root, mid_buf);
356
		/* once for the root ptr */
C
Chris Mason 已提交
357
		btrfs_block_release(root, mid_buf);
358
		return btrfs_free_extent(trans, root, blocknr, 1, 1);
359
	}
C
Chris Mason 已提交
360
	parent = btrfs_buffer_node(parent_buf);
361

C
Chris Mason 已提交
362 363
	if (btrfs_header_nritems(&mid->header) >
	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
364 365 366 367
		return 0;

	left_buf = read_node_slot(root, parent_buf, pslot - 1);
	right_buf = read_node_slot(root, parent_buf, pslot + 1);
368 369

	/* first, try to make some room in the middle buffer */
370
	if (left_buf) {
371 372
		btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1,
				&left_buf);
C
Chris Mason 已提交
373
		left = btrfs_buffer_node(left_buf);
374
		orig_slot += btrfs_header_nritems(&left->header);
375
		wret = push_node_left(trans, root, left_buf, mid_buf);
376 377
		if (wret < 0)
			ret = wret;
378
	}
379 380 381 382

	/*
	 * then try to empty the right most buffer into the middle
	 */
383
	if (right_buf) {
384 385
		btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1,
				&right_buf);
C
Chris Mason 已提交
386
		right = btrfs_buffer_node(right_buf);
387
		wret = push_node_left(trans, root, mid_buf, right_buf);
388 389
		if (wret < 0)
			ret = wret;
390
		if (btrfs_header_nritems(&right->header) == 0) {
391
			u64 blocknr = bh_blocknr(right_buf);
392
			clean_tree_block(trans, root, right_buf);
C
Chris Mason 已提交
393 394
			wait_on_buffer(right_buf);
			btrfs_block_release(root, right_buf);
395 396
			right_buf = NULL;
			right = NULL;
397 398
			wret = del_ptr(trans, root, path, level + 1, pslot +
				       1);
399 400
			if (wret)
				ret = wret;
401
			wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
402 403 404
			if (wret)
				ret = wret;
		} else {
C
Chris Mason 已提交
405 406 407 408 409
			btrfs_memcpy(root, parent,
				     &parent->ptrs[pslot + 1].key,
				     &right->ptrs[0].key,
				     sizeof(struct btrfs_disk_key));
			btrfs_mark_buffer_dirty(parent_buf);
410 411
		}
	}
412
	if (btrfs_header_nritems(&mid->header) == 1) {
413 414 415 416 417 418 419 420 421 422
		/*
		 * 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);
423
		wret = balance_node_right(trans, root, mid_buf, left_buf);
424 425 426 427
		if (wret < 0)
			ret = wret;
		BUG_ON(wret == 1);
	}
428
	if (btrfs_header_nritems(&mid->header) == 0) {
429
		/* we've managed to empty the middle node, drop it */
430
		u64 blocknr = bh_blocknr(mid_buf);
431
		clean_tree_block(trans, root, mid_buf);
C
Chris Mason 已提交
432 433
		wait_on_buffer(mid_buf);
		btrfs_block_release(root, mid_buf);
434 435
		mid_buf = NULL;
		mid = NULL;
436
		wret = del_ptr(trans, root, path, level + 1, pslot);
437 438
		if (wret)
			ret = wret;
439
		wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
440 441
		if (wret)
			ret = wret;
442 443
	} else {
		/* update the parent key to reflect our changes */
C
Chris Mason 已提交
444 445 446 447
		btrfs_memcpy(root, parent,
			     &parent->ptrs[pslot].key, &mid->ptrs[0].key,
			     sizeof(struct btrfs_disk_key));
		btrfs_mark_buffer_dirty(parent_buf);
448
	}
449

450
	/* update the path */
451
	if (left_buf) {
452
		if (btrfs_header_nritems(&left->header) > orig_slot) {
C
Chris Mason 已提交
453
			get_bh(left_buf);
454 455 456 457
			path->nodes[level] = left_buf;
			path->slots[level + 1] -= 1;
			path->slots[level] = orig_slot;
			if (mid_buf)
C
Chris Mason 已提交
458
				btrfs_block_release(root, mid_buf);
459
		} else {
460
			orig_slot -= btrfs_header_nritems(&left->header);
461 462 463
			path->slots[level] = orig_slot;
		}
	}
464
	/* double check we haven't messed things up */
C
Chris Mason 已提交
465
	check_block(root, path, level);
C
Chris Mason 已提交
466 467 468
	if (orig_ptr !=
	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
				path->slots[level]))
469
		BUG();
470 471

	if (right_buf)
C
Chris Mason 已提交
472
		btrfs_block_release(root, right_buf);
473
	if (left_buf)
C
Chris Mason 已提交
474
		btrfs_block_release(root, left_buf);
475 476 477
	return ret;
}

478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
/* 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 已提交
519 520 521 522 523 524 525 526
		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
			wret = 1;
		} else {
			btrfs_cow_block(trans, root, left_buf, parent_buf,
					pslot - 1, &left_buf);
			left = btrfs_buffer_node(left_buf);
			wret = push_node_left(trans, root, left_buf, mid_buf);
		}
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
		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 已提交
558
		u32 right_nr;
559
		right = btrfs_buffer_node(right_buf);
C
Chris Mason 已提交
560 561 562 563 564 565 566 567 568 569
		right_nr = btrfs_header_nritems(&right->header);
		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
			wret = 1;
		} else {
			btrfs_cow_block(trans, root, right_buf,
					parent_buf, pslot + 1, &right_buf);
			right = btrfs_buffer_node(right_buf);
			wret = balance_node_right(trans, root,
						  right_buf, mid_buf);
		}
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
		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;
}

C
Chris Mason 已提交
596 597 598 599 600 601
/*
 * 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 已提交
602 603
 * be inserted, and 1 is returned.  If there are other errors during the
 * search a negative error number is returned.
C
Chris Mason 已提交
604 605 606 607
 *
 * 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 已提交
608
 */
609 610 611
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)
612
{
C
Chris Mason 已提交
613 614
	struct buffer_head *b;
	struct buffer_head *cow_buf;
C
Chris Mason 已提交
615
	struct btrfs_node *c;
616 617 618
	int slot;
	int ret;
	int level;
C
Chris Mason 已提交
619

C
Chris Mason 已提交
620 621
	WARN_ON(p->nodes[0] != NULL);
	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
622 623
again:
	b = root->node;
C
Chris Mason 已提交
624
	get_bh(b);
625
	while (b) {
C
Chris Mason 已提交
626 627
		c = btrfs_buffer_node(b);
		level = btrfs_header_level(&c->header);
C
Chris Mason 已提交
628 629
		if (cow) {
			int wret;
C
Chris Mason 已提交
630 631 632
			wret = btrfs_cow_block(trans, root, b,
					       p->nodes[level + 1],
					       p->slots[level + 1],
633
					       &cow_buf);
C
Chris Mason 已提交
634
			b = cow_buf;
C
Chris Mason 已提交
635
			c = btrfs_buffer_node(b);
C
Chris Mason 已提交
636 637
		}
		BUG_ON(!cow && ins_len);
C
Chris Mason 已提交
638 639 640
		if (level != btrfs_header_level(&c->header))
			WARN_ON(1);
		level = btrfs_header_level(&c->header);
641
		p->nodes[level] = b;
C
Chris Mason 已提交
642
		ret = check_block(root, p, level);
C
Chris Mason 已提交
643 644
		if (ret)
			return -1;
645
		ret = bin_search(c, key, &slot);
646
		if (!btrfs_is_leaf(c)) {
647 648 649
			if (ret && slot > 0)
				slot -= 1;
			p->slots[level] = slot;
650 651
			if (ins_len > 0 && btrfs_header_nritems(&c->header) >=
			    BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
652
				int sret = split_node(trans, root, p, level);
C
Chris Mason 已提交
653 654 655 656
				BUG_ON(sret > 0);
				if (sret)
					return sret;
				b = p->nodes[level];
C
Chris Mason 已提交
657
				c = btrfs_buffer_node(b);
C
Chris Mason 已提交
658
				slot = p->slots[level];
659
			} else if (ins_len < 0) {
660 661
				int sret = balance_level(trans, root, p,
							 level);
662 663 664 665 666
				if (sret)
					return sret;
				b = p->nodes[level];
				if (!b)
					goto again;
C
Chris Mason 已提交
667
				c = btrfs_buffer_node(b);
668
				slot = p->slots[level];
669
				BUG_ON(btrfs_header_nritems(&c->header) == 1);
C
Chris Mason 已提交
670
			}
671
			b = read_tree_block(root, btrfs_node_blockptr(c, slot));
672
		} else {
C
Chris Mason 已提交
673
			struct btrfs_leaf *l = (struct btrfs_leaf *)c;
674
			p->slots[level] = slot;
C
Chris Mason 已提交
675
			if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
C
Chris Mason 已提交
676
			    sizeof(struct btrfs_item) + ins_len) {
677 678
				int sret = split_leaf(trans, root, key,
						      p, ins_len);
C
Chris Mason 已提交
679 680 681 682
				BUG_ON(sret > 0);
				if (sret)
					return sret;
			}
683 684 685
			return ret;
		}
	}
C
Chris Mason 已提交
686
	return 1;
687 688
}

C
Chris Mason 已提交
689 690 691 692 693 694
/*
 * 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 已提交
695 696 697
 *
 * 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 已提交
698
 */
699 700 701
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)
702 703
{
	int i;
C
Chris Mason 已提交
704
	int ret = 0;
C
Chris Mason 已提交
705 706
	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
		struct btrfs_node *t;
707
		int tslot = path->slots[i];
708
		if (!path->nodes[i])
709
			break;
C
Chris Mason 已提交
710
		t = btrfs_buffer_node(path->nodes[i]);
C
Chris Mason 已提交
711 712
		btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key));
		btrfs_mark_buffer_dirty(path->nodes[i]);
713 714 715
		if (tslot != 0)
			break;
	}
C
Chris Mason 已提交
716
	return ret;
717 718
}

C
Chris Mason 已提交
719 720
/*
 * try to push data from one node into the next node left in the
721
 * tree.
C
Chris Mason 已提交
722 723 724
 *
 * 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 已提交
725
 */
726
static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
727 728
			  *root, struct buffer_head *dst_buf, struct
			  buffer_head *src_buf)
729
{
C
Chris Mason 已提交
730 731
	struct btrfs_node *src = btrfs_buffer_node(src_buf);
	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
732
	int push_items = 0;
733 734
	int src_nritems;
	int dst_nritems;
C
Chris Mason 已提交
735
	int ret = 0;
736

737 738
	src_nritems = btrfs_header_nritems(&src->header);
	dst_nritems = btrfs_header_nritems(&dst->header);
C
Chris Mason 已提交
739
	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
740
	if (push_items <= 0) {
741
		return 1;
742
	}
743

744
	if (src_nritems < push_items)
745 746
		push_items = src_nritems;

C
Chris Mason 已提交
747 748
	btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs,
		     push_items * sizeof(struct btrfs_key_ptr));
749
	if (push_items < src_nritems) {
C
Chris Mason 已提交
750
		btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items,
C
Chris Mason 已提交
751
			(src_nritems - push_items) *
C
Chris Mason 已提交
752
			sizeof(struct btrfs_key_ptr));
753
	}
754 755
	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
C
Chris Mason 已提交
756 757
	btrfs_mark_buffer_dirty(src_buf);
	btrfs_mark_buffer_dirty(dst_buf);
758 759 760 761 762 763 764 765 766 767 768 769
	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
 */
770
static int balance_node_right(struct btrfs_trans_handle *trans, struct
C
Chris Mason 已提交
771 772
			      btrfs_root *root, struct buffer_head *dst_buf,
			      struct buffer_head *src_buf)
773
{
C
Chris Mason 已提交
774 775
	struct btrfs_node *src = btrfs_buffer_node(src_buf);
	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
776 777 778 779 780 781
	int push_items = 0;
	int max_push;
	int src_nritems;
	int dst_nritems;
	int ret = 0;

782 783
	src_nritems = btrfs_header_nritems(&src->header);
	dst_nritems = btrfs_header_nritems(&dst->header);
C
Chris Mason 已提交
784
	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
785 786 787 788 789 790 791 792 793 794 795
	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 已提交
796 797 798 799 800 801
	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));
802

803 804
	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
805

C
Chris Mason 已提交
806 807
	btrfs_mark_buffer_dirty(src_buf);
	btrfs_mark_buffer_dirty(dst_buf);
C
Chris Mason 已提交
808
	return ret;
809 810
}

C
Chris Mason 已提交
811 812 813 814
/*
 * 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 已提交
815 816
 *
 * returns zero on success or < 0 on failure.
C
Chris Mason 已提交
817
 */
818 819
static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
			   *root, struct btrfs_path *path, int level)
C
Chris Mason 已提交
820
{
C
Chris Mason 已提交
821
	struct buffer_head *t;
C
Chris Mason 已提交
822 823
	struct btrfs_node *lower;
	struct btrfs_node *c;
C
Chris Mason 已提交
824
	struct btrfs_disk_key *lower_key;
C
Chris Mason 已提交
825 826 827 828

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

829
	t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr);
C
Chris Mason 已提交
830
	c = btrfs_buffer_node(t);
C
Chris Mason 已提交
831
	memset(c, 0, root->blocksize);
832 833
	btrfs_set_header_nritems(&c->header, 1);
	btrfs_set_header_level(&c->header, level);
834
	btrfs_set_header_blocknr(&c->header, bh_blocknr(t));
835
	btrfs_set_header_generation(&c->header, trans->transid);
836
	btrfs_set_header_owner(&c->header, root->root_key.objectid);
C
Chris Mason 已提交
837
	lower = btrfs_buffer_node(path->nodes[level-1]);
C
Chris Mason 已提交
838 839
	memcpy(c->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(c->header.fsid));
840
	if (btrfs_is_leaf(lower))
C
Chris Mason 已提交
841
		lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
C
Chris Mason 已提交
842
	else
C
Chris Mason 已提交
843
		lower_key = &lower->ptrs[0].key;
C
Chris Mason 已提交
844 845
	btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key,
		     sizeof(struct btrfs_disk_key));
846
	btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1]));
847

C
Chris Mason 已提交
848
	btrfs_mark_buffer_dirty(t);
849

C
Chris Mason 已提交
850
	/* the super has an extra ref to root->node */
C
Chris Mason 已提交
851
	btrfs_block_release(root, root->node);
C
Chris Mason 已提交
852
	root->node = t;
C
Chris Mason 已提交
853
	get_bh(t);
C
Chris Mason 已提交
854 855 856 857 858
	path->nodes[level] = t;
	path->slots[level] = 0;
	return 0;
}

C
Chris Mason 已提交
859 860 861
/*
 * worker function to insert a single pointer in a node.
 * the node should have enough room for the pointer already
C
Chris Mason 已提交
862
 *
C
Chris Mason 已提交
863 864
 * slot and level indicate where you want the key to go, and
 * blocknr is the block the key points to.
C
Chris Mason 已提交
865 866
 *
 * returns zero on success and < 0 on any error
C
Chris Mason 已提交
867
 */
868 869 870
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 已提交
871
{
C
Chris Mason 已提交
872
	struct btrfs_node *lower;
C
Chris Mason 已提交
873
	int nritems;
C
Chris Mason 已提交
874 875

	BUG_ON(!path->nodes[level]);
C
Chris Mason 已提交
876
	lower = btrfs_buffer_node(path->nodes[level]);
877
	nritems = btrfs_header_nritems(&lower->header);
C
Chris Mason 已提交
878 879
	if (slot > nritems)
		BUG();
C
Chris Mason 已提交
880
	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
C
Chris Mason 已提交
881 882
		BUG();
	if (slot != nritems) {
C
Chris Mason 已提交
883 884 885
		btrfs_memmove(root, lower, lower->ptrs + slot + 1,
			      lower->ptrs + slot,
			      (nritems - slot) * sizeof(struct btrfs_key_ptr));
C
Chris Mason 已提交
886
	}
C
Chris Mason 已提交
887 888
	btrfs_memcpy(root, lower, &lower->ptrs[slot].key,
		     key, sizeof(struct btrfs_disk_key));
889
	btrfs_set_node_blockptr(lower, slot, blocknr);
890
	btrfs_set_header_nritems(&lower->header, nritems + 1);
C
Chris Mason 已提交
891
	btrfs_mark_buffer_dirty(path->nodes[level]);
892
	check_node(root, path, level);
C
Chris Mason 已提交
893 894 895
	return 0;
}

C
Chris Mason 已提交
896 897 898 899 900 901
/*
 * 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 已提交
902 903
 *
 * returns 0 on success and < 0 on failure
C
Chris Mason 已提交
904
 */
905 906
static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_path *path, int level)
907
{
C
Chris Mason 已提交
908
	struct buffer_head *t;
C
Chris Mason 已提交
909
	struct btrfs_node *c;
C
Chris Mason 已提交
910
	struct buffer_head *split_buffer;
C
Chris Mason 已提交
911
	struct btrfs_node *split;
912
	int mid;
C
Chris Mason 已提交
913
	int ret;
C
Chris Mason 已提交
914
	int wret;
915
	u32 c_nritems;
916

C
Chris Mason 已提交
917
	t = path->nodes[level];
C
Chris Mason 已提交
918
	c = btrfs_buffer_node(t);
C
Chris Mason 已提交
919 920
	if (t == root->node) {
		/* trying to split the root, lets make a new one */
921
		ret = insert_new_root(trans, root, path, level + 1);
C
Chris Mason 已提交
922 923
		if (ret)
			return ret;
924 925 926 927 928 929 930 931
	} 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;
932
	}
933

934
	c_nritems = btrfs_header_nritems(&c->header);
935
	split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr);
C
Chris Mason 已提交
936
	split = btrfs_buffer_node(split_buffer);
937
	btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
938
	btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
939
	btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer));
940
	btrfs_set_header_generation(&split->header, trans->transid);
941
	btrfs_set_header_owner(&split->header, root->root_key.objectid);
C
Chris Mason 已提交
942 943
	memcpy(split->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(split->header.fsid));
944
	mid = (c_nritems + 1) / 2;
C
Chris Mason 已提交
945 946
	btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid,
		     (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
947 948
	btrfs_set_header_nritems(&split->header, c_nritems - mid);
	btrfs_set_header_nritems(&c->header, mid);
C
Chris Mason 已提交
949 950
	ret = 0;

C
Chris Mason 已提交
951 952
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(split_buffer);
953
	wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
954
			  bh_blocknr(split_buffer), path->slots[level + 1] + 1,
C
Chris Mason 已提交
955
			  level + 1);
C
Chris Mason 已提交
956 957 958
	if (wret)
		ret = wret;

C
Chris Mason 已提交
959
	if (path->slots[level] >= mid) {
C
Chris Mason 已提交
960
		path->slots[level] -= mid;
C
Chris Mason 已提交
961
		btrfs_block_release(root, t);
C
Chris Mason 已提交
962 963 964
		path->nodes[level] = split_buffer;
		path->slots[level + 1] += 1;
	} else {
C
Chris Mason 已提交
965
		btrfs_block_release(root, split_buffer);
966
	}
C
Chris Mason 已提交
967
	return ret;
968 969
}

C
Chris Mason 已提交
970 971 972 973 974
/*
 * 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 已提交
975
static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
976 977
{
	int data_len;
978 979
	int nritems = btrfs_header_nritems(&l->header);
	int end = min(nritems, start + nr) - 1;
980 981 982

	if (!nr)
		return 0;
C
Chris Mason 已提交
983 984 985
	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;
986
	WARN_ON(data_len < 0);
987 988 989
	return data_len;
}

990 991 992 993 994 995 996 997 998 999 1000
/*
 * 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 已提交
1001 1002 1003
/*
 * 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 已提交
1004 1005 1006
 *
 * 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 已提交
1007
 */
1008 1009
static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
			   *root, struct btrfs_path *path, int data_size)
C
Chris Mason 已提交
1010
{
C
Chris Mason 已提交
1011 1012
	struct buffer_head *left_buf = path->nodes[0];
	struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf);
C
Chris Mason 已提交
1013
	struct btrfs_leaf *right;
C
Chris Mason 已提交
1014 1015 1016
	struct buffer_head *right_buf;
	struct buffer_head *upper;
	struct btrfs_node *upper_node;
C
Chris Mason 已提交
1017 1018 1019 1020 1021
	int slot;
	int i;
	int free_space;
	int push_space = 0;
	int push_items = 0;
C
Chris Mason 已提交
1022
	struct btrfs_item *item;
1023 1024
	u32 left_nritems;
	u32 right_nritems;
C
Chris Mason 已提交
1025 1026 1027 1028 1029 1030

	slot = path->slots[1];
	if (!path->nodes[1]) {
		return 1;
	}
	upper = path->nodes[1];
C
Chris Mason 已提交
1031 1032
	upper_node = btrfs_buffer_node(upper);
	if (slot >= btrfs_header_nritems(&upper_node->header) - 1) {
C
Chris Mason 已提交
1033 1034
		return 1;
	}
C
Chris Mason 已提交
1035 1036 1037
	right_buf = read_tree_block(root,
		    btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1));
	right = btrfs_buffer_leaf(right_buf);
C
Chris Mason 已提交
1038
	free_space = btrfs_leaf_free_space(root, right);
C
Chris Mason 已提交
1039
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1040
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1041 1042
		return 1;
	}
C
Chris Mason 已提交
1043
	/* cow and double check */
1044
	btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf);
C
Chris Mason 已提交
1045
	right = btrfs_buffer_leaf(right_buf);
C
Chris Mason 已提交
1046
	free_space = btrfs_leaf_free_space(root, right);
C
Chris Mason 已提交
1047
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1048
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1049 1050 1051
		return 1;
	}

1052
	left_nritems = btrfs_header_nritems(&left->header);
1053 1054 1055 1056 1057
	if (left_nritems == 0) {
		btrfs_block_release(root, right_buf);
		return 1;
	}
	for (i = left_nritems - 1; i >= 1; i--) {
C
Chris Mason 已提交
1058 1059 1060
		item = left->items + i;
		if (path->slots[0] == i)
			push_space += data_size + sizeof(*item);
C
Chris Mason 已提交
1061 1062
		if (btrfs_item_size(item) + sizeof(*item) + push_space >
		    free_space)
C
Chris Mason 已提交
1063 1064
			break;
		push_items++;
C
Chris Mason 已提交
1065
		push_space += btrfs_item_size(item) + sizeof(*item);
C
Chris Mason 已提交
1066 1067
	}
	if (push_items == 0) {
C
Chris Mason 已提交
1068
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1069 1070
		return 1;
	}
1071 1072
	if (push_items == left_nritems)
		WARN_ON(1);
1073
	right_nritems = btrfs_header_nritems(&right->header);
C
Chris Mason 已提交
1074
	/* push left to right */
C
Chris Mason 已提交
1075
	push_space = btrfs_item_end(left->items + left_nritems - push_items);
C
Chris Mason 已提交
1076
	push_space -= leaf_data_end(root, left);
C
Chris Mason 已提交
1077
	/* make room in the right data area */
C
Chris Mason 已提交
1078 1079 1080 1081 1082
	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 已提交
1083
	/* copy from the left data area */
C
Chris Mason 已提交
1084 1085 1086 1087 1088
	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 已提交
1089
		right_nritems * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1090
	/* copy the items from left to right */
C
Chris Mason 已提交
1091 1092 1093
	btrfs_memcpy(root, right, right->items, left->items +
		     left_nritems - push_items,
		     push_items * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1094 1095

	/* update the item pointers */
1096 1097
	right_nritems += push_items;
	btrfs_set_header_nritems(&right->header, right_nritems);
C
Chris Mason 已提交
1098
	push_space = BTRFS_LEAF_DATA_SIZE(root);
1099
	for (i = 0; i < right_nritems; i++) {
C
Chris Mason 已提交
1100 1101 1102
		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 已提交
1103
	}
1104 1105
	left_nritems -= push_items;
	btrfs_set_header_nritems(&left->header, left_nritems);
C
Chris Mason 已提交
1106

C
Chris Mason 已提交
1107 1108
	btrfs_mark_buffer_dirty(left_buf);
	btrfs_mark_buffer_dirty(right_buf);
1109

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

C
Chris Mason 已提交
1114
	/* then fixup the leaf pointer in the path */
1115 1116
	if (path->slots[0] >= left_nritems) {
		path->slots[0] -= left_nritems;
C
Chris Mason 已提交
1117
		btrfs_block_release(root, path->nodes[0]);
C
Chris Mason 已提交
1118 1119 1120
		path->nodes[0] = right_buf;
		path->slots[1] += 1;
	} else {
C
Chris Mason 已提交
1121
		btrfs_block_release(root, right_buf);
C
Chris Mason 已提交
1122
	}
1123 1124
	if (path->nodes[1])
		check_node(root, path, 1);
C
Chris Mason 已提交
1125 1126
	return 0;
}
C
Chris Mason 已提交
1127 1128 1129 1130
/*
 * 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
 */
1131 1132
static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
			  *root, struct btrfs_path *path, int data_size)
1133
{
C
Chris Mason 已提交
1134 1135 1136
	struct buffer_head *right_buf = path->nodes[0];
	struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf);
	struct buffer_head *t;
C
Chris Mason 已提交
1137
	struct btrfs_leaf *left;
1138 1139 1140 1141 1142
	int slot;
	int i;
	int free_space;
	int push_space = 0;
	int push_items = 0;
C
Chris Mason 已提交
1143
	struct btrfs_item *item;
1144
	u32 old_left_nritems;
C
Chris Mason 已提交
1145 1146
	int ret = 0;
	int wret;
1147 1148 1149 1150 1151 1152 1153 1154

	slot = path->slots[1];
	if (slot == 0) {
		return 1;
	}
	if (!path->nodes[1]) {
		return 1;
	}
C
Chris Mason 已提交
1155 1156 1157
	t = read_tree_block(root,
	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1));
	left = btrfs_buffer_leaf(t);
C
Chris Mason 已提交
1158
	free_space = btrfs_leaf_free_space(root, left);
C
Chris Mason 已提交
1159
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1160
		btrfs_block_release(root, t);
1161 1162
		return 1;
	}
C
Chris Mason 已提交
1163 1164

	/* cow and double check */
1165
	btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
C
Chris Mason 已提交
1166
	left = btrfs_buffer_leaf(t);
C
Chris Mason 已提交
1167
	free_space = btrfs_leaf_free_space(root, left);
C
Chris Mason 已提交
1168
	if (free_space < data_size + sizeof(struct btrfs_item)) {
C
Chris Mason 已提交
1169
		btrfs_block_release(root, t);
C
Chris Mason 已提交
1170 1171 1172
		return 1;
	}

1173 1174 1175 1176 1177 1178
	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++) {
1179 1180 1181
		item = right->items + i;
		if (path->slots[0] == i)
			push_space += data_size + sizeof(*item);
C
Chris Mason 已提交
1182 1183
		if (btrfs_item_size(item) + sizeof(*item) + push_space >
		    free_space)
1184 1185
			break;
		push_items++;
C
Chris Mason 已提交
1186
		push_space += btrfs_item_size(item) + sizeof(*item);
1187 1188
	}
	if (push_items == 0) {
C
Chris Mason 已提交
1189
		btrfs_block_release(root, t);
1190 1191
		return 1;
	}
1192 1193
	if (push_items == btrfs_header_nritems(&right->header))
		WARN_ON(1);
1194
	/* push data from right to left */
C
Chris Mason 已提交
1195 1196 1197
	btrfs_memcpy(root, left, left->items +
		     btrfs_header_nritems(&left->header),
		     right->items, push_items * sizeof(struct btrfs_item));
C
Chris Mason 已提交
1198
	push_space = BTRFS_LEAF_DATA_SIZE(root) -
C
Chris Mason 已提交
1199
		     btrfs_item_offset(right->items + push_items -1);
C
Chris Mason 已提交
1200 1201 1202 1203 1204
	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);
1205
	old_left_nritems = btrfs_header_nritems(&left->header);
1206 1207
	BUG_ON(old_left_nritems < 0);

C
Chris Mason 已提交
1208
	for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
C
Chris Mason 已提交
1209 1210 1211
		u32 ioff = btrfs_item_offset(left->items + i);
		btrfs_set_item_offset(left->items + i, ioff -
				     (BTRFS_LEAF_DATA_SIZE(root) -
C
Chris Mason 已提交
1212 1213
				      btrfs_item_offset(left->items +
						        old_left_nritems - 1)));
1214
	}
1215
	btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
1216 1217

	/* fixup right node */
C
Chris Mason 已提交
1218
	push_space = btrfs_item_offset(right->items + push_items - 1) -
C
Chris Mason 已提交
1219
		     leaf_data_end(root, right);
C
Chris Mason 已提交
1220 1221 1222 1223 1224
	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,
1225
		(btrfs_header_nritems(&right->header) - push_items) *
C
Chris Mason 已提交
1226
		sizeof(struct btrfs_item));
1227 1228 1229
	btrfs_set_header_nritems(&right->header,
				 btrfs_header_nritems(&right->header) -
				 push_items);
C
Chris Mason 已提交
1230
	push_space = BTRFS_LEAF_DATA_SIZE(root);
1231

1232
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1233 1234 1235
		btrfs_set_item_offset(right->items + i, push_space -
				      btrfs_item_size(right->items + i));
		push_space = btrfs_item_offset(right->items + i);
1236
	}
1237

C
Chris Mason 已提交
1238 1239
	btrfs_mark_buffer_dirty(t);
	btrfs_mark_buffer_dirty(right_buf);
1240

1241
	wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
C
Chris Mason 已提交
1242 1243
	if (wret)
		ret = wret;
1244 1245 1246 1247

	/* then fixup the leaf pointer in the path */
	if (path->slots[0] < push_items) {
		path->slots[0] += old_left_nritems;
C
Chris Mason 已提交
1248
		btrfs_block_release(root, path->nodes[0]);
1249
		path->nodes[0] = t;
1250 1251
		path->slots[1] -= 1;
	} else {
C
Chris Mason 已提交
1252
		btrfs_block_release(root, t);
1253 1254
		path->slots[0] -= push_items;
	}
1255
	BUG_ON(path->slots[0] < 0);
1256 1257
	if (path->nodes[1])
		check_node(root, path, 1);
C
Chris Mason 已提交
1258
	return ret;
1259 1260
}

C
Chris Mason 已提交
1261 1262 1263
/*
 * 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 已提交
1264 1265
 *
 * returns 0 if all went well and < 0 on failure.
C
Chris Mason 已提交
1266
 */
1267
static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1268 1269
		      *root, struct btrfs_key *ins_key,
		      struct btrfs_path *path, int data_size)
1270
{
C
Chris Mason 已提交
1271
	struct buffer_head *l_buf;
C
Chris Mason 已提交
1272
	struct btrfs_leaf *l;
1273
	u32 nritems;
1274 1275
	int mid;
	int slot;
C
Chris Mason 已提交
1276
	struct btrfs_leaf *right;
C
Chris Mason 已提交
1277
	struct buffer_head *right_buffer;
C
Chris Mason 已提交
1278
	int space_needed = data_size + sizeof(struct btrfs_item);
1279 1280 1281
	int data_copy_size;
	int rt_data_off;
	int i;
1282
	int ret = 0;
C
Chris Mason 已提交
1283
	int wret;
1284 1285
	int double_split = 0;
	struct btrfs_disk_key disk_key;
C
Chris Mason 已提交
1286

C
Chris Mason 已提交
1287
	/* first try to make some room by pushing left and right */
1288
	wret = push_leaf_left(trans, root, path, data_size);
C
Chris Mason 已提交
1289 1290 1291
	if (wret < 0)
		return wret;
	if (wret) {
1292
		wret = push_leaf_right(trans, root, path, data_size);
C
Chris Mason 已提交
1293 1294 1295
		if (wret < 0)
			return wret;
	}
C
Chris Mason 已提交
1296
	l_buf = path->nodes[0];
C
Chris Mason 已提交
1297
	l = btrfs_buffer_leaf(l_buf);
C
Chris Mason 已提交
1298 1299

	/* did the pushes work? */
C
Chris Mason 已提交
1300 1301
	if (btrfs_leaf_free_space(root, l) >=
	    sizeof(struct btrfs_item) + data_size)
C
Chris Mason 已提交
1302 1303
		return 0;

C
Chris Mason 已提交
1304
	if (!path->nodes[1]) {
1305
		ret = insert_new_root(trans, root, path, 1);
C
Chris Mason 已提交
1306 1307 1308
		if (ret)
			return ret;
	}
1309
	slot = path->slots[0];
1310
	nritems = btrfs_header_nritems(&l->header);
1311
	mid = (nritems + 1)/ 2;
1312
	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
1313
	BUG_ON(!right_buffer);
C
Chris Mason 已提交
1314
	right = btrfs_buffer_leaf(right_buffer);
C
Chris Mason 已提交
1315
	memset(&right->header, 0, sizeof(right->header));
1316
	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1317
	btrfs_set_header_generation(&right->header, trans->transid);
1318
	btrfs_set_header_owner(&right->header, root->root_key.objectid);
1319
	btrfs_set_header_level(&right->header, 0);
C
Chris Mason 已提交
1320 1321
	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(right->header.fsid));
1322 1323 1324 1325 1326 1327 1328 1329 1330
	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,
1331
						  bh_blocknr(right_buffer),
1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351
						  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,
1352
						  bh_blocknr(right_buffer),
1353
						  path->slots[1], 1);
1354 1355 1356 1357 1358
				if (wret)
					ret = wret;
				btrfs_block_release(root, path->nodes[0]);
				path->nodes[0] = right_buffer;
				path->slots[0] = 0;
1359 1360 1361 1362 1363 1364
				if (path->slots[1] == 0) {
					wret = fixup_low_keys(trans, root,
					           path, &disk_key, 1);
					if (wret)
						ret = wret;
				}
1365 1366 1367 1368 1369 1370 1371
				return ret;
			}
			mid = slot;
			double_split = 1;
		}
	}
	btrfs_set_header_nritems(&right->header, nritems - mid);
C
Chris Mason 已提交
1372 1373
	data_copy_size = btrfs_item_end(l->items + mid) -
			 leaf_data_end(root, l);
C
Chris Mason 已提交
1374 1375 1376 1377 1378 1379
	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 已提交
1380 1381
	rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
		      btrfs_item_end(l->items + mid);
C
Chris Mason 已提交
1382

C
Chris Mason 已提交
1383
	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
C
Chris Mason 已提交
1384
		u32 ioff = btrfs_item_offset(right->items + i);
C
Chris Mason 已提交
1385 1386
		btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
	}
C
Chris Mason 已提交
1387

1388
	btrfs_set_header_nritems(&l->header, mid);
C
Chris Mason 已提交
1389
	ret = 0;
1390
	wret = insert_ptr(trans, root, path, &right->items[0].key,
1391
			  bh_blocknr(right_buffer), path->slots[1] + 1, 1);
C
Chris Mason 已提交
1392 1393
	if (wret)
		ret = wret;
C
Chris Mason 已提交
1394 1395
	btrfs_mark_buffer_dirty(right_buffer);
	btrfs_mark_buffer_dirty(l_buf);
1396
	BUG_ON(path->slots[0] != slot);
1397
	if (mid <= slot) {
C
Chris Mason 已提交
1398
		btrfs_block_release(root, path->nodes[0]);
1399
		path->nodes[0] = right_buffer;
1400 1401
		path->slots[0] -= mid;
		path->slots[1] += 1;
1402
	} else
C
Chris Mason 已提交
1403
		btrfs_block_release(root, right_buffer);
1404
	BUG_ON(path->slots[0] < 0);
1405
	check_node(root, path, 1);
1406 1407 1408

	if (!double_split)
		return ret;
1409
	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
1410 1411 1412
	BUG_ON(!right_buffer);
	right = btrfs_buffer_leaf(right_buffer);
	memset(&right->header, 0, sizeof(right->header));
1413
	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1414
	btrfs_set_header_generation(&right->header, trans->transid);
1415
	btrfs_set_header_owner(&right->header, root->root_key.objectid);
1416
	btrfs_set_header_level(&right->header, 0);
C
Chris Mason 已提交
1417 1418
	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
	       sizeof(right->header.fsid));
1419 1420 1421 1422
	btrfs_cpu_key_to_disk(&disk_key, ins_key);
	btrfs_set_header_nritems(&right->header, 0);
	wret = insert_ptr(trans, root, path,
			  &disk_key,
1423
			  bh_blocknr(right_buffer),
1424 1425 1426
			  path->slots[1], 1);
	if (wret)
		ret = wret;
1427 1428 1429 1430 1431
	if (path->slots[1] == 0) {
		wret = fixup_low_keys(trans, root, path, &disk_key, 1);
		if (wret)
			ret = wret;
	}
1432 1433 1434 1435 1436
	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);
1437 1438 1439
	return ret;
}

C
Chris Mason 已提交
1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495
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;
}

1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
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 已提交
1550 1551 1552 1553
/*
 * 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.
 */
1554 1555 1556
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)
1557
{
C
Chris Mason 已提交
1558
	int ret = 0;
1559
	int slot;
1560
	int slot_orig;
C
Chris Mason 已提交
1561
	struct btrfs_leaf *leaf;
C
Chris Mason 已提交
1562
	struct buffer_head *leaf_buf;
1563
	u32 nritems;
1564
	unsigned int data_end;
C
Chris Mason 已提交
1565 1566 1567
	struct btrfs_disk_key disk_key;

	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1568

C
Chris Mason 已提交
1569
	/* create a root if there isn't one */
C
Chris Mason 已提交
1570
	if (!root->node)
C
Chris Mason 已提交
1571
		BUG();
1572
	ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
1573
	if (ret == 0) {
1574
		return -EEXIST;
C
Chris Mason 已提交
1575
	}
1576 1577
	if (ret < 0)
		goto out;
1578

1579 1580
	slot_orig = path->slots[0];
	leaf_buf = path->nodes[0];
C
Chris Mason 已提交
1581
	leaf = btrfs_buffer_leaf(leaf_buf);
C
Chris Mason 已提交
1582

1583
	nritems = btrfs_header_nritems(&leaf->header);
C
Chris Mason 已提交
1584
	data_end = leaf_data_end(root, leaf);
1585

C
Chris Mason 已提交
1586
	if (btrfs_leaf_free_space(root, leaf) <
1587
	    sizeof(struct btrfs_item) + data_size) {
1588
		BUG();
1589
	}
1590
	slot = path->slots[0];
1591
	BUG_ON(slot < 0);
1592 1593
	if (slot != nritems) {
		int i;
C
Chris Mason 已提交
1594
		unsigned int old_data = btrfs_item_end(leaf->items + slot);
1595 1596 1597 1598 1599

		/*
		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
		 */
		/* first correct the data pointers */
C
Chris Mason 已提交
1600
		for (i = slot; i < nritems; i++) {
C
Chris Mason 已提交
1601
			u32 ioff = btrfs_item_offset(leaf->items + i);
C
Chris Mason 已提交
1602 1603 1604
			btrfs_set_item_offset(leaf->items + i,
					      ioff - data_size);
		}
1605 1606

		/* shift the items */
C
Chris Mason 已提交
1607 1608 1609
		btrfs_memmove(root, leaf, leaf->items + slot + 1,
			      leaf->items + slot,
			      (nritems - slot) * sizeof(struct btrfs_item));
1610 1611

		/* shift the data */
C
Chris Mason 已提交
1612 1613 1614
		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
			      data_end - data_size, btrfs_leaf_data(leaf) +
			      data_end, old_data - data_end);
1615 1616
		data_end = old_data;
	}
1617
	/* setup the item for the new data */
C
Chris Mason 已提交
1618 1619
	btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key,
		     sizeof(struct btrfs_disk_key));
C
Chris Mason 已提交
1620 1621
	btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
	btrfs_set_item_size(leaf->items + slot, data_size);
1622
	btrfs_set_header_nritems(&leaf->header, nritems + 1);
C
Chris Mason 已提交
1623
	btrfs_mark_buffer_dirty(leaf_buf);
C
Chris Mason 已提交
1624 1625

	ret = 0;
1626
	if (slot == 0)
1627
		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
C
Chris Mason 已提交
1628

C
Chris Mason 已提交
1629
	if (btrfs_leaf_free_space(root, leaf) < 0)
1630
		BUG();
1631
	check_leaf(root, path, 0);
1632
out:
1633 1634 1635 1636 1637 1638 1639
	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.
 */
1640 1641 1642
int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct btrfs_key *cpu_key, void *data, u32
		      data_size)
1643 1644
{
	int ret = 0;
C
Chris Mason 已提交
1645
	struct btrfs_path *path;
1646 1647
	u8 *ptr;

C
Chris Mason 已提交
1648 1649 1650
	path = btrfs_alloc_path();
	BUG_ON(!path);
	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
1651
	if (!ret) {
C
Chris Mason 已提交
1652 1653 1654
		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 已提交
1655
			     ptr, data, data_size);
C
Chris Mason 已提交
1656
		btrfs_mark_buffer_dirty(path->nodes[0]);
1657
	}
C
Chris Mason 已提交
1658 1659
	btrfs_release_path(root, path);
	btrfs_free_path(path);
C
Chris Mason 已提交
1660
	return ret;
1661 1662
}

C
Chris Mason 已提交
1663
/*
C
Chris Mason 已提交
1664
 * delete the pointer from a given node.
C
Chris Mason 已提交
1665 1666 1667 1668 1669
 *
 * 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.
 */
1670 1671
static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path, int level, int slot)
1672
{
C
Chris Mason 已提交
1673
	struct btrfs_node *node;
C
Chris Mason 已提交
1674
	struct buffer_head *parent = path->nodes[level];
1675
	u32 nritems;
C
Chris Mason 已提交
1676
	int ret = 0;
1677
	int wret;
1678

C
Chris Mason 已提交
1679
	node = btrfs_buffer_node(parent);
1680
	nritems = btrfs_header_nritems(&node->header);
1681
	if (slot != nritems -1) {
C
Chris Mason 已提交
1682 1683 1684 1685
		btrfs_memmove(root, node, node->ptrs + slot,
			      node->ptrs + slot + 1,
			      sizeof(struct btrfs_key_ptr) *
			      (nritems - slot - 1));
1686
	}
1687 1688 1689
	nritems--;
	btrfs_set_header_nritems(&node->header, nritems);
	if (nritems == 0 && parent == root->node) {
C
Chris Mason 已提交
1690 1691
		struct btrfs_header *header = btrfs_buffer_header(root->node);
		BUG_ON(btrfs_header_level(header) != 1);
1692
		/* just turn the root into a leaf and break */
C
Chris Mason 已提交
1693
		btrfs_set_header_level(header, 0);
1694
	} else if (slot == 0) {
1695
		wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
C
Chris Mason 已提交
1696
				      level + 1);
C
Chris Mason 已提交
1697 1698
		if (wret)
			ret = wret;
1699
	}
C
Chris Mason 已提交
1700
	btrfs_mark_buffer_dirty(parent);
C
Chris Mason 已提交
1701
	return ret;
1702 1703
}

C
Chris Mason 已提交
1704 1705 1706 1707
/*
 * delete the item at the leaf level in path.  If that empties
 * the leaf, remove it from the tree
 */
1708 1709
int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct btrfs_path *path)
1710 1711
{
	int slot;
C
Chris Mason 已提交
1712
	struct btrfs_leaf *leaf;
C
Chris Mason 已提交
1713
	struct buffer_head *leaf_buf;
1714 1715
	int doff;
	int dsize;
C
Chris Mason 已提交
1716 1717
	int ret = 0;
	int wret;
1718
	u32 nritems;
1719

1720
	leaf_buf = path->nodes[0];
C
Chris Mason 已提交
1721
	leaf = btrfs_buffer_leaf(leaf_buf);
1722
	slot = path->slots[0];
C
Chris Mason 已提交
1723 1724
	doff = btrfs_item_offset(leaf->items + slot);
	dsize = btrfs_item_size(leaf->items + slot);
1725
	nritems = btrfs_header_nritems(&leaf->header);
1726

1727
	if (slot != nritems - 1) {
1728
		int i;
C
Chris Mason 已提交
1729
		int data_end = leaf_data_end(root, leaf);
C
Chris Mason 已提交
1730 1731 1732 1733
		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
			      data_end + dsize,
			      btrfs_leaf_data(leaf) + data_end,
			      doff - data_end);
C
Chris Mason 已提交
1734
		for (i = slot + 1; i < nritems; i++) {
C
Chris Mason 已提交
1735
			u32 ioff = btrfs_item_offset(leaf->items + i);
C
Chris Mason 已提交
1736 1737
			btrfs_set_item_offset(leaf->items + i, ioff + dsize);
		}
C
Chris Mason 已提交
1738 1739 1740 1741
		btrfs_memmove(root, leaf, leaf->items + slot,
			      leaf->items + slot + 1,
			      sizeof(struct btrfs_item) *
			      (nritems - slot - 1));
1742
	}
1743 1744
	btrfs_set_header_nritems(&leaf->header, nritems - 1);
	nritems--;
C
Chris Mason 已提交
1745
	/* delete the leaf if we've emptied it */
1746
	if (nritems == 0) {
1747
		if (leaf_buf == root->node) {
1748
			btrfs_set_header_level(&leaf->header, 0);
1749
		} else {
1750
			clean_tree_block(trans, root, leaf_buf);
C
Chris Mason 已提交
1751
			wait_on_buffer(leaf_buf);
1752
			wret = del_ptr(trans, root, path, 1, path->slots[1]);
C
Chris Mason 已提交
1753 1754
			if (wret)
				ret = wret;
1755
			wret = btrfs_free_extent(trans, root,
1756
						 bh_blocknr(leaf_buf), 1, 1);
C
Chris Mason 已提交
1757 1758
			if (wret)
				ret = wret;
1759
		}
1760
	} else {
1761
		int used = leaf_space_used(leaf, 0, nritems);
C
Chris Mason 已提交
1762
		if (slot == 0) {
1763 1764
			wret = fixup_low_keys(trans, root, path,
					      &leaf->items[0].key, 1);
C
Chris Mason 已提交
1765 1766 1767 1768
			if (wret)
				ret = wret;
		}

C
Chris Mason 已提交
1769
		/* delete the leaf if it is mostly empty */
C
Chris Mason 已提交
1770
		if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
1771 1772 1773 1774
			/* push_leaf_left fixes the path.
			 * make sure the path still points to our leaf
			 * for possible call to del_ptr below
			 */
1775
			slot = path->slots[1];
C
Chris Mason 已提交
1776
			get_bh(leaf_buf);
1777
			wret = push_leaf_left(trans, root, path, 1);
C
Chris Mason 已提交
1778 1779
			if (wret < 0)
				ret = wret;
1780
			if (path->nodes[0] == leaf_buf &&
1781
			    btrfs_header_nritems(&leaf->header)) {
1782
				wret = push_leaf_right(trans, root, path, 1);
C
Chris Mason 已提交
1783 1784 1785
				if (wret < 0)
					ret = wret;
			}
1786
			if (btrfs_header_nritems(&leaf->header) == 0) {
1787
				u64 blocknr = bh_blocknr(leaf_buf);
1788
				clean_tree_block(trans, root, leaf_buf);
C
Chris Mason 已提交
1789
				wait_on_buffer(leaf_buf);
1790
				wret = del_ptr(trans, root, path, 1, slot);
C
Chris Mason 已提交
1791 1792
				if (wret)
					ret = wret;
C
Chris Mason 已提交
1793
				btrfs_block_release(root, leaf_buf);
1794 1795
				wret = btrfs_free_extent(trans, root, blocknr,
							 1, 1);
C
Chris Mason 已提交
1796 1797
				if (wret)
					ret = wret;
C
Chris Mason 已提交
1798
			} else {
C
Chris Mason 已提交
1799
				btrfs_mark_buffer_dirty(leaf_buf);
C
Chris Mason 已提交
1800
				btrfs_block_release(root, leaf_buf);
1801
			}
1802
		} else {
C
Chris Mason 已提交
1803
			btrfs_mark_buffer_dirty(leaf_buf);
1804 1805
		}
	}
C
Chris Mason 已提交
1806
	return ret;
1807 1808
}

C
Chris Mason 已提交
1809 1810
/*
 * walk up the tree as far as required to find the next leaf.
C
Chris Mason 已提交
1811 1812
 * returns 0 if it found something or 1 if there are no greater leaves.
 * returns < 0 on io errors.
C
Chris Mason 已提交
1813
 */
C
Chris Mason 已提交
1814
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
1815 1816 1817 1818
{
	int slot;
	int level = 1;
	u64 blocknr;
C
Chris Mason 已提交
1819 1820 1821
	struct buffer_head *c;
	struct btrfs_node *c_node;
	struct buffer_head *next = NULL;
1822

C
Chris Mason 已提交
1823
	while(level < BTRFS_MAX_LEVEL) {
1824
		if (!path->nodes[level])
C
Chris Mason 已提交
1825
			return 1;
1826 1827
		slot = path->slots[level] + 1;
		c = path->nodes[level];
C
Chris Mason 已提交
1828 1829
		c_node = btrfs_buffer_node(c);
		if (slot >= btrfs_header_nritems(&c_node->header)) {
1830 1831 1832
			level++;
			continue;
		}
C
Chris Mason 已提交
1833
		blocknr = btrfs_node_blockptr(c_node, slot);
C
Chris Mason 已提交
1834
		if (next)
C
Chris Mason 已提交
1835
			btrfs_block_release(root, next);
1836 1837 1838 1839 1840 1841 1842
		next = read_tree_block(root, blocknr);
		break;
	}
	path->slots[level] = slot;
	while(1) {
		level--;
		c = path->nodes[level];
C
Chris Mason 已提交
1843
		btrfs_block_release(root, c);
1844 1845 1846 1847
		path->nodes[level] = next;
		path->slots[level] = 0;
		if (!level)
			break;
1848
		next = read_tree_block(root,
C
Chris Mason 已提交
1849
		       btrfs_node_blockptr(btrfs_buffer_node(next), 0));
1850 1851 1852
	}
	return 0;
}