aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-04-02 11:20:42 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-04-02 11:20:42 -0400
commit5caf2a002901f0fde475371c4bf1c553b51884af (patch)
tree1c262f723307fe924ea4e960761354f194f3843e /fs/btrfs/extent-tree.c
parent2c90e5d658424bc71b111eb5a972240d5d06fe86 (diff)
Btrfs: dynamic allocation of path struct
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c100
1 files changed, 61 insertions, 39 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 37b87e28a2f3..d785b721b461 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -15,7 +15,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
15static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root 15static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
16 *root, u64 blocknr, u64 num_blocks) 16 *root, u64 blocknr, u64 num_blocks)
17{ 17{
18 struct btrfs_path path; 18 struct btrfs_path *path;
19 int ret; 19 int ret;
20 struct btrfs_key key; 20 struct btrfs_key key;
21 struct btrfs_leaf *l; 21 struct btrfs_leaf *l;
@@ -25,23 +25,26 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
25 25
26 find_free_extent(trans, root->fs_info->extent_root, 0, 0, (u64)-1, 26 find_free_extent(trans, root->fs_info->extent_root, 0, 0, (u64)-1,
27 &ins); 27 &ins);
28 btrfs_init_path(&path); 28 path = btrfs_alloc_path();
29 BUG_ON(!path);
30 btrfs_init_path(path);
29 key.objectid = blocknr; 31 key.objectid = blocknr;
30 key.flags = 0; 32 key.flags = 0;
31 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 33 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
32 key.offset = num_blocks; 34 key.offset = num_blocks;
33 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path, 35 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path,
34 0, 1); 36 0, 1);
35 if (ret != 0) 37 if (ret != 0)
36 BUG(); 38 BUG();
37 BUG_ON(ret != 0); 39 BUG_ON(ret != 0);
38 l = btrfs_buffer_leaf(path.nodes[0]); 40 l = btrfs_buffer_leaf(path->nodes[0]);
39 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); 41 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item);
40 refs = btrfs_extent_refs(item); 42 refs = btrfs_extent_refs(item);
41 btrfs_set_extent_refs(item, refs + 1); 43 btrfs_set_extent_refs(item, refs + 1);
42 btrfs_mark_buffer_dirty(path.nodes[0]); 44 btrfs_mark_buffer_dirty(path->nodes[0]);
43 45
44 btrfs_release_path(root->fs_info->extent_root, &path); 46 btrfs_release_path(root->fs_info->extent_root, path);
47 btrfs_free_path(path);
45 finish_current_insert(trans, root->fs_info->extent_root); 48 finish_current_insert(trans, root->fs_info->extent_root);
46 del_pending_extents(trans, root->fs_info->extent_root); 49 del_pending_extents(trans, root->fs_info->extent_root);
47 return 0; 50 return 0;
@@ -50,24 +53,27 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
50static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root 53static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
51 *root, u64 blocknr, u64 num_blocks, u32 *refs) 54 *root, u64 blocknr, u64 num_blocks, u32 *refs)
52{ 55{
53 struct btrfs_path path; 56 struct btrfs_path *path;
54 int ret; 57 int ret;
55 struct btrfs_key key; 58 struct btrfs_key key;
56 struct btrfs_leaf *l; 59 struct btrfs_leaf *l;
57 struct btrfs_extent_item *item; 60 struct btrfs_extent_item *item;
58 btrfs_init_path(&path); 61
62 path = btrfs_alloc_path();
63 btrfs_init_path(path);
59 key.objectid = blocknr; 64 key.objectid = blocknr;
60 key.offset = num_blocks; 65 key.offset = num_blocks;
61 key.flags = 0; 66 key.flags = 0;
62 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 67 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
63 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path, 68 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path,
64 0, 0); 69 0, 0);
65 if (ret != 0) 70 if (ret != 0)
66 BUG(); 71 BUG();
67 l = btrfs_buffer_leaf(path.nodes[0]); 72 l = btrfs_buffer_leaf(path->nodes[0]);
68 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); 73 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item);
69 *refs = btrfs_extent_refs(item); 74 *refs = btrfs_extent_refs(item);
70 btrfs_release_path(root->fs_info->extent_root, &path); 75 btrfs_release_path(root->fs_info->extent_root, path);
76 btrfs_free_path(path);
71 return 0; 77 return 0;
72} 78}
73 79
@@ -200,7 +206,7 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending)
200static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root 206static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
201 *root, u64 blocknr, u64 num_blocks, int pin) 207 *root, u64 blocknr, u64 num_blocks, int pin)
202{ 208{
203 struct btrfs_path path; 209 struct btrfs_path *path;
204 struct btrfs_key key; 210 struct btrfs_key key;
205 struct btrfs_fs_info *info = root->fs_info; 211 struct btrfs_fs_info *info = root->fs_info;
206 struct btrfs_root *extent_root = info->extent_root; 212 struct btrfs_root *extent_root = info->extent_root;
@@ -215,20 +221,22 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
215 key.offset = num_blocks; 221 key.offset = num_blocks;
216 222
217 find_free_extent(trans, root, 0, 0, (u64)-1, &ins); 223 find_free_extent(trans, root, 0, 0, (u64)-1, &ins);
218 btrfs_init_path(&path); 224 path = btrfs_alloc_path();
219 ret = btrfs_search_slot(trans, extent_root, &key, &path, -1, 1); 225 BUG_ON(!path);
226 btrfs_init_path(path);
227 ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1);
220 if (ret) { 228 if (ret) {
221 printk("failed to find %Lu\n", key.objectid); 229 printk("failed to find %Lu\n", key.objectid);
222 btrfs_print_tree(extent_root, extent_root->node); 230 btrfs_print_tree(extent_root, extent_root->node);
223 printk("failed to find %Lu\n", key.objectid); 231 printk("failed to find %Lu\n", key.objectid);
224 BUG(); 232 BUG();
225 } 233 }
226 ei = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], 234 ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
227 struct btrfs_extent_item); 235 struct btrfs_extent_item);
228 BUG_ON(ei->refs == 0); 236 BUG_ON(ei->refs == 0);
229 refs = btrfs_extent_refs(ei) - 1; 237 refs = btrfs_extent_refs(ei) - 1;
230 btrfs_set_extent_refs(ei, refs); 238 btrfs_set_extent_refs(ei, refs);
231 btrfs_mark_buffer_dirty(path.nodes[0]); 239 btrfs_mark_buffer_dirty(path->nodes[0]);
232 if (refs == 0) { 240 if (refs == 0) {
233 u64 super_blocks_used; 241 u64 super_blocks_used;
234 242
@@ -240,13 +248,14 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
240 super_blocks_used = btrfs_super_blocks_used(info->disk_super); 248 super_blocks_used = btrfs_super_blocks_used(info->disk_super);
241 btrfs_set_super_blocks_used(info->disk_super, 249 btrfs_set_super_blocks_used(info->disk_super,
242 super_blocks_used - num_blocks); 250 super_blocks_used - num_blocks);
243 ret = btrfs_del_item(trans, extent_root, &path); 251 ret = btrfs_del_item(trans, extent_root, path);
244 if (extent_root->fs_info->last_insert.objectid > blocknr) 252 if (extent_root->fs_info->last_insert.objectid > blocknr)
245 extent_root->fs_info->last_insert.objectid = blocknr; 253 extent_root->fs_info->last_insert.objectid = blocknr;
246 if (ret) 254 if (ret)
247 BUG(); 255 BUG();
248 } 256 }
249 btrfs_release_path(extent_root, &path); 257 btrfs_release_path(extent_root, path);
258 btrfs_free_path(path);
250 finish_current_insert(trans, extent_root); 259 finish_current_insert(trans, extent_root);
251 return ret; 260 return ret;
252} 261}
@@ -319,7 +328,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
319 *orig_root, u64 num_blocks, u64 search_start, u64 328 *orig_root, u64 num_blocks, u64 search_start, u64
320 search_end, struct btrfs_key *ins) 329 search_end, struct btrfs_key *ins)
321{ 330{
322 struct btrfs_path path; 331 struct btrfs_path *path;
323 struct btrfs_key key; 332 struct btrfs_key key;
324 int ret; 333 int ret;
325 u64 hole_size = 0; 334 u64 hole_size = 0;
@@ -339,24 +348,25 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
339 348
340 ins->flags = 0; 349 ins->flags = 0;
341 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); 350 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
351 path = btrfs_alloc_path();
342 352
343check_failed: 353check_failed:
344 btrfs_init_path(&path); 354 btrfs_init_path(path);
345 ins->objectid = search_start; 355 ins->objectid = search_start;
346 ins->offset = 0; 356 ins->offset = 0;
347 start_found = 0; 357 start_found = 0;
348 ret = btrfs_search_slot(trans, root, ins, &path, 0, 0); 358 ret = btrfs_search_slot(trans, root, ins, path, 0, 0);
349 if (ret < 0) 359 if (ret < 0)
350 goto error; 360 goto error;
351 361
352 if (path.slots[0] > 0) 362 if (path->slots[0] > 0)
353 path.slots[0]--; 363 path->slots[0]--;
354 364
355 while (1) { 365 while (1) {
356 l = btrfs_buffer_leaf(path.nodes[0]); 366 l = btrfs_buffer_leaf(path->nodes[0]);
357 slot = path.slots[0]; 367 slot = path->slots[0];
358 if (slot >= btrfs_header_nritems(&l->header)) { 368 if (slot >= btrfs_header_nritems(&l->header)) {
359 ret = btrfs_next_leaf(root, &path); 369 ret = btrfs_next_leaf(root, path);
360 if (ret == 0) 370 if (ret == 0)
361 continue; 371 continue;
362 if (ret < 0) 372 if (ret < 0)
@@ -387,14 +397,14 @@ check_failed:
387 } 397 }
388 start_found = 1; 398 start_found = 1;
389 last_block = key.objectid + key.offset; 399 last_block = key.objectid + key.offset;
390 path.slots[0]++; 400 path->slots[0]++;
391 } 401 }
392 // FIXME -ENOSPC 402 // FIXME -ENOSPC
393check_pending: 403check_pending:
394 /* we have to make sure we didn't find an extent that has already 404 /* we have to make sure we didn't find an extent that has already
395 * been allocated by the map tree or the original allocation 405 * been allocated by the map tree or the original allocation
396 */ 406 */
397 btrfs_release_path(root, &path); 407 btrfs_release_path(root, path);
398 BUG_ON(ins->objectid < search_start); 408 BUG_ON(ins->objectid < search_start);
399 for (test_block = ins->objectid; 409 for (test_block = ins->objectid;
400 test_block < ins->objectid + total_needed; test_block++) { 410 test_block < ins->objectid + total_needed; test_block++) {
@@ -410,9 +420,11 @@ check_pending:
410 root->fs_info->current_insert.flags = 0; 420 root->fs_info->current_insert.flags = 0;
411 root->fs_info->last_insert.objectid = ins->objectid; 421 root->fs_info->last_insert.objectid = ins->objectid;
412 ins->offset = num_blocks; 422 ins->offset = num_blocks;
423 btrfs_free_path(path);
413 return 0; 424 return 0;
414error: 425error:
415 btrfs_release_path(root, &path); 426 btrfs_release_path(root, path);
427 btrfs_free_path(path);
416 return ret; 428 return ret;
417} 429}
418 430
@@ -533,6 +545,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
533 int ret; 545 int ret;
534 u32 refs; 546 u32 refs;
535 547
548 WARN_ON(*level < 0);
549 WARN_ON(*level >= BTRFS_MAX_LEVEL);
536 ret = lookup_block_ref(trans, root, path->nodes[*level]->b_blocknr, 550 ret = lookup_block_ref(trans, root, path->nodes[*level]->b_blocknr,
537 1, &refs); 551 1, &refs);
538 BUG_ON(ret); 552 BUG_ON(ret);
@@ -542,6 +556,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
542 * walk down to the last node level and free all the leaves 556 * walk down to the last node level and free all the leaves
543 */ 557 */
544 while(*level >= 0) { 558 while(*level >= 0) {
559 WARN_ON(*level < 0);
560 WARN_ON(*level >= BTRFS_MAX_LEVEL);
545 cur = path->nodes[*level]; 561 cur = path->nodes[*level];
546 if (btrfs_header_level(btrfs_buffer_header(cur)) != *level) 562 if (btrfs_header_level(btrfs_buffer_header(cur)) != *level)
547 WARN_ON(1); 563 WARN_ON(1);
@@ -564,6 +580,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
564 continue; 580 continue;
565 } 581 }
566 next = read_tree_block(root, blocknr); 582 next = read_tree_block(root, blocknr);
583 WARN_ON(*level <= 0);
567 if (path->nodes[*level-1]) 584 if (path->nodes[*level-1])
568 btrfs_block_release(root, path->nodes[*level-1]); 585 btrfs_block_release(root, path->nodes[*level-1]);
569 path->nodes[*level-1] = next; 586 path->nodes[*level-1] = next;
@@ -571,6 +588,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
571 path->slots[*level] = 0; 588 path->slots[*level] = 0;
572 } 589 }
573out: 590out:
591 WARN_ON(*level < 0);
592 WARN_ON(*level >= BTRFS_MAX_LEVEL);
574 ret = btrfs_free_extent(trans, root, 593 ret = btrfs_free_extent(trans, root,
575 path->nodes[*level]->b_blocknr, 1, 1); 594 path->nodes[*level]->b_blocknr, 1, 1);
576 btrfs_block_release(root, path->nodes[*level]); 595 btrfs_block_release(root, path->nodes[*level]);
@@ -622,33 +641,36 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
622 int ret = 0; 641 int ret = 0;
623 int wret; 642 int wret;
624 int level; 643 int level;
625 struct btrfs_path path; 644 struct btrfs_path *path;
626 int i; 645 int i;
627 int orig_level; 646 int orig_level;
628 647
629 btrfs_init_path(&path); 648 path = btrfs_alloc_path();
649 BUG_ON(!path);
650 btrfs_init_path(path);
630 651
631 level = btrfs_header_level(btrfs_buffer_header(snap)); 652 level = btrfs_header_level(btrfs_buffer_header(snap));
632 orig_level = level; 653 orig_level = level;
633 path.nodes[level] = snap; 654 path->nodes[level] = snap;
634 path.slots[level] = 0; 655 path->slots[level] = 0;
635 while(1) { 656 while(1) {
636 wret = walk_down_tree(trans, root, &path, &level); 657 wret = walk_down_tree(trans, root, path, &level);
637 if (wret > 0) 658 if (wret > 0)
638 break; 659 break;
639 if (wret < 0) 660 if (wret < 0)
640 ret = wret; 661 ret = wret;
641 662
642 wret = walk_up_tree(trans, root, &path, &level); 663 wret = walk_up_tree(trans, root, path, &level);
643 if (wret > 0) 664 if (wret > 0)
644 break; 665 break;
645 if (wret < 0) 666 if (wret < 0)
646 ret = wret; 667 ret = wret;
647 } 668 }
648 for (i = 0; i <= orig_level; i++) { 669 for (i = 0; i <= orig_level; i++) {
649 if (path.nodes[i]) { 670 if (path->nodes[i]) {
650 btrfs_block_release(root, path.nodes[i]); 671 btrfs_block_release(root, path->nodes[i]);
651 } 672 }
652 } 673 }
674 btrfs_free_path(path);
653 return ret; 675 return ret;
654} 676}