xref: /openbmc/linux/fs/btrfs/ctree.c (revision 6cbd5570)
16cbd5570SChris Mason /*
26cbd5570SChris Mason  * Copyright (C) 2007 Oracle.  All rights reserved.
36cbd5570SChris Mason  *
46cbd5570SChris Mason  * This program is free software; you can redistribute it and/or
56cbd5570SChris Mason  * modify it under the terms of the GNU General Public
66cbd5570SChris Mason  * License v2 as published by the Free Software Foundation.
76cbd5570SChris Mason  *
86cbd5570SChris Mason  * This program is distributed in the hope that it will be useful,
96cbd5570SChris Mason  * but WITHOUT ANY WARRANTY; without even the implied warranty of
106cbd5570SChris Mason  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
116cbd5570SChris Mason  * General Public License for more details.
126cbd5570SChris Mason  *
136cbd5570SChris Mason  * You should have received a copy of the GNU General Public
146cbd5570SChris Mason  * License along with this program; if not, write to the
156cbd5570SChris Mason  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
166cbd5570SChris Mason  * Boston, MA 021110-1307, USA.
176cbd5570SChris Mason  */
186cbd5570SChris Mason 
192e635a27SChris Mason #include <linux/module.h>
20eb60ceacSChris Mason #include "ctree.h"
21eb60ceacSChris Mason #include "disk-io.h"
227f5c1516SChris Mason #include "transaction.h"
239a8dd150SChris Mason 
24e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
25e089f05cSChris Mason 		      *root, struct btrfs_path *path, int level);
26e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
27d4dbff95SChris Mason 		      *root, struct btrfs_key *ins_key,
28d4dbff95SChris Mason 		      struct btrfs_path *path, int data_size);
29e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
30e20d96d6SChris Mason 			  *root, struct buffer_head *dst, struct buffer_head
31e089f05cSChris Mason 			  *src);
32e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct
33e20d96d6SChris Mason 			      btrfs_root *root, struct buffer_head *dst_buf,
34e20d96d6SChris Mason 			      struct buffer_head *src_buf);
35e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
36e089f05cSChris Mason 		   struct btrfs_path *path, int level, int slot);
37d97e63b6SChris Mason 
38df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p)
39df24a2b9SChris Mason {
40df24a2b9SChris Mason 	memset(p, 0, sizeof(*p));
41df24a2b9SChris Mason }
42df24a2b9SChris Mason 
432c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void)
442c90e5d6SChris Mason {
45df24a2b9SChris Mason 	struct btrfs_path *path;
46df24a2b9SChris Mason 	path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
47df24a2b9SChris Mason 	if (path)
48df24a2b9SChris Mason 		btrfs_init_path(path);
49df24a2b9SChris Mason 	return path;
502c90e5d6SChris Mason }
512c90e5d6SChris Mason 
522c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p)
532c90e5d6SChris Mason {
54df24a2b9SChris Mason 	btrfs_release_path(NULL, p);
552c90e5d6SChris Mason 	kmem_cache_free(btrfs_path_cachep, p);
562c90e5d6SChris Mason }
572c90e5d6SChris Mason 
58234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
59eb60ceacSChris Mason {
60eb60ceacSChris Mason 	int i;
61234b63a0SChris Mason 	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
62eb60ceacSChris Mason 		if (!p->nodes[i])
63eb60ceacSChris Mason 			break;
64234b63a0SChris Mason 		btrfs_block_release(root, p->nodes[i]);
65eb60ceacSChris Mason 	}
66aa5d6bedSChris Mason 	memset(p, 0, sizeof(*p));
67eb60ceacSChris Mason }
68eb60ceacSChris Mason 
69e089f05cSChris Mason static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
70e20d96d6SChris Mason 			   *root, struct buffer_head *buf, struct buffer_head
71e20d96d6SChris Mason 			   *parent, int parent_slot, struct buffer_head
72e089f05cSChris Mason 			   **cow_ret)
7302217ed2SChris Mason {
74e20d96d6SChris Mason 	struct buffer_head *cow;
75e20d96d6SChris Mason 	struct btrfs_node *cow_node;
7602217ed2SChris Mason 
777f5c1516SChris Mason 	if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
787f5c1516SChris Mason 				    trans->transid) {
7902217ed2SChris Mason 		*cow_ret = buf;
8002217ed2SChris Mason 		return 0;
8102217ed2SChris Mason 	}
8231f3c99bSChris Mason 	cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr);
83e20d96d6SChris Mason 	cow_node = btrfs_buffer_node(cow);
842c90e5d6SChris Mason 	if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
852c90e5d6SChris Mason 		WARN_ON(1);
86e20d96d6SChris Mason 	memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
877eccb903SChris Mason 	btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow));
887f5c1516SChris Mason 	btrfs_set_header_generation(&cow_node->header, trans->transid);
894d775673SChris Mason 	btrfs_set_header_owner(&cow_node->header, root->root_key.objectid);
90e089f05cSChris Mason 	btrfs_inc_ref(trans, root, buf);
9102217ed2SChris Mason 	if (buf == root->node) {
9202217ed2SChris Mason 		root->node = cow;
93e20d96d6SChris Mason 		get_bh(cow);
942c90e5d6SChris Mason 		if (buf != root->commit_root) {
957eccb903SChris Mason 			btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
962c90e5d6SChris Mason 		}
97234b63a0SChris Mason 		btrfs_block_release(root, buf);
9802217ed2SChris Mason 	} else {
99e20d96d6SChris Mason 		btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
1007eccb903SChris Mason 					bh_blocknr(cow));
101d6025579SChris Mason 		btrfs_mark_buffer_dirty(parent);
1027eccb903SChris Mason 		btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
10302217ed2SChris Mason 	}
104234b63a0SChris Mason 	btrfs_block_release(root, buf);
105df24a2b9SChris Mason 	mark_buffer_dirty(cow);
1062c90e5d6SChris Mason 	*cow_ret = cow;
10702217ed2SChris Mason 	return 0;
10802217ed2SChris Mason }
10902217ed2SChris Mason 
11074123bd7SChris Mason /*
11174123bd7SChris Mason  * The leaf data grows from end-to-front in the node.
11274123bd7SChris Mason  * this returns the address of the start of the last item,
11374123bd7SChris Mason  * which is the stop of the leaf data stack
11474123bd7SChris Mason  */
115123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root,
116123abc88SChris Mason 					 struct btrfs_leaf *leaf)
117be0e5c09SChris Mason {
1187518a238SChris Mason 	u32 nr = btrfs_header_nritems(&leaf->header);
119be0e5c09SChris Mason 	if (nr == 0)
120123abc88SChris Mason 		return BTRFS_LEAF_DATA_SIZE(root);
1210783fcfcSChris Mason 	return btrfs_item_offset(leaf->items + nr - 1);
122be0e5c09SChris Mason }
123be0e5c09SChris Mason 
12474123bd7SChris Mason /*
12574123bd7SChris Mason  * compare two keys in a memcmp fashion
12674123bd7SChris Mason  */
1279aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
128be0e5c09SChris Mason {
129e2fa7227SChris Mason 	struct btrfs_key k1;
130e2fa7227SChris Mason 
131e2fa7227SChris Mason 	btrfs_disk_key_to_cpu(&k1, disk);
132e2fa7227SChris Mason 
133e2fa7227SChris Mason 	if (k1.objectid > k2->objectid)
134be0e5c09SChris Mason 		return 1;
135e2fa7227SChris Mason 	if (k1.objectid < k2->objectid)
136be0e5c09SChris Mason 		return -1;
137f254e52cSChris Mason 	if (k1.flags > k2->flags)
138f254e52cSChris Mason 		return 1;
139f254e52cSChris Mason 	if (k1.flags < k2->flags)
140f254e52cSChris Mason 		return -1;
14170b2befdSChris Mason 	if (k1.offset > k2->offset)
14270b2befdSChris Mason 		return 1;
14370b2befdSChris Mason 	if (k1.offset < k2->offset)
14470b2befdSChris Mason 		return -1;
145be0e5c09SChris Mason 	return 0;
146be0e5c09SChris Mason }
14774123bd7SChris Mason 
148123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path,
149123abc88SChris Mason 		      int level)
150aa5d6bedSChris Mason {
151234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
152e20d96d6SChris Mason 	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
153aa5d6bedSChris Mason 	int parent_slot;
1548d7be552SChris Mason 	int slot;
1558d7be552SChris Mason 	struct btrfs_key cpukey;
1567518a238SChris Mason 	u32 nritems = btrfs_header_nritems(&node->header);
157aa5d6bedSChris Mason 
158aa5d6bedSChris Mason 	if (path->nodes[level + 1])
159e20d96d6SChris Mason 		parent = btrfs_buffer_node(path->nodes[level + 1]);
160aa5d6bedSChris Mason 	parent_slot = path->slots[level + 1];
1618d7be552SChris Mason 	slot = path->slots[level];
1627518a238SChris Mason 	BUG_ON(nritems == 0);
1637518a238SChris Mason 	if (parent) {
164e2fa7227SChris Mason 		struct btrfs_disk_key *parent_key;
165123abc88SChris Mason 		parent_key = &parent->ptrs[parent_slot].key;
166123abc88SChris Mason 		BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
167e2fa7227SChris Mason 			      sizeof(struct btrfs_disk_key)));
1681d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
1697518a238SChris Mason 		       btrfs_header_blocknr(&node->header));
170aa5d6bedSChris Mason 	}
171123abc88SChris Mason 	BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
1728d7be552SChris Mason 	if (slot != 0) {
1738d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key);
1748d7be552SChris Mason 		BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0);
1758d7be552SChris Mason 	}
1768d7be552SChris Mason 	if (slot < nritems - 1) {
1778d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key);
1788d7be552SChris Mason 		BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0);
179aa5d6bedSChris Mason 	}
180aa5d6bedSChris Mason 	return 0;
181aa5d6bedSChris Mason }
182aa5d6bedSChris Mason 
183123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
184123abc88SChris Mason 		      int level)
185aa5d6bedSChris Mason {
186e20d96d6SChris Mason 	struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]);
187234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
188aa5d6bedSChris Mason 	int parent_slot;
1898d7be552SChris Mason 	int slot = path->slots[0];
1908d7be552SChris Mason 	struct btrfs_key cpukey;
1918d7be552SChris Mason 
1927518a238SChris Mason 	u32 nritems = btrfs_header_nritems(&leaf->header);
193aa5d6bedSChris Mason 
194aa5d6bedSChris Mason 	if (path->nodes[level + 1])
195e20d96d6SChris Mason 		parent = btrfs_buffer_node(path->nodes[level + 1]);
196aa5d6bedSChris Mason 	parent_slot = path->slots[level + 1];
197123abc88SChris Mason 	BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
1987518a238SChris Mason 
1997518a238SChris Mason 	if (nritems == 0)
2007518a238SChris Mason 		return 0;
2017518a238SChris Mason 
2027518a238SChris Mason 	if (parent) {
203e2fa7227SChris Mason 		struct btrfs_disk_key *parent_key;
204123abc88SChris Mason 		parent_key = &parent->ptrs[parent_slot].key;
205aa5d6bedSChris Mason 		BUG_ON(memcmp(parent_key, &leaf->items[0].key,
206e2fa7227SChris Mason 		       sizeof(struct btrfs_disk_key)));
2071d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
2087518a238SChris Mason 		       btrfs_header_blocknr(&leaf->header));
209aa5d6bedSChris Mason 	}
2108d7be552SChris Mason 	if (slot != 0) {
2118d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key);
2128d7be552SChris Mason 		BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0);
2138d7be552SChris Mason 		BUG_ON(btrfs_item_offset(leaf->items + slot - 1) !=
2148d7be552SChris Mason 			btrfs_item_end(leaf->items + slot));
215aa5d6bedSChris Mason 	}
2168d7be552SChris Mason 	if (slot < nritems - 1) {
2178d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key);
2188d7be552SChris Mason 		BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0);
2198d7be552SChris Mason 		BUG_ON(btrfs_item_offset(leaf->items + slot) !=
2208d7be552SChris Mason 			btrfs_item_end(leaf->items + slot + 1));
221aa5d6bedSChris Mason 	}
2228d7be552SChris Mason 	BUG_ON(btrfs_item_offset(leaf->items) +
2238d7be552SChris Mason 	       btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root));
224aa5d6bedSChris Mason 	return 0;
225aa5d6bedSChris Mason }
226aa5d6bedSChris Mason 
227123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path,
228123abc88SChris Mason 			int level)
229aa5d6bedSChris Mason {
2303eb0314dSChris Mason 	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
2313eb0314dSChris Mason 	if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid,
2323eb0314dSChris Mason 		   sizeof(node->header.fsid)))
2333eb0314dSChris Mason 		BUG();
234aa5d6bedSChris Mason 	if (level == 0)
235123abc88SChris Mason 		return check_leaf(root, path, level);
236123abc88SChris Mason 	return check_node(root, path, level);
237aa5d6bedSChris Mason }
238aa5d6bedSChris Mason 
23974123bd7SChris Mason /*
24074123bd7SChris Mason  * search for key in the array p.  items p are item_size apart
24174123bd7SChris Mason  * and there are 'max' items in p
24274123bd7SChris Mason  * the slot in the array is returned via slot, and it points to
24374123bd7SChris Mason  * the place where you would insert key if it is not found in
24474123bd7SChris Mason  * the array.
24574123bd7SChris Mason  *
24674123bd7SChris Mason  * slot may point to max if the key is bigger than all of the keys
24774123bd7SChris Mason  */
2489aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key,
249be0e5c09SChris Mason 		       int max, int *slot)
250be0e5c09SChris Mason {
251be0e5c09SChris Mason 	int low = 0;
252be0e5c09SChris Mason 	int high = max;
253be0e5c09SChris Mason 	int mid;
254be0e5c09SChris Mason 	int ret;
255e2fa7227SChris Mason 	struct btrfs_disk_key *tmp;
256be0e5c09SChris Mason 
257be0e5c09SChris Mason 	while(low < high) {
258be0e5c09SChris Mason 		mid = (low + high) / 2;
259e2fa7227SChris Mason 		tmp = (struct btrfs_disk_key *)(p + mid * item_size);
260be0e5c09SChris Mason 		ret = comp_keys(tmp, key);
261be0e5c09SChris Mason 
262be0e5c09SChris Mason 		if (ret < 0)
263be0e5c09SChris Mason 			low = mid + 1;
264be0e5c09SChris Mason 		else if (ret > 0)
265be0e5c09SChris Mason 			high = mid;
266be0e5c09SChris Mason 		else {
267be0e5c09SChris Mason 			*slot = mid;
268be0e5c09SChris Mason 			return 0;
269be0e5c09SChris Mason 		}
270be0e5c09SChris Mason 	}
271be0e5c09SChris Mason 	*slot = low;
272be0e5c09SChris Mason 	return 1;
273be0e5c09SChris Mason }
274be0e5c09SChris Mason 
27597571fd0SChris Mason /*
27697571fd0SChris Mason  * simple bin_search frontend that does the right thing for
27797571fd0SChris Mason  * leaves vs nodes
27897571fd0SChris Mason  */
2799aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
280be0e5c09SChris Mason {
2817518a238SChris Mason 	if (btrfs_is_leaf(c)) {
282234b63a0SChris Mason 		struct btrfs_leaf *l = (struct btrfs_leaf *)c;
2830783fcfcSChris Mason 		return generic_bin_search((void *)l->items,
2840783fcfcSChris Mason 					  sizeof(struct btrfs_item),
2857518a238SChris Mason 					  key, btrfs_header_nritems(&c->header),
2867518a238SChris Mason 					  slot);
287be0e5c09SChris Mason 	} else {
288123abc88SChris Mason 		return generic_bin_search((void *)c->ptrs,
289123abc88SChris Mason 					  sizeof(struct btrfs_key_ptr),
2907518a238SChris Mason 					  key, btrfs_header_nritems(&c->header),
2917518a238SChris Mason 					  slot);
292be0e5c09SChris Mason 	}
293be0e5c09SChris Mason 	return -1;
294be0e5c09SChris Mason }
295be0e5c09SChris Mason 
296e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root,
297e20d96d6SChris Mason 				   struct buffer_head *parent_buf,
298bb803951SChris Mason 				   int slot)
299bb803951SChris Mason {
300e20d96d6SChris Mason 	struct btrfs_node *node = btrfs_buffer_node(parent_buf);
301bb803951SChris Mason 	if (slot < 0)
302bb803951SChris Mason 		return NULL;
3037518a238SChris Mason 	if (slot >= btrfs_header_nritems(&node->header))
304bb803951SChris Mason 		return NULL;
3051d4f8a0cSChris Mason 	return read_tree_block(root, btrfs_node_blockptr(node, slot));
306bb803951SChris Mason }
307bb803951SChris Mason 
308e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
309e089f05cSChris Mason 			 *root, struct btrfs_path *path, int level)
310bb803951SChris Mason {
311e20d96d6SChris Mason 	struct buffer_head *right_buf;
312e20d96d6SChris Mason 	struct buffer_head *mid_buf;
313e20d96d6SChris Mason 	struct buffer_head *left_buf;
314e20d96d6SChris Mason 	struct buffer_head *parent_buf = NULL;
315234b63a0SChris Mason 	struct btrfs_node *right = NULL;
316234b63a0SChris Mason 	struct btrfs_node *mid;
317234b63a0SChris Mason 	struct btrfs_node *left = NULL;
318234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
319bb803951SChris Mason 	int ret = 0;
320bb803951SChris Mason 	int wret;
321bb803951SChris Mason 	int pslot;
322bb803951SChris Mason 	int orig_slot = path->slots[level];
32379f95c82SChris Mason 	u64 orig_ptr;
324bb803951SChris Mason 
325bb803951SChris Mason 	if (level == 0)
326bb803951SChris Mason 		return 0;
327bb803951SChris Mason 
328bb803951SChris Mason 	mid_buf = path->nodes[level];
329e20d96d6SChris Mason 	mid = btrfs_buffer_node(mid_buf);
3301d4f8a0cSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
33179f95c82SChris Mason 
332234b63a0SChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
333bb803951SChris Mason 		parent_buf = path->nodes[level + 1];
334bb803951SChris Mason 	pslot = path->slots[level + 1];
335bb803951SChris Mason 
33640689478SChris Mason 	/*
33740689478SChris Mason 	 * deal with the case where there is only one pointer in the root
33840689478SChris Mason 	 * by promoting the node below to a root
33940689478SChris Mason 	 */
340bb803951SChris Mason 	if (!parent_buf) {
341e20d96d6SChris Mason 		struct buffer_head *child;
3427eccb903SChris Mason 		u64 blocknr = bh_blocknr(mid_buf);
343bb803951SChris Mason 
3447518a238SChris Mason 		if (btrfs_header_nritems(&mid->header) != 1)
345bb803951SChris Mason 			return 0;
346bb803951SChris Mason 
347bb803951SChris Mason 		/* promote the child to a root */
348bb803951SChris Mason 		child = read_node_slot(root, mid_buf, 0);
349bb803951SChris Mason 		BUG_ON(!child);
350bb803951SChris Mason 		root->node = child;
351bb803951SChris Mason 		path->nodes[level] = NULL;
352d6025579SChris Mason 		clean_tree_block(trans, root, mid_buf);
353d6025579SChris Mason 		wait_on_buffer(mid_buf);
354bb803951SChris Mason 		/* once for the path */
355234b63a0SChris Mason 		btrfs_block_release(root, mid_buf);
356bb803951SChris Mason 		/* once for the root ptr */
357234b63a0SChris Mason 		btrfs_block_release(root, mid_buf);
358e089f05cSChris Mason 		return btrfs_free_extent(trans, root, blocknr, 1, 1);
359bb803951SChris Mason 	}
360e20d96d6SChris Mason 	parent = btrfs_buffer_node(parent_buf);
361bb803951SChris Mason 
362123abc88SChris Mason 	if (btrfs_header_nritems(&mid->header) >
363123abc88SChris Mason 	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
364bb803951SChris Mason 		return 0;
365bb803951SChris Mason 
366bb803951SChris Mason 	left_buf = read_node_slot(root, parent_buf, pslot - 1);
367bb803951SChris Mason 	right_buf = read_node_slot(root, parent_buf, pslot + 1);
36879f95c82SChris Mason 
36979f95c82SChris Mason 	/* first, try to make some room in the middle buffer */
370bb803951SChris Mason 	if (left_buf) {
371e089f05cSChris Mason 		btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1,
372e089f05cSChris Mason 				&left_buf);
373e20d96d6SChris Mason 		left = btrfs_buffer_node(left_buf);
3747518a238SChris Mason 		orig_slot += btrfs_header_nritems(&left->header);
375e089f05cSChris Mason 		wret = push_node_left(trans, root, left_buf, mid_buf);
37679f95c82SChris Mason 		if (wret < 0)
37779f95c82SChris Mason 			ret = wret;
378bb803951SChris Mason 	}
37979f95c82SChris Mason 
38079f95c82SChris Mason 	/*
38179f95c82SChris Mason 	 * then try to empty the right most buffer into the middle
38279f95c82SChris Mason 	 */
383bb803951SChris Mason 	if (right_buf) {
384e089f05cSChris Mason 		btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1,
385e089f05cSChris Mason 				&right_buf);
386e20d96d6SChris Mason 		right = btrfs_buffer_node(right_buf);
387e089f05cSChris Mason 		wret = push_node_left(trans, root, mid_buf, right_buf);
38879f95c82SChris Mason 		if (wret < 0)
38979f95c82SChris Mason 			ret = wret;
3907518a238SChris Mason 		if (btrfs_header_nritems(&right->header) == 0) {
3917eccb903SChris Mason 			u64 blocknr = bh_blocknr(right_buf);
392e089f05cSChris Mason 			clean_tree_block(trans, root, right_buf);
393d6025579SChris Mason 			wait_on_buffer(right_buf);
394d6025579SChris Mason 			btrfs_block_release(root, right_buf);
395bb803951SChris Mason 			right_buf = NULL;
396bb803951SChris Mason 			right = NULL;
397e089f05cSChris Mason 			wret = del_ptr(trans, root, path, level + 1, pslot +
398e089f05cSChris Mason 				       1);
399bb803951SChris Mason 			if (wret)
400bb803951SChris Mason 				ret = wret;
401e089f05cSChris Mason 			wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
402bb803951SChris Mason 			if (wret)
403bb803951SChris Mason 				ret = wret;
404bb803951SChris Mason 		} else {
405d6025579SChris Mason 			btrfs_memcpy(root, parent,
406d6025579SChris Mason 				     &parent->ptrs[pslot + 1].key,
407123abc88SChris Mason 				     &right->ptrs[0].key,
408e2fa7227SChris Mason 				     sizeof(struct btrfs_disk_key));
409d6025579SChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
410bb803951SChris Mason 		}
411bb803951SChris Mason 	}
4127518a238SChris Mason 	if (btrfs_header_nritems(&mid->header) == 1) {
41379f95c82SChris Mason 		/*
41479f95c82SChris Mason 		 * we're not allowed to leave a node with one item in the
41579f95c82SChris Mason 		 * tree during a delete.  A deletion from lower in the tree
41679f95c82SChris Mason 		 * could try to delete the only pointer in this node.
41779f95c82SChris Mason 		 * So, pull some keys from the left.
41879f95c82SChris Mason 		 * There has to be a left pointer at this point because
41979f95c82SChris Mason 		 * otherwise we would have pulled some pointers from the
42079f95c82SChris Mason 		 * right
42179f95c82SChris Mason 		 */
42279f95c82SChris Mason 		BUG_ON(!left_buf);
423e089f05cSChris Mason 		wret = balance_node_right(trans, root, mid_buf, left_buf);
42479f95c82SChris Mason 		if (wret < 0)
42579f95c82SChris Mason 			ret = wret;
42679f95c82SChris Mason 		BUG_ON(wret == 1);
42779f95c82SChris Mason 	}
4287518a238SChris Mason 	if (btrfs_header_nritems(&mid->header) == 0) {
42979f95c82SChris Mason 		/* we've managed to empty the middle node, drop it */
4307eccb903SChris Mason 		u64 blocknr = bh_blocknr(mid_buf);
431e089f05cSChris Mason 		clean_tree_block(trans, root, mid_buf);
432d6025579SChris Mason 		wait_on_buffer(mid_buf);
433d6025579SChris Mason 		btrfs_block_release(root, mid_buf);
434bb803951SChris Mason 		mid_buf = NULL;
435bb803951SChris Mason 		mid = NULL;
436e089f05cSChris Mason 		wret = del_ptr(trans, root, path, level + 1, pslot);
437bb803951SChris Mason 		if (wret)
438bb803951SChris Mason 			ret = wret;
439e089f05cSChris Mason 		wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
440bb803951SChris Mason 		if (wret)
441bb803951SChris Mason 			ret = wret;
44279f95c82SChris Mason 	} else {
44379f95c82SChris Mason 		/* update the parent key to reflect our changes */
444d6025579SChris Mason 		btrfs_memcpy(root, parent,
445d6025579SChris Mason 			     &parent->ptrs[pslot].key, &mid->ptrs[0].key,
446e2fa7227SChris Mason 			     sizeof(struct btrfs_disk_key));
447d6025579SChris Mason 		btrfs_mark_buffer_dirty(parent_buf);
44879f95c82SChris Mason 	}
449bb803951SChris Mason 
45079f95c82SChris Mason 	/* update the path */
451bb803951SChris Mason 	if (left_buf) {
4527518a238SChris Mason 		if (btrfs_header_nritems(&left->header) > orig_slot) {
453e20d96d6SChris Mason 			get_bh(left_buf);
454bb803951SChris Mason 			path->nodes[level] = left_buf;
455bb803951SChris Mason 			path->slots[level + 1] -= 1;
456bb803951SChris Mason 			path->slots[level] = orig_slot;
457bb803951SChris Mason 			if (mid_buf)
458234b63a0SChris Mason 				btrfs_block_release(root, mid_buf);
459bb803951SChris Mason 		} else {
4607518a238SChris Mason 			orig_slot -= btrfs_header_nritems(&left->header);
461bb803951SChris Mason 			path->slots[level] = orig_slot;
462bb803951SChris Mason 		}
463bb803951SChris Mason 	}
46479f95c82SChris Mason 	/* double check we haven't messed things up */
465123abc88SChris Mason 	check_block(root, path, level);
466e20d96d6SChris Mason 	if (orig_ptr !=
467e20d96d6SChris Mason 	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
4681d4f8a0cSChris Mason 				path->slots[level]))
46979f95c82SChris Mason 		BUG();
470bb803951SChris Mason 
471bb803951SChris Mason 	if (right_buf)
472234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
473bb803951SChris Mason 	if (left_buf)
474234b63a0SChris Mason 		btrfs_block_release(root, left_buf);
475bb803951SChris Mason 	return ret;
476bb803951SChris Mason }
477bb803951SChris Mason 
478e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */
479e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
480e66f709bSChris Mason 				struct btrfs_root *root,
481e66f709bSChris Mason 				struct btrfs_path *path, int level)
482e66f709bSChris Mason {
483e66f709bSChris Mason 	struct buffer_head *right_buf;
484e66f709bSChris Mason 	struct buffer_head *mid_buf;
485e66f709bSChris Mason 	struct buffer_head *left_buf;
486e66f709bSChris Mason 	struct buffer_head *parent_buf = NULL;
487e66f709bSChris Mason 	struct btrfs_node *right = NULL;
488e66f709bSChris Mason 	struct btrfs_node *mid;
489e66f709bSChris Mason 	struct btrfs_node *left = NULL;
490e66f709bSChris Mason 	struct btrfs_node *parent = NULL;
491e66f709bSChris Mason 	int ret = 0;
492e66f709bSChris Mason 	int wret;
493e66f709bSChris Mason 	int pslot;
494e66f709bSChris Mason 	int orig_slot = path->slots[level];
495e66f709bSChris Mason 	u64 orig_ptr;
496e66f709bSChris Mason 
497e66f709bSChris Mason 	if (level == 0)
498e66f709bSChris Mason 		return 1;
499e66f709bSChris Mason 
500e66f709bSChris Mason 	mid_buf = path->nodes[level];
501e66f709bSChris Mason 	mid = btrfs_buffer_node(mid_buf);
502e66f709bSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
503e66f709bSChris Mason 
504e66f709bSChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
505e66f709bSChris Mason 		parent_buf = path->nodes[level + 1];
506e66f709bSChris Mason 	pslot = path->slots[level + 1];
507e66f709bSChris Mason 
508e66f709bSChris Mason 	if (!parent_buf)
509e66f709bSChris Mason 		return 1;
510e66f709bSChris Mason 	parent = btrfs_buffer_node(parent_buf);
511e66f709bSChris Mason 
512e66f709bSChris Mason 	left_buf = read_node_slot(root, parent_buf, pslot - 1);
513e66f709bSChris Mason 
514e66f709bSChris Mason 	/* first, try to make some room in the middle buffer */
515e66f709bSChris Mason 	if (left_buf) {
516e66f709bSChris Mason 		u32 left_nr;
517e66f709bSChris Mason 		left = btrfs_buffer_node(left_buf);
518e66f709bSChris Mason 		left_nr = btrfs_header_nritems(&left->header);
51933ade1f8SChris Mason 		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
52033ade1f8SChris Mason 			wret = 1;
52133ade1f8SChris Mason 		} else {
52233ade1f8SChris Mason 			btrfs_cow_block(trans, root, left_buf, parent_buf,
52333ade1f8SChris Mason 					pslot - 1, &left_buf);
52433ade1f8SChris Mason 			left = btrfs_buffer_node(left_buf);
525e66f709bSChris Mason 			wret = push_node_left(trans, root, left_buf, mid_buf);
52633ade1f8SChris Mason 		}
527e66f709bSChris Mason 		if (wret < 0)
528e66f709bSChris Mason 			ret = wret;
529e66f709bSChris Mason 		if (wret == 0) {
530e66f709bSChris Mason 			orig_slot += left_nr;
531e66f709bSChris Mason 			btrfs_memcpy(root, parent,
532e66f709bSChris Mason 				     &parent->ptrs[pslot].key,
533e66f709bSChris Mason 				     &mid->ptrs[0].key,
534e66f709bSChris Mason 				     sizeof(struct btrfs_disk_key));
535e66f709bSChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
536e66f709bSChris Mason 			if (btrfs_header_nritems(&left->header) > orig_slot) {
537e66f709bSChris Mason 				path->nodes[level] = left_buf;
538e66f709bSChris Mason 				path->slots[level + 1] -= 1;
539e66f709bSChris Mason 				path->slots[level] = orig_slot;
540e66f709bSChris Mason 				btrfs_block_release(root, mid_buf);
541e66f709bSChris Mason 			} else {
542e66f709bSChris Mason 				orig_slot -=
543e66f709bSChris Mason 					btrfs_header_nritems(&left->header);
544e66f709bSChris Mason 				path->slots[level] = orig_slot;
545e66f709bSChris Mason 				btrfs_block_release(root, left_buf);
546e66f709bSChris Mason 			}
547e66f709bSChris Mason 			check_node(root, path, level);
548e66f709bSChris Mason 			return 0;
549e66f709bSChris Mason 		}
550e66f709bSChris Mason 		btrfs_block_release(root, left_buf);
551e66f709bSChris Mason 	}
552e66f709bSChris Mason 	right_buf = read_node_slot(root, parent_buf, pslot + 1);
553e66f709bSChris Mason 
554e66f709bSChris Mason 	/*
555e66f709bSChris Mason 	 * then try to empty the right most buffer into the middle
556e66f709bSChris Mason 	 */
557e66f709bSChris Mason 	if (right_buf) {
55833ade1f8SChris Mason 		u32 right_nr;
559e66f709bSChris Mason 		right = btrfs_buffer_node(right_buf);
56033ade1f8SChris Mason 		right_nr = btrfs_header_nritems(&right->header);
56133ade1f8SChris Mason 		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
56233ade1f8SChris Mason 			wret = 1;
56333ade1f8SChris Mason 		} else {
56433ade1f8SChris Mason 			btrfs_cow_block(trans, root, right_buf,
56533ade1f8SChris Mason 					parent_buf, pslot + 1, &right_buf);
56633ade1f8SChris Mason 			right = btrfs_buffer_node(right_buf);
56733ade1f8SChris Mason 			wret = balance_node_right(trans, root,
56833ade1f8SChris Mason 						  right_buf, mid_buf);
56933ade1f8SChris Mason 		}
570e66f709bSChris Mason 		if (wret < 0)
571e66f709bSChris Mason 			ret = wret;
572e66f709bSChris Mason 		if (wret == 0) {
573e66f709bSChris Mason 			btrfs_memcpy(root, parent,
574e66f709bSChris Mason 				     &parent->ptrs[pslot + 1].key,
575e66f709bSChris Mason 				     &right->ptrs[0].key,
576e66f709bSChris Mason 				     sizeof(struct btrfs_disk_key));
577e66f709bSChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
578e66f709bSChris Mason 			if (btrfs_header_nritems(&mid->header) <= orig_slot) {
579e66f709bSChris Mason 				path->nodes[level] = right_buf;
580e66f709bSChris Mason 				path->slots[level + 1] += 1;
581e66f709bSChris Mason 				path->slots[level] = orig_slot -
582e66f709bSChris Mason 					btrfs_header_nritems(&mid->header);
583e66f709bSChris Mason 				btrfs_block_release(root, mid_buf);
584e66f709bSChris Mason 			} else {
585e66f709bSChris Mason 				btrfs_block_release(root, right_buf);
586e66f709bSChris Mason 			}
587e66f709bSChris Mason 			check_node(root, path, level);
588e66f709bSChris Mason 			return 0;
589e66f709bSChris Mason 		}
590e66f709bSChris Mason 		btrfs_block_release(root, right_buf);
591e66f709bSChris Mason 	}
592e66f709bSChris Mason 	check_node(root, path, level);
593e66f709bSChris Mason 	return 1;
594e66f709bSChris Mason }
595e66f709bSChris Mason 
59674123bd7SChris Mason /*
59774123bd7SChris Mason  * look for key in the tree.  path is filled in with nodes along the way
59874123bd7SChris Mason  * if key is found, we return zero and you can find the item in the leaf
59974123bd7SChris Mason  * level of the path (level 0)
60074123bd7SChris Mason  *
60174123bd7SChris Mason  * If the key isn't found, the path points to the slot where it should
602aa5d6bedSChris Mason  * be inserted, and 1 is returned.  If there are other errors during the
603aa5d6bedSChris Mason  * search a negative error number is returned.
60497571fd0SChris Mason  *
60597571fd0SChris Mason  * if ins_len > 0, nodes and leaves will be split as we walk down the
60697571fd0SChris Mason  * tree.  if ins_len < 0, nodes will be merged as we walk down the tree (if
60797571fd0SChris Mason  * possible)
60874123bd7SChris Mason  */
609e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
610e089f05cSChris Mason 		      *root, struct btrfs_key *key, struct btrfs_path *p, int
611e089f05cSChris Mason 		      ins_len, int cow)
612be0e5c09SChris Mason {
613e20d96d6SChris Mason 	struct buffer_head *b;
614e20d96d6SChris Mason 	struct buffer_head *cow_buf;
615234b63a0SChris Mason 	struct btrfs_node *c;
616be0e5c09SChris Mason 	int slot;
617be0e5c09SChris Mason 	int ret;
618be0e5c09SChris Mason 	int level;
6195c680ed6SChris Mason 
62022b0ebdaSChris Mason 	WARN_ON(p->nodes[0] != NULL);
62122b0ebdaSChris Mason 	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
622bb803951SChris Mason again:
623bb803951SChris Mason 	b = root->node;
624e20d96d6SChris Mason 	get_bh(b);
625eb60ceacSChris Mason 	while (b) {
626e20d96d6SChris Mason 		c = btrfs_buffer_node(b);
627e20d96d6SChris Mason 		level = btrfs_header_level(&c->header);
62802217ed2SChris Mason 		if (cow) {
62902217ed2SChris Mason 			int wret;
630e20d96d6SChris Mason 			wret = btrfs_cow_block(trans, root, b,
631e20d96d6SChris Mason 					       p->nodes[level + 1],
632e20d96d6SChris Mason 					       p->slots[level + 1],
633e089f05cSChris Mason 					       &cow_buf);
63402217ed2SChris Mason 			b = cow_buf;
6352c90e5d6SChris Mason 			c = btrfs_buffer_node(b);
63602217ed2SChris Mason 		}
63702217ed2SChris Mason 		BUG_ON(!cow && ins_len);
6382c90e5d6SChris Mason 		if (level != btrfs_header_level(&c->header))
6392c90e5d6SChris Mason 			WARN_ON(1);
6402c90e5d6SChris Mason 		level = btrfs_header_level(&c->header);
641eb60ceacSChris Mason 		p->nodes[level] = b;
642123abc88SChris Mason 		ret = check_block(root, p, level);
643aa5d6bedSChris Mason 		if (ret)
644aa5d6bedSChris Mason 			return -1;
645be0e5c09SChris Mason 		ret = bin_search(c, key, &slot);
6467518a238SChris Mason 		if (!btrfs_is_leaf(c)) {
647be0e5c09SChris Mason 			if (ret && slot > 0)
648be0e5c09SChris Mason 				slot -= 1;
649be0e5c09SChris Mason 			p->slots[level] = slot;
650d4dbff95SChris Mason 			if (ins_len > 0 && btrfs_header_nritems(&c->header) >=
651d4dbff95SChris Mason 			    BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
652e089f05cSChris Mason 				int sret = split_node(trans, root, p, level);
6535c680ed6SChris Mason 				BUG_ON(sret > 0);
6545c680ed6SChris Mason 				if (sret)
6555c680ed6SChris Mason 					return sret;
6565c680ed6SChris Mason 				b = p->nodes[level];
657e20d96d6SChris Mason 				c = btrfs_buffer_node(b);
6585c680ed6SChris Mason 				slot = p->slots[level];
659bb803951SChris Mason 			} else if (ins_len < 0) {
660e089f05cSChris Mason 				int sret = balance_level(trans, root, p,
661e089f05cSChris Mason 							 level);
662bb803951SChris Mason 				if (sret)
663bb803951SChris Mason 					return sret;
664bb803951SChris Mason 				b = p->nodes[level];
665bb803951SChris Mason 				if (!b)
666bb803951SChris Mason 					goto again;
667e20d96d6SChris Mason 				c = btrfs_buffer_node(b);
668bb803951SChris Mason 				slot = p->slots[level];
6697518a238SChris Mason 				BUG_ON(btrfs_header_nritems(&c->header) == 1);
6705c680ed6SChris Mason 			}
6711d4f8a0cSChris Mason 			b = read_tree_block(root, btrfs_node_blockptr(c, slot));
672be0e5c09SChris Mason 		} else {
673234b63a0SChris Mason 			struct btrfs_leaf *l = (struct btrfs_leaf *)c;
674be0e5c09SChris Mason 			p->slots[level] = slot;
675123abc88SChris Mason 			if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
6760783fcfcSChris Mason 			    sizeof(struct btrfs_item) + ins_len) {
677d4dbff95SChris Mason 				int sret = split_leaf(trans, root, key,
678d4dbff95SChris Mason 						      p, ins_len);
6795c680ed6SChris Mason 				BUG_ON(sret > 0);
6805c680ed6SChris Mason 				if (sret)
6815c680ed6SChris Mason 					return sret;
6825c680ed6SChris Mason 			}
683be0e5c09SChris Mason 			return ret;
684be0e5c09SChris Mason 		}
685be0e5c09SChris Mason 	}
686aa5d6bedSChris Mason 	return 1;
687be0e5c09SChris Mason }
688be0e5c09SChris Mason 
68974123bd7SChris Mason /*
69074123bd7SChris Mason  * adjust the pointers going up the tree, starting at level
69174123bd7SChris Mason  * making sure the right key of each node is points to 'key'.
69274123bd7SChris Mason  * This is used after shifting pointers to the left, so it stops
69374123bd7SChris Mason  * fixing up pointers when a given leaf/node is not in slot 0 of the
69474123bd7SChris Mason  * higher levels
695aa5d6bedSChris Mason  *
696aa5d6bedSChris Mason  * If this fails to write a tree block, it returns -1, but continues
697aa5d6bedSChris Mason  * fixing up the blocks in ram so the tree is consistent.
69874123bd7SChris Mason  */
699e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
700e089f05cSChris Mason 			  *root, struct btrfs_path *path, struct btrfs_disk_key
701e089f05cSChris Mason 			  *key, int level)
702be0e5c09SChris Mason {
703be0e5c09SChris Mason 	int i;
704aa5d6bedSChris Mason 	int ret = 0;
705234b63a0SChris Mason 	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
706234b63a0SChris Mason 		struct btrfs_node *t;
707be0e5c09SChris Mason 		int tslot = path->slots[i];
708eb60ceacSChris Mason 		if (!path->nodes[i])
709be0e5c09SChris Mason 			break;
710e20d96d6SChris Mason 		t = btrfs_buffer_node(path->nodes[i]);
711d6025579SChris Mason 		btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key));
712d6025579SChris Mason 		btrfs_mark_buffer_dirty(path->nodes[i]);
713be0e5c09SChris Mason 		if (tslot != 0)
714be0e5c09SChris Mason 			break;
715be0e5c09SChris Mason 	}
716aa5d6bedSChris Mason 	return ret;
717be0e5c09SChris Mason }
718be0e5c09SChris Mason 
71974123bd7SChris Mason /*
72074123bd7SChris Mason  * try to push data from one node into the next node left in the
72179f95c82SChris Mason  * tree.
722aa5d6bedSChris Mason  *
723aa5d6bedSChris Mason  * returns 0 if some ptrs were pushed left, < 0 if there was some horrible
724aa5d6bedSChris Mason  * error, and > 0 if there was no room in the left hand block.
72574123bd7SChris Mason  */
726e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
727e20d96d6SChris Mason 			  *root, struct buffer_head *dst_buf, struct
728e20d96d6SChris Mason 			  buffer_head *src_buf)
729be0e5c09SChris Mason {
730e20d96d6SChris Mason 	struct btrfs_node *src = btrfs_buffer_node(src_buf);
731e20d96d6SChris Mason 	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
732be0e5c09SChris Mason 	int push_items = 0;
733bb803951SChris Mason 	int src_nritems;
734bb803951SChris Mason 	int dst_nritems;
735aa5d6bedSChris Mason 	int ret = 0;
736be0e5c09SChris Mason 
7377518a238SChris Mason 	src_nritems = btrfs_header_nritems(&src->header);
7387518a238SChris Mason 	dst_nritems = btrfs_header_nritems(&dst->header);
739123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
740eb60ceacSChris Mason 	if (push_items <= 0) {
741be0e5c09SChris Mason 		return 1;
742eb60ceacSChris Mason 	}
743be0e5c09SChris Mason 
744be0e5c09SChris Mason 	if (src_nritems < push_items)
745be0e5c09SChris Mason 		push_items = src_nritems;
74679f95c82SChris Mason 
747d6025579SChris Mason 	btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs,
748123abc88SChris Mason 		     push_items * sizeof(struct btrfs_key_ptr));
749bb803951SChris Mason 	if (push_items < src_nritems) {
750d6025579SChris Mason 		btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items,
751e2fa7227SChris Mason 			(src_nritems - push_items) *
752123abc88SChris Mason 			sizeof(struct btrfs_key_ptr));
753bb803951SChris Mason 	}
7547518a238SChris Mason 	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
7557518a238SChris Mason 	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
756d6025579SChris Mason 	btrfs_mark_buffer_dirty(src_buf);
757d6025579SChris Mason 	btrfs_mark_buffer_dirty(dst_buf);
758bb803951SChris Mason 	return ret;
759be0e5c09SChris Mason }
760be0e5c09SChris Mason 
76197571fd0SChris Mason /*
76279f95c82SChris Mason  * try to push data from one node into the next node right in the
76379f95c82SChris Mason  * tree.
76479f95c82SChris Mason  *
76579f95c82SChris Mason  * returns 0 if some ptrs were pushed, < 0 if there was some horrible
76679f95c82SChris Mason  * error, and > 0 if there was no room in the right hand block.
76779f95c82SChris Mason  *
76879f95c82SChris Mason  * this will  only push up to 1/2 the contents of the left node over
76979f95c82SChris Mason  */
770e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct
771e20d96d6SChris Mason 			      btrfs_root *root, struct buffer_head *dst_buf,
772e20d96d6SChris Mason 			      struct buffer_head *src_buf)
77379f95c82SChris Mason {
774e20d96d6SChris Mason 	struct btrfs_node *src = btrfs_buffer_node(src_buf);
775e20d96d6SChris Mason 	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
77679f95c82SChris Mason 	int push_items = 0;
77779f95c82SChris Mason 	int max_push;
77879f95c82SChris Mason 	int src_nritems;
77979f95c82SChris Mason 	int dst_nritems;
78079f95c82SChris Mason 	int ret = 0;
78179f95c82SChris Mason 
7827518a238SChris Mason 	src_nritems = btrfs_header_nritems(&src->header);
7837518a238SChris Mason 	dst_nritems = btrfs_header_nritems(&dst->header);
784123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
78579f95c82SChris Mason 	if (push_items <= 0) {
78679f95c82SChris Mason 		return 1;
78779f95c82SChris Mason 	}
78879f95c82SChris Mason 
78979f95c82SChris Mason 	max_push = src_nritems / 2 + 1;
79079f95c82SChris Mason 	/* don't try to empty the node */
79179f95c82SChris Mason 	if (max_push > src_nritems)
79279f95c82SChris Mason 		return 1;
79379f95c82SChris Mason 	if (max_push < push_items)
79479f95c82SChris Mason 		push_items = max_push;
79579f95c82SChris Mason 
796d6025579SChris Mason 	btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs,
797123abc88SChris Mason 		      dst_nritems * sizeof(struct btrfs_key_ptr));
798d6025579SChris Mason 
799d6025579SChris Mason 	btrfs_memcpy(root, dst, dst->ptrs,
800d6025579SChris Mason 		     src->ptrs + src_nritems - push_items,
801123abc88SChris Mason 		     push_items * sizeof(struct btrfs_key_ptr));
80279f95c82SChris Mason 
8037518a238SChris Mason 	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
8047518a238SChris Mason 	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
80579f95c82SChris Mason 
806d6025579SChris Mason 	btrfs_mark_buffer_dirty(src_buf);
807d6025579SChris Mason 	btrfs_mark_buffer_dirty(dst_buf);
80879f95c82SChris Mason 	return ret;
80979f95c82SChris Mason }
81079f95c82SChris Mason 
81179f95c82SChris Mason /*
81297571fd0SChris Mason  * helper function to insert a new root level in the tree.
81397571fd0SChris Mason  * A new node is allocated, and a single item is inserted to
81497571fd0SChris Mason  * point to the existing root
815aa5d6bedSChris Mason  *
816aa5d6bedSChris Mason  * returns zero on success or < 0 on failure.
81797571fd0SChris Mason  */
818e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
819e089f05cSChris Mason 			   *root, struct btrfs_path *path, int level)
82074123bd7SChris Mason {
821e20d96d6SChris Mason 	struct buffer_head *t;
822234b63a0SChris Mason 	struct btrfs_node *lower;
823234b63a0SChris Mason 	struct btrfs_node *c;
824e2fa7227SChris Mason 	struct btrfs_disk_key *lower_key;
8255c680ed6SChris Mason 
8265c680ed6SChris Mason 	BUG_ON(path->nodes[level]);
8275c680ed6SChris Mason 	BUG_ON(path->nodes[level-1] != root->node);
8285c680ed6SChris Mason 
82931f3c99bSChris Mason 	t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr);
830e20d96d6SChris Mason 	c = btrfs_buffer_node(t);
831123abc88SChris Mason 	memset(c, 0, root->blocksize);
8327518a238SChris Mason 	btrfs_set_header_nritems(&c->header, 1);
8337518a238SChris Mason 	btrfs_set_header_level(&c->header, level);
8347eccb903SChris Mason 	btrfs_set_header_blocknr(&c->header, bh_blocknr(t));
8357f5c1516SChris Mason 	btrfs_set_header_generation(&c->header, trans->transid);
8364d775673SChris Mason 	btrfs_set_header_owner(&c->header, root->root_key.objectid);
837e20d96d6SChris Mason 	lower = btrfs_buffer_node(path->nodes[level-1]);
8383eb0314dSChris Mason 	memcpy(c->header.fsid, root->fs_info->disk_super->fsid,
8393eb0314dSChris Mason 	       sizeof(c->header.fsid));
8407518a238SChris Mason 	if (btrfs_is_leaf(lower))
841234b63a0SChris Mason 		lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
84274123bd7SChris Mason 	else
843123abc88SChris Mason 		lower_key = &lower->ptrs[0].key;
844d6025579SChris Mason 	btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key,
845d6025579SChris Mason 		     sizeof(struct btrfs_disk_key));
8467eccb903SChris Mason 	btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1]));
847d5719762SChris Mason 
848d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
849d5719762SChris Mason 
850cfaa7295SChris Mason 	/* the super has an extra ref to root->node */
851234b63a0SChris Mason 	btrfs_block_release(root, root->node);
85274123bd7SChris Mason 	root->node = t;
853e20d96d6SChris Mason 	get_bh(t);
85474123bd7SChris Mason 	path->nodes[level] = t;
85574123bd7SChris Mason 	path->slots[level] = 0;
85674123bd7SChris Mason 	return 0;
85774123bd7SChris Mason }
8585c680ed6SChris Mason 
8595c680ed6SChris Mason /*
8605c680ed6SChris Mason  * worker function to insert a single pointer in a node.
8615c680ed6SChris Mason  * the node should have enough room for the pointer already
86297571fd0SChris Mason  *
8635c680ed6SChris Mason  * slot and level indicate where you want the key to go, and
8645c680ed6SChris Mason  * blocknr is the block the key points to.
865aa5d6bedSChris Mason  *
866aa5d6bedSChris Mason  * returns zero on success and < 0 on any error
8675c680ed6SChris Mason  */
868e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
869e089f05cSChris Mason 		      *root, struct btrfs_path *path, struct btrfs_disk_key
870e089f05cSChris Mason 		      *key, u64 blocknr, int slot, int level)
8715c680ed6SChris Mason {
872234b63a0SChris Mason 	struct btrfs_node *lower;
8735c680ed6SChris Mason 	int nritems;
8745c680ed6SChris Mason 
8755c680ed6SChris Mason 	BUG_ON(!path->nodes[level]);
876e20d96d6SChris Mason 	lower = btrfs_buffer_node(path->nodes[level]);
8777518a238SChris Mason 	nritems = btrfs_header_nritems(&lower->header);
87874123bd7SChris Mason 	if (slot > nritems)
87974123bd7SChris Mason 		BUG();
880123abc88SChris Mason 	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
88174123bd7SChris Mason 		BUG();
88274123bd7SChris Mason 	if (slot != nritems) {
883d6025579SChris Mason 		btrfs_memmove(root, lower, lower->ptrs + slot + 1,
884d6025579SChris Mason 			      lower->ptrs + slot,
885123abc88SChris Mason 			      (nritems - slot) * sizeof(struct btrfs_key_ptr));
88674123bd7SChris Mason 	}
887d6025579SChris Mason 	btrfs_memcpy(root, lower, &lower->ptrs[slot].key,
888d6025579SChris Mason 		     key, sizeof(struct btrfs_disk_key));
8891d4f8a0cSChris Mason 	btrfs_set_node_blockptr(lower, slot, blocknr);
8907518a238SChris Mason 	btrfs_set_header_nritems(&lower->header, nritems + 1);
891d6025579SChris Mason 	btrfs_mark_buffer_dirty(path->nodes[level]);
892098f59c2SChris Mason 	check_node(root, path, level);
89374123bd7SChris Mason 	return 0;
89474123bd7SChris Mason }
89574123bd7SChris Mason 
89697571fd0SChris Mason /*
89797571fd0SChris Mason  * split the node at the specified level in path in two.
89897571fd0SChris Mason  * The path is corrected to point to the appropriate node after the split
89997571fd0SChris Mason  *
90097571fd0SChris Mason  * Before splitting this tries to make some room in the node by pushing
90197571fd0SChris Mason  * left and right, if either one works, it returns right away.
902aa5d6bedSChris Mason  *
903aa5d6bedSChris Mason  * returns 0 on success and < 0 on failure
90497571fd0SChris Mason  */
905e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
906e089f05cSChris Mason 		      *root, struct btrfs_path *path, int level)
907be0e5c09SChris Mason {
908e20d96d6SChris Mason 	struct buffer_head *t;
909234b63a0SChris Mason 	struct btrfs_node *c;
910e20d96d6SChris Mason 	struct buffer_head *split_buffer;
911234b63a0SChris Mason 	struct btrfs_node *split;
912be0e5c09SChris Mason 	int mid;
9135c680ed6SChris Mason 	int ret;
914aa5d6bedSChris Mason 	int wret;
9157518a238SChris Mason 	u32 c_nritems;
916be0e5c09SChris Mason 
9175c680ed6SChris Mason 	t = path->nodes[level];
918e20d96d6SChris Mason 	c = btrfs_buffer_node(t);
9195c680ed6SChris Mason 	if (t == root->node) {
9205c680ed6SChris Mason 		/* trying to split the root, lets make a new one */
921e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, level + 1);
9225c680ed6SChris Mason 		if (ret)
9235c680ed6SChris Mason 			return ret;
924e66f709bSChris Mason 	} else {
925e66f709bSChris Mason 		ret = push_nodes_for_insert(trans, root, path, level);
926e66f709bSChris Mason 		t = path->nodes[level];
927e66f709bSChris Mason 		c = btrfs_buffer_node(t);
928e66f709bSChris Mason 		if (!ret &&
929e66f709bSChris Mason 		    btrfs_header_nritems(&c->header) <
930e66f709bSChris Mason 		    BTRFS_NODEPTRS_PER_BLOCK(root) - 1)
931e66f709bSChris Mason 			return 0;
9325c680ed6SChris Mason 	}
933e66f709bSChris Mason 
9347518a238SChris Mason 	c_nritems = btrfs_header_nritems(&c->header);
93531f3c99bSChris Mason 	split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr);
936e20d96d6SChris Mason 	split = btrfs_buffer_node(split_buffer);
9377518a238SChris Mason 	btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
9389a6f11edSChris Mason 	btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
9397eccb903SChris Mason 	btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer));
9407f5c1516SChris Mason 	btrfs_set_header_generation(&split->header, trans->transid);
9414d775673SChris Mason 	btrfs_set_header_owner(&split->header, root->root_key.objectid);
9423eb0314dSChris Mason 	memcpy(split->header.fsid, root->fs_info->disk_super->fsid,
9433eb0314dSChris Mason 	       sizeof(split->header.fsid));
9447518a238SChris Mason 	mid = (c_nritems + 1) / 2;
945d6025579SChris Mason 	btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid,
946123abc88SChris Mason 		     (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
9477518a238SChris Mason 	btrfs_set_header_nritems(&split->header, c_nritems - mid);
9487518a238SChris Mason 	btrfs_set_header_nritems(&c->header, mid);
949aa5d6bedSChris Mason 	ret = 0;
950aa5d6bedSChris Mason 
951d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
952d6025579SChris Mason 	btrfs_mark_buffer_dirty(split_buffer);
953e089f05cSChris Mason 	wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
9547eccb903SChris Mason 			  bh_blocknr(split_buffer), path->slots[level + 1] + 1,
955123abc88SChris Mason 			  level + 1);
956aa5d6bedSChris Mason 	if (wret)
957aa5d6bedSChris Mason 		ret = wret;
958aa5d6bedSChris Mason 
9595de08d7dSChris Mason 	if (path->slots[level] >= mid) {
9605c680ed6SChris Mason 		path->slots[level] -= mid;
961234b63a0SChris Mason 		btrfs_block_release(root, t);
9625c680ed6SChris Mason 		path->nodes[level] = split_buffer;
9635c680ed6SChris Mason 		path->slots[level + 1] += 1;
964eb60ceacSChris Mason 	} else {
965234b63a0SChris Mason 		btrfs_block_release(root, split_buffer);
966be0e5c09SChris Mason 	}
967aa5d6bedSChris Mason 	return ret;
968be0e5c09SChris Mason }
969be0e5c09SChris Mason 
97074123bd7SChris Mason /*
97174123bd7SChris Mason  * how many bytes are required to store the items in a leaf.  start
97274123bd7SChris Mason  * and nr indicate which items in the leaf to check.  This totals up the
97374123bd7SChris Mason  * space used both by the item structs and the item data
97474123bd7SChris Mason  */
975234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
976be0e5c09SChris Mason {
977be0e5c09SChris Mason 	int data_len;
978d4dbff95SChris Mason 	int nritems = btrfs_header_nritems(&l->header);
979d4dbff95SChris Mason 	int end = min(nritems, start + nr) - 1;
980be0e5c09SChris Mason 
981be0e5c09SChris Mason 	if (!nr)
982be0e5c09SChris Mason 		return 0;
9830783fcfcSChris Mason 	data_len = btrfs_item_end(l->items + start);
9840783fcfcSChris Mason 	data_len = data_len - btrfs_item_offset(l->items + end);
9850783fcfcSChris Mason 	data_len += sizeof(struct btrfs_item) * nr;
986d4dbff95SChris Mason 	WARN_ON(data_len < 0);
987be0e5c09SChris Mason 	return data_len;
988be0e5c09SChris Mason }
989be0e5c09SChris Mason 
99074123bd7SChris Mason /*
991d4dbff95SChris Mason  * The space between the end of the leaf items and
992d4dbff95SChris Mason  * the start of the leaf data.  IOW, how much room
993d4dbff95SChris Mason  * the leaf has left for both items and data
994d4dbff95SChris Mason  */
995d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf)
996d4dbff95SChris Mason {
997d4dbff95SChris Mason 	int nritems = btrfs_header_nritems(&leaf->header);
998d4dbff95SChris Mason 	return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems);
999d4dbff95SChris Mason }
1000d4dbff95SChris Mason 
1001d4dbff95SChris Mason /*
100200ec4c51SChris Mason  * push some data in the path leaf to the right, trying to free up at
100300ec4c51SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
1004aa5d6bedSChris Mason  *
1005aa5d6bedSChris Mason  * returns 1 if the push failed because the other node didn't have enough
1006aa5d6bedSChris Mason  * room, 0 if everything worked out and < 0 if there were major errors.
100700ec4c51SChris Mason  */
1008e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
1009e089f05cSChris Mason 			   *root, struct btrfs_path *path, int data_size)
101000ec4c51SChris Mason {
1011e20d96d6SChris Mason 	struct buffer_head *left_buf = path->nodes[0];
1012e20d96d6SChris Mason 	struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf);
1013234b63a0SChris Mason 	struct btrfs_leaf *right;
1014e20d96d6SChris Mason 	struct buffer_head *right_buf;
1015e20d96d6SChris Mason 	struct buffer_head *upper;
1016e20d96d6SChris Mason 	struct btrfs_node *upper_node;
101700ec4c51SChris Mason 	int slot;
101800ec4c51SChris Mason 	int i;
101900ec4c51SChris Mason 	int free_space;
102000ec4c51SChris Mason 	int push_space = 0;
102100ec4c51SChris Mason 	int push_items = 0;
10220783fcfcSChris Mason 	struct btrfs_item *item;
10237518a238SChris Mason 	u32 left_nritems;
10247518a238SChris Mason 	u32 right_nritems;
102500ec4c51SChris Mason 
102600ec4c51SChris Mason 	slot = path->slots[1];
102700ec4c51SChris Mason 	if (!path->nodes[1]) {
102800ec4c51SChris Mason 		return 1;
102900ec4c51SChris Mason 	}
103000ec4c51SChris Mason 	upper = path->nodes[1];
1031e20d96d6SChris Mason 	upper_node = btrfs_buffer_node(upper);
1032e20d96d6SChris Mason 	if (slot >= btrfs_header_nritems(&upper_node->header) - 1) {
103300ec4c51SChris Mason 		return 1;
103400ec4c51SChris Mason 	}
1035e20d96d6SChris Mason 	right_buf = read_tree_block(root,
1036e20d96d6SChris Mason 		    btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1));
1037e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buf);
1038123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
10390783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1040234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
104100ec4c51SChris Mason 		return 1;
104200ec4c51SChris Mason 	}
104302217ed2SChris Mason 	/* cow and double check */
1044e089f05cSChris Mason 	btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf);
1045e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buf);
1046123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
10470783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1048234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
104902217ed2SChris Mason 		return 1;
105002217ed2SChris Mason 	}
105102217ed2SChris Mason 
10527518a238SChris Mason 	left_nritems = btrfs_header_nritems(&left->header);
1053a429e513SChris Mason 	if (left_nritems == 0) {
1054a429e513SChris Mason 		btrfs_block_release(root, right_buf);
1055a429e513SChris Mason 		return 1;
1056a429e513SChris Mason 	}
1057a429e513SChris Mason 	for (i = left_nritems - 1; i >= 1; i--) {
105800ec4c51SChris Mason 		item = left->items + i;
105900ec4c51SChris Mason 		if (path->slots[0] == i)
106000ec4c51SChris Mason 			push_space += data_size + sizeof(*item);
10610783fcfcSChris Mason 		if (btrfs_item_size(item) + sizeof(*item) + push_space >
10620783fcfcSChris Mason 		    free_space)
106300ec4c51SChris Mason 			break;
106400ec4c51SChris Mason 		push_items++;
10650783fcfcSChris Mason 		push_space += btrfs_item_size(item) + sizeof(*item);
106600ec4c51SChris Mason 	}
106700ec4c51SChris Mason 	if (push_items == 0) {
1068234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
106900ec4c51SChris Mason 		return 1;
107000ec4c51SChris Mason 	}
1071a429e513SChris Mason 	if (push_items == left_nritems)
1072a429e513SChris Mason 		WARN_ON(1);
10737518a238SChris Mason 	right_nritems = btrfs_header_nritems(&right->header);
107400ec4c51SChris Mason 	/* push left to right */
10750783fcfcSChris Mason 	push_space = btrfs_item_end(left->items + left_nritems - push_items);
1076123abc88SChris Mason 	push_space -= leaf_data_end(root, left);
107700ec4c51SChris Mason 	/* make room in the right data area */
1078d6025579SChris Mason 	btrfs_memmove(root, right, btrfs_leaf_data(right) +
1079d6025579SChris Mason 		      leaf_data_end(root, right) - push_space,
1080d6025579SChris Mason 		      btrfs_leaf_data(right) +
1081d6025579SChris Mason 		      leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) -
1082d6025579SChris Mason 		      leaf_data_end(root, right));
108300ec4c51SChris Mason 	/* copy from the left data area */
1084d6025579SChris Mason 	btrfs_memcpy(root, right, btrfs_leaf_data(right) +
1085d6025579SChris Mason 		     BTRFS_LEAF_DATA_SIZE(root) - push_space,
1086d6025579SChris Mason 		     btrfs_leaf_data(left) + leaf_data_end(root, left),
1087d6025579SChris Mason 		     push_space);
1088d6025579SChris Mason 	btrfs_memmove(root, right, right->items + push_items, right->items,
10890783fcfcSChris Mason 		right_nritems * sizeof(struct btrfs_item));
109000ec4c51SChris Mason 	/* copy the items from left to right */
1091d6025579SChris Mason 	btrfs_memcpy(root, right, right->items, left->items +
1092d6025579SChris Mason 		     left_nritems - push_items,
10930783fcfcSChris Mason 		     push_items * sizeof(struct btrfs_item));
109400ec4c51SChris Mason 
109500ec4c51SChris Mason 	/* update the item pointers */
10967518a238SChris Mason 	right_nritems += push_items;
10977518a238SChris Mason 	btrfs_set_header_nritems(&right->header, right_nritems);
1098123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
10997518a238SChris Mason 	for (i = 0; i < right_nritems; i++) {
11000783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, push_space -
11010783fcfcSChris Mason 				      btrfs_item_size(right->items + i));
11020783fcfcSChris Mason 		push_space = btrfs_item_offset(right->items + i);
110300ec4c51SChris Mason 	}
11047518a238SChris Mason 	left_nritems -= push_items;
11057518a238SChris Mason 	btrfs_set_header_nritems(&left->header, left_nritems);
110600ec4c51SChris Mason 
1107d6025579SChris Mason 	btrfs_mark_buffer_dirty(left_buf);
1108d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buf);
1109a429e513SChris Mason 
1110d6025579SChris Mason 	btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key,
1111e2fa7227SChris Mason 		&right->items[0].key, sizeof(struct btrfs_disk_key));
1112d6025579SChris Mason 	btrfs_mark_buffer_dirty(upper);
111302217ed2SChris Mason 
111400ec4c51SChris Mason 	/* then fixup the leaf pointer in the path */
11157518a238SChris Mason 	if (path->slots[0] >= left_nritems) {
11167518a238SChris Mason 		path->slots[0] -= left_nritems;
1117234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
111800ec4c51SChris Mason 		path->nodes[0] = right_buf;
111900ec4c51SChris Mason 		path->slots[1] += 1;
112000ec4c51SChris Mason 	} else {
1121234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
112200ec4c51SChris Mason 	}
1123098f59c2SChris Mason 	if (path->nodes[1])
1124098f59c2SChris Mason 		check_node(root, path, 1);
112500ec4c51SChris Mason 	return 0;
112600ec4c51SChris Mason }
112700ec4c51SChris Mason /*
112874123bd7SChris Mason  * push some data in the path leaf to the left, trying to free up at
112974123bd7SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
113074123bd7SChris Mason  */
1131e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
1132e089f05cSChris Mason 			  *root, struct btrfs_path *path, int data_size)
1133be0e5c09SChris Mason {
1134e20d96d6SChris Mason 	struct buffer_head *right_buf = path->nodes[0];
1135e20d96d6SChris Mason 	struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf);
1136e20d96d6SChris Mason 	struct buffer_head *t;
1137234b63a0SChris Mason 	struct btrfs_leaf *left;
1138be0e5c09SChris Mason 	int slot;
1139be0e5c09SChris Mason 	int i;
1140be0e5c09SChris Mason 	int free_space;
1141be0e5c09SChris Mason 	int push_space = 0;
1142be0e5c09SChris Mason 	int push_items = 0;
11430783fcfcSChris Mason 	struct btrfs_item *item;
11447518a238SChris Mason 	u32 old_left_nritems;
1145aa5d6bedSChris Mason 	int ret = 0;
1146aa5d6bedSChris Mason 	int wret;
1147be0e5c09SChris Mason 
1148be0e5c09SChris Mason 	slot = path->slots[1];
1149be0e5c09SChris Mason 	if (slot == 0) {
1150be0e5c09SChris Mason 		return 1;
1151be0e5c09SChris Mason 	}
1152be0e5c09SChris Mason 	if (!path->nodes[1]) {
1153be0e5c09SChris Mason 		return 1;
1154be0e5c09SChris Mason 	}
1155e20d96d6SChris Mason 	t = read_tree_block(root,
1156e20d96d6SChris Mason 	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1));
1157e20d96d6SChris Mason 	left = btrfs_buffer_leaf(t);
1158123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
11590783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1160234b63a0SChris Mason 		btrfs_block_release(root, t);
1161be0e5c09SChris Mason 		return 1;
1162be0e5c09SChris Mason 	}
116302217ed2SChris Mason 
116402217ed2SChris Mason 	/* cow and double check */
1165e089f05cSChris Mason 	btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
1166e20d96d6SChris Mason 	left = btrfs_buffer_leaf(t);
1167123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
11680783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1169234b63a0SChris Mason 		btrfs_block_release(root, t);
117002217ed2SChris Mason 		return 1;
117102217ed2SChris Mason 	}
117202217ed2SChris Mason 
1173a429e513SChris Mason 	if (btrfs_header_nritems(&right->header) == 0) {
1174a429e513SChris Mason 		btrfs_block_release(root, t);
1175a429e513SChris Mason 		return 1;
1176a429e513SChris Mason 	}
1177a429e513SChris Mason 
1178a429e513SChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) {
1179be0e5c09SChris Mason 		item = right->items + i;
1180be0e5c09SChris Mason 		if (path->slots[0] == i)
1181be0e5c09SChris Mason 			push_space += data_size + sizeof(*item);
11820783fcfcSChris Mason 		if (btrfs_item_size(item) + sizeof(*item) + push_space >
11830783fcfcSChris Mason 		    free_space)
1184be0e5c09SChris Mason 			break;
1185be0e5c09SChris Mason 		push_items++;
11860783fcfcSChris Mason 		push_space += btrfs_item_size(item) + sizeof(*item);
1187be0e5c09SChris Mason 	}
1188be0e5c09SChris Mason 	if (push_items == 0) {
1189234b63a0SChris Mason 		btrfs_block_release(root, t);
1190be0e5c09SChris Mason 		return 1;
1191be0e5c09SChris Mason 	}
1192a429e513SChris Mason 	if (push_items == btrfs_header_nritems(&right->header))
1193a429e513SChris Mason 		WARN_ON(1);
1194be0e5c09SChris Mason 	/* push data from right to left */
1195d6025579SChris Mason 	btrfs_memcpy(root, left, left->items +
1196d6025579SChris Mason 		     btrfs_header_nritems(&left->header),
11970783fcfcSChris Mason 		     right->items, push_items * sizeof(struct btrfs_item));
1198123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root) -
11990783fcfcSChris Mason 		     btrfs_item_offset(right->items + push_items -1);
1200d6025579SChris Mason 	btrfs_memcpy(root, left, btrfs_leaf_data(left) +
1201d6025579SChris Mason 		     leaf_data_end(root, left) - push_space,
1202123abc88SChris Mason 		     btrfs_leaf_data(right) +
1203123abc88SChris Mason 		     btrfs_item_offset(right->items + push_items - 1),
1204be0e5c09SChris Mason 		     push_space);
12057518a238SChris Mason 	old_left_nritems = btrfs_header_nritems(&left->header);
1206eb60ceacSChris Mason 	BUG_ON(old_left_nritems < 0);
1207eb60ceacSChris Mason 
1208be0e5c09SChris Mason 	for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
1209123abc88SChris Mason 		u32 ioff = btrfs_item_offset(left->items + i);
1210123abc88SChris Mason 		btrfs_set_item_offset(left->items + i, ioff -
1211123abc88SChris Mason 				     (BTRFS_LEAF_DATA_SIZE(root) -
12120783fcfcSChris Mason 				      btrfs_item_offset(left->items +
12130783fcfcSChris Mason 						        old_left_nritems - 1)));
1214be0e5c09SChris Mason 	}
12157518a238SChris Mason 	btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
1216be0e5c09SChris Mason 
1217be0e5c09SChris Mason 	/* fixup right node */
12180783fcfcSChris Mason 	push_space = btrfs_item_offset(right->items + push_items - 1) -
1219123abc88SChris Mason 		     leaf_data_end(root, right);
1220d6025579SChris Mason 	btrfs_memmove(root, right, btrfs_leaf_data(right) +
1221d6025579SChris Mason 		      BTRFS_LEAF_DATA_SIZE(root) - push_space,
1222d6025579SChris Mason 		      btrfs_leaf_data(right) +
1223123abc88SChris Mason 		      leaf_data_end(root, right), push_space);
1224d6025579SChris Mason 	btrfs_memmove(root, right, right->items, right->items + push_items,
12257518a238SChris Mason 		(btrfs_header_nritems(&right->header) - push_items) *
12260783fcfcSChris Mason 		sizeof(struct btrfs_item));
12277518a238SChris Mason 	btrfs_set_header_nritems(&right->header,
12287518a238SChris Mason 				 btrfs_header_nritems(&right->header) -
12297518a238SChris Mason 				 push_items);
1230123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
1231eb60ceacSChris Mason 
12327518a238SChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
12330783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, push_space -
12340783fcfcSChris Mason 				      btrfs_item_size(right->items + i));
12350783fcfcSChris Mason 		push_space = btrfs_item_offset(right->items + i);
1236be0e5c09SChris Mason 	}
1237eb60ceacSChris Mason 
1238d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
1239d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buf);
1240098f59c2SChris Mason 
1241e089f05cSChris Mason 	wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
1242aa5d6bedSChris Mason 	if (wret)
1243aa5d6bedSChris Mason 		ret = wret;
1244be0e5c09SChris Mason 
1245be0e5c09SChris Mason 	/* then fixup the leaf pointer in the path */
1246be0e5c09SChris Mason 	if (path->slots[0] < push_items) {
1247be0e5c09SChris Mason 		path->slots[0] += old_left_nritems;
1248234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
1249eb60ceacSChris Mason 		path->nodes[0] = t;
1250be0e5c09SChris Mason 		path->slots[1] -= 1;
1251be0e5c09SChris Mason 	} else {
1252234b63a0SChris Mason 		btrfs_block_release(root, t);
1253be0e5c09SChris Mason 		path->slots[0] -= push_items;
1254be0e5c09SChris Mason 	}
1255eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
1256098f59c2SChris Mason 	if (path->nodes[1])
1257098f59c2SChris Mason 		check_node(root, path, 1);
1258aa5d6bedSChris Mason 	return ret;
1259be0e5c09SChris Mason }
1260be0e5c09SChris Mason 
126174123bd7SChris Mason /*
126274123bd7SChris Mason  * split the path's leaf in two, making sure there is at least data_size
126374123bd7SChris Mason  * available for the resulting leaf level of the path.
1264aa5d6bedSChris Mason  *
1265aa5d6bedSChris Mason  * returns 0 if all went well and < 0 on failure.
126674123bd7SChris Mason  */
1267e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1268d4dbff95SChris Mason 		      *root, struct btrfs_key *ins_key,
1269d4dbff95SChris Mason 		      struct btrfs_path *path, int data_size)
1270be0e5c09SChris Mason {
1271e20d96d6SChris Mason 	struct buffer_head *l_buf;
1272234b63a0SChris Mason 	struct btrfs_leaf *l;
12737518a238SChris Mason 	u32 nritems;
1274eb60ceacSChris Mason 	int mid;
1275eb60ceacSChris Mason 	int slot;
1276234b63a0SChris Mason 	struct btrfs_leaf *right;
1277e20d96d6SChris Mason 	struct buffer_head *right_buffer;
12780783fcfcSChris Mason 	int space_needed = data_size + sizeof(struct btrfs_item);
1279be0e5c09SChris Mason 	int data_copy_size;
1280be0e5c09SChris Mason 	int rt_data_off;
1281be0e5c09SChris Mason 	int i;
1282d4dbff95SChris Mason 	int ret = 0;
1283aa5d6bedSChris Mason 	int wret;
1284d4dbff95SChris Mason 	int double_split = 0;
1285d4dbff95SChris Mason 	struct btrfs_disk_key disk_key;
1286be0e5c09SChris Mason 
128740689478SChris Mason 	/* first try to make some room by pushing left and right */
1288e089f05cSChris Mason 	wret = push_leaf_left(trans, root, path, data_size);
1289eaee50e8SChris Mason 	if (wret < 0)
1290eaee50e8SChris Mason 		return wret;
1291eaee50e8SChris Mason 	if (wret) {
1292e089f05cSChris Mason 		wret = push_leaf_right(trans, root, path, data_size);
1293eaee50e8SChris Mason 		if (wret < 0)
1294eaee50e8SChris Mason 			return wret;
1295eaee50e8SChris Mason 	}
1296eb60ceacSChris Mason 	l_buf = path->nodes[0];
1297e20d96d6SChris Mason 	l = btrfs_buffer_leaf(l_buf);
1298aa5d6bedSChris Mason 
1299aa5d6bedSChris Mason 	/* did the pushes work? */
1300123abc88SChris Mason 	if (btrfs_leaf_free_space(root, l) >=
1301123abc88SChris Mason 	    sizeof(struct btrfs_item) + data_size)
1302be0e5c09SChris Mason 		return 0;
1303aa5d6bedSChris Mason 
13045c680ed6SChris Mason 	if (!path->nodes[1]) {
1305e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, 1);
13065c680ed6SChris Mason 		if (ret)
13075c680ed6SChris Mason 			return ret;
13085c680ed6SChris Mason 	}
1309eb60ceacSChris Mason 	slot = path->slots[0];
13107518a238SChris Mason 	nritems = btrfs_header_nritems(&l->header);
1311eb60ceacSChris Mason 	mid = (nritems + 1)/ 2;
131231f3c99bSChris Mason 	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
1313eb60ceacSChris Mason 	BUG_ON(!right_buffer);
1314e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buffer);
1315123abc88SChris Mason 	memset(&right->header, 0, sizeof(right->header));
13167eccb903SChris Mason 	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
13177f5c1516SChris Mason 	btrfs_set_header_generation(&right->header, trans->transid);
13184d775673SChris Mason 	btrfs_set_header_owner(&right->header, root->root_key.objectid);
13197518a238SChris Mason 	btrfs_set_header_level(&right->header, 0);
13203eb0314dSChris Mason 	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
13213eb0314dSChris Mason 	       sizeof(right->header.fsid));
1322d4dbff95SChris Mason 	if (mid <= slot) {
1323d4dbff95SChris Mason 		if (nritems == 1 ||
1324d4dbff95SChris Mason 		    leaf_space_used(l, mid, nritems - mid) + space_needed >
1325d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
1326d4dbff95SChris Mason 			if (slot >= nritems) {
1327d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
1328d4dbff95SChris Mason 				btrfs_set_header_nritems(&right->header, 0);
1329d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
1330d4dbff95SChris Mason 						  &disk_key,
13317eccb903SChris Mason 						  bh_blocknr(right_buffer),
1332d4dbff95SChris Mason 						  path->slots[1] + 1, 1);
1333d4dbff95SChris Mason 				if (wret)
1334d4dbff95SChris Mason 					ret = wret;
1335d4dbff95SChris Mason 				btrfs_block_release(root, path->nodes[0]);
1336d4dbff95SChris Mason 				path->nodes[0] = right_buffer;
1337d4dbff95SChris Mason 				path->slots[0] = 0;
1338d4dbff95SChris Mason 				path->slots[1] += 1;
1339d4dbff95SChris Mason 				return ret;
1340d4dbff95SChris Mason 			}
1341d4dbff95SChris Mason 			mid = slot;
1342d4dbff95SChris Mason 			double_split = 1;
1343d4dbff95SChris Mason 		}
1344d4dbff95SChris Mason 	} else {
1345d4dbff95SChris Mason 		if (leaf_space_used(l, 0, mid + 1) + space_needed >
1346d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
1347d4dbff95SChris Mason 			if (slot == 0) {
1348d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
1349d4dbff95SChris Mason 				btrfs_set_header_nritems(&right->header, 0);
1350d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
1351d4dbff95SChris Mason 						  &disk_key,
13527eccb903SChris Mason 						  bh_blocknr(right_buffer),
1353098f59c2SChris Mason 						  path->slots[1], 1);
1354d4dbff95SChris Mason 				if (wret)
1355d4dbff95SChris Mason 					ret = wret;
1356d4dbff95SChris Mason 				btrfs_block_release(root, path->nodes[0]);
1357d4dbff95SChris Mason 				path->nodes[0] = right_buffer;
1358d4dbff95SChris Mason 				path->slots[0] = 0;
1359a429e513SChris Mason 				if (path->slots[1] == 0) {
1360a429e513SChris Mason 					wret = fixup_low_keys(trans, root,
1361a429e513SChris Mason 					           path, &disk_key, 1);
1362a429e513SChris Mason 					if (wret)
1363a429e513SChris Mason 						ret = wret;
1364a429e513SChris Mason 				}
1365d4dbff95SChris Mason 				return ret;
1366d4dbff95SChris Mason 			}
1367d4dbff95SChris Mason 			mid = slot;
1368d4dbff95SChris Mason 			double_split = 1;
1369d4dbff95SChris Mason 		}
1370d4dbff95SChris Mason 	}
1371d4dbff95SChris Mason 	btrfs_set_header_nritems(&right->header, nritems - mid);
1372123abc88SChris Mason 	data_copy_size = btrfs_item_end(l->items + mid) -
1373123abc88SChris Mason 			 leaf_data_end(root, l);
1374d6025579SChris Mason 	btrfs_memcpy(root, right, right->items, l->items + mid,
13750783fcfcSChris Mason 		     (nritems - mid) * sizeof(struct btrfs_item));
1376d6025579SChris Mason 	btrfs_memcpy(root, right,
1377d6025579SChris Mason 		     btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
1378123abc88SChris Mason 		     data_copy_size, btrfs_leaf_data(l) +
1379123abc88SChris Mason 		     leaf_data_end(root, l), data_copy_size);
1380123abc88SChris Mason 	rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
1381123abc88SChris Mason 		      btrfs_item_end(l->items + mid);
138274123bd7SChris Mason 
13830783fcfcSChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
1384123abc88SChris Mason 		u32 ioff = btrfs_item_offset(right->items + i);
13850783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
13860783fcfcSChris Mason 	}
138774123bd7SChris Mason 
13887518a238SChris Mason 	btrfs_set_header_nritems(&l->header, mid);
1389aa5d6bedSChris Mason 	ret = 0;
1390e089f05cSChris Mason 	wret = insert_ptr(trans, root, path, &right->items[0].key,
13917eccb903SChris Mason 			  bh_blocknr(right_buffer), path->slots[1] + 1, 1);
1392aa5d6bedSChris Mason 	if (wret)
1393aa5d6bedSChris Mason 		ret = wret;
1394d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buffer);
1395d6025579SChris Mason 	btrfs_mark_buffer_dirty(l_buf);
1396eb60ceacSChris Mason 	BUG_ON(path->slots[0] != slot);
1397be0e5c09SChris Mason 	if (mid <= slot) {
1398234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
1399eb60ceacSChris Mason 		path->nodes[0] = right_buffer;
1400be0e5c09SChris Mason 		path->slots[0] -= mid;
1401be0e5c09SChris Mason 		path->slots[1] += 1;
1402eb60ceacSChris Mason 	} else
1403234b63a0SChris Mason 		btrfs_block_release(root, right_buffer);
1404eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
1405098f59c2SChris Mason 	check_node(root, path, 1);
1406d4dbff95SChris Mason 
1407d4dbff95SChris Mason 	if (!double_split)
1408d4dbff95SChris Mason 		return ret;
140931f3c99bSChris Mason 	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
1410d4dbff95SChris Mason 	BUG_ON(!right_buffer);
1411d4dbff95SChris Mason 	right = btrfs_buffer_leaf(right_buffer);
1412d4dbff95SChris Mason 	memset(&right->header, 0, sizeof(right->header));
14137eccb903SChris Mason 	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1414d4dbff95SChris Mason 	btrfs_set_header_generation(&right->header, trans->transid);
14154d775673SChris Mason 	btrfs_set_header_owner(&right->header, root->root_key.objectid);
1416d4dbff95SChris Mason 	btrfs_set_header_level(&right->header, 0);
14173eb0314dSChris Mason 	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
14183eb0314dSChris Mason 	       sizeof(right->header.fsid));
1419d4dbff95SChris Mason 	btrfs_cpu_key_to_disk(&disk_key, ins_key);
1420d4dbff95SChris Mason 	btrfs_set_header_nritems(&right->header, 0);
1421d4dbff95SChris Mason 	wret = insert_ptr(trans, root, path,
1422d4dbff95SChris Mason 			  &disk_key,
14237eccb903SChris Mason 			  bh_blocknr(right_buffer),
1424d4dbff95SChris Mason 			  path->slots[1], 1);
1425d4dbff95SChris Mason 	if (wret)
1426d4dbff95SChris Mason 		ret = wret;
1427a429e513SChris Mason 	if (path->slots[1] == 0) {
1428a429e513SChris Mason 		wret = fixup_low_keys(trans, root, path, &disk_key, 1);
1429a429e513SChris Mason 		if (wret)
1430a429e513SChris Mason 			ret = wret;
1431a429e513SChris Mason 	}
1432d4dbff95SChris Mason 	btrfs_block_release(root, path->nodes[0]);
1433d4dbff95SChris Mason 	path->nodes[0] = right_buffer;
1434d4dbff95SChris Mason 	path->slots[0] = 0;
1435d4dbff95SChris Mason 	check_node(root, path, 1);
1436d4dbff95SChris Mason 	check_leaf(root, path, 0);
1437be0e5c09SChris Mason 	return ret;
1438be0e5c09SChris Mason }
1439be0e5c09SChris Mason 
1440b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans,
1441b18c6685SChris Mason 			struct btrfs_root *root,
1442b18c6685SChris Mason 			struct btrfs_path *path,
1443b18c6685SChris Mason 			u32 new_size)
1444b18c6685SChris Mason {
1445b18c6685SChris Mason 	int ret = 0;
1446b18c6685SChris Mason 	int slot;
1447b18c6685SChris Mason 	int slot_orig;
1448b18c6685SChris Mason 	struct btrfs_leaf *leaf;
1449b18c6685SChris Mason 	struct buffer_head *leaf_buf;
1450b18c6685SChris Mason 	u32 nritems;
1451b18c6685SChris Mason 	unsigned int data_end;
1452b18c6685SChris Mason 	unsigned int old_data_start;
1453b18c6685SChris Mason 	unsigned int old_size;
1454b18c6685SChris Mason 	unsigned int size_diff;
1455b18c6685SChris Mason 	int i;
1456b18c6685SChris Mason 
1457b18c6685SChris Mason 	slot_orig = path->slots[0];
1458b18c6685SChris Mason 	leaf_buf = path->nodes[0];
1459b18c6685SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
1460b18c6685SChris Mason 
1461b18c6685SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1462b18c6685SChris Mason 	data_end = leaf_data_end(root, leaf);
1463b18c6685SChris Mason 
1464b18c6685SChris Mason 	slot = path->slots[0];
1465b18c6685SChris Mason 	old_data_start = btrfs_item_offset(leaf->items + slot);
1466b18c6685SChris Mason 	old_size = btrfs_item_size(leaf->items + slot);
1467b18c6685SChris Mason 	BUG_ON(old_size <= new_size);
1468b18c6685SChris Mason 	size_diff = old_size - new_size;
1469b18c6685SChris Mason 
1470b18c6685SChris Mason 	BUG_ON(slot < 0);
1471b18c6685SChris Mason 	BUG_ON(slot >= nritems);
1472b18c6685SChris Mason 
1473b18c6685SChris Mason 	/*
1474b18c6685SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1475b18c6685SChris Mason 	 */
1476b18c6685SChris Mason 	/* first correct the data pointers */
1477b18c6685SChris Mason 	for (i = slot; i < nritems; i++) {
1478b18c6685SChris Mason 		u32 ioff = btrfs_item_offset(leaf->items + i);
1479b18c6685SChris Mason 		btrfs_set_item_offset(leaf->items + i,
1480b18c6685SChris Mason 				      ioff + size_diff);
1481b18c6685SChris Mason 	}
1482b18c6685SChris Mason 	/* shift the data */
1483b18c6685SChris Mason 	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1484b18c6685SChris Mason 		      data_end + size_diff, btrfs_leaf_data(leaf) +
1485b18c6685SChris Mason 		      data_end, old_data_start + new_size - data_end);
1486b18c6685SChris Mason 	btrfs_set_item_size(leaf->items + slot, new_size);
1487b18c6685SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
1488b18c6685SChris Mason 
1489b18c6685SChris Mason 	ret = 0;
1490b18c6685SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
1491b18c6685SChris Mason 		BUG();
1492b18c6685SChris Mason 	check_leaf(root, path, 0);
1493b18c6685SChris Mason 	return ret;
1494b18c6685SChris Mason }
1495b18c6685SChris Mason 
14966567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root
14976567e837SChris Mason 		      *root, struct btrfs_path *path, u32 data_size)
14986567e837SChris Mason {
14996567e837SChris Mason 	int ret = 0;
15006567e837SChris Mason 	int slot;
15016567e837SChris Mason 	int slot_orig;
15026567e837SChris Mason 	struct btrfs_leaf *leaf;
15036567e837SChris Mason 	struct buffer_head *leaf_buf;
15046567e837SChris Mason 	u32 nritems;
15056567e837SChris Mason 	unsigned int data_end;
15066567e837SChris Mason 	unsigned int old_data;
15076567e837SChris Mason 	unsigned int old_size;
15086567e837SChris Mason 	int i;
15096567e837SChris Mason 
15106567e837SChris Mason 	slot_orig = path->slots[0];
15116567e837SChris Mason 	leaf_buf = path->nodes[0];
15126567e837SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
15136567e837SChris Mason 
15146567e837SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
15156567e837SChris Mason 	data_end = leaf_data_end(root, leaf);
15166567e837SChris Mason 
15176567e837SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < data_size)
15186567e837SChris Mason 		BUG();
15196567e837SChris Mason 	slot = path->slots[0];
15206567e837SChris Mason 	old_data = btrfs_item_end(leaf->items + slot);
15216567e837SChris Mason 
15226567e837SChris Mason 	BUG_ON(slot < 0);
15236567e837SChris Mason 	BUG_ON(slot >= nritems);
15246567e837SChris Mason 
15256567e837SChris Mason 	/*
15266567e837SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
15276567e837SChris Mason 	 */
15286567e837SChris Mason 	/* first correct the data pointers */
15296567e837SChris Mason 	for (i = slot; i < nritems; i++) {
15306567e837SChris Mason 		u32 ioff = btrfs_item_offset(leaf->items + i);
15316567e837SChris Mason 		btrfs_set_item_offset(leaf->items + i,
15326567e837SChris Mason 				      ioff - data_size);
15336567e837SChris Mason 	}
15346567e837SChris Mason 	/* shift the data */
15356567e837SChris Mason 	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
15366567e837SChris Mason 		      data_end - data_size, btrfs_leaf_data(leaf) +
15376567e837SChris Mason 		      data_end, old_data - data_end);
15386567e837SChris Mason 	data_end = old_data;
15396567e837SChris Mason 	old_size = btrfs_item_size(leaf->items + slot);
15406567e837SChris Mason 	btrfs_set_item_size(leaf->items + slot, old_size + data_size);
15416567e837SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
15426567e837SChris Mason 
15436567e837SChris Mason 	ret = 0;
15446567e837SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
15456567e837SChris Mason 		BUG();
15466567e837SChris Mason 	check_leaf(root, path, 0);
15476567e837SChris Mason 	return ret;
15486567e837SChris Mason }
15496567e837SChris Mason 
155074123bd7SChris Mason /*
155174123bd7SChris Mason  * Given a key and some data, insert an item into the tree.
155274123bd7SChris Mason  * This does all the path init required, making room in the tree if needed.
155374123bd7SChris Mason  */
1554e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
1555e089f05cSChris Mason 			    *root, struct btrfs_path *path, struct btrfs_key
1556e089f05cSChris Mason 			    *cpu_key, u32 data_size)
1557be0e5c09SChris Mason {
1558aa5d6bedSChris Mason 	int ret = 0;
1559be0e5c09SChris Mason 	int slot;
1560eb60ceacSChris Mason 	int slot_orig;
1561234b63a0SChris Mason 	struct btrfs_leaf *leaf;
1562e20d96d6SChris Mason 	struct buffer_head *leaf_buf;
15637518a238SChris Mason 	u32 nritems;
1564be0e5c09SChris Mason 	unsigned int data_end;
1565e2fa7227SChris Mason 	struct btrfs_disk_key disk_key;
1566e2fa7227SChris Mason 
1567e2fa7227SChris Mason 	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1568be0e5c09SChris Mason 
156974123bd7SChris Mason 	/* create a root if there isn't one */
15705c680ed6SChris Mason 	if (!root->node)
1571cfaa7295SChris Mason 		BUG();
1572e089f05cSChris Mason 	ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
1573eb60ceacSChris Mason 	if (ret == 0) {
1574f0930a37SChris Mason 		return -EEXIST;
1575aa5d6bedSChris Mason 	}
1576ed2ff2cbSChris Mason 	if (ret < 0)
1577ed2ff2cbSChris Mason 		goto out;
1578be0e5c09SChris Mason 
157962e2749eSChris Mason 	slot_orig = path->slots[0];
158062e2749eSChris Mason 	leaf_buf = path->nodes[0];
1581e20d96d6SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
158274123bd7SChris Mason 
15837518a238SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1584123abc88SChris Mason 	data_end = leaf_data_end(root, leaf);
1585eb60ceacSChris Mason 
1586123abc88SChris Mason 	if (btrfs_leaf_free_space(root, leaf) <
1587d4dbff95SChris Mason 	    sizeof(struct btrfs_item) + data_size) {
1588be0e5c09SChris Mason 		BUG();
1589d4dbff95SChris Mason 	}
159062e2749eSChris Mason 	slot = path->slots[0];
1591eb60ceacSChris Mason 	BUG_ON(slot < 0);
1592be0e5c09SChris Mason 	if (slot != nritems) {
1593be0e5c09SChris Mason 		int i;
15940783fcfcSChris Mason 		unsigned int old_data = btrfs_item_end(leaf->items + slot);
1595be0e5c09SChris Mason 
1596be0e5c09SChris Mason 		/*
1597be0e5c09SChris Mason 		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1598be0e5c09SChris Mason 		 */
1599be0e5c09SChris Mason 		/* first correct the data pointers */
16000783fcfcSChris Mason 		for (i = slot; i < nritems; i++) {
1601123abc88SChris Mason 			u32 ioff = btrfs_item_offset(leaf->items + i);
16020783fcfcSChris Mason 			btrfs_set_item_offset(leaf->items + i,
16030783fcfcSChris Mason 					      ioff - data_size);
16040783fcfcSChris Mason 		}
1605be0e5c09SChris Mason 
1606be0e5c09SChris Mason 		/* shift the items */
1607d6025579SChris Mason 		btrfs_memmove(root, leaf, leaf->items + slot + 1,
1608d6025579SChris Mason 			      leaf->items + slot,
16090783fcfcSChris Mason 			      (nritems - slot) * sizeof(struct btrfs_item));
1610be0e5c09SChris Mason 
1611be0e5c09SChris Mason 		/* shift the data */
1612d6025579SChris Mason 		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1613d6025579SChris Mason 			      data_end - data_size, btrfs_leaf_data(leaf) +
1614be0e5c09SChris Mason 			      data_end, old_data - data_end);
1615be0e5c09SChris Mason 		data_end = old_data;
1616be0e5c09SChris Mason 	}
161762e2749eSChris Mason 	/* setup the item for the new data */
1618d6025579SChris Mason 	btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key,
1619e2fa7227SChris Mason 		     sizeof(struct btrfs_disk_key));
16200783fcfcSChris Mason 	btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
16210783fcfcSChris Mason 	btrfs_set_item_size(leaf->items + slot, data_size);
16227518a238SChris Mason 	btrfs_set_header_nritems(&leaf->header, nritems + 1);
1623d6025579SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
1624aa5d6bedSChris Mason 
1625aa5d6bedSChris Mason 	ret = 0;
16268e19f2cdSChris Mason 	if (slot == 0)
1627e089f05cSChris Mason 		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
1628aa5d6bedSChris Mason 
1629123abc88SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
1630be0e5c09SChris Mason 		BUG();
163162e2749eSChris Mason 	check_leaf(root, path, 0);
1632ed2ff2cbSChris Mason out:
163362e2749eSChris Mason 	return ret;
163462e2749eSChris Mason }
163562e2749eSChris Mason 
163662e2749eSChris Mason /*
163762e2749eSChris Mason  * Given a key and some data, insert an item into the tree.
163862e2749eSChris Mason  * This does all the path init required, making room in the tree if needed.
163962e2749eSChris Mason  */
1640e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
1641e089f05cSChris Mason 		      *root, struct btrfs_key *cpu_key, void *data, u32
1642e089f05cSChris Mason 		      data_size)
164362e2749eSChris Mason {
164462e2749eSChris Mason 	int ret = 0;
16452c90e5d6SChris Mason 	struct btrfs_path *path;
164662e2749eSChris Mason 	u8 *ptr;
164762e2749eSChris Mason 
16482c90e5d6SChris Mason 	path = btrfs_alloc_path();
16492c90e5d6SChris Mason 	BUG_ON(!path);
16502c90e5d6SChris Mason 	btrfs_init_path(path);
16512c90e5d6SChris Mason 	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
165262e2749eSChris Mason 	if (!ret) {
16532c90e5d6SChris Mason 		ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
16542c90e5d6SChris Mason 				     path->slots[0], u8);
16552c90e5d6SChris Mason 		btrfs_memcpy(root, path->nodes[0]->b_data,
1656d6025579SChris Mason 			     ptr, data, data_size);
16572c90e5d6SChris Mason 		btrfs_mark_buffer_dirty(path->nodes[0]);
165862e2749eSChris Mason 	}
16592c90e5d6SChris Mason 	btrfs_release_path(root, path);
16602c90e5d6SChris Mason 	btrfs_free_path(path);
1661aa5d6bedSChris Mason 	return ret;
1662be0e5c09SChris Mason }
1663be0e5c09SChris Mason 
166474123bd7SChris Mason /*
16655de08d7dSChris Mason  * delete the pointer from a given node.
166674123bd7SChris Mason  *
166774123bd7SChris Mason  * If the delete empties a node, the node is removed from the tree,
166874123bd7SChris Mason  * continuing all the way the root if required.  The root is converted into
166974123bd7SChris Mason  * a leaf if all the nodes are emptied.
167074123bd7SChris Mason  */
1671e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1672e089f05cSChris Mason 		   struct btrfs_path *path, int level, int slot)
1673be0e5c09SChris Mason {
1674234b63a0SChris Mason 	struct btrfs_node *node;
1675e20d96d6SChris Mason 	struct buffer_head *parent = path->nodes[level];
16767518a238SChris Mason 	u32 nritems;
1677aa5d6bedSChris Mason 	int ret = 0;
1678bb803951SChris Mason 	int wret;
1679be0e5c09SChris Mason 
1680e20d96d6SChris Mason 	node = btrfs_buffer_node(parent);
16817518a238SChris Mason 	nritems = btrfs_header_nritems(&node->header);
1682be0e5c09SChris Mason 	if (slot != nritems -1) {
1683d6025579SChris Mason 		btrfs_memmove(root, node, node->ptrs + slot,
1684d6025579SChris Mason 			      node->ptrs + slot + 1,
1685d6025579SChris Mason 			      sizeof(struct btrfs_key_ptr) *
1686d6025579SChris Mason 			      (nritems - slot - 1));
1687be0e5c09SChris Mason 	}
16887518a238SChris Mason 	nritems--;
16897518a238SChris Mason 	btrfs_set_header_nritems(&node->header, nritems);
16907518a238SChris Mason 	if (nritems == 0 && parent == root->node) {
1691e20d96d6SChris Mason 		struct btrfs_header *header = btrfs_buffer_header(root->node);
1692e20d96d6SChris Mason 		BUG_ON(btrfs_header_level(header) != 1);
1693eb60ceacSChris Mason 		/* just turn the root into a leaf and break */
1694e20d96d6SChris Mason 		btrfs_set_header_level(header, 0);
1695bb803951SChris Mason 	} else if (slot == 0) {
1696e089f05cSChris Mason 		wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
1697123abc88SChris Mason 				      level + 1);
16980f70abe2SChris Mason 		if (wret)
16990f70abe2SChris Mason 			ret = wret;
1700be0e5c09SChris Mason 	}
1701d6025579SChris Mason 	btrfs_mark_buffer_dirty(parent);
1702aa5d6bedSChris Mason 	return ret;
1703be0e5c09SChris Mason }
1704be0e5c09SChris Mason 
170574123bd7SChris Mason /*
170674123bd7SChris Mason  * delete the item at the leaf level in path.  If that empties
170774123bd7SChris Mason  * the leaf, remove it from the tree
170874123bd7SChris Mason  */
1709e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1710e089f05cSChris Mason 		   struct btrfs_path *path)
1711be0e5c09SChris Mason {
1712be0e5c09SChris Mason 	int slot;
1713234b63a0SChris Mason 	struct btrfs_leaf *leaf;
1714e20d96d6SChris Mason 	struct buffer_head *leaf_buf;
1715be0e5c09SChris Mason 	int doff;
1716be0e5c09SChris Mason 	int dsize;
1717aa5d6bedSChris Mason 	int ret = 0;
1718aa5d6bedSChris Mason 	int wret;
17197518a238SChris Mason 	u32 nritems;
1720be0e5c09SChris Mason 
1721eb60ceacSChris Mason 	leaf_buf = path->nodes[0];
1722e20d96d6SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
17234920c9acSChris Mason 	slot = path->slots[0];
17240783fcfcSChris Mason 	doff = btrfs_item_offset(leaf->items + slot);
17250783fcfcSChris Mason 	dsize = btrfs_item_size(leaf->items + slot);
17267518a238SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1727be0e5c09SChris Mason 
17287518a238SChris Mason 	if (slot != nritems - 1) {
1729be0e5c09SChris Mason 		int i;
1730123abc88SChris Mason 		int data_end = leaf_data_end(root, leaf);
1731d6025579SChris Mason 		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1732d6025579SChris Mason 			      data_end + dsize,
1733123abc88SChris Mason 			      btrfs_leaf_data(leaf) + data_end,
1734be0e5c09SChris Mason 			      doff - data_end);
17350783fcfcSChris Mason 		for (i = slot + 1; i < nritems; i++) {
1736123abc88SChris Mason 			u32 ioff = btrfs_item_offset(leaf->items + i);
17370783fcfcSChris Mason 			btrfs_set_item_offset(leaf->items + i, ioff + dsize);
17380783fcfcSChris Mason 		}
1739d6025579SChris Mason 		btrfs_memmove(root, leaf, leaf->items + slot,
1740d6025579SChris Mason 			      leaf->items + slot + 1,
17410783fcfcSChris Mason 			      sizeof(struct btrfs_item) *
17427518a238SChris Mason 			      (nritems - slot - 1));
1743be0e5c09SChris Mason 	}
17447518a238SChris Mason 	btrfs_set_header_nritems(&leaf->header, nritems - 1);
17457518a238SChris Mason 	nritems--;
174674123bd7SChris Mason 	/* delete the leaf if we've emptied it */
17477518a238SChris Mason 	if (nritems == 0) {
1748eb60ceacSChris Mason 		if (leaf_buf == root->node) {
17497518a238SChris Mason 			btrfs_set_header_level(&leaf->header, 0);
17509a8dd150SChris Mason 		} else {
1751e089f05cSChris Mason 			clean_tree_block(trans, root, leaf_buf);
1752d6025579SChris Mason 			wait_on_buffer(leaf_buf);
1753e089f05cSChris Mason 			wret = del_ptr(trans, root, path, 1, path->slots[1]);
1754aa5d6bedSChris Mason 			if (wret)
1755aa5d6bedSChris Mason 				ret = wret;
1756e089f05cSChris Mason 			wret = btrfs_free_extent(trans, root,
17577eccb903SChris Mason 						 bh_blocknr(leaf_buf), 1, 1);
17580f70abe2SChris Mason 			if (wret)
17590f70abe2SChris Mason 				ret = wret;
17609a8dd150SChris Mason 		}
1761be0e5c09SChris Mason 	} else {
17627518a238SChris Mason 		int used = leaf_space_used(leaf, 0, nritems);
1763aa5d6bedSChris Mason 		if (slot == 0) {
1764e089f05cSChris Mason 			wret = fixup_low_keys(trans, root, path,
1765aa5d6bedSChris Mason 					      &leaf->items[0].key, 1);
1766aa5d6bedSChris Mason 			if (wret)
1767aa5d6bedSChris Mason 				ret = wret;
1768aa5d6bedSChris Mason 		}
1769aa5d6bedSChris Mason 
177074123bd7SChris Mason 		/* delete the leaf if it is mostly empty */
1771123abc88SChris Mason 		if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
1772be0e5c09SChris Mason 			/* push_leaf_left fixes the path.
1773be0e5c09SChris Mason 			 * make sure the path still points to our leaf
1774be0e5c09SChris Mason 			 * for possible call to del_ptr below
1775be0e5c09SChris Mason 			 */
17764920c9acSChris Mason 			slot = path->slots[1];
1777e20d96d6SChris Mason 			get_bh(leaf_buf);
1778e089f05cSChris Mason 			wret = push_leaf_left(trans, root, path, 1);
1779aa5d6bedSChris Mason 			if (wret < 0)
1780aa5d6bedSChris Mason 				ret = wret;
1781f0930a37SChris Mason 			if (path->nodes[0] == leaf_buf &&
17827518a238SChris Mason 			    btrfs_header_nritems(&leaf->header)) {
1783e089f05cSChris Mason 				wret = push_leaf_right(trans, root, path, 1);
1784aa5d6bedSChris Mason 				if (wret < 0)
1785aa5d6bedSChris Mason 					ret = wret;
1786aa5d6bedSChris Mason 			}
17877518a238SChris Mason 			if (btrfs_header_nritems(&leaf->header) == 0) {
17887eccb903SChris Mason 				u64 blocknr = bh_blocknr(leaf_buf);
1789e089f05cSChris Mason 				clean_tree_block(trans, root, leaf_buf);
1790d6025579SChris Mason 				wait_on_buffer(leaf_buf);
1791e089f05cSChris Mason 				wret = del_ptr(trans, root, path, 1, slot);
1792aa5d6bedSChris Mason 				if (wret)
1793aa5d6bedSChris Mason 					ret = wret;
1794234b63a0SChris Mason 				btrfs_block_release(root, leaf_buf);
1795e089f05cSChris Mason 				wret = btrfs_free_extent(trans, root, blocknr,
1796e089f05cSChris Mason 							 1, 1);
17970f70abe2SChris Mason 				if (wret)
17980f70abe2SChris Mason 					ret = wret;
17995de08d7dSChris Mason 			} else {
1800d6025579SChris Mason 				btrfs_mark_buffer_dirty(leaf_buf);
1801234b63a0SChris Mason 				btrfs_block_release(root, leaf_buf);
1802be0e5c09SChris Mason 			}
1803d5719762SChris Mason 		} else {
1804d6025579SChris Mason 			btrfs_mark_buffer_dirty(leaf_buf);
1805be0e5c09SChris Mason 		}
18069a8dd150SChris Mason 	}
1807aa5d6bedSChris Mason 	return ret;
18089a8dd150SChris Mason }
18099a8dd150SChris Mason 
181097571fd0SChris Mason /*
181197571fd0SChris Mason  * walk up the tree as far as required to find the next leaf.
18120f70abe2SChris Mason  * returns 0 if it found something or 1 if there are no greater leaves.
18130f70abe2SChris Mason  * returns < 0 on io errors.
181497571fd0SChris Mason  */
1815234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
1816d97e63b6SChris Mason {
1817d97e63b6SChris Mason 	int slot;
1818d97e63b6SChris Mason 	int level = 1;
1819d97e63b6SChris Mason 	u64 blocknr;
1820e20d96d6SChris Mason 	struct buffer_head *c;
1821e20d96d6SChris Mason 	struct btrfs_node *c_node;
1822e20d96d6SChris Mason 	struct buffer_head *next = NULL;
1823d97e63b6SChris Mason 
1824234b63a0SChris Mason 	while(level < BTRFS_MAX_LEVEL) {
1825d97e63b6SChris Mason 		if (!path->nodes[level])
18260f70abe2SChris Mason 			return 1;
1827d97e63b6SChris Mason 		slot = path->slots[level] + 1;
1828d97e63b6SChris Mason 		c = path->nodes[level];
1829e20d96d6SChris Mason 		c_node = btrfs_buffer_node(c);
1830e20d96d6SChris Mason 		if (slot >= btrfs_header_nritems(&c_node->header)) {
1831d97e63b6SChris Mason 			level++;
1832d97e63b6SChris Mason 			continue;
1833d97e63b6SChris Mason 		}
1834e20d96d6SChris Mason 		blocknr = btrfs_node_blockptr(c_node, slot);
1835cfaa7295SChris Mason 		if (next)
1836234b63a0SChris Mason 			btrfs_block_release(root, next);
1837d97e63b6SChris Mason 		next = read_tree_block(root, blocknr);
1838d97e63b6SChris Mason 		break;
1839d97e63b6SChris Mason 	}
1840d97e63b6SChris Mason 	path->slots[level] = slot;
1841d97e63b6SChris Mason 	while(1) {
1842d97e63b6SChris Mason 		level--;
1843d97e63b6SChris Mason 		c = path->nodes[level];
1844234b63a0SChris Mason 		btrfs_block_release(root, c);
1845d97e63b6SChris Mason 		path->nodes[level] = next;
1846d97e63b6SChris Mason 		path->slots[level] = 0;
1847d97e63b6SChris Mason 		if (!level)
1848d97e63b6SChris Mason 			break;
18491d4f8a0cSChris Mason 		next = read_tree_block(root,
1850e20d96d6SChris Mason 		       btrfs_node_blockptr(btrfs_buffer_node(next), 0));
1851d97e63b6SChris Mason 	}
1852d97e63b6SChris Mason 	return 0;
1853d97e63b6SChris Mason }
1854