xref: /openbmc/linux/fs/btrfs/ctree.c (revision ccd467d60e81b48cdbecae93532b66bcdedca91d)
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;
7654aa1f4dSChris Mason 	int ret;
7702217ed2SChris Mason 
78*ccd467d6SChris Mason 	WARN_ON(!buffer_uptodate(buf));
79*ccd467d6SChris Mason 	if (trans->transaction != root->fs_info->running_transaction) {
80*ccd467d6SChris Mason 		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
81*ccd467d6SChris Mason 		       root->fs_info->running_transaction->transid);
82*ccd467d6SChris Mason 		WARN_ON(1);
83*ccd467d6SChris Mason 	}
84*ccd467d6SChris Mason 	if (trans->transid != root->fs_info->generation) {
85*ccd467d6SChris Mason 		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
86*ccd467d6SChris Mason 		       root->fs_info->generation);
87*ccd467d6SChris Mason 		WARN_ON(1);
88*ccd467d6SChris Mason 	}
897f5c1516SChris Mason 	if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
907f5c1516SChris Mason 				    trans->transid) {
9102217ed2SChris Mason 		*cow_ret = buf;
9202217ed2SChris Mason 		return 0;
9302217ed2SChris Mason 	}
9431f3c99bSChris Mason 	cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr);
9554aa1f4dSChris Mason 	if (IS_ERR(cow))
9654aa1f4dSChris Mason 		return PTR_ERR(cow);
97e20d96d6SChris Mason 	cow_node = btrfs_buffer_node(cow);
982c90e5d6SChris Mason 	if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
992c90e5d6SChris Mason 		WARN_ON(1);
100e20d96d6SChris Mason 	memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
1017eccb903SChris Mason 	btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow));
1027f5c1516SChris Mason 	btrfs_set_header_generation(&cow_node->header, trans->transid);
1034d775673SChris Mason 	btrfs_set_header_owner(&cow_node->header, root->root_key.objectid);
10454aa1f4dSChris Mason 	ret = btrfs_inc_ref(trans, root, buf);
10554aa1f4dSChris Mason 	if (ret)
10654aa1f4dSChris Mason 		return ret;
10702217ed2SChris Mason 	if (buf == root->node) {
10802217ed2SChris Mason 		root->node = cow;
109e20d96d6SChris Mason 		get_bh(cow);
1102c90e5d6SChris Mason 		if (buf != root->commit_root) {
1117eccb903SChris Mason 			btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
1122c90e5d6SChris Mason 		}
113234b63a0SChris Mason 		btrfs_block_release(root, buf);
11402217ed2SChris Mason 	} else {
115e20d96d6SChris Mason 		btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
1167eccb903SChris Mason 					bh_blocknr(cow));
117d6025579SChris Mason 		btrfs_mark_buffer_dirty(parent);
1187eccb903SChris Mason 		btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
11902217ed2SChris Mason 	}
120234b63a0SChris Mason 	btrfs_block_release(root, buf);
121*ccd467d6SChris Mason 	btrfs_mark_buffer_dirty(cow);
1222c90e5d6SChris Mason 	*cow_ret = cow;
12302217ed2SChris Mason 	return 0;
12402217ed2SChris Mason }
12502217ed2SChris Mason 
12674123bd7SChris Mason /*
12774123bd7SChris Mason  * The leaf data grows from end-to-front in the node.
12874123bd7SChris Mason  * this returns the address of the start of the last item,
12974123bd7SChris Mason  * which is the stop of the leaf data stack
13074123bd7SChris Mason  */
131123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root,
132123abc88SChris Mason 					 struct btrfs_leaf *leaf)
133be0e5c09SChris Mason {
1347518a238SChris Mason 	u32 nr = btrfs_header_nritems(&leaf->header);
135be0e5c09SChris Mason 	if (nr == 0)
136123abc88SChris Mason 		return BTRFS_LEAF_DATA_SIZE(root);
1370783fcfcSChris Mason 	return btrfs_item_offset(leaf->items + nr - 1);
138be0e5c09SChris Mason }
139be0e5c09SChris Mason 
14074123bd7SChris Mason /*
14174123bd7SChris Mason  * compare two keys in a memcmp fashion
14274123bd7SChris Mason  */
1439aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
144be0e5c09SChris Mason {
145e2fa7227SChris Mason 	struct btrfs_key k1;
146e2fa7227SChris Mason 
147e2fa7227SChris Mason 	btrfs_disk_key_to_cpu(&k1, disk);
148e2fa7227SChris Mason 
149e2fa7227SChris Mason 	if (k1.objectid > k2->objectid)
150be0e5c09SChris Mason 		return 1;
151e2fa7227SChris Mason 	if (k1.objectid < k2->objectid)
152be0e5c09SChris Mason 		return -1;
153f254e52cSChris Mason 	if (k1.flags > k2->flags)
154f254e52cSChris Mason 		return 1;
155f254e52cSChris Mason 	if (k1.flags < k2->flags)
156f254e52cSChris Mason 		return -1;
15770b2befdSChris Mason 	if (k1.offset > k2->offset)
15870b2befdSChris Mason 		return 1;
15970b2befdSChris Mason 	if (k1.offset < k2->offset)
16070b2befdSChris Mason 		return -1;
161be0e5c09SChris Mason 	return 0;
162be0e5c09SChris Mason }
16374123bd7SChris Mason 
164123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path,
165123abc88SChris Mason 		      int level)
166aa5d6bedSChris Mason {
167234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
168e20d96d6SChris Mason 	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
169aa5d6bedSChris Mason 	int parent_slot;
1708d7be552SChris Mason 	int slot;
1718d7be552SChris Mason 	struct btrfs_key cpukey;
1727518a238SChris Mason 	u32 nritems = btrfs_header_nritems(&node->header);
173aa5d6bedSChris Mason 
174aa5d6bedSChris Mason 	if (path->nodes[level + 1])
175e20d96d6SChris Mason 		parent = btrfs_buffer_node(path->nodes[level + 1]);
176aa5d6bedSChris Mason 	parent_slot = path->slots[level + 1];
1778d7be552SChris Mason 	slot = path->slots[level];
1787518a238SChris Mason 	BUG_ON(nritems == 0);
1797518a238SChris Mason 	if (parent) {
180e2fa7227SChris Mason 		struct btrfs_disk_key *parent_key;
181123abc88SChris Mason 		parent_key = &parent->ptrs[parent_slot].key;
182123abc88SChris Mason 		BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
183e2fa7227SChris Mason 			      sizeof(struct btrfs_disk_key)));
1841d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
1857518a238SChris Mason 		       btrfs_header_blocknr(&node->header));
186aa5d6bedSChris Mason 	}
187123abc88SChris Mason 	BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
1888d7be552SChris Mason 	if (slot != 0) {
1898d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key);
1908d7be552SChris Mason 		BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0);
1918d7be552SChris Mason 	}
1928d7be552SChris Mason 	if (slot < nritems - 1) {
1938d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key);
1948d7be552SChris Mason 		BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0);
195aa5d6bedSChris Mason 	}
196aa5d6bedSChris Mason 	return 0;
197aa5d6bedSChris Mason }
198aa5d6bedSChris Mason 
199123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
200123abc88SChris Mason 		      int level)
201aa5d6bedSChris Mason {
202e20d96d6SChris Mason 	struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]);
203234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
204aa5d6bedSChris Mason 	int parent_slot;
2058d7be552SChris Mason 	int slot = path->slots[0];
2068d7be552SChris Mason 	struct btrfs_key cpukey;
2078d7be552SChris Mason 
2087518a238SChris Mason 	u32 nritems = btrfs_header_nritems(&leaf->header);
209aa5d6bedSChris Mason 
210aa5d6bedSChris Mason 	if (path->nodes[level + 1])
211e20d96d6SChris Mason 		parent = btrfs_buffer_node(path->nodes[level + 1]);
212aa5d6bedSChris Mason 	parent_slot = path->slots[level + 1];
213123abc88SChris Mason 	BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
2147518a238SChris Mason 
2157518a238SChris Mason 	if (nritems == 0)
2167518a238SChris Mason 		return 0;
2177518a238SChris Mason 
2187518a238SChris Mason 	if (parent) {
219e2fa7227SChris Mason 		struct btrfs_disk_key *parent_key;
220123abc88SChris Mason 		parent_key = &parent->ptrs[parent_slot].key;
221aa5d6bedSChris Mason 		BUG_ON(memcmp(parent_key, &leaf->items[0].key,
222e2fa7227SChris Mason 		       sizeof(struct btrfs_disk_key)));
2231d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
2247518a238SChris Mason 		       btrfs_header_blocknr(&leaf->header));
225aa5d6bedSChris Mason 	}
2268d7be552SChris Mason 	if (slot != 0) {
2278d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key);
2288d7be552SChris Mason 		BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0);
2298d7be552SChris Mason 		BUG_ON(btrfs_item_offset(leaf->items + slot - 1) !=
2308d7be552SChris Mason 			btrfs_item_end(leaf->items + slot));
231aa5d6bedSChris Mason 	}
2328d7be552SChris Mason 	if (slot < nritems - 1) {
2338d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key);
2348d7be552SChris Mason 		BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0);
2358d7be552SChris Mason 		BUG_ON(btrfs_item_offset(leaf->items + slot) !=
2368d7be552SChris Mason 			btrfs_item_end(leaf->items + slot + 1));
237aa5d6bedSChris Mason 	}
2388d7be552SChris Mason 	BUG_ON(btrfs_item_offset(leaf->items) +
2398d7be552SChris Mason 	       btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root));
240aa5d6bedSChris Mason 	return 0;
241aa5d6bedSChris Mason }
242aa5d6bedSChris Mason 
243123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path,
244123abc88SChris Mason 			int level)
245aa5d6bedSChris Mason {
2463eb0314dSChris Mason 	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
2473eb0314dSChris Mason 	if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid,
2483eb0314dSChris Mason 		   sizeof(node->header.fsid)))
2493eb0314dSChris Mason 		BUG();
250aa5d6bedSChris Mason 	if (level == 0)
251123abc88SChris Mason 		return check_leaf(root, path, level);
252123abc88SChris Mason 	return check_node(root, path, level);
253aa5d6bedSChris Mason }
254aa5d6bedSChris Mason 
25574123bd7SChris Mason /*
25674123bd7SChris Mason  * search for key in the array p.  items p are item_size apart
25774123bd7SChris Mason  * and there are 'max' items in p
25874123bd7SChris Mason  * the slot in the array is returned via slot, and it points to
25974123bd7SChris Mason  * the place where you would insert key if it is not found in
26074123bd7SChris Mason  * the array.
26174123bd7SChris Mason  *
26274123bd7SChris Mason  * slot may point to max if the key is bigger than all of the keys
26374123bd7SChris Mason  */
2649aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key,
265be0e5c09SChris Mason 		       int max, int *slot)
266be0e5c09SChris Mason {
267be0e5c09SChris Mason 	int low = 0;
268be0e5c09SChris Mason 	int high = max;
269be0e5c09SChris Mason 	int mid;
270be0e5c09SChris Mason 	int ret;
271e2fa7227SChris Mason 	struct btrfs_disk_key *tmp;
272be0e5c09SChris Mason 
273be0e5c09SChris Mason 	while(low < high) {
274be0e5c09SChris Mason 		mid = (low + high) / 2;
275e2fa7227SChris Mason 		tmp = (struct btrfs_disk_key *)(p + mid * item_size);
276be0e5c09SChris Mason 		ret = comp_keys(tmp, key);
277be0e5c09SChris Mason 
278be0e5c09SChris Mason 		if (ret < 0)
279be0e5c09SChris Mason 			low = mid + 1;
280be0e5c09SChris Mason 		else if (ret > 0)
281be0e5c09SChris Mason 			high = mid;
282be0e5c09SChris Mason 		else {
283be0e5c09SChris Mason 			*slot = mid;
284be0e5c09SChris Mason 			return 0;
285be0e5c09SChris Mason 		}
286be0e5c09SChris Mason 	}
287be0e5c09SChris Mason 	*slot = low;
288be0e5c09SChris Mason 	return 1;
289be0e5c09SChris Mason }
290be0e5c09SChris Mason 
29197571fd0SChris Mason /*
29297571fd0SChris Mason  * simple bin_search frontend that does the right thing for
29397571fd0SChris Mason  * leaves vs nodes
29497571fd0SChris Mason  */
2959aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
296be0e5c09SChris Mason {
2977518a238SChris Mason 	if (btrfs_is_leaf(c)) {
298234b63a0SChris Mason 		struct btrfs_leaf *l = (struct btrfs_leaf *)c;
2990783fcfcSChris Mason 		return generic_bin_search((void *)l->items,
3000783fcfcSChris Mason 					  sizeof(struct btrfs_item),
3017518a238SChris Mason 					  key, btrfs_header_nritems(&c->header),
3027518a238SChris Mason 					  slot);
303be0e5c09SChris Mason 	} else {
304123abc88SChris Mason 		return generic_bin_search((void *)c->ptrs,
305123abc88SChris Mason 					  sizeof(struct btrfs_key_ptr),
3067518a238SChris Mason 					  key, btrfs_header_nritems(&c->header),
3077518a238SChris Mason 					  slot);
308be0e5c09SChris Mason 	}
309be0e5c09SChris Mason 	return -1;
310be0e5c09SChris Mason }
311be0e5c09SChris Mason 
312e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root,
313e20d96d6SChris Mason 				   struct buffer_head *parent_buf,
314bb803951SChris Mason 				   int slot)
315bb803951SChris Mason {
316e20d96d6SChris Mason 	struct btrfs_node *node = btrfs_buffer_node(parent_buf);
317bb803951SChris Mason 	if (slot < 0)
318bb803951SChris Mason 		return NULL;
3197518a238SChris Mason 	if (slot >= btrfs_header_nritems(&node->header))
320bb803951SChris Mason 		return NULL;
3211d4f8a0cSChris Mason 	return read_tree_block(root, btrfs_node_blockptr(node, slot));
322bb803951SChris Mason }
323bb803951SChris Mason 
324e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
325e089f05cSChris Mason 			 *root, struct btrfs_path *path, int level)
326bb803951SChris Mason {
327e20d96d6SChris Mason 	struct buffer_head *right_buf;
328e20d96d6SChris Mason 	struct buffer_head *mid_buf;
329e20d96d6SChris Mason 	struct buffer_head *left_buf;
330e20d96d6SChris Mason 	struct buffer_head *parent_buf = NULL;
331234b63a0SChris Mason 	struct btrfs_node *right = NULL;
332234b63a0SChris Mason 	struct btrfs_node *mid;
333234b63a0SChris Mason 	struct btrfs_node *left = NULL;
334234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
335bb803951SChris Mason 	int ret = 0;
336bb803951SChris Mason 	int wret;
337bb803951SChris Mason 	int pslot;
338bb803951SChris Mason 	int orig_slot = path->slots[level];
33954aa1f4dSChris Mason 	int err_on_enospc = 0;
34079f95c82SChris Mason 	u64 orig_ptr;
341bb803951SChris Mason 
342bb803951SChris Mason 	if (level == 0)
343bb803951SChris Mason 		return 0;
344bb803951SChris Mason 
345bb803951SChris Mason 	mid_buf = path->nodes[level];
346e20d96d6SChris Mason 	mid = btrfs_buffer_node(mid_buf);
3471d4f8a0cSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
34879f95c82SChris Mason 
349234b63a0SChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
350bb803951SChris Mason 		parent_buf = path->nodes[level + 1];
351bb803951SChris Mason 	pslot = path->slots[level + 1];
352bb803951SChris Mason 
35340689478SChris Mason 	/*
35440689478SChris Mason 	 * deal with the case where there is only one pointer in the root
35540689478SChris Mason 	 * by promoting the node below to a root
35640689478SChris Mason 	 */
357bb803951SChris Mason 	if (!parent_buf) {
358e20d96d6SChris Mason 		struct buffer_head *child;
3597eccb903SChris Mason 		u64 blocknr = bh_blocknr(mid_buf);
360bb803951SChris Mason 
3617518a238SChris Mason 		if (btrfs_header_nritems(&mid->header) != 1)
362bb803951SChris Mason 			return 0;
363bb803951SChris Mason 
364bb803951SChris Mason 		/* promote the child to a root */
365bb803951SChris Mason 		child = read_node_slot(root, mid_buf, 0);
366bb803951SChris Mason 		BUG_ON(!child);
367bb803951SChris Mason 		root->node = child;
368bb803951SChris Mason 		path->nodes[level] = NULL;
369d6025579SChris Mason 		clean_tree_block(trans, root, mid_buf);
370d6025579SChris Mason 		wait_on_buffer(mid_buf);
371bb803951SChris Mason 		/* once for the path */
372234b63a0SChris Mason 		btrfs_block_release(root, mid_buf);
373bb803951SChris Mason 		/* once for the root ptr */
374234b63a0SChris Mason 		btrfs_block_release(root, mid_buf);
375e089f05cSChris Mason 		return btrfs_free_extent(trans, root, blocknr, 1, 1);
376bb803951SChris Mason 	}
377e20d96d6SChris Mason 	parent = btrfs_buffer_node(parent_buf);
378bb803951SChris Mason 
379123abc88SChris Mason 	if (btrfs_header_nritems(&mid->header) >
380123abc88SChris Mason 	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
381bb803951SChris Mason 		return 0;
382bb803951SChris Mason 
38354aa1f4dSChris Mason 	if (btrfs_header_nritems(&mid->header) < 2)
38454aa1f4dSChris Mason 		err_on_enospc = 1;
38554aa1f4dSChris Mason 
386bb803951SChris Mason 	left_buf = read_node_slot(root, parent_buf, pslot - 1);
387bb803951SChris Mason 	right_buf = read_node_slot(root, parent_buf, pslot + 1);
38879f95c82SChris Mason 
38979f95c82SChris Mason 	/* first, try to make some room in the middle buffer */
390bb803951SChris Mason 	if (left_buf) {
39154aa1f4dSChris Mason 		wret = btrfs_cow_block(trans, root, left_buf,
39254aa1f4dSChris Mason 				       parent_buf, pslot - 1, &left_buf);
39354aa1f4dSChris Mason 		if (wret) {
39454aa1f4dSChris Mason 			ret = wret;
39554aa1f4dSChris Mason 			goto enospc;
39654aa1f4dSChris Mason 		}
397e20d96d6SChris Mason 		left = btrfs_buffer_node(left_buf);
3987518a238SChris Mason 		orig_slot += btrfs_header_nritems(&left->header);
399e089f05cSChris Mason 		wret = push_node_left(trans, root, left_buf, mid_buf);
40079f95c82SChris Mason 		if (wret < 0)
40179f95c82SChris Mason 			ret = wret;
40254aa1f4dSChris Mason 		if (btrfs_header_nritems(&mid->header) < 2)
40354aa1f4dSChris Mason 			err_on_enospc = 1;
404bb803951SChris Mason 	}
40579f95c82SChris Mason 
40679f95c82SChris Mason 	/*
40779f95c82SChris Mason 	 * then try to empty the right most buffer into the middle
40879f95c82SChris Mason 	 */
409bb803951SChris Mason 	if (right_buf) {
41054aa1f4dSChris Mason 		wret = btrfs_cow_block(trans, root, right_buf,
41154aa1f4dSChris Mason 				       parent_buf, pslot + 1, &right_buf);
41254aa1f4dSChris Mason 		if (wret) {
41354aa1f4dSChris Mason 			ret = wret;
41454aa1f4dSChris Mason 			goto enospc;
41554aa1f4dSChris Mason 		}
41654aa1f4dSChris Mason 
417e20d96d6SChris Mason 		right = btrfs_buffer_node(right_buf);
418e089f05cSChris Mason 		wret = push_node_left(trans, root, mid_buf, right_buf);
41954aa1f4dSChris Mason 		if (wret < 0 && wret != -ENOSPC)
42079f95c82SChris Mason 			ret = wret;
4217518a238SChris Mason 		if (btrfs_header_nritems(&right->header) == 0) {
4227eccb903SChris Mason 			u64 blocknr = bh_blocknr(right_buf);
423e089f05cSChris Mason 			clean_tree_block(trans, root, right_buf);
424d6025579SChris Mason 			wait_on_buffer(right_buf);
425d6025579SChris Mason 			btrfs_block_release(root, right_buf);
426bb803951SChris Mason 			right_buf = NULL;
427bb803951SChris Mason 			right = NULL;
428e089f05cSChris Mason 			wret = del_ptr(trans, root, path, level + 1, pslot +
429e089f05cSChris Mason 				       1);
430bb803951SChris Mason 			if (wret)
431bb803951SChris Mason 				ret = wret;
432e089f05cSChris Mason 			wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
433bb803951SChris Mason 			if (wret)
434bb803951SChris Mason 				ret = wret;
435bb803951SChris Mason 		} else {
436d6025579SChris Mason 			btrfs_memcpy(root, parent,
437d6025579SChris Mason 				     &parent->ptrs[pslot + 1].key,
438123abc88SChris Mason 				     &right->ptrs[0].key,
439e2fa7227SChris Mason 				     sizeof(struct btrfs_disk_key));
440d6025579SChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
441bb803951SChris Mason 		}
442bb803951SChris Mason 	}
4437518a238SChris Mason 	if (btrfs_header_nritems(&mid->header) == 1) {
44479f95c82SChris Mason 		/*
44579f95c82SChris Mason 		 * we're not allowed to leave a node with one item in the
44679f95c82SChris Mason 		 * tree during a delete.  A deletion from lower in the tree
44779f95c82SChris Mason 		 * could try to delete the only pointer in this node.
44879f95c82SChris Mason 		 * So, pull some keys from the left.
44979f95c82SChris Mason 		 * There has to be a left pointer at this point because
45079f95c82SChris Mason 		 * otherwise we would have pulled some pointers from the
45179f95c82SChris Mason 		 * right
45279f95c82SChris Mason 		 */
45379f95c82SChris Mason 		BUG_ON(!left_buf);
454e089f05cSChris Mason 		wret = balance_node_right(trans, root, mid_buf, left_buf);
45554aa1f4dSChris Mason 		if (wret < 0) {
45679f95c82SChris Mason 			ret = wret;
45754aa1f4dSChris Mason 			goto enospc;
45854aa1f4dSChris Mason 		}
45979f95c82SChris Mason 		BUG_ON(wret == 1);
46079f95c82SChris Mason 	}
4617518a238SChris Mason 	if (btrfs_header_nritems(&mid->header) == 0) {
46279f95c82SChris Mason 		/* we've managed to empty the middle node, drop it */
4637eccb903SChris Mason 		u64 blocknr = bh_blocknr(mid_buf);
464e089f05cSChris Mason 		clean_tree_block(trans, root, mid_buf);
465d6025579SChris Mason 		wait_on_buffer(mid_buf);
466d6025579SChris Mason 		btrfs_block_release(root, mid_buf);
467bb803951SChris Mason 		mid_buf = NULL;
468bb803951SChris Mason 		mid = NULL;
469e089f05cSChris Mason 		wret = del_ptr(trans, root, path, level + 1, pslot);
470bb803951SChris Mason 		if (wret)
471bb803951SChris Mason 			ret = wret;
472e089f05cSChris Mason 		wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
473bb803951SChris Mason 		if (wret)
474bb803951SChris Mason 			ret = wret;
47579f95c82SChris Mason 	} else {
47679f95c82SChris Mason 		/* update the parent key to reflect our changes */
477d6025579SChris Mason 		btrfs_memcpy(root, parent,
478d6025579SChris Mason 			     &parent->ptrs[pslot].key, &mid->ptrs[0].key,
479e2fa7227SChris Mason 			     sizeof(struct btrfs_disk_key));
480d6025579SChris Mason 		btrfs_mark_buffer_dirty(parent_buf);
48179f95c82SChris Mason 	}
482bb803951SChris Mason 
48379f95c82SChris Mason 	/* update the path */
484bb803951SChris Mason 	if (left_buf) {
4857518a238SChris Mason 		if (btrfs_header_nritems(&left->header) > orig_slot) {
486e20d96d6SChris Mason 			get_bh(left_buf);
487bb803951SChris Mason 			path->nodes[level] = left_buf;
488bb803951SChris Mason 			path->slots[level + 1] -= 1;
489bb803951SChris Mason 			path->slots[level] = orig_slot;
490bb803951SChris Mason 			if (mid_buf)
491234b63a0SChris Mason 				btrfs_block_release(root, mid_buf);
492bb803951SChris Mason 		} else {
4937518a238SChris Mason 			orig_slot -= btrfs_header_nritems(&left->header);
494bb803951SChris Mason 			path->slots[level] = orig_slot;
495bb803951SChris Mason 		}
496bb803951SChris Mason 	}
49779f95c82SChris Mason 	/* double check we haven't messed things up */
498123abc88SChris Mason 	check_block(root, path, level);
499e20d96d6SChris Mason 	if (orig_ptr !=
500e20d96d6SChris Mason 	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
5011d4f8a0cSChris Mason 				path->slots[level]))
50279f95c82SChris Mason 		BUG();
50354aa1f4dSChris Mason enospc:
504bb803951SChris Mason 	if (right_buf)
505234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
506bb803951SChris Mason 	if (left_buf)
507234b63a0SChris Mason 		btrfs_block_release(root, left_buf);
508bb803951SChris Mason 	return ret;
509bb803951SChris Mason }
510bb803951SChris Mason 
511e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */
512e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
513e66f709bSChris Mason 				struct btrfs_root *root,
514e66f709bSChris Mason 				struct btrfs_path *path, int level)
515e66f709bSChris Mason {
516e66f709bSChris Mason 	struct buffer_head *right_buf;
517e66f709bSChris Mason 	struct buffer_head *mid_buf;
518e66f709bSChris Mason 	struct buffer_head *left_buf;
519e66f709bSChris Mason 	struct buffer_head *parent_buf = NULL;
520e66f709bSChris Mason 	struct btrfs_node *right = NULL;
521e66f709bSChris Mason 	struct btrfs_node *mid;
522e66f709bSChris Mason 	struct btrfs_node *left = NULL;
523e66f709bSChris Mason 	struct btrfs_node *parent = NULL;
524e66f709bSChris Mason 	int ret = 0;
525e66f709bSChris Mason 	int wret;
526e66f709bSChris Mason 	int pslot;
527e66f709bSChris Mason 	int orig_slot = path->slots[level];
528e66f709bSChris Mason 	u64 orig_ptr;
529e66f709bSChris Mason 
530e66f709bSChris Mason 	if (level == 0)
531e66f709bSChris Mason 		return 1;
532e66f709bSChris Mason 
533e66f709bSChris Mason 	mid_buf = path->nodes[level];
534e66f709bSChris Mason 	mid = btrfs_buffer_node(mid_buf);
535e66f709bSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
536e66f709bSChris Mason 
537e66f709bSChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
538e66f709bSChris Mason 		parent_buf = path->nodes[level + 1];
539e66f709bSChris Mason 	pslot = path->slots[level + 1];
540e66f709bSChris Mason 
541e66f709bSChris Mason 	if (!parent_buf)
542e66f709bSChris Mason 		return 1;
543e66f709bSChris Mason 	parent = btrfs_buffer_node(parent_buf);
544e66f709bSChris Mason 
545e66f709bSChris Mason 	left_buf = read_node_slot(root, parent_buf, pslot - 1);
546e66f709bSChris Mason 
547e66f709bSChris Mason 	/* first, try to make some room in the middle buffer */
548e66f709bSChris Mason 	if (left_buf) {
549e66f709bSChris Mason 		u32 left_nr;
550e66f709bSChris Mason 		left = btrfs_buffer_node(left_buf);
551e66f709bSChris Mason 		left_nr = btrfs_header_nritems(&left->header);
55233ade1f8SChris Mason 		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
55333ade1f8SChris Mason 			wret = 1;
55433ade1f8SChris Mason 		} else {
55554aa1f4dSChris Mason 			ret = btrfs_cow_block(trans, root, left_buf, parent_buf,
55633ade1f8SChris Mason 					      pslot - 1, &left_buf);
55754aa1f4dSChris Mason 			if (ret)
55854aa1f4dSChris Mason 				wret = 1;
55954aa1f4dSChris Mason 			else {
56033ade1f8SChris Mason 				left = btrfs_buffer_node(left_buf);
56154aa1f4dSChris Mason 				wret = push_node_left(trans, root,
56254aa1f4dSChris Mason 						      left_buf, mid_buf);
56354aa1f4dSChris Mason 			}
56433ade1f8SChris Mason 		}
565e66f709bSChris Mason 		if (wret < 0)
566e66f709bSChris Mason 			ret = wret;
567e66f709bSChris Mason 		if (wret == 0) {
568e66f709bSChris Mason 			orig_slot += left_nr;
569e66f709bSChris Mason 			btrfs_memcpy(root, parent,
570e66f709bSChris Mason 				     &parent->ptrs[pslot].key,
571e66f709bSChris Mason 				     &mid->ptrs[0].key,
572e66f709bSChris Mason 				     sizeof(struct btrfs_disk_key));
573e66f709bSChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
574e66f709bSChris Mason 			if (btrfs_header_nritems(&left->header) > orig_slot) {
575e66f709bSChris Mason 				path->nodes[level] = left_buf;
576e66f709bSChris Mason 				path->slots[level + 1] -= 1;
577e66f709bSChris Mason 				path->slots[level] = orig_slot;
578e66f709bSChris Mason 				btrfs_block_release(root, mid_buf);
579e66f709bSChris Mason 			} else {
580e66f709bSChris Mason 				orig_slot -=
581e66f709bSChris Mason 					btrfs_header_nritems(&left->header);
582e66f709bSChris Mason 				path->slots[level] = orig_slot;
583e66f709bSChris Mason 				btrfs_block_release(root, left_buf);
584e66f709bSChris Mason 			}
585e66f709bSChris Mason 			check_node(root, path, level);
586e66f709bSChris Mason 			return 0;
587e66f709bSChris Mason 		}
588e66f709bSChris Mason 		btrfs_block_release(root, left_buf);
589e66f709bSChris Mason 	}
590e66f709bSChris Mason 	right_buf = read_node_slot(root, parent_buf, pslot + 1);
591e66f709bSChris Mason 
592e66f709bSChris Mason 	/*
593e66f709bSChris Mason 	 * then try to empty the right most buffer into the middle
594e66f709bSChris Mason 	 */
595e66f709bSChris Mason 	if (right_buf) {
59633ade1f8SChris Mason 		u32 right_nr;
597e66f709bSChris Mason 		right = btrfs_buffer_node(right_buf);
59833ade1f8SChris Mason 		right_nr = btrfs_header_nritems(&right->header);
59933ade1f8SChris Mason 		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
60033ade1f8SChris Mason 			wret = 1;
60133ade1f8SChris Mason 		} else {
60254aa1f4dSChris Mason 			ret = btrfs_cow_block(trans, root, right_buf,
60354aa1f4dSChris Mason 					      parent_buf, pslot + 1,
60454aa1f4dSChris Mason 					      &right_buf);
60554aa1f4dSChris Mason 			if (ret)
60654aa1f4dSChris Mason 				wret = 1;
60754aa1f4dSChris Mason 			else {
60833ade1f8SChris Mason 				right = btrfs_buffer_node(right_buf);
60933ade1f8SChris Mason 				wret = balance_node_right(trans, root,
61033ade1f8SChris Mason 							  right_buf, mid_buf);
61133ade1f8SChris Mason 			}
61254aa1f4dSChris Mason 		}
613e66f709bSChris Mason 		if (wret < 0)
614e66f709bSChris Mason 			ret = wret;
615e66f709bSChris Mason 		if (wret == 0) {
616e66f709bSChris Mason 			btrfs_memcpy(root, parent,
617e66f709bSChris Mason 				     &parent->ptrs[pslot + 1].key,
618e66f709bSChris Mason 				     &right->ptrs[0].key,
619e66f709bSChris Mason 				     sizeof(struct btrfs_disk_key));
620e66f709bSChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
621e66f709bSChris Mason 			if (btrfs_header_nritems(&mid->header) <= orig_slot) {
622e66f709bSChris Mason 				path->nodes[level] = right_buf;
623e66f709bSChris Mason 				path->slots[level + 1] += 1;
624e66f709bSChris Mason 				path->slots[level] = orig_slot -
625e66f709bSChris Mason 					btrfs_header_nritems(&mid->header);
626e66f709bSChris Mason 				btrfs_block_release(root, mid_buf);
627e66f709bSChris Mason 			} else {
628e66f709bSChris Mason 				btrfs_block_release(root, right_buf);
629e66f709bSChris Mason 			}
630e66f709bSChris Mason 			check_node(root, path, level);
631e66f709bSChris Mason 			return 0;
632e66f709bSChris Mason 		}
633e66f709bSChris Mason 		btrfs_block_release(root, right_buf);
634e66f709bSChris Mason 	}
635e66f709bSChris Mason 	check_node(root, path, level);
636e66f709bSChris Mason 	return 1;
637e66f709bSChris Mason }
638e66f709bSChris Mason 
63974123bd7SChris Mason /*
64074123bd7SChris Mason  * look for key in the tree.  path is filled in with nodes along the way
64174123bd7SChris Mason  * if key is found, we return zero and you can find the item in the leaf
64274123bd7SChris Mason  * level of the path (level 0)
64374123bd7SChris Mason  *
64474123bd7SChris Mason  * If the key isn't found, the path points to the slot where it should
645aa5d6bedSChris Mason  * be inserted, and 1 is returned.  If there are other errors during the
646aa5d6bedSChris Mason  * search a negative error number is returned.
64797571fd0SChris Mason  *
64897571fd0SChris Mason  * if ins_len > 0, nodes and leaves will be split as we walk down the
64997571fd0SChris Mason  * tree.  if ins_len < 0, nodes will be merged as we walk down the tree (if
65097571fd0SChris Mason  * possible)
65174123bd7SChris Mason  */
652e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
653e089f05cSChris Mason 		      *root, struct btrfs_key *key, struct btrfs_path *p, int
654e089f05cSChris Mason 		      ins_len, int cow)
655be0e5c09SChris Mason {
656e20d96d6SChris Mason 	struct buffer_head *b;
657e20d96d6SChris Mason 	struct buffer_head *cow_buf;
658234b63a0SChris Mason 	struct btrfs_node *c;
659be0e5c09SChris Mason 	int slot;
660be0e5c09SChris Mason 	int ret;
661be0e5c09SChris Mason 	int level;
6625c680ed6SChris Mason 
66322b0ebdaSChris Mason 	WARN_ON(p->nodes[0] != NULL);
66422b0ebdaSChris Mason 	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
665bb803951SChris Mason again:
666bb803951SChris Mason 	b = root->node;
667e20d96d6SChris Mason 	get_bh(b);
668eb60ceacSChris Mason 	while (b) {
669e20d96d6SChris Mason 		c = btrfs_buffer_node(b);
670e20d96d6SChris Mason 		level = btrfs_header_level(&c->header);
67102217ed2SChris Mason 		if (cow) {
67202217ed2SChris Mason 			int wret;
673e20d96d6SChris Mason 			wret = btrfs_cow_block(trans, root, b,
674e20d96d6SChris Mason 					       p->nodes[level + 1],
675e20d96d6SChris Mason 					       p->slots[level + 1],
676e089f05cSChris Mason 					       &cow_buf);
67754aa1f4dSChris Mason 			if (wret) {
67854aa1f4dSChris Mason 				btrfs_block_release(root, cow_buf);
67954aa1f4dSChris Mason 				return wret;
68054aa1f4dSChris Mason 			}
68102217ed2SChris Mason 			b = cow_buf;
6822c90e5d6SChris Mason 			c = btrfs_buffer_node(b);
68302217ed2SChris Mason 		}
68402217ed2SChris Mason 		BUG_ON(!cow && ins_len);
6852c90e5d6SChris Mason 		if (level != btrfs_header_level(&c->header))
6862c90e5d6SChris Mason 			WARN_ON(1);
6872c90e5d6SChris Mason 		level = btrfs_header_level(&c->header);
688eb60ceacSChris Mason 		p->nodes[level] = b;
689123abc88SChris Mason 		ret = check_block(root, p, level);
690aa5d6bedSChris Mason 		if (ret)
691aa5d6bedSChris Mason 			return -1;
692be0e5c09SChris Mason 		ret = bin_search(c, key, &slot);
6937518a238SChris Mason 		if (!btrfs_is_leaf(c)) {
694be0e5c09SChris Mason 			if (ret && slot > 0)
695be0e5c09SChris Mason 				slot -= 1;
696be0e5c09SChris Mason 			p->slots[level] = slot;
697d4dbff95SChris Mason 			if (ins_len > 0 && btrfs_header_nritems(&c->header) >=
698d4dbff95SChris Mason 			    BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
699e089f05cSChris Mason 				int sret = split_node(trans, root, p, level);
7005c680ed6SChris Mason 				BUG_ON(sret > 0);
7015c680ed6SChris Mason 				if (sret)
7025c680ed6SChris Mason 					return sret;
7035c680ed6SChris Mason 				b = p->nodes[level];
704e20d96d6SChris Mason 				c = btrfs_buffer_node(b);
7055c680ed6SChris Mason 				slot = p->slots[level];
706bb803951SChris Mason 			} else if (ins_len < 0) {
707e089f05cSChris Mason 				int sret = balance_level(trans, root, p,
708e089f05cSChris Mason 							 level);
709bb803951SChris Mason 				if (sret)
710bb803951SChris Mason 					return sret;
711bb803951SChris Mason 				b = p->nodes[level];
712bb803951SChris Mason 				if (!b)
713bb803951SChris Mason 					goto again;
714e20d96d6SChris Mason 				c = btrfs_buffer_node(b);
715bb803951SChris Mason 				slot = p->slots[level];
7167518a238SChris Mason 				BUG_ON(btrfs_header_nritems(&c->header) == 1);
7175c680ed6SChris Mason 			}
7181d4f8a0cSChris Mason 			b = read_tree_block(root, btrfs_node_blockptr(c, slot));
719be0e5c09SChris Mason 		} else {
720234b63a0SChris Mason 			struct btrfs_leaf *l = (struct btrfs_leaf *)c;
721be0e5c09SChris Mason 			p->slots[level] = slot;
722123abc88SChris Mason 			if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
7230783fcfcSChris Mason 			    sizeof(struct btrfs_item) + ins_len) {
724d4dbff95SChris Mason 				int sret = split_leaf(trans, root, key,
725d4dbff95SChris Mason 						      p, ins_len);
7265c680ed6SChris Mason 				BUG_ON(sret > 0);
7275c680ed6SChris Mason 				if (sret)
7285c680ed6SChris Mason 					return sret;
7295c680ed6SChris Mason 			}
730be0e5c09SChris Mason 			return ret;
731be0e5c09SChris Mason 		}
732be0e5c09SChris Mason 	}
733aa5d6bedSChris Mason 	return 1;
734be0e5c09SChris Mason }
735be0e5c09SChris Mason 
73674123bd7SChris Mason /*
73774123bd7SChris Mason  * adjust the pointers going up the tree, starting at level
73874123bd7SChris Mason  * making sure the right key of each node is points to 'key'.
73974123bd7SChris Mason  * This is used after shifting pointers to the left, so it stops
74074123bd7SChris Mason  * fixing up pointers when a given leaf/node is not in slot 0 of the
74174123bd7SChris Mason  * higher levels
742aa5d6bedSChris Mason  *
743aa5d6bedSChris Mason  * If this fails to write a tree block, it returns -1, but continues
744aa5d6bedSChris Mason  * fixing up the blocks in ram so the tree is consistent.
74574123bd7SChris Mason  */
746e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
747e089f05cSChris Mason 			  *root, struct btrfs_path *path, struct btrfs_disk_key
748e089f05cSChris Mason 			  *key, int level)
749be0e5c09SChris Mason {
750be0e5c09SChris Mason 	int i;
751aa5d6bedSChris Mason 	int ret = 0;
752234b63a0SChris Mason 	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
753234b63a0SChris Mason 		struct btrfs_node *t;
754be0e5c09SChris Mason 		int tslot = path->slots[i];
755eb60ceacSChris Mason 		if (!path->nodes[i])
756be0e5c09SChris Mason 			break;
757e20d96d6SChris Mason 		t = btrfs_buffer_node(path->nodes[i]);
758d6025579SChris Mason 		btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key));
759d6025579SChris Mason 		btrfs_mark_buffer_dirty(path->nodes[i]);
760be0e5c09SChris Mason 		if (tslot != 0)
761be0e5c09SChris Mason 			break;
762be0e5c09SChris Mason 	}
763aa5d6bedSChris Mason 	return ret;
764be0e5c09SChris Mason }
765be0e5c09SChris Mason 
76674123bd7SChris Mason /*
76774123bd7SChris Mason  * try to push data from one node into the next node left in the
76879f95c82SChris Mason  * tree.
769aa5d6bedSChris Mason  *
770aa5d6bedSChris Mason  * returns 0 if some ptrs were pushed left, < 0 if there was some horrible
771aa5d6bedSChris Mason  * error, and > 0 if there was no room in the left hand block.
77274123bd7SChris Mason  */
773e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
774e20d96d6SChris Mason 			  *root, struct buffer_head *dst_buf, struct
775e20d96d6SChris Mason 			  buffer_head *src_buf)
776be0e5c09SChris Mason {
777e20d96d6SChris Mason 	struct btrfs_node *src = btrfs_buffer_node(src_buf);
778e20d96d6SChris Mason 	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
779be0e5c09SChris Mason 	int push_items = 0;
780bb803951SChris Mason 	int src_nritems;
781bb803951SChris Mason 	int dst_nritems;
782aa5d6bedSChris Mason 	int ret = 0;
783be0e5c09SChris Mason 
7847518a238SChris Mason 	src_nritems = btrfs_header_nritems(&src->header);
7857518a238SChris Mason 	dst_nritems = btrfs_header_nritems(&dst->header);
786123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
78754aa1f4dSChris Mason 
788eb60ceacSChris Mason 	if (push_items <= 0) {
789be0e5c09SChris Mason 		return 1;
790eb60ceacSChris Mason 	}
791be0e5c09SChris Mason 
792be0e5c09SChris Mason 	if (src_nritems < push_items)
793be0e5c09SChris Mason 		push_items = src_nritems;
79479f95c82SChris Mason 
795d6025579SChris Mason 	btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs,
796123abc88SChris Mason 		     push_items * sizeof(struct btrfs_key_ptr));
797bb803951SChris Mason 	if (push_items < src_nritems) {
798d6025579SChris Mason 		btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items,
799e2fa7227SChris Mason 			(src_nritems - push_items) *
800123abc88SChris Mason 			sizeof(struct btrfs_key_ptr));
801bb803951SChris Mason 	}
8027518a238SChris Mason 	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
8037518a238SChris Mason 	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
804d6025579SChris Mason 	btrfs_mark_buffer_dirty(src_buf);
805d6025579SChris Mason 	btrfs_mark_buffer_dirty(dst_buf);
806bb803951SChris Mason 	return ret;
807be0e5c09SChris Mason }
808be0e5c09SChris Mason 
80997571fd0SChris Mason /*
81079f95c82SChris Mason  * try to push data from one node into the next node right in the
81179f95c82SChris Mason  * tree.
81279f95c82SChris Mason  *
81379f95c82SChris Mason  * returns 0 if some ptrs were pushed, < 0 if there was some horrible
81479f95c82SChris Mason  * error, and > 0 if there was no room in the right hand block.
81579f95c82SChris Mason  *
81679f95c82SChris Mason  * this will  only push up to 1/2 the contents of the left node over
81779f95c82SChris Mason  */
818e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct
819e20d96d6SChris Mason 			      btrfs_root *root, struct buffer_head *dst_buf,
820e20d96d6SChris Mason 			      struct buffer_head *src_buf)
82179f95c82SChris Mason {
822e20d96d6SChris Mason 	struct btrfs_node *src = btrfs_buffer_node(src_buf);
823e20d96d6SChris Mason 	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
82479f95c82SChris Mason 	int push_items = 0;
82579f95c82SChris Mason 	int max_push;
82679f95c82SChris Mason 	int src_nritems;
82779f95c82SChris Mason 	int dst_nritems;
82879f95c82SChris Mason 	int ret = 0;
82979f95c82SChris Mason 
8307518a238SChris Mason 	src_nritems = btrfs_header_nritems(&src->header);
8317518a238SChris Mason 	dst_nritems = btrfs_header_nritems(&dst->header);
832123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
83379f95c82SChris Mason 	if (push_items <= 0) {
83479f95c82SChris Mason 		return 1;
83579f95c82SChris Mason 	}
83679f95c82SChris Mason 
83779f95c82SChris Mason 	max_push = src_nritems / 2 + 1;
83879f95c82SChris Mason 	/* don't try to empty the node */
83979f95c82SChris Mason 	if (max_push > src_nritems)
84079f95c82SChris Mason 		return 1;
84179f95c82SChris Mason 	if (max_push < push_items)
84279f95c82SChris Mason 		push_items = max_push;
84379f95c82SChris Mason 
844d6025579SChris Mason 	btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs,
845123abc88SChris Mason 		      dst_nritems * sizeof(struct btrfs_key_ptr));
846d6025579SChris Mason 
847d6025579SChris Mason 	btrfs_memcpy(root, dst, dst->ptrs,
848d6025579SChris Mason 		     src->ptrs + src_nritems - push_items,
849123abc88SChris Mason 		     push_items * sizeof(struct btrfs_key_ptr));
85079f95c82SChris Mason 
8517518a238SChris Mason 	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
8527518a238SChris Mason 	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
85379f95c82SChris Mason 
854d6025579SChris Mason 	btrfs_mark_buffer_dirty(src_buf);
855d6025579SChris Mason 	btrfs_mark_buffer_dirty(dst_buf);
85679f95c82SChris Mason 	return ret;
85779f95c82SChris Mason }
85879f95c82SChris Mason 
85979f95c82SChris Mason /*
86097571fd0SChris Mason  * helper function to insert a new root level in the tree.
86197571fd0SChris Mason  * A new node is allocated, and a single item is inserted to
86297571fd0SChris Mason  * point to the existing root
863aa5d6bedSChris Mason  *
864aa5d6bedSChris Mason  * returns zero on success or < 0 on failure.
86597571fd0SChris Mason  */
866e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
867e089f05cSChris Mason 			   *root, struct btrfs_path *path, int level)
86874123bd7SChris Mason {
869e20d96d6SChris Mason 	struct buffer_head *t;
870234b63a0SChris Mason 	struct btrfs_node *lower;
871234b63a0SChris Mason 	struct btrfs_node *c;
872e2fa7227SChris Mason 	struct btrfs_disk_key *lower_key;
8735c680ed6SChris Mason 
8745c680ed6SChris Mason 	BUG_ON(path->nodes[level]);
8755c680ed6SChris Mason 	BUG_ON(path->nodes[level-1] != root->node);
8765c680ed6SChris Mason 
87731f3c99bSChris Mason 	t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr);
87854aa1f4dSChris Mason 	if (IS_ERR(t))
87954aa1f4dSChris Mason 		return PTR_ERR(t);
880e20d96d6SChris Mason 	c = btrfs_buffer_node(t);
881123abc88SChris Mason 	memset(c, 0, root->blocksize);
8827518a238SChris Mason 	btrfs_set_header_nritems(&c->header, 1);
8837518a238SChris Mason 	btrfs_set_header_level(&c->header, level);
8847eccb903SChris Mason 	btrfs_set_header_blocknr(&c->header, bh_blocknr(t));
8857f5c1516SChris Mason 	btrfs_set_header_generation(&c->header, trans->transid);
8864d775673SChris Mason 	btrfs_set_header_owner(&c->header, root->root_key.objectid);
887e20d96d6SChris Mason 	lower = btrfs_buffer_node(path->nodes[level-1]);
8883eb0314dSChris Mason 	memcpy(c->header.fsid, root->fs_info->disk_super->fsid,
8893eb0314dSChris Mason 	       sizeof(c->header.fsid));
8907518a238SChris Mason 	if (btrfs_is_leaf(lower))
891234b63a0SChris Mason 		lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
89274123bd7SChris Mason 	else
893123abc88SChris Mason 		lower_key = &lower->ptrs[0].key;
894d6025579SChris Mason 	btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key,
895d6025579SChris Mason 		     sizeof(struct btrfs_disk_key));
8967eccb903SChris Mason 	btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1]));
897d5719762SChris Mason 
898d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
899d5719762SChris Mason 
900cfaa7295SChris Mason 	/* the super has an extra ref to root->node */
901234b63a0SChris Mason 	btrfs_block_release(root, root->node);
90274123bd7SChris Mason 	root->node = t;
903e20d96d6SChris Mason 	get_bh(t);
90474123bd7SChris Mason 	path->nodes[level] = t;
90574123bd7SChris Mason 	path->slots[level] = 0;
90674123bd7SChris Mason 	return 0;
90774123bd7SChris Mason }
9085c680ed6SChris Mason 
9095c680ed6SChris Mason /*
9105c680ed6SChris Mason  * worker function to insert a single pointer in a node.
9115c680ed6SChris Mason  * the node should have enough room for the pointer already
91297571fd0SChris Mason  *
9135c680ed6SChris Mason  * slot and level indicate where you want the key to go, and
9145c680ed6SChris Mason  * blocknr is the block the key points to.
915aa5d6bedSChris Mason  *
916aa5d6bedSChris Mason  * returns zero on success and < 0 on any error
9175c680ed6SChris Mason  */
918e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
919e089f05cSChris Mason 		      *root, struct btrfs_path *path, struct btrfs_disk_key
920e089f05cSChris Mason 		      *key, u64 blocknr, int slot, int level)
9215c680ed6SChris Mason {
922234b63a0SChris Mason 	struct btrfs_node *lower;
9235c680ed6SChris Mason 	int nritems;
9245c680ed6SChris Mason 
9255c680ed6SChris Mason 	BUG_ON(!path->nodes[level]);
926e20d96d6SChris Mason 	lower = btrfs_buffer_node(path->nodes[level]);
9277518a238SChris Mason 	nritems = btrfs_header_nritems(&lower->header);
92874123bd7SChris Mason 	if (slot > nritems)
92974123bd7SChris Mason 		BUG();
930123abc88SChris Mason 	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
93174123bd7SChris Mason 		BUG();
93274123bd7SChris Mason 	if (slot != nritems) {
933d6025579SChris Mason 		btrfs_memmove(root, lower, lower->ptrs + slot + 1,
934d6025579SChris Mason 			      lower->ptrs + slot,
935123abc88SChris Mason 			      (nritems - slot) * sizeof(struct btrfs_key_ptr));
93674123bd7SChris Mason 	}
937d6025579SChris Mason 	btrfs_memcpy(root, lower, &lower->ptrs[slot].key,
938d6025579SChris Mason 		     key, sizeof(struct btrfs_disk_key));
9391d4f8a0cSChris Mason 	btrfs_set_node_blockptr(lower, slot, blocknr);
9407518a238SChris Mason 	btrfs_set_header_nritems(&lower->header, nritems + 1);
941d6025579SChris Mason 	btrfs_mark_buffer_dirty(path->nodes[level]);
942098f59c2SChris Mason 	check_node(root, path, level);
94374123bd7SChris Mason 	return 0;
94474123bd7SChris Mason }
94574123bd7SChris Mason 
94697571fd0SChris Mason /*
94797571fd0SChris Mason  * split the node at the specified level in path in two.
94897571fd0SChris Mason  * The path is corrected to point to the appropriate node after the split
94997571fd0SChris Mason  *
95097571fd0SChris Mason  * Before splitting this tries to make some room in the node by pushing
95197571fd0SChris Mason  * left and right, if either one works, it returns right away.
952aa5d6bedSChris Mason  *
953aa5d6bedSChris Mason  * returns 0 on success and < 0 on failure
95497571fd0SChris Mason  */
955e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
956e089f05cSChris Mason 		      *root, struct btrfs_path *path, int level)
957be0e5c09SChris Mason {
958e20d96d6SChris Mason 	struct buffer_head *t;
959234b63a0SChris Mason 	struct btrfs_node *c;
960e20d96d6SChris Mason 	struct buffer_head *split_buffer;
961234b63a0SChris Mason 	struct btrfs_node *split;
962be0e5c09SChris Mason 	int mid;
9635c680ed6SChris Mason 	int ret;
964aa5d6bedSChris Mason 	int wret;
9657518a238SChris Mason 	u32 c_nritems;
966be0e5c09SChris Mason 
9675c680ed6SChris Mason 	t = path->nodes[level];
968e20d96d6SChris Mason 	c = btrfs_buffer_node(t);
9695c680ed6SChris Mason 	if (t == root->node) {
9705c680ed6SChris Mason 		/* trying to split the root, lets make a new one */
971e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, level + 1);
9725c680ed6SChris Mason 		if (ret)
9735c680ed6SChris Mason 			return ret;
974e66f709bSChris Mason 	} else {
975e66f709bSChris Mason 		ret = push_nodes_for_insert(trans, root, path, level);
976e66f709bSChris Mason 		t = path->nodes[level];
977e66f709bSChris Mason 		c = btrfs_buffer_node(t);
978e66f709bSChris Mason 		if (!ret &&
979e66f709bSChris Mason 		    btrfs_header_nritems(&c->header) <
980e66f709bSChris Mason 		    BTRFS_NODEPTRS_PER_BLOCK(root) - 1)
981e66f709bSChris Mason 			return 0;
98254aa1f4dSChris Mason 		if (ret < 0)
98354aa1f4dSChris Mason 			return ret;
9845c680ed6SChris Mason 	}
985e66f709bSChris Mason 
9867518a238SChris Mason 	c_nritems = btrfs_header_nritems(&c->header);
98731f3c99bSChris Mason 	split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr);
98854aa1f4dSChris Mason 	if (IS_ERR(split_buffer))
98954aa1f4dSChris Mason 		return PTR_ERR(split_buffer);
99054aa1f4dSChris Mason 
991e20d96d6SChris Mason 	split = btrfs_buffer_node(split_buffer);
9927518a238SChris Mason 	btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
9939a6f11edSChris Mason 	btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
9947eccb903SChris Mason 	btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer));
9957f5c1516SChris Mason 	btrfs_set_header_generation(&split->header, trans->transid);
9964d775673SChris Mason 	btrfs_set_header_owner(&split->header, root->root_key.objectid);
9973eb0314dSChris Mason 	memcpy(split->header.fsid, root->fs_info->disk_super->fsid,
9983eb0314dSChris Mason 	       sizeof(split->header.fsid));
9997518a238SChris Mason 	mid = (c_nritems + 1) / 2;
1000d6025579SChris Mason 	btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid,
1001123abc88SChris Mason 		     (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
10027518a238SChris Mason 	btrfs_set_header_nritems(&split->header, c_nritems - mid);
10037518a238SChris Mason 	btrfs_set_header_nritems(&c->header, mid);
1004aa5d6bedSChris Mason 	ret = 0;
1005aa5d6bedSChris Mason 
1006d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
1007d6025579SChris Mason 	btrfs_mark_buffer_dirty(split_buffer);
1008e089f05cSChris Mason 	wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
10097eccb903SChris Mason 			  bh_blocknr(split_buffer), path->slots[level + 1] + 1,
1010123abc88SChris Mason 			  level + 1);
1011aa5d6bedSChris Mason 	if (wret)
1012aa5d6bedSChris Mason 		ret = wret;
1013aa5d6bedSChris Mason 
10145de08d7dSChris Mason 	if (path->slots[level] >= mid) {
10155c680ed6SChris Mason 		path->slots[level] -= mid;
1016234b63a0SChris Mason 		btrfs_block_release(root, t);
10175c680ed6SChris Mason 		path->nodes[level] = split_buffer;
10185c680ed6SChris Mason 		path->slots[level + 1] += 1;
1019eb60ceacSChris Mason 	} else {
1020234b63a0SChris Mason 		btrfs_block_release(root, split_buffer);
1021be0e5c09SChris Mason 	}
1022aa5d6bedSChris Mason 	return ret;
1023be0e5c09SChris Mason }
1024be0e5c09SChris Mason 
102574123bd7SChris Mason /*
102674123bd7SChris Mason  * how many bytes are required to store the items in a leaf.  start
102774123bd7SChris Mason  * and nr indicate which items in the leaf to check.  This totals up the
102874123bd7SChris Mason  * space used both by the item structs and the item data
102974123bd7SChris Mason  */
1030234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
1031be0e5c09SChris Mason {
1032be0e5c09SChris Mason 	int data_len;
1033d4dbff95SChris Mason 	int nritems = btrfs_header_nritems(&l->header);
1034d4dbff95SChris Mason 	int end = min(nritems, start + nr) - 1;
1035be0e5c09SChris Mason 
1036be0e5c09SChris Mason 	if (!nr)
1037be0e5c09SChris Mason 		return 0;
10380783fcfcSChris Mason 	data_len = btrfs_item_end(l->items + start);
10390783fcfcSChris Mason 	data_len = data_len - btrfs_item_offset(l->items + end);
10400783fcfcSChris Mason 	data_len += sizeof(struct btrfs_item) * nr;
1041d4dbff95SChris Mason 	WARN_ON(data_len < 0);
1042be0e5c09SChris Mason 	return data_len;
1043be0e5c09SChris Mason }
1044be0e5c09SChris Mason 
104574123bd7SChris Mason /*
1046d4dbff95SChris Mason  * The space between the end of the leaf items and
1047d4dbff95SChris Mason  * the start of the leaf data.  IOW, how much room
1048d4dbff95SChris Mason  * the leaf has left for both items and data
1049d4dbff95SChris Mason  */
1050d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf)
1051d4dbff95SChris Mason {
1052d4dbff95SChris Mason 	int nritems = btrfs_header_nritems(&leaf->header);
1053d4dbff95SChris Mason 	return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems);
1054d4dbff95SChris Mason }
1055d4dbff95SChris Mason 
1056d4dbff95SChris Mason /*
105700ec4c51SChris Mason  * push some data in the path leaf to the right, trying to free up at
105800ec4c51SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
1059aa5d6bedSChris Mason  *
1060aa5d6bedSChris Mason  * returns 1 if the push failed because the other node didn't have enough
1061aa5d6bedSChris Mason  * room, 0 if everything worked out and < 0 if there were major errors.
106200ec4c51SChris Mason  */
1063e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
1064e089f05cSChris Mason 			   *root, struct btrfs_path *path, int data_size)
106500ec4c51SChris Mason {
1066e20d96d6SChris Mason 	struct buffer_head *left_buf = path->nodes[0];
1067e20d96d6SChris Mason 	struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf);
1068234b63a0SChris Mason 	struct btrfs_leaf *right;
1069e20d96d6SChris Mason 	struct buffer_head *right_buf;
1070e20d96d6SChris Mason 	struct buffer_head *upper;
1071e20d96d6SChris Mason 	struct btrfs_node *upper_node;
107200ec4c51SChris Mason 	int slot;
107300ec4c51SChris Mason 	int i;
107400ec4c51SChris Mason 	int free_space;
107500ec4c51SChris Mason 	int push_space = 0;
107600ec4c51SChris Mason 	int push_items = 0;
10770783fcfcSChris Mason 	struct btrfs_item *item;
10787518a238SChris Mason 	u32 left_nritems;
10797518a238SChris Mason 	u32 right_nritems;
108054aa1f4dSChris Mason 	int ret;
108100ec4c51SChris Mason 
108200ec4c51SChris Mason 	slot = path->slots[1];
108300ec4c51SChris Mason 	if (!path->nodes[1]) {
108400ec4c51SChris Mason 		return 1;
108500ec4c51SChris Mason 	}
108600ec4c51SChris Mason 	upper = path->nodes[1];
1087e20d96d6SChris Mason 	upper_node = btrfs_buffer_node(upper);
1088e20d96d6SChris Mason 	if (slot >= btrfs_header_nritems(&upper_node->header) - 1) {
108900ec4c51SChris Mason 		return 1;
109000ec4c51SChris Mason 	}
1091e20d96d6SChris Mason 	right_buf = read_tree_block(root,
1092e20d96d6SChris Mason 		    btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1));
1093e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buf);
1094123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
10950783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1096234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
109700ec4c51SChris Mason 		return 1;
109800ec4c51SChris Mason 	}
109902217ed2SChris Mason 	/* cow and double check */
110054aa1f4dSChris Mason 	ret = btrfs_cow_block(trans, root, right_buf, upper,
110154aa1f4dSChris Mason 			      slot + 1, &right_buf);
110254aa1f4dSChris Mason 	if (ret) {
110354aa1f4dSChris Mason 		btrfs_block_release(root, right_buf);
110454aa1f4dSChris Mason 		return 1;
110554aa1f4dSChris Mason 	}
1106e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buf);
1107123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
11080783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1109234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
111002217ed2SChris Mason 		return 1;
111102217ed2SChris Mason 	}
111202217ed2SChris Mason 
11137518a238SChris Mason 	left_nritems = btrfs_header_nritems(&left->header);
1114a429e513SChris Mason 	if (left_nritems == 0) {
1115a429e513SChris Mason 		btrfs_block_release(root, right_buf);
1116a429e513SChris Mason 		return 1;
1117a429e513SChris Mason 	}
1118a429e513SChris Mason 	for (i = left_nritems - 1; i >= 1; i--) {
111900ec4c51SChris Mason 		item = left->items + i;
112000ec4c51SChris Mason 		if (path->slots[0] == i)
112100ec4c51SChris Mason 			push_space += data_size + sizeof(*item);
11220783fcfcSChris Mason 		if (btrfs_item_size(item) + sizeof(*item) + push_space >
11230783fcfcSChris Mason 		    free_space)
112400ec4c51SChris Mason 			break;
112500ec4c51SChris Mason 		push_items++;
11260783fcfcSChris Mason 		push_space += btrfs_item_size(item) + sizeof(*item);
112700ec4c51SChris Mason 	}
112800ec4c51SChris Mason 	if (push_items == 0) {
1129234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
113000ec4c51SChris Mason 		return 1;
113100ec4c51SChris Mason 	}
1132a429e513SChris Mason 	if (push_items == left_nritems)
1133a429e513SChris Mason 		WARN_ON(1);
11347518a238SChris Mason 	right_nritems = btrfs_header_nritems(&right->header);
113500ec4c51SChris Mason 	/* push left to right */
11360783fcfcSChris Mason 	push_space = btrfs_item_end(left->items + left_nritems - push_items);
1137123abc88SChris Mason 	push_space -= leaf_data_end(root, left);
113800ec4c51SChris Mason 	/* make room in the right data area */
1139d6025579SChris Mason 	btrfs_memmove(root, right, btrfs_leaf_data(right) +
1140d6025579SChris Mason 		      leaf_data_end(root, right) - push_space,
1141d6025579SChris Mason 		      btrfs_leaf_data(right) +
1142d6025579SChris Mason 		      leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) -
1143d6025579SChris Mason 		      leaf_data_end(root, right));
114400ec4c51SChris Mason 	/* copy from the left data area */
1145d6025579SChris Mason 	btrfs_memcpy(root, right, btrfs_leaf_data(right) +
1146d6025579SChris Mason 		     BTRFS_LEAF_DATA_SIZE(root) - push_space,
1147d6025579SChris Mason 		     btrfs_leaf_data(left) + leaf_data_end(root, left),
1148d6025579SChris Mason 		     push_space);
1149d6025579SChris Mason 	btrfs_memmove(root, right, right->items + push_items, right->items,
11500783fcfcSChris Mason 		right_nritems * sizeof(struct btrfs_item));
115100ec4c51SChris Mason 	/* copy the items from left to right */
1152d6025579SChris Mason 	btrfs_memcpy(root, right, right->items, left->items +
1153d6025579SChris Mason 		     left_nritems - push_items,
11540783fcfcSChris Mason 		     push_items * sizeof(struct btrfs_item));
115500ec4c51SChris Mason 
115600ec4c51SChris Mason 	/* update the item pointers */
11577518a238SChris Mason 	right_nritems += push_items;
11587518a238SChris Mason 	btrfs_set_header_nritems(&right->header, right_nritems);
1159123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
11607518a238SChris Mason 	for (i = 0; i < right_nritems; i++) {
11610783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, push_space -
11620783fcfcSChris Mason 				      btrfs_item_size(right->items + i));
11630783fcfcSChris Mason 		push_space = btrfs_item_offset(right->items + i);
116400ec4c51SChris Mason 	}
11657518a238SChris Mason 	left_nritems -= push_items;
11667518a238SChris Mason 	btrfs_set_header_nritems(&left->header, left_nritems);
116700ec4c51SChris Mason 
1168d6025579SChris Mason 	btrfs_mark_buffer_dirty(left_buf);
1169d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buf);
1170a429e513SChris Mason 
1171d6025579SChris Mason 	btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key,
1172e2fa7227SChris Mason 		&right->items[0].key, sizeof(struct btrfs_disk_key));
1173d6025579SChris Mason 	btrfs_mark_buffer_dirty(upper);
117402217ed2SChris Mason 
117500ec4c51SChris Mason 	/* then fixup the leaf pointer in the path */
11767518a238SChris Mason 	if (path->slots[0] >= left_nritems) {
11777518a238SChris Mason 		path->slots[0] -= left_nritems;
1178234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
117900ec4c51SChris Mason 		path->nodes[0] = right_buf;
118000ec4c51SChris Mason 		path->slots[1] += 1;
118100ec4c51SChris Mason 	} else {
1182234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
118300ec4c51SChris Mason 	}
1184098f59c2SChris Mason 	if (path->nodes[1])
1185098f59c2SChris Mason 		check_node(root, path, 1);
118600ec4c51SChris Mason 	return 0;
118700ec4c51SChris Mason }
118800ec4c51SChris Mason /*
118974123bd7SChris Mason  * push some data in the path leaf to the left, trying to free up at
119074123bd7SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
119174123bd7SChris Mason  */
1192e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
1193e089f05cSChris Mason 			  *root, struct btrfs_path *path, int data_size)
1194be0e5c09SChris Mason {
1195e20d96d6SChris Mason 	struct buffer_head *right_buf = path->nodes[0];
1196e20d96d6SChris Mason 	struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf);
1197e20d96d6SChris Mason 	struct buffer_head *t;
1198234b63a0SChris Mason 	struct btrfs_leaf *left;
1199be0e5c09SChris Mason 	int slot;
1200be0e5c09SChris Mason 	int i;
1201be0e5c09SChris Mason 	int free_space;
1202be0e5c09SChris Mason 	int push_space = 0;
1203be0e5c09SChris Mason 	int push_items = 0;
12040783fcfcSChris Mason 	struct btrfs_item *item;
12057518a238SChris Mason 	u32 old_left_nritems;
1206aa5d6bedSChris Mason 	int ret = 0;
1207aa5d6bedSChris Mason 	int wret;
1208be0e5c09SChris Mason 
1209be0e5c09SChris Mason 	slot = path->slots[1];
1210be0e5c09SChris Mason 	if (slot == 0) {
1211be0e5c09SChris Mason 		return 1;
1212be0e5c09SChris Mason 	}
1213be0e5c09SChris Mason 	if (!path->nodes[1]) {
1214be0e5c09SChris Mason 		return 1;
1215be0e5c09SChris Mason 	}
1216e20d96d6SChris Mason 	t = read_tree_block(root,
1217e20d96d6SChris Mason 	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1));
1218e20d96d6SChris Mason 	left = btrfs_buffer_leaf(t);
1219123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
12200783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1221234b63a0SChris Mason 		btrfs_block_release(root, t);
1222be0e5c09SChris Mason 		return 1;
1223be0e5c09SChris Mason 	}
122402217ed2SChris Mason 
122502217ed2SChris Mason 	/* cow and double check */
122654aa1f4dSChris Mason 	ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
122754aa1f4dSChris Mason 	if (ret) {
122854aa1f4dSChris Mason 		/* we hit -ENOSPC, but it isn't fatal here */
122954aa1f4dSChris Mason 		return 1;
123054aa1f4dSChris Mason 	}
1231e20d96d6SChris Mason 	left = btrfs_buffer_leaf(t);
1232123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
12330783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1234234b63a0SChris Mason 		btrfs_block_release(root, t);
123502217ed2SChris Mason 		return 1;
123602217ed2SChris Mason 	}
123702217ed2SChris Mason 
1238a429e513SChris Mason 	if (btrfs_header_nritems(&right->header) == 0) {
1239a429e513SChris Mason 		btrfs_block_release(root, t);
1240a429e513SChris Mason 		return 1;
1241a429e513SChris Mason 	}
1242a429e513SChris Mason 
1243a429e513SChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) {
1244be0e5c09SChris Mason 		item = right->items + i;
1245be0e5c09SChris Mason 		if (path->slots[0] == i)
1246be0e5c09SChris Mason 			push_space += data_size + sizeof(*item);
12470783fcfcSChris Mason 		if (btrfs_item_size(item) + sizeof(*item) + push_space >
12480783fcfcSChris Mason 		    free_space)
1249be0e5c09SChris Mason 			break;
1250be0e5c09SChris Mason 		push_items++;
12510783fcfcSChris Mason 		push_space += btrfs_item_size(item) + sizeof(*item);
1252be0e5c09SChris Mason 	}
1253be0e5c09SChris Mason 	if (push_items == 0) {
1254234b63a0SChris Mason 		btrfs_block_release(root, t);
1255be0e5c09SChris Mason 		return 1;
1256be0e5c09SChris Mason 	}
1257a429e513SChris Mason 	if (push_items == btrfs_header_nritems(&right->header))
1258a429e513SChris Mason 		WARN_ON(1);
1259be0e5c09SChris Mason 	/* push data from right to left */
1260d6025579SChris Mason 	btrfs_memcpy(root, left, left->items +
1261d6025579SChris Mason 		     btrfs_header_nritems(&left->header),
12620783fcfcSChris Mason 		     right->items, push_items * sizeof(struct btrfs_item));
1263123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root) -
12640783fcfcSChris Mason 		     btrfs_item_offset(right->items + push_items -1);
1265d6025579SChris Mason 	btrfs_memcpy(root, left, btrfs_leaf_data(left) +
1266d6025579SChris Mason 		     leaf_data_end(root, left) - push_space,
1267123abc88SChris Mason 		     btrfs_leaf_data(right) +
1268123abc88SChris Mason 		     btrfs_item_offset(right->items + push_items - 1),
1269be0e5c09SChris Mason 		     push_space);
12707518a238SChris Mason 	old_left_nritems = btrfs_header_nritems(&left->header);
1271eb60ceacSChris Mason 	BUG_ON(old_left_nritems < 0);
1272eb60ceacSChris Mason 
1273be0e5c09SChris Mason 	for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
1274123abc88SChris Mason 		u32 ioff = btrfs_item_offset(left->items + i);
1275123abc88SChris Mason 		btrfs_set_item_offset(left->items + i, ioff -
1276123abc88SChris Mason 				     (BTRFS_LEAF_DATA_SIZE(root) -
12770783fcfcSChris Mason 				      btrfs_item_offset(left->items +
12780783fcfcSChris Mason 						        old_left_nritems - 1)));
1279be0e5c09SChris Mason 	}
12807518a238SChris Mason 	btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
1281be0e5c09SChris Mason 
1282be0e5c09SChris Mason 	/* fixup right node */
12830783fcfcSChris Mason 	push_space = btrfs_item_offset(right->items + push_items - 1) -
1284123abc88SChris Mason 		     leaf_data_end(root, right);
1285d6025579SChris Mason 	btrfs_memmove(root, right, btrfs_leaf_data(right) +
1286d6025579SChris Mason 		      BTRFS_LEAF_DATA_SIZE(root) - push_space,
1287d6025579SChris Mason 		      btrfs_leaf_data(right) +
1288123abc88SChris Mason 		      leaf_data_end(root, right), push_space);
1289d6025579SChris Mason 	btrfs_memmove(root, right, right->items, right->items + push_items,
12907518a238SChris Mason 		(btrfs_header_nritems(&right->header) - push_items) *
12910783fcfcSChris Mason 		sizeof(struct btrfs_item));
12927518a238SChris Mason 	btrfs_set_header_nritems(&right->header,
12937518a238SChris Mason 				 btrfs_header_nritems(&right->header) -
12947518a238SChris Mason 				 push_items);
1295123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
1296eb60ceacSChris Mason 
12977518a238SChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
12980783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, push_space -
12990783fcfcSChris Mason 				      btrfs_item_size(right->items + i));
13000783fcfcSChris Mason 		push_space = btrfs_item_offset(right->items + i);
1301be0e5c09SChris Mason 	}
1302eb60ceacSChris Mason 
1303d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
1304d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buf);
1305098f59c2SChris Mason 
1306e089f05cSChris Mason 	wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
1307aa5d6bedSChris Mason 	if (wret)
1308aa5d6bedSChris Mason 		ret = wret;
1309be0e5c09SChris Mason 
1310be0e5c09SChris Mason 	/* then fixup the leaf pointer in the path */
1311be0e5c09SChris Mason 	if (path->slots[0] < push_items) {
1312be0e5c09SChris Mason 		path->slots[0] += old_left_nritems;
1313234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
1314eb60ceacSChris Mason 		path->nodes[0] = t;
1315be0e5c09SChris Mason 		path->slots[1] -= 1;
1316be0e5c09SChris Mason 	} else {
1317234b63a0SChris Mason 		btrfs_block_release(root, t);
1318be0e5c09SChris Mason 		path->slots[0] -= push_items;
1319be0e5c09SChris Mason 	}
1320eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
1321098f59c2SChris Mason 	if (path->nodes[1])
1322098f59c2SChris Mason 		check_node(root, path, 1);
1323aa5d6bedSChris Mason 	return ret;
1324be0e5c09SChris Mason }
1325be0e5c09SChris Mason 
132674123bd7SChris Mason /*
132774123bd7SChris Mason  * split the path's leaf in two, making sure there is at least data_size
132874123bd7SChris Mason  * available for the resulting leaf level of the path.
1329aa5d6bedSChris Mason  *
1330aa5d6bedSChris Mason  * returns 0 if all went well and < 0 on failure.
133174123bd7SChris Mason  */
1332e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1333d4dbff95SChris Mason 		      *root, struct btrfs_key *ins_key,
1334d4dbff95SChris Mason 		      struct btrfs_path *path, int data_size)
1335be0e5c09SChris Mason {
1336e20d96d6SChris Mason 	struct buffer_head *l_buf;
1337234b63a0SChris Mason 	struct btrfs_leaf *l;
13387518a238SChris Mason 	u32 nritems;
1339eb60ceacSChris Mason 	int mid;
1340eb60ceacSChris Mason 	int slot;
1341234b63a0SChris Mason 	struct btrfs_leaf *right;
1342e20d96d6SChris Mason 	struct buffer_head *right_buffer;
13430783fcfcSChris Mason 	int space_needed = data_size + sizeof(struct btrfs_item);
1344be0e5c09SChris Mason 	int data_copy_size;
1345be0e5c09SChris Mason 	int rt_data_off;
1346be0e5c09SChris Mason 	int i;
1347d4dbff95SChris Mason 	int ret = 0;
1348aa5d6bedSChris Mason 	int wret;
1349d4dbff95SChris Mason 	int double_split = 0;
1350d4dbff95SChris Mason 	struct btrfs_disk_key disk_key;
1351be0e5c09SChris Mason 
135240689478SChris Mason 	/* first try to make some room by pushing left and right */
1353e089f05cSChris Mason 	wret = push_leaf_left(trans, root, path, data_size);
1354eaee50e8SChris Mason 	if (wret < 0)
1355eaee50e8SChris Mason 		return wret;
1356eaee50e8SChris Mason 	if (wret) {
1357e089f05cSChris Mason 		wret = push_leaf_right(trans, root, path, data_size);
1358eaee50e8SChris Mason 		if (wret < 0)
1359eaee50e8SChris Mason 			return wret;
1360eaee50e8SChris Mason 	}
1361eb60ceacSChris Mason 	l_buf = path->nodes[0];
1362e20d96d6SChris Mason 	l = btrfs_buffer_leaf(l_buf);
1363aa5d6bedSChris Mason 
1364aa5d6bedSChris Mason 	/* did the pushes work? */
1365123abc88SChris Mason 	if (btrfs_leaf_free_space(root, l) >=
1366123abc88SChris Mason 	    sizeof(struct btrfs_item) + data_size)
1367be0e5c09SChris Mason 		return 0;
1368aa5d6bedSChris Mason 
13695c680ed6SChris Mason 	if (!path->nodes[1]) {
1370e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, 1);
13715c680ed6SChris Mason 		if (ret)
13725c680ed6SChris Mason 			return ret;
13735c680ed6SChris Mason 	}
1374eb60ceacSChris Mason 	slot = path->slots[0];
13757518a238SChris Mason 	nritems = btrfs_header_nritems(&l->header);
1376eb60ceacSChris Mason 	mid = (nritems + 1)/ 2;
137754aa1f4dSChris Mason 
137831f3c99bSChris Mason 	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
137954aa1f4dSChris Mason 	if (IS_ERR(right_buffer))
138054aa1f4dSChris Mason 		return PTR_ERR(right_buffer);
138154aa1f4dSChris Mason 
1382e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buffer);
1383123abc88SChris Mason 	memset(&right->header, 0, sizeof(right->header));
13847eccb903SChris Mason 	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
13857f5c1516SChris Mason 	btrfs_set_header_generation(&right->header, trans->transid);
13864d775673SChris Mason 	btrfs_set_header_owner(&right->header, root->root_key.objectid);
13877518a238SChris Mason 	btrfs_set_header_level(&right->header, 0);
13883eb0314dSChris Mason 	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
13893eb0314dSChris Mason 	       sizeof(right->header.fsid));
1390d4dbff95SChris Mason 	if (mid <= slot) {
1391d4dbff95SChris Mason 		if (nritems == 1 ||
1392d4dbff95SChris Mason 		    leaf_space_used(l, mid, nritems - mid) + space_needed >
1393d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
1394d4dbff95SChris Mason 			if (slot >= nritems) {
1395d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
1396d4dbff95SChris Mason 				btrfs_set_header_nritems(&right->header, 0);
1397d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
1398d4dbff95SChris Mason 						  &disk_key,
13997eccb903SChris Mason 						  bh_blocknr(right_buffer),
1400d4dbff95SChris Mason 						  path->slots[1] + 1, 1);
1401d4dbff95SChris Mason 				if (wret)
1402d4dbff95SChris Mason 					ret = wret;
1403d4dbff95SChris Mason 				btrfs_block_release(root, path->nodes[0]);
1404d4dbff95SChris Mason 				path->nodes[0] = right_buffer;
1405d4dbff95SChris Mason 				path->slots[0] = 0;
1406d4dbff95SChris Mason 				path->slots[1] += 1;
1407d4dbff95SChris Mason 				return ret;
1408d4dbff95SChris Mason 			}
1409d4dbff95SChris Mason 			mid = slot;
1410d4dbff95SChris Mason 			double_split = 1;
1411d4dbff95SChris Mason 		}
1412d4dbff95SChris Mason 	} else {
1413d4dbff95SChris Mason 		if (leaf_space_used(l, 0, mid + 1) + space_needed >
1414d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
1415d4dbff95SChris Mason 			if (slot == 0) {
1416d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
1417d4dbff95SChris Mason 				btrfs_set_header_nritems(&right->header, 0);
1418d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
1419d4dbff95SChris Mason 						  &disk_key,
14207eccb903SChris Mason 						  bh_blocknr(right_buffer),
1421098f59c2SChris Mason 						  path->slots[1], 1);
1422d4dbff95SChris Mason 				if (wret)
1423d4dbff95SChris Mason 					ret = wret;
1424d4dbff95SChris Mason 				btrfs_block_release(root, path->nodes[0]);
1425d4dbff95SChris Mason 				path->nodes[0] = right_buffer;
1426d4dbff95SChris Mason 				path->slots[0] = 0;
1427a429e513SChris Mason 				if (path->slots[1] == 0) {
1428a429e513SChris Mason 					wret = fixup_low_keys(trans, root,
1429a429e513SChris Mason 					           path, &disk_key, 1);
1430a429e513SChris Mason 					if (wret)
1431a429e513SChris Mason 						ret = wret;
1432a429e513SChris Mason 				}
1433d4dbff95SChris Mason 				return ret;
1434d4dbff95SChris Mason 			}
1435d4dbff95SChris Mason 			mid = slot;
1436d4dbff95SChris Mason 			double_split = 1;
1437d4dbff95SChris Mason 		}
1438d4dbff95SChris Mason 	}
1439d4dbff95SChris Mason 	btrfs_set_header_nritems(&right->header, nritems - mid);
1440123abc88SChris Mason 	data_copy_size = btrfs_item_end(l->items + mid) -
1441123abc88SChris Mason 			 leaf_data_end(root, l);
1442d6025579SChris Mason 	btrfs_memcpy(root, right, right->items, l->items + mid,
14430783fcfcSChris Mason 		     (nritems - mid) * sizeof(struct btrfs_item));
1444d6025579SChris Mason 	btrfs_memcpy(root, right,
1445d6025579SChris Mason 		     btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
1446123abc88SChris Mason 		     data_copy_size, btrfs_leaf_data(l) +
1447123abc88SChris Mason 		     leaf_data_end(root, l), data_copy_size);
1448123abc88SChris Mason 	rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
1449123abc88SChris Mason 		      btrfs_item_end(l->items + mid);
145074123bd7SChris Mason 
14510783fcfcSChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
1452123abc88SChris Mason 		u32 ioff = btrfs_item_offset(right->items + i);
14530783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
14540783fcfcSChris Mason 	}
145574123bd7SChris Mason 
14567518a238SChris Mason 	btrfs_set_header_nritems(&l->header, mid);
1457aa5d6bedSChris Mason 	ret = 0;
1458e089f05cSChris Mason 	wret = insert_ptr(trans, root, path, &right->items[0].key,
14597eccb903SChris Mason 			  bh_blocknr(right_buffer), path->slots[1] + 1, 1);
1460aa5d6bedSChris Mason 	if (wret)
1461aa5d6bedSChris Mason 		ret = wret;
1462d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buffer);
1463d6025579SChris Mason 	btrfs_mark_buffer_dirty(l_buf);
1464eb60ceacSChris Mason 	BUG_ON(path->slots[0] != slot);
1465be0e5c09SChris Mason 	if (mid <= slot) {
1466234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
1467eb60ceacSChris Mason 		path->nodes[0] = right_buffer;
1468be0e5c09SChris Mason 		path->slots[0] -= mid;
1469be0e5c09SChris Mason 		path->slots[1] += 1;
1470eb60ceacSChris Mason 	} else
1471234b63a0SChris Mason 		btrfs_block_release(root, right_buffer);
1472eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
1473098f59c2SChris Mason 	check_node(root, path, 1);
1474d4dbff95SChris Mason 
1475d4dbff95SChris Mason 	if (!double_split)
1476d4dbff95SChris Mason 		return ret;
147731f3c99bSChris Mason 	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
147854aa1f4dSChris Mason 	if (IS_ERR(right_buffer))
147954aa1f4dSChris Mason 		return PTR_ERR(right_buffer);
148054aa1f4dSChris Mason 
1481d4dbff95SChris Mason 	right = btrfs_buffer_leaf(right_buffer);
1482d4dbff95SChris Mason 	memset(&right->header, 0, sizeof(right->header));
14837eccb903SChris Mason 	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1484d4dbff95SChris Mason 	btrfs_set_header_generation(&right->header, trans->transid);
14854d775673SChris Mason 	btrfs_set_header_owner(&right->header, root->root_key.objectid);
1486d4dbff95SChris Mason 	btrfs_set_header_level(&right->header, 0);
14873eb0314dSChris Mason 	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
14883eb0314dSChris Mason 	       sizeof(right->header.fsid));
1489d4dbff95SChris Mason 	btrfs_cpu_key_to_disk(&disk_key, ins_key);
1490d4dbff95SChris Mason 	btrfs_set_header_nritems(&right->header, 0);
1491d4dbff95SChris Mason 	wret = insert_ptr(trans, root, path,
1492d4dbff95SChris Mason 			  &disk_key,
14937eccb903SChris Mason 			  bh_blocknr(right_buffer),
1494d4dbff95SChris Mason 			  path->slots[1], 1);
1495d4dbff95SChris Mason 	if (wret)
1496d4dbff95SChris Mason 		ret = wret;
1497a429e513SChris Mason 	if (path->slots[1] == 0) {
1498a429e513SChris Mason 		wret = fixup_low_keys(trans, root, path, &disk_key, 1);
1499a429e513SChris Mason 		if (wret)
1500a429e513SChris Mason 			ret = wret;
1501a429e513SChris Mason 	}
1502d4dbff95SChris Mason 	btrfs_block_release(root, path->nodes[0]);
1503d4dbff95SChris Mason 	path->nodes[0] = right_buffer;
1504d4dbff95SChris Mason 	path->slots[0] = 0;
1505d4dbff95SChris Mason 	check_node(root, path, 1);
1506d4dbff95SChris Mason 	check_leaf(root, path, 0);
1507be0e5c09SChris Mason 	return ret;
1508be0e5c09SChris Mason }
1509be0e5c09SChris Mason 
1510b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans,
1511b18c6685SChris Mason 			struct btrfs_root *root,
1512b18c6685SChris Mason 			struct btrfs_path *path,
1513b18c6685SChris Mason 			u32 new_size)
1514b18c6685SChris Mason {
1515b18c6685SChris Mason 	int ret = 0;
1516b18c6685SChris Mason 	int slot;
1517b18c6685SChris Mason 	int slot_orig;
1518b18c6685SChris Mason 	struct btrfs_leaf *leaf;
1519b18c6685SChris Mason 	struct buffer_head *leaf_buf;
1520b18c6685SChris Mason 	u32 nritems;
1521b18c6685SChris Mason 	unsigned int data_end;
1522b18c6685SChris Mason 	unsigned int old_data_start;
1523b18c6685SChris Mason 	unsigned int old_size;
1524b18c6685SChris Mason 	unsigned int size_diff;
1525b18c6685SChris Mason 	int i;
1526b18c6685SChris Mason 
1527b18c6685SChris Mason 	slot_orig = path->slots[0];
1528b18c6685SChris Mason 	leaf_buf = path->nodes[0];
1529b18c6685SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
1530b18c6685SChris Mason 
1531b18c6685SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1532b18c6685SChris Mason 	data_end = leaf_data_end(root, leaf);
1533b18c6685SChris Mason 
1534b18c6685SChris Mason 	slot = path->slots[0];
1535b18c6685SChris Mason 	old_data_start = btrfs_item_offset(leaf->items + slot);
1536b18c6685SChris Mason 	old_size = btrfs_item_size(leaf->items + slot);
1537b18c6685SChris Mason 	BUG_ON(old_size <= new_size);
1538b18c6685SChris Mason 	size_diff = old_size - new_size;
1539b18c6685SChris Mason 
1540b18c6685SChris Mason 	BUG_ON(slot < 0);
1541b18c6685SChris Mason 	BUG_ON(slot >= nritems);
1542b18c6685SChris Mason 
1543b18c6685SChris Mason 	/*
1544b18c6685SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1545b18c6685SChris Mason 	 */
1546b18c6685SChris Mason 	/* first correct the data pointers */
1547b18c6685SChris Mason 	for (i = slot; i < nritems; i++) {
1548b18c6685SChris Mason 		u32 ioff = btrfs_item_offset(leaf->items + i);
1549b18c6685SChris Mason 		btrfs_set_item_offset(leaf->items + i,
1550b18c6685SChris Mason 				      ioff + size_diff);
1551b18c6685SChris Mason 	}
1552b18c6685SChris Mason 	/* shift the data */
1553b18c6685SChris Mason 	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1554b18c6685SChris Mason 		      data_end + size_diff, btrfs_leaf_data(leaf) +
1555b18c6685SChris Mason 		      data_end, old_data_start + new_size - data_end);
1556b18c6685SChris Mason 	btrfs_set_item_size(leaf->items + slot, new_size);
1557b18c6685SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
1558b18c6685SChris Mason 
1559b18c6685SChris Mason 	ret = 0;
1560b18c6685SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
1561b18c6685SChris Mason 		BUG();
1562b18c6685SChris Mason 	check_leaf(root, path, 0);
1563b18c6685SChris Mason 	return ret;
1564b18c6685SChris Mason }
1565b18c6685SChris Mason 
15666567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root
15676567e837SChris Mason 		      *root, struct btrfs_path *path, u32 data_size)
15686567e837SChris Mason {
15696567e837SChris Mason 	int ret = 0;
15706567e837SChris Mason 	int slot;
15716567e837SChris Mason 	int slot_orig;
15726567e837SChris Mason 	struct btrfs_leaf *leaf;
15736567e837SChris Mason 	struct buffer_head *leaf_buf;
15746567e837SChris Mason 	u32 nritems;
15756567e837SChris Mason 	unsigned int data_end;
15766567e837SChris Mason 	unsigned int old_data;
15776567e837SChris Mason 	unsigned int old_size;
15786567e837SChris Mason 	int i;
15796567e837SChris Mason 
15806567e837SChris Mason 	slot_orig = path->slots[0];
15816567e837SChris Mason 	leaf_buf = path->nodes[0];
15826567e837SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
15836567e837SChris Mason 
15846567e837SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
15856567e837SChris Mason 	data_end = leaf_data_end(root, leaf);
15866567e837SChris Mason 
15876567e837SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < data_size)
15886567e837SChris Mason 		BUG();
15896567e837SChris Mason 	slot = path->slots[0];
15906567e837SChris Mason 	old_data = btrfs_item_end(leaf->items + slot);
15916567e837SChris Mason 
15926567e837SChris Mason 	BUG_ON(slot < 0);
15936567e837SChris Mason 	BUG_ON(slot >= nritems);
15946567e837SChris Mason 
15956567e837SChris Mason 	/*
15966567e837SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
15976567e837SChris Mason 	 */
15986567e837SChris Mason 	/* first correct the data pointers */
15996567e837SChris Mason 	for (i = slot; i < nritems; i++) {
16006567e837SChris Mason 		u32 ioff = btrfs_item_offset(leaf->items + i);
16016567e837SChris Mason 		btrfs_set_item_offset(leaf->items + i,
16026567e837SChris Mason 				      ioff - data_size);
16036567e837SChris Mason 	}
16046567e837SChris Mason 	/* shift the data */
16056567e837SChris Mason 	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
16066567e837SChris Mason 		      data_end - data_size, btrfs_leaf_data(leaf) +
16076567e837SChris Mason 		      data_end, old_data - data_end);
16086567e837SChris Mason 	data_end = old_data;
16096567e837SChris Mason 	old_size = btrfs_item_size(leaf->items + slot);
16106567e837SChris Mason 	btrfs_set_item_size(leaf->items + slot, old_size + data_size);
16116567e837SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
16126567e837SChris Mason 
16136567e837SChris Mason 	ret = 0;
16146567e837SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
16156567e837SChris Mason 		BUG();
16166567e837SChris Mason 	check_leaf(root, path, 0);
16176567e837SChris Mason 	return ret;
16186567e837SChris Mason }
16196567e837SChris Mason 
162074123bd7SChris Mason /*
162174123bd7SChris Mason  * Given a key and some data, insert an item into the tree.
162274123bd7SChris Mason  * This does all the path init required, making room in the tree if needed.
162374123bd7SChris Mason  */
1624e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
1625e089f05cSChris Mason 			    *root, struct btrfs_path *path, struct btrfs_key
1626e089f05cSChris Mason 			    *cpu_key, u32 data_size)
1627be0e5c09SChris Mason {
1628aa5d6bedSChris Mason 	int ret = 0;
1629be0e5c09SChris Mason 	int slot;
1630eb60ceacSChris Mason 	int slot_orig;
1631234b63a0SChris Mason 	struct btrfs_leaf *leaf;
1632e20d96d6SChris Mason 	struct buffer_head *leaf_buf;
16337518a238SChris Mason 	u32 nritems;
1634be0e5c09SChris Mason 	unsigned int data_end;
1635e2fa7227SChris Mason 	struct btrfs_disk_key disk_key;
1636e2fa7227SChris Mason 
1637e2fa7227SChris Mason 	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1638be0e5c09SChris Mason 
163974123bd7SChris Mason 	/* create a root if there isn't one */
16405c680ed6SChris Mason 	if (!root->node)
1641cfaa7295SChris Mason 		BUG();
1642e089f05cSChris Mason 	ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
1643eb60ceacSChris Mason 	if (ret == 0) {
1644f0930a37SChris Mason 		return -EEXIST;
1645aa5d6bedSChris Mason 	}
1646ed2ff2cbSChris Mason 	if (ret < 0)
1647ed2ff2cbSChris Mason 		goto out;
1648be0e5c09SChris Mason 
164962e2749eSChris Mason 	slot_orig = path->slots[0];
165062e2749eSChris Mason 	leaf_buf = path->nodes[0];
1651e20d96d6SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
165274123bd7SChris Mason 
16537518a238SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1654123abc88SChris Mason 	data_end = leaf_data_end(root, leaf);
1655eb60ceacSChris Mason 
1656123abc88SChris Mason 	if (btrfs_leaf_free_space(root, leaf) <
1657d4dbff95SChris Mason 	    sizeof(struct btrfs_item) + data_size) {
1658be0e5c09SChris Mason 		BUG();
1659d4dbff95SChris Mason 	}
166062e2749eSChris Mason 	slot = path->slots[0];
1661eb60ceacSChris Mason 	BUG_ON(slot < 0);
1662be0e5c09SChris Mason 	if (slot != nritems) {
1663be0e5c09SChris Mason 		int i;
16640783fcfcSChris Mason 		unsigned int old_data = btrfs_item_end(leaf->items + slot);
1665be0e5c09SChris Mason 
1666be0e5c09SChris Mason 		/*
1667be0e5c09SChris Mason 		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1668be0e5c09SChris Mason 		 */
1669be0e5c09SChris Mason 		/* first correct the data pointers */
16700783fcfcSChris Mason 		for (i = slot; i < nritems; i++) {
1671123abc88SChris Mason 			u32 ioff = btrfs_item_offset(leaf->items + i);
16720783fcfcSChris Mason 			btrfs_set_item_offset(leaf->items + i,
16730783fcfcSChris Mason 					      ioff - data_size);
16740783fcfcSChris Mason 		}
1675be0e5c09SChris Mason 
1676be0e5c09SChris Mason 		/* shift the items */
1677d6025579SChris Mason 		btrfs_memmove(root, leaf, leaf->items + slot + 1,
1678d6025579SChris Mason 			      leaf->items + slot,
16790783fcfcSChris Mason 			      (nritems - slot) * sizeof(struct btrfs_item));
1680be0e5c09SChris Mason 
1681be0e5c09SChris Mason 		/* shift the data */
1682d6025579SChris Mason 		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1683d6025579SChris Mason 			      data_end - data_size, btrfs_leaf_data(leaf) +
1684be0e5c09SChris Mason 			      data_end, old_data - data_end);
1685be0e5c09SChris Mason 		data_end = old_data;
1686be0e5c09SChris Mason 	}
168762e2749eSChris Mason 	/* setup the item for the new data */
1688d6025579SChris Mason 	btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key,
1689e2fa7227SChris Mason 		     sizeof(struct btrfs_disk_key));
16900783fcfcSChris Mason 	btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
16910783fcfcSChris Mason 	btrfs_set_item_size(leaf->items + slot, data_size);
16927518a238SChris Mason 	btrfs_set_header_nritems(&leaf->header, nritems + 1);
1693d6025579SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
1694aa5d6bedSChris Mason 
1695aa5d6bedSChris Mason 	ret = 0;
16968e19f2cdSChris Mason 	if (slot == 0)
1697e089f05cSChris Mason 		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
1698aa5d6bedSChris Mason 
1699123abc88SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
1700be0e5c09SChris Mason 		BUG();
170162e2749eSChris Mason 	check_leaf(root, path, 0);
1702ed2ff2cbSChris Mason out:
170362e2749eSChris Mason 	return ret;
170462e2749eSChris Mason }
170562e2749eSChris Mason 
170662e2749eSChris Mason /*
170762e2749eSChris Mason  * Given a key and some data, insert an item into the tree.
170862e2749eSChris Mason  * This does all the path init required, making room in the tree if needed.
170962e2749eSChris Mason  */
1710e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
1711e089f05cSChris Mason 		      *root, struct btrfs_key *cpu_key, void *data, u32
1712e089f05cSChris Mason 		      data_size)
171362e2749eSChris Mason {
171462e2749eSChris Mason 	int ret = 0;
17152c90e5d6SChris Mason 	struct btrfs_path *path;
171662e2749eSChris Mason 	u8 *ptr;
171762e2749eSChris Mason 
17182c90e5d6SChris Mason 	path = btrfs_alloc_path();
17192c90e5d6SChris Mason 	BUG_ON(!path);
17202c90e5d6SChris Mason 	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
172162e2749eSChris Mason 	if (!ret) {
17222c90e5d6SChris Mason 		ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
17232c90e5d6SChris Mason 				     path->slots[0], u8);
17242c90e5d6SChris Mason 		btrfs_memcpy(root, path->nodes[0]->b_data,
1725d6025579SChris Mason 			     ptr, data, data_size);
17262c90e5d6SChris Mason 		btrfs_mark_buffer_dirty(path->nodes[0]);
172762e2749eSChris Mason 	}
17282c90e5d6SChris Mason 	btrfs_free_path(path);
1729aa5d6bedSChris Mason 	return ret;
1730be0e5c09SChris Mason }
1731be0e5c09SChris Mason 
173274123bd7SChris Mason /*
17335de08d7dSChris Mason  * delete the pointer from a given node.
173474123bd7SChris Mason  *
173574123bd7SChris Mason  * If the delete empties a node, the node is removed from the tree,
173674123bd7SChris Mason  * continuing all the way the root if required.  The root is converted into
173774123bd7SChris Mason  * a leaf if all the nodes are emptied.
173874123bd7SChris Mason  */
1739e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1740e089f05cSChris Mason 		   struct btrfs_path *path, int level, int slot)
1741be0e5c09SChris Mason {
1742234b63a0SChris Mason 	struct btrfs_node *node;
1743e20d96d6SChris Mason 	struct buffer_head *parent = path->nodes[level];
17447518a238SChris Mason 	u32 nritems;
1745aa5d6bedSChris Mason 	int ret = 0;
1746bb803951SChris Mason 	int wret;
1747be0e5c09SChris Mason 
1748e20d96d6SChris Mason 	node = btrfs_buffer_node(parent);
17497518a238SChris Mason 	nritems = btrfs_header_nritems(&node->header);
1750be0e5c09SChris Mason 	if (slot != nritems -1) {
1751d6025579SChris Mason 		btrfs_memmove(root, node, node->ptrs + slot,
1752d6025579SChris Mason 			      node->ptrs + slot + 1,
1753d6025579SChris Mason 			      sizeof(struct btrfs_key_ptr) *
1754d6025579SChris Mason 			      (nritems - slot - 1));
1755be0e5c09SChris Mason 	}
17567518a238SChris Mason 	nritems--;
17577518a238SChris Mason 	btrfs_set_header_nritems(&node->header, nritems);
17587518a238SChris Mason 	if (nritems == 0 && parent == root->node) {
1759e20d96d6SChris Mason 		struct btrfs_header *header = btrfs_buffer_header(root->node);
1760e20d96d6SChris Mason 		BUG_ON(btrfs_header_level(header) != 1);
1761eb60ceacSChris Mason 		/* just turn the root into a leaf and break */
1762e20d96d6SChris Mason 		btrfs_set_header_level(header, 0);
1763bb803951SChris Mason 	} else if (slot == 0) {
1764e089f05cSChris Mason 		wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
1765123abc88SChris Mason 				      level + 1);
17660f70abe2SChris Mason 		if (wret)
17670f70abe2SChris Mason 			ret = wret;
1768be0e5c09SChris Mason 	}
1769d6025579SChris Mason 	btrfs_mark_buffer_dirty(parent);
1770aa5d6bedSChris Mason 	return ret;
1771be0e5c09SChris Mason }
1772be0e5c09SChris Mason 
177374123bd7SChris Mason /*
177474123bd7SChris Mason  * delete the item at the leaf level in path.  If that empties
177574123bd7SChris Mason  * the leaf, remove it from the tree
177674123bd7SChris Mason  */
1777e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1778e089f05cSChris Mason 		   struct btrfs_path *path)
1779be0e5c09SChris Mason {
1780be0e5c09SChris Mason 	int slot;
1781234b63a0SChris Mason 	struct btrfs_leaf *leaf;
1782e20d96d6SChris Mason 	struct buffer_head *leaf_buf;
1783be0e5c09SChris Mason 	int doff;
1784be0e5c09SChris Mason 	int dsize;
1785aa5d6bedSChris Mason 	int ret = 0;
1786aa5d6bedSChris Mason 	int wret;
17877518a238SChris Mason 	u32 nritems;
1788be0e5c09SChris Mason 
1789eb60ceacSChris Mason 	leaf_buf = path->nodes[0];
1790e20d96d6SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
17914920c9acSChris Mason 	slot = path->slots[0];
17920783fcfcSChris Mason 	doff = btrfs_item_offset(leaf->items + slot);
17930783fcfcSChris Mason 	dsize = btrfs_item_size(leaf->items + slot);
17947518a238SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1795be0e5c09SChris Mason 
17967518a238SChris Mason 	if (slot != nritems - 1) {
1797be0e5c09SChris Mason 		int i;
1798123abc88SChris Mason 		int data_end = leaf_data_end(root, leaf);
1799d6025579SChris Mason 		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1800d6025579SChris Mason 			      data_end + dsize,
1801123abc88SChris Mason 			      btrfs_leaf_data(leaf) + data_end,
1802be0e5c09SChris Mason 			      doff - data_end);
18030783fcfcSChris Mason 		for (i = slot + 1; i < nritems; i++) {
1804123abc88SChris Mason 			u32 ioff = btrfs_item_offset(leaf->items + i);
18050783fcfcSChris Mason 			btrfs_set_item_offset(leaf->items + i, ioff + dsize);
18060783fcfcSChris Mason 		}
1807d6025579SChris Mason 		btrfs_memmove(root, leaf, leaf->items + slot,
1808d6025579SChris Mason 			      leaf->items + slot + 1,
18090783fcfcSChris Mason 			      sizeof(struct btrfs_item) *
18107518a238SChris Mason 			      (nritems - slot - 1));
1811be0e5c09SChris Mason 	}
18127518a238SChris Mason 	btrfs_set_header_nritems(&leaf->header, nritems - 1);
18137518a238SChris Mason 	nritems--;
181474123bd7SChris Mason 	/* delete the leaf if we've emptied it */
18157518a238SChris Mason 	if (nritems == 0) {
1816eb60ceacSChris Mason 		if (leaf_buf == root->node) {
18177518a238SChris Mason 			btrfs_set_header_level(&leaf->header, 0);
18189a8dd150SChris Mason 		} else {
1819e089f05cSChris Mason 			clean_tree_block(trans, root, leaf_buf);
1820d6025579SChris Mason 			wait_on_buffer(leaf_buf);
1821e089f05cSChris Mason 			wret = del_ptr(trans, root, path, 1, path->slots[1]);
1822aa5d6bedSChris Mason 			if (wret)
1823aa5d6bedSChris Mason 				ret = wret;
1824e089f05cSChris Mason 			wret = btrfs_free_extent(trans, root,
18257eccb903SChris Mason 						 bh_blocknr(leaf_buf), 1, 1);
18260f70abe2SChris Mason 			if (wret)
18270f70abe2SChris Mason 				ret = wret;
18289a8dd150SChris Mason 		}
1829be0e5c09SChris Mason 	} else {
18307518a238SChris Mason 		int used = leaf_space_used(leaf, 0, nritems);
1831aa5d6bedSChris Mason 		if (slot == 0) {
1832e089f05cSChris Mason 			wret = fixup_low_keys(trans, root, path,
1833aa5d6bedSChris Mason 					      &leaf->items[0].key, 1);
1834aa5d6bedSChris Mason 			if (wret)
1835aa5d6bedSChris Mason 				ret = wret;
1836aa5d6bedSChris Mason 		}
1837aa5d6bedSChris Mason 
183874123bd7SChris Mason 		/* delete the leaf if it is mostly empty */
1839123abc88SChris Mason 		if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
1840be0e5c09SChris Mason 			/* push_leaf_left fixes the path.
1841be0e5c09SChris Mason 			 * make sure the path still points to our leaf
1842be0e5c09SChris Mason 			 * for possible call to del_ptr below
1843be0e5c09SChris Mason 			 */
18444920c9acSChris Mason 			slot = path->slots[1];
1845e20d96d6SChris Mason 			get_bh(leaf_buf);
1846e089f05cSChris Mason 			wret = push_leaf_left(trans, root, path, 1);
184754aa1f4dSChris Mason 			if (wret < 0 && wret != -ENOSPC)
1848aa5d6bedSChris Mason 				ret = wret;
1849f0930a37SChris Mason 			if (path->nodes[0] == leaf_buf &&
18507518a238SChris Mason 			    btrfs_header_nritems(&leaf->header)) {
1851e089f05cSChris Mason 				wret = push_leaf_right(trans, root, path, 1);
185254aa1f4dSChris Mason 				if (wret < 0 && wret != -ENOSPC)
1853aa5d6bedSChris Mason 					ret = wret;
1854aa5d6bedSChris Mason 			}
18557518a238SChris Mason 			if (btrfs_header_nritems(&leaf->header) == 0) {
18567eccb903SChris Mason 				u64 blocknr = bh_blocknr(leaf_buf);
1857e089f05cSChris Mason 				clean_tree_block(trans, root, leaf_buf);
1858d6025579SChris Mason 				wait_on_buffer(leaf_buf);
1859e089f05cSChris Mason 				wret = del_ptr(trans, root, path, 1, slot);
1860aa5d6bedSChris Mason 				if (wret)
1861aa5d6bedSChris Mason 					ret = wret;
1862234b63a0SChris Mason 				btrfs_block_release(root, leaf_buf);
1863e089f05cSChris Mason 				wret = btrfs_free_extent(trans, root, blocknr,
1864e089f05cSChris Mason 							 1, 1);
18650f70abe2SChris Mason 				if (wret)
18660f70abe2SChris Mason 					ret = wret;
18675de08d7dSChris Mason 			} else {
1868d6025579SChris Mason 				btrfs_mark_buffer_dirty(leaf_buf);
1869234b63a0SChris Mason 				btrfs_block_release(root, leaf_buf);
1870be0e5c09SChris Mason 			}
1871d5719762SChris Mason 		} else {
1872d6025579SChris Mason 			btrfs_mark_buffer_dirty(leaf_buf);
1873be0e5c09SChris Mason 		}
18749a8dd150SChris Mason 	}
1875aa5d6bedSChris Mason 	return ret;
18769a8dd150SChris Mason }
18779a8dd150SChris Mason 
187897571fd0SChris Mason /*
187997571fd0SChris Mason  * walk up the tree as far as required to find the next leaf.
18800f70abe2SChris Mason  * returns 0 if it found something or 1 if there are no greater leaves.
18810f70abe2SChris Mason  * returns < 0 on io errors.
188297571fd0SChris Mason  */
1883234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
1884d97e63b6SChris Mason {
1885d97e63b6SChris Mason 	int slot;
1886d97e63b6SChris Mason 	int level = 1;
1887d97e63b6SChris Mason 	u64 blocknr;
1888e20d96d6SChris Mason 	struct buffer_head *c;
1889e20d96d6SChris Mason 	struct btrfs_node *c_node;
1890e20d96d6SChris Mason 	struct buffer_head *next = NULL;
1891d97e63b6SChris Mason 
1892234b63a0SChris Mason 	while(level < BTRFS_MAX_LEVEL) {
1893d97e63b6SChris Mason 		if (!path->nodes[level])
18940f70abe2SChris Mason 			return 1;
1895d97e63b6SChris Mason 		slot = path->slots[level] + 1;
1896d97e63b6SChris Mason 		c = path->nodes[level];
1897e20d96d6SChris Mason 		c_node = btrfs_buffer_node(c);
1898e20d96d6SChris Mason 		if (slot >= btrfs_header_nritems(&c_node->header)) {
1899d97e63b6SChris Mason 			level++;
1900d97e63b6SChris Mason 			continue;
1901d97e63b6SChris Mason 		}
1902e20d96d6SChris Mason 		blocknr = btrfs_node_blockptr(c_node, slot);
1903cfaa7295SChris Mason 		if (next)
1904234b63a0SChris Mason 			btrfs_block_release(root, next);
1905d97e63b6SChris Mason 		next = read_tree_block(root, blocknr);
1906d97e63b6SChris Mason 		break;
1907d97e63b6SChris Mason 	}
1908d97e63b6SChris Mason 	path->slots[level] = slot;
1909d97e63b6SChris Mason 	while(1) {
1910d97e63b6SChris Mason 		level--;
1911d97e63b6SChris Mason 		c = path->nodes[level];
1912234b63a0SChris Mason 		btrfs_block_release(root, c);
1913d97e63b6SChris Mason 		path->nodes[level] = next;
1914d97e63b6SChris Mason 		path->slots[level] = 0;
1915d97e63b6SChris Mason 		if (!level)
1916d97e63b6SChris Mason 			break;
19171d4f8a0cSChris Mason 		next = read_tree_block(root,
1918e20d96d6SChris Mason 		       btrfs_node_blockptr(btrfs_buffer_node(next), 0));
1919d97e63b6SChris Mason 	}
1920d97e63b6SChris Mason 	return 0;
1921d97e63b6SChris Mason }
1922