xref: /openbmc/linux/fs/btrfs/ctree.c (revision a1f396304fb7e5f18e4ea81c294415375f1c814c)
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 
19eb60ceacSChris Mason #include "ctree.h"
20eb60ceacSChris Mason #include "disk-io.h"
217f5c1516SChris Mason #include "transaction.h"
229a8dd150SChris Mason 
23e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
24e089f05cSChris Mason 		      *root, struct btrfs_path *path, int level);
25e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
26d4dbff95SChris Mason 		      *root, struct btrfs_key *ins_key,
27d4dbff95SChris Mason 		      struct btrfs_path *path, int data_size);
28e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
29e20d96d6SChris Mason 			  *root, struct buffer_head *dst, struct buffer_head
30e089f05cSChris Mason 			  *src);
31e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct
32e20d96d6SChris Mason 			      btrfs_root *root, struct buffer_head *dst_buf,
33e20d96d6SChris Mason 			      struct buffer_head *src_buf);
34e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
35e089f05cSChris Mason 		   struct btrfs_path *path, int level, int slot);
36d97e63b6SChris Mason 
37df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p)
38df24a2b9SChris Mason {
39df24a2b9SChris Mason 	memset(p, 0, sizeof(*p));
40df24a2b9SChris Mason }
41df24a2b9SChris Mason 
422c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void)
432c90e5d6SChris Mason {
44df24a2b9SChris Mason 	struct btrfs_path *path;
45df24a2b9SChris Mason 	path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
46df24a2b9SChris Mason 	if (path)
47df24a2b9SChris Mason 		btrfs_init_path(path);
48df24a2b9SChris Mason 	return path;
492c90e5d6SChris Mason }
502c90e5d6SChris Mason 
512c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p)
522c90e5d6SChris Mason {
53df24a2b9SChris Mason 	btrfs_release_path(NULL, p);
542c90e5d6SChris Mason 	kmem_cache_free(btrfs_path_cachep, p);
552c90e5d6SChris Mason }
562c90e5d6SChris Mason 
57234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
58eb60ceacSChris Mason {
59eb60ceacSChris Mason 	int i;
60234b63a0SChris Mason 	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
61eb60ceacSChris Mason 		if (!p->nodes[i])
62eb60ceacSChris Mason 			break;
63234b63a0SChris Mason 		btrfs_block_release(root, p->nodes[i]);
64eb60ceacSChris Mason 	}
65aa5d6bedSChris Mason 	memset(p, 0, sizeof(*p));
66eb60ceacSChris Mason }
67eb60ceacSChris Mason 
68e089f05cSChris Mason static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
69e20d96d6SChris Mason 			   *root, struct buffer_head *buf, struct buffer_head
70e20d96d6SChris Mason 			   *parent, int parent_slot, struct buffer_head
71e089f05cSChris Mason 			   **cow_ret)
7202217ed2SChris Mason {
73e20d96d6SChris Mason 	struct buffer_head *cow;
74e20d96d6SChris Mason 	struct btrfs_node *cow_node;
7554aa1f4dSChris Mason 	int ret;
7602217ed2SChris Mason 
77ccd467d6SChris Mason 	WARN_ON(!buffer_uptodate(buf));
78ccd467d6SChris Mason 	if (trans->transaction != root->fs_info->running_transaction) {
79ccd467d6SChris Mason 		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
80ccd467d6SChris Mason 		       root->fs_info->running_transaction->transid);
81ccd467d6SChris Mason 		WARN_ON(1);
82ccd467d6SChris Mason 	}
83ccd467d6SChris Mason 	if (trans->transid != root->fs_info->generation) {
84ccd467d6SChris Mason 		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
85ccd467d6SChris Mason 		       root->fs_info->generation);
86ccd467d6SChris Mason 		WARN_ON(1);
87ccd467d6SChris Mason 	}
887f5c1516SChris Mason 	if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
897f5c1516SChris Mason 				    trans->transid) {
9002217ed2SChris Mason 		*cow_ret = buf;
9102217ed2SChris Mason 		return 0;
9202217ed2SChris Mason 	}
9331f3c99bSChris Mason 	cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr);
9454aa1f4dSChris Mason 	if (IS_ERR(cow))
9554aa1f4dSChris Mason 		return PTR_ERR(cow);
96e20d96d6SChris Mason 	cow_node = btrfs_buffer_node(cow);
972c90e5d6SChris Mason 	if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
982c90e5d6SChris Mason 		WARN_ON(1);
99e20d96d6SChris Mason 	memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
1007eccb903SChris Mason 	btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow));
1017f5c1516SChris Mason 	btrfs_set_header_generation(&cow_node->header, trans->transid);
1024d775673SChris Mason 	btrfs_set_header_owner(&cow_node->header, root->root_key.objectid);
10354aa1f4dSChris Mason 	ret = btrfs_inc_ref(trans, root, buf);
10454aa1f4dSChris Mason 	if (ret)
10554aa1f4dSChris Mason 		return ret;
10602217ed2SChris Mason 	if (buf == root->node) {
10702217ed2SChris Mason 		root->node = cow;
108e20d96d6SChris Mason 		get_bh(cow);
1092c90e5d6SChris Mason 		if (buf != root->commit_root) {
1107eccb903SChris Mason 			btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
1112c90e5d6SChris Mason 		}
112234b63a0SChris Mason 		btrfs_block_release(root, buf);
11302217ed2SChris Mason 	} else {
114e20d96d6SChris Mason 		btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
1157eccb903SChris Mason 					bh_blocknr(cow));
116d6025579SChris Mason 		btrfs_mark_buffer_dirty(parent);
1177eccb903SChris Mason 		btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
11802217ed2SChris Mason 	}
119234b63a0SChris Mason 	btrfs_block_release(root, buf);
120ccd467d6SChris Mason 	btrfs_mark_buffer_dirty(cow);
1212c90e5d6SChris Mason 	*cow_ret = cow;
12202217ed2SChris Mason 	return 0;
12302217ed2SChris Mason }
12402217ed2SChris Mason 
12574123bd7SChris Mason /*
12674123bd7SChris Mason  * The leaf data grows from end-to-front in the node.
12774123bd7SChris Mason  * this returns the address of the start of the last item,
12874123bd7SChris Mason  * which is the stop of the leaf data stack
12974123bd7SChris Mason  */
130123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root,
131123abc88SChris Mason 					 struct btrfs_leaf *leaf)
132be0e5c09SChris Mason {
1337518a238SChris Mason 	u32 nr = btrfs_header_nritems(&leaf->header);
134be0e5c09SChris Mason 	if (nr == 0)
135123abc88SChris Mason 		return BTRFS_LEAF_DATA_SIZE(root);
1360783fcfcSChris Mason 	return btrfs_item_offset(leaf->items + nr - 1);
137be0e5c09SChris Mason }
138be0e5c09SChris Mason 
13974123bd7SChris Mason /*
14074123bd7SChris Mason  * compare two keys in a memcmp fashion
14174123bd7SChris Mason  */
1429aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
143be0e5c09SChris Mason {
144e2fa7227SChris Mason 	struct btrfs_key k1;
145e2fa7227SChris Mason 
146e2fa7227SChris Mason 	btrfs_disk_key_to_cpu(&k1, disk);
147e2fa7227SChris Mason 
148e2fa7227SChris Mason 	if (k1.objectid > k2->objectid)
149be0e5c09SChris Mason 		return 1;
150e2fa7227SChris Mason 	if (k1.objectid < k2->objectid)
151be0e5c09SChris Mason 		return -1;
152f254e52cSChris Mason 	if (k1.flags > k2->flags)
153f254e52cSChris Mason 		return 1;
154f254e52cSChris Mason 	if (k1.flags < k2->flags)
155f254e52cSChris Mason 		return -1;
15670b2befdSChris Mason 	if (k1.offset > k2->offset)
15770b2befdSChris Mason 		return 1;
15870b2befdSChris Mason 	if (k1.offset < k2->offset)
15970b2befdSChris Mason 		return -1;
160be0e5c09SChris Mason 	return 0;
161be0e5c09SChris Mason }
16274123bd7SChris Mason 
163123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path,
164123abc88SChris Mason 		      int level)
165aa5d6bedSChris Mason {
166234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
167e20d96d6SChris Mason 	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
168aa5d6bedSChris Mason 	int parent_slot;
1698d7be552SChris Mason 	int slot;
1708d7be552SChris Mason 	struct btrfs_key cpukey;
1717518a238SChris Mason 	u32 nritems = btrfs_header_nritems(&node->header);
172aa5d6bedSChris Mason 
173aa5d6bedSChris Mason 	if (path->nodes[level + 1])
174e20d96d6SChris Mason 		parent = btrfs_buffer_node(path->nodes[level + 1]);
175*a1f39630SAneesh 
1768d7be552SChris Mason 	slot = path->slots[level];
1777518a238SChris Mason 	BUG_ON(nritems == 0);
1787518a238SChris Mason 	if (parent) {
179e2fa7227SChris Mason 		struct btrfs_disk_key *parent_key;
180*a1f39630SAneesh 
181*a1f39630SAneesh 		parent_slot = path->slots[level + 1];
182123abc88SChris Mason 		parent_key = &parent->ptrs[parent_slot].key;
183123abc88SChris Mason 		BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
184e2fa7227SChris Mason 			      sizeof(struct btrfs_disk_key)));
1851d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
1867518a238SChris Mason 		       btrfs_header_blocknr(&node->header));
187aa5d6bedSChris Mason 	}
188123abc88SChris Mason 	BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
1898d7be552SChris Mason 	if (slot != 0) {
1908d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot - 1].key);
1918d7be552SChris Mason 		BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) <= 0);
1928d7be552SChris Mason 	}
1938d7be552SChris Mason 	if (slot < nritems - 1) {
1948d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[slot + 1].key);
1958d7be552SChris Mason 		BUG_ON(comp_keys(&node->ptrs[slot].key, &cpukey) >= 0);
196aa5d6bedSChris Mason 	}
197aa5d6bedSChris Mason 	return 0;
198aa5d6bedSChris Mason }
199aa5d6bedSChris Mason 
200123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
201123abc88SChris Mason 		      int level)
202aa5d6bedSChris Mason {
203e20d96d6SChris Mason 	struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]);
204234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
205aa5d6bedSChris Mason 	int parent_slot;
2068d7be552SChris Mason 	int slot = path->slots[0];
2078d7be552SChris Mason 	struct btrfs_key cpukey;
2088d7be552SChris Mason 
2097518a238SChris Mason 	u32 nritems = btrfs_header_nritems(&leaf->header);
210aa5d6bedSChris Mason 
211aa5d6bedSChris Mason 	if (path->nodes[level + 1])
212e20d96d6SChris Mason 		parent = btrfs_buffer_node(path->nodes[level + 1]);
213*a1f39630SAneesh 
214123abc88SChris Mason 	BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
2157518a238SChris Mason 
2167518a238SChris Mason 	if (nritems == 0)
2177518a238SChris Mason 		return 0;
2187518a238SChris Mason 
2197518a238SChris Mason 	if (parent) {
220e2fa7227SChris Mason 		struct btrfs_disk_key *parent_key;
221*a1f39630SAneesh 
222*a1f39630SAneesh 		parent_slot = path->slots[level + 1];
223123abc88SChris Mason 		parent_key = &parent->ptrs[parent_slot].key;
224aa5d6bedSChris Mason 		BUG_ON(memcmp(parent_key, &leaf->items[0].key,
225e2fa7227SChris Mason 		       sizeof(struct btrfs_disk_key)));
2261d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
2277518a238SChris Mason 		       btrfs_header_blocknr(&leaf->header));
228aa5d6bedSChris Mason 	}
2298d7be552SChris Mason 	if (slot != 0) {
2308d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot - 1].key);
2318d7be552SChris Mason 		BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) <= 0);
2328d7be552SChris Mason 		BUG_ON(btrfs_item_offset(leaf->items + slot - 1) !=
2338d7be552SChris Mason 			btrfs_item_end(leaf->items + slot));
234aa5d6bedSChris Mason 	}
2358d7be552SChris Mason 	if (slot < nritems - 1) {
2368d7be552SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[slot + 1].key);
2378d7be552SChris Mason 		BUG_ON(comp_keys(&leaf->items[slot].key, &cpukey) >= 0);
2388d7be552SChris Mason 		BUG_ON(btrfs_item_offset(leaf->items + slot) !=
2398d7be552SChris Mason 			btrfs_item_end(leaf->items + slot + 1));
240aa5d6bedSChris Mason 	}
2418d7be552SChris Mason 	BUG_ON(btrfs_item_offset(leaf->items) +
2428d7be552SChris Mason 	       btrfs_item_size(leaf->items) != BTRFS_LEAF_DATA_SIZE(root));
243aa5d6bedSChris Mason 	return 0;
244aa5d6bedSChris Mason }
245aa5d6bedSChris Mason 
246123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path,
247123abc88SChris Mason 			int level)
248aa5d6bedSChris Mason {
2493eb0314dSChris Mason 	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
2503eb0314dSChris Mason 	if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid,
2513eb0314dSChris Mason 		   sizeof(node->header.fsid)))
2523eb0314dSChris Mason 		BUG();
253aa5d6bedSChris Mason 	if (level == 0)
254123abc88SChris Mason 		return check_leaf(root, path, level);
255123abc88SChris Mason 	return check_node(root, path, level);
256aa5d6bedSChris Mason }
257aa5d6bedSChris Mason 
25874123bd7SChris Mason /*
25974123bd7SChris Mason  * search for key in the array p.  items p are item_size apart
26074123bd7SChris Mason  * and there are 'max' items in p
26174123bd7SChris Mason  * the slot in the array is returned via slot, and it points to
26274123bd7SChris Mason  * the place where you would insert key if it is not found in
26374123bd7SChris Mason  * the array.
26474123bd7SChris Mason  *
26574123bd7SChris Mason  * slot may point to max if the key is bigger than all of the keys
26674123bd7SChris Mason  */
2679aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key,
268be0e5c09SChris Mason 		       int max, int *slot)
269be0e5c09SChris Mason {
270be0e5c09SChris Mason 	int low = 0;
271be0e5c09SChris Mason 	int high = max;
272be0e5c09SChris Mason 	int mid;
273be0e5c09SChris Mason 	int ret;
274e2fa7227SChris Mason 	struct btrfs_disk_key *tmp;
275be0e5c09SChris Mason 
276be0e5c09SChris Mason 	while(low < high) {
277be0e5c09SChris Mason 		mid = (low + high) / 2;
278e2fa7227SChris Mason 		tmp = (struct btrfs_disk_key *)(p + mid * item_size);
279be0e5c09SChris Mason 		ret = comp_keys(tmp, key);
280be0e5c09SChris Mason 
281be0e5c09SChris Mason 		if (ret < 0)
282be0e5c09SChris Mason 			low = mid + 1;
283be0e5c09SChris Mason 		else if (ret > 0)
284be0e5c09SChris Mason 			high = mid;
285be0e5c09SChris Mason 		else {
286be0e5c09SChris Mason 			*slot = mid;
287be0e5c09SChris Mason 			return 0;
288be0e5c09SChris Mason 		}
289be0e5c09SChris Mason 	}
290be0e5c09SChris Mason 	*slot = low;
291be0e5c09SChris Mason 	return 1;
292be0e5c09SChris Mason }
293be0e5c09SChris Mason 
29497571fd0SChris Mason /*
29597571fd0SChris Mason  * simple bin_search frontend that does the right thing for
29697571fd0SChris Mason  * leaves vs nodes
29797571fd0SChris Mason  */
2989aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
299be0e5c09SChris Mason {
3007518a238SChris Mason 	if (btrfs_is_leaf(c)) {
301234b63a0SChris Mason 		struct btrfs_leaf *l = (struct btrfs_leaf *)c;
3020783fcfcSChris Mason 		return generic_bin_search((void *)l->items,
3030783fcfcSChris Mason 					  sizeof(struct btrfs_item),
3047518a238SChris Mason 					  key, btrfs_header_nritems(&c->header),
3057518a238SChris Mason 					  slot);
306be0e5c09SChris Mason 	} else {
307123abc88SChris Mason 		return generic_bin_search((void *)c->ptrs,
308123abc88SChris Mason 					  sizeof(struct btrfs_key_ptr),
3097518a238SChris Mason 					  key, btrfs_header_nritems(&c->header),
3107518a238SChris Mason 					  slot);
311be0e5c09SChris Mason 	}
312be0e5c09SChris Mason 	return -1;
313be0e5c09SChris Mason }
314be0e5c09SChris Mason 
315e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root,
316e20d96d6SChris Mason 				   struct buffer_head *parent_buf,
317bb803951SChris Mason 				   int slot)
318bb803951SChris Mason {
319e20d96d6SChris Mason 	struct btrfs_node *node = btrfs_buffer_node(parent_buf);
320bb803951SChris Mason 	if (slot < 0)
321bb803951SChris Mason 		return NULL;
3227518a238SChris Mason 	if (slot >= btrfs_header_nritems(&node->header))
323bb803951SChris Mason 		return NULL;
3241d4f8a0cSChris Mason 	return read_tree_block(root, btrfs_node_blockptr(node, slot));
325bb803951SChris Mason }
326bb803951SChris Mason 
327e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
328e089f05cSChris Mason 			 *root, struct btrfs_path *path, int level)
329bb803951SChris Mason {
330e20d96d6SChris Mason 	struct buffer_head *right_buf;
331e20d96d6SChris Mason 	struct buffer_head *mid_buf;
332e20d96d6SChris Mason 	struct buffer_head *left_buf;
333e20d96d6SChris Mason 	struct buffer_head *parent_buf = NULL;
334234b63a0SChris Mason 	struct btrfs_node *right = NULL;
335234b63a0SChris Mason 	struct btrfs_node *mid;
336234b63a0SChris Mason 	struct btrfs_node *left = NULL;
337234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
338bb803951SChris Mason 	int ret = 0;
339bb803951SChris Mason 	int wret;
340bb803951SChris Mason 	int pslot;
341bb803951SChris Mason 	int orig_slot = path->slots[level];
34254aa1f4dSChris Mason 	int err_on_enospc = 0;
34379f95c82SChris Mason 	u64 orig_ptr;
344bb803951SChris Mason 
345bb803951SChris Mason 	if (level == 0)
346bb803951SChris Mason 		return 0;
347bb803951SChris Mason 
348bb803951SChris Mason 	mid_buf = path->nodes[level];
349e20d96d6SChris Mason 	mid = btrfs_buffer_node(mid_buf);
3501d4f8a0cSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
35179f95c82SChris Mason 
352234b63a0SChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
353bb803951SChris Mason 		parent_buf = path->nodes[level + 1];
354bb803951SChris Mason 	pslot = path->slots[level + 1];
355bb803951SChris Mason 
35640689478SChris Mason 	/*
35740689478SChris Mason 	 * deal with the case where there is only one pointer in the root
35840689478SChris Mason 	 * by promoting the node below to a root
35940689478SChris Mason 	 */
360bb803951SChris Mason 	if (!parent_buf) {
361e20d96d6SChris Mason 		struct buffer_head *child;
3627eccb903SChris Mason 		u64 blocknr = bh_blocknr(mid_buf);
363bb803951SChris Mason 
3647518a238SChris Mason 		if (btrfs_header_nritems(&mid->header) != 1)
365bb803951SChris Mason 			return 0;
366bb803951SChris Mason 
367bb803951SChris Mason 		/* promote the child to a root */
368bb803951SChris Mason 		child = read_node_slot(root, mid_buf, 0);
369bb803951SChris Mason 		BUG_ON(!child);
370bb803951SChris Mason 		root->node = child;
371bb803951SChris Mason 		path->nodes[level] = NULL;
372d6025579SChris Mason 		clean_tree_block(trans, root, mid_buf);
373d6025579SChris Mason 		wait_on_buffer(mid_buf);
374bb803951SChris Mason 		/* once for the path */
375234b63a0SChris Mason 		btrfs_block_release(root, mid_buf);
376bb803951SChris Mason 		/* once for the root ptr */
377234b63a0SChris Mason 		btrfs_block_release(root, mid_buf);
378e089f05cSChris Mason 		return btrfs_free_extent(trans, root, blocknr, 1, 1);
379bb803951SChris Mason 	}
380e20d96d6SChris Mason 	parent = btrfs_buffer_node(parent_buf);
381bb803951SChris Mason 
382123abc88SChris Mason 	if (btrfs_header_nritems(&mid->header) >
383123abc88SChris Mason 	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
384bb803951SChris Mason 		return 0;
385bb803951SChris Mason 
38654aa1f4dSChris Mason 	if (btrfs_header_nritems(&mid->header) < 2)
38754aa1f4dSChris Mason 		err_on_enospc = 1;
38854aa1f4dSChris Mason 
389bb803951SChris Mason 	left_buf = read_node_slot(root, parent_buf, pslot - 1);
390bb803951SChris Mason 	right_buf = read_node_slot(root, parent_buf, pslot + 1);
39179f95c82SChris Mason 
39279f95c82SChris Mason 	/* first, try to make some room in the middle buffer */
393bb803951SChris Mason 	if (left_buf) {
39454aa1f4dSChris Mason 		wret = btrfs_cow_block(trans, root, left_buf,
39554aa1f4dSChris Mason 				       parent_buf, pslot - 1, &left_buf);
39654aa1f4dSChris Mason 		if (wret) {
39754aa1f4dSChris Mason 			ret = wret;
39854aa1f4dSChris Mason 			goto enospc;
39954aa1f4dSChris Mason 		}
400e20d96d6SChris Mason 		left = btrfs_buffer_node(left_buf);
4017518a238SChris Mason 		orig_slot += btrfs_header_nritems(&left->header);
402e089f05cSChris Mason 		wret = push_node_left(trans, root, left_buf, mid_buf);
40379f95c82SChris Mason 		if (wret < 0)
40479f95c82SChris Mason 			ret = wret;
40554aa1f4dSChris Mason 		if (btrfs_header_nritems(&mid->header) < 2)
40654aa1f4dSChris Mason 			err_on_enospc = 1;
407bb803951SChris Mason 	}
40879f95c82SChris Mason 
40979f95c82SChris Mason 	/*
41079f95c82SChris Mason 	 * then try to empty the right most buffer into the middle
41179f95c82SChris Mason 	 */
412bb803951SChris Mason 	if (right_buf) {
41354aa1f4dSChris Mason 		wret = btrfs_cow_block(trans, root, right_buf,
41454aa1f4dSChris Mason 				       parent_buf, pslot + 1, &right_buf);
41554aa1f4dSChris Mason 		if (wret) {
41654aa1f4dSChris Mason 			ret = wret;
41754aa1f4dSChris Mason 			goto enospc;
41854aa1f4dSChris Mason 		}
41954aa1f4dSChris Mason 
420e20d96d6SChris Mason 		right = btrfs_buffer_node(right_buf);
421e089f05cSChris Mason 		wret = push_node_left(trans, root, mid_buf, right_buf);
42254aa1f4dSChris Mason 		if (wret < 0 && wret != -ENOSPC)
42379f95c82SChris Mason 			ret = wret;
4247518a238SChris Mason 		if (btrfs_header_nritems(&right->header) == 0) {
4257eccb903SChris Mason 			u64 blocknr = bh_blocknr(right_buf);
426e089f05cSChris Mason 			clean_tree_block(trans, root, right_buf);
427d6025579SChris Mason 			wait_on_buffer(right_buf);
428d6025579SChris Mason 			btrfs_block_release(root, right_buf);
429bb803951SChris Mason 			right_buf = NULL;
430bb803951SChris Mason 			right = NULL;
431e089f05cSChris Mason 			wret = del_ptr(trans, root, path, level + 1, pslot +
432e089f05cSChris Mason 				       1);
433bb803951SChris Mason 			if (wret)
434bb803951SChris Mason 				ret = wret;
435e089f05cSChris Mason 			wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
436bb803951SChris Mason 			if (wret)
437bb803951SChris Mason 				ret = wret;
438bb803951SChris Mason 		} else {
439d6025579SChris Mason 			btrfs_memcpy(root, parent,
440d6025579SChris Mason 				     &parent->ptrs[pslot + 1].key,
441123abc88SChris Mason 				     &right->ptrs[0].key,
442e2fa7227SChris Mason 				     sizeof(struct btrfs_disk_key));
443d6025579SChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
444bb803951SChris Mason 		}
445bb803951SChris Mason 	}
4467518a238SChris Mason 	if (btrfs_header_nritems(&mid->header) == 1) {
44779f95c82SChris Mason 		/*
44879f95c82SChris Mason 		 * we're not allowed to leave a node with one item in the
44979f95c82SChris Mason 		 * tree during a delete.  A deletion from lower in the tree
45079f95c82SChris Mason 		 * could try to delete the only pointer in this node.
45179f95c82SChris Mason 		 * So, pull some keys from the left.
45279f95c82SChris Mason 		 * There has to be a left pointer at this point because
45379f95c82SChris Mason 		 * otherwise we would have pulled some pointers from the
45479f95c82SChris Mason 		 * right
45579f95c82SChris Mason 		 */
45679f95c82SChris Mason 		BUG_ON(!left_buf);
457e089f05cSChris Mason 		wret = balance_node_right(trans, root, mid_buf, left_buf);
45854aa1f4dSChris Mason 		if (wret < 0) {
45979f95c82SChris Mason 			ret = wret;
46054aa1f4dSChris Mason 			goto enospc;
46154aa1f4dSChris Mason 		}
46279f95c82SChris Mason 		BUG_ON(wret == 1);
46379f95c82SChris Mason 	}
4647518a238SChris Mason 	if (btrfs_header_nritems(&mid->header) == 0) {
46579f95c82SChris Mason 		/* we've managed to empty the middle node, drop it */
4667eccb903SChris Mason 		u64 blocknr = bh_blocknr(mid_buf);
467e089f05cSChris Mason 		clean_tree_block(trans, root, mid_buf);
468d6025579SChris Mason 		wait_on_buffer(mid_buf);
469d6025579SChris Mason 		btrfs_block_release(root, mid_buf);
470bb803951SChris Mason 		mid_buf = NULL;
471bb803951SChris Mason 		mid = NULL;
472e089f05cSChris Mason 		wret = del_ptr(trans, root, path, level + 1, pslot);
473bb803951SChris Mason 		if (wret)
474bb803951SChris Mason 			ret = wret;
475e089f05cSChris Mason 		wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
476bb803951SChris Mason 		if (wret)
477bb803951SChris Mason 			ret = wret;
47879f95c82SChris Mason 	} else {
47979f95c82SChris Mason 		/* update the parent key to reflect our changes */
480d6025579SChris Mason 		btrfs_memcpy(root, parent,
481d6025579SChris Mason 			     &parent->ptrs[pslot].key, &mid->ptrs[0].key,
482e2fa7227SChris Mason 			     sizeof(struct btrfs_disk_key));
483d6025579SChris Mason 		btrfs_mark_buffer_dirty(parent_buf);
48479f95c82SChris Mason 	}
485bb803951SChris Mason 
48679f95c82SChris Mason 	/* update the path */
487bb803951SChris Mason 	if (left_buf) {
4887518a238SChris Mason 		if (btrfs_header_nritems(&left->header) > orig_slot) {
489e20d96d6SChris Mason 			get_bh(left_buf);
490bb803951SChris Mason 			path->nodes[level] = left_buf;
491bb803951SChris Mason 			path->slots[level + 1] -= 1;
492bb803951SChris Mason 			path->slots[level] = orig_slot;
493bb803951SChris Mason 			if (mid_buf)
494234b63a0SChris Mason 				btrfs_block_release(root, mid_buf);
495bb803951SChris Mason 		} else {
4967518a238SChris Mason 			orig_slot -= btrfs_header_nritems(&left->header);
497bb803951SChris Mason 			path->slots[level] = orig_slot;
498bb803951SChris Mason 		}
499bb803951SChris Mason 	}
50079f95c82SChris Mason 	/* double check we haven't messed things up */
501123abc88SChris Mason 	check_block(root, path, level);
502e20d96d6SChris Mason 	if (orig_ptr !=
503e20d96d6SChris Mason 	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
5041d4f8a0cSChris Mason 				path->slots[level]))
50579f95c82SChris Mason 		BUG();
50654aa1f4dSChris Mason enospc:
507bb803951SChris Mason 	if (right_buf)
508234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
509bb803951SChris Mason 	if (left_buf)
510234b63a0SChris Mason 		btrfs_block_release(root, left_buf);
511bb803951SChris Mason 	return ret;
512bb803951SChris Mason }
513bb803951SChris Mason 
514e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */
515e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
516e66f709bSChris Mason 				struct btrfs_root *root,
517e66f709bSChris Mason 				struct btrfs_path *path, int level)
518e66f709bSChris Mason {
519e66f709bSChris Mason 	struct buffer_head *right_buf;
520e66f709bSChris Mason 	struct buffer_head *mid_buf;
521e66f709bSChris Mason 	struct buffer_head *left_buf;
522e66f709bSChris Mason 	struct buffer_head *parent_buf = NULL;
523e66f709bSChris Mason 	struct btrfs_node *right = NULL;
524e66f709bSChris Mason 	struct btrfs_node *mid;
525e66f709bSChris Mason 	struct btrfs_node *left = NULL;
526e66f709bSChris Mason 	struct btrfs_node *parent = NULL;
527e66f709bSChris Mason 	int ret = 0;
528e66f709bSChris Mason 	int wret;
529e66f709bSChris Mason 	int pslot;
530e66f709bSChris Mason 	int orig_slot = path->slots[level];
531e66f709bSChris Mason 	u64 orig_ptr;
532e66f709bSChris Mason 
533e66f709bSChris Mason 	if (level == 0)
534e66f709bSChris Mason 		return 1;
535e66f709bSChris Mason 
536e66f709bSChris Mason 	mid_buf = path->nodes[level];
537e66f709bSChris Mason 	mid = btrfs_buffer_node(mid_buf);
538e66f709bSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
539e66f709bSChris Mason 
540e66f709bSChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
541e66f709bSChris Mason 		parent_buf = path->nodes[level + 1];
542e66f709bSChris Mason 	pslot = path->slots[level + 1];
543e66f709bSChris Mason 
544e66f709bSChris Mason 	if (!parent_buf)
545e66f709bSChris Mason 		return 1;
546e66f709bSChris Mason 	parent = btrfs_buffer_node(parent_buf);
547e66f709bSChris Mason 
548e66f709bSChris Mason 	left_buf = read_node_slot(root, parent_buf, pslot - 1);
549e66f709bSChris Mason 
550e66f709bSChris Mason 	/* first, try to make some room in the middle buffer */
551e66f709bSChris Mason 	if (left_buf) {
552e66f709bSChris Mason 		u32 left_nr;
553e66f709bSChris Mason 		left = btrfs_buffer_node(left_buf);
554e66f709bSChris Mason 		left_nr = btrfs_header_nritems(&left->header);
55533ade1f8SChris Mason 		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
55633ade1f8SChris Mason 			wret = 1;
55733ade1f8SChris Mason 		} else {
55854aa1f4dSChris Mason 			ret = btrfs_cow_block(trans, root, left_buf, parent_buf,
55933ade1f8SChris Mason 					      pslot - 1, &left_buf);
56054aa1f4dSChris Mason 			if (ret)
56154aa1f4dSChris Mason 				wret = 1;
56254aa1f4dSChris Mason 			else {
56333ade1f8SChris Mason 				left = btrfs_buffer_node(left_buf);
56454aa1f4dSChris Mason 				wret = push_node_left(trans, root,
56554aa1f4dSChris Mason 						      left_buf, mid_buf);
56654aa1f4dSChris Mason 			}
56733ade1f8SChris Mason 		}
568e66f709bSChris Mason 		if (wret < 0)
569e66f709bSChris Mason 			ret = wret;
570e66f709bSChris Mason 		if (wret == 0) {
571e66f709bSChris Mason 			orig_slot += left_nr;
572e66f709bSChris Mason 			btrfs_memcpy(root, parent,
573e66f709bSChris Mason 				     &parent->ptrs[pslot].key,
574e66f709bSChris Mason 				     &mid->ptrs[0].key,
575e66f709bSChris Mason 				     sizeof(struct btrfs_disk_key));
576e66f709bSChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
577e66f709bSChris Mason 			if (btrfs_header_nritems(&left->header) > orig_slot) {
578e66f709bSChris Mason 				path->nodes[level] = left_buf;
579e66f709bSChris Mason 				path->slots[level + 1] -= 1;
580e66f709bSChris Mason 				path->slots[level] = orig_slot;
581e66f709bSChris Mason 				btrfs_block_release(root, mid_buf);
582e66f709bSChris Mason 			} else {
583e66f709bSChris Mason 				orig_slot -=
584e66f709bSChris Mason 					btrfs_header_nritems(&left->header);
585e66f709bSChris Mason 				path->slots[level] = orig_slot;
586e66f709bSChris Mason 				btrfs_block_release(root, left_buf);
587e66f709bSChris Mason 			}
588e66f709bSChris Mason 			check_node(root, path, level);
589e66f709bSChris Mason 			return 0;
590e66f709bSChris Mason 		}
591e66f709bSChris Mason 		btrfs_block_release(root, left_buf);
592e66f709bSChris Mason 	}
593e66f709bSChris Mason 	right_buf = read_node_slot(root, parent_buf, pslot + 1);
594e66f709bSChris Mason 
595e66f709bSChris Mason 	/*
596e66f709bSChris Mason 	 * then try to empty the right most buffer into the middle
597e66f709bSChris Mason 	 */
598e66f709bSChris Mason 	if (right_buf) {
59933ade1f8SChris Mason 		u32 right_nr;
600e66f709bSChris Mason 		right = btrfs_buffer_node(right_buf);
60133ade1f8SChris Mason 		right_nr = btrfs_header_nritems(&right->header);
60233ade1f8SChris Mason 		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
60333ade1f8SChris Mason 			wret = 1;
60433ade1f8SChris Mason 		} else {
60554aa1f4dSChris Mason 			ret = btrfs_cow_block(trans, root, right_buf,
60654aa1f4dSChris Mason 					      parent_buf, pslot + 1,
60754aa1f4dSChris Mason 					      &right_buf);
60854aa1f4dSChris Mason 			if (ret)
60954aa1f4dSChris Mason 				wret = 1;
61054aa1f4dSChris Mason 			else {
61133ade1f8SChris Mason 				right = btrfs_buffer_node(right_buf);
61233ade1f8SChris Mason 				wret = balance_node_right(trans, root,
61333ade1f8SChris Mason 							  right_buf, mid_buf);
61433ade1f8SChris Mason 			}
61554aa1f4dSChris Mason 		}
616e66f709bSChris Mason 		if (wret < 0)
617e66f709bSChris Mason 			ret = wret;
618e66f709bSChris Mason 		if (wret == 0) {
619e66f709bSChris Mason 			btrfs_memcpy(root, parent,
620e66f709bSChris Mason 				     &parent->ptrs[pslot + 1].key,
621e66f709bSChris Mason 				     &right->ptrs[0].key,
622e66f709bSChris Mason 				     sizeof(struct btrfs_disk_key));
623e66f709bSChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
624e66f709bSChris Mason 			if (btrfs_header_nritems(&mid->header) <= orig_slot) {
625e66f709bSChris Mason 				path->nodes[level] = right_buf;
626e66f709bSChris Mason 				path->slots[level + 1] += 1;
627e66f709bSChris Mason 				path->slots[level] = orig_slot -
628e66f709bSChris Mason 					btrfs_header_nritems(&mid->header);
629e66f709bSChris Mason 				btrfs_block_release(root, mid_buf);
630e66f709bSChris Mason 			} else {
631e66f709bSChris Mason 				btrfs_block_release(root, right_buf);
632e66f709bSChris Mason 			}
633e66f709bSChris Mason 			check_node(root, path, level);
634e66f709bSChris Mason 			return 0;
635e66f709bSChris Mason 		}
636e66f709bSChris Mason 		btrfs_block_release(root, right_buf);
637e66f709bSChris Mason 	}
638e66f709bSChris Mason 	check_node(root, path, level);
639e66f709bSChris Mason 	return 1;
640e66f709bSChris Mason }
641e66f709bSChris Mason 
64274123bd7SChris Mason /*
64374123bd7SChris Mason  * look for key in the tree.  path is filled in with nodes along the way
64474123bd7SChris Mason  * if key is found, we return zero and you can find the item in the leaf
64574123bd7SChris Mason  * level of the path (level 0)
64674123bd7SChris Mason  *
64774123bd7SChris Mason  * If the key isn't found, the path points to the slot where it should
648aa5d6bedSChris Mason  * be inserted, and 1 is returned.  If there are other errors during the
649aa5d6bedSChris Mason  * search a negative error number is returned.
65097571fd0SChris Mason  *
65197571fd0SChris Mason  * if ins_len > 0, nodes and leaves will be split as we walk down the
65297571fd0SChris Mason  * tree.  if ins_len < 0, nodes will be merged as we walk down the tree (if
65397571fd0SChris Mason  * possible)
65474123bd7SChris Mason  */
655e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
656e089f05cSChris Mason 		      *root, struct btrfs_key *key, struct btrfs_path *p, int
657e089f05cSChris Mason 		      ins_len, int cow)
658be0e5c09SChris Mason {
659e20d96d6SChris Mason 	struct buffer_head *b;
660e20d96d6SChris Mason 	struct buffer_head *cow_buf;
661234b63a0SChris Mason 	struct btrfs_node *c;
662be0e5c09SChris Mason 	int slot;
663be0e5c09SChris Mason 	int ret;
664be0e5c09SChris Mason 	int level;
6655c680ed6SChris Mason 
66622b0ebdaSChris Mason 	WARN_ON(p->nodes[0] != NULL);
66722b0ebdaSChris Mason 	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
668bb803951SChris Mason again:
669bb803951SChris Mason 	b = root->node;
670e20d96d6SChris Mason 	get_bh(b);
671eb60ceacSChris Mason 	while (b) {
672e20d96d6SChris Mason 		c = btrfs_buffer_node(b);
673e20d96d6SChris Mason 		level = btrfs_header_level(&c->header);
67402217ed2SChris Mason 		if (cow) {
67502217ed2SChris Mason 			int wret;
676e20d96d6SChris Mason 			wret = btrfs_cow_block(trans, root, b,
677e20d96d6SChris Mason 					       p->nodes[level + 1],
678e20d96d6SChris Mason 					       p->slots[level + 1],
679e089f05cSChris Mason 					       &cow_buf);
68054aa1f4dSChris Mason 			if (wret) {
68154aa1f4dSChris Mason 				btrfs_block_release(root, cow_buf);
68254aa1f4dSChris Mason 				return wret;
68354aa1f4dSChris Mason 			}
68402217ed2SChris Mason 			b = cow_buf;
6852c90e5d6SChris Mason 			c = btrfs_buffer_node(b);
68602217ed2SChris Mason 		}
68702217ed2SChris Mason 		BUG_ON(!cow && ins_len);
6882c90e5d6SChris Mason 		if (level != btrfs_header_level(&c->header))
6892c90e5d6SChris Mason 			WARN_ON(1);
6902c90e5d6SChris Mason 		level = btrfs_header_level(&c->header);
691eb60ceacSChris Mason 		p->nodes[level] = b;
692123abc88SChris Mason 		ret = check_block(root, p, level);
693aa5d6bedSChris Mason 		if (ret)
694aa5d6bedSChris Mason 			return -1;
695be0e5c09SChris Mason 		ret = bin_search(c, key, &slot);
6967518a238SChris Mason 		if (!btrfs_is_leaf(c)) {
697be0e5c09SChris Mason 			if (ret && slot > 0)
698be0e5c09SChris Mason 				slot -= 1;
699be0e5c09SChris Mason 			p->slots[level] = slot;
700d4dbff95SChris Mason 			if (ins_len > 0 && btrfs_header_nritems(&c->header) >=
701d4dbff95SChris Mason 			    BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
702e089f05cSChris Mason 				int sret = split_node(trans, root, p, level);
7035c680ed6SChris Mason 				BUG_ON(sret > 0);
7045c680ed6SChris Mason 				if (sret)
7055c680ed6SChris Mason 					return sret;
7065c680ed6SChris Mason 				b = p->nodes[level];
707e20d96d6SChris Mason 				c = btrfs_buffer_node(b);
7085c680ed6SChris Mason 				slot = p->slots[level];
709bb803951SChris Mason 			} else if (ins_len < 0) {
710e089f05cSChris Mason 				int sret = balance_level(trans, root, p,
711e089f05cSChris Mason 							 level);
712bb803951SChris Mason 				if (sret)
713bb803951SChris Mason 					return sret;
714bb803951SChris Mason 				b = p->nodes[level];
715bb803951SChris Mason 				if (!b)
716bb803951SChris Mason 					goto again;
717e20d96d6SChris Mason 				c = btrfs_buffer_node(b);
718bb803951SChris Mason 				slot = p->slots[level];
7197518a238SChris Mason 				BUG_ON(btrfs_header_nritems(&c->header) == 1);
7205c680ed6SChris Mason 			}
7211d4f8a0cSChris Mason 			b = read_tree_block(root, btrfs_node_blockptr(c, slot));
722be0e5c09SChris Mason 		} else {
723234b63a0SChris Mason 			struct btrfs_leaf *l = (struct btrfs_leaf *)c;
724be0e5c09SChris Mason 			p->slots[level] = slot;
725123abc88SChris Mason 			if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
7260783fcfcSChris Mason 			    sizeof(struct btrfs_item) + ins_len) {
727d4dbff95SChris Mason 				int sret = split_leaf(trans, root, key,
728d4dbff95SChris Mason 						      p, ins_len);
7295c680ed6SChris Mason 				BUG_ON(sret > 0);
7305c680ed6SChris Mason 				if (sret)
7315c680ed6SChris Mason 					return sret;
7325c680ed6SChris Mason 			}
733be0e5c09SChris Mason 			return ret;
734be0e5c09SChris Mason 		}
735be0e5c09SChris Mason 	}
736aa5d6bedSChris Mason 	return 1;
737be0e5c09SChris Mason }
738be0e5c09SChris Mason 
73974123bd7SChris Mason /*
74074123bd7SChris Mason  * adjust the pointers going up the tree, starting at level
74174123bd7SChris Mason  * making sure the right key of each node is points to 'key'.
74274123bd7SChris Mason  * This is used after shifting pointers to the left, so it stops
74374123bd7SChris Mason  * fixing up pointers when a given leaf/node is not in slot 0 of the
74474123bd7SChris Mason  * higher levels
745aa5d6bedSChris Mason  *
746aa5d6bedSChris Mason  * If this fails to write a tree block, it returns -1, but continues
747aa5d6bedSChris Mason  * fixing up the blocks in ram so the tree is consistent.
74874123bd7SChris Mason  */
749e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
750e089f05cSChris Mason 			  *root, struct btrfs_path *path, struct btrfs_disk_key
751e089f05cSChris Mason 			  *key, int level)
752be0e5c09SChris Mason {
753be0e5c09SChris Mason 	int i;
754aa5d6bedSChris Mason 	int ret = 0;
755234b63a0SChris Mason 	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
756234b63a0SChris Mason 		struct btrfs_node *t;
757be0e5c09SChris Mason 		int tslot = path->slots[i];
758eb60ceacSChris Mason 		if (!path->nodes[i])
759be0e5c09SChris Mason 			break;
760e20d96d6SChris Mason 		t = btrfs_buffer_node(path->nodes[i]);
761d6025579SChris Mason 		btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key));
762d6025579SChris Mason 		btrfs_mark_buffer_dirty(path->nodes[i]);
763be0e5c09SChris Mason 		if (tslot != 0)
764be0e5c09SChris Mason 			break;
765be0e5c09SChris Mason 	}
766aa5d6bedSChris Mason 	return ret;
767be0e5c09SChris Mason }
768be0e5c09SChris Mason 
76974123bd7SChris Mason /*
77074123bd7SChris Mason  * try to push data from one node into the next node left in the
77179f95c82SChris Mason  * tree.
772aa5d6bedSChris Mason  *
773aa5d6bedSChris Mason  * returns 0 if some ptrs were pushed left, < 0 if there was some horrible
774aa5d6bedSChris Mason  * error, and > 0 if there was no room in the left hand block.
77574123bd7SChris Mason  */
776e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
777e20d96d6SChris Mason 			  *root, struct buffer_head *dst_buf, struct
778e20d96d6SChris Mason 			  buffer_head *src_buf)
779be0e5c09SChris Mason {
780e20d96d6SChris Mason 	struct btrfs_node *src = btrfs_buffer_node(src_buf);
781e20d96d6SChris Mason 	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
782be0e5c09SChris Mason 	int push_items = 0;
783bb803951SChris Mason 	int src_nritems;
784bb803951SChris Mason 	int dst_nritems;
785aa5d6bedSChris Mason 	int ret = 0;
786be0e5c09SChris Mason 
7877518a238SChris Mason 	src_nritems = btrfs_header_nritems(&src->header);
7887518a238SChris Mason 	dst_nritems = btrfs_header_nritems(&dst->header);
789123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
79054aa1f4dSChris Mason 
791eb60ceacSChris Mason 	if (push_items <= 0) {
792be0e5c09SChris Mason 		return 1;
793eb60ceacSChris Mason 	}
794be0e5c09SChris Mason 
795be0e5c09SChris Mason 	if (src_nritems < push_items)
796be0e5c09SChris Mason 		push_items = src_nritems;
79779f95c82SChris Mason 
798d6025579SChris Mason 	btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs,
799123abc88SChris Mason 		     push_items * sizeof(struct btrfs_key_ptr));
800bb803951SChris Mason 	if (push_items < src_nritems) {
801d6025579SChris Mason 		btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items,
802e2fa7227SChris Mason 			(src_nritems - push_items) *
803123abc88SChris Mason 			sizeof(struct btrfs_key_ptr));
804bb803951SChris Mason 	}
8057518a238SChris Mason 	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
8067518a238SChris Mason 	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
807d6025579SChris Mason 	btrfs_mark_buffer_dirty(src_buf);
808d6025579SChris Mason 	btrfs_mark_buffer_dirty(dst_buf);
809bb803951SChris Mason 	return ret;
810be0e5c09SChris Mason }
811be0e5c09SChris Mason 
81297571fd0SChris Mason /*
81379f95c82SChris Mason  * try to push data from one node into the next node right in the
81479f95c82SChris Mason  * tree.
81579f95c82SChris Mason  *
81679f95c82SChris Mason  * returns 0 if some ptrs were pushed, < 0 if there was some horrible
81779f95c82SChris Mason  * error, and > 0 if there was no room in the right hand block.
81879f95c82SChris Mason  *
81979f95c82SChris Mason  * this will  only push up to 1/2 the contents of the left node over
82079f95c82SChris Mason  */
821e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct
822e20d96d6SChris Mason 			      btrfs_root *root, struct buffer_head *dst_buf,
823e20d96d6SChris Mason 			      struct buffer_head *src_buf)
82479f95c82SChris Mason {
825e20d96d6SChris Mason 	struct btrfs_node *src = btrfs_buffer_node(src_buf);
826e20d96d6SChris Mason 	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
82779f95c82SChris Mason 	int push_items = 0;
82879f95c82SChris Mason 	int max_push;
82979f95c82SChris Mason 	int src_nritems;
83079f95c82SChris Mason 	int dst_nritems;
83179f95c82SChris Mason 	int ret = 0;
83279f95c82SChris Mason 
8337518a238SChris Mason 	src_nritems = btrfs_header_nritems(&src->header);
8347518a238SChris Mason 	dst_nritems = btrfs_header_nritems(&dst->header);
835123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
83679f95c82SChris Mason 	if (push_items <= 0) {
83779f95c82SChris Mason 		return 1;
83879f95c82SChris Mason 	}
83979f95c82SChris Mason 
84079f95c82SChris Mason 	max_push = src_nritems / 2 + 1;
84179f95c82SChris Mason 	/* don't try to empty the node */
84279f95c82SChris Mason 	if (max_push > src_nritems)
84379f95c82SChris Mason 		return 1;
84479f95c82SChris Mason 	if (max_push < push_items)
84579f95c82SChris Mason 		push_items = max_push;
84679f95c82SChris Mason 
847d6025579SChris Mason 	btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs,
848123abc88SChris Mason 		      dst_nritems * sizeof(struct btrfs_key_ptr));
849d6025579SChris Mason 
850d6025579SChris Mason 	btrfs_memcpy(root, dst, dst->ptrs,
851d6025579SChris Mason 		     src->ptrs + src_nritems - push_items,
852123abc88SChris Mason 		     push_items * sizeof(struct btrfs_key_ptr));
85379f95c82SChris Mason 
8547518a238SChris Mason 	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
8557518a238SChris Mason 	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
85679f95c82SChris Mason 
857d6025579SChris Mason 	btrfs_mark_buffer_dirty(src_buf);
858d6025579SChris Mason 	btrfs_mark_buffer_dirty(dst_buf);
85979f95c82SChris Mason 	return ret;
86079f95c82SChris Mason }
86179f95c82SChris Mason 
86279f95c82SChris Mason /*
86397571fd0SChris Mason  * helper function to insert a new root level in the tree.
86497571fd0SChris Mason  * A new node is allocated, and a single item is inserted to
86597571fd0SChris Mason  * point to the existing root
866aa5d6bedSChris Mason  *
867aa5d6bedSChris Mason  * returns zero on success or < 0 on failure.
86897571fd0SChris Mason  */
869e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
870e089f05cSChris Mason 			   *root, struct btrfs_path *path, int level)
87174123bd7SChris Mason {
872e20d96d6SChris Mason 	struct buffer_head *t;
873234b63a0SChris Mason 	struct btrfs_node *lower;
874234b63a0SChris Mason 	struct btrfs_node *c;
875e2fa7227SChris Mason 	struct btrfs_disk_key *lower_key;
8765c680ed6SChris Mason 
8775c680ed6SChris Mason 	BUG_ON(path->nodes[level]);
8785c680ed6SChris Mason 	BUG_ON(path->nodes[level-1] != root->node);
8795c680ed6SChris Mason 
88031f3c99bSChris Mason 	t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr);
88154aa1f4dSChris Mason 	if (IS_ERR(t))
88254aa1f4dSChris Mason 		return PTR_ERR(t);
883e20d96d6SChris Mason 	c = btrfs_buffer_node(t);
884123abc88SChris Mason 	memset(c, 0, root->blocksize);
8857518a238SChris Mason 	btrfs_set_header_nritems(&c->header, 1);
8867518a238SChris Mason 	btrfs_set_header_level(&c->header, level);
8877eccb903SChris Mason 	btrfs_set_header_blocknr(&c->header, bh_blocknr(t));
8887f5c1516SChris Mason 	btrfs_set_header_generation(&c->header, trans->transid);
8894d775673SChris Mason 	btrfs_set_header_owner(&c->header, root->root_key.objectid);
890e20d96d6SChris Mason 	lower = btrfs_buffer_node(path->nodes[level-1]);
8913eb0314dSChris Mason 	memcpy(c->header.fsid, root->fs_info->disk_super->fsid,
8923eb0314dSChris Mason 	       sizeof(c->header.fsid));
8937518a238SChris Mason 	if (btrfs_is_leaf(lower))
894234b63a0SChris Mason 		lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
89574123bd7SChris Mason 	else
896123abc88SChris Mason 		lower_key = &lower->ptrs[0].key;
897d6025579SChris Mason 	btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key,
898d6025579SChris Mason 		     sizeof(struct btrfs_disk_key));
8997eccb903SChris Mason 	btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1]));
900d5719762SChris Mason 
901d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
902d5719762SChris Mason 
903cfaa7295SChris Mason 	/* the super has an extra ref to root->node */
904234b63a0SChris Mason 	btrfs_block_release(root, root->node);
90574123bd7SChris Mason 	root->node = t;
906e20d96d6SChris Mason 	get_bh(t);
90774123bd7SChris Mason 	path->nodes[level] = t;
90874123bd7SChris Mason 	path->slots[level] = 0;
90974123bd7SChris Mason 	return 0;
91074123bd7SChris Mason }
9115c680ed6SChris Mason 
9125c680ed6SChris Mason /*
9135c680ed6SChris Mason  * worker function to insert a single pointer in a node.
9145c680ed6SChris Mason  * the node should have enough room for the pointer already
91597571fd0SChris Mason  *
9165c680ed6SChris Mason  * slot and level indicate where you want the key to go, and
9175c680ed6SChris Mason  * blocknr is the block the key points to.
918aa5d6bedSChris Mason  *
919aa5d6bedSChris Mason  * returns zero on success and < 0 on any error
9205c680ed6SChris Mason  */
921e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
922e089f05cSChris Mason 		      *root, struct btrfs_path *path, struct btrfs_disk_key
923e089f05cSChris Mason 		      *key, u64 blocknr, int slot, int level)
9245c680ed6SChris Mason {
925234b63a0SChris Mason 	struct btrfs_node *lower;
9265c680ed6SChris Mason 	int nritems;
9275c680ed6SChris Mason 
9285c680ed6SChris Mason 	BUG_ON(!path->nodes[level]);
929e20d96d6SChris Mason 	lower = btrfs_buffer_node(path->nodes[level]);
9307518a238SChris Mason 	nritems = btrfs_header_nritems(&lower->header);
93174123bd7SChris Mason 	if (slot > nritems)
93274123bd7SChris Mason 		BUG();
933123abc88SChris Mason 	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
93474123bd7SChris Mason 		BUG();
93574123bd7SChris Mason 	if (slot != nritems) {
936d6025579SChris Mason 		btrfs_memmove(root, lower, lower->ptrs + slot + 1,
937d6025579SChris Mason 			      lower->ptrs + slot,
938123abc88SChris Mason 			      (nritems - slot) * sizeof(struct btrfs_key_ptr));
93974123bd7SChris Mason 	}
940d6025579SChris Mason 	btrfs_memcpy(root, lower, &lower->ptrs[slot].key,
941d6025579SChris Mason 		     key, sizeof(struct btrfs_disk_key));
9421d4f8a0cSChris Mason 	btrfs_set_node_blockptr(lower, slot, blocknr);
9437518a238SChris Mason 	btrfs_set_header_nritems(&lower->header, nritems + 1);
944d6025579SChris Mason 	btrfs_mark_buffer_dirty(path->nodes[level]);
945098f59c2SChris Mason 	check_node(root, path, level);
94674123bd7SChris Mason 	return 0;
94774123bd7SChris Mason }
94874123bd7SChris Mason 
94997571fd0SChris Mason /*
95097571fd0SChris Mason  * split the node at the specified level in path in two.
95197571fd0SChris Mason  * The path is corrected to point to the appropriate node after the split
95297571fd0SChris Mason  *
95397571fd0SChris Mason  * Before splitting this tries to make some room in the node by pushing
95497571fd0SChris Mason  * left and right, if either one works, it returns right away.
955aa5d6bedSChris Mason  *
956aa5d6bedSChris Mason  * returns 0 on success and < 0 on failure
95797571fd0SChris Mason  */
958e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
959e089f05cSChris Mason 		      *root, struct btrfs_path *path, int level)
960be0e5c09SChris Mason {
961e20d96d6SChris Mason 	struct buffer_head *t;
962234b63a0SChris Mason 	struct btrfs_node *c;
963e20d96d6SChris Mason 	struct buffer_head *split_buffer;
964234b63a0SChris Mason 	struct btrfs_node *split;
965be0e5c09SChris Mason 	int mid;
9665c680ed6SChris Mason 	int ret;
967aa5d6bedSChris Mason 	int wret;
9687518a238SChris Mason 	u32 c_nritems;
969be0e5c09SChris Mason 
9705c680ed6SChris Mason 	t = path->nodes[level];
971e20d96d6SChris Mason 	c = btrfs_buffer_node(t);
9725c680ed6SChris Mason 	if (t == root->node) {
9735c680ed6SChris Mason 		/* trying to split the root, lets make a new one */
974e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, level + 1);
9755c680ed6SChris Mason 		if (ret)
9765c680ed6SChris Mason 			return ret;
977e66f709bSChris Mason 	} else {
978e66f709bSChris Mason 		ret = push_nodes_for_insert(trans, root, path, level);
979e66f709bSChris Mason 		t = path->nodes[level];
980e66f709bSChris Mason 		c = btrfs_buffer_node(t);
981e66f709bSChris Mason 		if (!ret &&
982e66f709bSChris Mason 		    btrfs_header_nritems(&c->header) <
983e66f709bSChris Mason 		    BTRFS_NODEPTRS_PER_BLOCK(root) - 1)
984e66f709bSChris Mason 			return 0;
98554aa1f4dSChris Mason 		if (ret < 0)
98654aa1f4dSChris Mason 			return ret;
9875c680ed6SChris Mason 	}
988e66f709bSChris Mason 
9897518a238SChris Mason 	c_nritems = btrfs_header_nritems(&c->header);
99031f3c99bSChris Mason 	split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr);
99154aa1f4dSChris Mason 	if (IS_ERR(split_buffer))
99254aa1f4dSChris Mason 		return PTR_ERR(split_buffer);
99354aa1f4dSChris Mason 
994e20d96d6SChris Mason 	split = btrfs_buffer_node(split_buffer);
9957518a238SChris Mason 	btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
9969a6f11edSChris Mason 	btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
9977eccb903SChris Mason 	btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer));
9987f5c1516SChris Mason 	btrfs_set_header_generation(&split->header, trans->transid);
9994d775673SChris Mason 	btrfs_set_header_owner(&split->header, root->root_key.objectid);
10003eb0314dSChris Mason 	memcpy(split->header.fsid, root->fs_info->disk_super->fsid,
10013eb0314dSChris Mason 	       sizeof(split->header.fsid));
10027518a238SChris Mason 	mid = (c_nritems + 1) / 2;
1003d6025579SChris Mason 	btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid,
1004123abc88SChris Mason 		     (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
10057518a238SChris Mason 	btrfs_set_header_nritems(&split->header, c_nritems - mid);
10067518a238SChris Mason 	btrfs_set_header_nritems(&c->header, mid);
1007aa5d6bedSChris Mason 	ret = 0;
1008aa5d6bedSChris Mason 
1009d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
1010d6025579SChris Mason 	btrfs_mark_buffer_dirty(split_buffer);
1011e089f05cSChris Mason 	wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
10127eccb903SChris Mason 			  bh_blocknr(split_buffer), path->slots[level + 1] + 1,
1013123abc88SChris Mason 			  level + 1);
1014aa5d6bedSChris Mason 	if (wret)
1015aa5d6bedSChris Mason 		ret = wret;
1016aa5d6bedSChris Mason 
10175de08d7dSChris Mason 	if (path->slots[level] >= mid) {
10185c680ed6SChris Mason 		path->slots[level] -= mid;
1019234b63a0SChris Mason 		btrfs_block_release(root, t);
10205c680ed6SChris Mason 		path->nodes[level] = split_buffer;
10215c680ed6SChris Mason 		path->slots[level + 1] += 1;
1022eb60ceacSChris Mason 	} else {
1023234b63a0SChris Mason 		btrfs_block_release(root, split_buffer);
1024be0e5c09SChris Mason 	}
1025aa5d6bedSChris Mason 	return ret;
1026be0e5c09SChris Mason }
1027be0e5c09SChris Mason 
102874123bd7SChris Mason /*
102974123bd7SChris Mason  * how many bytes are required to store the items in a leaf.  start
103074123bd7SChris Mason  * and nr indicate which items in the leaf to check.  This totals up the
103174123bd7SChris Mason  * space used both by the item structs and the item data
103274123bd7SChris Mason  */
1033234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
1034be0e5c09SChris Mason {
1035be0e5c09SChris Mason 	int data_len;
1036d4dbff95SChris Mason 	int nritems = btrfs_header_nritems(&l->header);
1037d4dbff95SChris Mason 	int end = min(nritems, start + nr) - 1;
1038be0e5c09SChris Mason 
1039be0e5c09SChris Mason 	if (!nr)
1040be0e5c09SChris Mason 		return 0;
10410783fcfcSChris Mason 	data_len = btrfs_item_end(l->items + start);
10420783fcfcSChris Mason 	data_len = data_len - btrfs_item_offset(l->items + end);
10430783fcfcSChris Mason 	data_len += sizeof(struct btrfs_item) * nr;
1044d4dbff95SChris Mason 	WARN_ON(data_len < 0);
1045be0e5c09SChris Mason 	return data_len;
1046be0e5c09SChris Mason }
1047be0e5c09SChris Mason 
104874123bd7SChris Mason /*
1049d4dbff95SChris Mason  * The space between the end of the leaf items and
1050d4dbff95SChris Mason  * the start of the leaf data.  IOW, how much room
1051d4dbff95SChris Mason  * the leaf has left for both items and data
1052d4dbff95SChris Mason  */
1053d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf)
1054d4dbff95SChris Mason {
1055d4dbff95SChris Mason 	int nritems = btrfs_header_nritems(&leaf->header);
1056d4dbff95SChris Mason 	return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems);
1057d4dbff95SChris Mason }
1058d4dbff95SChris Mason 
1059d4dbff95SChris Mason /*
106000ec4c51SChris Mason  * push some data in the path leaf to the right, trying to free up at
106100ec4c51SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
1062aa5d6bedSChris Mason  *
1063aa5d6bedSChris Mason  * returns 1 if the push failed because the other node didn't have enough
1064aa5d6bedSChris Mason  * room, 0 if everything worked out and < 0 if there were major errors.
106500ec4c51SChris Mason  */
1066e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
1067e089f05cSChris Mason 			   *root, struct btrfs_path *path, int data_size)
106800ec4c51SChris Mason {
1069e20d96d6SChris Mason 	struct buffer_head *left_buf = path->nodes[0];
1070e20d96d6SChris Mason 	struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf);
1071234b63a0SChris Mason 	struct btrfs_leaf *right;
1072e20d96d6SChris Mason 	struct buffer_head *right_buf;
1073e20d96d6SChris Mason 	struct buffer_head *upper;
1074e20d96d6SChris Mason 	struct btrfs_node *upper_node;
107500ec4c51SChris Mason 	int slot;
107600ec4c51SChris Mason 	int i;
107700ec4c51SChris Mason 	int free_space;
107800ec4c51SChris Mason 	int push_space = 0;
107900ec4c51SChris Mason 	int push_items = 0;
10800783fcfcSChris Mason 	struct btrfs_item *item;
10817518a238SChris Mason 	u32 left_nritems;
10827518a238SChris Mason 	u32 right_nritems;
108354aa1f4dSChris Mason 	int ret;
108400ec4c51SChris Mason 
108500ec4c51SChris Mason 	slot = path->slots[1];
108600ec4c51SChris Mason 	if (!path->nodes[1]) {
108700ec4c51SChris Mason 		return 1;
108800ec4c51SChris Mason 	}
108900ec4c51SChris Mason 	upper = path->nodes[1];
1090e20d96d6SChris Mason 	upper_node = btrfs_buffer_node(upper);
1091e20d96d6SChris Mason 	if (slot >= btrfs_header_nritems(&upper_node->header) - 1) {
109200ec4c51SChris Mason 		return 1;
109300ec4c51SChris Mason 	}
1094e20d96d6SChris Mason 	right_buf = read_tree_block(root,
1095e20d96d6SChris Mason 		    btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1));
1096e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buf);
1097123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
10980783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1099234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
110000ec4c51SChris Mason 		return 1;
110100ec4c51SChris Mason 	}
110202217ed2SChris Mason 	/* cow and double check */
110354aa1f4dSChris Mason 	ret = btrfs_cow_block(trans, root, right_buf, upper,
110454aa1f4dSChris Mason 			      slot + 1, &right_buf);
110554aa1f4dSChris Mason 	if (ret) {
110654aa1f4dSChris Mason 		btrfs_block_release(root, right_buf);
110754aa1f4dSChris Mason 		return 1;
110854aa1f4dSChris Mason 	}
1109e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buf);
1110123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
11110783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1112234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
111302217ed2SChris Mason 		return 1;
111402217ed2SChris Mason 	}
111502217ed2SChris Mason 
11167518a238SChris Mason 	left_nritems = btrfs_header_nritems(&left->header);
1117a429e513SChris Mason 	if (left_nritems == 0) {
1118a429e513SChris Mason 		btrfs_block_release(root, right_buf);
1119a429e513SChris Mason 		return 1;
1120a429e513SChris Mason 	}
1121a429e513SChris Mason 	for (i = left_nritems - 1; i >= 1; i--) {
112200ec4c51SChris Mason 		item = left->items + i;
112300ec4c51SChris Mason 		if (path->slots[0] == i)
112400ec4c51SChris Mason 			push_space += data_size + sizeof(*item);
11250783fcfcSChris Mason 		if (btrfs_item_size(item) + sizeof(*item) + push_space >
11260783fcfcSChris Mason 		    free_space)
112700ec4c51SChris Mason 			break;
112800ec4c51SChris Mason 		push_items++;
11290783fcfcSChris Mason 		push_space += btrfs_item_size(item) + sizeof(*item);
113000ec4c51SChris Mason 	}
113100ec4c51SChris Mason 	if (push_items == 0) {
1132234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
113300ec4c51SChris Mason 		return 1;
113400ec4c51SChris Mason 	}
1135a429e513SChris Mason 	if (push_items == left_nritems)
1136a429e513SChris Mason 		WARN_ON(1);
11377518a238SChris Mason 	right_nritems = btrfs_header_nritems(&right->header);
113800ec4c51SChris Mason 	/* push left to right */
11390783fcfcSChris Mason 	push_space = btrfs_item_end(left->items + left_nritems - push_items);
1140123abc88SChris Mason 	push_space -= leaf_data_end(root, left);
114100ec4c51SChris Mason 	/* make room in the right data area */
1142d6025579SChris Mason 	btrfs_memmove(root, right, btrfs_leaf_data(right) +
1143d6025579SChris Mason 		      leaf_data_end(root, right) - push_space,
1144d6025579SChris Mason 		      btrfs_leaf_data(right) +
1145d6025579SChris Mason 		      leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) -
1146d6025579SChris Mason 		      leaf_data_end(root, right));
114700ec4c51SChris Mason 	/* copy from the left data area */
1148d6025579SChris Mason 	btrfs_memcpy(root, right, btrfs_leaf_data(right) +
1149d6025579SChris Mason 		     BTRFS_LEAF_DATA_SIZE(root) - push_space,
1150d6025579SChris Mason 		     btrfs_leaf_data(left) + leaf_data_end(root, left),
1151d6025579SChris Mason 		     push_space);
1152d6025579SChris Mason 	btrfs_memmove(root, right, right->items + push_items, right->items,
11530783fcfcSChris Mason 		right_nritems * sizeof(struct btrfs_item));
115400ec4c51SChris Mason 	/* copy the items from left to right */
1155d6025579SChris Mason 	btrfs_memcpy(root, right, right->items, left->items +
1156d6025579SChris Mason 		     left_nritems - push_items,
11570783fcfcSChris Mason 		     push_items * sizeof(struct btrfs_item));
115800ec4c51SChris Mason 
115900ec4c51SChris Mason 	/* update the item pointers */
11607518a238SChris Mason 	right_nritems += push_items;
11617518a238SChris Mason 	btrfs_set_header_nritems(&right->header, right_nritems);
1162123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
11637518a238SChris Mason 	for (i = 0; i < right_nritems; i++) {
11640783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, push_space -
11650783fcfcSChris Mason 				      btrfs_item_size(right->items + i));
11660783fcfcSChris Mason 		push_space = btrfs_item_offset(right->items + i);
116700ec4c51SChris Mason 	}
11687518a238SChris Mason 	left_nritems -= push_items;
11697518a238SChris Mason 	btrfs_set_header_nritems(&left->header, left_nritems);
117000ec4c51SChris Mason 
1171d6025579SChris Mason 	btrfs_mark_buffer_dirty(left_buf);
1172d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buf);
1173a429e513SChris Mason 
1174d6025579SChris Mason 	btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key,
1175e2fa7227SChris Mason 		&right->items[0].key, sizeof(struct btrfs_disk_key));
1176d6025579SChris Mason 	btrfs_mark_buffer_dirty(upper);
117702217ed2SChris Mason 
117800ec4c51SChris Mason 	/* then fixup the leaf pointer in the path */
11797518a238SChris Mason 	if (path->slots[0] >= left_nritems) {
11807518a238SChris Mason 		path->slots[0] -= left_nritems;
1181234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
118200ec4c51SChris Mason 		path->nodes[0] = right_buf;
118300ec4c51SChris Mason 		path->slots[1] += 1;
118400ec4c51SChris Mason 	} else {
1185234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
118600ec4c51SChris Mason 	}
1187098f59c2SChris Mason 	if (path->nodes[1])
1188098f59c2SChris Mason 		check_node(root, path, 1);
118900ec4c51SChris Mason 	return 0;
119000ec4c51SChris Mason }
119100ec4c51SChris Mason /*
119274123bd7SChris Mason  * push some data in the path leaf to the left, trying to free up at
119374123bd7SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
119474123bd7SChris Mason  */
1195e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
1196e089f05cSChris Mason 			  *root, struct btrfs_path *path, int data_size)
1197be0e5c09SChris Mason {
1198e20d96d6SChris Mason 	struct buffer_head *right_buf = path->nodes[0];
1199e20d96d6SChris Mason 	struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf);
1200e20d96d6SChris Mason 	struct buffer_head *t;
1201234b63a0SChris Mason 	struct btrfs_leaf *left;
1202be0e5c09SChris Mason 	int slot;
1203be0e5c09SChris Mason 	int i;
1204be0e5c09SChris Mason 	int free_space;
1205be0e5c09SChris Mason 	int push_space = 0;
1206be0e5c09SChris Mason 	int push_items = 0;
12070783fcfcSChris Mason 	struct btrfs_item *item;
12087518a238SChris Mason 	u32 old_left_nritems;
1209aa5d6bedSChris Mason 	int ret = 0;
1210aa5d6bedSChris Mason 	int wret;
1211be0e5c09SChris Mason 
1212be0e5c09SChris Mason 	slot = path->slots[1];
1213be0e5c09SChris Mason 	if (slot == 0) {
1214be0e5c09SChris Mason 		return 1;
1215be0e5c09SChris Mason 	}
1216be0e5c09SChris Mason 	if (!path->nodes[1]) {
1217be0e5c09SChris Mason 		return 1;
1218be0e5c09SChris Mason 	}
1219e20d96d6SChris Mason 	t = read_tree_block(root,
1220e20d96d6SChris Mason 	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1));
1221e20d96d6SChris Mason 	left = btrfs_buffer_leaf(t);
1222123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
12230783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1224234b63a0SChris Mason 		btrfs_block_release(root, t);
1225be0e5c09SChris Mason 		return 1;
1226be0e5c09SChris Mason 	}
122702217ed2SChris Mason 
122802217ed2SChris Mason 	/* cow and double check */
122954aa1f4dSChris Mason 	ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
123054aa1f4dSChris Mason 	if (ret) {
123154aa1f4dSChris Mason 		/* we hit -ENOSPC, but it isn't fatal here */
123254aa1f4dSChris Mason 		return 1;
123354aa1f4dSChris Mason 	}
1234e20d96d6SChris Mason 	left = btrfs_buffer_leaf(t);
1235123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
12360783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1237234b63a0SChris Mason 		btrfs_block_release(root, t);
123802217ed2SChris Mason 		return 1;
123902217ed2SChris Mason 	}
124002217ed2SChris Mason 
1241a429e513SChris Mason 	if (btrfs_header_nritems(&right->header) == 0) {
1242a429e513SChris Mason 		btrfs_block_release(root, t);
1243a429e513SChris Mason 		return 1;
1244a429e513SChris Mason 	}
1245a429e513SChris Mason 
1246a429e513SChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) {
1247be0e5c09SChris Mason 		item = right->items + i;
1248be0e5c09SChris Mason 		if (path->slots[0] == i)
1249be0e5c09SChris Mason 			push_space += data_size + sizeof(*item);
12500783fcfcSChris Mason 		if (btrfs_item_size(item) + sizeof(*item) + push_space >
12510783fcfcSChris Mason 		    free_space)
1252be0e5c09SChris Mason 			break;
1253be0e5c09SChris Mason 		push_items++;
12540783fcfcSChris Mason 		push_space += btrfs_item_size(item) + sizeof(*item);
1255be0e5c09SChris Mason 	}
1256be0e5c09SChris Mason 	if (push_items == 0) {
1257234b63a0SChris Mason 		btrfs_block_release(root, t);
1258be0e5c09SChris Mason 		return 1;
1259be0e5c09SChris Mason 	}
1260a429e513SChris Mason 	if (push_items == btrfs_header_nritems(&right->header))
1261a429e513SChris Mason 		WARN_ON(1);
1262be0e5c09SChris Mason 	/* push data from right to left */
1263d6025579SChris Mason 	btrfs_memcpy(root, left, left->items +
1264d6025579SChris Mason 		     btrfs_header_nritems(&left->header),
12650783fcfcSChris Mason 		     right->items, push_items * sizeof(struct btrfs_item));
1266123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root) -
12670783fcfcSChris Mason 		     btrfs_item_offset(right->items + push_items -1);
1268d6025579SChris Mason 	btrfs_memcpy(root, left, btrfs_leaf_data(left) +
1269d6025579SChris Mason 		     leaf_data_end(root, left) - push_space,
1270123abc88SChris Mason 		     btrfs_leaf_data(right) +
1271123abc88SChris Mason 		     btrfs_item_offset(right->items + push_items - 1),
1272be0e5c09SChris Mason 		     push_space);
12737518a238SChris Mason 	old_left_nritems = btrfs_header_nritems(&left->header);
1274eb60ceacSChris Mason 	BUG_ON(old_left_nritems < 0);
1275eb60ceacSChris Mason 
1276be0e5c09SChris Mason 	for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
1277123abc88SChris Mason 		u32 ioff = btrfs_item_offset(left->items + i);
1278123abc88SChris Mason 		btrfs_set_item_offset(left->items + i, ioff -
1279123abc88SChris Mason 				     (BTRFS_LEAF_DATA_SIZE(root) -
12800783fcfcSChris Mason 				      btrfs_item_offset(left->items +
12810783fcfcSChris Mason 						        old_left_nritems - 1)));
1282be0e5c09SChris Mason 	}
12837518a238SChris Mason 	btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
1284be0e5c09SChris Mason 
1285be0e5c09SChris Mason 	/* fixup right node */
12860783fcfcSChris Mason 	push_space = btrfs_item_offset(right->items + push_items - 1) -
1287123abc88SChris Mason 		     leaf_data_end(root, right);
1288d6025579SChris Mason 	btrfs_memmove(root, right, btrfs_leaf_data(right) +
1289d6025579SChris Mason 		      BTRFS_LEAF_DATA_SIZE(root) - push_space,
1290d6025579SChris Mason 		      btrfs_leaf_data(right) +
1291123abc88SChris Mason 		      leaf_data_end(root, right), push_space);
1292d6025579SChris Mason 	btrfs_memmove(root, right, right->items, right->items + push_items,
12937518a238SChris Mason 		(btrfs_header_nritems(&right->header) - push_items) *
12940783fcfcSChris Mason 		sizeof(struct btrfs_item));
12957518a238SChris Mason 	btrfs_set_header_nritems(&right->header,
12967518a238SChris Mason 				 btrfs_header_nritems(&right->header) -
12977518a238SChris Mason 				 push_items);
1298123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
1299eb60ceacSChris Mason 
13007518a238SChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
13010783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, push_space -
13020783fcfcSChris Mason 				      btrfs_item_size(right->items + i));
13030783fcfcSChris Mason 		push_space = btrfs_item_offset(right->items + i);
1304be0e5c09SChris Mason 	}
1305eb60ceacSChris Mason 
1306d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
1307d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buf);
1308098f59c2SChris Mason 
1309e089f05cSChris Mason 	wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
1310aa5d6bedSChris Mason 	if (wret)
1311aa5d6bedSChris Mason 		ret = wret;
1312be0e5c09SChris Mason 
1313be0e5c09SChris Mason 	/* then fixup the leaf pointer in the path */
1314be0e5c09SChris Mason 	if (path->slots[0] < push_items) {
1315be0e5c09SChris Mason 		path->slots[0] += old_left_nritems;
1316234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
1317eb60ceacSChris Mason 		path->nodes[0] = t;
1318be0e5c09SChris Mason 		path->slots[1] -= 1;
1319be0e5c09SChris Mason 	} else {
1320234b63a0SChris Mason 		btrfs_block_release(root, t);
1321be0e5c09SChris Mason 		path->slots[0] -= push_items;
1322be0e5c09SChris Mason 	}
1323eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
1324098f59c2SChris Mason 	if (path->nodes[1])
1325098f59c2SChris Mason 		check_node(root, path, 1);
1326aa5d6bedSChris Mason 	return ret;
1327be0e5c09SChris Mason }
1328be0e5c09SChris Mason 
132974123bd7SChris Mason /*
133074123bd7SChris Mason  * split the path's leaf in two, making sure there is at least data_size
133174123bd7SChris Mason  * available for the resulting leaf level of the path.
1332aa5d6bedSChris Mason  *
1333aa5d6bedSChris Mason  * returns 0 if all went well and < 0 on failure.
133474123bd7SChris Mason  */
1335e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1336d4dbff95SChris Mason 		      *root, struct btrfs_key *ins_key,
1337d4dbff95SChris Mason 		      struct btrfs_path *path, int data_size)
1338be0e5c09SChris Mason {
1339e20d96d6SChris Mason 	struct buffer_head *l_buf;
1340234b63a0SChris Mason 	struct btrfs_leaf *l;
13417518a238SChris Mason 	u32 nritems;
1342eb60ceacSChris Mason 	int mid;
1343eb60ceacSChris Mason 	int slot;
1344234b63a0SChris Mason 	struct btrfs_leaf *right;
1345e20d96d6SChris Mason 	struct buffer_head *right_buffer;
13460783fcfcSChris Mason 	int space_needed = data_size + sizeof(struct btrfs_item);
1347be0e5c09SChris Mason 	int data_copy_size;
1348be0e5c09SChris Mason 	int rt_data_off;
1349be0e5c09SChris Mason 	int i;
1350d4dbff95SChris Mason 	int ret = 0;
1351aa5d6bedSChris Mason 	int wret;
1352d4dbff95SChris Mason 	int double_split = 0;
1353d4dbff95SChris Mason 	struct btrfs_disk_key disk_key;
1354be0e5c09SChris Mason 
135540689478SChris Mason 	/* first try to make some room by pushing left and right */
1356e089f05cSChris Mason 	wret = push_leaf_left(trans, root, path, data_size);
1357eaee50e8SChris Mason 	if (wret < 0)
1358eaee50e8SChris Mason 		return wret;
1359eaee50e8SChris Mason 	if (wret) {
1360e089f05cSChris Mason 		wret = push_leaf_right(trans, root, path, data_size);
1361eaee50e8SChris Mason 		if (wret < 0)
1362eaee50e8SChris Mason 			return wret;
1363eaee50e8SChris Mason 	}
1364eb60ceacSChris Mason 	l_buf = path->nodes[0];
1365e20d96d6SChris Mason 	l = btrfs_buffer_leaf(l_buf);
1366aa5d6bedSChris Mason 
1367aa5d6bedSChris Mason 	/* did the pushes work? */
1368123abc88SChris Mason 	if (btrfs_leaf_free_space(root, l) >=
1369123abc88SChris Mason 	    sizeof(struct btrfs_item) + data_size)
1370be0e5c09SChris Mason 		return 0;
1371aa5d6bedSChris Mason 
13725c680ed6SChris Mason 	if (!path->nodes[1]) {
1373e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, 1);
13745c680ed6SChris Mason 		if (ret)
13755c680ed6SChris Mason 			return ret;
13765c680ed6SChris Mason 	}
1377eb60ceacSChris Mason 	slot = path->slots[0];
13787518a238SChris Mason 	nritems = btrfs_header_nritems(&l->header);
1379eb60ceacSChris Mason 	mid = (nritems + 1)/ 2;
138054aa1f4dSChris Mason 
138131f3c99bSChris Mason 	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
138254aa1f4dSChris Mason 	if (IS_ERR(right_buffer))
138354aa1f4dSChris Mason 		return PTR_ERR(right_buffer);
138454aa1f4dSChris Mason 
1385e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buffer);
1386123abc88SChris Mason 	memset(&right->header, 0, sizeof(right->header));
13877eccb903SChris Mason 	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
13887f5c1516SChris Mason 	btrfs_set_header_generation(&right->header, trans->transid);
13894d775673SChris Mason 	btrfs_set_header_owner(&right->header, root->root_key.objectid);
13907518a238SChris Mason 	btrfs_set_header_level(&right->header, 0);
13913eb0314dSChris Mason 	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
13923eb0314dSChris Mason 	       sizeof(right->header.fsid));
1393d4dbff95SChris Mason 	if (mid <= slot) {
1394d4dbff95SChris Mason 		if (nritems == 1 ||
1395d4dbff95SChris Mason 		    leaf_space_used(l, mid, nritems - mid) + space_needed >
1396d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
1397d4dbff95SChris Mason 			if (slot >= nritems) {
1398d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
1399d4dbff95SChris Mason 				btrfs_set_header_nritems(&right->header, 0);
1400d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
1401d4dbff95SChris Mason 						  &disk_key,
14027eccb903SChris Mason 						  bh_blocknr(right_buffer),
1403d4dbff95SChris Mason 						  path->slots[1] + 1, 1);
1404d4dbff95SChris Mason 				if (wret)
1405d4dbff95SChris Mason 					ret = wret;
1406d4dbff95SChris Mason 				btrfs_block_release(root, path->nodes[0]);
1407d4dbff95SChris Mason 				path->nodes[0] = right_buffer;
1408d4dbff95SChris Mason 				path->slots[0] = 0;
1409d4dbff95SChris Mason 				path->slots[1] += 1;
1410d4dbff95SChris Mason 				return ret;
1411d4dbff95SChris Mason 			}
1412d4dbff95SChris Mason 			mid = slot;
1413d4dbff95SChris Mason 			double_split = 1;
1414d4dbff95SChris Mason 		}
1415d4dbff95SChris Mason 	} else {
1416d4dbff95SChris Mason 		if (leaf_space_used(l, 0, mid + 1) + space_needed >
1417d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
1418d4dbff95SChris Mason 			if (slot == 0) {
1419d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
1420d4dbff95SChris Mason 				btrfs_set_header_nritems(&right->header, 0);
1421d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
1422d4dbff95SChris Mason 						  &disk_key,
14237eccb903SChris Mason 						  bh_blocknr(right_buffer),
1424098f59c2SChris Mason 						  path->slots[1], 1);
1425d4dbff95SChris Mason 				if (wret)
1426d4dbff95SChris Mason 					ret = wret;
1427d4dbff95SChris Mason 				btrfs_block_release(root, path->nodes[0]);
1428d4dbff95SChris Mason 				path->nodes[0] = right_buffer;
1429d4dbff95SChris Mason 				path->slots[0] = 0;
1430a429e513SChris Mason 				if (path->slots[1] == 0) {
1431a429e513SChris Mason 					wret = fixup_low_keys(trans, root,
1432a429e513SChris Mason 					           path, &disk_key, 1);
1433a429e513SChris Mason 					if (wret)
1434a429e513SChris Mason 						ret = wret;
1435a429e513SChris Mason 				}
1436d4dbff95SChris Mason 				return ret;
1437d4dbff95SChris Mason 			}
1438d4dbff95SChris Mason 			mid = slot;
1439d4dbff95SChris Mason 			double_split = 1;
1440d4dbff95SChris Mason 		}
1441d4dbff95SChris Mason 	}
1442d4dbff95SChris Mason 	btrfs_set_header_nritems(&right->header, nritems - mid);
1443123abc88SChris Mason 	data_copy_size = btrfs_item_end(l->items + mid) -
1444123abc88SChris Mason 			 leaf_data_end(root, l);
1445d6025579SChris Mason 	btrfs_memcpy(root, right, right->items, l->items + mid,
14460783fcfcSChris Mason 		     (nritems - mid) * sizeof(struct btrfs_item));
1447d6025579SChris Mason 	btrfs_memcpy(root, right,
1448d6025579SChris Mason 		     btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
1449123abc88SChris Mason 		     data_copy_size, btrfs_leaf_data(l) +
1450123abc88SChris Mason 		     leaf_data_end(root, l), data_copy_size);
1451123abc88SChris Mason 	rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
1452123abc88SChris Mason 		      btrfs_item_end(l->items + mid);
145374123bd7SChris Mason 
14540783fcfcSChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
1455123abc88SChris Mason 		u32 ioff = btrfs_item_offset(right->items + i);
14560783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
14570783fcfcSChris Mason 	}
145874123bd7SChris Mason 
14597518a238SChris Mason 	btrfs_set_header_nritems(&l->header, mid);
1460aa5d6bedSChris Mason 	ret = 0;
1461e089f05cSChris Mason 	wret = insert_ptr(trans, root, path, &right->items[0].key,
14627eccb903SChris Mason 			  bh_blocknr(right_buffer), path->slots[1] + 1, 1);
1463aa5d6bedSChris Mason 	if (wret)
1464aa5d6bedSChris Mason 		ret = wret;
1465d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buffer);
1466d6025579SChris Mason 	btrfs_mark_buffer_dirty(l_buf);
1467eb60ceacSChris Mason 	BUG_ON(path->slots[0] != slot);
1468be0e5c09SChris Mason 	if (mid <= slot) {
1469234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
1470eb60ceacSChris Mason 		path->nodes[0] = right_buffer;
1471be0e5c09SChris Mason 		path->slots[0] -= mid;
1472be0e5c09SChris Mason 		path->slots[1] += 1;
1473eb60ceacSChris Mason 	} else
1474234b63a0SChris Mason 		btrfs_block_release(root, right_buffer);
1475eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
1476098f59c2SChris Mason 	check_node(root, path, 1);
1477d4dbff95SChris Mason 
1478d4dbff95SChris Mason 	if (!double_split)
1479d4dbff95SChris Mason 		return ret;
148031f3c99bSChris Mason 	right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
148154aa1f4dSChris Mason 	if (IS_ERR(right_buffer))
148254aa1f4dSChris Mason 		return PTR_ERR(right_buffer);
148354aa1f4dSChris Mason 
1484d4dbff95SChris Mason 	right = btrfs_buffer_leaf(right_buffer);
1485d4dbff95SChris Mason 	memset(&right->header, 0, sizeof(right->header));
14867eccb903SChris Mason 	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1487d4dbff95SChris Mason 	btrfs_set_header_generation(&right->header, trans->transid);
14884d775673SChris Mason 	btrfs_set_header_owner(&right->header, root->root_key.objectid);
1489d4dbff95SChris Mason 	btrfs_set_header_level(&right->header, 0);
14903eb0314dSChris Mason 	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
14913eb0314dSChris Mason 	       sizeof(right->header.fsid));
1492d4dbff95SChris Mason 	btrfs_cpu_key_to_disk(&disk_key, ins_key);
1493d4dbff95SChris Mason 	btrfs_set_header_nritems(&right->header, 0);
1494d4dbff95SChris Mason 	wret = insert_ptr(trans, root, path,
1495d4dbff95SChris Mason 			  &disk_key,
14967eccb903SChris Mason 			  bh_blocknr(right_buffer),
1497d4dbff95SChris Mason 			  path->slots[1], 1);
1498d4dbff95SChris Mason 	if (wret)
1499d4dbff95SChris Mason 		ret = wret;
1500a429e513SChris Mason 	if (path->slots[1] == 0) {
1501a429e513SChris Mason 		wret = fixup_low_keys(trans, root, path, &disk_key, 1);
1502a429e513SChris Mason 		if (wret)
1503a429e513SChris Mason 			ret = wret;
1504a429e513SChris Mason 	}
1505d4dbff95SChris Mason 	btrfs_block_release(root, path->nodes[0]);
1506d4dbff95SChris Mason 	path->nodes[0] = right_buffer;
1507d4dbff95SChris Mason 	path->slots[0] = 0;
1508d4dbff95SChris Mason 	check_node(root, path, 1);
1509d4dbff95SChris Mason 	check_leaf(root, path, 0);
1510be0e5c09SChris Mason 	return ret;
1511be0e5c09SChris Mason }
1512be0e5c09SChris Mason 
1513b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans,
1514b18c6685SChris Mason 			struct btrfs_root *root,
1515b18c6685SChris Mason 			struct btrfs_path *path,
1516b18c6685SChris Mason 			u32 new_size)
1517b18c6685SChris Mason {
1518b18c6685SChris Mason 	int ret = 0;
1519b18c6685SChris Mason 	int slot;
1520b18c6685SChris Mason 	int slot_orig;
1521b18c6685SChris Mason 	struct btrfs_leaf *leaf;
1522b18c6685SChris Mason 	struct buffer_head *leaf_buf;
1523b18c6685SChris Mason 	u32 nritems;
1524b18c6685SChris Mason 	unsigned int data_end;
1525b18c6685SChris Mason 	unsigned int old_data_start;
1526b18c6685SChris Mason 	unsigned int old_size;
1527b18c6685SChris Mason 	unsigned int size_diff;
1528b18c6685SChris Mason 	int i;
1529b18c6685SChris Mason 
1530b18c6685SChris Mason 	slot_orig = path->slots[0];
1531b18c6685SChris Mason 	leaf_buf = path->nodes[0];
1532b18c6685SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
1533b18c6685SChris Mason 
1534b18c6685SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1535b18c6685SChris Mason 	data_end = leaf_data_end(root, leaf);
1536b18c6685SChris Mason 
1537b18c6685SChris Mason 	slot = path->slots[0];
1538b18c6685SChris Mason 	old_data_start = btrfs_item_offset(leaf->items + slot);
1539b18c6685SChris Mason 	old_size = btrfs_item_size(leaf->items + slot);
1540b18c6685SChris Mason 	BUG_ON(old_size <= new_size);
1541b18c6685SChris Mason 	size_diff = old_size - new_size;
1542b18c6685SChris Mason 
1543b18c6685SChris Mason 	BUG_ON(slot < 0);
1544b18c6685SChris Mason 	BUG_ON(slot >= nritems);
1545b18c6685SChris Mason 
1546b18c6685SChris Mason 	/*
1547b18c6685SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1548b18c6685SChris Mason 	 */
1549b18c6685SChris Mason 	/* first correct the data pointers */
1550b18c6685SChris Mason 	for (i = slot; i < nritems; i++) {
1551b18c6685SChris Mason 		u32 ioff = btrfs_item_offset(leaf->items + i);
1552b18c6685SChris Mason 		btrfs_set_item_offset(leaf->items + i,
1553b18c6685SChris Mason 				      ioff + size_diff);
1554b18c6685SChris Mason 	}
1555b18c6685SChris Mason 	/* shift the data */
1556b18c6685SChris Mason 	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1557b18c6685SChris Mason 		      data_end + size_diff, btrfs_leaf_data(leaf) +
1558b18c6685SChris Mason 		      data_end, old_data_start + new_size - data_end);
1559b18c6685SChris Mason 	btrfs_set_item_size(leaf->items + slot, new_size);
1560b18c6685SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
1561b18c6685SChris Mason 
1562b18c6685SChris Mason 	ret = 0;
1563b18c6685SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
1564b18c6685SChris Mason 		BUG();
1565b18c6685SChris Mason 	check_leaf(root, path, 0);
1566b18c6685SChris Mason 	return ret;
1567b18c6685SChris Mason }
1568b18c6685SChris Mason 
15696567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root
15706567e837SChris Mason 		      *root, struct btrfs_path *path, u32 data_size)
15716567e837SChris Mason {
15726567e837SChris Mason 	int ret = 0;
15736567e837SChris Mason 	int slot;
15746567e837SChris Mason 	int slot_orig;
15756567e837SChris Mason 	struct btrfs_leaf *leaf;
15766567e837SChris Mason 	struct buffer_head *leaf_buf;
15776567e837SChris Mason 	u32 nritems;
15786567e837SChris Mason 	unsigned int data_end;
15796567e837SChris Mason 	unsigned int old_data;
15806567e837SChris Mason 	unsigned int old_size;
15816567e837SChris Mason 	int i;
15826567e837SChris Mason 
15836567e837SChris Mason 	slot_orig = path->slots[0];
15846567e837SChris Mason 	leaf_buf = path->nodes[0];
15856567e837SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
15866567e837SChris Mason 
15876567e837SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
15886567e837SChris Mason 	data_end = leaf_data_end(root, leaf);
15896567e837SChris Mason 
15906567e837SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < data_size)
15916567e837SChris Mason 		BUG();
15926567e837SChris Mason 	slot = path->slots[0];
15936567e837SChris Mason 	old_data = btrfs_item_end(leaf->items + slot);
15946567e837SChris Mason 
15956567e837SChris Mason 	BUG_ON(slot < 0);
15966567e837SChris Mason 	BUG_ON(slot >= nritems);
15976567e837SChris Mason 
15986567e837SChris Mason 	/*
15996567e837SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
16006567e837SChris Mason 	 */
16016567e837SChris Mason 	/* first correct the data pointers */
16026567e837SChris Mason 	for (i = slot; i < nritems; i++) {
16036567e837SChris Mason 		u32 ioff = btrfs_item_offset(leaf->items + i);
16046567e837SChris Mason 		btrfs_set_item_offset(leaf->items + i,
16056567e837SChris Mason 				      ioff - data_size);
16066567e837SChris Mason 	}
16076567e837SChris Mason 	/* shift the data */
16086567e837SChris Mason 	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
16096567e837SChris Mason 		      data_end - data_size, btrfs_leaf_data(leaf) +
16106567e837SChris Mason 		      data_end, old_data - data_end);
16116567e837SChris Mason 	data_end = old_data;
16126567e837SChris Mason 	old_size = btrfs_item_size(leaf->items + slot);
16136567e837SChris Mason 	btrfs_set_item_size(leaf->items + slot, old_size + data_size);
16146567e837SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
16156567e837SChris Mason 
16166567e837SChris Mason 	ret = 0;
16176567e837SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
16186567e837SChris Mason 		BUG();
16196567e837SChris Mason 	check_leaf(root, path, 0);
16206567e837SChris Mason 	return ret;
16216567e837SChris Mason }
16226567e837SChris Mason 
162374123bd7SChris Mason /*
162474123bd7SChris Mason  * Given a key and some data, insert an item into the tree.
162574123bd7SChris Mason  * This does all the path init required, making room in the tree if needed.
162674123bd7SChris Mason  */
1627e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
1628e089f05cSChris Mason 			    *root, struct btrfs_path *path, struct btrfs_key
1629e089f05cSChris Mason 			    *cpu_key, u32 data_size)
1630be0e5c09SChris Mason {
1631aa5d6bedSChris Mason 	int ret = 0;
1632be0e5c09SChris Mason 	int slot;
1633eb60ceacSChris Mason 	int slot_orig;
1634234b63a0SChris Mason 	struct btrfs_leaf *leaf;
1635e20d96d6SChris Mason 	struct buffer_head *leaf_buf;
16367518a238SChris Mason 	u32 nritems;
1637be0e5c09SChris Mason 	unsigned int data_end;
1638e2fa7227SChris Mason 	struct btrfs_disk_key disk_key;
1639e2fa7227SChris Mason 
1640e2fa7227SChris Mason 	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1641be0e5c09SChris Mason 
164274123bd7SChris Mason 	/* create a root if there isn't one */
16435c680ed6SChris Mason 	if (!root->node)
1644cfaa7295SChris Mason 		BUG();
1645e089f05cSChris Mason 	ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
1646eb60ceacSChris Mason 	if (ret == 0) {
1647f0930a37SChris Mason 		return -EEXIST;
1648aa5d6bedSChris Mason 	}
1649ed2ff2cbSChris Mason 	if (ret < 0)
1650ed2ff2cbSChris Mason 		goto out;
1651be0e5c09SChris Mason 
165262e2749eSChris Mason 	slot_orig = path->slots[0];
165362e2749eSChris Mason 	leaf_buf = path->nodes[0];
1654e20d96d6SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
165574123bd7SChris Mason 
16567518a238SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1657123abc88SChris Mason 	data_end = leaf_data_end(root, leaf);
1658eb60ceacSChris Mason 
1659123abc88SChris Mason 	if (btrfs_leaf_free_space(root, leaf) <
1660d4dbff95SChris Mason 	    sizeof(struct btrfs_item) + data_size) {
1661be0e5c09SChris Mason 		BUG();
1662d4dbff95SChris Mason 	}
166362e2749eSChris Mason 	slot = path->slots[0];
1664eb60ceacSChris Mason 	BUG_ON(slot < 0);
1665be0e5c09SChris Mason 	if (slot != nritems) {
1666be0e5c09SChris Mason 		int i;
16670783fcfcSChris Mason 		unsigned int old_data = btrfs_item_end(leaf->items + slot);
1668be0e5c09SChris Mason 
1669be0e5c09SChris Mason 		/*
1670be0e5c09SChris Mason 		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1671be0e5c09SChris Mason 		 */
1672be0e5c09SChris Mason 		/* first correct the data pointers */
16730783fcfcSChris Mason 		for (i = slot; i < nritems; i++) {
1674123abc88SChris Mason 			u32 ioff = btrfs_item_offset(leaf->items + i);
16750783fcfcSChris Mason 			btrfs_set_item_offset(leaf->items + i,
16760783fcfcSChris Mason 					      ioff - data_size);
16770783fcfcSChris Mason 		}
1678be0e5c09SChris Mason 
1679be0e5c09SChris Mason 		/* shift the items */
1680d6025579SChris Mason 		btrfs_memmove(root, leaf, leaf->items + slot + 1,
1681d6025579SChris Mason 			      leaf->items + slot,
16820783fcfcSChris Mason 			      (nritems - slot) * sizeof(struct btrfs_item));
1683be0e5c09SChris Mason 
1684be0e5c09SChris Mason 		/* shift the data */
1685d6025579SChris Mason 		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1686d6025579SChris Mason 			      data_end - data_size, btrfs_leaf_data(leaf) +
1687be0e5c09SChris Mason 			      data_end, old_data - data_end);
1688be0e5c09SChris Mason 		data_end = old_data;
1689be0e5c09SChris Mason 	}
169062e2749eSChris Mason 	/* setup the item for the new data */
1691d6025579SChris Mason 	btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key,
1692e2fa7227SChris Mason 		     sizeof(struct btrfs_disk_key));
16930783fcfcSChris Mason 	btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
16940783fcfcSChris Mason 	btrfs_set_item_size(leaf->items + slot, data_size);
16957518a238SChris Mason 	btrfs_set_header_nritems(&leaf->header, nritems + 1);
1696d6025579SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
1697aa5d6bedSChris Mason 
1698aa5d6bedSChris Mason 	ret = 0;
16998e19f2cdSChris Mason 	if (slot == 0)
1700e089f05cSChris Mason 		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
1701aa5d6bedSChris Mason 
1702123abc88SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
1703be0e5c09SChris Mason 		BUG();
170462e2749eSChris Mason 	check_leaf(root, path, 0);
1705ed2ff2cbSChris Mason out:
170662e2749eSChris Mason 	return ret;
170762e2749eSChris Mason }
170862e2749eSChris Mason 
170962e2749eSChris Mason /*
171062e2749eSChris Mason  * Given a key and some data, insert an item into the tree.
171162e2749eSChris Mason  * This does all the path init required, making room in the tree if needed.
171262e2749eSChris Mason  */
1713e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
1714e089f05cSChris Mason 		      *root, struct btrfs_key *cpu_key, void *data, u32
1715e089f05cSChris Mason 		      data_size)
171662e2749eSChris Mason {
171762e2749eSChris Mason 	int ret = 0;
17182c90e5d6SChris Mason 	struct btrfs_path *path;
171962e2749eSChris Mason 	u8 *ptr;
172062e2749eSChris Mason 
17212c90e5d6SChris Mason 	path = btrfs_alloc_path();
17222c90e5d6SChris Mason 	BUG_ON(!path);
17232c90e5d6SChris Mason 	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
172462e2749eSChris Mason 	if (!ret) {
17252c90e5d6SChris Mason 		ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
17262c90e5d6SChris Mason 				     path->slots[0], u8);
17272c90e5d6SChris Mason 		btrfs_memcpy(root, path->nodes[0]->b_data,
1728d6025579SChris Mason 			     ptr, data, data_size);
17292c90e5d6SChris Mason 		btrfs_mark_buffer_dirty(path->nodes[0]);
173062e2749eSChris Mason 	}
17312c90e5d6SChris Mason 	btrfs_free_path(path);
1732aa5d6bedSChris Mason 	return ret;
1733be0e5c09SChris Mason }
1734be0e5c09SChris Mason 
173574123bd7SChris Mason /*
17365de08d7dSChris Mason  * delete the pointer from a given node.
173774123bd7SChris Mason  *
173874123bd7SChris Mason  * If the delete empties a node, the node is removed from the tree,
173974123bd7SChris Mason  * continuing all the way the root if required.  The root is converted into
174074123bd7SChris Mason  * a leaf if all the nodes are emptied.
174174123bd7SChris Mason  */
1742e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1743e089f05cSChris Mason 		   struct btrfs_path *path, int level, int slot)
1744be0e5c09SChris Mason {
1745234b63a0SChris Mason 	struct btrfs_node *node;
1746e20d96d6SChris Mason 	struct buffer_head *parent = path->nodes[level];
17477518a238SChris Mason 	u32 nritems;
1748aa5d6bedSChris Mason 	int ret = 0;
1749bb803951SChris Mason 	int wret;
1750be0e5c09SChris Mason 
1751e20d96d6SChris Mason 	node = btrfs_buffer_node(parent);
17527518a238SChris Mason 	nritems = btrfs_header_nritems(&node->header);
1753be0e5c09SChris Mason 	if (slot != nritems -1) {
1754d6025579SChris Mason 		btrfs_memmove(root, node, node->ptrs + slot,
1755d6025579SChris Mason 			      node->ptrs + slot + 1,
1756d6025579SChris Mason 			      sizeof(struct btrfs_key_ptr) *
1757d6025579SChris Mason 			      (nritems - slot - 1));
1758be0e5c09SChris Mason 	}
17597518a238SChris Mason 	nritems--;
17607518a238SChris Mason 	btrfs_set_header_nritems(&node->header, nritems);
17617518a238SChris Mason 	if (nritems == 0 && parent == root->node) {
1762e20d96d6SChris Mason 		struct btrfs_header *header = btrfs_buffer_header(root->node);
1763e20d96d6SChris Mason 		BUG_ON(btrfs_header_level(header) != 1);
1764eb60ceacSChris Mason 		/* just turn the root into a leaf and break */
1765e20d96d6SChris Mason 		btrfs_set_header_level(header, 0);
1766bb803951SChris Mason 	} else if (slot == 0) {
1767e089f05cSChris Mason 		wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
1768123abc88SChris Mason 				      level + 1);
17690f70abe2SChris Mason 		if (wret)
17700f70abe2SChris Mason 			ret = wret;
1771be0e5c09SChris Mason 	}
1772d6025579SChris Mason 	btrfs_mark_buffer_dirty(parent);
1773aa5d6bedSChris Mason 	return ret;
1774be0e5c09SChris Mason }
1775be0e5c09SChris Mason 
177674123bd7SChris Mason /*
177774123bd7SChris Mason  * delete the item at the leaf level in path.  If that empties
177874123bd7SChris Mason  * the leaf, remove it from the tree
177974123bd7SChris Mason  */
1780e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1781e089f05cSChris Mason 		   struct btrfs_path *path)
1782be0e5c09SChris Mason {
1783be0e5c09SChris Mason 	int slot;
1784234b63a0SChris Mason 	struct btrfs_leaf *leaf;
1785e20d96d6SChris Mason 	struct buffer_head *leaf_buf;
1786be0e5c09SChris Mason 	int doff;
1787be0e5c09SChris Mason 	int dsize;
1788aa5d6bedSChris Mason 	int ret = 0;
1789aa5d6bedSChris Mason 	int wret;
17907518a238SChris Mason 	u32 nritems;
1791be0e5c09SChris Mason 
1792eb60ceacSChris Mason 	leaf_buf = path->nodes[0];
1793e20d96d6SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
17944920c9acSChris Mason 	slot = path->slots[0];
17950783fcfcSChris Mason 	doff = btrfs_item_offset(leaf->items + slot);
17960783fcfcSChris Mason 	dsize = btrfs_item_size(leaf->items + slot);
17977518a238SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1798be0e5c09SChris Mason 
17997518a238SChris Mason 	if (slot != nritems - 1) {
1800be0e5c09SChris Mason 		int i;
1801123abc88SChris Mason 		int data_end = leaf_data_end(root, leaf);
1802d6025579SChris Mason 		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1803d6025579SChris Mason 			      data_end + dsize,
1804123abc88SChris Mason 			      btrfs_leaf_data(leaf) + data_end,
1805be0e5c09SChris Mason 			      doff - data_end);
18060783fcfcSChris Mason 		for (i = slot + 1; i < nritems; i++) {
1807123abc88SChris Mason 			u32 ioff = btrfs_item_offset(leaf->items + i);
18080783fcfcSChris Mason 			btrfs_set_item_offset(leaf->items + i, ioff + dsize);
18090783fcfcSChris Mason 		}
1810d6025579SChris Mason 		btrfs_memmove(root, leaf, leaf->items + slot,
1811d6025579SChris Mason 			      leaf->items + slot + 1,
18120783fcfcSChris Mason 			      sizeof(struct btrfs_item) *
18137518a238SChris Mason 			      (nritems - slot - 1));
1814be0e5c09SChris Mason 	}
18157518a238SChris Mason 	btrfs_set_header_nritems(&leaf->header, nritems - 1);
18167518a238SChris Mason 	nritems--;
181774123bd7SChris Mason 	/* delete the leaf if we've emptied it */
18187518a238SChris Mason 	if (nritems == 0) {
1819eb60ceacSChris Mason 		if (leaf_buf == root->node) {
18207518a238SChris Mason 			btrfs_set_header_level(&leaf->header, 0);
18219a8dd150SChris Mason 		} else {
1822e089f05cSChris Mason 			clean_tree_block(trans, root, leaf_buf);
1823d6025579SChris Mason 			wait_on_buffer(leaf_buf);
1824e089f05cSChris Mason 			wret = del_ptr(trans, root, path, 1, path->slots[1]);
1825aa5d6bedSChris Mason 			if (wret)
1826aa5d6bedSChris Mason 				ret = wret;
1827e089f05cSChris Mason 			wret = btrfs_free_extent(trans, root,
18287eccb903SChris Mason 						 bh_blocknr(leaf_buf), 1, 1);
18290f70abe2SChris Mason 			if (wret)
18300f70abe2SChris Mason 				ret = wret;
18319a8dd150SChris Mason 		}
1832be0e5c09SChris Mason 	} else {
18337518a238SChris Mason 		int used = leaf_space_used(leaf, 0, nritems);
1834aa5d6bedSChris Mason 		if (slot == 0) {
1835e089f05cSChris Mason 			wret = fixup_low_keys(trans, root, path,
1836aa5d6bedSChris Mason 					      &leaf->items[0].key, 1);
1837aa5d6bedSChris Mason 			if (wret)
1838aa5d6bedSChris Mason 				ret = wret;
1839aa5d6bedSChris Mason 		}
1840aa5d6bedSChris Mason 
184174123bd7SChris Mason 		/* delete the leaf if it is mostly empty */
1842123abc88SChris Mason 		if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
1843be0e5c09SChris Mason 			/* push_leaf_left fixes the path.
1844be0e5c09SChris Mason 			 * make sure the path still points to our leaf
1845be0e5c09SChris Mason 			 * for possible call to del_ptr below
1846be0e5c09SChris Mason 			 */
18474920c9acSChris Mason 			slot = path->slots[1];
1848e20d96d6SChris Mason 			get_bh(leaf_buf);
1849e089f05cSChris Mason 			wret = push_leaf_left(trans, root, path, 1);
185054aa1f4dSChris Mason 			if (wret < 0 && wret != -ENOSPC)
1851aa5d6bedSChris Mason 				ret = wret;
1852f0930a37SChris Mason 			if (path->nodes[0] == leaf_buf &&
18537518a238SChris Mason 			    btrfs_header_nritems(&leaf->header)) {
1854e089f05cSChris Mason 				wret = push_leaf_right(trans, root, path, 1);
185554aa1f4dSChris Mason 				if (wret < 0 && wret != -ENOSPC)
1856aa5d6bedSChris Mason 					ret = wret;
1857aa5d6bedSChris Mason 			}
18587518a238SChris Mason 			if (btrfs_header_nritems(&leaf->header) == 0) {
18597eccb903SChris Mason 				u64 blocknr = bh_blocknr(leaf_buf);
1860e089f05cSChris Mason 				clean_tree_block(trans, root, leaf_buf);
1861d6025579SChris Mason 				wait_on_buffer(leaf_buf);
1862e089f05cSChris Mason 				wret = del_ptr(trans, root, path, 1, slot);
1863aa5d6bedSChris Mason 				if (wret)
1864aa5d6bedSChris Mason 					ret = wret;
1865234b63a0SChris Mason 				btrfs_block_release(root, leaf_buf);
1866e089f05cSChris Mason 				wret = btrfs_free_extent(trans, root, blocknr,
1867e089f05cSChris Mason 							 1, 1);
18680f70abe2SChris Mason 				if (wret)
18690f70abe2SChris Mason 					ret = wret;
18705de08d7dSChris Mason 			} else {
1871d6025579SChris Mason 				btrfs_mark_buffer_dirty(leaf_buf);
1872234b63a0SChris Mason 				btrfs_block_release(root, leaf_buf);
1873be0e5c09SChris Mason 			}
1874d5719762SChris Mason 		} else {
1875d6025579SChris Mason 			btrfs_mark_buffer_dirty(leaf_buf);
1876be0e5c09SChris Mason 		}
18779a8dd150SChris Mason 	}
1878aa5d6bedSChris Mason 	return ret;
18799a8dd150SChris Mason }
18809a8dd150SChris Mason 
188197571fd0SChris Mason /*
188297571fd0SChris Mason  * walk up the tree as far as required to find the next leaf.
18830f70abe2SChris Mason  * returns 0 if it found something or 1 if there are no greater leaves.
18840f70abe2SChris Mason  * returns < 0 on io errors.
188597571fd0SChris Mason  */
1886234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
1887d97e63b6SChris Mason {
1888d97e63b6SChris Mason 	int slot;
1889d97e63b6SChris Mason 	int level = 1;
1890d97e63b6SChris Mason 	u64 blocknr;
1891e20d96d6SChris Mason 	struct buffer_head *c;
1892e20d96d6SChris Mason 	struct btrfs_node *c_node;
1893e20d96d6SChris Mason 	struct buffer_head *next = NULL;
1894d97e63b6SChris Mason 
1895234b63a0SChris Mason 	while(level < BTRFS_MAX_LEVEL) {
1896d97e63b6SChris Mason 		if (!path->nodes[level])
18970f70abe2SChris Mason 			return 1;
1898d97e63b6SChris Mason 		slot = path->slots[level] + 1;
1899d97e63b6SChris Mason 		c = path->nodes[level];
1900e20d96d6SChris Mason 		c_node = btrfs_buffer_node(c);
1901e20d96d6SChris Mason 		if (slot >= btrfs_header_nritems(&c_node->header)) {
1902d97e63b6SChris Mason 			level++;
1903d97e63b6SChris Mason 			continue;
1904d97e63b6SChris Mason 		}
1905e20d96d6SChris Mason 		blocknr = btrfs_node_blockptr(c_node, slot);
1906cfaa7295SChris Mason 		if (next)
1907234b63a0SChris Mason 			btrfs_block_release(root, next);
1908d97e63b6SChris Mason 		next = read_tree_block(root, blocknr);
1909d97e63b6SChris Mason 		break;
1910d97e63b6SChris Mason 	}
1911d97e63b6SChris Mason 	path->slots[level] = slot;
1912d97e63b6SChris Mason 	while(1) {
1913d97e63b6SChris Mason 		level--;
1914d97e63b6SChris Mason 		c = path->nodes[level];
1915234b63a0SChris Mason 		btrfs_block_release(root, c);
1916d97e63b6SChris Mason 		path->nodes[level] = next;
1917d97e63b6SChris Mason 		path->slots[level] = 0;
1918d97e63b6SChris Mason 		if (!level)
1919d97e63b6SChris Mason 			break;
19201d4f8a0cSChris Mason 		next = read_tree_block(root,
1921e20d96d6SChris Mason 		       btrfs_node_blockptr(btrfs_buffer_node(next), 0));
1922d97e63b6SChris Mason 	}
1923d97e63b6SChris Mason 	return 0;
1924d97e63b6SChris Mason }
1925