xref: /openbmc/linux/fs/btrfs/ctree.c (revision 0b86a832a1f38abec695864ec2eaedc9d2383f1b)
16cbd5570SChris Mason /*
26cbd5570SChris Mason  * Copyright (C) 2007 Oracle.  All rights reserved.
36cbd5570SChris Mason  *
46cbd5570SChris Mason  * This program is free software; you can redistribute it and/or
56cbd5570SChris Mason  * modify it under the terms of the GNU General Public
66cbd5570SChris Mason  * License v2 as published by the Free Software Foundation.
76cbd5570SChris Mason  *
86cbd5570SChris Mason  * This program is distributed in the hope that it will be useful,
96cbd5570SChris Mason  * but WITHOUT ANY WARRANTY; without even the implied warranty of
106cbd5570SChris Mason  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
116cbd5570SChris Mason  * General Public License for more details.
126cbd5570SChris Mason  *
136cbd5570SChris Mason  * You should have received a copy of the GNU General Public
146cbd5570SChris Mason  * License along with this program; if not, write to the
156cbd5570SChris Mason  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
166cbd5570SChris Mason  * Boston, MA 021110-1307, USA.
176cbd5570SChris Mason  */
186cbd5570SChris Mason 
19a6b6e75eSChris Mason #include <linux/sched.h>
20eb60ceacSChris Mason #include "ctree.h"
21eb60ceacSChris Mason #include "disk-io.h"
227f5c1516SChris Mason #include "transaction.h"
235f39d397SChris Mason #include "print-tree.h"
249a8dd150SChris Mason 
25e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
26e089f05cSChris Mason 		      *root, struct btrfs_path *path, int level);
27e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
28d4dbff95SChris Mason 		      *root, struct btrfs_key *ins_key,
29cc0c5538SChris Mason 		      struct btrfs_path *path, int data_size, int extend);
305f39d397SChris Mason static int push_node_left(struct btrfs_trans_handle *trans,
315f39d397SChris Mason 			  struct btrfs_root *root, struct extent_buffer *dst,
325f39d397SChris Mason 			  struct extent_buffer *src);
335f39d397SChris Mason static int balance_node_right(struct btrfs_trans_handle *trans,
345f39d397SChris Mason 			      struct btrfs_root *root,
355f39d397SChris Mason 			      struct extent_buffer *dst_buf,
365f39d397SChris Mason 			      struct extent_buffer *src_buf);
37e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
38e089f05cSChris Mason 		   struct btrfs_path *path, int level, int slot);
39d97e63b6SChris Mason 
40df24a2b9SChris Mason inline void btrfs_init_path(struct btrfs_path *p)
41df24a2b9SChris Mason {
42df24a2b9SChris Mason 	memset(p, 0, sizeof(*p));
43df24a2b9SChris Mason }
44df24a2b9SChris Mason 
452c90e5d6SChris Mason struct btrfs_path *btrfs_alloc_path(void)
462c90e5d6SChris Mason {
47df24a2b9SChris Mason 	struct btrfs_path *path;
48df24a2b9SChris Mason 	path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
492cc58cf2SChris Mason 	if (path) {
50df24a2b9SChris Mason 		btrfs_init_path(path);
512cc58cf2SChris Mason 		path->reada = 1;
522cc58cf2SChris Mason 	}
53df24a2b9SChris Mason 	return path;
542c90e5d6SChris Mason }
552c90e5d6SChris Mason 
562c90e5d6SChris Mason void btrfs_free_path(struct btrfs_path *p)
572c90e5d6SChris Mason {
58df24a2b9SChris Mason 	btrfs_release_path(NULL, p);
592c90e5d6SChris Mason 	kmem_cache_free(btrfs_path_cachep, p);
602c90e5d6SChris Mason }
612c90e5d6SChris Mason 
62234b63a0SChris Mason void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
63eb60ceacSChris Mason {
64eb60ceacSChris Mason 	int i;
65234b63a0SChris Mason 	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
66eb60ceacSChris Mason 		if (!p->nodes[i])
67eb60ceacSChris Mason 			break;
685f39d397SChris Mason 		free_extent_buffer(p->nodes[i]);
69eb60ceacSChris Mason 	}
70aa5d6bedSChris Mason 	memset(p, 0, sizeof(*p));
71eb60ceacSChris Mason }
72eb60ceacSChris Mason 
73*0b86a832SChris Mason static void add_root_to_dirty_list(struct btrfs_root *root)
74*0b86a832SChris Mason {
75*0b86a832SChris Mason 	if (root->track_dirty && list_empty(&root->dirty_list)) {
76*0b86a832SChris Mason 		list_add(&root->dirty_list,
77*0b86a832SChris Mason 			 &root->fs_info->dirty_cowonly_roots);
78*0b86a832SChris Mason 	}
79*0b86a832SChris Mason }
80*0b86a832SChris Mason 
81be20aa9dSChris Mason int btrfs_copy_root(struct btrfs_trans_handle *trans,
82be20aa9dSChris Mason 		      struct btrfs_root *root,
83be20aa9dSChris Mason 		      struct extent_buffer *buf,
84be20aa9dSChris Mason 		      struct extent_buffer **cow_ret, u64 new_root_objectid)
85be20aa9dSChris Mason {
86be20aa9dSChris Mason 	struct extent_buffer *cow;
87be20aa9dSChris Mason 	u32 nritems;
88be20aa9dSChris Mason 	int ret = 0;
89be20aa9dSChris Mason 	int level;
90be20aa9dSChris Mason 	struct btrfs_key first_key;
914aec2b52SChris Mason 	struct btrfs_root *new_root;
92be20aa9dSChris Mason 
934aec2b52SChris Mason 	new_root = kmalloc(sizeof(*new_root), GFP_NOFS);
944aec2b52SChris Mason 	if (!new_root)
954aec2b52SChris Mason 		return -ENOMEM;
964aec2b52SChris Mason 
974aec2b52SChris Mason 	memcpy(new_root, root, sizeof(*new_root));
984aec2b52SChris Mason 	new_root->root_key.objectid = new_root_objectid;
99be20aa9dSChris Mason 
100be20aa9dSChris Mason 	WARN_ON(root->ref_cows && trans->transid !=
101be20aa9dSChris Mason 		root->fs_info->running_transaction->transid);
102be20aa9dSChris Mason 	WARN_ON(root->ref_cows && trans->transid != root->last_trans);
103be20aa9dSChris Mason 
104be20aa9dSChris Mason 	level = btrfs_header_level(buf);
105be20aa9dSChris Mason 	nritems = btrfs_header_nritems(buf);
106be20aa9dSChris Mason 	if (nritems) {
107be20aa9dSChris Mason 		if (level == 0)
108be20aa9dSChris Mason 			btrfs_item_key_to_cpu(buf, &first_key, 0);
109be20aa9dSChris Mason 		else
110be20aa9dSChris Mason 			btrfs_node_key_to_cpu(buf, &first_key, 0);
111be20aa9dSChris Mason 	} else {
112be20aa9dSChris Mason 		first_key.objectid = 0;
113be20aa9dSChris Mason 	}
1144aec2b52SChris Mason 	cow = __btrfs_alloc_free_block(trans, new_root, buf->len,
115be20aa9dSChris Mason 				       new_root_objectid,
116be20aa9dSChris Mason 				       trans->transid, first_key.objectid,
117be20aa9dSChris Mason 				       level, buf->start, 0);
1184aec2b52SChris Mason 	if (IS_ERR(cow)) {
1194aec2b52SChris Mason 		kfree(new_root);
120be20aa9dSChris Mason 		return PTR_ERR(cow);
1214aec2b52SChris Mason 	}
122be20aa9dSChris Mason 
123be20aa9dSChris Mason 	copy_extent_buffer(cow, buf, 0, 0, cow->len);
124be20aa9dSChris Mason 	btrfs_set_header_bytenr(cow, cow->start);
125be20aa9dSChris Mason 	btrfs_set_header_generation(cow, trans->transid);
126be20aa9dSChris Mason 	btrfs_set_header_owner(cow, new_root_objectid);
127be20aa9dSChris Mason 
128be20aa9dSChris Mason 	WARN_ON(btrfs_header_generation(buf) > trans->transid);
1294aec2b52SChris Mason 	ret = btrfs_inc_ref(trans, new_root, buf);
1304aec2b52SChris Mason 	kfree(new_root);
1314aec2b52SChris Mason 
132be20aa9dSChris Mason 	if (ret)
133be20aa9dSChris Mason 		return ret;
134be20aa9dSChris Mason 
135be20aa9dSChris Mason 	btrfs_mark_buffer_dirty(cow);
136be20aa9dSChris Mason 	*cow_ret = cow;
137be20aa9dSChris Mason 	return 0;
138be20aa9dSChris Mason }
139be20aa9dSChris Mason 
140be20aa9dSChris Mason int __btrfs_cow_block(struct btrfs_trans_handle *trans,
1415f39d397SChris Mason 			     struct btrfs_root *root,
1425f39d397SChris Mason 			     struct extent_buffer *buf,
1435f39d397SChris Mason 			     struct extent_buffer *parent, int parent_slot,
1445f39d397SChris Mason 			     struct extent_buffer **cow_ret,
1455f39d397SChris Mason 			     u64 search_start, u64 empty_size)
1466702ed49SChris Mason {
1477bb86316SChris Mason 	u64 root_gen;
1485f39d397SChris Mason 	struct extent_buffer *cow;
1497bb86316SChris Mason 	u32 nritems;
1506702ed49SChris Mason 	int ret = 0;
1516702ed49SChris Mason 	int different_trans = 0;
1527bb86316SChris Mason 	int level;
1537bb86316SChris Mason 	struct btrfs_key first_key;
1546702ed49SChris Mason 
1557bb86316SChris Mason 	if (root->ref_cows) {
1567bb86316SChris Mason 		root_gen = trans->transid;
1577bb86316SChris Mason 	} else {
1587bb86316SChris Mason 		root_gen = 0;
1597bb86316SChris Mason 	}
1607bb86316SChris Mason 
1617bb86316SChris Mason 	WARN_ON(root->ref_cows && trans->transid !=
1627bb86316SChris Mason 		root->fs_info->running_transaction->transid);
1636702ed49SChris Mason 	WARN_ON(root->ref_cows && trans->transid != root->last_trans);
1645f39d397SChris Mason 
1657bb86316SChris Mason 	level = btrfs_header_level(buf);
1667bb86316SChris Mason 	nritems = btrfs_header_nritems(buf);
1677bb86316SChris Mason 	if (nritems) {
1687bb86316SChris Mason 		if (level == 0)
1697bb86316SChris Mason 			btrfs_item_key_to_cpu(buf, &first_key, 0);
1707bb86316SChris Mason 		else
1717bb86316SChris Mason 			btrfs_node_key_to_cpu(buf, &first_key, 0);
1727bb86316SChris Mason 	} else {
1737bb86316SChris Mason 		first_key.objectid = 0;
1747bb86316SChris Mason 	}
1757bb86316SChris Mason 	cow = __btrfs_alloc_free_block(trans, root, buf->len,
1767bb86316SChris Mason 				     root->root_key.objectid,
1777bb86316SChris Mason 				     root_gen, first_key.objectid, level,
178db94535dSChris Mason 				     search_start, empty_size);
1796702ed49SChris Mason 	if (IS_ERR(cow))
1806702ed49SChris Mason 		return PTR_ERR(cow);
1816702ed49SChris Mason 
1825f39d397SChris Mason 	copy_extent_buffer(cow, buf, 0, 0, cow->len);
183db94535dSChris Mason 	btrfs_set_header_bytenr(cow, cow->start);
1845f39d397SChris Mason 	btrfs_set_header_generation(cow, trans->transid);
1855f39d397SChris Mason 	btrfs_set_header_owner(cow, root->root_key.objectid);
1866702ed49SChris Mason 
1875f39d397SChris Mason 	WARN_ON(btrfs_header_generation(buf) > trans->transid);
1885f39d397SChris Mason 	if (btrfs_header_generation(buf) != trans->transid) {
1896702ed49SChris Mason 		different_trans = 1;
1906702ed49SChris Mason 		ret = btrfs_inc_ref(trans, root, buf);
1916702ed49SChris Mason 		if (ret)
1926702ed49SChris Mason 			return ret;
1936702ed49SChris Mason 	} else {
1946702ed49SChris Mason 		clean_tree_block(trans, root, buf);
1956702ed49SChris Mason 	}
1966702ed49SChris Mason 
1976702ed49SChris Mason 	if (buf == root->node) {
1987bb86316SChris Mason 		root_gen = btrfs_header_generation(buf);
1996702ed49SChris Mason 		root->node = cow;
2005f39d397SChris Mason 		extent_buffer_get(cow);
2016702ed49SChris Mason 		if (buf != root->commit_root) {
202db94535dSChris Mason 			btrfs_free_extent(trans, root, buf->start,
2037bb86316SChris Mason 					  buf->len, root->root_key.objectid,
2047bb86316SChris Mason 					  root_gen, 0, 0, 1);
2056702ed49SChris Mason 		}
2065f39d397SChris Mason 		free_extent_buffer(buf);
207*0b86a832SChris Mason 		add_root_to_dirty_list(root);
2086702ed49SChris Mason 	} else {
2097bb86316SChris Mason 		root_gen = btrfs_header_generation(parent);
2105f39d397SChris Mason 		btrfs_set_node_blockptr(parent, parent_slot,
211db94535dSChris Mason 					cow->start);
21274493f7aSChris Mason 		WARN_ON(trans->transid == 0);
21374493f7aSChris Mason 		btrfs_set_node_ptr_generation(parent, parent_slot,
21474493f7aSChris Mason 					      trans->transid);
2156702ed49SChris Mason 		btrfs_mark_buffer_dirty(parent);
2165f39d397SChris Mason 		WARN_ON(btrfs_header_generation(parent) != trans->transid);
2177bb86316SChris Mason 		btrfs_free_extent(trans, root, buf->start, buf->len,
2187bb86316SChris Mason 				  btrfs_header_owner(parent), root_gen,
2197bb86316SChris Mason 				  0, 0, 1);
2206702ed49SChris Mason 	}
2215f39d397SChris Mason 	free_extent_buffer(buf);
2226702ed49SChris Mason 	btrfs_mark_buffer_dirty(cow);
2236702ed49SChris Mason 	*cow_ret = cow;
2246702ed49SChris Mason 	return 0;
2256702ed49SChris Mason }
2266702ed49SChris Mason 
2275f39d397SChris Mason int btrfs_cow_block(struct btrfs_trans_handle *trans,
2285f39d397SChris Mason 		    struct btrfs_root *root, struct extent_buffer *buf,
2295f39d397SChris Mason 		    struct extent_buffer *parent, int parent_slot,
2305f39d397SChris Mason 		    struct extent_buffer **cow_ret)
23102217ed2SChris Mason {
2326702ed49SChris Mason 	u64 search_start;
233dc17ff8fSChris Mason 	u64 header_trans;
234f510cfecSChris Mason 	int ret;
235dc17ff8fSChris Mason 
236ccd467d6SChris Mason 	if (trans->transaction != root->fs_info->running_transaction) {
237ccd467d6SChris Mason 		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
238ccd467d6SChris Mason 		       root->fs_info->running_transaction->transid);
239ccd467d6SChris Mason 		WARN_ON(1);
240ccd467d6SChris Mason 	}
241ccd467d6SChris Mason 	if (trans->transid != root->fs_info->generation) {
242ccd467d6SChris Mason 		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
243ccd467d6SChris Mason 		       root->fs_info->generation);
244ccd467d6SChris Mason 		WARN_ON(1);
245ccd467d6SChris Mason 	}
246dc17ff8fSChris Mason 
247dc17ff8fSChris Mason 	header_trans = btrfs_header_generation(buf);
248dc17ff8fSChris Mason 	if (header_trans == trans->transid) {
24902217ed2SChris Mason 		*cow_ret = buf;
25002217ed2SChris Mason 		return 0;
25102217ed2SChris Mason 	}
2526702ed49SChris Mason 
253*0b86a832SChris Mason 	search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1);
254f510cfecSChris Mason 	ret = __btrfs_cow_block(trans, root, buf, parent,
2556702ed49SChris Mason 				 parent_slot, cow_ret, search_start, 0);
256f510cfecSChris Mason 	return ret;
2572c90e5d6SChris Mason }
2586702ed49SChris Mason 
2596b80053dSChris Mason static int close_blocks(u64 blocknr, u64 other, u32 blocksize)
2606702ed49SChris Mason {
2616b80053dSChris Mason 	if (blocknr < other && other - (blocknr + blocksize) < 32768)
2626702ed49SChris Mason 		return 1;
2636b80053dSChris Mason 	if (blocknr > other && blocknr - (other + blocksize) < 32768)
2646702ed49SChris Mason 		return 1;
26502217ed2SChris Mason 	return 0;
26602217ed2SChris Mason }
26702217ed2SChris Mason 
268081e9573SChris Mason /*
269081e9573SChris Mason  * compare two keys in a memcmp fashion
270081e9573SChris Mason  */
271081e9573SChris Mason static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
272081e9573SChris Mason {
273081e9573SChris Mason 	struct btrfs_key k1;
274081e9573SChris Mason 
275081e9573SChris Mason 	btrfs_disk_key_to_cpu(&k1, disk);
276081e9573SChris Mason 
277081e9573SChris Mason 	if (k1.objectid > k2->objectid)
278081e9573SChris Mason 		return 1;
279081e9573SChris Mason 	if (k1.objectid < k2->objectid)
280081e9573SChris Mason 		return -1;
281081e9573SChris Mason 	if (k1.type > k2->type)
282081e9573SChris Mason 		return 1;
283081e9573SChris Mason 	if (k1.type < k2->type)
284081e9573SChris Mason 		return -1;
285081e9573SChris Mason 	if (k1.offset > k2->offset)
286081e9573SChris Mason 		return 1;
287081e9573SChris Mason 	if (k1.offset < k2->offset)
288081e9573SChris Mason 		return -1;
289081e9573SChris Mason 	return 0;
290081e9573SChris Mason }
291081e9573SChris Mason 
292081e9573SChris Mason 
2936702ed49SChris Mason int btrfs_realloc_node(struct btrfs_trans_handle *trans,
2945f39d397SChris Mason 		       struct btrfs_root *root, struct extent_buffer *parent,
295a6b6e75eSChris Mason 		       int start_slot, int cache_only, u64 *last_ret,
296a6b6e75eSChris Mason 		       struct btrfs_key *progress)
2976702ed49SChris Mason {
2986b80053dSChris Mason 	struct extent_buffer *cur;
2996b80053dSChris Mason 	struct extent_buffer *tmp;
3006702ed49SChris Mason 	u64 blocknr;
301e9d0b13bSChris Mason 	u64 search_start = *last_ret;
302e9d0b13bSChris Mason 	u64 last_block = 0;
3036702ed49SChris Mason 	u64 other;
3046702ed49SChris Mason 	u32 parent_nritems;
3056702ed49SChris Mason 	int end_slot;
3066702ed49SChris Mason 	int i;
3076702ed49SChris Mason 	int err = 0;
308f2183bdeSChris Mason 	int parent_level;
3096b80053dSChris Mason 	int uptodate;
3106b80053dSChris Mason 	u32 blocksize;
311081e9573SChris Mason 	int progress_passed = 0;
312081e9573SChris Mason 	struct btrfs_disk_key disk_key;
3136702ed49SChris Mason 
3145708b959SChris Mason 	parent_level = btrfs_header_level(parent);
3155708b959SChris Mason 	if (cache_only && parent_level != 1)
3165708b959SChris Mason 		return 0;
3175708b959SChris Mason 
3186702ed49SChris Mason 	if (trans->transaction != root->fs_info->running_transaction) {
3196702ed49SChris Mason 		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
3206702ed49SChris Mason 		       root->fs_info->running_transaction->transid);
3216702ed49SChris Mason 		WARN_ON(1);
3226702ed49SChris Mason 	}
3236702ed49SChris Mason 	if (trans->transid != root->fs_info->generation) {
3246702ed49SChris Mason 		printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
3256702ed49SChris Mason 		       root->fs_info->generation);
3266702ed49SChris Mason 		WARN_ON(1);
3276702ed49SChris Mason 	}
32886479a04SChris Mason 
3296b80053dSChris Mason 	parent_nritems = btrfs_header_nritems(parent);
3306b80053dSChris Mason 	blocksize = btrfs_level_size(root, parent_level - 1);
3316702ed49SChris Mason 	end_slot = parent_nritems;
3326702ed49SChris Mason 
3336702ed49SChris Mason 	if (parent_nritems == 1)
3346702ed49SChris Mason 		return 0;
3356702ed49SChris Mason 
3366702ed49SChris Mason 	for (i = start_slot; i < end_slot; i++) {
3376702ed49SChris Mason 		int close = 1;
338a6b6e75eSChris Mason 
3395708b959SChris Mason 		if (!parent->map_token) {
3405708b959SChris Mason 			map_extent_buffer(parent,
3415708b959SChris Mason 					btrfs_node_key_ptr_offset(i),
3425708b959SChris Mason 					sizeof(struct btrfs_key_ptr),
3435708b959SChris Mason 					&parent->map_token, &parent->kaddr,
3445708b959SChris Mason 					&parent->map_start, &parent->map_len,
3455708b959SChris Mason 					KM_USER1);
3465708b959SChris Mason 		}
347081e9573SChris Mason 		btrfs_node_key(parent, &disk_key, i);
348081e9573SChris Mason 		if (!progress_passed && comp_keys(&disk_key, progress) < 0)
349081e9573SChris Mason 			continue;
350081e9573SChris Mason 
351081e9573SChris Mason 		progress_passed = 1;
3526b80053dSChris Mason 		blocknr = btrfs_node_blockptr(parent, i);
353e9d0b13bSChris Mason 		if (last_block == 0)
354e9d0b13bSChris Mason 			last_block = blocknr;
3555708b959SChris Mason 
3566702ed49SChris Mason 		if (i > 0) {
3576b80053dSChris Mason 			other = btrfs_node_blockptr(parent, i - 1);
3586b80053dSChris Mason 			close = close_blocks(blocknr, other, blocksize);
3596702ed49SChris Mason 		}
3605708b959SChris Mason 		if (close && i < end_slot - 2) {
3616b80053dSChris Mason 			other = btrfs_node_blockptr(parent, i + 1);
3626b80053dSChris Mason 			close = close_blocks(blocknr, other, blocksize);
3636702ed49SChris Mason 		}
364e9d0b13bSChris Mason 		if (close) {
365e9d0b13bSChris Mason 			last_block = blocknr;
3666702ed49SChris Mason 			continue;
367e9d0b13bSChris Mason 		}
3685708b959SChris Mason 		if (parent->map_token) {
3695708b959SChris Mason 			unmap_extent_buffer(parent, parent->map_token,
3705708b959SChris Mason 					    KM_USER1);
3715708b959SChris Mason 			parent->map_token = NULL;
3725708b959SChris Mason 		}
3736702ed49SChris Mason 
3746b80053dSChris Mason 		cur = btrfs_find_tree_block(root, blocknr, blocksize);
3756b80053dSChris Mason 		if (cur)
3766b80053dSChris Mason 			uptodate = btrfs_buffer_uptodate(cur);
3776b80053dSChris Mason 		else
3786b80053dSChris Mason 			uptodate = 0;
3795708b959SChris Mason 		if (!cur || !uptodate) {
3806702ed49SChris Mason 			if (cache_only) {
3816b80053dSChris Mason 				free_extent_buffer(cur);
3826702ed49SChris Mason 				continue;
3836702ed49SChris Mason 			}
3846b80053dSChris Mason 			if (!cur) {
3856b80053dSChris Mason 				cur = read_tree_block(root, blocknr,
3866b80053dSChris Mason 							 blocksize);
3876b80053dSChris Mason 			} else if (!uptodate) {
3886b80053dSChris Mason 				btrfs_read_buffer(cur);
3896702ed49SChris Mason 			}
390f2183bdeSChris Mason 		}
391e9d0b13bSChris Mason 		if (search_start == 0)
3926b80053dSChris Mason 			search_start = last_block;
393e9d0b13bSChris Mason 
3946b80053dSChris Mason 		err = __btrfs_cow_block(trans, root, cur, parent, i,
3956b80053dSChris Mason 					&tmp, search_start,
3966b80053dSChris Mason 					min(16 * blocksize,
3976b80053dSChris Mason 					    (end_slot - i) * blocksize));
398252c38f0SYan 		if (err) {
3996b80053dSChris Mason 			free_extent_buffer(cur);
4006702ed49SChris Mason 			break;
401252c38f0SYan 		}
4026b80053dSChris Mason 		search_start = tmp->start;
4035708b959SChris Mason 		last_block = tmp->start;
404f2183bdeSChris Mason 		*last_ret = search_start;
405f2183bdeSChris Mason 		if (parent_level == 1)
4066b80053dSChris Mason 			btrfs_clear_buffer_defrag(tmp);
4076b80053dSChris Mason 		free_extent_buffer(tmp);
4086702ed49SChris Mason 	}
4095708b959SChris Mason 	if (parent->map_token) {
4105708b959SChris Mason 		unmap_extent_buffer(parent, parent->map_token,
4115708b959SChris Mason 				    KM_USER1);
4125708b959SChris Mason 		parent->map_token = NULL;
4135708b959SChris Mason 	}
4146702ed49SChris Mason 	return err;
4156702ed49SChris Mason }
4166702ed49SChris Mason 
41774123bd7SChris Mason /*
41874123bd7SChris Mason  * The leaf data grows from end-to-front in the node.
41974123bd7SChris Mason  * this returns the address of the start of the last item,
42074123bd7SChris Mason  * which is the stop of the leaf data stack
42174123bd7SChris Mason  */
422123abc88SChris Mason static inline unsigned int leaf_data_end(struct btrfs_root *root,
4235f39d397SChris Mason 					 struct extent_buffer *leaf)
424be0e5c09SChris Mason {
4255f39d397SChris Mason 	u32 nr = btrfs_header_nritems(leaf);
426be0e5c09SChris Mason 	if (nr == 0)
427123abc88SChris Mason 		return BTRFS_LEAF_DATA_SIZE(root);
4285f39d397SChris Mason 	return btrfs_item_offset_nr(leaf, nr - 1);
429be0e5c09SChris Mason }
430be0e5c09SChris Mason 
431123abc88SChris Mason static int check_node(struct btrfs_root *root, struct btrfs_path *path,
432123abc88SChris Mason 		      int level)
433aa5d6bedSChris Mason {
4345f39d397SChris Mason 	struct extent_buffer *parent = NULL;
4355f39d397SChris Mason 	struct extent_buffer *node = path->nodes[level];
4365f39d397SChris Mason 	struct btrfs_disk_key parent_key;
4375f39d397SChris Mason 	struct btrfs_disk_key node_key;
438aa5d6bedSChris Mason 	int parent_slot;
4398d7be552SChris Mason 	int slot;
4408d7be552SChris Mason 	struct btrfs_key cpukey;
4415f39d397SChris Mason 	u32 nritems = btrfs_header_nritems(node);
442aa5d6bedSChris Mason 
443aa5d6bedSChris Mason 	if (path->nodes[level + 1])
4445f39d397SChris Mason 		parent = path->nodes[level + 1];
445a1f39630SAneesh 
4468d7be552SChris Mason 	slot = path->slots[level];
4477518a238SChris Mason 	BUG_ON(nritems == 0);
4487518a238SChris Mason 	if (parent) {
449a1f39630SAneesh 		parent_slot = path->slots[level + 1];
4505f39d397SChris Mason 		btrfs_node_key(parent, &parent_key, parent_slot);
4515f39d397SChris Mason 		btrfs_node_key(node, &node_key, 0);
4525f39d397SChris Mason 		BUG_ON(memcmp(&parent_key, &node_key,
453e2fa7227SChris Mason 			      sizeof(struct btrfs_disk_key)));
4541d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
455db94535dSChris Mason 		       btrfs_header_bytenr(node));
456aa5d6bedSChris Mason 	}
457123abc88SChris Mason 	BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
4588d7be552SChris Mason 	if (slot != 0) {
4595f39d397SChris Mason 		btrfs_node_key_to_cpu(node, &cpukey, slot - 1);
4605f39d397SChris Mason 		btrfs_node_key(node, &node_key, slot);
4615f39d397SChris Mason 		BUG_ON(comp_keys(&node_key, &cpukey) <= 0);
4628d7be552SChris Mason 	}
4638d7be552SChris Mason 	if (slot < nritems - 1) {
4645f39d397SChris Mason 		btrfs_node_key_to_cpu(node, &cpukey, slot + 1);
4655f39d397SChris Mason 		btrfs_node_key(node, &node_key, slot);
4665f39d397SChris Mason 		BUG_ON(comp_keys(&node_key, &cpukey) >= 0);
467aa5d6bedSChris Mason 	}
468aa5d6bedSChris Mason 	return 0;
469aa5d6bedSChris Mason }
470aa5d6bedSChris Mason 
471123abc88SChris Mason static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
472123abc88SChris Mason 		      int level)
473aa5d6bedSChris Mason {
4745f39d397SChris Mason 	struct extent_buffer *leaf = path->nodes[level];
4755f39d397SChris Mason 	struct extent_buffer *parent = NULL;
476aa5d6bedSChris Mason 	int parent_slot;
4778d7be552SChris Mason 	struct btrfs_key cpukey;
4785f39d397SChris Mason 	struct btrfs_disk_key parent_key;
4795f39d397SChris Mason 	struct btrfs_disk_key leaf_key;
4805f39d397SChris Mason 	int slot = path->slots[0];
4818d7be552SChris Mason 
4825f39d397SChris Mason 	u32 nritems = btrfs_header_nritems(leaf);
483aa5d6bedSChris Mason 
484aa5d6bedSChris Mason 	if (path->nodes[level + 1])
4855f39d397SChris Mason 		parent = path->nodes[level + 1];
4867518a238SChris Mason 
4877518a238SChris Mason 	if (nritems == 0)
4887518a238SChris Mason 		return 0;
4897518a238SChris Mason 
4907518a238SChris Mason 	if (parent) {
491a1f39630SAneesh 		parent_slot = path->slots[level + 1];
4925f39d397SChris Mason 		btrfs_node_key(parent, &parent_key, parent_slot);
4935f39d397SChris Mason 		btrfs_item_key(leaf, &leaf_key, 0);
4946702ed49SChris Mason 
4955f39d397SChris Mason 		BUG_ON(memcmp(&parent_key, &leaf_key,
496e2fa7227SChris Mason 		       sizeof(struct btrfs_disk_key)));
4971d4f8a0cSChris Mason 		BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
498db94535dSChris Mason 		       btrfs_header_bytenr(leaf));
499aa5d6bedSChris Mason 	}
5005f39d397SChris Mason #if 0
5015f39d397SChris Mason 	for (i = 0; nritems > 1 && i < nritems - 2; i++) {
5025f39d397SChris Mason 		btrfs_item_key_to_cpu(leaf, &cpukey, i + 1);
5035f39d397SChris Mason 		btrfs_item_key(leaf, &leaf_key, i);
5045f39d397SChris Mason 		if (comp_keys(&leaf_key, &cpukey) >= 0) {
5055f39d397SChris Mason 			btrfs_print_leaf(root, leaf);
5065f39d397SChris Mason 			printk("slot %d offset bad key\n", i);
5075f39d397SChris Mason 			BUG_ON(1);
5085f39d397SChris Mason 		}
5095f39d397SChris Mason 		if (btrfs_item_offset_nr(leaf, i) !=
5105f39d397SChris Mason 			btrfs_item_end_nr(leaf, i + 1)) {
5115f39d397SChris Mason 			btrfs_print_leaf(root, leaf);
5125f39d397SChris Mason 			printk("slot %d offset bad\n", i);
5135f39d397SChris Mason 			BUG_ON(1);
5145f39d397SChris Mason 		}
5155f39d397SChris Mason 		if (i == 0) {
5165f39d397SChris Mason 			if (btrfs_item_offset_nr(leaf, i) +
5175f39d397SChris Mason 			       btrfs_item_size_nr(leaf, i) !=
5185f39d397SChris Mason 			       BTRFS_LEAF_DATA_SIZE(root)) {
5195f39d397SChris Mason 				btrfs_print_leaf(root, leaf);
5205f39d397SChris Mason 				printk("slot %d first offset bad\n", i);
5215f39d397SChris Mason 				BUG_ON(1);
5225f39d397SChris Mason 			}
5235f39d397SChris Mason 		}
5245f39d397SChris Mason 	}
5255f39d397SChris Mason 	if (nritems > 0) {
5265f39d397SChris Mason 		if (btrfs_item_size_nr(leaf, nritems - 1) > 4096) {
5275f39d397SChris Mason 				btrfs_print_leaf(root, leaf);
5285f39d397SChris Mason 				printk("slot %d bad size \n", nritems - 1);
5295f39d397SChris Mason 				BUG_ON(1);
5305f39d397SChris Mason 		}
5315f39d397SChris Mason 	}
5325f39d397SChris Mason #endif
5335f39d397SChris Mason 	if (slot != 0 && slot < nritems - 1) {
5345f39d397SChris Mason 		btrfs_item_key(leaf, &leaf_key, slot);
5355f39d397SChris Mason 		btrfs_item_key_to_cpu(leaf, &cpukey, slot - 1);
5365f39d397SChris Mason 		if (comp_keys(&leaf_key, &cpukey) <= 0) {
5375f39d397SChris Mason 			btrfs_print_leaf(root, leaf);
5385f39d397SChris Mason 			printk("slot %d offset bad key\n", slot);
5395f39d397SChris Mason 			BUG_ON(1);
5405f39d397SChris Mason 		}
5415f39d397SChris Mason 		if (btrfs_item_offset_nr(leaf, slot - 1) !=
5425f39d397SChris Mason 		       btrfs_item_end_nr(leaf, slot)) {
5435f39d397SChris Mason 			btrfs_print_leaf(root, leaf);
5445f39d397SChris Mason 			printk("slot %d offset bad\n", slot);
5455f39d397SChris Mason 			BUG_ON(1);
5465f39d397SChris Mason 		}
547aa5d6bedSChris Mason 	}
5488d7be552SChris Mason 	if (slot < nritems - 1) {
5495f39d397SChris Mason 		btrfs_item_key(leaf, &leaf_key, slot);
5505f39d397SChris Mason 		btrfs_item_key_to_cpu(leaf, &cpukey, slot + 1);
5515f39d397SChris Mason 		BUG_ON(comp_keys(&leaf_key, &cpukey) >= 0);
5525f39d397SChris Mason 		if (btrfs_item_offset_nr(leaf, slot) !=
5535f39d397SChris Mason 			btrfs_item_end_nr(leaf, slot + 1)) {
5545f39d397SChris Mason 			btrfs_print_leaf(root, leaf);
5555f39d397SChris Mason 			printk("slot %d offset bad\n", slot);
5565f39d397SChris Mason 			BUG_ON(1);
557aa5d6bedSChris Mason 		}
5585f39d397SChris Mason 	}
5595f39d397SChris Mason 	BUG_ON(btrfs_item_offset_nr(leaf, 0) +
5605f39d397SChris Mason 	       btrfs_item_size_nr(leaf, 0) != BTRFS_LEAF_DATA_SIZE(root));
561aa5d6bedSChris Mason 	return 0;
562aa5d6bedSChris Mason }
563aa5d6bedSChris Mason 
56498ed5174SChris Mason static int noinline check_block(struct btrfs_root *root,
56598ed5174SChris Mason 				struct btrfs_path *path, int level)
566aa5d6bedSChris Mason {
567810191ffSChris Mason 	return 0;
568db94535dSChris Mason #if 0
5695f39d397SChris Mason 	struct extent_buffer *buf = path->nodes[level];
5705f39d397SChris Mason 
571479965d6SChris Mason 	if (memcmp_extent_buffer(buf, root->fs_info->fsid,
572479965d6SChris Mason 				 (unsigned long)btrfs_header_fsid(buf),
573479965d6SChris Mason 				 BTRFS_FSID_SIZE)) {
5745f39d397SChris Mason 		printk("warning bad block %Lu\n", buf->start);
575db94535dSChris Mason 		return 1;
5765f39d397SChris Mason 	}
577db94535dSChris Mason #endif
578aa5d6bedSChris Mason 	if (level == 0)
579123abc88SChris Mason 		return check_leaf(root, path, level);
580123abc88SChris Mason 	return check_node(root, path, level);
581aa5d6bedSChris Mason }
582aa5d6bedSChris Mason 
58374123bd7SChris Mason /*
5845f39d397SChris Mason  * search for key in the extent_buffer.  The items start at offset p,
5855f39d397SChris Mason  * and they are item_size apart.  There are 'max' items in p.
5865f39d397SChris Mason  *
58774123bd7SChris Mason  * the slot in the array is returned via slot, and it points to
58874123bd7SChris Mason  * the place where you would insert key if it is not found in
58974123bd7SChris Mason  * the array.
59074123bd7SChris Mason  *
59174123bd7SChris Mason  * slot may point to max if the key is bigger than all of the keys
59274123bd7SChris Mason  */
5935f39d397SChris Mason static int generic_bin_search(struct extent_buffer *eb, unsigned long p,
5945f39d397SChris Mason 			      int item_size, struct btrfs_key *key,
595be0e5c09SChris Mason 			      int max, int *slot)
596be0e5c09SChris Mason {
597be0e5c09SChris Mason 	int low = 0;
598be0e5c09SChris Mason 	int high = max;
599be0e5c09SChris Mason 	int mid;
600be0e5c09SChris Mason 	int ret;
601479965d6SChris Mason 	struct btrfs_disk_key *tmp = NULL;
6025f39d397SChris Mason 	struct btrfs_disk_key unaligned;
6035f39d397SChris Mason 	unsigned long offset;
6045f39d397SChris Mason 	char *map_token = NULL;
6055f39d397SChris Mason 	char *kaddr = NULL;
6065f39d397SChris Mason 	unsigned long map_start = 0;
6075f39d397SChris Mason 	unsigned long map_len = 0;
608479965d6SChris Mason 	int err;
609be0e5c09SChris Mason 
610be0e5c09SChris Mason 	while(low < high) {
611be0e5c09SChris Mason 		mid = (low + high) / 2;
6125f39d397SChris Mason 		offset = p + mid * item_size;
6135f39d397SChris Mason 
6145f39d397SChris Mason 		if (!map_token || offset < map_start ||
6155f39d397SChris Mason 		    (offset + sizeof(struct btrfs_disk_key)) >
6165f39d397SChris Mason 		    map_start + map_len) {
617479965d6SChris Mason 			if (map_token) {
6185f39d397SChris Mason 				unmap_extent_buffer(eb, map_token, KM_USER0);
619479965d6SChris Mason 				map_token = NULL;
620479965d6SChris Mason 			}
621479965d6SChris Mason 			err = map_extent_buffer(eb, offset,
622479965d6SChris Mason 						sizeof(struct btrfs_disk_key),
623479965d6SChris Mason 						&map_token, &kaddr,
6245f39d397SChris Mason 						&map_start, &map_len, KM_USER0);
6255f39d397SChris Mason 
626479965d6SChris Mason 			if (!err) {
627479965d6SChris Mason 				tmp = (struct btrfs_disk_key *)(kaddr + offset -
628479965d6SChris Mason 							map_start);
629479965d6SChris Mason 			} else {
6305f39d397SChris Mason 				read_extent_buffer(eb, &unaligned,
6315f39d397SChris Mason 						   offset, sizeof(unaligned));
6325f39d397SChris Mason 				tmp = &unaligned;
633479965d6SChris Mason 			}
634479965d6SChris Mason 
6355f39d397SChris Mason 		} else {
6365f39d397SChris Mason 			tmp = (struct btrfs_disk_key *)(kaddr + offset -
6375f39d397SChris Mason 							map_start);
6385f39d397SChris Mason 		}
639be0e5c09SChris Mason 		ret = comp_keys(tmp, key);
640be0e5c09SChris Mason 
641be0e5c09SChris Mason 		if (ret < 0)
642be0e5c09SChris Mason 			low = mid + 1;
643be0e5c09SChris Mason 		else if (ret > 0)
644be0e5c09SChris Mason 			high = mid;
645be0e5c09SChris Mason 		else {
646be0e5c09SChris Mason 			*slot = mid;
647479965d6SChris Mason 			if (map_token)
6485f39d397SChris Mason 				unmap_extent_buffer(eb, map_token, KM_USER0);
649be0e5c09SChris Mason 			return 0;
650be0e5c09SChris Mason 		}
651be0e5c09SChris Mason 	}
652be0e5c09SChris Mason 	*slot = low;
6535f39d397SChris Mason 	if (map_token)
6545f39d397SChris Mason 		unmap_extent_buffer(eb, map_token, KM_USER0);
655be0e5c09SChris Mason 	return 1;
656be0e5c09SChris Mason }
657be0e5c09SChris Mason 
65897571fd0SChris Mason /*
65997571fd0SChris Mason  * simple bin_search frontend that does the right thing for
66097571fd0SChris Mason  * leaves vs nodes
66197571fd0SChris Mason  */
6625f39d397SChris Mason static int bin_search(struct extent_buffer *eb, struct btrfs_key *key,
6635f39d397SChris Mason 		      int level, int *slot)
664be0e5c09SChris Mason {
6655f39d397SChris Mason 	if (level == 0) {
6665f39d397SChris Mason 		return generic_bin_search(eb,
6675f39d397SChris Mason 					  offsetof(struct btrfs_leaf, items),
6680783fcfcSChris Mason 					  sizeof(struct btrfs_item),
6695f39d397SChris Mason 					  key, btrfs_header_nritems(eb),
6707518a238SChris Mason 					  slot);
671be0e5c09SChris Mason 	} else {
6725f39d397SChris Mason 		return generic_bin_search(eb,
6735f39d397SChris Mason 					  offsetof(struct btrfs_node, ptrs),
674123abc88SChris Mason 					  sizeof(struct btrfs_key_ptr),
6755f39d397SChris Mason 					  key, btrfs_header_nritems(eb),
6767518a238SChris Mason 					  slot);
677be0e5c09SChris Mason 	}
678be0e5c09SChris Mason 	return -1;
679be0e5c09SChris Mason }
680be0e5c09SChris Mason 
6815f39d397SChris Mason static struct extent_buffer *read_node_slot(struct btrfs_root *root,
6825f39d397SChris Mason 				   struct extent_buffer *parent, int slot)
683bb803951SChris Mason {
684bb803951SChris Mason 	if (slot < 0)
685bb803951SChris Mason 		return NULL;
6865f39d397SChris Mason 	if (slot >= btrfs_header_nritems(parent))
687bb803951SChris Mason 		return NULL;
688db94535dSChris Mason 	return read_tree_block(root, btrfs_node_blockptr(parent, slot),
689db94535dSChris Mason 		       btrfs_level_size(root, btrfs_header_level(parent) - 1));
690bb803951SChris Mason }
691bb803951SChris Mason 
69298ed5174SChris Mason static int balance_level(struct btrfs_trans_handle *trans,
69398ed5174SChris Mason 			 struct btrfs_root *root,
69498ed5174SChris Mason 			 struct btrfs_path *path, int level)
695bb803951SChris Mason {
6965f39d397SChris Mason 	struct extent_buffer *right = NULL;
6975f39d397SChris Mason 	struct extent_buffer *mid;
6985f39d397SChris Mason 	struct extent_buffer *left = NULL;
6995f39d397SChris Mason 	struct extent_buffer *parent = NULL;
700bb803951SChris Mason 	int ret = 0;
701bb803951SChris Mason 	int wret;
702bb803951SChris Mason 	int pslot;
703bb803951SChris Mason 	int orig_slot = path->slots[level];
70454aa1f4dSChris Mason 	int err_on_enospc = 0;
70579f95c82SChris Mason 	u64 orig_ptr;
706bb803951SChris Mason 
707bb803951SChris Mason 	if (level == 0)
708bb803951SChris Mason 		return 0;
709bb803951SChris Mason 
7105f39d397SChris Mason 	mid = path->nodes[level];
7117bb86316SChris Mason 	WARN_ON(btrfs_header_generation(mid) != trans->transid);
7127bb86316SChris Mason 
7131d4f8a0cSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
71479f95c82SChris Mason 
715234b63a0SChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
7165f39d397SChris Mason 		parent = path->nodes[level + 1];
717bb803951SChris Mason 	pslot = path->slots[level + 1];
718bb803951SChris Mason 
71940689478SChris Mason 	/*
72040689478SChris Mason 	 * deal with the case where there is only one pointer in the root
72140689478SChris Mason 	 * by promoting the node below to a root
72240689478SChris Mason 	 */
7235f39d397SChris Mason 	if (!parent) {
7245f39d397SChris Mason 		struct extent_buffer *child;
725bb803951SChris Mason 
7265f39d397SChris Mason 		if (btrfs_header_nritems(mid) != 1)
727bb803951SChris Mason 			return 0;
728bb803951SChris Mason 
729bb803951SChris Mason 		/* promote the child to a root */
7305f39d397SChris Mason 		child = read_node_slot(root, mid, 0);
731bb803951SChris Mason 		BUG_ON(!child);
7322f375ab9SYan 		ret = btrfs_cow_block(trans, root, child, mid, 0, &child);
7332f375ab9SYan 		BUG_ON(ret);
7342f375ab9SYan 
735bb803951SChris Mason 		root->node = child;
736*0b86a832SChris Mason 		add_root_to_dirty_list(root);
737bb803951SChris Mason 		path->nodes[level] = NULL;
7385f39d397SChris Mason 		clean_tree_block(trans, root, mid);
7395f39d397SChris Mason 		wait_on_tree_block_writeback(root, mid);
740bb803951SChris Mason 		/* once for the path */
7415f39d397SChris Mason 		free_extent_buffer(mid);
7427bb86316SChris Mason 		ret = btrfs_free_extent(trans, root, mid->start, mid->len,
7437bb86316SChris Mason 					root->root_key.objectid,
7447bb86316SChris Mason 					btrfs_header_generation(mid), 0, 0, 1);
745bb803951SChris Mason 		/* once for the root ptr */
7465f39d397SChris Mason 		free_extent_buffer(mid);
747db94535dSChris Mason 		return ret;
748bb803951SChris Mason 	}
7495f39d397SChris Mason 	if (btrfs_header_nritems(mid) >
750123abc88SChris Mason 	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
751bb803951SChris Mason 		return 0;
752bb803951SChris Mason 
7535f39d397SChris Mason 	if (btrfs_header_nritems(mid) < 2)
75454aa1f4dSChris Mason 		err_on_enospc = 1;
75554aa1f4dSChris Mason 
7565f39d397SChris Mason 	left = read_node_slot(root, parent, pslot - 1);
7575f39d397SChris Mason 	if (left) {
7585f39d397SChris Mason 		wret = btrfs_cow_block(trans, root, left,
7595f39d397SChris Mason 				       parent, pslot - 1, &left);
76054aa1f4dSChris Mason 		if (wret) {
76154aa1f4dSChris Mason 			ret = wret;
76254aa1f4dSChris Mason 			goto enospc;
76354aa1f4dSChris Mason 		}
7642cc58cf2SChris Mason 	}
7655f39d397SChris Mason 	right = read_node_slot(root, parent, pslot + 1);
7665f39d397SChris Mason 	if (right) {
7675f39d397SChris Mason 		wret = btrfs_cow_block(trans, root, right,
7685f39d397SChris Mason 				       parent, pslot + 1, &right);
7692cc58cf2SChris Mason 		if (wret) {
7702cc58cf2SChris Mason 			ret = wret;
7712cc58cf2SChris Mason 			goto enospc;
7722cc58cf2SChris Mason 		}
7732cc58cf2SChris Mason 	}
7742cc58cf2SChris Mason 
7752cc58cf2SChris Mason 	/* first, try to make some room in the middle buffer */
7765f39d397SChris Mason 	if (left) {
7775f39d397SChris Mason 		orig_slot += btrfs_header_nritems(left);
7785f39d397SChris Mason 		wret = push_node_left(trans, root, left, mid);
77979f95c82SChris Mason 		if (wret < 0)
78079f95c82SChris Mason 			ret = wret;
7815f39d397SChris Mason 		if (btrfs_header_nritems(mid) < 2)
78254aa1f4dSChris Mason 			err_on_enospc = 1;
783bb803951SChris Mason 	}
78479f95c82SChris Mason 
78579f95c82SChris Mason 	/*
78679f95c82SChris Mason 	 * then try to empty the right most buffer into the middle
78779f95c82SChris Mason 	 */
7885f39d397SChris Mason 	if (right) {
7895f39d397SChris Mason 		wret = push_node_left(trans, root, mid, right);
79054aa1f4dSChris Mason 		if (wret < 0 && wret != -ENOSPC)
79179f95c82SChris Mason 			ret = wret;
7925f39d397SChris Mason 		if (btrfs_header_nritems(right) == 0) {
793db94535dSChris Mason 			u64 bytenr = right->start;
7947bb86316SChris Mason 			u64 generation = btrfs_header_generation(parent);
795db94535dSChris Mason 			u32 blocksize = right->len;
796db94535dSChris Mason 
7975f39d397SChris Mason 			clean_tree_block(trans, root, right);
7985f39d397SChris Mason 			wait_on_tree_block_writeback(root, right);
7995f39d397SChris Mason 			free_extent_buffer(right);
800bb803951SChris Mason 			right = NULL;
801e089f05cSChris Mason 			wret = del_ptr(trans, root, path, level + 1, pslot +
802e089f05cSChris Mason 				       1);
803bb803951SChris Mason 			if (wret)
804bb803951SChris Mason 				ret = wret;
805db94535dSChris Mason 			wret = btrfs_free_extent(trans, root, bytenr,
8067bb86316SChris Mason 						 blocksize,
8077bb86316SChris Mason 						 btrfs_header_owner(parent),
8087bb86316SChris Mason 						 generation, 0, 0, 1);
809bb803951SChris Mason 			if (wret)
810bb803951SChris Mason 				ret = wret;
811bb803951SChris Mason 		} else {
8125f39d397SChris Mason 			struct btrfs_disk_key right_key;
8135f39d397SChris Mason 			btrfs_node_key(right, &right_key, 0);
8145f39d397SChris Mason 			btrfs_set_node_key(parent, &right_key, pslot + 1);
8155f39d397SChris Mason 			btrfs_mark_buffer_dirty(parent);
816bb803951SChris Mason 		}
817bb803951SChris Mason 	}
8185f39d397SChris Mason 	if (btrfs_header_nritems(mid) == 1) {
81979f95c82SChris Mason 		/*
82079f95c82SChris Mason 		 * we're not allowed to leave a node with one item in the
82179f95c82SChris Mason 		 * tree during a delete.  A deletion from lower in the tree
82279f95c82SChris Mason 		 * could try to delete the only pointer in this node.
82379f95c82SChris Mason 		 * So, pull some keys from the left.
82479f95c82SChris Mason 		 * There has to be a left pointer at this point because
82579f95c82SChris Mason 		 * otherwise we would have pulled some pointers from the
82679f95c82SChris Mason 		 * right
82779f95c82SChris Mason 		 */
8285f39d397SChris Mason 		BUG_ON(!left);
8295f39d397SChris Mason 		wret = balance_node_right(trans, root, mid, left);
83054aa1f4dSChris Mason 		if (wret < 0) {
83179f95c82SChris Mason 			ret = wret;
83254aa1f4dSChris Mason 			goto enospc;
83354aa1f4dSChris Mason 		}
83479f95c82SChris Mason 		BUG_ON(wret == 1);
83579f95c82SChris Mason 	}
8365f39d397SChris Mason 	if (btrfs_header_nritems(mid) == 0) {
83779f95c82SChris Mason 		/* we've managed to empty the middle node, drop it */
8387bb86316SChris Mason 		u64 root_gen = btrfs_header_generation(parent);
839db94535dSChris Mason 		u64 bytenr = mid->start;
840db94535dSChris Mason 		u32 blocksize = mid->len;
8415f39d397SChris Mason 		clean_tree_block(trans, root, mid);
8425f39d397SChris Mason 		wait_on_tree_block_writeback(root, mid);
8435f39d397SChris Mason 		free_extent_buffer(mid);
844bb803951SChris Mason 		mid = NULL;
845e089f05cSChris Mason 		wret = del_ptr(trans, root, path, level + 1, pslot);
846bb803951SChris Mason 		if (wret)
847bb803951SChris Mason 			ret = wret;
8487bb86316SChris Mason 		wret = btrfs_free_extent(trans, root, bytenr, blocksize,
8497bb86316SChris Mason 					 btrfs_header_owner(parent),
8507bb86316SChris Mason 					 root_gen, 0, 0, 1);
851bb803951SChris Mason 		if (wret)
852bb803951SChris Mason 			ret = wret;
85379f95c82SChris Mason 	} else {
85479f95c82SChris Mason 		/* update the parent key to reflect our changes */
8555f39d397SChris Mason 		struct btrfs_disk_key mid_key;
8565f39d397SChris Mason 		btrfs_node_key(mid, &mid_key, 0);
8575f39d397SChris Mason 		btrfs_set_node_key(parent, &mid_key, pslot);
8585f39d397SChris Mason 		btrfs_mark_buffer_dirty(parent);
85979f95c82SChris Mason 	}
860bb803951SChris Mason 
86179f95c82SChris Mason 	/* update the path */
8625f39d397SChris Mason 	if (left) {
8635f39d397SChris Mason 		if (btrfs_header_nritems(left) > orig_slot) {
8645f39d397SChris Mason 			extent_buffer_get(left);
8655f39d397SChris Mason 			path->nodes[level] = left;
866bb803951SChris Mason 			path->slots[level + 1] -= 1;
867bb803951SChris Mason 			path->slots[level] = orig_slot;
8685f39d397SChris Mason 			if (mid)
8695f39d397SChris Mason 				free_extent_buffer(mid);
870bb803951SChris Mason 		} else {
8715f39d397SChris Mason 			orig_slot -= btrfs_header_nritems(left);
872bb803951SChris Mason 			path->slots[level] = orig_slot;
873bb803951SChris Mason 		}
874bb803951SChris Mason 	}
87579f95c82SChris Mason 	/* double check we haven't messed things up */
876123abc88SChris Mason 	check_block(root, path, level);
877e20d96d6SChris Mason 	if (orig_ptr !=
8785f39d397SChris Mason 	    btrfs_node_blockptr(path->nodes[level], path->slots[level]))
87979f95c82SChris Mason 		BUG();
88054aa1f4dSChris Mason enospc:
8815f39d397SChris Mason 	if (right)
8825f39d397SChris Mason 		free_extent_buffer(right);
8835f39d397SChris Mason 	if (left)
8845f39d397SChris Mason 		free_extent_buffer(left);
885bb803951SChris Mason 	return ret;
886bb803951SChris Mason }
887bb803951SChris Mason 
888e66f709bSChris Mason /* returns zero if the push worked, non-zero otherwise */
88998ed5174SChris Mason static int noinline push_nodes_for_insert(struct btrfs_trans_handle *trans,
890e66f709bSChris Mason 					  struct btrfs_root *root,
891e66f709bSChris Mason 					  struct btrfs_path *path, int level)
892e66f709bSChris Mason {
8935f39d397SChris Mason 	struct extent_buffer *right = NULL;
8945f39d397SChris Mason 	struct extent_buffer *mid;
8955f39d397SChris Mason 	struct extent_buffer *left = NULL;
8965f39d397SChris Mason 	struct extent_buffer *parent = NULL;
897e66f709bSChris Mason 	int ret = 0;
898e66f709bSChris Mason 	int wret;
899e66f709bSChris Mason 	int pslot;
900e66f709bSChris Mason 	int orig_slot = path->slots[level];
901e66f709bSChris Mason 	u64 orig_ptr;
902e66f709bSChris Mason 
903e66f709bSChris Mason 	if (level == 0)
904e66f709bSChris Mason 		return 1;
905e66f709bSChris Mason 
9065f39d397SChris Mason 	mid = path->nodes[level];
9077bb86316SChris Mason 	WARN_ON(btrfs_header_generation(mid) != trans->transid);
908e66f709bSChris Mason 	orig_ptr = btrfs_node_blockptr(mid, orig_slot);
909e66f709bSChris Mason 
910e66f709bSChris Mason 	if (level < BTRFS_MAX_LEVEL - 1)
9115f39d397SChris Mason 		parent = path->nodes[level + 1];
912e66f709bSChris Mason 	pslot = path->slots[level + 1];
913e66f709bSChris Mason 
9145f39d397SChris Mason 	if (!parent)
915e66f709bSChris Mason 		return 1;
916e66f709bSChris Mason 
9175f39d397SChris Mason 	left = read_node_slot(root, parent, pslot - 1);
918e66f709bSChris Mason 
919e66f709bSChris Mason 	/* first, try to make some room in the middle buffer */
9205f39d397SChris Mason 	if (left) {
921e66f709bSChris Mason 		u32 left_nr;
9225f39d397SChris Mason 		left_nr = btrfs_header_nritems(left);
92333ade1f8SChris Mason 		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
92433ade1f8SChris Mason 			wret = 1;
92533ade1f8SChris Mason 		} else {
9265f39d397SChris Mason 			ret = btrfs_cow_block(trans, root, left, parent,
9275f39d397SChris Mason 					      pslot - 1, &left);
92854aa1f4dSChris Mason 			if (ret)
92954aa1f4dSChris Mason 				wret = 1;
93054aa1f4dSChris Mason 			else {
93154aa1f4dSChris Mason 				wret = push_node_left(trans, root,
9325f39d397SChris Mason 						      left, mid);
93354aa1f4dSChris Mason 			}
93433ade1f8SChris Mason 		}
935e66f709bSChris Mason 		if (wret < 0)
936e66f709bSChris Mason 			ret = wret;
937e66f709bSChris Mason 		if (wret == 0) {
9385f39d397SChris Mason 			struct btrfs_disk_key disk_key;
939e66f709bSChris Mason 			orig_slot += left_nr;
9405f39d397SChris Mason 			btrfs_node_key(mid, &disk_key, 0);
9415f39d397SChris Mason 			btrfs_set_node_key(parent, &disk_key, pslot);
9425f39d397SChris Mason 			btrfs_mark_buffer_dirty(parent);
9435f39d397SChris Mason 			if (btrfs_header_nritems(left) > orig_slot) {
9445f39d397SChris Mason 				path->nodes[level] = left;
945e66f709bSChris Mason 				path->slots[level + 1] -= 1;
946e66f709bSChris Mason 				path->slots[level] = orig_slot;
9475f39d397SChris Mason 				free_extent_buffer(mid);
948e66f709bSChris Mason 			} else {
949e66f709bSChris Mason 				orig_slot -=
9505f39d397SChris Mason 					btrfs_header_nritems(left);
951e66f709bSChris Mason 				path->slots[level] = orig_slot;
9525f39d397SChris Mason 				free_extent_buffer(left);
953e66f709bSChris Mason 			}
954e66f709bSChris Mason 			return 0;
955e66f709bSChris Mason 		}
9565f39d397SChris Mason 		free_extent_buffer(left);
957e66f709bSChris Mason 	}
9585f39d397SChris Mason 	right= read_node_slot(root, parent, pslot + 1);
959e66f709bSChris Mason 
960e66f709bSChris Mason 	/*
961e66f709bSChris Mason 	 * then try to empty the right most buffer into the middle
962e66f709bSChris Mason 	 */
9635f39d397SChris Mason 	if (right) {
96433ade1f8SChris Mason 		u32 right_nr;
9655f39d397SChris Mason 		right_nr = btrfs_header_nritems(right);
96633ade1f8SChris Mason 		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
96733ade1f8SChris Mason 			wret = 1;
96833ade1f8SChris Mason 		} else {
9695f39d397SChris Mason 			ret = btrfs_cow_block(trans, root, right,
9705f39d397SChris Mason 					      parent, pslot + 1,
9715f39d397SChris Mason 					      &right);
97254aa1f4dSChris Mason 			if (ret)
97354aa1f4dSChris Mason 				wret = 1;
97454aa1f4dSChris Mason 			else {
97533ade1f8SChris Mason 				wret = balance_node_right(trans, root,
9765f39d397SChris Mason 							  right, mid);
97733ade1f8SChris Mason 			}
97854aa1f4dSChris Mason 		}
979e66f709bSChris Mason 		if (wret < 0)
980e66f709bSChris Mason 			ret = wret;
981e66f709bSChris Mason 		if (wret == 0) {
9825f39d397SChris Mason 			struct btrfs_disk_key disk_key;
9835f39d397SChris Mason 
9845f39d397SChris Mason 			btrfs_node_key(right, &disk_key, 0);
9855f39d397SChris Mason 			btrfs_set_node_key(parent, &disk_key, pslot + 1);
9865f39d397SChris Mason 			btrfs_mark_buffer_dirty(parent);
9875f39d397SChris Mason 
9885f39d397SChris Mason 			if (btrfs_header_nritems(mid) <= orig_slot) {
9895f39d397SChris Mason 				path->nodes[level] = right;
990e66f709bSChris Mason 				path->slots[level + 1] += 1;
991e66f709bSChris Mason 				path->slots[level] = orig_slot -
9925f39d397SChris Mason 					btrfs_header_nritems(mid);
9935f39d397SChris Mason 				free_extent_buffer(mid);
994e66f709bSChris Mason 			} else {
9955f39d397SChris Mason 				free_extent_buffer(right);
996e66f709bSChris Mason 			}
997e66f709bSChris Mason 			return 0;
998e66f709bSChris Mason 		}
9995f39d397SChris Mason 		free_extent_buffer(right);
1000e66f709bSChris Mason 	}
1001e66f709bSChris Mason 	return 1;
1002e66f709bSChris Mason }
1003e66f709bSChris Mason 
100474123bd7SChris Mason /*
10053c69faecSChris Mason  * readahead one full node of leaves
10063c69faecSChris Mason  */
10073c69faecSChris Mason static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
100801f46658SChris Mason 			     int level, int slot, u64 objectid)
10093c69faecSChris Mason {
10105f39d397SChris Mason 	struct extent_buffer *node;
101101f46658SChris Mason 	struct btrfs_disk_key disk_key;
10123c69faecSChris Mason 	u32 nritems;
10133c69faecSChris Mason 	u64 search;
10146b80053dSChris Mason 	u64 lowest_read;
10156b80053dSChris Mason 	u64 highest_read;
10166b80053dSChris Mason 	u64 nread = 0;
10173c69faecSChris Mason 	int direction = path->reada;
10185f39d397SChris Mason 	struct extent_buffer *eb;
10196b80053dSChris Mason 	u32 nr;
10206b80053dSChris Mason 	u32 blocksize;
10216b80053dSChris Mason 	u32 nscan = 0;
1022db94535dSChris Mason 
1023a6b6e75eSChris Mason 	if (level != 1)
10243c69faecSChris Mason 		return;
10253c69faecSChris Mason 
10266702ed49SChris Mason 	if (!path->nodes[level])
10276702ed49SChris Mason 		return;
10286702ed49SChris Mason 
10295f39d397SChris Mason 	node = path->nodes[level];
10303c69faecSChris Mason 	search = btrfs_node_blockptr(node, slot);
10316b80053dSChris Mason 	blocksize = btrfs_level_size(root, level - 1);
10326b80053dSChris Mason 	eb = btrfs_find_tree_block(root, search, blocksize);
10335f39d397SChris Mason 	if (eb) {
10345f39d397SChris Mason 		free_extent_buffer(eb);
10353c69faecSChris Mason 		return;
10363c69faecSChris Mason 	}
10373c69faecSChris Mason 
10386b80053dSChris Mason 	highest_read = search;
10396b80053dSChris Mason 	lowest_read = search;
10406b80053dSChris Mason 
10415f39d397SChris Mason 	nritems = btrfs_header_nritems(node);
10426b80053dSChris Mason 	nr = slot;
10433c69faecSChris Mason 	while(1) {
10446b80053dSChris Mason 		if (direction < 0) {
10456b80053dSChris Mason 			if (nr == 0)
10463c69faecSChris Mason 				break;
10476b80053dSChris Mason 			nr--;
10486b80053dSChris Mason 		} else if (direction > 0) {
10496b80053dSChris Mason 			nr++;
10506b80053dSChris Mason 			if (nr >= nritems)
10516b80053dSChris Mason 				break;
10523c69faecSChris Mason 		}
105301f46658SChris Mason 		if (path->reada < 0 && objectid) {
105401f46658SChris Mason 			btrfs_node_key(node, &disk_key, nr);
105501f46658SChris Mason 			if (btrfs_disk_key_objectid(&disk_key) != objectid)
105601f46658SChris Mason 				break;
105701f46658SChris Mason 		}
10586b80053dSChris Mason 		search = btrfs_node_blockptr(node, nr);
10596b80053dSChris Mason 		if ((search >= lowest_read && search <= highest_read) ||
10606b80053dSChris Mason 		    (search < lowest_read && lowest_read - search <= 32768) ||
10616b80053dSChris Mason 		    (search > highest_read && search - highest_read <= 32768)) {
10626b80053dSChris Mason 			readahead_tree_block(root, search, blocksize);
10636b80053dSChris Mason 			nread += blocksize;
10643c69faecSChris Mason 		}
10656b80053dSChris Mason 		nscan++;
10666b80053dSChris Mason 		if (path->reada < 2 && (nread > (256 * 1024) || nscan > 32))
10676b80053dSChris Mason 			break;
10686b80053dSChris Mason 		if(nread > (1024 * 1024) || nscan > 128)
10696b80053dSChris Mason 			break;
10706b80053dSChris Mason 
10716b80053dSChris Mason 		if (search < lowest_read)
10726b80053dSChris Mason 			lowest_read = search;
10736b80053dSChris Mason 		if (search > highest_read)
10746b80053dSChris Mason 			highest_read = search;
10753c69faecSChris Mason 	}
10763c69faecSChris Mason }
10773c69faecSChris Mason /*
107874123bd7SChris Mason  * look for key in the tree.  path is filled in with nodes along the way
107974123bd7SChris Mason  * if key is found, we return zero and you can find the item in the leaf
108074123bd7SChris Mason  * level of the path (level 0)
108174123bd7SChris Mason  *
108274123bd7SChris Mason  * If the key isn't found, the path points to the slot where it should
1083aa5d6bedSChris Mason  * be inserted, and 1 is returned.  If there are other errors during the
1084aa5d6bedSChris Mason  * search a negative error number is returned.
108597571fd0SChris Mason  *
108697571fd0SChris Mason  * if ins_len > 0, nodes and leaves will be split as we walk down the
108797571fd0SChris Mason  * tree.  if ins_len < 0, nodes will be merged as we walk down the tree (if
108897571fd0SChris Mason  * possible)
108974123bd7SChris Mason  */
1090e089f05cSChris Mason int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
1091e089f05cSChris Mason 		      *root, struct btrfs_key *key, struct btrfs_path *p, int
1092e089f05cSChris Mason 		      ins_len, int cow)
1093be0e5c09SChris Mason {
10945f39d397SChris Mason 	struct extent_buffer *b;
1095db94535dSChris Mason 	u64 bytenr;
109674493f7aSChris Mason 	u64 ptr_gen;
1097be0e5c09SChris Mason 	int slot;
1098be0e5c09SChris Mason 	int ret;
1099be0e5c09SChris Mason 	int level;
11003c69faecSChris Mason 	int should_reada = p->reada;
11019f3a7427SChris Mason 	u8 lowest_level = 0;
11029f3a7427SChris Mason 
11036702ed49SChris Mason 	lowest_level = p->lowest_level;
11046702ed49SChris Mason 	WARN_ON(lowest_level && ins_len);
110522b0ebdaSChris Mason 	WARN_ON(p->nodes[0] != NULL);
110622b0ebdaSChris Mason 	WARN_ON(!mutex_is_locked(&root->fs_info->fs_mutex));
1107bb803951SChris Mason again:
1108bb803951SChris Mason 	b = root->node;
11095f39d397SChris Mason 	extent_buffer_get(b);
1110eb60ceacSChris Mason 	while (b) {
11115f39d397SChris Mason 		level = btrfs_header_level(b);
111202217ed2SChris Mason 		if (cow) {
111302217ed2SChris Mason 			int wret;
1114e20d96d6SChris Mason 			wret = btrfs_cow_block(trans, root, b,
1115e20d96d6SChris Mason 					       p->nodes[level + 1],
1116e20d96d6SChris Mason 					       p->slots[level + 1],
1117252c38f0SYan 					       &b);
111854aa1f4dSChris Mason 			if (wret) {
11195f39d397SChris Mason 				free_extent_buffer(b);
112054aa1f4dSChris Mason 				return wret;
112154aa1f4dSChris Mason 			}
112202217ed2SChris Mason 		}
112302217ed2SChris Mason 		BUG_ON(!cow && ins_len);
11245f39d397SChris Mason 		if (level != btrfs_header_level(b))
11252c90e5d6SChris Mason 			WARN_ON(1);
11265f39d397SChris Mason 		level = btrfs_header_level(b);
1127eb60ceacSChris Mason 		p->nodes[level] = b;
1128123abc88SChris Mason 		ret = check_block(root, p, level);
1129aa5d6bedSChris Mason 		if (ret)
1130aa5d6bedSChris Mason 			return -1;
11315f39d397SChris Mason 		ret = bin_search(b, key, level, &slot);
11325f39d397SChris Mason 		if (level != 0) {
1133be0e5c09SChris Mason 			if (ret && slot > 0)
1134be0e5c09SChris Mason 				slot -= 1;
1135be0e5c09SChris Mason 			p->slots[level] = slot;
11365f39d397SChris Mason 			if (ins_len > 0 && btrfs_header_nritems(b) >=
1137d4dbff95SChris Mason 			    BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
1138e089f05cSChris Mason 				int sret = split_node(trans, root, p, level);
11395c680ed6SChris Mason 				BUG_ON(sret > 0);
11405c680ed6SChris Mason 				if (sret)
11415c680ed6SChris Mason 					return sret;
11425c680ed6SChris Mason 				b = p->nodes[level];
11435c680ed6SChris Mason 				slot = p->slots[level];
1144bb803951SChris Mason 			} else if (ins_len < 0) {
1145e089f05cSChris Mason 				int sret = balance_level(trans, root, p,
1146e089f05cSChris Mason 							 level);
1147bb803951SChris Mason 				if (sret)
1148bb803951SChris Mason 					return sret;
1149bb803951SChris Mason 				b = p->nodes[level];
1150f510cfecSChris Mason 				if (!b) {
1151f510cfecSChris Mason 					btrfs_release_path(NULL, p);
1152bb803951SChris Mason 					goto again;
1153f510cfecSChris Mason 				}
1154bb803951SChris Mason 				slot = p->slots[level];
11555f39d397SChris Mason 				BUG_ON(btrfs_header_nritems(b) == 1);
11565c680ed6SChris Mason 			}
11579f3a7427SChris Mason 			/* this is only true while dropping a snapshot */
11589f3a7427SChris Mason 			if (level == lowest_level)
11599f3a7427SChris Mason 				break;
1160db94535dSChris Mason 			bytenr = btrfs_node_blockptr(b, slot);
116174493f7aSChris Mason 			ptr_gen = btrfs_node_ptr_generation(b, slot);
11626702ed49SChris Mason 			if (should_reada)
116301f46658SChris Mason 				reada_for_search(root, p, level, slot,
116401f46658SChris Mason 						 key->objectid);
1165db94535dSChris Mason 			b = read_tree_block(root, bytenr,
1166db94535dSChris Mason 					    btrfs_level_size(root, level - 1));
116774493f7aSChris Mason 			if (ptr_gen != btrfs_header_generation(b)) {
116874493f7aSChris Mason 				printk("block %llu bad gen wanted %llu "
116974493f7aSChris Mason 				       "found %llu\n",
117074493f7aSChris Mason 			        (unsigned long long)b->start,
117174493f7aSChris Mason 				(unsigned long long)ptr_gen,
117274493f7aSChris Mason 			        (unsigned long long)btrfs_header_generation(b));
117374493f7aSChris Mason 			}
1174be0e5c09SChris Mason 		} else {
1175be0e5c09SChris Mason 			p->slots[level] = slot;
11765f39d397SChris Mason 			if (ins_len > 0 && btrfs_leaf_free_space(root, b) <
11770783fcfcSChris Mason 			    sizeof(struct btrfs_item) + ins_len) {
1178d4dbff95SChris Mason 				int sret = split_leaf(trans, root, key,
1179cc0c5538SChris Mason 						      p, ins_len, ret == 0);
11805c680ed6SChris Mason 				BUG_ON(sret > 0);
11815c680ed6SChris Mason 				if (sret)
11825c680ed6SChris Mason 					return sret;
11835c680ed6SChris Mason 			}
1184be0e5c09SChris Mason 			return ret;
1185be0e5c09SChris Mason 		}
1186be0e5c09SChris Mason 	}
1187aa5d6bedSChris Mason 	return 1;
1188be0e5c09SChris Mason }
1189be0e5c09SChris Mason 
119074123bd7SChris Mason /*
119174123bd7SChris Mason  * adjust the pointers going up the tree, starting at level
119274123bd7SChris Mason  * making sure the right key of each node is points to 'key'.
119374123bd7SChris Mason  * This is used after shifting pointers to the left, so it stops
119474123bd7SChris Mason  * fixing up pointers when a given leaf/node is not in slot 0 of the
119574123bd7SChris Mason  * higher levels
1196aa5d6bedSChris Mason  *
1197aa5d6bedSChris Mason  * If this fails to write a tree block, it returns -1, but continues
1198aa5d6bedSChris Mason  * fixing up the blocks in ram so the tree is consistent.
119974123bd7SChris Mason  */
12005f39d397SChris Mason static int fixup_low_keys(struct btrfs_trans_handle *trans,
12015f39d397SChris Mason 			  struct btrfs_root *root, struct btrfs_path *path,
12025f39d397SChris Mason 			  struct btrfs_disk_key *key, int level)
1203be0e5c09SChris Mason {
1204be0e5c09SChris Mason 	int i;
1205aa5d6bedSChris Mason 	int ret = 0;
12065f39d397SChris Mason 	struct extent_buffer *t;
12075f39d397SChris Mason 
1208234b63a0SChris Mason 	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
1209be0e5c09SChris Mason 		int tslot = path->slots[i];
1210eb60ceacSChris Mason 		if (!path->nodes[i])
1211be0e5c09SChris Mason 			break;
12125f39d397SChris Mason 		t = path->nodes[i];
12135f39d397SChris Mason 		btrfs_set_node_key(t, key, tslot);
1214d6025579SChris Mason 		btrfs_mark_buffer_dirty(path->nodes[i]);
1215be0e5c09SChris Mason 		if (tslot != 0)
1216be0e5c09SChris Mason 			break;
1217be0e5c09SChris Mason 	}
1218aa5d6bedSChris Mason 	return ret;
1219be0e5c09SChris Mason }
1220be0e5c09SChris Mason 
122174123bd7SChris Mason /*
122274123bd7SChris Mason  * try to push data from one node into the next node left in the
122379f95c82SChris Mason  * tree.
1224aa5d6bedSChris Mason  *
1225aa5d6bedSChris Mason  * returns 0 if some ptrs were pushed left, < 0 if there was some horrible
1226aa5d6bedSChris Mason  * error, and > 0 if there was no room in the left hand block.
122774123bd7SChris Mason  */
122898ed5174SChris Mason static int push_node_left(struct btrfs_trans_handle *trans,
122998ed5174SChris Mason 			  struct btrfs_root *root, struct extent_buffer *dst,
12305f39d397SChris Mason 			  struct extent_buffer *src)
1231be0e5c09SChris Mason {
1232be0e5c09SChris Mason 	int push_items = 0;
1233bb803951SChris Mason 	int src_nritems;
1234bb803951SChris Mason 	int dst_nritems;
1235aa5d6bedSChris Mason 	int ret = 0;
1236be0e5c09SChris Mason 
12375f39d397SChris Mason 	src_nritems = btrfs_header_nritems(src);
12385f39d397SChris Mason 	dst_nritems = btrfs_header_nritems(dst);
1239123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
12407bb86316SChris Mason 	WARN_ON(btrfs_header_generation(src) != trans->transid);
12417bb86316SChris Mason 	WARN_ON(btrfs_header_generation(dst) != trans->transid);
124254aa1f4dSChris Mason 
1243eb60ceacSChris Mason 	if (push_items <= 0) {
1244be0e5c09SChris Mason 		return 1;
1245eb60ceacSChris Mason 	}
1246be0e5c09SChris Mason 
1247be0e5c09SChris Mason 	if (src_nritems < push_items)
1248be0e5c09SChris Mason 		push_items = src_nritems;
124979f95c82SChris Mason 
12505f39d397SChris Mason 	copy_extent_buffer(dst, src,
12515f39d397SChris Mason 			   btrfs_node_key_ptr_offset(dst_nritems),
12525f39d397SChris Mason 			   btrfs_node_key_ptr_offset(0),
1253123abc88SChris Mason 		           push_items * sizeof(struct btrfs_key_ptr));
12545f39d397SChris Mason 
1255bb803951SChris Mason 	if (push_items < src_nritems) {
12565f39d397SChris Mason 		memmove_extent_buffer(src, btrfs_node_key_ptr_offset(0),
12575f39d397SChris Mason 				      btrfs_node_key_ptr_offset(push_items),
1258e2fa7227SChris Mason 				      (src_nritems - push_items) *
1259123abc88SChris Mason 				      sizeof(struct btrfs_key_ptr));
1260bb803951SChris Mason 	}
12615f39d397SChris Mason 	btrfs_set_header_nritems(src, src_nritems - push_items);
12625f39d397SChris Mason 	btrfs_set_header_nritems(dst, dst_nritems + push_items);
12635f39d397SChris Mason 	btrfs_mark_buffer_dirty(src);
12645f39d397SChris Mason 	btrfs_mark_buffer_dirty(dst);
1265bb803951SChris Mason 	return ret;
1266be0e5c09SChris Mason }
1267be0e5c09SChris Mason 
126897571fd0SChris Mason /*
126979f95c82SChris Mason  * try to push data from one node into the next node right in the
127079f95c82SChris Mason  * tree.
127179f95c82SChris Mason  *
127279f95c82SChris Mason  * returns 0 if some ptrs were pushed, < 0 if there was some horrible
127379f95c82SChris Mason  * error, and > 0 if there was no room in the right hand block.
127479f95c82SChris Mason  *
127579f95c82SChris Mason  * this will  only push up to 1/2 the contents of the left node over
127679f95c82SChris Mason  */
12775f39d397SChris Mason static int balance_node_right(struct btrfs_trans_handle *trans,
12785f39d397SChris Mason 			      struct btrfs_root *root,
12795f39d397SChris Mason 			      struct extent_buffer *dst,
12805f39d397SChris Mason 			      struct extent_buffer *src)
128179f95c82SChris Mason {
128279f95c82SChris Mason 	int push_items = 0;
128379f95c82SChris Mason 	int max_push;
128479f95c82SChris Mason 	int src_nritems;
128579f95c82SChris Mason 	int dst_nritems;
128679f95c82SChris Mason 	int ret = 0;
128779f95c82SChris Mason 
12887bb86316SChris Mason 	WARN_ON(btrfs_header_generation(src) != trans->transid);
12897bb86316SChris Mason 	WARN_ON(btrfs_header_generation(dst) != trans->transid);
12907bb86316SChris Mason 
12915f39d397SChris Mason 	src_nritems = btrfs_header_nritems(src);
12925f39d397SChris Mason 	dst_nritems = btrfs_header_nritems(dst);
1293123abc88SChris Mason 	push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
12945f39d397SChris Mason 	if (push_items <= 0)
129579f95c82SChris Mason 		return 1;
129679f95c82SChris Mason 
129779f95c82SChris Mason 	max_push = src_nritems / 2 + 1;
129879f95c82SChris Mason 	/* don't try to empty the node */
1299252c38f0SYan 	if (max_push >= src_nritems)
130079f95c82SChris Mason 		return 1;
1301252c38f0SYan 
130279f95c82SChris Mason 	if (max_push < push_items)
130379f95c82SChris Mason 		push_items = max_push;
130479f95c82SChris Mason 
13055f39d397SChris Mason 	memmove_extent_buffer(dst, btrfs_node_key_ptr_offset(push_items),
13065f39d397SChris Mason 				      btrfs_node_key_ptr_offset(0),
13075f39d397SChris Mason 				      (dst_nritems) *
13085f39d397SChris Mason 				      sizeof(struct btrfs_key_ptr));
1309d6025579SChris Mason 
13105f39d397SChris Mason 	copy_extent_buffer(dst, src,
13115f39d397SChris Mason 			   btrfs_node_key_ptr_offset(0),
13125f39d397SChris Mason 			   btrfs_node_key_ptr_offset(src_nritems - push_items),
1313123abc88SChris Mason 		           push_items * sizeof(struct btrfs_key_ptr));
131479f95c82SChris Mason 
13155f39d397SChris Mason 	btrfs_set_header_nritems(src, src_nritems - push_items);
13165f39d397SChris Mason 	btrfs_set_header_nritems(dst, dst_nritems + push_items);
131779f95c82SChris Mason 
13185f39d397SChris Mason 	btrfs_mark_buffer_dirty(src);
13195f39d397SChris Mason 	btrfs_mark_buffer_dirty(dst);
132079f95c82SChris Mason 	return ret;
132179f95c82SChris Mason }
132279f95c82SChris Mason 
132379f95c82SChris Mason /*
132497571fd0SChris Mason  * helper function to insert a new root level in the tree.
132597571fd0SChris Mason  * A new node is allocated, and a single item is inserted to
132697571fd0SChris Mason  * point to the existing root
1327aa5d6bedSChris Mason  *
1328aa5d6bedSChris Mason  * returns zero on success or < 0 on failure.
132997571fd0SChris Mason  */
133098ed5174SChris Mason static int noinline insert_new_root(struct btrfs_trans_handle *trans,
13315f39d397SChris Mason 			   struct btrfs_root *root,
13325f39d397SChris Mason 			   struct btrfs_path *path, int level)
133374123bd7SChris Mason {
13347bb86316SChris Mason 	u64 root_gen;
13357bb86316SChris Mason 	u64 lower_gen;
13365f39d397SChris Mason 	struct extent_buffer *lower;
13375f39d397SChris Mason 	struct extent_buffer *c;
13385f39d397SChris Mason 	struct btrfs_disk_key lower_key;
13395c680ed6SChris Mason 
13405c680ed6SChris Mason 	BUG_ON(path->nodes[level]);
13415c680ed6SChris Mason 	BUG_ON(path->nodes[level-1] != root->node);
13425c680ed6SChris Mason 
13437bb86316SChris Mason 	if (root->ref_cows)
13447bb86316SChris Mason 		root_gen = trans->transid;
13457bb86316SChris Mason 	else
13467bb86316SChris Mason 		root_gen = 0;
13477bb86316SChris Mason 
13487bb86316SChris Mason 	lower = path->nodes[level-1];
13497bb86316SChris Mason 	if (level == 1)
13507bb86316SChris Mason 		btrfs_item_key(lower, &lower_key, 0);
13517bb86316SChris Mason 	else
13527bb86316SChris Mason 		btrfs_node_key(lower, &lower_key, 0);
13537bb86316SChris Mason 
13547bb86316SChris Mason 	c = __btrfs_alloc_free_block(trans, root, root->nodesize,
13557bb86316SChris Mason 				   root->root_key.objectid,
13567bb86316SChris Mason 				   root_gen, lower_key.objectid, level,
1357db94535dSChris Mason 				   root->node->start, 0);
13585f39d397SChris Mason 	if (IS_ERR(c))
13595f39d397SChris Mason 		return PTR_ERR(c);
13605f39d397SChris Mason 	memset_extent_buffer(c, 0, 0, root->nodesize);
13615f39d397SChris Mason 	btrfs_set_header_nritems(c, 1);
13625f39d397SChris Mason 	btrfs_set_header_level(c, level);
1363db94535dSChris Mason 	btrfs_set_header_bytenr(c, c->start);
13645f39d397SChris Mason 	btrfs_set_header_generation(c, trans->transid);
13655f39d397SChris Mason 	btrfs_set_header_owner(c, root->root_key.objectid);
1366d5719762SChris Mason 
13675f39d397SChris Mason 	write_extent_buffer(c, root->fs_info->fsid,
13685f39d397SChris Mason 			    (unsigned long)btrfs_header_fsid(c),
13695f39d397SChris Mason 			    BTRFS_FSID_SIZE);
13705f39d397SChris Mason 	btrfs_set_node_key(c, &lower_key, 0);
1371db94535dSChris Mason 	btrfs_set_node_blockptr(c, 0, lower->start);
13727bb86316SChris Mason 	lower_gen = btrfs_header_generation(lower);
13737bb86316SChris Mason 	WARN_ON(lower_gen == 0);
13747bb86316SChris Mason 
13757bb86316SChris Mason 	btrfs_set_node_ptr_generation(c, 0, lower_gen);
13765f39d397SChris Mason 
13775f39d397SChris Mason 	btrfs_mark_buffer_dirty(c);
1378d5719762SChris Mason 
1379cfaa7295SChris Mason 	/* the super has an extra ref to root->node */
13805f39d397SChris Mason 	free_extent_buffer(root->node);
13815f39d397SChris Mason 	root->node = c;
1382*0b86a832SChris Mason 	add_root_to_dirty_list(root);
13835f39d397SChris Mason 	extent_buffer_get(c);
13845f39d397SChris Mason 	path->nodes[level] = c;
138574123bd7SChris Mason 	path->slots[level] = 0;
13867bb86316SChris Mason 
13877bb86316SChris Mason 	if (root->ref_cows && lower_gen != trans->transid) {
13887bb86316SChris Mason 		struct btrfs_path *back_path = btrfs_alloc_path();
13897bb86316SChris Mason 		int ret;
13907bb86316SChris Mason 		ret = btrfs_insert_extent_backref(trans,
13917bb86316SChris Mason 						  root->fs_info->extent_root,
13927bb86316SChris Mason 						  path, lower->start,
13937bb86316SChris Mason 						  root->root_key.objectid,
13947bb86316SChris Mason 						  trans->transid, 0, 0);
13957bb86316SChris Mason 		BUG_ON(ret);
13967bb86316SChris Mason 		btrfs_free_path(back_path);
13977bb86316SChris Mason 	}
139874123bd7SChris Mason 	return 0;
139974123bd7SChris Mason }
14005c680ed6SChris Mason 
14015c680ed6SChris Mason /*
14025c680ed6SChris Mason  * worker function to insert a single pointer in a node.
14035c680ed6SChris Mason  * the node should have enough room for the pointer already
140497571fd0SChris Mason  *
14055c680ed6SChris Mason  * slot and level indicate where you want the key to go, and
14065c680ed6SChris Mason  * blocknr is the block the key points to.
1407aa5d6bedSChris Mason  *
1408aa5d6bedSChris Mason  * returns zero on success and < 0 on any error
14095c680ed6SChris Mason  */
1410e089f05cSChris Mason static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
1411e089f05cSChris Mason 		      *root, struct btrfs_path *path, struct btrfs_disk_key
1412db94535dSChris Mason 		      *key, u64 bytenr, int slot, int level)
14135c680ed6SChris Mason {
14145f39d397SChris Mason 	struct extent_buffer *lower;
14155c680ed6SChris Mason 	int nritems;
14165c680ed6SChris Mason 
14175c680ed6SChris Mason 	BUG_ON(!path->nodes[level]);
14185f39d397SChris Mason 	lower = path->nodes[level];
14195f39d397SChris Mason 	nritems = btrfs_header_nritems(lower);
142074123bd7SChris Mason 	if (slot > nritems)
142174123bd7SChris Mason 		BUG();
1422123abc88SChris Mason 	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
142374123bd7SChris Mason 		BUG();
142474123bd7SChris Mason 	if (slot != nritems) {
14255f39d397SChris Mason 		memmove_extent_buffer(lower,
14265f39d397SChris Mason 			      btrfs_node_key_ptr_offset(slot + 1),
14275f39d397SChris Mason 			      btrfs_node_key_ptr_offset(slot),
1428123abc88SChris Mason 			      (nritems - slot) * sizeof(struct btrfs_key_ptr));
142974123bd7SChris Mason 	}
14305f39d397SChris Mason 	btrfs_set_node_key(lower, key, slot);
1431db94535dSChris Mason 	btrfs_set_node_blockptr(lower, slot, bytenr);
143274493f7aSChris Mason 	WARN_ON(trans->transid == 0);
143374493f7aSChris Mason 	btrfs_set_node_ptr_generation(lower, slot, trans->transid);
14345f39d397SChris Mason 	btrfs_set_header_nritems(lower, nritems + 1);
14355f39d397SChris Mason 	btrfs_mark_buffer_dirty(lower);
143674123bd7SChris Mason 	return 0;
143774123bd7SChris Mason }
143874123bd7SChris Mason 
143997571fd0SChris Mason /*
144097571fd0SChris Mason  * split the node at the specified level in path in two.
144197571fd0SChris Mason  * The path is corrected to point to the appropriate node after the split
144297571fd0SChris Mason  *
144397571fd0SChris Mason  * Before splitting this tries to make some room in the node by pushing
144497571fd0SChris Mason  * left and right, if either one works, it returns right away.
1445aa5d6bedSChris Mason  *
1446aa5d6bedSChris Mason  * returns 0 on success and < 0 on failure
144797571fd0SChris Mason  */
1448e089f05cSChris Mason static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
1449e089f05cSChris Mason 		      *root, struct btrfs_path *path, int level)
1450be0e5c09SChris Mason {
14517bb86316SChris Mason 	u64 root_gen;
14525f39d397SChris Mason 	struct extent_buffer *c;
14535f39d397SChris Mason 	struct extent_buffer *split;
14545f39d397SChris Mason 	struct btrfs_disk_key disk_key;
1455be0e5c09SChris Mason 	int mid;
14565c680ed6SChris Mason 	int ret;
1457aa5d6bedSChris Mason 	int wret;
14587518a238SChris Mason 	u32 c_nritems;
1459be0e5c09SChris Mason 
14605f39d397SChris Mason 	c = path->nodes[level];
14617bb86316SChris Mason 	WARN_ON(btrfs_header_generation(c) != trans->transid);
14625f39d397SChris Mason 	if (c == root->node) {
14635c680ed6SChris Mason 		/* trying to split the root, lets make a new one */
1464e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, level + 1);
14655c680ed6SChris Mason 		if (ret)
14665c680ed6SChris Mason 			return ret;
1467e66f709bSChris Mason 	} else {
1468e66f709bSChris Mason 		ret = push_nodes_for_insert(trans, root, path, level);
14695f39d397SChris Mason 		c = path->nodes[level];
14705f39d397SChris Mason 		if (!ret && btrfs_header_nritems(c) <
1471e66f709bSChris Mason 		    BTRFS_NODEPTRS_PER_BLOCK(root) - 1)
1472e66f709bSChris Mason 			return 0;
147354aa1f4dSChris Mason 		if (ret < 0)
147454aa1f4dSChris Mason 			return ret;
14755c680ed6SChris Mason 	}
1476e66f709bSChris Mason 
14775f39d397SChris Mason 	c_nritems = btrfs_header_nritems(c);
14787bb86316SChris Mason 	if (root->ref_cows)
14797bb86316SChris Mason 		root_gen = trans->transid;
14807bb86316SChris Mason 	else
14817bb86316SChris Mason 		root_gen = 0;
14827bb86316SChris Mason 
14837bb86316SChris Mason 	btrfs_node_key(c, &disk_key, 0);
14847bb86316SChris Mason 	split = __btrfs_alloc_free_block(trans, root, root->nodesize,
14857bb86316SChris Mason 					 root->root_key.objectid,
14867bb86316SChris Mason 					 root_gen,
14877bb86316SChris Mason 					 btrfs_disk_key_objectid(&disk_key),
14887bb86316SChris Mason 					 level, c->start, 0);
14895f39d397SChris Mason 	if (IS_ERR(split))
14905f39d397SChris Mason 		return PTR_ERR(split);
149154aa1f4dSChris Mason 
14925f39d397SChris Mason 	btrfs_set_header_flags(split, btrfs_header_flags(c));
14935f39d397SChris Mason 	btrfs_set_header_level(split, btrfs_header_level(c));
1494db94535dSChris Mason 	btrfs_set_header_bytenr(split, split->start);
14955f39d397SChris Mason 	btrfs_set_header_generation(split, trans->transid);
14965f39d397SChris Mason 	btrfs_set_header_owner(split, root->root_key.objectid);
14975f39d397SChris Mason 	write_extent_buffer(split, root->fs_info->fsid,
14985f39d397SChris Mason 			    (unsigned long)btrfs_header_fsid(split),
14995f39d397SChris Mason 			    BTRFS_FSID_SIZE);
15005f39d397SChris Mason 
15017518a238SChris Mason 	mid = (c_nritems + 1) / 2;
15025f39d397SChris Mason 
15035f39d397SChris Mason 	copy_extent_buffer(split, c,
15045f39d397SChris Mason 			   btrfs_node_key_ptr_offset(0),
15055f39d397SChris Mason 			   btrfs_node_key_ptr_offset(mid),
1506123abc88SChris Mason 			   (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
15075f39d397SChris Mason 	btrfs_set_header_nritems(split, c_nritems - mid);
15085f39d397SChris Mason 	btrfs_set_header_nritems(c, mid);
1509aa5d6bedSChris Mason 	ret = 0;
1510aa5d6bedSChris Mason 
15115f39d397SChris Mason 	btrfs_mark_buffer_dirty(c);
15125f39d397SChris Mason 	btrfs_mark_buffer_dirty(split);
15135f39d397SChris Mason 
15145f39d397SChris Mason 	btrfs_node_key(split, &disk_key, 0);
1515db94535dSChris Mason 	wret = insert_ptr(trans, root, path, &disk_key, split->start,
15165f39d397SChris Mason 			  path->slots[level + 1] + 1,
1517123abc88SChris Mason 			  level + 1);
1518aa5d6bedSChris Mason 	if (wret)
1519aa5d6bedSChris Mason 		ret = wret;
1520aa5d6bedSChris Mason 
15215de08d7dSChris Mason 	if (path->slots[level] >= mid) {
15225c680ed6SChris Mason 		path->slots[level] -= mid;
15235f39d397SChris Mason 		free_extent_buffer(c);
15245f39d397SChris Mason 		path->nodes[level] = split;
15255c680ed6SChris Mason 		path->slots[level + 1] += 1;
1526eb60ceacSChris Mason 	} else {
15275f39d397SChris Mason 		free_extent_buffer(split);
1528be0e5c09SChris Mason 	}
1529aa5d6bedSChris Mason 	return ret;
1530be0e5c09SChris Mason }
1531be0e5c09SChris Mason 
153274123bd7SChris Mason /*
153374123bd7SChris Mason  * how many bytes are required to store the items in a leaf.  start
153474123bd7SChris Mason  * and nr indicate which items in the leaf to check.  This totals up the
153574123bd7SChris Mason  * space used both by the item structs and the item data
153674123bd7SChris Mason  */
15375f39d397SChris Mason static int leaf_space_used(struct extent_buffer *l, int start, int nr)
1538be0e5c09SChris Mason {
1539be0e5c09SChris Mason 	int data_len;
15405f39d397SChris Mason 	int nritems = btrfs_header_nritems(l);
1541d4dbff95SChris Mason 	int end = min(nritems, start + nr) - 1;
1542be0e5c09SChris Mason 
1543be0e5c09SChris Mason 	if (!nr)
1544be0e5c09SChris Mason 		return 0;
15455f39d397SChris Mason 	data_len = btrfs_item_end_nr(l, start);
15465f39d397SChris Mason 	data_len = data_len - btrfs_item_offset_nr(l, end);
15470783fcfcSChris Mason 	data_len += sizeof(struct btrfs_item) * nr;
1548d4dbff95SChris Mason 	WARN_ON(data_len < 0);
1549be0e5c09SChris Mason 	return data_len;
1550be0e5c09SChris Mason }
1551be0e5c09SChris Mason 
155274123bd7SChris Mason /*
1553d4dbff95SChris Mason  * The space between the end of the leaf items and
1554d4dbff95SChris Mason  * the start of the leaf data.  IOW, how much room
1555d4dbff95SChris Mason  * the leaf has left for both items and data
1556d4dbff95SChris Mason  */
15575f39d397SChris Mason int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf)
1558d4dbff95SChris Mason {
15595f39d397SChris Mason 	int nritems = btrfs_header_nritems(leaf);
15605f39d397SChris Mason 	int ret;
15615f39d397SChris Mason 	ret = BTRFS_LEAF_DATA_SIZE(root) - leaf_space_used(leaf, 0, nritems);
15625f39d397SChris Mason 	if (ret < 0) {
15635f39d397SChris Mason 		printk("leaf free space ret %d, leaf data size %lu, used %d nritems %d\n",
1564ae2f5411SJens Axboe 		       ret, (unsigned long) BTRFS_LEAF_DATA_SIZE(root),
15655f39d397SChris Mason 		       leaf_space_used(leaf, 0, nritems), nritems);
15665f39d397SChris Mason 	}
15675f39d397SChris Mason 	return ret;
1568d4dbff95SChris Mason }
1569d4dbff95SChris Mason 
1570d4dbff95SChris Mason /*
157100ec4c51SChris Mason  * push some data in the path leaf to the right, trying to free up at
157200ec4c51SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
1573aa5d6bedSChris Mason  *
1574aa5d6bedSChris Mason  * returns 1 if the push failed because the other node didn't have enough
1575aa5d6bedSChris Mason  * room, 0 if everything worked out and < 0 if there were major errors.
157600ec4c51SChris Mason  */
1577e089f05cSChris Mason static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
157834a38218SChris Mason 			   *root, struct btrfs_path *path, int data_size,
157934a38218SChris Mason 			   int empty)
158000ec4c51SChris Mason {
15815f39d397SChris Mason 	struct extent_buffer *left = path->nodes[0];
15825f39d397SChris Mason 	struct extent_buffer *right;
15835f39d397SChris Mason 	struct extent_buffer *upper;
15845f39d397SChris Mason 	struct btrfs_disk_key disk_key;
158500ec4c51SChris Mason 	int slot;
158634a38218SChris Mason 	u32 i;
158700ec4c51SChris Mason 	int free_space;
158800ec4c51SChris Mason 	int push_space = 0;
158900ec4c51SChris Mason 	int push_items = 0;
15900783fcfcSChris Mason 	struct btrfs_item *item;
15917518a238SChris Mason 	u32 left_nritems;
159234a38218SChris Mason 	u32 nr;
15937518a238SChris Mason 	u32 right_nritems;
15945f39d397SChris Mason 	u32 data_end;
1595db94535dSChris Mason 	u32 this_item_size;
159654aa1f4dSChris Mason 	int ret;
159700ec4c51SChris Mason 
159800ec4c51SChris Mason 	slot = path->slots[1];
159900ec4c51SChris Mason 	if (!path->nodes[1]) {
160000ec4c51SChris Mason 		return 1;
160100ec4c51SChris Mason 	}
160200ec4c51SChris Mason 	upper = path->nodes[1];
16035f39d397SChris Mason 	if (slot >= btrfs_header_nritems(upper) - 1)
160400ec4c51SChris Mason 		return 1;
16055f39d397SChris Mason 
1606db94535dSChris Mason 	right = read_tree_block(root, btrfs_node_blockptr(upper, slot + 1),
1607db94535dSChris Mason 				root->leafsize);
1608123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
16090783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
16105f39d397SChris Mason 		free_extent_buffer(right);
161102217ed2SChris Mason 		return 1;
161202217ed2SChris Mason 	}
161302217ed2SChris Mason 
16145f39d397SChris Mason 	/* cow and double check */
16155f39d397SChris Mason 	ret = btrfs_cow_block(trans, root, right, upper,
16165f39d397SChris Mason 			      slot + 1, &right);
16175f39d397SChris Mason 	if (ret) {
16185f39d397SChris Mason 		free_extent_buffer(right);
1619a429e513SChris Mason 		return 1;
1620a429e513SChris Mason 	}
16215f39d397SChris Mason 	free_space = btrfs_leaf_free_space(root, right);
16225f39d397SChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
16235f39d397SChris Mason 		free_extent_buffer(right);
16245f39d397SChris Mason 		return 1;
16255f39d397SChris Mason 	}
16265f39d397SChris Mason 
16275f39d397SChris Mason 	left_nritems = btrfs_header_nritems(left);
16285f39d397SChris Mason 	if (left_nritems == 0) {
16295f39d397SChris Mason 		free_extent_buffer(right);
16305f39d397SChris Mason 		return 1;
16315f39d397SChris Mason 	}
16325f39d397SChris Mason 
163334a38218SChris Mason 	if (empty)
163434a38218SChris Mason 		nr = 0;
163534a38218SChris Mason 	else
163634a38218SChris Mason 		nr = 1;
163734a38218SChris Mason 
163834a38218SChris Mason 	i = left_nritems - 1;
163934a38218SChris Mason 	while (i >= nr) {
16405f39d397SChris Mason 		item = btrfs_item_nr(left, i);
1641db94535dSChris Mason 
164200ec4c51SChris Mason 		if (path->slots[0] == i)
164300ec4c51SChris Mason 			push_space += data_size + sizeof(*item);
1644db94535dSChris Mason 
1645db94535dSChris Mason 		if (!left->map_token) {
1646db94535dSChris Mason 			map_extent_buffer(left, (unsigned long)item,
1647db94535dSChris Mason 					sizeof(struct btrfs_item),
1648db94535dSChris Mason 					&left->map_token, &left->kaddr,
1649db94535dSChris Mason 					&left->map_start, &left->map_len,
1650db94535dSChris Mason 					KM_USER1);
1651db94535dSChris Mason 		}
1652db94535dSChris Mason 
1653db94535dSChris Mason 		this_item_size = btrfs_item_size(left, item);
1654db94535dSChris Mason 		if (this_item_size + sizeof(*item) + push_space > free_space)
165500ec4c51SChris Mason 			break;
165600ec4c51SChris Mason 		push_items++;
1657db94535dSChris Mason 		push_space += this_item_size + sizeof(*item);
165834a38218SChris Mason 		if (i == 0)
165934a38218SChris Mason 			break;
166034a38218SChris Mason 		i--;
1661db94535dSChris Mason 	}
1662db94535dSChris Mason 	if (left->map_token) {
1663db94535dSChris Mason 		unmap_extent_buffer(left, left->map_token, KM_USER1);
1664db94535dSChris Mason 		left->map_token = NULL;
166500ec4c51SChris Mason 	}
16665f39d397SChris Mason 
166700ec4c51SChris Mason 	if (push_items == 0) {
16685f39d397SChris Mason 		free_extent_buffer(right);
166900ec4c51SChris Mason 		return 1;
167000ec4c51SChris Mason 	}
16715f39d397SChris Mason 
167234a38218SChris Mason 	if (!empty && push_items == left_nritems)
1673a429e513SChris Mason 		WARN_ON(1);
16745f39d397SChris Mason 
167500ec4c51SChris Mason 	/* push left to right */
16765f39d397SChris Mason 	right_nritems = btrfs_header_nritems(right);
167734a38218SChris Mason 
16785f39d397SChris Mason 	push_space = btrfs_item_end_nr(left, left_nritems - push_items);
1679123abc88SChris Mason 	push_space -= leaf_data_end(root, left);
16805f39d397SChris Mason 
168100ec4c51SChris Mason 	/* make room in the right data area */
16825f39d397SChris Mason 	data_end = leaf_data_end(root, right);
16835f39d397SChris Mason 	memmove_extent_buffer(right,
16845f39d397SChris Mason 			      btrfs_leaf_data(right) + data_end - push_space,
16855f39d397SChris Mason 			      btrfs_leaf_data(right) + data_end,
16865f39d397SChris Mason 			      BTRFS_LEAF_DATA_SIZE(root) - data_end);
16875f39d397SChris Mason 
168800ec4c51SChris Mason 	/* copy from the left data area */
16895f39d397SChris Mason 	copy_extent_buffer(right, left, btrfs_leaf_data(right) +
1690d6025579SChris Mason 		     BTRFS_LEAF_DATA_SIZE(root) - push_space,
1691d6025579SChris Mason 		     btrfs_leaf_data(left) + leaf_data_end(root, left),
1692d6025579SChris Mason 		     push_space);
16935f39d397SChris Mason 
16945f39d397SChris Mason 	memmove_extent_buffer(right, btrfs_item_nr_offset(push_items),
16955f39d397SChris Mason 			      btrfs_item_nr_offset(0),
16960783fcfcSChris Mason 			      right_nritems * sizeof(struct btrfs_item));
16975f39d397SChris Mason 
169800ec4c51SChris Mason 	/* copy the items from left to right */
16995f39d397SChris Mason 	copy_extent_buffer(right, left, btrfs_item_nr_offset(0),
17005f39d397SChris Mason 		   btrfs_item_nr_offset(left_nritems - push_items),
17010783fcfcSChris Mason 		   push_items * sizeof(struct btrfs_item));
170200ec4c51SChris Mason 
170300ec4c51SChris Mason 	/* update the item pointers */
17047518a238SChris Mason 	right_nritems += push_items;
17055f39d397SChris Mason 	btrfs_set_header_nritems(right, right_nritems);
1706123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
17077518a238SChris Mason 	for (i = 0; i < right_nritems; i++) {
17085f39d397SChris Mason 		item = btrfs_item_nr(right, i);
1709db94535dSChris Mason 		if (!right->map_token) {
1710db94535dSChris Mason 			map_extent_buffer(right, (unsigned long)item,
1711db94535dSChris Mason 					sizeof(struct btrfs_item),
1712db94535dSChris Mason 					&right->map_token, &right->kaddr,
1713db94535dSChris Mason 					&right->map_start, &right->map_len,
1714db94535dSChris Mason 					KM_USER1);
1715db94535dSChris Mason 		}
1716db94535dSChris Mason 		push_space -= btrfs_item_size(right, item);
1717db94535dSChris Mason 		btrfs_set_item_offset(right, item, push_space);
1718db94535dSChris Mason 	}
1719db94535dSChris Mason 
1720db94535dSChris Mason 	if (right->map_token) {
1721db94535dSChris Mason 		unmap_extent_buffer(right, right->map_token, KM_USER1);
1722db94535dSChris Mason 		right->map_token = NULL;
172300ec4c51SChris Mason 	}
17247518a238SChris Mason 	left_nritems -= push_items;
17255f39d397SChris Mason 	btrfs_set_header_nritems(left, left_nritems);
172600ec4c51SChris Mason 
172734a38218SChris Mason 	if (left_nritems)
17285f39d397SChris Mason 		btrfs_mark_buffer_dirty(left);
17295f39d397SChris Mason 	btrfs_mark_buffer_dirty(right);
1730a429e513SChris Mason 
17315f39d397SChris Mason 	btrfs_item_key(right, &disk_key, 0);
17325f39d397SChris Mason 	btrfs_set_node_key(upper, &disk_key, slot + 1);
1733d6025579SChris Mason 	btrfs_mark_buffer_dirty(upper);
173402217ed2SChris Mason 
173500ec4c51SChris Mason 	/* then fixup the leaf pointer in the path */
17367518a238SChris Mason 	if (path->slots[0] >= left_nritems) {
17377518a238SChris Mason 		path->slots[0] -= left_nritems;
17385f39d397SChris Mason 		free_extent_buffer(path->nodes[0]);
17395f39d397SChris Mason 		path->nodes[0] = right;
174000ec4c51SChris Mason 		path->slots[1] += 1;
174100ec4c51SChris Mason 	} else {
17425f39d397SChris Mason 		free_extent_buffer(right);
174300ec4c51SChris Mason 	}
174400ec4c51SChris Mason 	return 0;
174500ec4c51SChris Mason }
174600ec4c51SChris Mason /*
174774123bd7SChris Mason  * push some data in the path leaf to the left, trying to free up at
174874123bd7SChris Mason  * least data_size bytes.  returns zero if the push worked, nonzero otherwise
174974123bd7SChris Mason  */
1750e089f05cSChris Mason static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
175134a38218SChris Mason 			  *root, struct btrfs_path *path, int data_size,
175234a38218SChris Mason 			  int empty)
1753be0e5c09SChris Mason {
17545f39d397SChris Mason 	struct btrfs_disk_key disk_key;
17555f39d397SChris Mason 	struct extent_buffer *right = path->nodes[0];
17565f39d397SChris Mason 	struct extent_buffer *left;
1757be0e5c09SChris Mason 	int slot;
1758be0e5c09SChris Mason 	int i;
1759be0e5c09SChris Mason 	int free_space;
1760be0e5c09SChris Mason 	int push_space = 0;
1761be0e5c09SChris Mason 	int push_items = 0;
17620783fcfcSChris Mason 	struct btrfs_item *item;
17637518a238SChris Mason 	u32 old_left_nritems;
17645f39d397SChris Mason 	u32 right_nritems;
176534a38218SChris Mason 	u32 nr;
1766aa5d6bedSChris Mason 	int ret = 0;
1767aa5d6bedSChris Mason 	int wret;
1768db94535dSChris Mason 	u32 this_item_size;
1769db94535dSChris Mason 	u32 old_left_item_size;
1770be0e5c09SChris Mason 
1771be0e5c09SChris Mason 	slot = path->slots[1];
17725f39d397SChris Mason 	if (slot == 0)
1773be0e5c09SChris Mason 		return 1;
17745f39d397SChris Mason 	if (!path->nodes[1])
1775be0e5c09SChris Mason 		return 1;
17765f39d397SChris Mason 
17773685f791SChris Mason 	right_nritems = btrfs_header_nritems(right);
17783685f791SChris Mason 	if (right_nritems == 0) {
17793685f791SChris Mason 		return 1;
17803685f791SChris Mason 	}
17813685f791SChris Mason 
17825f39d397SChris Mason 	left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1],
1783db94535dSChris Mason 			       slot - 1), root->leafsize);
1784123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
17850783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
17865f39d397SChris Mason 		free_extent_buffer(left);
1787be0e5c09SChris Mason 		return 1;
1788be0e5c09SChris Mason 	}
178902217ed2SChris Mason 
179002217ed2SChris Mason 	/* cow and double check */
17915f39d397SChris Mason 	ret = btrfs_cow_block(trans, root, left,
17925f39d397SChris Mason 			      path->nodes[1], slot - 1, &left);
179354aa1f4dSChris Mason 	if (ret) {
179454aa1f4dSChris Mason 		/* we hit -ENOSPC, but it isn't fatal here */
17955f39d397SChris Mason 		free_extent_buffer(left);
179654aa1f4dSChris Mason 		return 1;
179754aa1f4dSChris Mason 	}
17983685f791SChris Mason 
1799123abc88SChris Mason 	free_space = btrfs_leaf_free_space(root, left);
18000783fcfcSChris Mason 	if (free_space < data_size + sizeof(struct btrfs_item)) {
18015f39d397SChris Mason 		free_extent_buffer(left);
180202217ed2SChris Mason 		return 1;
180302217ed2SChris Mason 	}
180402217ed2SChris Mason 
180534a38218SChris Mason 	if (empty)
180634a38218SChris Mason 		nr = right_nritems;
180734a38218SChris Mason 	else
180834a38218SChris Mason 		nr = right_nritems - 1;
180934a38218SChris Mason 
181034a38218SChris Mason 	for (i = 0; i < nr; i++) {
18115f39d397SChris Mason 		item = btrfs_item_nr(right, i);
1812db94535dSChris Mason 		if (!right->map_token) {
1813db94535dSChris Mason 			map_extent_buffer(right, (unsigned long)item,
1814db94535dSChris Mason 					sizeof(struct btrfs_item),
1815db94535dSChris Mason 					&right->map_token, &right->kaddr,
1816db94535dSChris Mason 					&right->map_start, &right->map_len,
1817db94535dSChris Mason 					KM_USER1);
1818db94535dSChris Mason 		}
1819db94535dSChris Mason 
1820be0e5c09SChris Mason 		if (path->slots[0] == i)
1821be0e5c09SChris Mason 			push_space += data_size + sizeof(*item);
1822db94535dSChris Mason 
1823db94535dSChris Mason 		this_item_size = btrfs_item_size(right, item);
1824db94535dSChris Mason 		if (this_item_size + sizeof(*item) + push_space > free_space)
1825be0e5c09SChris Mason 			break;
1826db94535dSChris Mason 
1827be0e5c09SChris Mason 		push_items++;
1828db94535dSChris Mason 		push_space += this_item_size + sizeof(*item);
1829be0e5c09SChris Mason 	}
1830db94535dSChris Mason 
1831db94535dSChris Mason 	if (right->map_token) {
1832db94535dSChris Mason 		unmap_extent_buffer(right, right->map_token, KM_USER1);
1833db94535dSChris Mason 		right->map_token = NULL;
1834db94535dSChris Mason 	}
1835db94535dSChris Mason 
1836be0e5c09SChris Mason 	if (push_items == 0) {
18375f39d397SChris Mason 		free_extent_buffer(left);
1838be0e5c09SChris Mason 		return 1;
1839be0e5c09SChris Mason 	}
184034a38218SChris Mason 	if (!empty && push_items == btrfs_header_nritems(right))
1841a429e513SChris Mason 		WARN_ON(1);
18425f39d397SChris Mason 
1843be0e5c09SChris Mason 	/* push data from right to left */
18445f39d397SChris Mason 	copy_extent_buffer(left, right,
18455f39d397SChris Mason 			   btrfs_item_nr_offset(btrfs_header_nritems(left)),
18465f39d397SChris Mason 			   btrfs_item_nr_offset(0),
18475f39d397SChris Mason 			   push_items * sizeof(struct btrfs_item));
18485f39d397SChris Mason 
1849123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root) -
18505f39d397SChris Mason 		     btrfs_item_offset_nr(right, push_items -1);
18515f39d397SChris Mason 
18525f39d397SChris Mason 	copy_extent_buffer(left, right, btrfs_leaf_data(left) +
1853d6025579SChris Mason 		     leaf_data_end(root, left) - push_space,
1854123abc88SChris Mason 		     btrfs_leaf_data(right) +
18555f39d397SChris Mason 		     btrfs_item_offset_nr(right, push_items - 1),
1856be0e5c09SChris Mason 		     push_space);
18575f39d397SChris Mason 	old_left_nritems = btrfs_header_nritems(left);
1858eb60ceacSChris Mason 	BUG_ON(old_left_nritems < 0);
1859eb60ceacSChris Mason 
1860db94535dSChris Mason 	old_left_item_size = btrfs_item_offset_nr(left, old_left_nritems - 1);
1861be0e5c09SChris Mason 	for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
18625f39d397SChris Mason 		u32 ioff;
1863db94535dSChris Mason 
18645f39d397SChris Mason 		item = btrfs_item_nr(left, i);
1865db94535dSChris Mason 		if (!left->map_token) {
1866db94535dSChris Mason 			map_extent_buffer(left, (unsigned long)item,
1867db94535dSChris Mason 					sizeof(struct btrfs_item),
1868db94535dSChris Mason 					&left->map_token, &left->kaddr,
1869db94535dSChris Mason 					&left->map_start, &left->map_len,
1870db94535dSChris Mason 					KM_USER1);
1871db94535dSChris Mason 		}
1872db94535dSChris Mason 
18735f39d397SChris Mason 		ioff = btrfs_item_offset(left, item);
18745f39d397SChris Mason 		btrfs_set_item_offset(left, item,
1875db94535dSChris Mason 		      ioff - (BTRFS_LEAF_DATA_SIZE(root) - old_left_item_size));
1876be0e5c09SChris Mason 	}
18775f39d397SChris Mason 	btrfs_set_header_nritems(left, old_left_nritems + push_items);
1878db94535dSChris Mason 	if (left->map_token) {
1879db94535dSChris Mason 		unmap_extent_buffer(left, left->map_token, KM_USER1);
1880db94535dSChris Mason 		left->map_token = NULL;
1881db94535dSChris Mason 	}
1882be0e5c09SChris Mason 
1883be0e5c09SChris Mason 	/* fixup right node */
188434a38218SChris Mason 	if (push_items > right_nritems) {
188534a38218SChris Mason 		printk("push items %d nr %u\n", push_items, right_nritems);
188634a38218SChris Mason 		WARN_ON(1);
188734a38218SChris Mason 	}
188834a38218SChris Mason 
188934a38218SChris Mason 	if (push_items < right_nritems) {
18905f39d397SChris Mason 		push_space = btrfs_item_offset_nr(right, push_items - 1) -
1891123abc88SChris Mason 						  leaf_data_end(root, right);
18925f39d397SChris Mason 		memmove_extent_buffer(right, btrfs_leaf_data(right) +
1893d6025579SChris Mason 				      BTRFS_LEAF_DATA_SIZE(root) - push_space,
1894d6025579SChris Mason 				      btrfs_leaf_data(right) +
1895123abc88SChris Mason 				      leaf_data_end(root, right), push_space);
18965f39d397SChris Mason 
18975f39d397SChris Mason 		memmove_extent_buffer(right, btrfs_item_nr_offset(0),
18985f39d397SChris Mason 			      btrfs_item_nr_offset(push_items),
18995f39d397SChris Mason 			     (btrfs_header_nritems(right) - push_items) *
19000783fcfcSChris Mason 			     sizeof(struct btrfs_item));
190134a38218SChris Mason 	}
1902eef1c494SYan 	right_nritems -= push_items;
1903eef1c494SYan 	btrfs_set_header_nritems(right, right_nritems);
1904123abc88SChris Mason 	push_space = BTRFS_LEAF_DATA_SIZE(root);
19055f39d397SChris Mason 	for (i = 0; i < right_nritems; i++) {
19065f39d397SChris Mason 		item = btrfs_item_nr(right, i);
1907db94535dSChris Mason 
1908db94535dSChris Mason 		if (!right->map_token) {
1909db94535dSChris Mason 			map_extent_buffer(right, (unsigned long)item,
1910db94535dSChris Mason 					sizeof(struct btrfs_item),
1911db94535dSChris Mason 					&right->map_token, &right->kaddr,
1912db94535dSChris Mason 					&right->map_start, &right->map_len,
1913db94535dSChris Mason 					KM_USER1);
1914db94535dSChris Mason 		}
1915db94535dSChris Mason 
1916db94535dSChris Mason 		push_space = push_space - btrfs_item_size(right, item);
1917db94535dSChris Mason 		btrfs_set_item_offset(right, item, push_space);
1918db94535dSChris Mason 	}
1919db94535dSChris Mason 	if (right->map_token) {
1920db94535dSChris Mason 		unmap_extent_buffer(right, right->map_token, KM_USER1);
1921db94535dSChris Mason 		right->map_token = NULL;
1922be0e5c09SChris Mason 	}
1923eb60ceacSChris Mason 
19245f39d397SChris Mason 	btrfs_mark_buffer_dirty(left);
192534a38218SChris Mason 	if (right_nritems)
19265f39d397SChris Mason 		btrfs_mark_buffer_dirty(right);
1927098f59c2SChris Mason 
19285f39d397SChris Mason 	btrfs_item_key(right, &disk_key, 0);
19295f39d397SChris Mason 	wret = fixup_low_keys(trans, root, path, &disk_key, 1);
1930aa5d6bedSChris Mason 	if (wret)
1931aa5d6bedSChris Mason 		ret = wret;
1932be0e5c09SChris Mason 
1933be0e5c09SChris Mason 	/* then fixup the leaf pointer in the path */
1934be0e5c09SChris Mason 	if (path->slots[0] < push_items) {
1935be0e5c09SChris Mason 		path->slots[0] += old_left_nritems;
19365f39d397SChris Mason 		free_extent_buffer(path->nodes[0]);
19375f39d397SChris Mason 		path->nodes[0] = left;
1938be0e5c09SChris Mason 		path->slots[1] -= 1;
1939be0e5c09SChris Mason 	} else {
19405f39d397SChris Mason 		free_extent_buffer(left);
1941be0e5c09SChris Mason 		path->slots[0] -= push_items;
1942be0e5c09SChris Mason 	}
1943eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
1944aa5d6bedSChris Mason 	return ret;
1945be0e5c09SChris Mason }
1946be0e5c09SChris Mason 
194774123bd7SChris Mason /*
194874123bd7SChris Mason  * split the path's leaf in two, making sure there is at least data_size
194974123bd7SChris Mason  * available for the resulting leaf level of the path.
1950aa5d6bedSChris Mason  *
1951aa5d6bedSChris Mason  * returns 0 if all went well and < 0 on failure.
195274123bd7SChris Mason  */
1953e089f05cSChris Mason static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1954d4dbff95SChris Mason 		      *root, struct btrfs_key *ins_key,
1955cc0c5538SChris Mason 		      struct btrfs_path *path, int data_size, int extend)
1956be0e5c09SChris Mason {
19577bb86316SChris Mason 	u64 root_gen;
19585f39d397SChris Mason 	struct extent_buffer *l;
19597518a238SChris Mason 	u32 nritems;
1960eb60ceacSChris Mason 	int mid;
1961eb60ceacSChris Mason 	int slot;
19625f39d397SChris Mason 	struct extent_buffer *right;
19630783fcfcSChris Mason 	int space_needed = data_size + sizeof(struct btrfs_item);
1964be0e5c09SChris Mason 	int data_copy_size;
1965be0e5c09SChris Mason 	int rt_data_off;
1966be0e5c09SChris Mason 	int i;
1967d4dbff95SChris Mason 	int ret = 0;
1968aa5d6bedSChris Mason 	int wret;
1969cc0c5538SChris Mason 	int double_split;
1970cc0c5538SChris Mason 	int num_doubles = 0;
1971d4dbff95SChris Mason 	struct btrfs_disk_key disk_key;
1972be0e5c09SChris Mason 
1973cc0c5538SChris Mason 	if (extend)
1974cc0c5538SChris Mason 		space_needed = data_size;
1975cc0c5538SChris Mason 
19767bb86316SChris Mason 	if (root->ref_cows)
19777bb86316SChris Mason 		root_gen = trans->transid;
19787bb86316SChris Mason 	else
19797bb86316SChris Mason 		root_gen = 0;
19807bb86316SChris Mason 
198140689478SChris Mason 	/* first try to make some room by pushing left and right */
19823685f791SChris Mason 	if (ins_key->type != BTRFS_DIR_ITEM_KEY) {
198334a38218SChris Mason 		wret = push_leaf_right(trans, root, path, data_size, 0);
19843326d1b0SChris Mason 		if (wret < 0) {
1985eaee50e8SChris Mason 			return wret;
19863326d1b0SChris Mason 		}
1987eaee50e8SChris Mason 		if (wret) {
198834a38218SChris Mason 			wret = push_leaf_left(trans, root, path, data_size, 0);
1989eaee50e8SChris Mason 			if (wret < 0)
1990eaee50e8SChris Mason 				return wret;
1991eaee50e8SChris Mason 		}
19925f39d397SChris Mason 		l = path->nodes[0];
1993aa5d6bedSChris Mason 
1994aa5d6bedSChris Mason 		/* did the pushes work? */
1995cc0c5538SChris Mason 		if (btrfs_leaf_free_space(root, l) >= space_needed)
1996be0e5c09SChris Mason 			return 0;
19973326d1b0SChris Mason 	}
1998aa5d6bedSChris Mason 
19995c680ed6SChris Mason 	if (!path->nodes[1]) {
2000e089f05cSChris Mason 		ret = insert_new_root(trans, root, path, 1);
20015c680ed6SChris Mason 		if (ret)
20025c680ed6SChris Mason 			return ret;
20035c680ed6SChris Mason 	}
2004cc0c5538SChris Mason again:
2005cc0c5538SChris Mason 	double_split = 0;
2006cc0c5538SChris Mason 	l = path->nodes[0];
2007eb60ceacSChris Mason 	slot = path->slots[0];
20085f39d397SChris Mason 	nritems = btrfs_header_nritems(l);
2009eb60ceacSChris Mason 	mid = (nritems + 1)/ 2;
201054aa1f4dSChris Mason 
20117bb86316SChris Mason 	btrfs_item_key(l, &disk_key, 0);
20127bb86316SChris Mason 
20137bb86316SChris Mason 	right = __btrfs_alloc_free_block(trans, root, root->leafsize,
20147bb86316SChris Mason 					 root->root_key.objectid,
20157bb86316SChris Mason 					 root_gen, disk_key.objectid, 0,
2016db94535dSChris Mason 					 l->start, 0);
20175f39d397SChris Mason 	if (IS_ERR(right))
20185f39d397SChris Mason 		return PTR_ERR(right);
201954aa1f4dSChris Mason 
20205f39d397SChris Mason 	memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header));
2021db94535dSChris Mason 	btrfs_set_header_bytenr(right, right->start);
20225f39d397SChris Mason 	btrfs_set_header_generation(right, trans->transid);
20235f39d397SChris Mason 	btrfs_set_header_owner(right, root->root_key.objectid);
20245f39d397SChris Mason 	btrfs_set_header_level(right, 0);
20255f39d397SChris Mason 	write_extent_buffer(right, root->fs_info->fsid,
20265f39d397SChris Mason 			    (unsigned long)btrfs_header_fsid(right),
20275f39d397SChris Mason 			    BTRFS_FSID_SIZE);
2028d4dbff95SChris Mason 	if (mid <= slot) {
2029d4dbff95SChris Mason 		if (nritems == 1 ||
2030d4dbff95SChris Mason 		    leaf_space_used(l, mid, nritems - mid) + space_needed >
2031d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
2032d4dbff95SChris Mason 			if (slot >= nritems) {
2033d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
20345f39d397SChris Mason 				btrfs_set_header_nritems(right, 0);
2035d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
2036db94535dSChris Mason 						  &disk_key, right->start,
2037d4dbff95SChris Mason 						  path->slots[1] + 1, 1);
2038d4dbff95SChris Mason 				if (wret)
2039d4dbff95SChris Mason 					ret = wret;
20405f39d397SChris Mason 				free_extent_buffer(path->nodes[0]);
20415f39d397SChris Mason 				path->nodes[0] = right;
2042d4dbff95SChris Mason 				path->slots[0] = 0;
2043d4dbff95SChris Mason 				path->slots[1] += 1;
2044d4dbff95SChris Mason 				return ret;
2045d4dbff95SChris Mason 			}
2046d4dbff95SChris Mason 			mid = slot;
20473326d1b0SChris Mason 			if (mid != nritems &&
20483326d1b0SChris Mason 			    leaf_space_used(l, mid, nritems - mid) +
20493326d1b0SChris Mason 			    space_needed > BTRFS_LEAF_DATA_SIZE(root)) {
2050d4dbff95SChris Mason 				double_split = 1;
2051d4dbff95SChris Mason 			}
20523326d1b0SChris Mason 		}
2053d4dbff95SChris Mason 	} else {
2054d4dbff95SChris Mason 		if (leaf_space_used(l, 0, mid + 1) + space_needed >
2055d4dbff95SChris Mason 			BTRFS_LEAF_DATA_SIZE(root)) {
2056cc0c5538SChris Mason 			if (!extend && slot == 0) {
2057d4dbff95SChris Mason 				btrfs_cpu_key_to_disk(&disk_key, ins_key);
20585f39d397SChris Mason 				btrfs_set_header_nritems(right, 0);
2059d4dbff95SChris Mason 				wret = insert_ptr(trans, root, path,
2060d4dbff95SChris Mason 						  &disk_key,
2061db94535dSChris Mason 						  right->start,
2062098f59c2SChris Mason 						  path->slots[1], 1);
2063d4dbff95SChris Mason 				if (wret)
2064d4dbff95SChris Mason 					ret = wret;
20655f39d397SChris Mason 				free_extent_buffer(path->nodes[0]);
20665f39d397SChris Mason 				path->nodes[0] = right;
2067d4dbff95SChris Mason 				path->slots[0] = 0;
2068a429e513SChris Mason 				if (path->slots[1] == 0) {
2069a429e513SChris Mason 					wret = fixup_low_keys(trans, root,
2070a429e513SChris Mason 					           path, &disk_key, 1);
2071a429e513SChris Mason 					if (wret)
2072a429e513SChris Mason 						ret = wret;
2073a429e513SChris Mason 				}
2074d4dbff95SChris Mason 				return ret;
2075cc0c5538SChris Mason 			} else if (extend && slot == 0) {
2076cc0c5538SChris Mason 				mid = 1;
2077cc0c5538SChris Mason 			} else {
2078d4dbff95SChris Mason 				mid = slot;
20795ee78ac7SChris Mason 				if (mid != nritems &&
20805ee78ac7SChris Mason 				    leaf_space_used(l, mid, nritems - mid) +
20815ee78ac7SChris Mason 				    space_needed > BTRFS_LEAF_DATA_SIZE(root)) {
2082d4dbff95SChris Mason 					double_split = 1;
2083d4dbff95SChris Mason 				}
2084d4dbff95SChris Mason 			}
20855ee78ac7SChris Mason 		}
2086cc0c5538SChris Mason 	}
20875f39d397SChris Mason 	nritems = nritems - mid;
20885f39d397SChris Mason 	btrfs_set_header_nritems(right, nritems);
20895f39d397SChris Mason 	data_copy_size = btrfs_item_end_nr(l, mid) - leaf_data_end(root, l);
20905f39d397SChris Mason 
20915f39d397SChris Mason 	copy_extent_buffer(right, l, btrfs_item_nr_offset(0),
20925f39d397SChris Mason 			   btrfs_item_nr_offset(mid),
20935f39d397SChris Mason 			   nritems * sizeof(struct btrfs_item));
20945f39d397SChris Mason 
20955f39d397SChris Mason 	copy_extent_buffer(right, l,
2096d6025579SChris Mason 		     btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
2097123abc88SChris Mason 		     data_copy_size, btrfs_leaf_data(l) +
2098123abc88SChris Mason 		     leaf_data_end(root, l), data_copy_size);
209974123bd7SChris Mason 
21005f39d397SChris Mason 	rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
21015f39d397SChris Mason 		      btrfs_item_end_nr(l, mid);
21025f39d397SChris Mason 
21035f39d397SChris Mason 	for (i = 0; i < nritems; i++) {
21045f39d397SChris Mason 		struct btrfs_item *item = btrfs_item_nr(right, i);
2105db94535dSChris Mason 		u32 ioff;
2106db94535dSChris Mason 
2107db94535dSChris Mason 		if (!right->map_token) {
2108db94535dSChris Mason 			map_extent_buffer(right, (unsigned long)item,
2109db94535dSChris Mason 					sizeof(struct btrfs_item),
2110db94535dSChris Mason 					&right->map_token, &right->kaddr,
2111db94535dSChris Mason 					&right->map_start, &right->map_len,
2112db94535dSChris Mason 					KM_USER1);
2113db94535dSChris Mason 		}
2114db94535dSChris Mason 
2115db94535dSChris Mason 		ioff = btrfs_item_offset(right, item);
21165f39d397SChris Mason 		btrfs_set_item_offset(right, item, ioff + rt_data_off);
21170783fcfcSChris Mason 	}
211874123bd7SChris Mason 
2119db94535dSChris Mason 	if (right->map_token) {
2120db94535dSChris Mason 		unmap_extent_buffer(right, right->map_token, KM_USER1);
2121db94535dSChris Mason 		right->map_token = NULL;
2122db94535dSChris Mason 	}
2123db94535dSChris Mason 
21245f39d397SChris Mason 	btrfs_set_header_nritems(l, mid);
2125aa5d6bedSChris Mason 	ret = 0;
21265f39d397SChris Mason 	btrfs_item_key(right, &disk_key, 0);
2127db94535dSChris Mason 	wret = insert_ptr(trans, root, path, &disk_key, right->start,
2128db94535dSChris Mason 			  path->slots[1] + 1, 1);
2129aa5d6bedSChris Mason 	if (wret)
2130aa5d6bedSChris Mason 		ret = wret;
21315f39d397SChris Mason 
21325f39d397SChris Mason 	btrfs_mark_buffer_dirty(right);
21335f39d397SChris Mason 	btrfs_mark_buffer_dirty(l);
2134eb60ceacSChris Mason 	BUG_ON(path->slots[0] != slot);
21355f39d397SChris Mason 
2136be0e5c09SChris Mason 	if (mid <= slot) {
21375f39d397SChris Mason 		free_extent_buffer(path->nodes[0]);
21385f39d397SChris Mason 		path->nodes[0] = right;
2139be0e5c09SChris Mason 		path->slots[0] -= mid;
2140be0e5c09SChris Mason 		path->slots[1] += 1;
2141eb60ceacSChris Mason 	} else
21425f39d397SChris Mason 		free_extent_buffer(right);
21435f39d397SChris Mason 
2144eb60ceacSChris Mason 	BUG_ON(path->slots[0] < 0);
2145d4dbff95SChris Mason 
2146cc0c5538SChris Mason 	if (double_split) {
2147cc0c5538SChris Mason 		BUG_ON(num_doubles != 0);
2148cc0c5538SChris Mason 		num_doubles++;
2149cc0c5538SChris Mason 		goto again;
21503326d1b0SChris Mason 	}
2151be0e5c09SChris Mason 	return ret;
2152be0e5c09SChris Mason }
2153be0e5c09SChris Mason 
2154b18c6685SChris Mason int btrfs_truncate_item(struct btrfs_trans_handle *trans,
2155b18c6685SChris Mason 			struct btrfs_root *root,
2156b18c6685SChris Mason 			struct btrfs_path *path,
2157179e29e4SChris Mason 			u32 new_size, int from_end)
2158b18c6685SChris Mason {
2159b18c6685SChris Mason 	int ret = 0;
2160b18c6685SChris Mason 	int slot;
2161b18c6685SChris Mason 	int slot_orig;
21625f39d397SChris Mason 	struct extent_buffer *leaf;
21635f39d397SChris Mason 	struct btrfs_item *item;
2164b18c6685SChris Mason 	u32 nritems;
2165b18c6685SChris Mason 	unsigned int data_end;
2166b18c6685SChris Mason 	unsigned int old_data_start;
2167b18c6685SChris Mason 	unsigned int old_size;
2168b18c6685SChris Mason 	unsigned int size_diff;
2169b18c6685SChris Mason 	int i;
2170b18c6685SChris Mason 
2171b18c6685SChris Mason 	slot_orig = path->slots[0];
21725f39d397SChris Mason 	leaf = path->nodes[0];
2173179e29e4SChris Mason 	slot = path->slots[0];
2174179e29e4SChris Mason 
2175179e29e4SChris Mason 	old_size = btrfs_item_size_nr(leaf, slot);
2176179e29e4SChris Mason 	if (old_size == new_size)
2177179e29e4SChris Mason 		return 0;
2178b18c6685SChris Mason 
21795f39d397SChris Mason 	nritems = btrfs_header_nritems(leaf);
2180b18c6685SChris Mason 	data_end = leaf_data_end(root, leaf);
2181b18c6685SChris Mason 
21825f39d397SChris Mason 	old_data_start = btrfs_item_offset_nr(leaf, slot);
2183179e29e4SChris Mason 
2184b18c6685SChris Mason 	size_diff = old_size - new_size;
2185b18c6685SChris Mason 
2186b18c6685SChris Mason 	BUG_ON(slot < 0);
2187b18c6685SChris Mason 	BUG_ON(slot >= nritems);
2188b18c6685SChris Mason 
2189b18c6685SChris Mason 	/*
2190b18c6685SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
2191b18c6685SChris Mason 	 */
2192b18c6685SChris Mason 	/* first correct the data pointers */
2193b18c6685SChris Mason 	for (i = slot; i < nritems; i++) {
21945f39d397SChris Mason 		u32 ioff;
21955f39d397SChris Mason 		item = btrfs_item_nr(leaf, i);
2196db94535dSChris Mason 
2197db94535dSChris Mason 		if (!leaf->map_token) {
2198db94535dSChris Mason 			map_extent_buffer(leaf, (unsigned long)item,
2199db94535dSChris Mason 					sizeof(struct btrfs_item),
2200db94535dSChris Mason 					&leaf->map_token, &leaf->kaddr,
2201db94535dSChris Mason 					&leaf->map_start, &leaf->map_len,
2202db94535dSChris Mason 					KM_USER1);
2203db94535dSChris Mason 		}
2204db94535dSChris Mason 
22055f39d397SChris Mason 		ioff = btrfs_item_offset(leaf, item);
22065f39d397SChris Mason 		btrfs_set_item_offset(leaf, item, ioff + size_diff);
2207b18c6685SChris Mason 	}
2208db94535dSChris Mason 
2209db94535dSChris Mason 	if (leaf->map_token) {
2210db94535dSChris Mason 		unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
2211db94535dSChris Mason 		leaf->map_token = NULL;
2212db94535dSChris Mason 	}
2213db94535dSChris Mason 
2214b18c6685SChris Mason 	/* shift the data */
2215179e29e4SChris Mason 	if (from_end) {
22165f39d397SChris Mason 		memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
2217b18c6685SChris Mason 			      data_end + size_diff, btrfs_leaf_data(leaf) +
2218b18c6685SChris Mason 			      data_end, old_data_start + new_size - data_end);
2219179e29e4SChris Mason 	} else {
2220179e29e4SChris Mason 		struct btrfs_disk_key disk_key;
2221179e29e4SChris Mason 		u64 offset;
2222179e29e4SChris Mason 
2223179e29e4SChris Mason 		btrfs_item_key(leaf, &disk_key, slot);
2224179e29e4SChris Mason 
2225179e29e4SChris Mason 		if (btrfs_disk_key_type(&disk_key) == BTRFS_EXTENT_DATA_KEY) {
2226179e29e4SChris Mason 			unsigned long ptr;
2227179e29e4SChris Mason 			struct btrfs_file_extent_item *fi;
2228179e29e4SChris Mason 
2229179e29e4SChris Mason 			fi = btrfs_item_ptr(leaf, slot,
2230179e29e4SChris Mason 					    struct btrfs_file_extent_item);
2231179e29e4SChris Mason 			fi = (struct btrfs_file_extent_item *)(
2232179e29e4SChris Mason 			     (unsigned long)fi - size_diff);
2233179e29e4SChris Mason 
2234179e29e4SChris Mason 			if (btrfs_file_extent_type(leaf, fi) ==
2235179e29e4SChris Mason 			    BTRFS_FILE_EXTENT_INLINE) {
2236179e29e4SChris Mason 				ptr = btrfs_item_ptr_offset(leaf, slot);
2237179e29e4SChris Mason 				memmove_extent_buffer(leaf, ptr,
2238179e29e4SChris Mason 				        (unsigned long)fi,
2239179e29e4SChris Mason 				        offsetof(struct btrfs_file_extent_item,
2240179e29e4SChris Mason 						 disk_bytenr));
2241179e29e4SChris Mason 			}
2242179e29e4SChris Mason 		}
2243179e29e4SChris Mason 
2244179e29e4SChris Mason 		memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
2245179e29e4SChris Mason 			      data_end + size_diff, btrfs_leaf_data(leaf) +
2246179e29e4SChris Mason 			      data_end, old_data_start - data_end);
2247179e29e4SChris Mason 
2248179e29e4SChris Mason 		offset = btrfs_disk_key_offset(&disk_key);
2249179e29e4SChris Mason 		btrfs_set_disk_key_offset(&disk_key, offset + size_diff);
2250179e29e4SChris Mason 		btrfs_set_item_key(leaf, &disk_key, slot);
2251179e29e4SChris Mason 		if (slot == 0)
2252179e29e4SChris Mason 			fixup_low_keys(trans, root, path, &disk_key, 1);
2253179e29e4SChris Mason 	}
22545f39d397SChris Mason 
22555f39d397SChris Mason 	item = btrfs_item_nr(leaf, slot);
22565f39d397SChris Mason 	btrfs_set_item_size(leaf, item, new_size);
22575f39d397SChris Mason 	btrfs_mark_buffer_dirty(leaf);
2258b18c6685SChris Mason 
2259b18c6685SChris Mason 	ret = 0;
22605f39d397SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0) {
22615f39d397SChris Mason 		btrfs_print_leaf(root, leaf);
2262b18c6685SChris Mason 		BUG();
22635f39d397SChris Mason 	}
2264b18c6685SChris Mason 	return ret;
2265b18c6685SChris Mason }
2266b18c6685SChris Mason 
22675f39d397SChris Mason int btrfs_extend_item(struct btrfs_trans_handle *trans,
22685f39d397SChris Mason 		      struct btrfs_root *root, struct btrfs_path *path,
22695f39d397SChris Mason 		      u32 data_size)
22706567e837SChris Mason {
22716567e837SChris Mason 	int ret = 0;
22726567e837SChris Mason 	int slot;
22736567e837SChris Mason 	int slot_orig;
22745f39d397SChris Mason 	struct extent_buffer *leaf;
22755f39d397SChris Mason 	struct btrfs_item *item;
22766567e837SChris Mason 	u32 nritems;
22776567e837SChris Mason 	unsigned int data_end;
22786567e837SChris Mason 	unsigned int old_data;
22796567e837SChris Mason 	unsigned int old_size;
22806567e837SChris Mason 	int i;
22816567e837SChris Mason 
22826567e837SChris Mason 	slot_orig = path->slots[0];
22835f39d397SChris Mason 	leaf = path->nodes[0];
22846567e837SChris Mason 
22855f39d397SChris Mason 	nritems = btrfs_header_nritems(leaf);
22866567e837SChris Mason 	data_end = leaf_data_end(root, leaf);
22876567e837SChris Mason 
22885f39d397SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < data_size) {
22895f39d397SChris Mason 		btrfs_print_leaf(root, leaf);
22906567e837SChris Mason 		BUG();
22915f39d397SChris Mason 	}
22926567e837SChris Mason 	slot = path->slots[0];
22935f39d397SChris Mason 	old_data = btrfs_item_end_nr(leaf, slot);
22946567e837SChris Mason 
22956567e837SChris Mason 	BUG_ON(slot < 0);
22963326d1b0SChris Mason 	if (slot >= nritems) {
22973326d1b0SChris Mason 		btrfs_print_leaf(root, leaf);
22983326d1b0SChris Mason 		printk("slot %d too large, nritems %d\n", slot, nritems);
22993326d1b0SChris Mason 		BUG_ON(1);
23003326d1b0SChris Mason 	}
23016567e837SChris Mason 
23026567e837SChris Mason 	/*
23036567e837SChris Mason 	 * item0..itemN ... dataN.offset..dataN.size .. data0.size
23046567e837SChris Mason 	 */
23056567e837SChris Mason 	/* first correct the data pointers */
23066567e837SChris Mason 	for (i = slot; i < nritems; i++) {
23075f39d397SChris Mason 		u32 ioff;
23085f39d397SChris Mason 		item = btrfs_item_nr(leaf, i);
2309db94535dSChris Mason 
2310db94535dSChris Mason 		if (!leaf->map_token) {
2311db94535dSChris Mason 			map_extent_buffer(leaf, (unsigned long)item,
2312db94535dSChris Mason 					sizeof(struct btrfs_item),
2313db94535dSChris Mason 					&leaf->map_token, &leaf->kaddr,
2314db94535dSChris Mason 					&leaf->map_start, &leaf->map_len,
2315db94535dSChris Mason 					KM_USER1);
2316db94535dSChris Mason 		}
23175f39d397SChris Mason 		ioff = btrfs_item_offset(leaf, item);
23185f39d397SChris Mason 		btrfs_set_item_offset(leaf, item, ioff - data_size);
23196567e837SChris Mason 	}
23205f39d397SChris Mason 
2321db94535dSChris Mason 	if (leaf->map_token) {
2322db94535dSChris Mason 		unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
2323db94535dSChris Mason 		leaf->map_token = NULL;
2324db94535dSChris Mason 	}
2325db94535dSChris Mason 
23266567e837SChris Mason 	/* shift the data */
23275f39d397SChris Mason 	memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
23286567e837SChris Mason 		      data_end - data_size, btrfs_leaf_data(leaf) +
23296567e837SChris Mason 		      data_end, old_data - data_end);
23305f39d397SChris Mason 
23316567e837SChris Mason 	data_end = old_data;
23325f39d397SChris Mason 	old_size = btrfs_item_size_nr(leaf, slot);
23335f39d397SChris Mason 	item = btrfs_item_nr(leaf, slot);
23345f39d397SChris Mason 	btrfs_set_item_size(leaf, item, old_size + data_size);
23355f39d397SChris Mason 	btrfs_mark_buffer_dirty(leaf);
23366567e837SChris Mason 
23376567e837SChris Mason 	ret = 0;
23385f39d397SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0) {
23395f39d397SChris Mason 		btrfs_print_leaf(root, leaf);
23406567e837SChris Mason 		BUG();
23415f39d397SChris Mason 	}
23426567e837SChris Mason 	return ret;
23436567e837SChris Mason }
23446567e837SChris Mason 
234574123bd7SChris Mason /*
234674123bd7SChris Mason  * Given a key and some data, insert an item into the tree.
234774123bd7SChris Mason  * This does all the path init required, making room in the tree if needed.
234874123bd7SChris Mason  */
23499c58309dSChris Mason int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
23505f39d397SChris Mason 			    struct btrfs_root *root,
23515f39d397SChris Mason 			    struct btrfs_path *path,
23529c58309dSChris Mason 			    struct btrfs_key *cpu_key, u32 *data_size,
23539c58309dSChris Mason 			    int nr)
2354be0e5c09SChris Mason {
23555f39d397SChris Mason 	struct extent_buffer *leaf;
23565f39d397SChris Mason 	struct btrfs_item *item;
2357aa5d6bedSChris Mason 	int ret = 0;
2358be0e5c09SChris Mason 	int slot;
2359eb60ceacSChris Mason 	int slot_orig;
23609c58309dSChris Mason 	int i;
23617518a238SChris Mason 	u32 nritems;
23629c58309dSChris Mason 	u32 total_size = 0;
23639c58309dSChris Mason 	u32 total_data = 0;
2364be0e5c09SChris Mason 	unsigned int data_end;
2365e2fa7227SChris Mason 	struct btrfs_disk_key disk_key;
2366e2fa7227SChris Mason 
23679c58309dSChris Mason 	for (i = 0; i < nr; i++) {
23689c58309dSChris Mason 		total_data += data_size[i];
23699c58309dSChris Mason 	}
2370be0e5c09SChris Mason 
237174123bd7SChris Mason 	/* create a root if there isn't one */
23725c680ed6SChris Mason 	if (!root->node)
2373cfaa7295SChris Mason 		BUG();
23745f39d397SChris Mason 
23759c58309dSChris Mason 	total_size = total_data + (nr - 1) * sizeof(struct btrfs_item);
23769c58309dSChris Mason 	ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1);
2377eb60ceacSChris Mason 	if (ret == 0) {
2378f0930a37SChris Mason 		return -EEXIST;
2379aa5d6bedSChris Mason 	}
2380ed2ff2cbSChris Mason 	if (ret < 0)
2381ed2ff2cbSChris Mason 		goto out;
2382be0e5c09SChris Mason 
238362e2749eSChris Mason 	slot_orig = path->slots[0];
23845f39d397SChris Mason 	leaf = path->nodes[0];
238574123bd7SChris Mason 
23865f39d397SChris Mason 	nritems = btrfs_header_nritems(leaf);
2387123abc88SChris Mason 	data_end = leaf_data_end(root, leaf);
2388eb60ceacSChris Mason 
2389123abc88SChris Mason 	if (btrfs_leaf_free_space(root, leaf) <
23909c58309dSChris Mason 	    sizeof(struct btrfs_item) + total_size) {
23913326d1b0SChris Mason 		btrfs_print_leaf(root, leaf);
23923326d1b0SChris Mason 		printk("not enough freespace need %u have %d\n",
23939c58309dSChris Mason 		       total_size, btrfs_leaf_free_space(root, leaf));
2394be0e5c09SChris Mason 		BUG();
2395d4dbff95SChris Mason 	}
23965f39d397SChris Mason 
239762e2749eSChris Mason 	slot = path->slots[0];
2398eb60ceacSChris Mason 	BUG_ON(slot < 0);
23995f39d397SChris Mason 
2400be0e5c09SChris Mason 	if (slot != nritems) {
2401be0e5c09SChris Mason 		int i;
24025f39d397SChris Mason 		unsigned int old_data = btrfs_item_end_nr(leaf, slot);
2403be0e5c09SChris Mason 
24045f39d397SChris Mason 		if (old_data < data_end) {
24055f39d397SChris Mason 			btrfs_print_leaf(root, leaf);
24065f39d397SChris Mason 			printk("slot %d old_data %d data_end %d\n",
24075f39d397SChris Mason 			       slot, old_data, data_end);
24085f39d397SChris Mason 			BUG_ON(1);
24095f39d397SChris Mason 		}
2410be0e5c09SChris Mason 		/*
2411be0e5c09SChris Mason 		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
2412be0e5c09SChris Mason 		 */
2413be0e5c09SChris Mason 		/* first correct the data pointers */
2414db94535dSChris Mason 		WARN_ON(leaf->map_token);
24150783fcfcSChris Mason 		for (i = slot; i < nritems; i++) {
24165f39d397SChris Mason 			u32 ioff;
2417db94535dSChris Mason 
24185f39d397SChris Mason 			item = btrfs_item_nr(leaf, i);
2419db94535dSChris Mason 			if (!leaf->map_token) {
2420db94535dSChris Mason 				map_extent_buffer(leaf, (unsigned long)item,
2421db94535dSChris Mason 					sizeof(struct btrfs_item),
2422db94535dSChris Mason 					&leaf->map_token, &leaf->kaddr,
2423db94535dSChris Mason 					&leaf->map_start, &leaf->map_len,
2424db94535dSChris Mason 					KM_USER1);
2425db94535dSChris Mason 			}
2426db94535dSChris Mason 
24275f39d397SChris Mason 			ioff = btrfs_item_offset(leaf, item);
24289c58309dSChris Mason 			btrfs_set_item_offset(leaf, item, ioff - total_data);
24290783fcfcSChris Mason 		}
2430db94535dSChris Mason 		if (leaf->map_token) {
2431db94535dSChris Mason 			unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
2432db94535dSChris Mason 			leaf->map_token = NULL;
2433db94535dSChris Mason 		}
2434be0e5c09SChris Mason 
2435be0e5c09SChris Mason 		/* shift the items */
24369c58309dSChris Mason 		memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr),
24375f39d397SChris Mason 			      btrfs_item_nr_offset(slot),
24380783fcfcSChris Mason 			      (nritems - slot) * sizeof(struct btrfs_item));
2439be0e5c09SChris Mason 
2440be0e5c09SChris Mason 		/* shift the data */
24415f39d397SChris Mason 		memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
24429c58309dSChris Mason 			      data_end - total_data, btrfs_leaf_data(leaf) +
2443be0e5c09SChris Mason 			      data_end, old_data - data_end);
2444be0e5c09SChris Mason 		data_end = old_data;
2445be0e5c09SChris Mason 	}
24465f39d397SChris Mason 
244762e2749eSChris Mason 	/* setup the item for the new data */
24489c58309dSChris Mason 	for (i = 0; i < nr; i++) {
24499c58309dSChris Mason 		btrfs_cpu_key_to_disk(&disk_key, cpu_key + i);
24509c58309dSChris Mason 		btrfs_set_item_key(leaf, &disk_key, slot + i);
24519c58309dSChris Mason 		item = btrfs_item_nr(leaf, slot + i);
24529c58309dSChris Mason 		btrfs_set_item_offset(leaf, item, data_end - data_size[i]);
24539c58309dSChris Mason 		data_end -= data_size[i];
24549c58309dSChris Mason 		btrfs_set_item_size(leaf, item, data_size[i]);
24559c58309dSChris Mason 	}
24569c58309dSChris Mason 	btrfs_set_header_nritems(leaf, nritems + nr);
24575f39d397SChris Mason 	btrfs_mark_buffer_dirty(leaf);
2458aa5d6bedSChris Mason 
2459aa5d6bedSChris Mason 	ret = 0;
24605a01a2e3SChris Mason 	if (slot == 0) {
24615a01a2e3SChris Mason 		btrfs_cpu_key_to_disk(&disk_key, cpu_key);
2462e089f05cSChris Mason 		ret = fixup_low_keys(trans, root, path, &disk_key, 1);
24635a01a2e3SChris Mason 	}
2464aa5d6bedSChris Mason 
24655f39d397SChris Mason 	if (btrfs_leaf_free_space(root, leaf) < 0) {
24665f39d397SChris Mason 		btrfs_print_leaf(root, leaf);
2467be0e5c09SChris Mason 		BUG();
24685f39d397SChris Mason 	}
24695a01a2e3SChris Mason 
2470ed2ff2cbSChris Mason out:
247162e2749eSChris Mason 	return ret;
247262e2749eSChris Mason }
247362e2749eSChris Mason 
247462e2749eSChris Mason /*
247562e2749eSChris Mason  * Given a key and some data, insert an item into the tree.
247662e2749eSChris Mason  * This does all the path init required, making room in the tree if needed.
247762e2749eSChris Mason  */
2478e089f05cSChris Mason int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
2479e089f05cSChris Mason 		      *root, struct btrfs_key *cpu_key, void *data, u32
2480e089f05cSChris Mason 		      data_size)
248162e2749eSChris Mason {
248262e2749eSChris Mason 	int ret = 0;
24832c90e5d6SChris Mason 	struct btrfs_path *path;
24845f39d397SChris Mason 	struct extent_buffer *leaf;
24855f39d397SChris Mason 	unsigned long ptr;
248662e2749eSChris Mason 
24872c90e5d6SChris Mason 	path = btrfs_alloc_path();
24882c90e5d6SChris Mason 	BUG_ON(!path);
24892c90e5d6SChris Mason 	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
249062e2749eSChris Mason 	if (!ret) {
24915f39d397SChris Mason 		leaf = path->nodes[0];
24925f39d397SChris Mason 		ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
24935f39d397SChris Mason 		write_extent_buffer(leaf, data, ptr, data_size);
24945f39d397SChris Mason 		btrfs_mark_buffer_dirty(leaf);
249562e2749eSChris Mason 	}
24962c90e5d6SChris Mason 	btrfs_free_path(path);
2497aa5d6bedSChris Mason 	return ret;
2498be0e5c09SChris Mason }
2499be0e5c09SChris Mason 
250074123bd7SChris Mason /*
25015de08d7dSChris Mason  * delete the pointer from a given node.
250274123bd7SChris Mason  *
250374123bd7SChris Mason  * If the delete empties a node, the node is removed from the tree,
250474123bd7SChris Mason  * continuing all the way the root if required.  The root is converted into
250574123bd7SChris Mason  * a leaf if all the nodes are emptied.
250674123bd7SChris Mason  */
2507e089f05cSChris Mason static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
2508e089f05cSChris Mason 		   struct btrfs_path *path, int level, int slot)
2509be0e5c09SChris Mason {
25105f39d397SChris Mason 	struct extent_buffer *parent = path->nodes[level];
25117518a238SChris Mason 	u32 nritems;
2512aa5d6bedSChris Mason 	int ret = 0;
2513bb803951SChris Mason 	int wret;
2514be0e5c09SChris Mason 
25155f39d397SChris Mason 	nritems = btrfs_header_nritems(parent);
2516be0e5c09SChris Mason 	if (slot != nritems -1) {
25175f39d397SChris Mason 		memmove_extent_buffer(parent,
25185f39d397SChris Mason 			      btrfs_node_key_ptr_offset(slot),
25195f39d397SChris Mason 			      btrfs_node_key_ptr_offset(slot + 1),
2520d6025579SChris Mason 			      sizeof(struct btrfs_key_ptr) *
2521d6025579SChris Mason 			      (nritems - slot - 1));
2522be0e5c09SChris Mason 	}
25237518a238SChris Mason 	nritems--;
25245f39d397SChris Mason 	btrfs_set_header_nritems(parent, nritems);
25257518a238SChris Mason 	if (nritems == 0 && parent == root->node) {
25265f39d397SChris Mason 		BUG_ON(btrfs_header_level(root->node) != 1);
2527eb60ceacSChris Mason 		/* just turn the root into a leaf and break */
25285f39d397SChris Mason 		btrfs_set_header_level(root->node, 0);
2529bb803951SChris Mason 	} else if (slot == 0) {
25305f39d397SChris Mason 		struct btrfs_disk_key disk_key;
25315f39d397SChris Mason 
25325f39d397SChris Mason 		btrfs_node_key(parent, &disk_key, 0);
25335f39d397SChris Mason 		wret = fixup_low_keys(trans, root, path, &disk_key, level + 1);
25340f70abe2SChris Mason 		if (wret)
25350f70abe2SChris Mason 			ret = wret;
2536be0e5c09SChris Mason 	}
2537d6025579SChris Mason 	btrfs_mark_buffer_dirty(parent);
2538aa5d6bedSChris Mason 	return ret;
2539be0e5c09SChris Mason }
2540be0e5c09SChris Mason 
254174123bd7SChris Mason /*
254274123bd7SChris Mason  * delete the item at the leaf level in path.  If that empties
254374123bd7SChris Mason  * the leaf, remove it from the tree
254474123bd7SChris Mason  */
254585e21bacSChris Mason int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
254685e21bacSChris Mason 		    struct btrfs_path *path, int slot, int nr)
2547be0e5c09SChris Mason {
25485f39d397SChris Mason 	struct extent_buffer *leaf;
25495f39d397SChris Mason 	struct btrfs_item *item;
255085e21bacSChris Mason 	int last_off;
255185e21bacSChris Mason 	int dsize = 0;
2552aa5d6bedSChris Mason 	int ret = 0;
2553aa5d6bedSChris Mason 	int wret;
255485e21bacSChris Mason 	int i;
25557518a238SChris Mason 	u32 nritems;
2556be0e5c09SChris Mason 
25575f39d397SChris Mason 	leaf = path->nodes[0];
255885e21bacSChris Mason 	last_off = btrfs_item_offset_nr(leaf, slot + nr - 1);
255985e21bacSChris Mason 
256085e21bacSChris Mason 	for (i = 0; i < nr; i++)
256185e21bacSChris Mason 		dsize += btrfs_item_size_nr(leaf, slot + i);
256285e21bacSChris Mason 
25635f39d397SChris Mason 	nritems = btrfs_header_nritems(leaf);
2564be0e5c09SChris Mason 
256585e21bacSChris Mason 	if (slot + nr != nritems) {
2566be0e5c09SChris Mason 		int i;
2567123abc88SChris Mason 		int data_end = leaf_data_end(root, leaf);
25685f39d397SChris Mason 
25695f39d397SChris Mason 		memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
2570d6025579SChris Mason 			      data_end + dsize,
2571123abc88SChris Mason 			      btrfs_leaf_data(leaf) + data_end,
257285e21bacSChris Mason 			      last_off - data_end);
25735f39d397SChris Mason 
257485e21bacSChris Mason 		for (i = slot + nr; i < nritems; i++) {
25755f39d397SChris Mason 			u32 ioff;
2576db94535dSChris Mason 
25775f39d397SChris Mason 			item = btrfs_item_nr(leaf, i);
2578db94535dSChris Mason 			if (!leaf->map_token) {
2579db94535dSChris Mason 				map_extent_buffer(leaf, (unsigned long)item,
2580db94535dSChris Mason 					sizeof(struct btrfs_item),
2581db94535dSChris Mason 					&leaf->map_token, &leaf->kaddr,
2582db94535dSChris Mason 					&leaf->map_start, &leaf->map_len,
2583db94535dSChris Mason 					KM_USER1);
2584db94535dSChris Mason 			}
25855f39d397SChris Mason 			ioff = btrfs_item_offset(leaf, item);
25865f39d397SChris Mason 			btrfs_set_item_offset(leaf, item, ioff + dsize);
25870783fcfcSChris Mason 		}
2588db94535dSChris Mason 
2589db94535dSChris Mason 		if (leaf->map_token) {
2590db94535dSChris Mason 			unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
2591db94535dSChris Mason 			leaf->map_token = NULL;
2592db94535dSChris Mason 		}
2593db94535dSChris Mason 
25945f39d397SChris Mason 		memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot),
259585e21bacSChris Mason 			      btrfs_item_nr_offset(slot + nr),
25960783fcfcSChris Mason 			      sizeof(struct btrfs_item) *
259785e21bacSChris Mason 			      (nritems - slot - nr));
2598be0e5c09SChris Mason 	}
259985e21bacSChris Mason 	btrfs_set_header_nritems(leaf, nritems - nr);
260085e21bacSChris Mason 	nritems -= nr;
26015f39d397SChris Mason 
260274123bd7SChris Mason 	/* delete the leaf if we've emptied it */
26037518a238SChris Mason 	if (nritems == 0) {
26045f39d397SChris Mason 		if (leaf == root->node) {
26055f39d397SChris Mason 			btrfs_set_header_level(leaf, 0);
26069a8dd150SChris Mason 		} else {
26077bb86316SChris Mason 			u64 root_gen = btrfs_header_generation(path->nodes[1]);
26085f39d397SChris Mason 			clean_tree_block(trans, root, leaf);
26095f39d397SChris Mason 			wait_on_tree_block_writeback(root, leaf);
2610e089f05cSChris Mason 			wret = del_ptr(trans, root, path, 1, path->slots[1]);
2611aa5d6bedSChris Mason 			if (wret)
2612aa5d6bedSChris Mason 				ret = wret;
2613e089f05cSChris Mason 			wret = btrfs_free_extent(trans, root,
26147bb86316SChris Mason 					 leaf->start, leaf->len,
26157bb86316SChris Mason 					 btrfs_header_owner(path->nodes[1]),
26167bb86316SChris Mason 					 root_gen, 0, 0, 1);
26170f70abe2SChris Mason 			if (wret)
26180f70abe2SChris Mason 				ret = wret;
26199a8dd150SChris Mason 		}
2620be0e5c09SChris Mason 	} else {
26217518a238SChris Mason 		int used = leaf_space_used(leaf, 0, nritems);
2622aa5d6bedSChris Mason 		if (slot == 0) {
26235f39d397SChris Mason 			struct btrfs_disk_key disk_key;
26245f39d397SChris Mason 
26255f39d397SChris Mason 			btrfs_item_key(leaf, &disk_key, 0);
2626e089f05cSChris Mason 			wret = fixup_low_keys(trans, root, path,
26275f39d397SChris Mason 					      &disk_key, 1);
2628aa5d6bedSChris Mason 			if (wret)
2629aa5d6bedSChris Mason 				ret = wret;
2630aa5d6bedSChris Mason 		}
2631aa5d6bedSChris Mason 
263274123bd7SChris Mason 		/* delete the leaf if it is mostly empty */
263385e21bacSChris Mason 		if (used < BTRFS_LEAF_DATA_SIZE(root) / 4) {
2634be0e5c09SChris Mason 			/* push_leaf_left fixes the path.
2635be0e5c09SChris Mason 			 * make sure the path still points to our leaf
2636be0e5c09SChris Mason 			 * for possible call to del_ptr below
2637be0e5c09SChris Mason 			 */
26384920c9acSChris Mason 			slot = path->slots[1];
26395f39d397SChris Mason 			extent_buffer_get(leaf);
26405f39d397SChris Mason 
264185e21bacSChris Mason 			wret = push_leaf_left(trans, root, path, 1, 1);
264254aa1f4dSChris Mason 			if (wret < 0 && wret != -ENOSPC)
2643aa5d6bedSChris Mason 				ret = wret;
26445f39d397SChris Mason 
26455f39d397SChris Mason 			if (path->nodes[0] == leaf &&
26465f39d397SChris Mason 			    btrfs_header_nritems(leaf)) {
264785e21bacSChris Mason 				wret = push_leaf_right(trans, root, path, 1, 1);
264854aa1f4dSChris Mason 				if (wret < 0 && wret != -ENOSPC)
2649aa5d6bedSChris Mason 					ret = wret;
2650aa5d6bedSChris Mason 			}
26515f39d397SChris Mason 
26525f39d397SChris Mason 			if (btrfs_header_nritems(leaf) == 0) {
26537bb86316SChris Mason 				u64 root_gen;
2654db94535dSChris Mason 				u64 bytenr = leaf->start;
2655db94535dSChris Mason 				u32 blocksize = leaf->len;
26565f39d397SChris Mason 
26577bb86316SChris Mason 				root_gen = btrfs_header_generation(
26587bb86316SChris Mason 							   path->nodes[1]);
26597bb86316SChris Mason 
26605f39d397SChris Mason 				clean_tree_block(trans, root, leaf);
26615f39d397SChris Mason 				wait_on_tree_block_writeback(root, leaf);
26625f39d397SChris Mason 
2663e089f05cSChris Mason 				wret = del_ptr(trans, root, path, 1, slot);
2664aa5d6bedSChris Mason 				if (wret)
2665aa5d6bedSChris Mason 					ret = wret;
26665f39d397SChris Mason 
26675f39d397SChris Mason 				free_extent_buffer(leaf);
2668db94535dSChris Mason 				wret = btrfs_free_extent(trans, root, bytenr,
26697bb86316SChris Mason 					     blocksize,
26707bb86316SChris Mason 					     btrfs_header_owner(path->nodes[1]),
26717bb86316SChris Mason 					     root_gen, 0, 0, 1);
26720f70abe2SChris Mason 				if (wret)
26730f70abe2SChris Mason 					ret = wret;
26745de08d7dSChris Mason 			} else {
26755f39d397SChris Mason 				btrfs_mark_buffer_dirty(leaf);
26765f39d397SChris Mason 				free_extent_buffer(leaf);
2677be0e5c09SChris Mason 			}
2678d5719762SChris Mason 		} else {
26795f39d397SChris Mason 			btrfs_mark_buffer_dirty(leaf);
2680be0e5c09SChris Mason 		}
26819a8dd150SChris Mason 	}
2682aa5d6bedSChris Mason 	return ret;
26839a8dd150SChris Mason }
26849a8dd150SChris Mason 
268597571fd0SChris Mason /*
26867bb86316SChris Mason  * walk up the tree as far as required to find the previous leaf.
26877bb86316SChris Mason  * returns 0 if it found something or 1 if there are no lesser leaves.
26887bb86316SChris Mason  * returns < 0 on io errors.
26897bb86316SChris Mason  */
26907bb86316SChris Mason int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
26917bb86316SChris Mason {
26928f662a76SChris Mason 	u64 bytenr;
26937bb86316SChris Mason 	int slot;
26947bb86316SChris Mason 	int level = 1;
26957bb86316SChris Mason 	struct extent_buffer *c;
26967bb86316SChris Mason 	struct extent_buffer *next = NULL;
26977bb86316SChris Mason 
26987bb86316SChris Mason 	while(level < BTRFS_MAX_LEVEL) {
26997bb86316SChris Mason 		if (!path->nodes[level])
27007bb86316SChris Mason 			return 1;
27017bb86316SChris Mason 
27027bb86316SChris Mason 		slot = path->slots[level];
27037bb86316SChris Mason 		c = path->nodes[level];
27047bb86316SChris Mason 		if (slot == 0) {
27057bb86316SChris Mason 			level++;
27067bb86316SChris Mason 			if (level == BTRFS_MAX_LEVEL)
27077bb86316SChris Mason 				return 1;
27087bb86316SChris Mason 			continue;
27097bb86316SChris Mason 		}
27107bb86316SChris Mason 		slot--;
27117bb86316SChris Mason 
27127bb86316SChris Mason 		bytenr = btrfs_node_blockptr(c, slot);
27137bb86316SChris Mason 		if (next)
27147bb86316SChris Mason 			free_extent_buffer(next);
27157bb86316SChris Mason 
27167bb86316SChris Mason 		next = read_tree_block(root, bytenr,
27177bb86316SChris Mason 				       btrfs_level_size(root, level - 1));
27187bb86316SChris Mason 		break;
27197bb86316SChris Mason 	}
27207bb86316SChris Mason 	path->slots[level] = slot;
27217bb86316SChris Mason 	while(1) {
27227bb86316SChris Mason 		level--;
27237bb86316SChris Mason 		c = path->nodes[level];
27247bb86316SChris Mason 		free_extent_buffer(c);
27258f662a76SChris Mason 		slot = btrfs_header_nritems(next);
27268f662a76SChris Mason 		if (slot != 0)
27278f662a76SChris Mason 			slot--;
27287bb86316SChris Mason 		path->nodes[level] = next;
27298f662a76SChris Mason 		path->slots[level] = slot;
27307bb86316SChris Mason 		if (!level)
27317bb86316SChris Mason 			break;
27328f662a76SChris Mason 		next = read_tree_block(root, btrfs_node_blockptr(next, slot),
27337bb86316SChris Mason 				       btrfs_level_size(root, level - 1));
27347bb86316SChris Mason 	}
27357bb86316SChris Mason 	return 0;
27367bb86316SChris Mason }
27377bb86316SChris Mason 
27387bb86316SChris Mason /*
273997571fd0SChris Mason  * walk up the tree as far as required to find the next leaf.
27400f70abe2SChris Mason  * returns 0 if it found something or 1 if there are no greater leaves.
27410f70abe2SChris Mason  * returns < 0 on io errors.
274297571fd0SChris Mason  */
2743234b63a0SChris Mason int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
2744d97e63b6SChris Mason {
2745d97e63b6SChris Mason 	int slot;
2746d97e63b6SChris Mason 	int level = 1;
2747db94535dSChris Mason 	u64 bytenr;
27485f39d397SChris Mason 	struct extent_buffer *c;
27495f39d397SChris Mason 	struct extent_buffer *next = NULL;
2750d97e63b6SChris Mason 
2751234b63a0SChris Mason 	while(level < BTRFS_MAX_LEVEL) {
2752d97e63b6SChris Mason 		if (!path->nodes[level])
27530f70abe2SChris Mason 			return 1;
27545f39d397SChris Mason 
2755d97e63b6SChris Mason 		slot = path->slots[level] + 1;
2756d97e63b6SChris Mason 		c = path->nodes[level];
27575f39d397SChris Mason 		if (slot >= btrfs_header_nritems(c)) {
2758d97e63b6SChris Mason 			level++;
27597bb86316SChris Mason 			if (level == BTRFS_MAX_LEVEL)
27607bb86316SChris Mason 				return 1;
2761d97e63b6SChris Mason 			continue;
2762d97e63b6SChris Mason 		}
27635f39d397SChris Mason 
2764db94535dSChris Mason 		bytenr = btrfs_node_blockptr(c, slot);
2765cfaa7295SChris Mason 		if (next)
27665f39d397SChris Mason 			free_extent_buffer(next);
27675f39d397SChris Mason 
27686702ed49SChris Mason 		if (path->reada)
276901f46658SChris Mason 			reada_for_search(root, path, level, slot, 0);
27705f39d397SChris Mason 
2771db94535dSChris Mason 		next = read_tree_block(root, bytenr,
2772db94535dSChris Mason 				       btrfs_level_size(root, level -1));
2773d97e63b6SChris Mason 		break;
2774d97e63b6SChris Mason 	}
2775d97e63b6SChris Mason 	path->slots[level] = slot;
2776d97e63b6SChris Mason 	while(1) {
2777d97e63b6SChris Mason 		level--;
2778d97e63b6SChris Mason 		c = path->nodes[level];
27795f39d397SChris Mason 		free_extent_buffer(c);
2780d97e63b6SChris Mason 		path->nodes[level] = next;
2781d97e63b6SChris Mason 		path->slots[level] = 0;
2782d97e63b6SChris Mason 		if (!level)
2783d97e63b6SChris Mason 			break;
27846702ed49SChris Mason 		if (path->reada)
278501f46658SChris Mason 			reada_for_search(root, path, level, 0, 0);
2786db94535dSChris Mason 		next = read_tree_block(root, btrfs_node_blockptr(next, 0),
2787db94535dSChris Mason 				       btrfs_level_size(root, level - 1));
2788d97e63b6SChris Mason 	}
2789d97e63b6SChris Mason 	return 0;
2790d97e63b6SChris Mason }
2791*0b86a832SChris Mason 
2792*0b86a832SChris Mason int btrfs_previous_item(struct btrfs_root *root,
2793*0b86a832SChris Mason 			struct btrfs_path *path, u64 min_objectid,
2794*0b86a832SChris Mason 			int type)
2795*0b86a832SChris Mason {
2796*0b86a832SChris Mason 	struct btrfs_key found_key;
2797*0b86a832SChris Mason 	struct extent_buffer *leaf;
2798*0b86a832SChris Mason 	int ret;
2799*0b86a832SChris Mason 
2800*0b86a832SChris Mason 	while(1) {
2801*0b86a832SChris Mason 		if (path->slots[0] == 0) {
2802*0b86a832SChris Mason 			ret = btrfs_prev_leaf(root, path);
2803*0b86a832SChris Mason 			if (ret != 0)
2804*0b86a832SChris Mason 				return ret;
2805*0b86a832SChris Mason 		} else {
2806*0b86a832SChris Mason 			path->slots[0]--;
2807*0b86a832SChris Mason 		}
2808*0b86a832SChris Mason 		leaf = path->nodes[0];
2809*0b86a832SChris Mason 		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
2810*0b86a832SChris Mason 		if (found_key.type == type)
2811*0b86a832SChris Mason 			return 0;
2812*0b86a832SChris Mason 	}
2813*0b86a832SChris Mason 	return 1;
2814*0b86a832SChris Mason }
2815*0b86a832SChris Mason 
2816