1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * BTRFS filesystem implementation for U-Boot
4  *
5  * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
6  */
7 
8 #include <linux/kernel.h>
9 #include <log.h>
10 #include <malloc.h>
11 #include <memalign.h>
12 #include "btrfs.h"
13 #include "disk-io.h"
14 
15 static const struct btrfs_csum {
16 	u16 size;
17 	const char name[14];
18 } btrfs_csums[] = {
19 	[BTRFS_CSUM_TYPE_CRC32]		= {  4, "crc32c" },
20 	[BTRFS_CSUM_TYPE_XXHASH]	= {  8, "xxhash64" },
21 	[BTRFS_CSUM_TYPE_SHA256]	= { 32, "sha256" },
22 	[BTRFS_CSUM_TYPE_BLAKE2]	= { 32, "blake2" },
23 };
24 
btrfs_super_csum_size(const struct btrfs_super_block * sb)25 u16 btrfs_super_csum_size(const struct btrfs_super_block *sb)
26 {
27 	const u16 csum_type = btrfs_super_csum_type(sb);
28 
29 	return btrfs_csums[csum_type].size;
30 }
31 
btrfs_super_csum_name(u16 csum_type)32 const char *btrfs_super_csum_name(u16 csum_type)
33 {
34 	return btrfs_csums[csum_type].name;
35 }
36 
btrfs_super_num_csums(void)37 size_t btrfs_super_num_csums(void)
38 {
39 	return ARRAY_SIZE(btrfs_csums);
40 }
41 
btrfs_csum_type_size(u16 csum_type)42 u16 btrfs_csum_type_size(u16 csum_type)
43 {
44 	return btrfs_csums[csum_type].size;
45 }
46 
btrfs_alloc_path(void)47 struct btrfs_path *btrfs_alloc_path(void)
48 {
49 	struct btrfs_path *path;
50 	path = kzalloc(sizeof(struct btrfs_path), GFP_NOFS);
51 	return path;
52 }
53 
btrfs_free_path(struct btrfs_path * p)54 void btrfs_free_path(struct btrfs_path *p)
55 {
56 	if (!p)
57 		return;
58 	btrfs_release_path(p);
59 	kfree(p);
60 }
61 
btrfs_release_path(struct btrfs_path * p)62 void btrfs_release_path(struct btrfs_path *p)
63 {
64 	int i;
65 	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
66 		if (!p->nodes[i])
67 			continue;
68 		free_extent_buffer(p->nodes[i]);
69 	}
70 	memset(p, 0, sizeof(*p));
71 }
72 
btrfs_comp_cpu_keys(const struct btrfs_key * k1,const struct btrfs_key * k2)73 int btrfs_comp_cpu_keys(const struct btrfs_key *k1, const struct btrfs_key *k2)
74 {
75 	if (k1->objectid > k2->objectid)
76 		return 1;
77 	if (k1->objectid < k2->objectid)
78 		return -1;
79 	if (k1->type > k2->type)
80 		return 1;
81 	if (k1->type < k2->type)
82 		return -1;
83 	if (k1->offset > k2->offset)
84 		return 1;
85 	if (k1->offset < k2->offset)
86 		return -1;
87 	return 0;
88 }
89 
btrfs_comp_keys(struct btrfs_disk_key * disk,const struct btrfs_key * k2)90 static int btrfs_comp_keys(struct btrfs_disk_key *disk,
91 			     const struct btrfs_key *k2)
92 {
93 	struct btrfs_key k1;
94 
95 	btrfs_disk_key_to_cpu(&k1, disk);
96 	return btrfs_comp_cpu_keys(&k1, k2);
97 }
98 
99 enum btrfs_tree_block_status
btrfs_check_node(struct btrfs_fs_info * fs_info,struct btrfs_disk_key * parent_key,struct extent_buffer * buf)100 btrfs_check_node(struct btrfs_fs_info *fs_info,
101 		 struct btrfs_disk_key *parent_key, struct extent_buffer *buf)
102 {
103 	int i;
104 	struct btrfs_key cpukey;
105 	struct btrfs_disk_key key;
106 	u32 nritems = btrfs_header_nritems(buf);
107 	enum btrfs_tree_block_status ret = BTRFS_TREE_BLOCK_INVALID_NRITEMS;
108 
109 	if (nritems == 0 || nritems > BTRFS_NODEPTRS_PER_BLOCK(fs_info))
110 		goto fail;
111 
112 	ret = BTRFS_TREE_BLOCK_INVALID_PARENT_KEY;
113 	if (parent_key && parent_key->type) {
114 		btrfs_node_key(buf, &key, 0);
115 		if (memcmp(parent_key, &key, sizeof(key)))
116 			goto fail;
117 	}
118 	ret = BTRFS_TREE_BLOCK_BAD_KEY_ORDER;
119 	for (i = 0; nritems > 1 && i < nritems - 2; i++) {
120 		btrfs_node_key(buf, &key, i);
121 		btrfs_node_key_to_cpu(buf, &cpukey, i + 1);
122 		if (btrfs_comp_keys(&key, &cpukey) >= 0)
123 			goto fail;
124 	}
125 	return BTRFS_TREE_BLOCK_CLEAN;
126 fail:
127 	return ret;
128 }
129 
130 enum btrfs_tree_block_status
btrfs_check_leaf(struct btrfs_fs_info * fs_info,struct btrfs_disk_key * parent_key,struct extent_buffer * buf)131 btrfs_check_leaf(struct btrfs_fs_info *fs_info,
132 		 struct btrfs_disk_key *parent_key, struct extent_buffer *buf)
133 {
134 	int i;
135 	struct btrfs_key cpukey;
136 	struct btrfs_disk_key key;
137 	u32 nritems = btrfs_header_nritems(buf);
138 	enum btrfs_tree_block_status ret = BTRFS_TREE_BLOCK_INVALID_NRITEMS;
139 
140 	if (nritems * sizeof(struct btrfs_item) > buf->len)  {
141 		fprintf(stderr, "invalid number of items %llu\n",
142 			(unsigned long long)buf->start);
143 		goto fail;
144 	}
145 
146 	if (btrfs_header_level(buf) != 0) {
147 		ret = BTRFS_TREE_BLOCK_INVALID_LEVEL;
148 		fprintf(stderr, "leaf is not a leaf %llu\n",
149 		       (unsigned long long)btrfs_header_bytenr(buf));
150 		goto fail;
151 	}
152 	if (btrfs_leaf_free_space(buf) < 0) {
153 		ret = BTRFS_TREE_BLOCK_INVALID_FREE_SPACE;
154 		fprintf(stderr, "leaf free space incorrect %llu %d\n",
155 			(unsigned long long)btrfs_header_bytenr(buf),
156 			btrfs_leaf_free_space(buf));
157 		goto fail;
158 	}
159 
160 	if (nritems == 0)
161 		return BTRFS_TREE_BLOCK_CLEAN;
162 
163 	btrfs_item_key(buf, &key, 0);
164 	if (parent_key && parent_key->type &&
165 	    memcmp(parent_key, &key, sizeof(key))) {
166 		ret = BTRFS_TREE_BLOCK_INVALID_PARENT_KEY;
167 		fprintf(stderr, "leaf parent key incorrect %llu\n",
168 		       (unsigned long long)btrfs_header_bytenr(buf));
169 		goto fail;
170 	}
171 	for (i = 0; nritems > 1 && i < nritems - 1; i++) {
172 		btrfs_item_key(buf, &key, i);
173 		btrfs_item_key_to_cpu(buf, &cpukey, i + 1);
174 		if (btrfs_comp_keys(&key, &cpukey) >= 0) {
175 			ret = BTRFS_TREE_BLOCK_BAD_KEY_ORDER;
176 			fprintf(stderr, "bad key ordering %d %d\n", i, i+1);
177 			goto fail;
178 		}
179 		if (btrfs_item_offset_nr(buf, i) !=
180 			btrfs_item_end_nr(buf, i + 1)) {
181 			ret = BTRFS_TREE_BLOCK_INVALID_OFFSETS;
182 			fprintf(stderr, "incorrect offsets %u %u\n",
183 				btrfs_item_offset_nr(buf, i),
184 				btrfs_item_end_nr(buf, i + 1));
185 			goto fail;
186 		}
187 		if (i == 0 && btrfs_item_end_nr(buf, i) !=
188 		    BTRFS_LEAF_DATA_SIZE(fs_info)) {
189 			ret = BTRFS_TREE_BLOCK_INVALID_OFFSETS;
190 			fprintf(stderr, "bad item end %u wanted %u\n",
191 				btrfs_item_end_nr(buf, i),
192 				(unsigned)BTRFS_LEAF_DATA_SIZE(fs_info));
193 			goto fail;
194 		}
195 	}
196 
197 	for (i = 0; i < nritems; i++) {
198 		if (btrfs_item_end_nr(buf, i) >
199 				BTRFS_LEAF_DATA_SIZE(fs_info)) {
200 			btrfs_item_key(buf, &key, 0);
201 			ret = BTRFS_TREE_BLOCK_INVALID_OFFSETS;
202 			fprintf(stderr, "slot end outside of leaf %llu > %llu\n",
203 				(unsigned long long)btrfs_item_end_nr(buf, i),
204 				(unsigned long long)BTRFS_LEAF_DATA_SIZE(
205 					fs_info));
206 			goto fail;
207 		}
208 	}
209 
210 	return BTRFS_TREE_BLOCK_CLEAN;
211 fail:
212 	return ret;
213 }
214 
check_block(struct btrfs_fs_info * fs_info,struct btrfs_path * path,int level)215 static int noinline check_block(struct btrfs_fs_info *fs_info,
216 				struct btrfs_path *path, int level)
217 {
218 	struct btrfs_disk_key key;
219 	struct btrfs_disk_key *key_ptr = NULL;
220 	struct extent_buffer *parent;
221 	enum btrfs_tree_block_status ret;
222 
223 	if (path->nodes[level + 1]) {
224 		parent = path->nodes[level + 1];
225 		btrfs_node_key(parent, &key, path->slots[level + 1]);
226 		key_ptr = &key;
227 	}
228 	if (level == 0)
229 		ret = btrfs_check_leaf(fs_info, key_ptr, path->nodes[0]);
230 	else
231 		ret = btrfs_check_node(fs_info, key_ptr, path->nodes[level]);
232 	if (ret == BTRFS_TREE_BLOCK_CLEAN)
233 		return 0;
234 	return -EIO;
235 }
236 
237 /*
238  * search for key in the extent_buffer.  The items start at offset p,
239  * and they are item_size apart.  There are 'max' items in p.
240  *
241  * the slot in the array is returned via slot, and it points to
242  * the place where you would insert key if it is not found in
243  * the array.
244  *
245  * slot may point to max if the key is bigger than all of the keys
246  */
generic_bin_search(struct extent_buffer * eb,unsigned long p,int item_size,const struct btrfs_key * key,int max,int * slot)247 static int generic_bin_search(struct extent_buffer *eb, unsigned long p,
248 			      int item_size, const struct btrfs_key *key,
249 			      int max, int *slot)
250 {
251 	int low = 0;
252 	int high = max;
253 	int mid;
254 	int ret;
255 	unsigned long offset;
256 	struct btrfs_disk_key *tmp;
257 
258 	while(low < high) {
259 		mid = (low + high) / 2;
260 		offset = p + mid * item_size;
261 
262 		tmp = (struct btrfs_disk_key *)(eb->data + offset);
263 		ret = btrfs_comp_keys(tmp, key);
264 
265 		if (ret < 0)
266 			low = mid + 1;
267 		else if (ret > 0)
268 			high = mid;
269 		else {
270 			*slot = mid;
271 			return 0;
272 		}
273 	}
274 	*slot = low;
275 	return 1;
276 }
277 
278 /*
279  * simple bin_search frontend that does the right thing for
280  * leaves vs nodes
281  */
btrfs_bin_search(struct extent_buffer * eb,const struct btrfs_key * key,int * slot)282 int btrfs_bin_search(struct extent_buffer *eb, const struct btrfs_key *key,
283 		     int *slot)
284 {
285 	if (btrfs_header_level(eb) == 0)
286 		return generic_bin_search(eb,
287 					  offsetof(struct btrfs_leaf, items),
288 					  sizeof(struct btrfs_item),
289 					  key, btrfs_header_nritems(eb),
290 					  slot);
291 	else
292 		return generic_bin_search(eb,
293 					  offsetof(struct btrfs_node, ptrs),
294 					  sizeof(struct btrfs_key_ptr),
295 					  key, btrfs_header_nritems(eb),
296 					  slot);
297 }
298 
read_node_slot(struct btrfs_fs_info * fs_info,struct extent_buffer * parent,int slot)299 struct extent_buffer *read_node_slot(struct btrfs_fs_info *fs_info,
300 				   struct extent_buffer *parent, int slot)
301 {
302 	struct extent_buffer *ret;
303 	int level = btrfs_header_level(parent);
304 
305 	if (slot < 0)
306 		return NULL;
307 	if (slot >= btrfs_header_nritems(parent))
308 		return NULL;
309 
310 	if (level == 0)
311 		return NULL;
312 
313 	ret = read_tree_block(fs_info, btrfs_node_blockptr(parent, slot),
314 		       btrfs_node_ptr_generation(parent, slot));
315 	if (!extent_buffer_uptodate(ret))
316 		return ERR_PTR(-EIO);
317 
318 	if (btrfs_header_level(ret) != level - 1) {
319 		error("child eb corrupted: parent bytenr=%llu item=%d parent level=%d child level=%d",
320 		      btrfs_header_bytenr(parent), slot,
321 		      btrfs_header_level(parent), btrfs_header_level(ret));
322 		free_extent_buffer(ret);
323 		return ERR_PTR(-EIO);
324 	}
325 	return ret;
326 }
327 
btrfs_find_item(struct btrfs_root * fs_root,struct btrfs_path * found_path,u64 iobjectid,u64 ioff,u8 key_type,struct btrfs_key * found_key)328 int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path,
329 		u64 iobjectid, u64 ioff, u8 key_type,
330 		struct btrfs_key *found_key)
331 {
332 	int ret;
333 	struct btrfs_key key;
334 	struct extent_buffer *eb;
335 	struct btrfs_path *path;
336 
337 	key.type = key_type;
338 	key.objectid = iobjectid;
339 	key.offset = ioff;
340 
341 	if (found_path == NULL) {
342 		path = btrfs_alloc_path();
343 		if (!path)
344 			return -ENOMEM;
345 	} else
346 		path = found_path;
347 
348 	ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
349 	if ((ret < 0) || (found_key == NULL))
350 		goto out;
351 
352 	eb = path->nodes[0];
353 	if (ret && path->slots[0] >= btrfs_header_nritems(eb)) {
354 		ret = btrfs_next_leaf(fs_root, path);
355 		if (ret)
356 			goto out;
357 		eb = path->nodes[0];
358 	}
359 
360 	btrfs_item_key_to_cpu(eb, found_key, path->slots[0]);
361 	if (found_key->type != key.type ||
362 			found_key->objectid != key.objectid) {
363 		ret = 1;
364 		goto out;
365 	}
366 
367 out:
368 	if (path != found_path)
369 		btrfs_free_path(path);
370 	return ret;
371 }
372 
373 /*
374  * look for key in the tree.  path is filled in with nodes along the way
375  * if key is found, we return zero and you can find the item in the leaf
376  * level of the path (level 0)
377  *
378  * If the key isn't found, the path points to the slot where it should
379  * be inserted, and 1 is returned.  If there are other errors during the
380  * search a negative error number is returned.
381  *
382  * if ins_len > 0, nodes and leaves will be split as we walk down the
383  * tree.  if ins_len < 0, nodes will be merged as we walk down the tree (if
384  * possible)
385  *
386  * NOTE: This version has no COW ability, thus we expect trans == NULL,
387  * ins_len == 0 and cow == 0.
388  */
btrfs_search_slot(struct btrfs_trans_handle * trans,struct btrfs_root * root,const struct btrfs_key * key,struct btrfs_path * p,int ins_len,int cow)389 int btrfs_search_slot(struct btrfs_trans_handle *trans,
390 		struct btrfs_root *root, const struct btrfs_key *key,
391 		struct btrfs_path *p, int ins_len, int cow)
392 {
393 	struct extent_buffer *b;
394 	int slot;
395 	int ret;
396 	int level;
397 	struct btrfs_fs_info *fs_info = root->fs_info;
398 	u8 lowest_level = 0;
399 
400 	assert(trans == NULL && ins_len == 0 && cow == 0);
401 	lowest_level = p->lowest_level;
402 	WARN_ON(lowest_level && ins_len > 0);
403 	WARN_ON(p->nodes[0] != NULL);
404 
405 	b = root->node;
406 	extent_buffer_get(b);
407 	while (b) {
408 		level = btrfs_header_level(b);
409 		/*
410 		if (cow) {
411 			int wret;
412 			wret = btrfs_cow_block(trans, root, b,
413 					       p->nodes[level + 1],
414 					       p->slots[level + 1],
415 					       &b);
416 			if (wret) {
417 				free_extent_buffer(b);
418 				return wret;
419 			}
420 		}
421 		*/
422 		BUG_ON(!cow && ins_len);
423 		if (level != btrfs_header_level(b))
424 			WARN_ON(1);
425 		level = btrfs_header_level(b);
426 		p->nodes[level] = b;
427 		ret = check_block(fs_info, p, level);
428 		if (ret)
429 			return -1;
430 		ret = btrfs_bin_search(b, key, &slot);
431 		if (level != 0) {
432 			if (ret && slot > 0)
433 				slot -= 1;
434 			p->slots[level] = slot;
435 			/*
436 			if ((p->search_for_split || ins_len > 0) &&
437 			    btrfs_header_nritems(b) >=
438 			    BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 3) {
439 				int sret = split_node(trans, root, p, level);
440 				BUG_ON(sret > 0);
441 				if (sret)
442 					return sret;
443 				b = p->nodes[level];
444 				slot = p->slots[level];
445 			} else if (ins_len < 0) {
446 				int sret = balance_level(trans, root, p,
447 							 level);
448 				if (sret)
449 					return sret;
450 				b = p->nodes[level];
451 				if (!b) {
452 					btrfs_release_path(p);
453 					goto again;
454 				}
455 				slot = p->slots[level];
456 				BUG_ON(btrfs_header_nritems(b) == 1);
457 			}
458 			*/
459 			/* this is only true while dropping a snapshot */
460 			if (level == lowest_level)
461 				break;
462 
463 			b = read_node_slot(fs_info, b, slot);
464 			if (!extent_buffer_uptodate(b))
465 				return -EIO;
466 		} else {
467 			p->slots[level] = slot;
468 			/*
469 			if (ins_len > 0 &&
470 			    ins_len > btrfs_leaf_free_space(b)) {
471 				int sret = split_leaf(trans, root, key,
472 						      p, ins_len, ret == 0);
473 				BUG_ON(sret > 0);
474 				if (sret)
475 					return sret;
476 			}
477 			*/
478 			return ret;
479 		}
480 	}
481 	return 1;
482 }
483 
484 /*
485  * Helper to use instead of search slot if no exact match is needed but
486  * instead the next or previous item should be returned.
487  * When find_higher is true, the next higher item is returned, the next lower
488  * otherwise.
489  * When return_any and find_higher are both true, and no higher item is found,
490  * return the next lower instead.
491  * When return_any is true and find_higher is false, and no lower item is found,
492  * return the next higher instead.
493  * It returns 0 if any item is found, 1 if none is found (tree empty), and
494  * < 0 on error
495  */
btrfs_search_slot_for_read(struct btrfs_root * root,const struct btrfs_key * key,struct btrfs_path * p,int find_higher,int return_any)496 int btrfs_search_slot_for_read(struct btrfs_root *root,
497 			       const struct btrfs_key *key,
498 			       struct btrfs_path *p, int find_higher,
499 			       int return_any)
500 {
501 	int ret;
502 	struct extent_buffer *leaf;
503 
504 again:
505 	ret = btrfs_search_slot(NULL, root, key, p, 0, 0);
506 	if (ret <= 0)
507 		 return ret;
508 	/*
509 	 * A return value of 1 means the path is at the position where the item
510 	 * should be inserted. Normally this is the next bigger item, but in
511 	 * case the previous item is the last in a leaf, path points to the
512 	 * first free slot in the previous leaf, i.e. at an invalid item.
513 	 */
514 	leaf = p->nodes[0];
515 
516 	if (find_higher) {
517 		if (p->slots[0] >= btrfs_header_nritems(leaf)) {
518 			ret = btrfs_next_leaf(root, p);
519 			if (ret <= 0)
520 				return ret;
521 			if (!return_any)
522 				return 1;
523 			/*
524 			 * No higher item found, return the next lower instead
525 			 */
526 			return_any = 0;
527 			find_higher = 0;
528 			btrfs_release_path(p);
529 			goto again;
530 		}
531 	} else {
532 		if (p->slots[0] == 0) {
533 			ret = btrfs_prev_leaf(root, p);
534 			if (ret < 0)
535 				return ret;
536 			if (!ret) {
537 				leaf = p->nodes[0];
538 				if (p->slots[0] == btrfs_header_nritems(leaf))
539 					p->slots[0]--;
540 				return 0;
541 			}
542 			if (!return_any)
543 				return 1;
544 			/*
545 			 * No lower item found, return the next higher instead
546 			 */
547 			return_any = 0;
548 			find_higher = 1;
549 			btrfs_release_path(p);
550 			goto again;
551 		} else {
552 			--p->slots[0];
553 		}
554 	}
555 	return 0;
556 }
557 
558 /*
559  * how many bytes are required to store the items in a leaf.  start
560  * and nr indicate which items in the leaf to check.  This totals up the
561  * space used both by the item structs and the item data
562  */
leaf_space_used(struct extent_buffer * l,int start,int nr)563 static int leaf_space_used(struct extent_buffer *l, int start, int nr)
564 {
565 	int data_len;
566 	int nritems = btrfs_header_nritems(l);
567 	int end = min(nritems, start + nr) - 1;
568 
569 	if (!nr)
570 		return 0;
571 	data_len = btrfs_item_end_nr(l, start);
572 	data_len = data_len - btrfs_item_offset_nr(l, end);
573 	data_len += sizeof(struct btrfs_item) * nr;
574 	WARN_ON(data_len < 0);
575 	return data_len;
576 }
577 
578 /*
579  * The space between the end of the leaf items and
580  * the start of the leaf data.  IOW, how much room
581  * the leaf has left for both items and data
582  */
btrfs_leaf_free_space(struct extent_buffer * leaf)583 int btrfs_leaf_free_space(struct extent_buffer *leaf)
584 {
585 	int nritems = btrfs_header_nritems(leaf);
586 	u32 leaf_data_size;
587 	int ret;
588 
589 	BUG_ON(leaf->fs_info && leaf->fs_info->nodesize != leaf->len);
590 	leaf_data_size = __BTRFS_LEAF_DATA_SIZE(leaf->len);
591 	ret = leaf_data_size - leaf_space_used(leaf, 0 ,nritems);
592 	if (ret < 0) {
593 		printk("leaf free space ret %d, leaf data size %u, used %d nritems %d\n",
594 		       ret, leaf_data_size, leaf_space_used(leaf, 0, nritems),
595 		       nritems);
596 	}
597 	return ret;
598 }
599 
600 /*
601  * walk up the tree as far as required to find the previous leaf.
602  * returns 0 if it found something or 1 if there are no lesser leaves.
603  * returns < 0 on io errors.
604  */
btrfs_prev_leaf(struct btrfs_root * root,struct btrfs_path * path)605 int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
606 {
607 	int slot;
608 	int level = 1;
609 	struct extent_buffer *c;
610 	struct extent_buffer *next = NULL;
611 	struct btrfs_fs_info *fs_info = root->fs_info;
612 
613 	while(level < BTRFS_MAX_LEVEL) {
614 		if (!path->nodes[level])
615 			return 1;
616 
617 		slot = path->slots[level];
618 		c = path->nodes[level];
619 		if (slot == 0) {
620 			level++;
621 			if (level == BTRFS_MAX_LEVEL)
622 				return 1;
623 			continue;
624 		}
625 		slot--;
626 
627 		next = read_node_slot(fs_info, c, slot);
628 		if (!extent_buffer_uptodate(next)) {
629 			if (IS_ERR(next))
630 				return PTR_ERR(next);
631 			return -EIO;
632 		}
633 		break;
634 	}
635 	path->slots[level] = slot;
636 	while(1) {
637 		level--;
638 		c = path->nodes[level];
639 		free_extent_buffer(c);
640 		slot = btrfs_header_nritems(next);
641 		if (slot != 0)
642 			slot--;
643 		path->nodes[level] = next;
644 		path->slots[level] = slot;
645 		if (!level)
646 			break;
647 		next = read_node_slot(fs_info, next, slot);
648 		if (!extent_buffer_uptodate(next)) {
649 			if (IS_ERR(next))
650 				return PTR_ERR(next);
651 			return -EIO;
652 		}
653 	}
654 	return 0;
655 }
656 
657 /*
658  * Walk up the tree as far as necessary to find the next sibling tree block.
659  * More generic version of btrfs_next_leaf(), as it could find sibling nodes
660  * if @path->lowest_level is not 0.
661  *
662  * returns 0 if it found something or 1 if there are no greater leaves.
663  * returns < 0 on io errors.
664  */
btrfs_next_sibling_tree_block(struct btrfs_fs_info * fs_info,struct btrfs_path * path)665 int btrfs_next_sibling_tree_block(struct btrfs_fs_info *fs_info,
666 				  struct btrfs_path *path)
667 {
668 	int slot;
669 	int level = path->lowest_level + 1;
670 	struct extent_buffer *c;
671 	struct extent_buffer *next = NULL;
672 
673 	BUG_ON(path->lowest_level + 1 >= BTRFS_MAX_LEVEL);
674 	do {
675 		if (!path->nodes[level])
676 			return 1;
677 
678 		slot = path->slots[level] + 1;
679 		c = path->nodes[level];
680 		if (slot >= btrfs_header_nritems(c)) {
681 			level++;
682 			if (level == BTRFS_MAX_LEVEL)
683 				return 1;
684 			continue;
685 		}
686 
687 		next = read_node_slot(fs_info, c, slot);
688 		if (!extent_buffer_uptodate(next))
689 			return -EIO;
690 		break;
691 	} while (level < BTRFS_MAX_LEVEL);
692 	path->slots[level] = slot;
693 	while(1) {
694 		level--;
695 		c = path->nodes[level];
696 		free_extent_buffer(c);
697 		path->nodes[level] = next;
698 		path->slots[level] = 0;
699 		if (level == path->lowest_level)
700 			break;
701 		next = read_node_slot(fs_info, next, 0);
702 		if (!extent_buffer_uptodate(next))
703 			return -EIO;
704 	}
705 	return 0;
706 }
707 
btrfs_previous_item(struct btrfs_root * root,struct btrfs_path * path,u64 min_objectid,int type)708 int btrfs_previous_item(struct btrfs_root *root,
709 			struct btrfs_path *path, u64 min_objectid,
710 			int type)
711 {
712 	struct btrfs_key found_key;
713 	struct extent_buffer *leaf;
714 	u32 nritems;
715 	int ret;
716 
717 	while(1) {
718 		if (path->slots[0] == 0) {
719 			ret = btrfs_prev_leaf(root, path);
720 			if (ret != 0)
721 				return ret;
722 		} else {
723 			path->slots[0]--;
724 		}
725 		leaf = path->nodes[0];
726 		nritems = btrfs_header_nritems(leaf);
727 		if (nritems == 0)
728 			return 1;
729 		if (path->slots[0] == nritems)
730 			path->slots[0]--;
731 
732 		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
733 		if (found_key.objectid < min_objectid)
734 			break;
735 		if (found_key.type == type)
736 			return 0;
737 		if (found_key.objectid == min_objectid &&
738 		    found_key.type < type)
739 			break;
740 	}
741 	return 1;
742 }
743