]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - fs/btrfs/extent-tree.c
Btrfs: dynamic allocation of path struct
[linux-2.6-omap-h63xx.git] / fs / btrfs / extent-tree.c
1 #include <linux/module.h>
2 #include "ctree.h"
3 #include "disk-io.h"
4 #include "print-tree.h"
5 #include "transaction.h"
6
7 static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
8                             *orig_root, u64 num_blocks, u64 search_start, u64
9                             search_end, struct btrfs_key *ins);
10 static int finish_current_insert(struct btrfs_trans_handle *trans, struct
11                                  btrfs_root *extent_root);
12 static int del_pending_extents(struct btrfs_trans_handle *trans, struct
13                                btrfs_root *extent_root);
14
15 static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
16                          *root, u64 blocknr, u64 num_blocks)
17 {
18         struct btrfs_path *path;
19         int ret;
20         struct btrfs_key key;
21         struct btrfs_leaf *l;
22         struct btrfs_extent_item *item;
23         struct btrfs_key ins;
24         u32 refs;
25
26         find_free_extent(trans, root->fs_info->extent_root, 0, 0, (u64)-1,
27                          &ins);
28         path = btrfs_alloc_path();
29         BUG_ON(!path);
30         btrfs_init_path(path);
31         key.objectid = blocknr;
32         key.flags = 0;
33         btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
34         key.offset = num_blocks;
35         ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path,
36                                 0, 1);
37         if (ret != 0)
38                 BUG();
39         BUG_ON(ret != 0);
40         l = btrfs_buffer_leaf(path->nodes[0]);
41         item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item);
42         refs = btrfs_extent_refs(item);
43         btrfs_set_extent_refs(item, refs + 1);
44         btrfs_mark_buffer_dirty(path->nodes[0]);
45
46         btrfs_release_path(root->fs_info->extent_root, path);
47         btrfs_free_path(path);
48         finish_current_insert(trans, root->fs_info->extent_root);
49         del_pending_extents(trans, root->fs_info->extent_root);
50         return 0;
51 }
52
53 static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
54                             *root, u64 blocknr, u64 num_blocks, u32 *refs)
55 {
56         struct btrfs_path *path;
57         int ret;
58         struct btrfs_key key;
59         struct btrfs_leaf *l;
60         struct btrfs_extent_item *item;
61
62         path = btrfs_alloc_path();
63         btrfs_init_path(path);
64         key.objectid = blocknr;
65         key.offset = num_blocks;
66         key.flags = 0;
67         btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
68         ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path,
69                                 0, 0);
70         if (ret != 0)
71                 BUG();
72         l = btrfs_buffer_leaf(path->nodes[0]);
73         item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item);
74         *refs = btrfs_extent_refs(item);
75         btrfs_release_path(root->fs_info->extent_root, path);
76         btrfs_free_path(path);
77         return 0;
78 }
79
80 int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
81                   struct buffer_head *buf)
82 {
83         u64 blocknr;
84         struct btrfs_node *buf_node;
85         struct btrfs_leaf *buf_leaf;
86         struct btrfs_disk_key *key;
87         struct btrfs_file_extent_item *fi;
88         int i;
89         int leaf;
90         int ret;
91
92         if (!root->ref_cows)
93                 return 0;
94         buf_node = btrfs_buffer_node(buf);
95         leaf = btrfs_is_leaf(buf_node);
96         buf_leaf = btrfs_buffer_leaf(buf);
97         for (i = 0; i < btrfs_header_nritems(&buf_node->header); i++) {
98                 if (leaf) {
99                         key = &buf_leaf->items[i].key;
100                         if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY)
101                                 continue;
102                         fi = btrfs_item_ptr(buf_leaf, i,
103                                             struct btrfs_file_extent_item);
104                         ret = inc_block_ref(trans, root,
105                                     btrfs_file_extent_disk_blocknr(fi),
106                                     btrfs_file_extent_disk_num_blocks(fi));
107                         BUG_ON(ret);
108                 } else {
109                         blocknr = btrfs_node_blockptr(buf_node, i);
110                         ret = inc_block_ref(trans, root, blocknr, 1);
111                         BUG_ON(ret);
112                 }
113         }
114         return 0;
115 }
116
117 int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
118                                btrfs_root *root)
119 {
120         unsigned long gang[8];
121         u64 first = 0;
122         int ret;
123         int i;
124         struct radix_tree_root *pinned_radix = &root->fs_info->pinned_radix;
125
126         while(1) {
127                 ret = find_first_radix_bit(pinned_radix, gang,
128                                            ARRAY_SIZE(gang));
129                 if (!ret)
130                         break;
131                 if (!first)
132                         first = gang[0];
133                 for (i = 0; i < ret; i++) {
134                         clear_radix_bit(pinned_radix, gang[i]);
135                 }
136         }
137         if (root->fs_info->last_insert.objectid > first)
138                 root->fs_info->last_insert.objectid = first;
139         root->fs_info->last_insert.offset = 0;
140         return 0;
141 }
142
143 static int finish_current_insert(struct btrfs_trans_handle *trans, struct
144                                  btrfs_root *extent_root)
145 {
146         struct btrfs_key ins;
147         struct btrfs_extent_item extent_item;
148         int i;
149         int ret;
150         u64 super_blocks_used;
151         struct btrfs_fs_info *info = extent_root->fs_info;
152
153         btrfs_set_extent_refs(&extent_item, 1);
154         btrfs_set_extent_owner(&extent_item,
155                 btrfs_header_parentid(btrfs_buffer_header(extent_root->node)));
156         ins.offset = 1;
157         ins.flags = 0;
158         btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY);
159
160         for (i = 0; i < extent_root->fs_info->current_insert.flags; i++) {
161                 ins.objectid = extent_root->fs_info->current_insert.objectid +
162                                 i;
163                 super_blocks_used = btrfs_super_blocks_used(info->disk_super);
164                 btrfs_set_super_blocks_used(info->disk_super,
165                                             super_blocks_used + 1);
166                 ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item,
167                                         sizeof(extent_item));
168                 BUG_ON(ret);
169         }
170         extent_root->fs_info->current_insert.offset = 0;
171         return 0;
172 }
173
174 static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending)
175 {
176         int err;
177         struct btrfs_header *header;
178         struct buffer_head *bh;
179
180         if (!pending) {
181                 bh = btrfs_find_tree_block(root, blocknr);
182                 if (bh) {
183                         if (buffer_uptodate(bh)) {
184                                 u64 transid =
185                                     root->fs_info->running_transaction->transid;
186                                 header = btrfs_buffer_header(bh);
187                                 if (btrfs_header_generation(header) ==
188                                     transid) {
189                                         btrfs_block_release(root, bh);
190                                         return 0;
191                                 }
192                         }
193                         btrfs_block_release(root, bh);
194                 }
195                 err = set_radix_bit(&root->fs_info->pinned_radix, blocknr);
196         } else {
197                 err = set_radix_bit(&root->fs_info->pending_del_radix, blocknr);
198         }
199         BUG_ON(err);
200         return 0;
201 }
202
203 /*
204  * remove an extent from the root, returns 0 on success
205  */
206 static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
207                          *root, u64 blocknr, u64 num_blocks, int pin)
208 {
209         struct btrfs_path *path;
210         struct btrfs_key key;
211         struct btrfs_fs_info *info = root->fs_info;
212         struct btrfs_root *extent_root = info->extent_root;
213         int ret;
214         struct btrfs_extent_item *ei;
215         struct btrfs_key ins;
216         u32 refs;
217
218         key.objectid = blocknr;
219         key.flags = 0;
220         btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
221         key.offset = num_blocks;
222
223         find_free_extent(trans, root, 0, 0, (u64)-1, &ins);
224         path = btrfs_alloc_path();
225         BUG_ON(!path);
226         btrfs_init_path(path);
227         ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1);
228         if (ret) {
229                 printk("failed to find %Lu\n", key.objectid);
230                 btrfs_print_tree(extent_root, extent_root->node);
231                 printk("failed to find %Lu\n", key.objectid);
232                 BUG();
233         }
234         ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
235                             struct btrfs_extent_item);
236         BUG_ON(ei->refs == 0);
237         refs = btrfs_extent_refs(ei) - 1;
238         btrfs_set_extent_refs(ei, refs);
239         btrfs_mark_buffer_dirty(path->nodes[0]);
240         if (refs == 0) {
241                 u64 super_blocks_used;
242
243                 if (pin) {
244                         ret = pin_down_block(root, blocknr, 0);
245                         BUG_ON(ret);
246                 }
247
248                 super_blocks_used = btrfs_super_blocks_used(info->disk_super);
249                 btrfs_set_super_blocks_used(info->disk_super,
250                                             super_blocks_used - num_blocks);
251                 ret = btrfs_del_item(trans, extent_root, path);
252                 if (extent_root->fs_info->last_insert.objectid > blocknr)
253                         extent_root->fs_info->last_insert.objectid = blocknr;
254                 if (ret)
255                         BUG();
256         }
257         btrfs_release_path(extent_root, path);
258         btrfs_free_path(path);
259         finish_current_insert(trans, extent_root);
260         return ret;
261 }
262
263 /*
264  * find all the blocks marked as pending in the radix tree and remove
265  * them from the extent map
266  */
267 static int del_pending_extents(struct btrfs_trans_handle *trans, struct
268                                btrfs_root *extent_root)
269 {
270         int ret;
271         int wret;
272         int err = 0;
273         unsigned long gang[4];
274         int i;
275         struct radix_tree_root *pending_radix;
276         struct radix_tree_root *pinned_radix;
277
278         pending_radix = &extent_root->fs_info->pending_del_radix;
279         pinned_radix = &extent_root->fs_info->pinned_radix;
280
281         while(1) {
282                 ret = find_first_radix_bit(pending_radix, gang,
283                                            ARRAY_SIZE(gang));
284                 if (!ret)
285                         break;
286                 for (i = 0; i < ret; i++) {
287                         wret = set_radix_bit(pinned_radix, gang[i]);
288                         BUG_ON(wret);
289                         wret = clear_radix_bit(pending_radix, gang[i]);
290                         BUG_ON(wret);
291                         wret = __free_extent(trans, extent_root,
292                                              gang[i], 1, 0);
293                         if (wret)
294                                 err = wret;
295                 }
296         }
297         return err;
298 }
299
300 /*
301  * remove an extent from the root, returns 0 on success
302  */
303 int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
304                       *root, u64 blocknr, u64 num_blocks, int pin)
305 {
306         struct btrfs_root *extent_root = root->fs_info->extent_root;
307         int pending_ret;
308         int ret;
309
310         if (root == extent_root) {
311                 pin_down_block(root, blocknr, 1);
312                 return 0;
313         }
314         ret = __free_extent(trans, root, blocknr, num_blocks, pin);
315         pending_ret = del_pending_extents(trans, root->fs_info->extent_root);
316         return ret ? ret : pending_ret;
317 }
318
319 /*
320  * walks the btree of allocated extents and find a hole of a given size.
321  * The key ins is changed to record the hole:
322  * ins->objectid == block start
323  * ins->flags = BTRFS_EXTENT_ITEM_KEY
324  * ins->offset == number of blocks
325  * Any available blocks before search_start are skipped.
326  */
327 static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
328                             *orig_root, u64 num_blocks, u64 search_start, u64
329                             search_end, struct btrfs_key *ins)
330 {
331         struct btrfs_path *path;
332         struct btrfs_key key;
333         int ret;
334         u64 hole_size = 0;
335         int slot = 0;
336         u64 last_block = 0;
337         u64 test_block;
338         int start_found;
339         struct btrfs_leaf *l;
340         struct btrfs_root * root = orig_root->fs_info->extent_root;
341         int total_needed = num_blocks;
342         int level;
343
344         level = btrfs_header_level(btrfs_buffer_header(root->node));
345         total_needed += (level + 1) * 3;
346         if (root->fs_info->last_insert.objectid > search_start)
347                 search_start = root->fs_info->last_insert.objectid;
348
349         ins->flags = 0;
350         btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
351         path = btrfs_alloc_path();
352
353 check_failed:
354         btrfs_init_path(path);
355         ins->objectid = search_start;
356         ins->offset = 0;
357         start_found = 0;
358         ret = btrfs_search_slot(trans, root, ins, path, 0, 0);
359         if (ret < 0)
360                 goto error;
361
362         if (path->slots[0] > 0)
363                 path->slots[0]--;
364
365         while (1) {
366                 l = btrfs_buffer_leaf(path->nodes[0]);
367                 slot = path->slots[0];
368                 if (slot >= btrfs_header_nritems(&l->header)) {
369                         ret = btrfs_next_leaf(root, path);
370                         if (ret == 0)
371                                 continue;
372                         if (ret < 0)
373                                 goto error;
374                         if (!start_found) {
375                                 ins->objectid = search_start;
376                                 ins->offset = (u64)-1;
377                                 start_found = 1;
378                                 goto check_pending;
379                         }
380                         ins->objectid = last_block > search_start ?
381                                         last_block : search_start;
382                         ins->offset = (u64)-1;
383                         goto check_pending;
384                 }
385                 btrfs_disk_key_to_cpu(&key, &l->items[slot].key);
386                 if (key.objectid >= search_start) {
387                         if (start_found) {
388                                 if (last_block < search_start)
389                                         last_block = search_start;
390                                 hole_size = key.objectid - last_block;
391                                 if (hole_size > total_needed) {
392                                         ins->objectid = last_block;
393                                         ins->offset = hole_size;
394                                         goto check_pending;
395                                 }
396                         }
397                 }
398                 start_found = 1;
399                 last_block = key.objectid + key.offset;
400                 path->slots[0]++;
401         }
402         // FIXME -ENOSPC
403 check_pending:
404         /* we have to make sure we didn't find an extent that has already
405          * been allocated by the map tree or the original allocation
406          */
407         btrfs_release_path(root, path);
408         BUG_ON(ins->objectid < search_start);
409         for (test_block = ins->objectid;
410              test_block < ins->objectid + total_needed; test_block++) {
411                 if (test_radix_bit(&root->fs_info->pinned_radix,
412                                       test_block)) {
413                         search_start = test_block + 1;
414                         goto check_failed;
415                 }
416         }
417         BUG_ON(root->fs_info->current_insert.offset);
418         root->fs_info->current_insert.offset = total_needed - num_blocks;
419         root->fs_info->current_insert.objectid = ins->objectid + num_blocks;
420         root->fs_info->current_insert.flags = 0;
421         root->fs_info->last_insert.objectid = ins->objectid;
422         ins->offset = num_blocks;
423         btrfs_free_path(path);
424         return 0;
425 error:
426         btrfs_release_path(root, path);
427         btrfs_free_path(path);
428         return ret;
429 }
430
431 /*
432  * finds a free extent and does all the dirty work required for allocation
433  * returns the key for the extent through ins, and a tree buffer for
434  * the first block of the extent through buf.
435  *
436  * returns 0 if everything worked, non-zero otherwise.
437  */
438 int btrfs_alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
439                         *root, u64 num_blocks, u64 search_start, u64
440                         search_end, u64 owner, struct btrfs_key *ins)
441 {
442         int ret;
443         int pending_ret;
444         u64 super_blocks_used;
445         struct btrfs_fs_info *info = root->fs_info;
446         struct btrfs_root *extent_root = info->extent_root;
447         struct btrfs_extent_item extent_item;
448
449         btrfs_set_extent_refs(&extent_item, 1);
450         btrfs_set_extent_owner(&extent_item, owner);
451
452         if (root == extent_root) {
453                 BUG_ON(extent_root->fs_info->current_insert.offset == 0);
454                 BUG_ON(num_blocks != 1);
455                 BUG_ON(extent_root->fs_info->current_insert.flags ==
456                        extent_root->fs_info->current_insert.offset);
457                 ins->offset = 1;
458                 ins->objectid = extent_root->fs_info->current_insert.objectid +
459                                 extent_root->fs_info->current_insert.flags++;
460                 return 0;
461         }
462         ret = find_free_extent(trans, root, num_blocks, search_start,
463                                search_end, ins);
464         if (ret)
465                 return ret;
466
467         super_blocks_used = btrfs_super_blocks_used(info->disk_super);
468         btrfs_set_super_blocks_used(info->disk_super, super_blocks_used +
469                                     num_blocks);
470         ret = btrfs_insert_item(trans, extent_root, ins, &extent_item,
471                                 sizeof(extent_item));
472
473         finish_current_insert(trans, extent_root);
474         pending_ret = del_pending_extents(trans, extent_root);
475         if (ret)
476                 return ret;
477         if (pending_ret)
478                 return pending_ret;
479         return 0;
480 }
481
482 /*
483  * helper function to allocate a block for a given tree
484  * returns the tree buffer or NULL.
485  */
486 struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
487                                             struct btrfs_root *root)
488 {
489         struct btrfs_key ins;
490         int ret;
491         struct buffer_head *buf;
492
493         ret = btrfs_alloc_extent(trans, root, 1, 0, (unsigned long)-1,
494                 btrfs_header_parentid(btrfs_buffer_header(root->node)), &ins);
495         if (ret) {
496                 BUG();
497                 return NULL;
498         }
499         buf = btrfs_find_create_tree_block(root, ins.objectid);
500         set_buffer_uptodate(buf);
501         return buf;
502 }
503
504 static int drop_leaf_ref(struct btrfs_trans_handle *trans,
505                          struct btrfs_root *root, struct buffer_head *cur)
506 {
507         struct btrfs_disk_key *key;
508         struct btrfs_leaf *leaf;
509         struct btrfs_file_extent_item *fi;
510         int i;
511         int nritems;
512         int ret;
513
514         BUG_ON(!btrfs_is_leaf(btrfs_buffer_node(cur)));
515         leaf = btrfs_buffer_leaf(cur);
516         nritems = btrfs_header_nritems(&leaf->header);
517         for (i = 0; i < nritems; i++) {
518                 key = &leaf->items[i].key;
519                 if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY)
520                         continue;
521                 fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item);
522                 /*
523                  * FIXME make sure to insert a trans record that
524                  * repeats the snapshot del on crash
525                  */
526                 ret = btrfs_free_extent(trans, root,
527                                         btrfs_file_extent_disk_blocknr(fi),
528                                         btrfs_file_extent_disk_num_blocks(fi),
529                                         0);
530                 BUG_ON(ret);
531         }
532         return 0;
533 }
534
535 /*
536  * helper function for drop_snapshot, this walks down the tree dropping ref
537  * counts as it goes.
538  */
539 static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
540                           *root, struct btrfs_path *path, int *level)
541 {
542         struct buffer_head *next;
543         struct buffer_head *cur;
544         u64 blocknr;
545         int ret;
546         u32 refs;
547
548         WARN_ON(*level < 0);
549         WARN_ON(*level >= BTRFS_MAX_LEVEL);
550         ret = lookup_block_ref(trans, root, path->nodes[*level]->b_blocknr,
551                                1, &refs);
552         BUG_ON(ret);
553         if (refs > 1)
554                 goto out;
555         /*
556          * walk down to the last node level and free all the leaves
557          */
558         while(*level >= 0) {
559                 WARN_ON(*level < 0);
560                 WARN_ON(*level >= BTRFS_MAX_LEVEL);
561                 cur = path->nodes[*level];
562                 if (btrfs_header_level(btrfs_buffer_header(cur)) != *level)
563                         WARN_ON(1);
564                 if (path->slots[*level] >=
565                     btrfs_header_nritems(btrfs_buffer_header(cur)))
566                         break;
567                 if (*level == 0) {
568                         ret = drop_leaf_ref(trans, root, cur);
569                         BUG_ON(ret);
570                         break;
571                 }
572                 blocknr = btrfs_node_blockptr(btrfs_buffer_node(cur),
573                                               path->slots[*level]);
574                 ret = lookup_block_ref(trans, root, blocknr, 1, &refs);
575                 BUG_ON(ret);
576                 if (refs != 1) {
577                         path->slots[*level]++;
578                         ret = btrfs_free_extent(trans, root, blocknr, 1, 1);
579                         BUG_ON(ret);
580                         continue;
581                 }
582                 next = read_tree_block(root, blocknr);
583                 WARN_ON(*level <= 0);
584                 if (path->nodes[*level-1])
585                         btrfs_block_release(root, path->nodes[*level-1]);
586                 path->nodes[*level-1] = next;
587                 *level = btrfs_header_level(btrfs_buffer_header(next));
588                 path->slots[*level] = 0;
589         }
590 out:
591         WARN_ON(*level < 0);
592         WARN_ON(*level >= BTRFS_MAX_LEVEL);
593         ret = btrfs_free_extent(trans, root,
594                                 path->nodes[*level]->b_blocknr, 1, 1);
595         btrfs_block_release(root, path->nodes[*level]);
596         path->nodes[*level] = NULL;
597         *level += 1;
598         BUG_ON(ret);
599         return 0;
600 }
601
602 /*
603  * helper for dropping snapshots.  This walks back up the tree in the path
604  * to find the first node higher up where we haven't yet gone through
605  * all the slots
606  */
607 static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root
608                         *root, struct btrfs_path *path, int *level)
609 {
610         int i;
611         int slot;
612         int ret;
613         for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) {
614                 slot = path->slots[i];
615                 if (slot < btrfs_header_nritems(
616                     btrfs_buffer_header(path->nodes[i])) - 1) {
617                         path->slots[i]++;
618                         *level = i;
619                         return 0;
620                 } else {
621                         ret = btrfs_free_extent(trans, root,
622                                                 path->nodes[*level]->b_blocknr,
623                                                 1, 1);
624                         BUG_ON(ret);
625                         btrfs_block_release(root, path->nodes[*level]);
626                         path->nodes[*level] = NULL;
627                         *level = i + 1;
628                 }
629         }
630         return 1;
631 }
632
633 /*
634  * drop the reference count on the tree rooted at 'snap'.  This traverses
635  * the tree freeing any blocks that have a ref count of zero after being
636  * decremented.
637  */
638 int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
639                         *root, struct buffer_head *snap)
640 {
641         int ret = 0;
642         int wret;
643         int level;
644         struct btrfs_path *path;
645         int i;
646         int orig_level;
647
648         path = btrfs_alloc_path();
649         BUG_ON(!path);
650         btrfs_init_path(path);
651
652         level = btrfs_header_level(btrfs_buffer_header(snap));
653         orig_level = level;
654         path->nodes[level] = snap;
655         path->slots[level] = 0;
656         while(1) {
657                 wret = walk_down_tree(trans, root, path, &level);
658                 if (wret > 0)
659                         break;
660                 if (wret < 0)
661                         ret = wret;
662
663                 wret = walk_up_tree(trans, root, path, &level);
664                 if (wret > 0)
665                         break;
666                 if (wret < 0)
667                         ret = wret;
668         }
669         for (i = 0; i <= orig_level; i++) {
670                 if (path->nodes[i]) {
671                         btrfs_block_release(root, path->nodes[i]);
672                 }
673         }
674         btrfs_free_path(path);
675         return ret;
676 }