xref: /openbmc/linux/fs/btrfs/ctree.c (revision 33ade1f8)
12e635a27SChris Mason #include <linux/module.h>
2eb60ceacSChris Mason #include "ctree.h"
3eb60ceacSChris Mason #include "disk-io.h"
47f5c1516SChris Mason #include "transaction.h"
59a8dd150SChris Mason 
6e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
7e089f05cSChris Mason 		      *root, struct btrfs_path *path, int level);
8e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
9d4dbff95SChris Mason 		      *root, struct btrfs_key *ins_key,
10d4dbff95SChris Mason 		      struct btrfs_path *path, int data_size);
11e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
12e20d96d6SChris Mason 			  *root, struct buffer_head *dst, struct buffer_head
13e089f05cSChris Mason 			  *src);
14e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct
15e20d96d6SChris Mason 			      btrfs_root *root, struct buffer_head *dst_buf,
16e20d96d6SChris Mason 			      struct buffer_head *src_buf);
17e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
18e089f05cSChris Mason 		   struct btrfs_path *path, int level, int slot);
19d97e63b6SChris Mason 
20df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p)
21df24a2b9SChris Mason {
22df24a2b9SChris Mason 	memset(p, 0, sizeof(*p));
23df24a2b9SChris Mason }
24df24a2b9SChris Mason 
252c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void)
262c90e5d6SChris Mason {
27df24a2b9SChris Mason 	struct btrfs_path *path;
28df24a2b9SChris Mason 	path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
29df24a2b9SChris Mason 	if (path)
30df24a2b9SChris Mason 		btrfs_init_path(path);
31df24a2b9SChris Mason 	return path;
322c90e5d6SChris Mason }
332c90e5d6SChris Mason 
342c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p)
352c90e5d6SChris Mason {
36df24a2b9SChris Mason 	btrfs_release_path(NULL, p);
372c90e5d6SChris Mason 	kmem_cache_free(btrfs_path_cachep, p);
382c90e5d6SChris Mason }
392c90e5d6SChris Mason 
40234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
41eb60ceacSChris Mason {
42eb60ceacSChris Mason 	int i;
43234b63a0SChris Mason 	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
44eb60ceacSChris Mason 		if (!p->nodes[i])
45eb60ceacSChris Mason 			break;
46234b63a0SChris Mason 		btrfs_block_release(root, p->nodes[i]);
47eb60ceacSChris Mason 	}
48aa5d6bedSChris Mason 	memset(p, 0, sizeof(*p));
49eb60ceacSChris Mason }
50eb60ceacSChris Mason 
51e089f05cSChris Mason static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
52e20d96d6SChris Mason 			   *root, struct buffer_head *buf, struct buffer_head
53e20d96d6SChris Mason 			   *parent, int parent_slot, struct buffer_head
54e089f05cSChris Mason 			   **cow_ret)
5502217ed2SChris Mason {
56e20d96d6SChris Mason 	struct buffer_head *cow;
57e20d96d6SChris Mason 	struct btrfs_node *cow_node;
5802217ed2SChris Mason 
597f5c1516SChris Mason 	if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
607f5c1516SChris Mason 				    trans->transid) {
6102217ed2SChris Mason 		*cow_ret = buf;
6202217ed2SChris Mason 		return 0;
6302217ed2SChris Mason 	}
64e089f05cSChris Mason 	cow = btrfs_alloc_free_block(trans, root);
65e20d96d6SChris Mason 	cow_node = btrfs_buffer_node(cow);
662c90e5d6SChris Mason 	if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
672c90e5d6SChris Mason 		WARN_ON(1);
68e20d96d6SChris Mason 	memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
697eccb903SChris Mason 	btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow));
707f5c1516SChris Mason 	btrfs_set_header_generation(&cow_node->header, trans->transid);
71e089f05cSChris Mason 	btrfs_inc_ref(trans, root, buf);
7202217ed2SChris Mason 	if (buf == root->node) {
7302217ed2SChris Mason 		root->node = cow;
74e20d96d6SChris Mason 		get_bh(cow);
752c90e5d6SChris Mason 		if (buf != root->commit_root) {
767eccb903SChris Mason 			btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
772c90e5d6SChris Mason 		}
78234b63a0SChris Mason 		btrfs_block_release(root, buf);
7902217ed2SChris Mason 	} else {
80e20d96d6SChris Mason 		btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
817eccb903SChris Mason 					bh_blocknr(cow));
82d6025579SChris Mason 		btrfs_mark_buffer_dirty(parent);
837eccb903SChris Mason 		btrfs_free_extent(trans, root, bh_blocknr(buf), 1, 1);
8402217ed2SChris Mason 	}
85234b63a0SChris Mason 	btrfs_block_release(root, buf);
86df24a2b9SChris Mason 	mark_buffer_dirty(cow);
872c90e5d6SChris Mason 	*cow_ret = cow;
8802217ed2SChris Mason 	return 0;
8902217ed2SChris Mason }
9002217ed2SChris Mason 
9174123bd7SChris Mason /*
9274123bd7SChris Mason  * The leaf data grows from end-to-front in the node.
9374123bd7SChris Mason  * this returns the address of the start of the last item,
9474123bd7SChris Mason  * which is the stop of the leaf data stack
9574123bd7SChris Mason  */
96123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root,
97123abc88SChris Mason 					 struct btrfs_leaf *leaf)
98be0e5c09SChris Mason {
997518a238SChris Mason 	u32 nr = btrfs_header_nritems(&leaf->header);
100be0e5c09SChris Mason 	if (nr == 0)
101123abc88SChris Mason 		return BTRFS_LEAF_DATA_SIZE(root);
1020783fcfcSChris Mason 	return btrfs_item_offset(leaf->items + nr - 1);
103be0e5c09SChris Mason }
104be0e5c09SChris Mason 
10574123bd7SChris Mason /*
10674123bd7SChris Mason  * compare two keys in a memcmp fashion
10774123bd7SChris Mason  */
1089aca1d51SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
109be0e5c09SChris Mason {
110e2fa7227SChris Mason 	struct btrfs_key k1;
111e2fa7227SChris Mason 
112e2fa7227SChris Mason 	btrfs_disk_key_to_cpu(&k1, disk);
113e2fa7227SChris Mason 
114e2fa7227SChris Mason 	if (k1.objectid > k2->objectid)
115be0e5c09SChris Mason 		return 1;
116e2fa7227SChris Mason 	if (k1.objectid < k2->objectid)
117be0e5c09SChris Mason 		return -1;
118f254e52cSChris Mason 	if (k1.flags > k2->flags)
119f254e52cSChris Mason 		return 1;
120f254e52cSChris Mason 	if (k1.flags < k2->flags)
121f254e52cSChris Mason 		return -1;
12270b2befdSChris Mason 	if (k1.offset > k2->offset)
12370b2befdSChris Mason 		return 1;
12470b2befdSChris Mason 	if (k1.offset < k2->offset)
12570b2befdSChris Mason 		return -1;
126be0e5c09SChris Mason 	return 0;
127be0e5c09SChris Mason }
12874123bd7SChris Mason 
129123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path,
130123abc88SChris Mason 		      int level)
131aa5d6bedSChris Mason {
132aa5d6bedSChris Mason 	int i;
133234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
134e20d96d6SChris Mason 	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
135aa5d6bedSChris Mason 	int parent_slot;
1367518a238SChris Mason 	u32 nritems = btrfs_header_nritems(&node->header);
137aa5d6bedSChris Mason 
138aa5d6bedSChris Mason 	if (path->nodes[level + 1])
139e20d96d6SChris Mason 		parent = btrfs_buffer_node(path->nodes[level + 1]);
140aa5d6bedSChris Mason 	parent_slot = path->slots[level + 1];
1417518a238SChris Mason 	BUG_ON(nritems == 0);
1427518a238SChris Mason 	if (parent) {
143e2fa7227SChris Mason 		struct btrfs_disk_key *parent_key;
144123abc88SChris Mason 		parent_key = &parent->ptrs[parent_slot].key;
145123abc88SChris Mason 		BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
146e2fa7227SChris Mason 			      sizeof(struct btrfs_disk_key)));
1471d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
1487518a238SChris Mason 		       btrfs_header_blocknr(&node->header));
149aa5d6bedSChris Mason 	}
150123abc88SChris Mason 	BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
1517518a238SChris Mason 	for (i = 0; nritems > 1 && i < nritems - 2; i++) {
152e2fa7227SChris Mason 		struct btrfs_key cpukey;
153123abc88SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[i + 1].key);
154123abc88SChris Mason 		BUG_ON(comp_keys(&node->ptrs[i].key, &cpukey) >= 0);
155aa5d6bedSChris Mason 	}
156aa5d6bedSChris Mason 	return 0;
157aa5d6bedSChris Mason }
158aa5d6bedSChris Mason 
159123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
160123abc88SChris Mason 		      int level)
161aa5d6bedSChris Mason {
162aa5d6bedSChris Mason 	int i;
163e20d96d6SChris Mason 	struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]);
164234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
165aa5d6bedSChris Mason 	int parent_slot;
1667518a238SChris Mason 	u32 nritems = btrfs_header_nritems(&leaf->header);
167aa5d6bedSChris Mason 
168aa5d6bedSChris Mason 	if (path->nodes[level + 1])
169e20d96d6SChris Mason 		parent = btrfs_buffer_node(path->nodes[level + 1]);
170aa5d6bedSChris Mason 	parent_slot = path->slots[level + 1];
171123abc88SChris Mason 	BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
1727518a238SChris Mason 
1737518a238SChris Mason 	if (nritems == 0)
1747518a238SChris Mason 		return 0;
1757518a238SChris Mason 
1767518a238SChris Mason 	if (parent) {
177e2fa7227SChris Mason 		struct btrfs_disk_key *parent_key;
178123abc88SChris Mason 		parent_key = &parent->ptrs[parent_slot].key;
179aa5d6bedSChris Mason 		BUG_ON(memcmp(parent_key, &leaf->items[0].key,
180e2fa7227SChris Mason 		       sizeof(struct btrfs_disk_key)));
1811d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
1827518a238SChris Mason 		       btrfs_header_blocknr(&leaf->header));
183aa5d6bedSChris Mason 	}
1847518a238SChris Mason 	for (i = 0; nritems > 1 && i < nritems - 2; i++) {
185e2fa7227SChris Mason 		struct btrfs_key cpukey;
186e2fa7227SChris Mason 		btrfs_disk_key_to_cpu(&cpukey, &leaf->items[i + 1].key);
187aa5d6bedSChris Mason 		BUG_ON(comp_keys(&leaf->items[i].key,
188e2fa7227SChris Mason 		                 &cpukey) >= 0);
1890783fcfcSChris Mason 		BUG_ON(btrfs_item_offset(leaf->items + i) !=
1900783fcfcSChris Mason 			btrfs_item_end(leaf->items + i + 1));
191aa5d6bedSChris Mason 		if (i == 0) {
1920783fcfcSChris Mason 			BUG_ON(btrfs_item_offset(leaf->items + i) +
1930783fcfcSChris Mason 			       btrfs_item_size(leaf->items + i) !=
194123abc88SChris Mason 			       BTRFS_LEAF_DATA_SIZE(root));
195aa5d6bedSChris Mason 		}
196aa5d6bedSChris Mason 	}
197aa5d6bedSChris Mason 	return 0;
198aa5d6bedSChris Mason }
199aa5d6bedSChris Mason 
200123abc88SChris Mason static int check_block(struct btrfs_root *root, struct btrfs_path *path,
201123abc88SChris Mason 			int level)
202aa5d6bedSChris Mason {
2033eb0314dSChris Mason 	struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
2043eb0314dSChris Mason 	if (memcmp(node->header.fsid, root->fs_info->disk_super->fsid,
2053eb0314dSChris Mason 		   sizeof(node->header.fsid)))
2063eb0314dSChris Mason 		BUG();
207aa5d6bedSChris Mason 	if (level == 0)
208123abc88SChris Mason 		return check_leaf(root, path, level);
209123abc88SChris Mason 	return check_node(root, path, level);
210aa5d6bedSChris Mason }
211aa5d6bedSChris Mason 
21274123bd7SChris Mason /*
21374123bd7SChris Mason  * search for key in the array p.  items p are item_size apart
21474123bd7SChris Mason  * and there are 'max' items in p
21574123bd7SChris Mason  * the slot in the array is returned via slot, and it points to
21674123bd7SChris Mason  * the place where you would insert key if it is not found in
21774123bd7SChris Mason  * the array.
21874123bd7SChris Mason  *
21974123bd7SChris Mason  * slot may point to max if the key is bigger than all of the keys
22074123bd7SChris Mason  */
2219aca1d51SChris Mason static int generic_bin_search(char *p, int item_size, struct btrfs_key *key,
222be0e5c09SChris Mason 		       int max, int *slot)
223be0e5c09SChris Mason {
224be0e5c09SChris Mason 	int low = 0;
225be0e5c09SChris Mason 	int high = max;
226be0e5c09SChris Mason 	int mid;
227be0e5c09SChris Mason 	int ret;
228e2fa7227SChris Mason 	struct btrfs_disk_key *tmp;
229be0e5c09SChris Mason 
230be0e5c09SChris Mason 	while(low < high) {
231be0e5c09SChris Mason 		mid = (low + high) / 2;
232e2fa7227SChris Mason 		tmp = (struct btrfs_disk_key *)(p + mid * item_size);
233be0e5c09SChris Mason 		ret = comp_keys(tmp, key);
234be0e5c09SChris Mason 
235be0e5c09SChris Mason 		if (ret < 0)
236be0e5c09SChris Mason 			low = mid + 1;
237be0e5c09SChris Mason 		else if (ret > 0)
238be0e5c09SChris Mason 			high = mid;
239be0e5c09SChris Mason 		else {
240be0e5c09SChris Mason 			*slot = mid;
241be0e5c09SChris Mason 			return 0;
242be0e5c09SChris Mason 		}
243be0e5c09SChris Mason 	}
244be0e5c09SChris Mason 	*slot = low;
245be0e5c09SChris Mason 	return 1;
246be0e5c09SChris Mason }
247be0e5c09SChris Mason 
24897571fd0SChris Mason /*
24997571fd0SChris Mason  * simple bin_search frontend that does the right thing for
25097571fd0SChris Mason  * leaves vs nodes
25197571fd0SChris Mason  */
2529aca1d51SChris Mason static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
253be0e5c09SChris Mason {
2547518a238SChris Mason 	if (btrfs_is_leaf(c)) {
255234b63a0SChris Mason 		struct btrfs_leaf *l = (struct btrfs_leaf *)c;
2560783fcfcSChris Mason 		return generic_bin_search((void *)l->items,
2570783fcfcSChris Mason 					  sizeof(struct btrfs_item),
2587518a238SChris Mason 					  key, btrfs_header_nritems(&c->header),
2597518a238SChris Mason 					  slot);
260be0e5c09SChris Mason 	} else {
261123abc88SChris Mason 		return generic_bin_search((void *)c->ptrs,
262123abc88SChris Mason 					  sizeof(struct btrfs_key_ptr),
2637518a238SChris Mason 					  key, btrfs_header_nritems(&c->header),
2647518a238SChris Mason 					  slot);
265be0e5c09SChris Mason 	}
266be0e5c09SChris Mason 	return -1;
267be0e5c09SChris Mason }
268be0e5c09SChris Mason 
269e20d96d6SChris Mason static struct buffer_head *read_node_slot(struct btrfs_root *root,
270e20d96d6SChris Mason 				   struct buffer_head *parent_buf,
271bb803951SChris Mason 				   int slot)
272bb803951SChris Mason {
273e20d96d6SChris Mason 	struct btrfs_node *node = btrfs_buffer_node(parent_buf);
274bb803951SChris Mason 	if (slot < 0)
275bb803951SChris Mason 		return NULL;
2767518a238SChris Mason 	if (slot >= btrfs_header_nritems(&node->header))
277bb803951SChris Mason 		return NULL;
2781d4f8a0cSChris Mason 	return read_tree_block(root, btrfs_node_blockptr(node, slot));
279bb803951SChris Mason }
280bb803951SChris Mason 
281e089f05cSChris Mason static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
282e089f05cSChris Mason 			 *root, struct btrfs_path *path, int level)
283bb803951SChris Mason {
284e20d96d6SChris Mason 	struct buffer_head *right_buf;
285e20d96d6SChris Mason 	struct buffer_head *mid_buf;
286e20d96d6SChris Mason 	struct buffer_head *left_buf;
287e20d96d6SChris Mason 	struct buffer_head *parent_buf = NULL;
288234b63a0SChris Mason 	struct btrfs_node *right = NULL;
289234b63a0SChris Mason 	struct btrfs_node *mid;
290234b63a0SChris Mason 	struct btrfs_node *left = NULL;
291234b63a0SChris Mason 	struct btrfs_node *parent = NULL;
292bb803951SChris Mason 	int ret = 0;
293bb803951SChris Mason 	int wret;
294bb803951SChris Mason 	int pslot;
295bb803951SChris Mason 	int orig_slot = path->slots[level];
29679f95c82SChris Mason 	u64 orig_ptr;
297bb803951SChris Mason 
298bb803951SChris Mason 	if (level == 0)
299bb803951SChris Mason 		return 0;
300bb803951SChris Mason 
301bb803951SChris Mason 	mid_buf = path->nodes[level];
302e20d96d6SChris Mason 	mid = btrfs_buffer_node(mid_buf);
3031d4f8a0cSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
30479f95c82SChris Mason 
305234b63a0SChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
306bb803951SChris Mason 		parent_buf = path->nodes[level + 1];
307bb803951SChris Mason 	pslot = path->slots[level + 1];
308bb803951SChris Mason 
30940689478SChris Mason 	/*
31040689478SChris Mason 	 * deal with the case where there is only one pointer in the root
31140689478SChris Mason 	 * by promoting the node below to a root
31240689478SChris Mason 	 */
313bb803951SChris Mason 	if (!parent_buf) {
314e20d96d6SChris Mason 		struct buffer_head *child;
3157eccb903SChris Mason 		u64 blocknr = bh_blocknr(mid_buf);
316bb803951SChris Mason 
3177518a238SChris Mason 		if (btrfs_header_nritems(&mid->header) != 1)
318bb803951SChris Mason 			return 0;
319bb803951SChris Mason 
320bb803951SChris Mason 		/* promote the child to a root */
321bb803951SChris Mason 		child = read_node_slot(root, mid_buf, 0);
322bb803951SChris Mason 		BUG_ON(!child);
323bb803951SChris Mason 		root->node = child;
324bb803951SChris Mason 		path->nodes[level] = NULL;
325d6025579SChris Mason 		clean_tree_block(trans, root, mid_buf);
326d6025579SChris Mason 		wait_on_buffer(mid_buf);
327bb803951SChris Mason 		/* once for the path */
328234b63a0SChris Mason 		btrfs_block_release(root, mid_buf);
329bb803951SChris Mason 		/* once for the root ptr */
330234b63a0SChris Mason 		btrfs_block_release(root, mid_buf);
331e089f05cSChris Mason 		return btrfs_free_extent(trans, root, blocknr, 1, 1);
332bb803951SChris Mason 	}
333e20d96d6SChris Mason 	parent = btrfs_buffer_node(parent_buf);
334bb803951SChris Mason 
335123abc88SChris Mason 	if (btrfs_header_nritems(&mid->header) >
336123abc88SChris Mason 	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
337bb803951SChris Mason 		return 0;
338bb803951SChris Mason 
339bb803951SChris Mason 	left_buf = read_node_slot(root, parent_buf, pslot - 1);
340bb803951SChris Mason 	right_buf = read_node_slot(root, parent_buf, pslot + 1);
34179f95c82SChris Mason 
34279f95c82SChris Mason 	/* first, try to make some room in the middle buffer */
343bb803951SChris Mason 	if (left_buf) {
344e089f05cSChris Mason 		btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1,
345e089f05cSChris Mason 				&left_buf);
346e20d96d6SChris Mason 		left = btrfs_buffer_node(left_buf);
3477518a238SChris Mason 		orig_slot += btrfs_header_nritems(&left->header);
348e089f05cSChris Mason 		wret = push_node_left(trans, root, left_buf, mid_buf);
34979f95c82SChris Mason 		if (wret < 0)
35079f95c82SChris Mason 			ret = wret;
351bb803951SChris Mason 	}
35279f95c82SChris Mason 
35379f95c82SChris Mason 	/*
35479f95c82SChris Mason 	 * then try to empty the right most buffer into the middle
35579f95c82SChris Mason 	 */
356bb803951SChris Mason 	if (right_buf) {
357e089f05cSChris Mason 		btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1,
358e089f05cSChris Mason 				&right_buf);
359e20d96d6SChris Mason 		right = btrfs_buffer_node(right_buf);
360e089f05cSChris Mason 		wret = push_node_left(trans, root, mid_buf, right_buf);
36179f95c82SChris Mason 		if (wret < 0)
36279f95c82SChris Mason 			ret = wret;
3637518a238SChris Mason 		if (btrfs_header_nritems(&right->header) == 0) {
3647eccb903SChris Mason 			u64 blocknr = bh_blocknr(right_buf);
365e089f05cSChris Mason 			clean_tree_block(trans, root, right_buf);
366d6025579SChris Mason 			wait_on_buffer(right_buf);
367d6025579SChris Mason 			btrfs_block_release(root, right_buf);
368bb803951SChris Mason 			right_buf = NULL;
369bb803951SChris Mason 			right = NULL;
370e089f05cSChris Mason 			wret = del_ptr(trans, root, path, level + 1, pslot +
371e089f05cSChris Mason 				       1);
372bb803951SChris Mason 			if (wret)
373bb803951SChris Mason 				ret = wret;
374e089f05cSChris Mason 			wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
375bb803951SChris Mason 			if (wret)
376bb803951SChris Mason 				ret = wret;
377bb803951SChris Mason 		} else {
378d6025579SChris Mason 			btrfs_memcpy(root, parent,
379d6025579SChris Mason 				     &parent->ptrs[pslot + 1].key,
380123abc88SChris Mason 				     &right->ptrs[0].key,
381e2fa7227SChris Mason 				     sizeof(struct btrfs_disk_key));
382d6025579SChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
383bb803951SChris Mason 		}
384bb803951SChris Mason 	}
3857518a238SChris Mason 	if (btrfs_header_nritems(&mid->header) == 1) {
38679f95c82SChris Mason 		/*
38779f95c82SChris Mason 		 * we're not allowed to leave a node with one item in the
38879f95c82SChris Mason 		 * tree during a delete.  A deletion from lower in the tree
38979f95c82SChris Mason 		 * could try to delete the only pointer in this node.
39079f95c82SChris Mason 		 * So, pull some keys from the left.
39179f95c82SChris Mason 		 * There has to be a left pointer at this point because
39279f95c82SChris Mason 		 * otherwise we would have pulled some pointers from the
39379f95c82SChris Mason 		 * right
39479f95c82SChris Mason 		 */
39579f95c82SChris Mason 		BUG_ON(!left_buf);
396e089f05cSChris Mason 		wret = balance_node_right(trans, root, mid_buf, left_buf);
39779f95c82SChris Mason 		if (wret < 0)
39879f95c82SChris Mason 			ret = wret;
39979f95c82SChris Mason 		BUG_ON(wret == 1);
40079f95c82SChris Mason 	}
4017518a238SChris Mason 	if (btrfs_header_nritems(&mid->header) == 0) {
40279f95c82SChris Mason 		/* we've managed to empty the middle node, drop it */
4037eccb903SChris Mason 		u64 blocknr = bh_blocknr(mid_buf);
404e089f05cSChris Mason 		clean_tree_block(trans, root, mid_buf);
405d6025579SChris Mason 		wait_on_buffer(mid_buf);
406d6025579SChris Mason 		btrfs_block_release(root, mid_buf);
407bb803951SChris Mason 		mid_buf = NULL;
408bb803951SChris Mason 		mid = NULL;
409e089f05cSChris Mason 		wret = del_ptr(trans, root, path, level + 1, pslot);
410bb803951SChris Mason 		if (wret)
411bb803951SChris Mason 			ret = wret;
412e089f05cSChris Mason 		wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
413bb803951SChris Mason 		if (wret)
414bb803951SChris Mason 			ret = wret;
41579f95c82SChris Mason 	} else {
41679f95c82SChris Mason 		/* update the parent key to reflect our changes */
417d6025579SChris Mason 		btrfs_memcpy(root, parent,
418d6025579SChris Mason 			     &parent->ptrs[pslot].key, &mid->ptrs[0].key,
419e2fa7227SChris Mason 			     sizeof(struct btrfs_disk_key));
420d6025579SChris Mason 		btrfs_mark_buffer_dirty(parent_buf);
42179f95c82SChris Mason 	}
422bb803951SChris Mason 
42379f95c82SChris Mason 	/* update the path */
424bb803951SChris Mason 	if (left_buf) {
4257518a238SChris Mason 		if (btrfs_header_nritems(&left->header) > orig_slot) {
426e20d96d6SChris Mason 			get_bh(left_buf);
427bb803951SChris Mason 			path->nodes[level] = left_buf;
428bb803951SChris Mason 			path->slots[level + 1] -= 1;
429bb803951SChris Mason 			path->slots[level] = orig_slot;
430bb803951SChris Mason 			if (mid_buf)
431234b63a0SChris Mason 				btrfs_block_release(root, mid_buf);
432bb803951SChris Mason 		} else {
4337518a238SChris Mason 			orig_slot -= btrfs_header_nritems(&left->header);
434bb803951SChris Mason 			path->slots[level] = orig_slot;
435bb803951SChris Mason 		}
436bb803951SChris Mason 	}
43779f95c82SChris Mason 	/* double check we haven't messed things up */
438123abc88SChris Mason 	check_block(root, path, level);
439e20d96d6SChris Mason 	if (orig_ptr !=
440e20d96d6SChris Mason 	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
4411d4f8a0cSChris Mason 				path->slots[level]))
44279f95c82SChris Mason 		BUG();
443bb803951SChris Mason 
444bb803951SChris Mason 	if (right_buf)
445234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
446bb803951SChris Mason 	if (left_buf)
447234b63a0SChris Mason 		btrfs_block_release(root, left_buf);
448bb803951SChris Mason 	return ret;
449bb803951SChris Mason }
450bb803951SChris Mason 
451e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */
452e66f709bSChris Mason static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
453e66f709bSChris Mason 				struct btrfs_root *root,
454e66f709bSChris Mason 				struct btrfs_path *path, int level)
455e66f709bSChris Mason {
456e66f709bSChris Mason 	struct buffer_head *right_buf;
457e66f709bSChris Mason 	struct buffer_head *mid_buf;
458e66f709bSChris Mason 	struct buffer_head *left_buf;
459e66f709bSChris Mason 	struct buffer_head *parent_buf = NULL;
460e66f709bSChris Mason 	struct btrfs_node *right = NULL;
461e66f709bSChris Mason 	struct btrfs_node *mid;
462e66f709bSChris Mason 	struct btrfs_node *left = NULL;
463e66f709bSChris Mason 	struct btrfs_node *parent = NULL;
464e66f709bSChris Mason 	int ret = 0;
465e66f709bSChris Mason 	int wret;
466e66f709bSChris Mason 	int pslot;
467e66f709bSChris Mason 	int orig_slot = path->slots[level];
468e66f709bSChris Mason 	u64 orig_ptr;
469e66f709bSChris Mason 
470e66f709bSChris Mason 	if (level == 0)
471e66f709bSChris Mason 		return 1;
472e66f709bSChris Mason 
473e66f709bSChris Mason 	mid_buf = path->nodes[level];
474e66f709bSChris Mason 	mid = btrfs_buffer_node(mid_buf);
475e66f709bSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
476e66f709bSChris Mason 
477e66f709bSChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
478e66f709bSChris Mason 		parent_buf = path->nodes[level + 1];
479e66f709bSChris Mason 	pslot = path->slots[level + 1];
480e66f709bSChris Mason 
481e66f709bSChris Mason 	if (!parent_buf)
482e66f709bSChris Mason 		return 1;
483e66f709bSChris Mason 	parent = btrfs_buffer_node(parent_buf);
484e66f709bSChris Mason 
485e66f709bSChris Mason 	left_buf = read_node_slot(root, parent_buf, pslot - 1);
486e66f709bSChris Mason 
487e66f709bSChris Mason 	/* first, try to make some room in the middle buffer */
488e66f709bSChris Mason 	if (left_buf) {
489e66f709bSChris Mason 		u32 left_nr;
490e66f709bSChris Mason 		left = btrfs_buffer_node(left_buf);
491e66f709bSChris Mason 		left_nr = btrfs_header_nritems(&left->header);
49233ade1f8SChris Mason 		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
49333ade1f8SChris Mason 			wret = 1;
49433ade1f8SChris Mason 		} else {
49533ade1f8SChris Mason 			btrfs_cow_block(trans, root, left_buf, parent_buf,
49633ade1f8SChris Mason 					pslot - 1, &left_buf);
49733ade1f8SChris Mason 			left = btrfs_buffer_node(left_buf);
498e66f709bSChris Mason 			wret = push_node_left(trans, root, left_buf, mid_buf);
49933ade1f8SChris Mason 		}
500e66f709bSChris Mason 		if (wret < 0)
501e66f709bSChris Mason 			ret = wret;
502e66f709bSChris Mason 		if (wret == 0) {
503e66f709bSChris Mason 			orig_slot += left_nr;
504e66f709bSChris Mason 			btrfs_memcpy(root, parent,
505e66f709bSChris Mason 				     &parent->ptrs[pslot].key,
506e66f709bSChris Mason 				     &mid->ptrs[0].key,
507e66f709bSChris Mason 				     sizeof(struct btrfs_disk_key));
508e66f709bSChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
509e66f709bSChris Mason 			if (btrfs_header_nritems(&left->header) > orig_slot) {
510e66f709bSChris Mason 				path->nodes[level] = left_buf;
511e66f709bSChris Mason 				path->slots[level + 1] -= 1;
512e66f709bSChris Mason 				path->slots[level] = orig_slot;
513e66f709bSChris Mason 				btrfs_block_release(root, mid_buf);
514e66f709bSChris Mason 			} else {
515e66f709bSChris Mason 				orig_slot -=
516e66f709bSChris Mason 					btrfs_header_nritems(&left->header);
517e66f709bSChris Mason 				path->slots[level] = orig_slot;
518e66f709bSChris Mason 				btrfs_block_release(root, left_buf);
519e66f709bSChris Mason 			}
520e66f709bSChris Mason 			check_node(root, path, level);
521e66f709bSChris Mason 			return 0;
522e66f709bSChris Mason 		}
523e66f709bSChris Mason 		btrfs_block_release(root, left_buf);
524e66f709bSChris Mason 	}
525e66f709bSChris Mason 	right_buf = read_node_slot(root, parent_buf, pslot + 1);
526e66f709bSChris Mason 
527e66f709bSChris Mason 	/*
528e66f709bSChris Mason 	 * then try to empty the right most buffer into the middle
529e66f709bSChris Mason 	 */
530e66f709bSChris Mason 	if (right_buf) {
53133ade1f8SChris Mason 		u32 right_nr;
532e66f709bSChris Mason 		right = btrfs_buffer_node(right_buf);
53333ade1f8SChris Mason 		right_nr = btrfs_header_nritems(&right->header);
53433ade1f8SChris Mason 		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
53533ade1f8SChris Mason 			wret = 1;
53633ade1f8SChris Mason 		} else {
53733ade1f8SChris Mason 			btrfs_cow_block(trans, root, right_buf,
53833ade1f8SChris Mason 					parent_buf, pslot + 1, &right_buf);
53933ade1f8SChris Mason 			right = btrfs_buffer_node(right_buf);
54033ade1f8SChris Mason 			wret = balance_node_right(trans, root,
54133ade1f8SChris Mason 						  right_buf, mid_buf);
54233ade1f8SChris Mason 		}
543e66f709bSChris Mason 		if (wret < 0)
544e66f709bSChris Mason 			ret = wret;
545e66f709bSChris Mason 		if (wret == 0) {
546e66f709bSChris Mason 			btrfs_memcpy(root, parent,
547e66f709bSChris Mason 				     &parent->ptrs[pslot + 1].key,
548e66f709bSChris Mason 				     &right->ptrs[0].key,
549e66f709bSChris Mason 				     sizeof(struct btrfs_disk_key));
550e66f709bSChris Mason 			btrfs_mark_buffer_dirty(parent_buf);
551e66f709bSChris Mason 			if (btrfs_header_nritems(&mid->header) <= orig_slot) {
552e66f709bSChris Mason 				path->nodes[level] = right_buf;
553e66f709bSChris Mason 				path->slots[level + 1] += 1;
554e66f709bSChris Mason 				path->slots[level] = orig_slot -
555e66f709bSChris Mason 					btrfs_header_nritems(&mid->header);
556e66f709bSChris Mason 				btrfs_block_release(root, mid_buf);
557e66f709bSChris Mason 			} else {
558e66f709bSChris Mason 				btrfs_block_release(root, right_buf);
559e66f709bSChris Mason 			}
560e66f709bSChris Mason 			check_node(root, path, level);
561e66f709bSChris Mason 			return 0;
562e66f709bSChris Mason 		}
563e66f709bSChris Mason 		btrfs_block_release(root, right_buf);
564e66f709bSChris Mason 	}
565e66f709bSChris Mason 	check_node(root, path, level);
566e66f709bSChris Mason 	return 1;
567e66f709bSChris Mason }
568e66f709bSChris Mason 
56974123bd7SChris Mason /*
57074123bd7SChris Mason  * look for key in the tree.  path is filled in with nodes along the way
57174123bd7SChris Mason  * if key is found, we return zero and you can find the item in the leaf
57274123bd7SChris Mason  * level of the path (level 0)
57374123bd7SChris Mason  *
57474123bd7SChris Mason  * If the key isn't found, the path points to the slot where it should
575aa5d6bedSChris Mason  * be inserted, and 1 is returned.  If there are other errors during the
576aa5d6bedSChris Mason  * search a negative error number is returned.
57797571fd0SChris Mason  *
57897571fd0SChris Mason  * if ins_len > 0, nodes and leaves will be split as we walk down the
57997571fd0SChris Mason  * tree.  if ins_len < 0, nodes will be merged as we walk down the tree (if
58097571fd0SChris Mason  * possible)
58174123bd7SChris Mason  */
582e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
583e089f05cSChris Mason 		      *root, struct btrfs_key *key, struct btrfs_path *p, int
584e089f05cSChris Mason 		      ins_len, int cow)
585be0e5c09SChris Mason {
586e20d96d6SChris Mason 	struct buffer_head *b;
587e20d96d6SChris Mason 	struct buffer_head *cow_buf;
588234b63a0SChris Mason 	struct btrfs_node *c;
589be0e5c09SChris Mason 	int slot;
590be0e5c09SChris Mason 	int ret;
591be0e5c09SChris Mason 	int level;
5925c680ed6SChris Mason 
59322b0ebdaSChris Mason 	WARN_ON(p->nodes[0] != NULL);
59422b0ebdaSChris Mason 	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
595bb803951SChris Mason again:
596bb803951SChris Mason 	b = root->node;
597e20d96d6SChris Mason 	get_bh(b);
598eb60ceacSChris Mason 	while (b) {
599e20d96d6SChris Mason 		c = btrfs_buffer_node(b);
600e20d96d6SChris Mason 		level = btrfs_header_level(&c->header);
60102217ed2SChris Mason 		if (cow) {
60202217ed2SChris Mason 			int wret;
603e20d96d6SChris Mason 			wret = btrfs_cow_block(trans, root, b,
604e20d96d6SChris Mason 					       p->nodes[level + 1],
605e20d96d6SChris Mason 					       p->slots[level + 1],
606e089f05cSChris Mason 					       &cow_buf);
60702217ed2SChris Mason 			b = cow_buf;
6082c90e5d6SChris Mason 			c = btrfs_buffer_node(b);
60902217ed2SChris Mason 		}
61002217ed2SChris Mason 		BUG_ON(!cow && ins_len);
6112c90e5d6SChris Mason 		if (level != btrfs_header_level(&c->header))
6122c90e5d6SChris Mason 			WARN_ON(1);
6132c90e5d6SChris Mason 		level = btrfs_header_level(&c->header);
614eb60ceacSChris Mason 		p->nodes[level] = b;
615123abc88SChris Mason 		ret = check_block(root, p, level);
616aa5d6bedSChris Mason 		if (ret)
617aa5d6bedSChris Mason 			return -1;
618be0e5c09SChris Mason 		ret = bin_search(c, key, &slot);
6197518a238SChris Mason 		if (!btrfs_is_leaf(c)) {
620be0e5c09SChris Mason 			if (ret && slot > 0)
621be0e5c09SChris Mason 				slot -= 1;
622be0e5c09SChris Mason 			p->slots[level] = slot;
623d4dbff95SChris Mason 			if (ins_len > 0 && btrfs_header_nritems(&c->header) >=
624d4dbff95SChris Mason 			    BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
625e089f05cSChris Mason 				int sret = split_node(trans, root, p, level);
6265c680ed6SChris Mason 				BUG_ON(sret > 0);
6275c680ed6SChris Mason 				if (sret)
6285c680ed6SChris Mason 					return sret;
6295c680ed6SChris Mason 				b = p->nodes[level];
630e20d96d6SChris Mason 				c = btrfs_buffer_node(b);
6315c680ed6SChris Mason 				slot = p->slots[level];
632bb803951SChris Mason 			} else if (ins_len < 0) {
633e089f05cSChris Mason 				int sret = balance_level(trans, root, p,
634e089f05cSChris Mason 							 level);
635bb803951SChris Mason 				if (sret)
636bb803951SChris Mason 					return sret;
637bb803951SChris Mason 				b = p->nodes[level];
638bb803951SChris Mason 				if (!b)
639bb803951SChris Mason 					goto again;
640e20d96d6SChris Mason 				c = btrfs_buffer_node(b);
641bb803951SChris Mason 				slot = p->slots[level];
6427518a238SChris Mason 				BUG_ON(btrfs_header_nritems(&c->header) == 1);
6435c680ed6SChris Mason 			}
6441d4f8a0cSChris Mason 			b = read_tree_block(root, btrfs_node_blockptr(c, slot));
645be0e5c09SChris Mason 		} else {
646234b63a0SChris Mason 			struct btrfs_leaf *l = (struct btrfs_leaf *)c;
647be0e5c09SChris Mason 			p->slots[level] = slot;
648123abc88SChris Mason 			if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
6490783fcfcSChris Mason 			    sizeof(struct btrfs_item) + ins_len) {
650d4dbff95SChris Mason 				int sret = split_leaf(trans, root, key,
651d4dbff95SChris Mason 						      p, ins_len);
6525c680ed6SChris Mason 				BUG_ON(sret > 0);
6535c680ed6SChris Mason 				if (sret)
6545c680ed6SChris Mason 					return sret;
6555c680ed6SChris Mason 			}
656be0e5c09SChris Mason 			return ret;
657be0e5c09SChris Mason 		}
658be0e5c09SChris Mason 	}
659aa5d6bedSChris Mason 	return 1;
660be0e5c09SChris Mason }
661be0e5c09SChris Mason 
66274123bd7SChris Mason /*
66374123bd7SChris Mason  * adjust the pointers going up the tree, starting at level
66474123bd7SChris Mason  * making sure the right key of each node is points to 'key'.
66574123bd7SChris Mason  * This is used after shifting pointers to the left, so it stops
66674123bd7SChris Mason  * fixing up pointers when a given leaf/node is not in slot 0 of the
66774123bd7SChris Mason  * higher levels
668aa5d6bedSChris Mason  *
669aa5d6bedSChris Mason  * If this fails to write a tree block, it returns -1, but continues
670aa5d6bedSChris Mason  * fixing up the blocks in ram so the tree is consistent.
67174123bd7SChris Mason  */
672e089f05cSChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
673e089f05cSChris Mason 			  *root, struct btrfs_path *path, struct btrfs_disk_key
674e089f05cSChris Mason 			  *key, int level)
675be0e5c09SChris Mason {
676be0e5c09SChris Mason 	int i;
677aa5d6bedSChris Mason 	int ret = 0;
678234b63a0SChris Mason 	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
679234b63a0SChris Mason 		struct btrfs_node *t;
680be0e5c09SChris Mason 		int tslot = path->slots[i];
681eb60ceacSChris Mason 		if (!path->nodes[i])
682be0e5c09SChris Mason 			break;
683e20d96d6SChris Mason 		t = btrfs_buffer_node(path->nodes[i]);
684d6025579SChris Mason 		btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key));
685d6025579SChris Mason 		btrfs_mark_buffer_dirty(path->nodes[i]);
686be0e5c09SChris Mason 		if (tslot != 0)
687be0e5c09SChris Mason 			break;
688be0e5c09SChris Mason 	}
689aa5d6bedSChris Mason 	return ret;
690be0e5c09SChris Mason }
691be0e5c09SChris Mason 
69274123bd7SChris Mason /*
69374123bd7SChris Mason  * try to push data from one node into the next node left in the
69479f95c82SChris Mason  * tree.
695aa5d6bedSChris Mason  *
696aa5d6bedSChris Mason  * returns 0 if some ptrs were pushed left, < 0 if there was some horrible
697aa5d6bedSChris Mason  * error, and > 0 if there was no room in the left hand block.
69874123bd7SChris Mason  */
699e089f05cSChris Mason static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
700e20d96d6SChris Mason 			  *root, struct buffer_head *dst_buf, struct
701e20d96d6SChris Mason 			  buffer_head *src_buf)
702be0e5c09SChris Mason {
703e20d96d6SChris Mason 	struct btrfs_node *src = btrfs_buffer_node(src_buf);
704e20d96d6SChris Mason 	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
705be0e5c09SChris Mason 	int push_items = 0;
706bb803951SChris Mason 	int src_nritems;
707bb803951SChris Mason 	int dst_nritems;
708aa5d6bedSChris Mason 	int ret = 0;
709be0e5c09SChris Mason 
7107518a238SChris Mason 	src_nritems = btrfs_header_nritems(&src->header);
7117518a238SChris Mason 	dst_nritems = btrfs_header_nritems(&dst->header);
712123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
713eb60ceacSChris Mason 	if (push_items <= 0) {
714be0e5c09SChris Mason 		return 1;
715eb60ceacSChris Mason 	}
716be0e5c09SChris Mason 
717be0e5c09SChris Mason 	if (src_nritems < push_items)
718be0e5c09SChris Mason 		push_items = src_nritems;
71979f95c82SChris Mason 
720d6025579SChris Mason 	btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs,
721123abc88SChris Mason 		     push_items * sizeof(struct btrfs_key_ptr));
722bb803951SChris Mason 	if (push_items < src_nritems) {
723d6025579SChris Mason 		btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items,
724e2fa7227SChris Mason 			(src_nritems - push_items) *
725123abc88SChris Mason 			sizeof(struct btrfs_key_ptr));
726bb803951SChris Mason 	}
7277518a238SChris Mason 	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
7287518a238SChris Mason 	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
729d6025579SChris Mason 	btrfs_mark_buffer_dirty(src_buf);
730d6025579SChris Mason 	btrfs_mark_buffer_dirty(dst_buf);
731bb803951SChris Mason 	return ret;
732be0e5c09SChris Mason }
733be0e5c09SChris Mason 
73497571fd0SChris Mason /*
73579f95c82SChris Mason  * try to push data from one node into the next node right in the
73679f95c82SChris Mason  * tree.
73779f95c82SChris Mason  *
73879f95c82SChris Mason  * returns 0 if some ptrs were pushed, < 0 if there was some horrible
73979f95c82SChris Mason  * error, and > 0 if there was no room in the right hand block.
74079f95c82SChris Mason  *
74179f95c82SChris Mason  * this will  only push up to 1/2 the contents of the left node over
74279f95c82SChris Mason  */
743e089f05cSChris Mason static int balance_node_right(struct btrfs_trans_handle *trans, struct
744e20d96d6SChris Mason 			      btrfs_root *root, struct buffer_head *dst_buf,
745e20d96d6SChris Mason 			      struct buffer_head *src_buf)
74679f95c82SChris Mason {
747e20d96d6SChris Mason 	struct btrfs_node *src = btrfs_buffer_node(src_buf);
748e20d96d6SChris Mason 	struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
74979f95c82SChris Mason 	int push_items = 0;
75079f95c82SChris Mason 	int max_push;
75179f95c82SChris Mason 	int src_nritems;
75279f95c82SChris Mason 	int dst_nritems;
75379f95c82SChris Mason 	int ret = 0;
75479f95c82SChris Mason 
7557518a238SChris Mason 	src_nritems = btrfs_header_nritems(&src->header);
7567518a238SChris Mason 	dst_nritems = btrfs_header_nritems(&dst->header);
757123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
75879f95c82SChris Mason 	if (push_items <= 0) {
75979f95c82SChris Mason 		return 1;
76079f95c82SChris Mason 	}
76179f95c82SChris Mason 
76279f95c82SChris Mason 	max_push = src_nritems / 2 + 1;
76379f95c82SChris Mason 	/* don't try to empty the node */
76479f95c82SChris Mason 	if (max_push > src_nritems)
76579f95c82SChris Mason 		return 1;
76679f95c82SChris Mason 	if (max_push < push_items)
76779f95c82SChris Mason 		push_items = max_push;
76879f95c82SChris Mason 
769d6025579SChris Mason 	btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs,
770123abc88SChris Mason 		      dst_nritems * sizeof(struct btrfs_key_ptr));
771d6025579SChris Mason 
772d6025579SChris Mason 	btrfs_memcpy(root, dst, dst->ptrs,
773d6025579SChris Mason 		     src->ptrs + src_nritems - push_items,
774123abc88SChris Mason 		     push_items * sizeof(struct btrfs_key_ptr));
77579f95c82SChris Mason 
7767518a238SChris Mason 	btrfs_set_header_nritems(&src->header, src_nritems - push_items);
7777518a238SChris Mason 	btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
77879f95c82SChris Mason 
779d6025579SChris Mason 	btrfs_mark_buffer_dirty(src_buf);
780d6025579SChris Mason 	btrfs_mark_buffer_dirty(dst_buf);
78179f95c82SChris Mason 	return ret;
78279f95c82SChris Mason }
78379f95c82SChris Mason 
78479f95c82SChris Mason /*
78597571fd0SChris Mason  * helper function to insert a new root level in the tree.
78697571fd0SChris Mason  * A new node is allocated, and a single item is inserted to
78797571fd0SChris Mason  * point to the existing root
788aa5d6bedSChris Mason  *
789aa5d6bedSChris Mason  * returns zero on success or < 0 on failure.
79097571fd0SChris Mason  */
791e089f05cSChris Mason static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
792e089f05cSChris Mason 			   *root, struct btrfs_path *path, int level)
79374123bd7SChris Mason {
794e20d96d6SChris Mason 	struct buffer_head *t;
795234b63a0SChris Mason 	struct btrfs_node *lower;
796234b63a0SChris Mason 	struct btrfs_node *c;
797e2fa7227SChris Mason 	struct btrfs_disk_key *lower_key;
7985c680ed6SChris Mason 
7995c680ed6SChris Mason 	BUG_ON(path->nodes[level]);
8005c680ed6SChris Mason 	BUG_ON(path->nodes[level-1] != root->node);
8015c680ed6SChris Mason 
802e089f05cSChris Mason 	t = btrfs_alloc_free_block(trans, root);
803e20d96d6SChris Mason 	c = btrfs_buffer_node(t);
804123abc88SChris Mason 	memset(c, 0, root->blocksize);
8057518a238SChris Mason 	btrfs_set_header_nritems(&c->header, 1);
8067518a238SChris Mason 	btrfs_set_header_level(&c->header, level);
8077eccb903SChris Mason 	btrfs_set_header_blocknr(&c->header, bh_blocknr(t));
8087f5c1516SChris Mason 	btrfs_set_header_generation(&c->header, trans->transid);
809e20d96d6SChris Mason 	lower = btrfs_buffer_node(path->nodes[level-1]);
8103eb0314dSChris Mason 	memcpy(c->header.fsid, root->fs_info->disk_super->fsid,
8113eb0314dSChris Mason 	       sizeof(c->header.fsid));
8127518a238SChris Mason 	if (btrfs_is_leaf(lower))
813234b63a0SChris Mason 		lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
81474123bd7SChris Mason 	else
815123abc88SChris Mason 		lower_key = &lower->ptrs[0].key;
816d6025579SChris Mason 	btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key,
817d6025579SChris Mason 		     sizeof(struct btrfs_disk_key));
8187eccb903SChris Mason 	btrfs_set_node_blockptr(c, 0, bh_blocknr(path->nodes[level - 1]));
819d5719762SChris Mason 
820d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
821d5719762SChris Mason 
822cfaa7295SChris Mason 	/* the super has an extra ref to root->node */
823234b63a0SChris Mason 	btrfs_block_release(root, root->node);
82474123bd7SChris Mason 	root->node = t;
825e20d96d6SChris Mason 	get_bh(t);
82674123bd7SChris Mason 	path->nodes[level] = t;
82774123bd7SChris Mason 	path->slots[level] = 0;
82874123bd7SChris Mason 	return 0;
82974123bd7SChris Mason }
8305c680ed6SChris Mason 
8315c680ed6SChris Mason /*
8325c680ed6SChris Mason  * worker function to insert a single pointer in a node.
8335c680ed6SChris Mason  * the node should have enough room for the pointer already
83497571fd0SChris Mason  *
8355c680ed6SChris Mason  * slot and level indicate where you want the key to go, and
8365c680ed6SChris Mason  * blocknr is the block the key points to.
837aa5d6bedSChris Mason  *
838aa5d6bedSChris Mason  * returns zero on success and < 0 on any error
8395c680ed6SChris Mason  */
840e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
841e089f05cSChris Mason 		      *root, struct btrfs_path *path, struct btrfs_disk_key
842e089f05cSChris Mason 		      *key, u64 blocknr, int slot, int level)
8435c680ed6SChris Mason {
844234b63a0SChris Mason 	struct btrfs_node *lower;
8455c680ed6SChris Mason 	int nritems;
8465c680ed6SChris Mason 
8475c680ed6SChris Mason 	BUG_ON(!path->nodes[level]);
848e20d96d6SChris Mason 	lower = btrfs_buffer_node(path->nodes[level]);
8497518a238SChris Mason 	nritems = btrfs_header_nritems(&lower->header);
85074123bd7SChris Mason 	if (slot > nritems)
85174123bd7SChris Mason 		BUG();
852123abc88SChris Mason 	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
85374123bd7SChris Mason 		BUG();
85474123bd7SChris Mason 	if (slot != nritems) {
855d6025579SChris Mason 		btrfs_memmove(root, lower, lower->ptrs + slot + 1,
856d6025579SChris Mason 			      lower->ptrs + slot,
857123abc88SChris Mason 			      (nritems - slot) * sizeof(struct btrfs_key_ptr));
85874123bd7SChris Mason 	}
859d6025579SChris Mason 	btrfs_memcpy(root, lower, &lower->ptrs[slot].key,
860d6025579SChris Mason 		     key, sizeof(struct btrfs_disk_key));
8611d4f8a0cSChris Mason 	btrfs_set_node_blockptr(lower, slot, blocknr);
8627518a238SChris Mason 	btrfs_set_header_nritems(&lower->header, nritems + 1);
863d6025579SChris Mason 	btrfs_mark_buffer_dirty(path->nodes[level]);
86474123bd7SChris Mason 	return 0;
86574123bd7SChris Mason }
86674123bd7SChris Mason 
86797571fd0SChris Mason /*
86897571fd0SChris Mason  * split the node at the specified level in path in two.
86997571fd0SChris Mason  * The path is corrected to point to the appropriate node after the split
87097571fd0SChris Mason  *
87197571fd0SChris Mason  * Before splitting this tries to make some room in the node by pushing
87297571fd0SChris Mason  * left and right, if either one works, it returns right away.
873aa5d6bedSChris Mason  *
874aa5d6bedSChris Mason  * returns 0 on success and < 0 on failure
87597571fd0SChris Mason  */
876e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
877e089f05cSChris Mason 		      *root, struct btrfs_path *path, int level)
878be0e5c09SChris Mason {
879e20d96d6SChris Mason 	struct buffer_head *t;
880234b63a0SChris Mason 	struct btrfs_node *c;
881e20d96d6SChris Mason 	struct buffer_head *split_buffer;
882234b63a0SChris Mason 	struct btrfs_node *split;
883be0e5c09SChris Mason 	int mid;
8845c680ed6SChris Mason 	int ret;
885aa5d6bedSChris Mason 	int wret;
8867518a238SChris Mason 	u32 c_nritems;
887be0e5c09SChris Mason 
8885c680ed6SChris Mason 	t = path->nodes[level];
889e20d96d6SChris Mason 	c = btrfs_buffer_node(t);
8905c680ed6SChris Mason 	if (t == root->node) {
8915c680ed6SChris Mason 		/* trying to split the root, lets make a new one */
892e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, level + 1);
8935c680ed6SChris Mason 		if (ret)
8945c680ed6SChris Mason 			return ret;
895e66f709bSChris Mason 	} else {
896e66f709bSChris Mason 		ret = push_nodes_for_insert(trans, root, path, level);
897e66f709bSChris Mason 		t = path->nodes[level];
898e66f709bSChris Mason 		c = btrfs_buffer_node(t);
899e66f709bSChris Mason 		if (!ret &&
900e66f709bSChris Mason 		    btrfs_header_nritems(&c->header) <
901e66f709bSChris Mason 		    BTRFS_NODEPTRS_PER_BLOCK(root) - 1)
902e66f709bSChris Mason 			return 0;
9035c680ed6SChris Mason 	}
904e66f709bSChris Mason 
9057518a238SChris Mason 	c_nritems = btrfs_header_nritems(&c->header);
906e089f05cSChris Mason 	split_buffer = btrfs_alloc_free_block(trans, root);
907e20d96d6SChris Mason 	split = btrfs_buffer_node(split_buffer);
9087518a238SChris Mason 	btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
9099a6f11edSChris Mason 	btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
9107eccb903SChris Mason 	btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer));
9117f5c1516SChris Mason 	btrfs_set_header_generation(&split->header, trans->transid);
9123eb0314dSChris Mason 	memcpy(split->header.fsid, root->fs_info->disk_super->fsid,
9133eb0314dSChris Mason 	       sizeof(split->header.fsid));
9147518a238SChris Mason 	mid = (c_nritems + 1) / 2;
915d6025579SChris Mason 	btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid,
916123abc88SChris Mason 		     (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
9177518a238SChris Mason 	btrfs_set_header_nritems(&split->header, c_nritems - mid);
9187518a238SChris Mason 	btrfs_set_header_nritems(&c->header, mid);
919aa5d6bedSChris Mason 	ret = 0;
920aa5d6bedSChris Mason 
921d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
922d6025579SChris Mason 	btrfs_mark_buffer_dirty(split_buffer);
923e089f05cSChris Mason 	wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
9247eccb903SChris Mason 			  bh_blocknr(split_buffer), path->slots[level + 1] + 1,
925123abc88SChris Mason 			  level + 1);
926aa5d6bedSChris Mason 	if (wret)
927aa5d6bedSChris Mason 		ret = wret;
928aa5d6bedSChris Mason 
9295de08d7dSChris Mason 	if (path->slots[level] >= mid) {
9305c680ed6SChris Mason 		path->slots[level] -= mid;
931234b63a0SChris Mason 		btrfs_block_release(root, t);
9325c680ed6SChris Mason 		path->nodes[level] = split_buffer;
9335c680ed6SChris Mason 		path->slots[level + 1] += 1;
934eb60ceacSChris Mason 	} else {
935234b63a0SChris Mason 		btrfs_block_release(root, split_buffer);
936be0e5c09SChris Mason 	}
937aa5d6bedSChris Mason 	return ret;
938be0e5c09SChris Mason }
939be0e5c09SChris Mason 
94074123bd7SChris Mason /*
94174123bd7SChris Mason  * how many bytes are required to store the items in a leaf.  start
94274123bd7SChris Mason  * and nr indicate which items in the leaf to check.  This totals up the
94374123bd7SChris Mason  * space used both by the item structs and the item data
94474123bd7SChris Mason  */
945234b63a0SChris Mason static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
946be0e5c09SChris Mason {
947be0e5c09SChris Mason 	int data_len;
948d4dbff95SChris Mason 	int nritems = btrfs_header_nritems(&l->header);
949d4dbff95SChris Mason 	int end = min(nritems, start + nr) - 1;
950be0e5c09SChris Mason 
951be0e5c09SChris Mason 	if (!nr)
952be0e5c09SChris Mason 		return 0;
9530783fcfcSChris Mason 	data_len = btrfs_item_end(l->items + start);
9540783fcfcSChris Mason 	data_len = data_len - btrfs_item_offset(l->items + end);
9550783fcfcSChris Mason 	data_len += sizeof(struct btrfs_item) * nr;
956d4dbff95SChris Mason 	WARN_ON(data_len < 0);
957be0e5c09SChris Mason 	return data_len;
958be0e5c09SChris Mason }
959be0e5c09SChris Mason 
96074123bd7SChris Mason /*
961d4dbff95SChris Mason  * The space between the end of the leaf items and
962d4dbff95SChris Mason  * the start of the leaf data.  IOW, how much room
963d4dbff95SChris Mason  * the leaf has left for both items and data
964d4dbff95SChris Mason  */
965d4dbff95SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf)
966d4dbff95SChris Mason {
967d4dbff95SChris Mason 	int nritems = btrfs_header_nritems(&leaf->header);
968d4dbff95SChris Mason 	return BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems);
969d4dbff95SChris Mason }
970d4dbff95SChris Mason 
971d4dbff95SChris Mason /*
97200ec4c51SChris Mason  * push some data in the path leaf to the right, trying to free up at
97300ec4c51SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
974aa5d6bedSChris Mason  *
975aa5d6bedSChris Mason  * returns 1 if the push failed because the other node didn't have enough
976aa5d6bedSChris Mason  * room, 0 if everything worked out and < 0 if there were major errors.
97700ec4c51SChris Mason  */
978e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
979e089f05cSChris Mason 			   *root, struct btrfs_path *path, int data_size)
98000ec4c51SChris Mason {
981e20d96d6SChris Mason 	struct buffer_head *left_buf = path->nodes[0];
982e20d96d6SChris Mason 	struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf);
983234b63a0SChris Mason 	struct btrfs_leaf *right;
984e20d96d6SChris Mason 	struct buffer_head *right_buf;
985e20d96d6SChris Mason 	struct buffer_head *upper;
986e20d96d6SChris Mason 	struct btrfs_node *upper_node;
98700ec4c51SChris Mason 	int slot;
98800ec4c51SChris Mason 	int i;
98900ec4c51SChris Mason 	int free_space;
99000ec4c51SChris Mason 	int push_space = 0;
99100ec4c51SChris Mason 	int push_items = 0;
9920783fcfcSChris Mason 	struct btrfs_item *item;
9937518a238SChris Mason 	u32 left_nritems;
9947518a238SChris Mason 	u32 right_nritems;
99500ec4c51SChris Mason 
99600ec4c51SChris Mason 	slot = path->slots[1];
99700ec4c51SChris Mason 	if (!path->nodes[1]) {
99800ec4c51SChris Mason 		return 1;
99900ec4c51SChris Mason 	}
100000ec4c51SChris Mason 	upper = path->nodes[1];
1001e20d96d6SChris Mason 	upper_node = btrfs_buffer_node(upper);
1002e20d96d6SChris Mason 	if (slot >= btrfs_header_nritems(&upper_node->header) - 1) {
100300ec4c51SChris Mason 		return 1;
100400ec4c51SChris Mason 	}
1005e20d96d6SChris Mason 	right_buf = read_tree_block(root,
1006e20d96d6SChris Mason 		    btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1));
1007e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buf);
1008123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
10090783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1010234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
101100ec4c51SChris Mason 		return 1;
101200ec4c51SChris Mason 	}
101302217ed2SChris Mason 	/* cow and double check */
1014e089f05cSChris Mason 	btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf);
1015e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buf);
1016123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
10170783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1018234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
101902217ed2SChris Mason 		return 1;
102002217ed2SChris Mason 	}
102102217ed2SChris Mason 
10227518a238SChris Mason 	left_nritems = btrfs_header_nritems(&left->header);
1023a429e513SChris Mason 	if (left_nritems == 0) {
1024a429e513SChris Mason 		btrfs_block_release(root, right_buf);
1025a429e513SChris Mason 		return 1;
1026a429e513SChris Mason 	}
1027a429e513SChris Mason 	for (i = left_nritems - 1; i >= 1; i--) {
102800ec4c51SChris Mason 		item = left->items + i;
102900ec4c51SChris Mason 		if (path->slots[0] == i)
103000ec4c51SChris Mason 			push_space += data_size + sizeof(*item);
10310783fcfcSChris Mason 		if (btrfs_item_size(item) + sizeof(*item) + push_space >
10320783fcfcSChris Mason 		    free_space)
103300ec4c51SChris Mason 			break;
103400ec4c51SChris Mason 		push_items++;
10350783fcfcSChris Mason 		push_space += btrfs_item_size(item) + sizeof(*item);
103600ec4c51SChris Mason 	}
103700ec4c51SChris Mason 	if (push_items == 0) {
1038234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
103900ec4c51SChris Mason 		return 1;
104000ec4c51SChris Mason 	}
1041a429e513SChris Mason 	if (push_items == left_nritems)
1042a429e513SChris Mason 		WARN_ON(1);
10437518a238SChris Mason 	right_nritems = btrfs_header_nritems(&right->header);
104400ec4c51SChris Mason 	/* push left to right */
10450783fcfcSChris Mason 	push_space = btrfs_item_end(left->items + left_nritems - push_items);
1046123abc88SChris Mason 	push_space -= leaf_data_end(root, left);
104700ec4c51SChris Mason 	/* make room in the right data area */
1048d6025579SChris Mason 	btrfs_memmove(root, right, btrfs_leaf_data(right) +
1049d6025579SChris Mason 		      leaf_data_end(root, right) - push_space,
1050d6025579SChris Mason 		      btrfs_leaf_data(right) +
1051d6025579SChris Mason 		      leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) -
1052d6025579SChris Mason 		      leaf_data_end(root, right));
105300ec4c51SChris Mason 	/* copy from the left data area */
1054d6025579SChris Mason 	btrfs_memcpy(root, right, btrfs_leaf_data(right) +
1055d6025579SChris Mason 		     BTRFS_LEAF_DATA_SIZE(root) - push_space,
1056d6025579SChris Mason 		     btrfs_leaf_data(left) + leaf_data_end(root, left),
1057d6025579SChris Mason 		     push_space);
1058d6025579SChris Mason 	btrfs_memmove(root, right, right->items + push_items, right->items,
10590783fcfcSChris Mason 		right_nritems * sizeof(struct btrfs_item));
106000ec4c51SChris Mason 	/* copy the items from left to right */
1061d6025579SChris Mason 	btrfs_memcpy(root, right, right->items, left->items +
1062d6025579SChris Mason 		     left_nritems - push_items,
10630783fcfcSChris Mason 		     push_items * sizeof(struct btrfs_item));
106400ec4c51SChris Mason 
106500ec4c51SChris Mason 	/* update the item pointers */
10667518a238SChris Mason 	right_nritems += push_items;
10677518a238SChris Mason 	btrfs_set_header_nritems(&right->header, right_nritems);
1068123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
10697518a238SChris Mason 	for (i = 0; i < right_nritems; i++) {
10700783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, push_space -
10710783fcfcSChris Mason 				      btrfs_item_size(right->items + i));
10720783fcfcSChris Mason 		push_space = btrfs_item_offset(right->items + i);
107300ec4c51SChris Mason 	}
10747518a238SChris Mason 	left_nritems -= push_items;
10757518a238SChris Mason 	btrfs_set_header_nritems(&left->header, left_nritems);
107600ec4c51SChris Mason 
1077d6025579SChris Mason 	btrfs_mark_buffer_dirty(left_buf);
1078d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buf);
1079a429e513SChris Mason 
1080d6025579SChris Mason 	btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key,
1081e2fa7227SChris Mason 		&right->items[0].key, sizeof(struct btrfs_disk_key));
1082d6025579SChris Mason 	btrfs_mark_buffer_dirty(upper);
108302217ed2SChris Mason 
108400ec4c51SChris Mason 	/* then fixup the leaf pointer in the path */
10857518a238SChris Mason 	if (path->slots[0] >= left_nritems) {
10867518a238SChris Mason 		path->slots[0] -= left_nritems;
1087234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
108800ec4c51SChris Mason 		path->nodes[0] = right_buf;
108900ec4c51SChris Mason 		path->slots[1] += 1;
109000ec4c51SChris Mason 	} else {
1091234b63a0SChris Mason 		btrfs_block_release(root, right_buf);
109200ec4c51SChris Mason 	}
109300ec4c51SChris Mason 	return 0;
109400ec4c51SChris Mason }
109500ec4c51SChris Mason /*
109674123bd7SChris Mason  * push some data in the path leaf to the left, trying to free up at
109774123bd7SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
109874123bd7SChris Mason  */
1099e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
1100e089f05cSChris Mason 			  *root, struct btrfs_path *path, int data_size)
1101be0e5c09SChris Mason {
1102e20d96d6SChris Mason 	struct buffer_head *right_buf = path->nodes[0];
1103e20d96d6SChris Mason 	struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf);
1104e20d96d6SChris Mason 	struct buffer_head *t;
1105234b63a0SChris Mason 	struct btrfs_leaf *left;
1106be0e5c09SChris Mason 	int slot;
1107be0e5c09SChris Mason 	int i;
1108be0e5c09SChris Mason 	int free_space;
1109be0e5c09SChris Mason 	int push_space = 0;
1110be0e5c09SChris Mason 	int push_items = 0;
11110783fcfcSChris Mason 	struct btrfs_item *item;
11127518a238SChris Mason 	u32 old_left_nritems;
1113aa5d6bedSChris Mason 	int ret = 0;
1114aa5d6bedSChris Mason 	int wret;
1115be0e5c09SChris Mason 
1116be0e5c09SChris Mason 	slot = path->slots[1];
1117be0e5c09SChris Mason 	if (slot == 0) {
1118be0e5c09SChris Mason 		return 1;
1119be0e5c09SChris Mason 	}
1120be0e5c09SChris Mason 	if (!path->nodes[1]) {
1121be0e5c09SChris Mason 		return 1;
1122be0e5c09SChris Mason 	}
1123e20d96d6SChris Mason 	t = read_tree_block(root,
1124e20d96d6SChris Mason 	    btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1));
1125e20d96d6SChris Mason 	left = btrfs_buffer_leaf(t);
1126123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
11270783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1128234b63a0SChris Mason 		btrfs_block_release(root, t);
1129be0e5c09SChris Mason 		return 1;
1130be0e5c09SChris Mason 	}
113102217ed2SChris Mason 
113202217ed2SChris Mason 	/* cow and double check */
1133e089f05cSChris Mason 	btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
1134e20d96d6SChris Mason 	left = btrfs_buffer_leaf(t);
1135123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
11360783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
1137234b63a0SChris Mason 		btrfs_block_release(root, t);
113802217ed2SChris Mason 		return 1;
113902217ed2SChris Mason 	}
114002217ed2SChris Mason 
1141a429e513SChris Mason 	if (btrfs_header_nritems(&right->header) == 0) {
1142a429e513SChris Mason 		btrfs_block_release(root, t);
1143a429e513SChris Mason 		return 1;
1144a429e513SChris Mason 	}
1145a429e513SChris Mason 
1146a429e513SChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header) - 1; i++) {
1147be0e5c09SChris Mason 		item = right->items + i;
1148be0e5c09SChris Mason 		if (path->slots[0] == i)
1149be0e5c09SChris Mason 			push_space += data_size + sizeof(*item);
11500783fcfcSChris Mason 		if (btrfs_item_size(item) + sizeof(*item) + push_space >
11510783fcfcSChris Mason 		    free_space)
1152be0e5c09SChris Mason 			break;
1153be0e5c09SChris Mason 		push_items++;
11540783fcfcSChris Mason 		push_space += btrfs_item_size(item) + sizeof(*item);
1155be0e5c09SChris Mason 	}
1156be0e5c09SChris Mason 	if (push_items == 0) {
1157234b63a0SChris Mason 		btrfs_block_release(root, t);
1158be0e5c09SChris Mason 		return 1;
1159be0e5c09SChris Mason 	}
1160a429e513SChris Mason 	if (push_items == btrfs_header_nritems(&right->header))
1161a429e513SChris Mason 		WARN_ON(1);
1162be0e5c09SChris Mason 	/* push data from right to left */
1163d6025579SChris Mason 	btrfs_memcpy(root, left, left->items +
1164d6025579SChris Mason 		     btrfs_header_nritems(&left->header),
11650783fcfcSChris Mason 		     right->items, push_items * sizeof(struct btrfs_item));
1166123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root) -
11670783fcfcSChris Mason 		     btrfs_item_offset(right->items + push_items -1);
1168d6025579SChris Mason 	btrfs_memcpy(root, left, btrfs_leaf_data(left) +
1169d6025579SChris Mason 		     leaf_data_end(root, left) - push_space,
1170123abc88SChris Mason 		     btrfs_leaf_data(right) +
1171123abc88SChris Mason 		     btrfs_item_offset(right->items + push_items - 1),
1172be0e5c09SChris Mason 		     push_space);
11737518a238SChris Mason 	old_left_nritems = btrfs_header_nritems(&left->header);
1174eb60ceacSChris Mason 	BUG_ON(old_left_nritems < 0);
1175eb60ceacSChris Mason 
1176be0e5c09SChris Mason 	for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
1177123abc88SChris Mason 		u32 ioff = btrfs_item_offset(left->items + i);
1178123abc88SChris Mason 		btrfs_set_item_offset(left->items + i, ioff -
1179123abc88SChris Mason 				     (BTRFS_LEAF_DATA_SIZE(root) -
11800783fcfcSChris Mason 				      btrfs_item_offset(left->items +
11810783fcfcSChris Mason 						        old_left_nritems - 1)));
1182be0e5c09SChris Mason 	}
11837518a238SChris Mason 	btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
1184be0e5c09SChris Mason 
1185be0e5c09SChris Mason 	/* fixup right node */
11860783fcfcSChris Mason 	push_space = btrfs_item_offset(right->items + push_items - 1) -
1187123abc88SChris Mason 		     leaf_data_end(root, right);
1188d6025579SChris Mason 	btrfs_memmove(root, right, btrfs_leaf_data(right) +
1189d6025579SChris Mason 		      BTRFS_LEAF_DATA_SIZE(root) - push_space,
1190d6025579SChris Mason 		      btrfs_leaf_data(right) +
1191123abc88SChris Mason 		      leaf_data_end(root, right), push_space);
1192d6025579SChris Mason 	btrfs_memmove(root, right, right->items, right->items + push_items,
11937518a238SChris Mason 		(btrfs_header_nritems(&right->header) - push_items) *
11940783fcfcSChris Mason 		sizeof(struct btrfs_item));
11957518a238SChris Mason 	btrfs_set_header_nritems(&right->header,
11967518a238SChris Mason 				 btrfs_header_nritems(&right->header) -
11977518a238SChris Mason 				 push_items);
1198123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
1199eb60ceacSChris Mason 
12007518a238SChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
12010783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, push_space -
12020783fcfcSChris Mason 				      btrfs_item_size(right->items + i));
12030783fcfcSChris Mason 		push_space = btrfs_item_offset(right->items + i);
1204be0e5c09SChris Mason 	}
1205eb60ceacSChris Mason 
1206d6025579SChris Mason 	btrfs_mark_buffer_dirty(t);
1207d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buf);
1208e089f05cSChris Mason 	wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
1209aa5d6bedSChris Mason 	if (wret)
1210aa5d6bedSChris Mason 		ret = wret;
1211be0e5c09SChris Mason 
1212be0e5c09SChris Mason 	/* then fixup the leaf pointer in the path */
1213be0e5c09SChris Mason 	if (path->slots[0] < push_items) {
1214be0e5c09SChris Mason 		path->slots[0] += old_left_nritems;
1215234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
1216eb60ceacSChris Mason 		path->nodes[0] = t;
1217be0e5c09SChris Mason 		path->slots[1] -= 1;
1218be0e5c09SChris Mason 	} else {
1219234b63a0SChris Mason 		btrfs_block_release(root, t);
1220be0e5c09SChris Mason 		path->slots[0] -= push_items;
1221be0e5c09SChris Mason 	}
1222eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
1223aa5d6bedSChris Mason 	return ret;
1224be0e5c09SChris Mason }
1225be0e5c09SChris Mason 
122674123bd7SChris Mason /*
122774123bd7SChris Mason  * split the path's leaf in two, making sure there is at least data_size
122874123bd7SChris Mason  * available for the resulting leaf level of the path.
1229aa5d6bedSChris Mason  *
1230aa5d6bedSChris Mason  * returns 0 if all went well and < 0 on failure.
123174123bd7SChris Mason  */
1232e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1233d4dbff95SChris Mason 		      *root, struct btrfs_key *ins_key,
1234d4dbff95SChris Mason 		      struct btrfs_path *path, int data_size)
1235be0e5c09SChris Mason {
1236e20d96d6SChris Mason 	struct buffer_head *l_buf;
1237234b63a0SChris Mason 	struct btrfs_leaf *l;
12387518a238SChris Mason 	u32 nritems;
1239eb60ceacSChris Mason 	int mid;
1240eb60ceacSChris Mason 	int slot;
1241234b63a0SChris Mason 	struct btrfs_leaf *right;
1242e20d96d6SChris Mason 	struct buffer_head *right_buffer;
12430783fcfcSChris Mason 	int space_needed = data_size + sizeof(struct btrfs_item);
1244be0e5c09SChris Mason 	int data_copy_size;
1245be0e5c09SChris Mason 	int rt_data_off;
1246be0e5c09SChris Mason 	int i;
1247d4dbff95SChris Mason 	int ret = 0;
1248aa5d6bedSChris Mason 	int wret;
1249d4dbff95SChris Mason 	int double_split = 0;
1250d4dbff95SChris Mason 	struct btrfs_disk_key disk_key;
1251be0e5c09SChris Mason 
125240689478SChris Mason 	/* first try to make some room by pushing left and right */
1253e089f05cSChris Mason 	wret = push_leaf_left(trans, root, path, data_size);
1254eaee50e8SChris Mason 	if (wret < 0)
1255eaee50e8SChris Mason 		return wret;
1256eaee50e8SChris Mason 	if (wret) {
1257e089f05cSChris Mason 		wret = push_leaf_right(trans, root, path, data_size);
1258eaee50e8SChris Mason 		if (wret < 0)
1259eaee50e8SChris Mason 			return wret;
1260eaee50e8SChris Mason 	}
1261eb60ceacSChris Mason 	l_buf = path->nodes[0];
1262e20d96d6SChris Mason 	l = btrfs_buffer_leaf(l_buf);
1263aa5d6bedSChris Mason 
1264aa5d6bedSChris Mason 	/* did the pushes work? */
1265123abc88SChris Mason 	if (btrfs_leaf_free_space(root, l) >=
1266123abc88SChris Mason 	    sizeof(struct btrfs_item) + data_size)
1267be0e5c09SChris Mason 		return 0;
1268aa5d6bedSChris Mason 
12695c680ed6SChris Mason 	if (!path->nodes[1]) {
1270e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, 1);
12715c680ed6SChris Mason 		if (ret)
12725c680ed6SChris Mason 			return ret;
12735c680ed6SChris Mason 	}
1274eb60ceacSChris Mason 	slot = path->slots[0];
12757518a238SChris Mason 	nritems = btrfs_header_nritems(&l->header);
1276eb60ceacSChris Mason 	mid = (nritems + 1)/ 2;
1277e089f05cSChris Mason 	right_buffer = btrfs_alloc_free_block(trans, root);
1278eb60ceacSChris Mason 	BUG_ON(!right_buffer);
1279e20d96d6SChris Mason 	right = btrfs_buffer_leaf(right_buffer);
1280123abc88SChris Mason 	memset(&right->header, 0, sizeof(right->header));
12817eccb903SChris Mason 	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
12827f5c1516SChris Mason 	btrfs_set_header_generation(&right->header, trans->transid);
12837518a238SChris Mason 	btrfs_set_header_level(&right->header, 0);
12843eb0314dSChris Mason 	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
12853eb0314dSChris Mason 	       sizeof(right->header.fsid));
1286d4dbff95SChris Mason 	if (mid <= slot) {
1287d4dbff95SChris Mason 		if (nritems == 1 ||
1288d4dbff95SChris Mason 		    leaf_space_used(l, mid, nritems - mid) + space_needed >
1289d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
1290d4dbff95SChris Mason 			if (slot >= nritems) {
1291d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
1292d4dbff95SChris Mason 				btrfs_set_header_nritems(&right->header, 0);
1293d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
1294d4dbff95SChris Mason 						  &disk_key,
12957eccb903SChris Mason 						  bh_blocknr(right_buffer),
1296d4dbff95SChris Mason 						  path->slots[1] + 1, 1);
1297d4dbff95SChris Mason 				if (wret)
1298d4dbff95SChris Mason 					ret = wret;
1299d4dbff95SChris Mason 				btrfs_block_release(root, path->nodes[0]);
1300d4dbff95SChris Mason 				path->nodes[0] = right_buffer;
1301d4dbff95SChris Mason 				path->slots[0] = 0;
1302d4dbff95SChris Mason 				path->slots[1] += 1;
1303d4dbff95SChris Mason 				return ret;
1304d4dbff95SChris Mason 			}
1305d4dbff95SChris Mason 			mid = slot;
1306d4dbff95SChris Mason 			double_split = 1;
1307d4dbff95SChris Mason 		}
1308d4dbff95SChris Mason 	} else {
1309d4dbff95SChris Mason 		if (leaf_space_used(l, 0, mid + 1) + space_needed >
1310d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
1311d4dbff95SChris Mason 			if (slot == 0) {
1312d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
1313d4dbff95SChris Mason 				btrfs_set_header_nritems(&right->header, 0);
1314d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
1315d4dbff95SChris Mason 						  &disk_key,
13167eccb903SChris Mason 						  bh_blocknr(right_buffer),
1317d4dbff95SChris Mason 						  path->slots[1] - 1, 1);
1318d4dbff95SChris Mason 				if (wret)
1319d4dbff95SChris Mason 					ret = wret;
1320d4dbff95SChris Mason 				btrfs_block_release(root, path->nodes[0]);
1321d4dbff95SChris Mason 				path->nodes[0] = right_buffer;
1322d4dbff95SChris Mason 				path->slots[0] = 0;
1323d4dbff95SChris Mason 				path->slots[1] -= 1;
1324a429e513SChris Mason 				if (path->slots[1] == 0) {
1325a429e513SChris Mason 					wret = fixup_low_keys(trans, root,
1326a429e513SChris Mason 					           path, &disk_key, 1);
1327a429e513SChris Mason 					if (wret)
1328a429e513SChris Mason 						ret = wret;
1329a429e513SChris Mason 				}
1330d4dbff95SChris Mason 				return ret;
1331d4dbff95SChris Mason 			}
1332d4dbff95SChris Mason 			mid = slot;
1333d4dbff95SChris Mason 			double_split = 1;
1334d4dbff95SChris Mason 		}
1335d4dbff95SChris Mason 	}
1336d4dbff95SChris Mason 	btrfs_set_header_nritems(&right->header, nritems - mid);
1337123abc88SChris Mason 	data_copy_size = btrfs_item_end(l->items + mid) -
1338123abc88SChris Mason 			 leaf_data_end(root, l);
1339d6025579SChris Mason 	btrfs_memcpy(root, right, right->items, l->items + mid,
13400783fcfcSChris Mason 		     (nritems - mid) * sizeof(struct btrfs_item));
1341d6025579SChris Mason 	btrfs_memcpy(root, right,
1342d6025579SChris Mason 		     btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
1343123abc88SChris Mason 		     data_copy_size, btrfs_leaf_data(l) +
1344123abc88SChris Mason 		     leaf_data_end(root, l), data_copy_size);
1345123abc88SChris Mason 	rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
1346123abc88SChris Mason 		      btrfs_item_end(l->items + mid);
134774123bd7SChris Mason 
13480783fcfcSChris Mason 	for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
1349123abc88SChris Mason 		u32 ioff = btrfs_item_offset(right->items + i);
13500783fcfcSChris Mason 		btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
13510783fcfcSChris Mason 	}
135274123bd7SChris Mason 
13537518a238SChris Mason 	btrfs_set_header_nritems(&l->header, mid);
1354aa5d6bedSChris Mason 	ret = 0;
1355e089f05cSChris Mason 	wret = insert_ptr(trans, root, path, &right->items[0].key,
13567eccb903SChris Mason 			  bh_blocknr(right_buffer), path->slots[1] + 1, 1);
1357aa5d6bedSChris Mason 	if (wret)
1358aa5d6bedSChris Mason 		ret = wret;
1359d6025579SChris Mason 	btrfs_mark_buffer_dirty(right_buffer);
1360d6025579SChris Mason 	btrfs_mark_buffer_dirty(l_buf);
1361eb60ceacSChris Mason 	BUG_ON(path->slots[0] != slot);
1362be0e5c09SChris Mason 	if (mid <= slot) {
1363234b63a0SChris Mason 		btrfs_block_release(root, path->nodes[0]);
1364eb60ceacSChris Mason 		path->nodes[0] = right_buffer;
1365be0e5c09SChris Mason 		path->slots[0] -= mid;
1366be0e5c09SChris Mason 		path->slots[1] += 1;
1367eb60ceacSChris Mason 	} else
1368234b63a0SChris Mason 		btrfs_block_release(root, right_buffer);
1369eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
1370d4dbff95SChris Mason 
1371d4dbff95SChris Mason 	if (!double_split)
1372d4dbff95SChris Mason 		return ret;
1373d4dbff95SChris Mason 	right_buffer = btrfs_alloc_free_block(trans, root);
1374d4dbff95SChris Mason 	BUG_ON(!right_buffer);
1375d4dbff95SChris Mason 	right = btrfs_buffer_leaf(right_buffer);
1376d4dbff95SChris Mason 	memset(&right->header, 0, sizeof(right->header));
13777eccb903SChris Mason 	btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
1378d4dbff95SChris Mason 	btrfs_set_header_generation(&right->header, trans->transid);
1379d4dbff95SChris Mason 	btrfs_set_header_level(&right->header, 0);
13803eb0314dSChris Mason 	memcpy(right->header.fsid, root->fs_info->disk_super->fsid,
13813eb0314dSChris Mason 	       sizeof(right->header.fsid));
1382d4dbff95SChris Mason 	btrfs_cpu_key_to_disk(&disk_key, ins_key);
1383d4dbff95SChris Mason 	btrfs_set_header_nritems(&right->header, 0);
1384d4dbff95SChris Mason 	wret = insert_ptr(trans, root, path,
1385d4dbff95SChris Mason 			  &disk_key,
13867eccb903SChris Mason 			  bh_blocknr(right_buffer),
1387d4dbff95SChris Mason 			  path->slots[1], 1);
1388d4dbff95SChris Mason 	if (wret)
1389d4dbff95SChris Mason 		ret = wret;
1390a429e513SChris Mason 	if (path->slots[1] == 0) {
1391a429e513SChris Mason 		wret = fixup_low_keys(trans, root, path, &disk_key, 1);
1392a429e513SChris Mason 		if (wret)
1393a429e513SChris Mason 			ret = wret;
1394a429e513SChris Mason 	}
1395d4dbff95SChris Mason 	btrfs_block_release(root, path->nodes[0]);
1396d4dbff95SChris Mason 	path->nodes[0] = right_buffer;
1397d4dbff95SChris Mason 	path->slots[0] = 0;
1398d4dbff95SChris Mason 	check_node(root, path, 1);
1399d4dbff95SChris Mason 	check_leaf(root, path, 0);
1400be0e5c09SChris Mason 	return ret;
1401be0e5c09SChris Mason }
1402be0e5c09SChris Mason 
1403b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans,
1404b18c6685SChris Mason 			struct btrfs_root *root,
1405b18c6685SChris Mason 			struct btrfs_path *path,
1406b18c6685SChris Mason 			u32 new_size)
1407b18c6685SChris Mason {
1408b18c6685SChris Mason 	int ret = 0;
1409b18c6685SChris Mason 	int slot;
1410b18c6685SChris Mason 	int slot_orig;
1411b18c6685SChris Mason 	struct btrfs_leaf *leaf;
1412b18c6685SChris Mason 	struct buffer_head *leaf_buf;
1413b18c6685SChris Mason 	u32 nritems;
1414b18c6685SChris Mason 	unsigned int data_end;
1415b18c6685SChris Mason 	unsigned int old_data_start;
1416b18c6685SChris Mason 	unsigned int old_size;
1417b18c6685SChris Mason 	unsigned int size_diff;
1418b18c6685SChris Mason 	int i;
1419b18c6685SChris Mason 
1420b18c6685SChris Mason 	slot_orig = path->slots[0];
1421b18c6685SChris Mason 	leaf_buf = path->nodes[0];
1422b18c6685SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
1423b18c6685SChris Mason 
1424b18c6685SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1425b18c6685SChris Mason 	data_end = leaf_data_end(root, leaf);
1426b18c6685SChris Mason 
1427b18c6685SChris Mason 	slot = path->slots[0];
1428b18c6685SChris Mason 	old_data_start = btrfs_item_offset(leaf->items + slot);
1429b18c6685SChris Mason 	old_size = btrfs_item_size(leaf->items + slot);
1430b18c6685SChris Mason 	BUG_ON(old_size <= new_size);
1431b18c6685SChris Mason 	size_diff = old_size - new_size;
1432b18c6685SChris Mason 
1433b18c6685SChris Mason 	BUG_ON(slot < 0);
1434b18c6685SChris Mason 	BUG_ON(slot >= nritems);
1435b18c6685SChris Mason 
1436b18c6685SChris Mason 	/*
1437b18c6685SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1438b18c6685SChris Mason 	 */
1439b18c6685SChris Mason 	/* first correct the data pointers */
1440b18c6685SChris Mason 	for (i = slot; i < nritems; i++) {
1441b18c6685SChris Mason 		u32 ioff = btrfs_item_offset(leaf->items + i);
1442b18c6685SChris Mason 		btrfs_set_item_offset(leaf->items + i,
1443b18c6685SChris Mason 				      ioff + size_diff);
1444b18c6685SChris Mason 	}
1445b18c6685SChris Mason 	/* shift the data */
1446b18c6685SChris Mason 	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1447b18c6685SChris Mason 		      data_end + size_diff, btrfs_leaf_data(leaf) +
1448b18c6685SChris Mason 		      data_end, old_data_start + new_size - data_end);
1449b18c6685SChris Mason 	btrfs_set_item_size(leaf->items + slot, new_size);
1450b18c6685SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
1451b18c6685SChris Mason 
1452b18c6685SChris Mason 	ret = 0;
1453b18c6685SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
1454b18c6685SChris Mason 		BUG();
1455b18c6685SChris Mason 	check_leaf(root, path, 0);
1456b18c6685SChris Mason 	return ret;
1457b18c6685SChris Mason }
1458b18c6685SChris Mason 
14596567e837SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root
14606567e837SChris Mason 		      *root, struct btrfs_path *path, u32 data_size)
14616567e837SChris Mason {
14626567e837SChris Mason 	int ret = 0;
14636567e837SChris Mason 	int slot;
14646567e837SChris Mason 	int slot_orig;
14656567e837SChris Mason 	struct btrfs_leaf *leaf;
14666567e837SChris Mason 	struct buffer_head *leaf_buf;
14676567e837SChris Mason 	u32 nritems;
14686567e837SChris Mason 	unsigned int data_end;
14696567e837SChris Mason 	unsigned int old_data;
14706567e837SChris Mason 	unsigned int old_size;
14716567e837SChris Mason 	int i;
14726567e837SChris Mason 
14736567e837SChris Mason 	slot_orig = path->slots[0];
14746567e837SChris Mason 	leaf_buf = path->nodes[0];
14756567e837SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
14766567e837SChris Mason 
14776567e837SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
14786567e837SChris Mason 	data_end = leaf_data_end(root, leaf);
14796567e837SChris Mason 
14806567e837SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < data_size)
14816567e837SChris Mason 		BUG();
14826567e837SChris Mason 	slot = path->slots[0];
14836567e837SChris Mason 	old_data = btrfs_item_end(leaf->items + slot);
14846567e837SChris Mason 
14856567e837SChris Mason 	BUG_ON(slot < 0);
14866567e837SChris Mason 	BUG_ON(slot >= nritems);
14876567e837SChris Mason 
14886567e837SChris Mason 	/*
14896567e837SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
14906567e837SChris Mason 	 */
14916567e837SChris Mason 	/* first correct the data pointers */
14926567e837SChris Mason 	for (i = slot; i < nritems; i++) {
14936567e837SChris Mason 		u32 ioff = btrfs_item_offset(leaf->items + i);
14946567e837SChris Mason 		btrfs_set_item_offset(leaf->items + i,
14956567e837SChris Mason 				      ioff - data_size);
14966567e837SChris Mason 	}
14976567e837SChris Mason 	/* shift the data */
14986567e837SChris Mason 	btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
14996567e837SChris Mason 		      data_end - data_size, btrfs_leaf_data(leaf) +
15006567e837SChris Mason 		      data_end, old_data - data_end);
15016567e837SChris Mason 	data_end = old_data;
15026567e837SChris Mason 	old_size = btrfs_item_size(leaf->items + slot);
15036567e837SChris Mason 	btrfs_set_item_size(leaf->items + slot, old_size + data_size);
15046567e837SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
15056567e837SChris Mason 
15066567e837SChris Mason 	ret = 0;
15076567e837SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
15086567e837SChris Mason 		BUG();
15096567e837SChris Mason 	check_leaf(root, path, 0);
15106567e837SChris Mason 	return ret;
15116567e837SChris Mason }
15126567e837SChris Mason 
151374123bd7SChris Mason /*
151474123bd7SChris Mason  * Given a key and some data, insert an item into the tree.
151574123bd7SChris Mason  * This does all the path init required, making room in the tree if needed.
151674123bd7SChris Mason  */
1517e089f05cSChris Mason int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
1518e089f05cSChris Mason 			    *root, struct btrfs_path *path, struct btrfs_key
1519e089f05cSChris Mason 			    *cpu_key, u32 data_size)
1520be0e5c09SChris Mason {
1521aa5d6bedSChris Mason 	int ret = 0;
1522be0e5c09SChris Mason 	int slot;
1523eb60ceacSChris Mason 	int slot_orig;
1524234b63a0SChris Mason 	struct btrfs_leaf *leaf;
1525e20d96d6SChris Mason 	struct buffer_head *leaf_buf;
15267518a238SChris Mason 	u32 nritems;
1527be0e5c09SChris Mason 	unsigned int data_end;
1528e2fa7227SChris Mason 	struct btrfs_disk_key disk_key;
1529e2fa7227SChris Mason 
1530e2fa7227SChris Mason 	btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1531be0e5c09SChris Mason 
153274123bd7SChris Mason 	/* create a root if there isn't one */
15335c680ed6SChris Mason 	if (!root->node)
1534cfaa7295SChris Mason 		BUG();
1535e089f05cSChris Mason 	ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1);
1536eb60ceacSChris Mason 	if (ret == 0) {
1537f0930a37SChris Mason 		return -EEXIST;
1538aa5d6bedSChris Mason 	}
1539ed2ff2cbSChris Mason 	if (ret < 0)
1540ed2ff2cbSChris Mason 		goto out;
1541be0e5c09SChris Mason 
154262e2749eSChris Mason 	slot_orig = path->slots[0];
154362e2749eSChris Mason 	leaf_buf = path->nodes[0];
1544e20d96d6SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
154574123bd7SChris Mason 
15467518a238SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1547123abc88SChris Mason 	data_end = leaf_data_end(root, leaf);
1548eb60ceacSChris Mason 
1549123abc88SChris Mason 	if (btrfs_leaf_free_space(root, leaf) <
1550d4dbff95SChris Mason 	    sizeof(struct btrfs_item) + data_size) {
1551be0e5c09SChris Mason 		BUG();
1552d4dbff95SChris Mason 	}
155362e2749eSChris Mason 	slot = path->slots[0];
1554eb60ceacSChris Mason 	BUG_ON(slot < 0);
1555be0e5c09SChris Mason 	if (slot != nritems) {
1556be0e5c09SChris Mason 		int i;
15570783fcfcSChris Mason 		unsigned int old_data = btrfs_item_end(leaf->items + slot);
1558be0e5c09SChris Mason 
1559be0e5c09SChris Mason 		/*
1560be0e5c09SChris Mason 		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1561be0e5c09SChris Mason 		 */
1562be0e5c09SChris Mason 		/* first correct the data pointers */
15630783fcfcSChris Mason 		for (i = slot; i < nritems; i++) {
1564123abc88SChris Mason 			u32 ioff = btrfs_item_offset(leaf->items + i);
15650783fcfcSChris Mason 			btrfs_set_item_offset(leaf->items + i,
15660783fcfcSChris Mason 					      ioff - data_size);
15670783fcfcSChris Mason 		}
1568be0e5c09SChris Mason 
1569be0e5c09SChris Mason 		/* shift the items */
1570d6025579SChris Mason 		btrfs_memmove(root, leaf, leaf->items + slot + 1,
1571d6025579SChris Mason 			      leaf->items + slot,
15720783fcfcSChris Mason 			      (nritems - slot) * sizeof(struct btrfs_item));
1573be0e5c09SChris Mason 
1574be0e5c09SChris Mason 		/* shift the data */
1575d6025579SChris Mason 		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1576d6025579SChris Mason 			      data_end - data_size, btrfs_leaf_data(leaf) +
1577be0e5c09SChris Mason 			      data_end, old_data - data_end);
1578be0e5c09SChris Mason 		data_end = old_data;
1579be0e5c09SChris Mason 	}
158062e2749eSChris Mason 	/* setup the item for the new data */
1581d6025579SChris Mason 	btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key,
1582e2fa7227SChris Mason 		     sizeof(struct btrfs_disk_key));
15830783fcfcSChris Mason 	btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
15840783fcfcSChris Mason 	btrfs_set_item_size(leaf->items + slot, data_size);
15857518a238SChris Mason 	btrfs_set_header_nritems(&leaf->header, nritems + 1);
1586d6025579SChris Mason 	btrfs_mark_buffer_dirty(leaf_buf);
1587aa5d6bedSChris Mason 
1588aa5d6bedSChris Mason 	ret = 0;
15898e19f2cdSChris Mason 	if (slot == 0)
1590e089f05cSChris Mason 		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
1591aa5d6bedSChris Mason 
1592123abc88SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0)
1593be0e5c09SChris Mason 		BUG();
159462e2749eSChris Mason 	check_leaf(root, path, 0);
1595ed2ff2cbSChris Mason out:
159662e2749eSChris Mason 	return ret;
159762e2749eSChris Mason }
159862e2749eSChris Mason 
159962e2749eSChris Mason /*
160062e2749eSChris Mason  * Given a key and some data, insert an item into the tree.
160162e2749eSChris Mason  * This does all the path init required, making room in the tree if needed.
160262e2749eSChris Mason  */
1603e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
1604e089f05cSChris Mason 		      *root, struct btrfs_key *cpu_key, void *data, u32
1605e089f05cSChris Mason 		      data_size)
160662e2749eSChris Mason {
160762e2749eSChris Mason 	int ret = 0;
16082c90e5d6SChris Mason 	struct btrfs_path *path;
160962e2749eSChris Mason 	u8 *ptr;
161062e2749eSChris Mason 
16112c90e5d6SChris Mason 	path = btrfs_alloc_path();
16122c90e5d6SChris Mason 	BUG_ON(!path);
16132c90e5d6SChris Mason 	btrfs_init_path(path);
16142c90e5d6SChris Mason 	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
161562e2749eSChris Mason 	if (!ret) {
16162c90e5d6SChris Mason 		ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
16172c90e5d6SChris Mason 				     path->slots[0], u8);
16182c90e5d6SChris Mason 		btrfs_memcpy(root, path->nodes[0]->b_data,
1619d6025579SChris Mason 			     ptr, data, data_size);
16202c90e5d6SChris Mason 		btrfs_mark_buffer_dirty(path->nodes[0]);
162162e2749eSChris Mason 	}
16222c90e5d6SChris Mason 	btrfs_release_path(root, path);
16232c90e5d6SChris Mason 	btrfs_free_path(path);
1624aa5d6bedSChris Mason 	return ret;
1625be0e5c09SChris Mason }
1626be0e5c09SChris Mason 
162774123bd7SChris Mason /*
16285de08d7dSChris Mason  * delete the pointer from a given node.
162974123bd7SChris Mason  *
163074123bd7SChris Mason  * If the delete empties a node, the node is removed from the tree,
163174123bd7SChris Mason  * continuing all the way the root if required.  The root is converted into
163274123bd7SChris Mason  * a leaf if all the nodes are emptied.
163374123bd7SChris Mason  */
1634e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1635e089f05cSChris Mason 		   struct btrfs_path *path, int level, int slot)
1636be0e5c09SChris Mason {
1637234b63a0SChris Mason 	struct btrfs_node *node;
1638e20d96d6SChris Mason 	struct buffer_head *parent = path->nodes[level];
16397518a238SChris Mason 	u32 nritems;
1640aa5d6bedSChris Mason 	int ret = 0;
1641bb803951SChris Mason 	int wret;
1642be0e5c09SChris Mason 
1643e20d96d6SChris Mason 	node = btrfs_buffer_node(parent);
16447518a238SChris Mason 	nritems = btrfs_header_nritems(&node->header);
1645be0e5c09SChris Mason 	if (slot != nritems -1) {
1646d6025579SChris Mason 		btrfs_memmove(root, node, node->ptrs + slot,
1647d6025579SChris Mason 			      node->ptrs + slot + 1,
1648d6025579SChris Mason 			      sizeof(struct btrfs_key_ptr) *
1649d6025579SChris Mason 			      (nritems - slot - 1));
1650be0e5c09SChris Mason 	}
16517518a238SChris Mason 	nritems--;
16527518a238SChris Mason 	btrfs_set_header_nritems(&node->header, nritems);
16537518a238SChris Mason 	if (nritems == 0 && parent == root->node) {
1654e20d96d6SChris Mason 		struct btrfs_header *header = btrfs_buffer_header(root->node);
1655e20d96d6SChris Mason 		BUG_ON(btrfs_header_level(header) != 1);
1656eb60ceacSChris Mason 		/* just turn the root into a leaf and break */
1657e20d96d6SChris Mason 		btrfs_set_header_level(header, 0);
1658bb803951SChris Mason 	} else if (slot == 0) {
1659e089f05cSChris Mason 		wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
1660123abc88SChris Mason 				      level + 1);
16610f70abe2SChris Mason 		if (wret)
16620f70abe2SChris Mason 			ret = wret;
1663be0e5c09SChris Mason 	}
1664d6025579SChris Mason 	btrfs_mark_buffer_dirty(parent);
1665aa5d6bedSChris Mason 	return ret;
1666be0e5c09SChris Mason }
1667be0e5c09SChris Mason 
166874123bd7SChris Mason /*
166974123bd7SChris Mason  * delete the item at the leaf level in path.  If that empties
167074123bd7SChris Mason  * the leaf, remove it from the tree
167174123bd7SChris Mason  */
1672e089f05cSChris Mason int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1673e089f05cSChris Mason 		   struct btrfs_path *path)
1674be0e5c09SChris Mason {
1675be0e5c09SChris Mason 	int slot;
1676234b63a0SChris Mason 	struct btrfs_leaf *leaf;
1677e20d96d6SChris Mason 	struct buffer_head *leaf_buf;
1678be0e5c09SChris Mason 	int doff;
1679be0e5c09SChris Mason 	int dsize;
1680aa5d6bedSChris Mason 	int ret = 0;
1681aa5d6bedSChris Mason 	int wret;
16827518a238SChris Mason 	u32 nritems;
1683be0e5c09SChris Mason 
1684eb60ceacSChris Mason 	leaf_buf = path->nodes[0];
1685e20d96d6SChris Mason 	leaf = btrfs_buffer_leaf(leaf_buf);
16864920c9acSChris Mason 	slot = path->slots[0];
16870783fcfcSChris Mason 	doff = btrfs_item_offset(leaf->items + slot);
16880783fcfcSChris Mason 	dsize = btrfs_item_size(leaf->items + slot);
16897518a238SChris Mason 	nritems = btrfs_header_nritems(&leaf->header);
1690be0e5c09SChris Mason 
16917518a238SChris Mason 	if (slot != nritems - 1) {
1692be0e5c09SChris Mason 		int i;
1693123abc88SChris Mason 		int data_end = leaf_data_end(root, leaf);
1694d6025579SChris Mason 		btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1695d6025579SChris Mason 			      data_end + dsize,
1696123abc88SChris Mason 			      btrfs_leaf_data(leaf) + data_end,
1697be0e5c09SChris Mason 			      doff - data_end);
16980783fcfcSChris Mason 		for (i = slot + 1; i < nritems; i++) {
1699123abc88SChris Mason 			u32 ioff = btrfs_item_offset(leaf->items + i);
17000783fcfcSChris Mason 			btrfs_set_item_offset(leaf->items + i, ioff + dsize);
17010783fcfcSChris Mason 		}
1702d6025579SChris Mason 		btrfs_memmove(root, leaf, leaf->items + slot,
1703d6025579SChris Mason 			      leaf->items + slot + 1,
17040783fcfcSChris Mason 			      sizeof(struct btrfs_item) *
17057518a238SChris Mason 			      (nritems - slot - 1));
1706be0e5c09SChris Mason 	}
17077518a238SChris Mason 	btrfs_set_header_nritems(&leaf->header, nritems - 1);
17087518a238SChris Mason 	nritems--;
170974123bd7SChris Mason 	/* delete the leaf if we've emptied it */
17107518a238SChris Mason 	if (nritems == 0) {
1711eb60ceacSChris Mason 		if (leaf_buf == root->node) {
17127518a238SChris Mason 			btrfs_set_header_level(&leaf->header, 0);
17139a8dd150SChris Mason 		} else {
1714e089f05cSChris Mason 			clean_tree_block(trans, root, leaf_buf);
1715d6025579SChris Mason 			wait_on_buffer(leaf_buf);
1716e089f05cSChris Mason 			wret = del_ptr(trans, root, path, 1, path->slots[1]);
1717aa5d6bedSChris Mason 			if (wret)
1718aa5d6bedSChris Mason 				ret = wret;
1719e089f05cSChris Mason 			wret = btrfs_free_extent(trans, root,
17207eccb903SChris Mason 						 bh_blocknr(leaf_buf), 1, 1);
17210f70abe2SChris Mason 			if (wret)
17220f70abe2SChris Mason 				ret = wret;
17239a8dd150SChris Mason 		}
1724be0e5c09SChris Mason 	} else {
17257518a238SChris Mason 		int used = leaf_space_used(leaf, 0, nritems);
1726aa5d6bedSChris Mason 		if (slot == 0) {
1727e089f05cSChris Mason 			wret = fixup_low_keys(trans, root, path,
1728aa5d6bedSChris Mason 					      &leaf->items[0].key, 1);
1729aa5d6bedSChris Mason 			if (wret)
1730aa5d6bedSChris Mason 				ret = wret;
1731aa5d6bedSChris Mason 		}
1732aa5d6bedSChris Mason 
173374123bd7SChris Mason 		/* delete the leaf if it is mostly empty */
1734123abc88SChris Mason 		if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
1735be0e5c09SChris Mason 			/* push_leaf_left fixes the path.
1736be0e5c09SChris Mason 			 * make sure the path still points to our leaf
1737be0e5c09SChris Mason 			 * for possible call to del_ptr below
1738be0e5c09SChris Mason 			 */
17394920c9acSChris Mason 			slot = path->slots[1];
1740e20d96d6SChris Mason 			get_bh(leaf_buf);
1741e089f05cSChris Mason 			wret = push_leaf_left(trans, root, path, 1);
1742aa5d6bedSChris Mason 			if (wret < 0)
1743aa5d6bedSChris Mason 				ret = wret;
1744f0930a37SChris Mason 			if (path->nodes[0] == leaf_buf &&
17457518a238SChris Mason 			    btrfs_header_nritems(&leaf->header)) {
1746e089f05cSChris Mason 				wret = push_leaf_right(trans, root, path, 1);
1747aa5d6bedSChris Mason 				if (wret < 0)
1748aa5d6bedSChris Mason 					ret = wret;
1749aa5d6bedSChris Mason 			}
17507518a238SChris Mason 			if (btrfs_header_nritems(&leaf->header) == 0) {
17517eccb903SChris Mason 				u64 blocknr = bh_blocknr(leaf_buf);
1752e089f05cSChris Mason 				clean_tree_block(trans, root, leaf_buf);
1753d6025579SChris Mason 				wait_on_buffer(leaf_buf);
1754e089f05cSChris Mason 				wret = del_ptr(trans, root, path, 1, slot);
1755aa5d6bedSChris Mason 				if (wret)
1756aa5d6bedSChris Mason 					ret = wret;
1757234b63a0SChris Mason 				btrfs_block_release(root, leaf_buf);
1758e089f05cSChris Mason 				wret = btrfs_free_extent(trans, root, blocknr,
1759e089f05cSChris Mason 							 1, 1);
17600f70abe2SChris Mason 				if (wret)
17610f70abe2SChris Mason 					ret = wret;
17625de08d7dSChris Mason 			} else {
1763d6025579SChris Mason 				btrfs_mark_buffer_dirty(leaf_buf);
1764234b63a0SChris Mason 				btrfs_block_release(root, leaf_buf);
1765be0e5c09SChris Mason 			}
1766d5719762SChris Mason 		} else {
1767d6025579SChris Mason 			btrfs_mark_buffer_dirty(leaf_buf);
1768be0e5c09SChris Mason 		}
17699a8dd150SChris Mason 	}
1770aa5d6bedSChris Mason 	return ret;
17719a8dd150SChris Mason }
17729a8dd150SChris Mason 
177397571fd0SChris Mason /*
177497571fd0SChris Mason  * walk up the tree as far as required to find the next leaf.
17750f70abe2SChris Mason  * returns 0 if it found something or 1 if there are no greater leaves.
17760f70abe2SChris Mason  * returns < 0 on io errors.
177797571fd0SChris Mason  */
1778234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
1779d97e63b6SChris Mason {
1780d97e63b6SChris Mason 	int slot;
1781d97e63b6SChris Mason 	int level = 1;
1782d97e63b6SChris Mason 	u64 blocknr;
1783e20d96d6SChris Mason 	struct buffer_head *c;
1784e20d96d6SChris Mason 	struct btrfs_node *c_node;
1785e20d96d6SChris Mason 	struct buffer_head *next = NULL;
1786d97e63b6SChris Mason 
1787234b63a0SChris Mason 	while(level < BTRFS_MAX_LEVEL) {
1788d97e63b6SChris Mason 		if (!path->nodes[level])
17890f70abe2SChris Mason 			return 1;
1790d97e63b6SChris Mason 		slot = path->slots[level] + 1;
1791d97e63b6SChris Mason 		c = path->nodes[level];
1792e20d96d6SChris Mason 		c_node = btrfs_buffer_node(c);
1793e20d96d6SChris Mason 		if (slot >= btrfs_header_nritems(&c_node->header)) {
1794d97e63b6SChris Mason 			level++;
1795d97e63b6SChris Mason 			continue;
1796d97e63b6SChris Mason 		}
1797e20d96d6SChris Mason 		blocknr = btrfs_node_blockptr(c_node, slot);
1798cfaa7295SChris Mason 		if (next)
1799234b63a0SChris Mason 			btrfs_block_release(root, next);
1800d97e63b6SChris Mason 		next = read_tree_block(root, blocknr);
1801d97e63b6SChris Mason 		break;
1802d97e63b6SChris Mason 	}
1803d97e63b6SChris Mason 	path->slots[level] = slot;
1804d97e63b6SChris Mason 	while(1) {
1805d97e63b6SChris Mason 		level--;
1806d97e63b6SChris Mason 		c = path->nodes[level];
1807234b63a0SChris Mason 		btrfs_block_release(root, c);
1808d97e63b6SChris Mason 		path->nodes[level] = next;
1809d97e63b6SChris Mason 		path->slots[level] = 0;
1810d97e63b6SChris Mason 		if (!level)
1811d97e63b6SChris Mason 			break;
18121d4f8a0cSChris Mason 		next = read_tree_block(root,
1813e20d96d6SChris Mason 		       btrfs_node_blockptr(btrfs_buffer_node(next), 0));
1814d97e63b6SChris Mason 	}
1815d97e63b6SChris Mason 	return 0;
1816d97e63b6SChris Mason }
1817