diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-04-02 11:20:42 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-04-02 11:20:42 -0400 |
commit | 5caf2a002901f0fde475371c4bf1c553b51884af (patch) | |
tree | 1c262f723307fe924ea4e960761354f194f3843e /fs | |
parent | 2c90e5d658424bc71b111eb5a972240d5d06fe86 (diff) |
Btrfs: dynamic allocation of path struct
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/dir-item.c | 18 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 100 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 43 | ||||
-rw-r--r-- | fs/btrfs/inode-item.c | 9 | ||||
-rw-r--r-- | fs/btrfs/root-tree.c | 47 | ||||
-rw-r--r-- | fs/btrfs/super.c | 198 |
6 files changed, 243 insertions, 172 deletions
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index f55c89472ac0..baceb1da609f 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c | |||
@@ -9,7 +9,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
9 | objectid, u8 type) | 9 | objectid, u8 type) |
10 | { | 10 | { |
11 | int ret = 0; | 11 | int ret = 0; |
12 | struct btrfs_path path; | 12 | struct btrfs_path *path; |
13 | struct btrfs_dir_item *dir_item; | 13 | struct btrfs_dir_item *dir_item; |
14 | char *name_ptr; | 14 | char *name_ptr; |
15 | struct btrfs_key key; | 15 | struct btrfs_key key; |
@@ -20,24 +20,26 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
20 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); | 20 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); |
21 | ret = btrfs_name_hash(name, name_len, &key.offset); | 21 | ret = btrfs_name_hash(name, name_len, &key.offset); |
22 | BUG_ON(ret); | 22 | BUG_ON(ret); |
23 | btrfs_init_path(&path); | 23 | path = btrfs_alloc_path(); |
24 | btrfs_init_path(path); | ||
24 | data_size = sizeof(*dir_item) + name_len; | 25 | data_size = sizeof(*dir_item) + name_len; |
25 | ret = btrfs_insert_empty_item(trans, root, &path, &key, data_size); | 26 | ret = btrfs_insert_empty_item(trans, root, path, &key, data_size); |
26 | if (ret) | 27 | if (ret) |
27 | goto out; | 28 | goto out; |
28 | 29 | ||
29 | dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), | 30 | dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), |
30 | path.slots[0], | 31 | path->slots[0], |
31 | struct btrfs_dir_item); | 32 | struct btrfs_dir_item); |
32 | btrfs_set_dir_objectid(dir_item, objectid); | 33 | btrfs_set_dir_objectid(dir_item, objectid); |
33 | btrfs_set_dir_type(dir_item, type); | 34 | btrfs_set_dir_type(dir_item, type); |
34 | btrfs_set_dir_flags(dir_item, 0); | 35 | btrfs_set_dir_flags(dir_item, 0); |
35 | btrfs_set_dir_name_len(dir_item, name_len); | 36 | btrfs_set_dir_name_len(dir_item, name_len); |
36 | name_ptr = (char *)(dir_item + 1); | 37 | name_ptr = (char *)(dir_item + 1); |
37 | btrfs_memcpy(root, path.nodes[0]->b_data, name_ptr, name, name_len); | 38 | btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len); |
38 | btrfs_mark_buffer_dirty(path.nodes[0]); | 39 | btrfs_mark_buffer_dirty(path->nodes[0]); |
39 | out: | 40 | out: |
40 | btrfs_release_path(root, &path); | 41 | btrfs_release_path(root, path); |
42 | btrfs_free_path(path); | ||
41 | return ret; | 43 | return ret; |
42 | } | 44 | } |
43 | 45 | ||
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 | |||
15 | static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root | 15 | static 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 | |||
50 | static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root | 53 | static 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) | |||
200 | static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 206 | static 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 | ||
343 | check_failed: | 353 | check_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 |
393 | check_pending: | 403 | check_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; |
414 | error: | 425 | error: |
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 | } |
573 | out: | 590 | out: |
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 | } |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index c3992b7b0c60..e7510ac5559d 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -13,9 +13,11 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans, | |||
13 | int ret = 0; | 13 | int ret = 0; |
14 | struct btrfs_file_extent_item *item; | 14 | struct btrfs_file_extent_item *item; |
15 | struct btrfs_key file_key; | 15 | struct btrfs_key file_key; |
16 | struct btrfs_path path; | 16 | struct btrfs_path *path; |
17 | 17 | ||
18 | btrfs_init_path(&path); | 18 | path = btrfs_alloc_path(); |
19 | BUG_ON(!path); | ||
20 | btrfs_init_path(path); | ||
19 | ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block, | 21 | ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block, |
20 | (u64)-1, objectid, &ins); | 22 | (u64)-1, objectid, &ins); |
21 | BUG_ON(ret); | 23 | BUG_ON(ret); |
@@ -24,19 +26,20 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans, | |||
24 | file_key.flags = 0; | 26 | file_key.flags = 0; |
25 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); | 27 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); |
26 | 28 | ||
27 | ret = btrfs_insert_empty_item(trans, root, &path, &file_key, | 29 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, |
28 | sizeof(*item)); | 30 | sizeof(*item)); |
29 | BUG_ON(ret); | 31 | BUG_ON(ret); |
30 | item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 32 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
31 | struct btrfs_file_extent_item); | 33 | struct btrfs_file_extent_item); |
32 | btrfs_set_file_extent_disk_blocknr(item, ins.objectid); | 34 | btrfs_set_file_extent_disk_blocknr(item, ins.objectid); |
33 | btrfs_set_file_extent_disk_num_blocks(item, ins.offset); | 35 | btrfs_set_file_extent_disk_num_blocks(item, ins.offset); |
34 | btrfs_set_file_extent_offset(item, 0); | 36 | btrfs_set_file_extent_offset(item, 0); |
35 | btrfs_set_file_extent_num_blocks(item, ins.offset); | 37 | btrfs_set_file_extent_num_blocks(item, ins.offset); |
36 | btrfs_set_file_extent_generation(item, trans->transid); | 38 | btrfs_set_file_extent_generation(item, trans->transid); |
37 | btrfs_mark_buffer_dirty(path.nodes[0]); | 39 | btrfs_mark_buffer_dirty(path->nodes[0]); |
38 | *result = ins.objectid; | 40 | *result = ins.objectid; |
39 | btrfs_release_path(root, &path); | 41 | btrfs_release_path(root, path); |
42 | btrfs_free_path(path); | ||
40 | return 0; | 43 | return 0; |
41 | } | 44 | } |
42 | 45 | ||
@@ -65,25 +68,28 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | |||
65 | { | 68 | { |
66 | int ret; | 69 | int ret; |
67 | struct btrfs_key file_key; | 70 | struct btrfs_key file_key; |
68 | struct btrfs_path path; | 71 | struct btrfs_path *path; |
69 | struct btrfs_csum_item *item; | 72 | struct btrfs_csum_item *item; |
70 | 73 | ||
71 | btrfs_init_path(&path); | 74 | path = btrfs_alloc_path(); |
75 | BUG_ON(!path); | ||
76 | btrfs_init_path(path); | ||
72 | file_key.objectid = objectid; | 77 | file_key.objectid = objectid; |
73 | file_key.offset = offset; | 78 | file_key.offset = offset; |
74 | file_key.flags = 0; | 79 | file_key.flags = 0; |
75 | btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); | 80 | btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); |
76 | ret = btrfs_insert_empty_item(trans, root, &path, &file_key, | 81 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, |
77 | BTRFS_CSUM_SIZE); | 82 | BTRFS_CSUM_SIZE); |
78 | if (ret != 0 && ret != -EEXIST) | 83 | if (ret != 0 && ret != -EEXIST) |
79 | goto fail; | 84 | goto fail; |
80 | item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 85 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
81 | struct btrfs_csum_item); | 86 | struct btrfs_csum_item); |
82 | ret = 0; | 87 | ret = 0; |
83 | ret = btrfs_csum_data(root, data, len, item->csum); | 88 | ret = btrfs_csum_data(root, data, len, item->csum); |
84 | btrfs_mark_buffer_dirty(path.nodes[0]); | 89 | btrfs_mark_buffer_dirty(path->nodes[0]); |
85 | fail: | 90 | fail: |
86 | btrfs_release_path(root, &path); | 91 | btrfs_release_path(root, path); |
92 | btrfs_free_path(path); | ||
87 | return ret; | 93 | return ret; |
88 | } | 94 | } |
89 | 95 | ||
@@ -93,19 +99,21 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root, | |||
93 | { | 99 | { |
94 | int ret; | 100 | int ret; |
95 | struct btrfs_key file_key; | 101 | struct btrfs_key file_key; |
96 | struct btrfs_path path; | 102 | struct btrfs_path *path; |
97 | struct btrfs_csum_item *item; | 103 | struct btrfs_csum_item *item; |
98 | char result[BTRFS_CSUM_SIZE]; | 104 | char result[BTRFS_CSUM_SIZE]; |
99 | 105 | ||
100 | btrfs_init_path(&path); | 106 | path = btrfs_alloc_path(); |
107 | BUG_ON(!path); | ||
108 | btrfs_init_path(path); | ||
101 | file_key.objectid = objectid; | 109 | file_key.objectid = objectid; |
102 | file_key.offset = offset; | 110 | file_key.offset = offset; |
103 | file_key.flags = 0; | 111 | file_key.flags = 0; |
104 | btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); | 112 | btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); |
105 | ret = btrfs_search_slot(NULL, root, &file_key, &path, 0, 0); | 113 | ret = btrfs_search_slot(NULL, root, &file_key, path, 0, 0); |
106 | if (ret) | 114 | if (ret) |
107 | goto fail; | 115 | goto fail; |
108 | item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 116 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
109 | struct btrfs_csum_item); | 117 | struct btrfs_csum_item); |
110 | ret = 0; | 118 | ret = 0; |
111 | ret = btrfs_csum_data(root, data, len, result); | 119 | ret = btrfs_csum_data(root, data, len, result); |
@@ -113,7 +121,8 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root, | |||
113 | if (memcmp(result, item->csum, BTRFS_CSUM_SIZE)) | 121 | if (memcmp(result, item->csum, BTRFS_CSUM_SIZE)) |
114 | ret = 1; | 122 | ret = 1; |
115 | fail: | 123 | fail: |
116 | btrfs_release_path(root, &path); | 124 | btrfs_release_path(root, path); |
125 | btrfs_free_path(path); | ||
117 | return ret; | 126 | return ret; |
118 | } | 127 | } |
119 | 128 | ||
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c index 8d8c26a6c1a0..6bfa980790c2 100644 --- a/fs/btrfs/inode-item.c +++ b/fs/btrfs/inode-item.c | |||
@@ -7,7 +7,7 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root | |||
7 | *root, u64 objectid, struct btrfs_inode_item | 7 | *root, u64 objectid, struct btrfs_inode_item |
8 | *inode_item) | 8 | *inode_item) |
9 | { | 9 | { |
10 | struct btrfs_path path; | 10 | struct btrfs_path *path; |
11 | struct btrfs_key key; | 11 | struct btrfs_key key; |
12 | int ret; | 12 | int ret; |
13 | key.objectid = objectid; | 13 | key.objectid = objectid; |
@@ -15,10 +15,13 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root | |||
15 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 15 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
16 | key.offset = 0; | 16 | key.offset = 0; |
17 | 17 | ||
18 | btrfs_init_path(&path); | 18 | path = btrfs_alloc_path(); |
19 | BUG_ON(!path); | ||
20 | btrfs_init_path(path); | ||
19 | ret = btrfs_insert_item(trans, root, &key, inode_item, | 21 | ret = btrfs_insert_item(trans, root, &key, inode_item, |
20 | sizeof(*inode_item)); | 22 | sizeof(*inode_item)); |
21 | btrfs_release_path(root, &path); | 23 | btrfs_release_path(root, path); |
24 | btrfs_free_path(path); | ||
22 | return ret; | 25 | return ret; |
23 | } | 26 | } |
24 | 27 | ||
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index f37dab87de16..ddc1c13a5352 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
@@ -6,7 +6,7 @@ | |||
6 | int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | 6 | int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, |
7 | struct btrfs_root_item *item, struct btrfs_key *key) | 7 | struct btrfs_root_item *item, struct btrfs_key *key) |
8 | { | 8 | { |
9 | struct btrfs_path path; | 9 | struct btrfs_path *path; |
10 | struct btrfs_key search_key; | 10 | struct btrfs_key search_key; |
11 | struct btrfs_leaf *l; | 11 | struct btrfs_leaf *l; |
12 | int ret; | 12 | int ret; |
@@ -16,14 +16,16 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | |||
16 | search_key.flags = (u32)-1; | 16 | search_key.flags = (u32)-1; |
17 | search_key.offset = (u32)-1; | 17 | search_key.offset = (u32)-1; |
18 | 18 | ||
19 | btrfs_init_path(&path); | 19 | path = btrfs_alloc_path(); |
20 | ret = btrfs_search_slot(NULL, root, &search_key, &path, 0, 0); | 20 | BUG_ON(!path); |
21 | btrfs_init_path(path); | ||
22 | ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); | ||
21 | if (ret < 0) | 23 | if (ret < 0) |
22 | goto out; | 24 | goto out; |
23 | BUG_ON(ret == 0); | 25 | BUG_ON(ret == 0); |
24 | l = btrfs_buffer_leaf(path.nodes[0]); | 26 | l = btrfs_buffer_leaf(path->nodes[0]); |
25 | BUG_ON(path.slots[0] == 0); | 27 | BUG_ON(path->slots[0] == 0); |
26 | slot = path.slots[0] - 1; | 28 | slot = path->slots[0] - 1; |
27 | if (btrfs_disk_key_objectid(&l->items[slot].key) != objectid) { | 29 | if (btrfs_disk_key_objectid(&l->items[slot].key) != objectid) { |
28 | ret = 1; | 30 | ret = 1; |
29 | goto out; | 31 | goto out; |
@@ -31,9 +33,10 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | |||
31 | memcpy(item, btrfs_item_ptr(l, slot, struct btrfs_root_item), | 33 | memcpy(item, btrfs_item_ptr(l, slot, struct btrfs_root_item), |
32 | sizeof(*item)); | 34 | sizeof(*item)); |
33 | btrfs_disk_key_to_cpu(key, &l->items[slot].key); | 35 | btrfs_disk_key_to_cpu(key, &l->items[slot].key); |
34 | btrfs_release_path(root, &path); | ||
35 | ret = 0; | 36 | ret = 0; |
36 | out: | 37 | out: |
38 | btrfs_release_path(root, path); | ||
39 | btrfs_free_path(path); | ||
37 | return ret; | 40 | return ret; |
38 | } | 41 | } |
39 | 42 | ||
@@ -41,24 +44,27 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root | |||
41 | *root, struct btrfs_key *key, struct btrfs_root_item | 44 | *root, struct btrfs_key *key, struct btrfs_root_item |
42 | *item) | 45 | *item) |
43 | { | 46 | { |
44 | struct btrfs_path path; | 47 | struct btrfs_path *path; |
45 | struct btrfs_leaf *l; | 48 | struct btrfs_leaf *l; |
46 | int ret; | 49 | int ret; |
47 | int slot; | 50 | int slot; |
48 | struct btrfs_root_item *update_item; | 51 | struct btrfs_root_item *update_item; |
49 | 52 | ||
50 | btrfs_init_path(&path); | 53 | path = btrfs_alloc_path(); |
51 | ret = btrfs_search_slot(trans, root, key, &path, 0, 1); | 54 | BUG_ON(!path); |
55 | btrfs_init_path(path); | ||
56 | ret = btrfs_search_slot(trans, root, key, path, 0, 1); | ||
52 | if (ret < 0) | 57 | if (ret < 0) |
53 | goto out; | 58 | goto out; |
54 | BUG_ON(ret != 0); | 59 | BUG_ON(ret != 0); |
55 | l = btrfs_buffer_leaf(path.nodes[0]); | 60 | l = btrfs_buffer_leaf(path->nodes[0]); |
56 | slot = path.slots[0]; | 61 | slot = path->slots[0]; |
57 | update_item = btrfs_item_ptr(l, slot, struct btrfs_root_item); | 62 | update_item = btrfs_item_ptr(l, slot, struct btrfs_root_item); |
58 | btrfs_memcpy(root, l, update_item, item, sizeof(*item)); | 63 | btrfs_memcpy(root, l, update_item, item, sizeof(*item)); |
59 | btrfs_mark_buffer_dirty(path.nodes[0]); | 64 | btrfs_mark_buffer_dirty(path->nodes[0]); |
60 | out: | 65 | out: |
61 | btrfs_release_path(root, &path); | 66 | btrfs_release_path(root, path); |
67 | btrfs_free_path(path); | ||
62 | return ret; | 68 | return ret; |
63 | } | 69 | } |
64 | 70 | ||
@@ -75,16 +81,19 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root | |||
75 | int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 81 | int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
76 | struct btrfs_key *key) | 82 | struct btrfs_key *key) |
77 | { | 83 | { |
78 | struct btrfs_path path; | 84 | struct btrfs_path *path; |
79 | int ret; | 85 | int ret; |
80 | 86 | ||
81 | btrfs_init_path(&path); | 87 | path = btrfs_alloc_path(); |
82 | ret = btrfs_search_slot(trans, root, key, &path, -1, 1); | 88 | BUG_ON(!path); |
89 | btrfs_init_path(path); | ||
90 | ret = btrfs_search_slot(trans, root, key, path, -1, 1); | ||
83 | if (ret < 0) | 91 | if (ret < 0) |
84 | goto out; | 92 | goto out; |
85 | BUG_ON(ret != 0); | 93 | BUG_ON(ret != 0); |
86 | ret = btrfs_del_item(trans, root, &path); | 94 | ret = btrfs_del_item(trans, root, path); |
87 | out: | 95 | out: |
88 | btrfs_release_path(root, &path); | 96 | btrfs_release_path(root, path); |
97 | btrfs_free_path(path); | ||
89 | return ret; | 98 | return ret; |
90 | } | 99 | } |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 6969b672b570..c260fcad17b3 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -35,25 +35,27 @@ static int check_inode(struct inode *inode) | |||
35 | 35 | ||
36 | static void btrfs_read_locked_inode(struct inode *inode) | 36 | static void btrfs_read_locked_inode(struct inode *inode) |
37 | { | 37 | { |
38 | struct btrfs_path path; | 38 | struct btrfs_path *path; |
39 | struct btrfs_inode_item *inode_item; | 39 | struct btrfs_inode_item *inode_item; |
40 | struct btrfs_root *root = btrfs_sb(inode->i_sb); | 40 | struct btrfs_root *root = btrfs_sb(inode->i_sb); |
41 | int ret; | 41 | int ret; |
42 | 42 | ||
43 | btrfs_init_path(&path); | 43 | path = btrfs_alloc_path(); |
44 | BUG_ON(!path); | ||
45 | btrfs_init_path(path); | ||
44 | mutex_lock(&root->fs_info->fs_mutex); | 46 | mutex_lock(&root->fs_info->fs_mutex); |
45 | 47 | ||
46 | check_inode(inode); | 48 | check_inode(inode); |
47 | ret = btrfs_lookup_inode(NULL, root, &path, inode->i_ino, 0); | 49 | ret = btrfs_lookup_inode(NULL, root, path, inode->i_ino, 0); |
48 | if (ret) { | 50 | if (ret) { |
49 | btrfs_release_path(root, &path); | 51 | btrfs_release_path(root, path); |
50 | mutex_unlock(&root->fs_info->fs_mutex); | 52 | mutex_unlock(&root->fs_info->fs_mutex); |
51 | make_bad_inode(inode); | 53 | make_bad_inode(inode); |
52 | return; | 54 | return; |
53 | } | 55 | } |
54 | check_inode(inode); | 56 | check_inode(inode); |
55 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), | 57 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), |
56 | path.slots[0], | 58 | path->slots[0], |
57 | struct btrfs_inode_item); | 59 | struct btrfs_inode_item); |
58 | 60 | ||
59 | inode->i_mode = btrfs_inode_mode(inode_item); | 61 | inode->i_mode = btrfs_inode_mode(inode_item); |
@@ -69,7 +71,11 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
69 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime); | 71 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime); |
70 | inode->i_blocks = btrfs_inode_nblocks(inode_item); | 72 | inode->i_blocks = btrfs_inode_nblocks(inode_item); |
71 | inode->i_generation = btrfs_inode_generation(inode_item); | 73 | inode->i_generation = btrfs_inode_generation(inode_item); |
72 | btrfs_release_path(root, &path); | 74 | |
75 | btrfs_release_path(root, path); | ||
76 | btrfs_free_path(path); | ||
77 | inode_item = NULL; | ||
78 | |||
73 | mutex_unlock(&root->fs_info->fs_mutex); | 79 | mutex_unlock(&root->fs_info->fs_mutex); |
74 | check_inode(inode); | 80 | check_inode(inode); |
75 | switch (inode->i_mode & S_IFMT) { | 81 | switch (inode->i_mode & S_IFMT) { |
@@ -101,15 +107,17 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
101 | struct inode *dir, | 107 | struct inode *dir, |
102 | struct dentry *dentry) | 108 | struct dentry *dentry) |
103 | { | 109 | { |
104 | struct btrfs_path path; | 110 | struct btrfs_path *path; |
105 | const char *name = dentry->d_name.name; | 111 | const char *name = dentry->d_name.name; |
106 | int name_len = dentry->d_name.len; | 112 | int name_len = dentry->d_name.len; |
107 | int ret; | 113 | int ret; |
108 | u64 objectid; | 114 | u64 objectid; |
109 | struct btrfs_dir_item *di; | 115 | struct btrfs_dir_item *di; |
110 | 116 | ||
111 | btrfs_init_path(&path); | 117 | path = btrfs_alloc_path(); |
112 | ret = btrfs_lookup_dir_item(trans, root, &path, dir->i_ino, | 118 | BUG_ON(!path); |
119 | btrfs_init_path(path); | ||
120 | ret = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, | ||
113 | name, name_len, -1); | 121 | name, name_len, -1); |
114 | if (ret < 0) | 122 | if (ret < 0) |
115 | goto err; | 123 | goto err; |
@@ -117,15 +125,16 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
117 | ret = -ENOENT; | 125 | ret = -ENOENT; |
118 | goto err; | 126 | goto err; |
119 | } | 127 | } |
120 | di = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 128 | di = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
121 | struct btrfs_dir_item); | 129 | struct btrfs_dir_item); |
122 | objectid = btrfs_dir_objectid(di); | 130 | objectid = btrfs_dir_objectid(di); |
123 | 131 | ||
124 | ret = btrfs_del_item(trans, root, &path); | 132 | ret = btrfs_del_item(trans, root, path); |
125 | BUG_ON(ret); | 133 | BUG_ON(ret); |
126 | dentry->d_inode->i_ctime = dir->i_ctime; | 134 | dentry->d_inode->i_ctime = dir->i_ctime; |
127 | err: | 135 | err: |
128 | btrfs_release_path(root, &path); | 136 | btrfs_release_path(root, path); |
137 | btrfs_free_path(path); | ||
129 | if (ret == 0) | 138 | if (ret == 0) |
130 | inode_dec_link_count(dentry->d_inode); | 139 | inode_dec_link_count(dentry->d_inode); |
131 | return ret; | 140 | return ret; |
@@ -152,30 +161,32 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
152 | int err; | 161 | int err; |
153 | int ret; | 162 | int ret; |
154 | struct btrfs_root *root = btrfs_sb(dir->i_sb); | 163 | struct btrfs_root *root = btrfs_sb(dir->i_sb); |
155 | struct btrfs_path path; | 164 | struct btrfs_path *path; |
156 | struct btrfs_key key; | 165 | struct btrfs_key key; |
157 | struct btrfs_trans_handle *trans; | 166 | struct btrfs_trans_handle *trans; |
158 | struct btrfs_disk_key *found_key; | 167 | struct btrfs_disk_key *found_key; |
159 | struct btrfs_leaf *leaf; | 168 | struct btrfs_leaf *leaf; |
160 | 169 | ||
161 | btrfs_init_path(&path); | 170 | path = btrfs_alloc_path(); |
171 | BUG_ON(!path); | ||
172 | btrfs_init_path(path); | ||
162 | mutex_lock(&root->fs_info->fs_mutex); | 173 | mutex_lock(&root->fs_info->fs_mutex); |
163 | trans = btrfs_start_transaction(root, 1); | 174 | trans = btrfs_start_transaction(root, 1); |
164 | key.objectid = inode->i_ino; | 175 | key.objectid = inode->i_ino; |
165 | key.offset = (u64)-1; | 176 | key.offset = (u64)-1; |
166 | key.flags = 0; | 177 | key.flags = 0; |
167 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); | 178 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); |
168 | ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); | 179 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
169 | if (ret < 0) { | 180 | if (ret < 0) { |
170 | err = ret; | 181 | err = ret; |
171 | goto out; | 182 | goto out; |
172 | } | 183 | } |
173 | 184 | ||
174 | BUG_ON(ret == 0); | 185 | BUG_ON(ret == 0); |
175 | BUG_ON(path.slots[0] == 0); | 186 | BUG_ON(path->slots[0] == 0); |
176 | path.slots[0]--; | 187 | path->slots[0]--; |
177 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 188 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
178 | found_key = &leaf->items[path.slots[0]].key; | 189 | found_key = &leaf->items[path->slots[0]].key; |
179 | if (btrfs_disk_key_objectid(found_key) != inode->i_ino) { | 190 | if (btrfs_disk_key_objectid(found_key) != inode->i_ino) { |
180 | err = -ENOENT; | 191 | err = -ENOENT; |
181 | goto out; | 192 | goto out; |
@@ -185,11 +196,11 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
185 | err = -ENOTEMPTY; | 196 | err = -ENOTEMPTY; |
186 | goto out; | 197 | goto out; |
187 | } | 198 | } |
188 | ret = btrfs_del_item(trans, root, &path); | 199 | ret = btrfs_del_item(trans, root, path); |
189 | BUG_ON(ret); | 200 | BUG_ON(ret); |
190 | btrfs_release_path(root, &path); | 201 | btrfs_release_path(root, path); |
191 | key.offset = 1; | 202 | key.offset = 1; |
192 | ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); | 203 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
193 | if (ret < 0) { | 204 | if (ret < 0) { |
194 | err = ret; | 205 | err = ret; |
195 | goto out; | 206 | goto out; |
@@ -198,12 +209,13 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
198 | err = -ENOTEMPTY; | 209 | err = -ENOTEMPTY; |
199 | goto out; | 210 | goto out; |
200 | } | 211 | } |
201 | ret = btrfs_del_item(trans, root, &path); | 212 | ret = btrfs_del_item(trans, root, path); |
202 | if (ret) { | 213 | if (ret) { |
203 | err = ret; | 214 | err = ret; |
204 | goto out; | 215 | goto out; |
205 | } | 216 | } |
206 | btrfs_release_path(root, &path); | 217 | btrfs_release_path(root, path); |
218 | btrfs_free_path(path); | ||
207 | 219 | ||
208 | /* now the directory is empty */ | 220 | /* now the directory is empty */ |
209 | err = btrfs_unlink_trans(trans, root, dir, dentry); | 221 | err = btrfs_unlink_trans(trans, root, dir, dentry); |
@@ -223,33 +235,36 @@ static int btrfs_free_inode(struct btrfs_trans_handle *trans, | |||
223 | struct inode *inode) | 235 | struct inode *inode) |
224 | { | 236 | { |
225 | u64 objectid = inode->i_ino; | 237 | u64 objectid = inode->i_ino; |
226 | struct btrfs_path path; | 238 | struct btrfs_path *path; |
227 | struct btrfs_inode_map_item *map; | 239 | struct btrfs_inode_map_item *map; |
228 | struct btrfs_key stat_data_key; | 240 | struct btrfs_key stat_data_key; |
229 | int ret; | 241 | int ret; |
242 | |||
230 | clear_inode(inode); | 243 | clear_inode(inode); |
231 | btrfs_init_path(&path); | 244 | |
232 | ret = btrfs_lookup_inode_map(trans, root, &path, objectid, -1); | 245 | path = btrfs_alloc_path(); |
246 | BUG_ON(!path); | ||
247 | btrfs_init_path(path); | ||
248 | ret = btrfs_lookup_inode_map(trans, root, path, objectid, -1); | ||
233 | if (ret) { | 249 | if (ret) { |
234 | if (ret > 0) | 250 | if (ret > 0) |
235 | ret = -ENOENT; | 251 | ret = -ENOENT; |
236 | btrfs_release_path(root, &path); | ||
237 | goto error; | 252 | goto error; |
238 | } | 253 | } |
239 | map = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 254 | map = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
240 | struct btrfs_inode_map_item); | 255 | struct btrfs_inode_map_item); |
241 | btrfs_disk_key_to_cpu(&stat_data_key, &map->key); | 256 | btrfs_disk_key_to_cpu(&stat_data_key, &map->key); |
242 | ret = btrfs_del_item(trans, root->fs_info->inode_root, &path); | 257 | ret = btrfs_del_item(trans, root->fs_info->inode_root, path); |
243 | BUG_ON(ret); | 258 | BUG_ON(ret); |
244 | btrfs_release_path(root, &path); | 259 | btrfs_release_path(root, path); |
245 | btrfs_init_path(&path); | ||
246 | 260 | ||
247 | ret = btrfs_lookup_inode(trans, root, &path, objectid, -1); | 261 | ret = btrfs_lookup_inode(trans, root, path, objectid, -1); |
248 | BUG_ON(ret); | 262 | BUG_ON(ret); |
249 | ret = btrfs_del_item(trans, root, &path); | 263 | ret = btrfs_del_item(trans, root, path); |
250 | BUG_ON(ret); | 264 | BUG_ON(ret); |
251 | btrfs_release_path(root, &path); | ||
252 | error: | 265 | error: |
266 | btrfs_release_path(root, path); | ||
267 | btrfs_free_path(path); | ||
253 | return ret; | 268 | return ret; |
254 | } | 269 | } |
255 | 270 | ||
@@ -258,7 +273,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
258 | struct inode *inode) | 273 | struct inode *inode) |
259 | { | 274 | { |
260 | int ret; | 275 | int ret; |
261 | struct btrfs_path path; | 276 | struct btrfs_path *path; |
262 | struct btrfs_key key; | 277 | struct btrfs_key key; |
263 | struct btrfs_disk_key *found_key; | 278 | struct btrfs_disk_key *found_key; |
264 | struct btrfs_leaf *leaf; | 279 | struct btrfs_leaf *leaf; |
@@ -267,24 +282,25 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
267 | u64 extent_num_blocks = 0; | 282 | u64 extent_num_blocks = 0; |
268 | int found_extent; | 283 | int found_extent; |
269 | 284 | ||
285 | path = btrfs_alloc_path(); | ||
286 | BUG_ON(!path); | ||
270 | /* FIXME, add redo link to tree so we don't leak on crash */ | 287 | /* FIXME, add redo link to tree so we don't leak on crash */ |
271 | key.objectid = inode->i_ino; | 288 | key.objectid = inode->i_ino; |
272 | key.offset = (u64)-1; | 289 | key.offset = (u64)-1; |
273 | key.flags = 0; | 290 | key.flags = 0; |
274 | btrfs_set_key_type(&key, BTRFS_CSUM_ITEM_KEY); | 291 | btrfs_set_key_type(&key, BTRFS_CSUM_ITEM_KEY); |
275 | while(1) { | 292 | while(1) { |
276 | btrfs_init_path(&path); | 293 | btrfs_init_path(path); |
277 | ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); | 294 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
278 | if (ret < 0) { | 295 | if (ret < 0) { |
279 | btrfs_release_path(root, &path); | ||
280 | goto error; | 296 | goto error; |
281 | } | 297 | } |
282 | if (ret > 0) { | 298 | if (ret > 0) { |
283 | BUG_ON(path.slots[0] == 0); | 299 | BUG_ON(path->slots[0] == 0); |
284 | path.slots[0]--; | 300 | path->slots[0]--; |
285 | } | 301 | } |
286 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 302 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
287 | found_key = &leaf->items[path.slots[0]].key; | 303 | found_key = &leaf->items[path->slots[0]].key; |
288 | if (btrfs_disk_key_objectid(found_key) != inode->i_ino) | 304 | if (btrfs_disk_key_objectid(found_key) != inode->i_ino) |
289 | break; | 305 | break; |
290 | if (btrfs_disk_key_type(found_key) != BTRFS_CSUM_ITEM_KEY && | 306 | if (btrfs_disk_key_type(found_key) != BTRFS_CSUM_ITEM_KEY && |
@@ -293,8 +309,8 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
293 | if (btrfs_disk_key_offset(found_key) < inode->i_size) | 309 | if (btrfs_disk_key_offset(found_key) < inode->i_size) |
294 | break; | 310 | break; |
295 | if (btrfs_disk_key_type(found_key) == BTRFS_EXTENT_DATA_KEY) { | 311 | if (btrfs_disk_key_type(found_key) == BTRFS_EXTENT_DATA_KEY) { |
296 | fi = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), | 312 | fi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), |
297 | path.slots[0], | 313 | path->slots[0], |
298 | struct btrfs_file_extent_item); | 314 | struct btrfs_file_extent_item); |
299 | extent_start = btrfs_file_extent_disk_blocknr(fi); | 315 | extent_start = btrfs_file_extent_disk_blocknr(fi); |
300 | extent_num_blocks = | 316 | extent_num_blocks = |
@@ -305,18 +321,19 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
305 | } else { | 321 | } else { |
306 | found_extent = 0; | 322 | found_extent = 0; |
307 | } | 323 | } |
308 | ret = btrfs_del_item(trans, root, &path); | 324 | ret = btrfs_del_item(trans, root, path); |
309 | BUG_ON(ret); | 325 | BUG_ON(ret); |
310 | btrfs_release_path(root, &path); | 326 | btrfs_release_path(root, path); |
311 | if (found_extent) { | 327 | if (found_extent) { |
312 | ret = btrfs_free_extent(trans, root, extent_start, | 328 | ret = btrfs_free_extent(trans, root, extent_start, |
313 | extent_num_blocks, 0); | 329 | extent_num_blocks, 0); |
314 | BUG_ON(ret); | 330 | BUG_ON(ret); |
315 | } | 331 | } |
316 | } | 332 | } |
317 | btrfs_release_path(root, &path); | ||
318 | ret = 0; | 333 | ret = 0; |
319 | error: | 334 | error: |
335 | btrfs_release_path(root, path); | ||
336 | btrfs_free_path(path); | ||
320 | return ret; | 337 | return ret; |
321 | } | 338 | } |
322 | 339 | ||
@@ -351,23 +368,26 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, | |||
351 | const char *name = dentry->d_name.name; | 368 | const char *name = dentry->d_name.name; |
352 | int namelen = dentry->d_name.len; | 369 | int namelen = dentry->d_name.len; |
353 | struct btrfs_dir_item *di; | 370 | struct btrfs_dir_item *di; |
354 | struct btrfs_path path; | 371 | struct btrfs_path *path; |
355 | struct btrfs_root *root = btrfs_sb(dir->i_sb); | 372 | struct btrfs_root *root = btrfs_sb(dir->i_sb); |
356 | int ret; | 373 | int ret; |
357 | 374 | ||
358 | btrfs_init_path(&path); | 375 | path = btrfs_alloc_path(); |
359 | ret = btrfs_lookup_dir_item(NULL, root, &path, dir->i_ino, name, | 376 | BUG_ON(!path); |
377 | btrfs_init_path(path); | ||
378 | ret = btrfs_lookup_dir_item(NULL, root, path, dir->i_ino, name, | ||
360 | namelen, 0); | 379 | namelen, 0); |
361 | if (ret || !btrfs_match_dir_item_name(root, &path, name, namelen)) { | 380 | if (ret || !btrfs_match_dir_item_name(root, path, name, namelen)) { |
362 | *ino = 0; | 381 | *ino = 0; |
363 | ret = 0; | 382 | ret = 0; |
364 | goto out; | 383 | goto out; |
365 | } | 384 | } |
366 | di = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 385 | di = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
367 | struct btrfs_dir_item); | 386 | struct btrfs_dir_item); |
368 | *ino = btrfs_dir_objectid(di); | 387 | *ino = btrfs_dir_objectid(di); |
369 | out: | 388 | out: |
370 | btrfs_release_path(root, &path); | 389 | btrfs_release_path(root, path); |
390 | btrfs_free_path(path); | ||
371 | check_inode(dir); | 391 | check_inode(dir); |
372 | return ret; | 392 | return ret; |
373 | } | 393 | } |
@@ -405,7 +425,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
405 | struct btrfs_item *item; | 425 | struct btrfs_item *item; |
406 | struct btrfs_dir_item *di; | 426 | struct btrfs_dir_item *di; |
407 | struct btrfs_key key; | 427 | struct btrfs_key key; |
408 | struct btrfs_path path; | 428 | struct btrfs_path *path; |
409 | int ret; | 429 | int ret; |
410 | u32 nritems; | 430 | u32 nritems; |
411 | struct btrfs_leaf *leaf; | 431 | struct btrfs_leaf *leaf; |
@@ -419,27 +439,28 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
419 | key.flags = 0; | 439 | key.flags = 0; |
420 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); | 440 | btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); |
421 | key.offset = filp->f_pos; | 441 | key.offset = filp->f_pos; |
422 | btrfs_init_path(&path); | 442 | path = btrfs_alloc_path(); |
423 | ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); | 443 | btrfs_init_path(path); |
444 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
424 | if (ret < 0) { | 445 | if (ret < 0) { |
425 | goto err; | 446 | goto err; |
426 | } | 447 | } |
427 | advance = 0; | 448 | advance = 0; |
428 | while(1) { | 449 | while(1) { |
429 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 450 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
430 | nritems = btrfs_header_nritems(&leaf->header); | 451 | nritems = btrfs_header_nritems(&leaf->header); |
431 | slot = path.slots[0]; | 452 | slot = path->slots[0]; |
432 | if (advance || slot >= nritems) { | 453 | if (advance || slot >= nritems) { |
433 | if (slot >= nritems -1) { | 454 | if (slot >= nritems -1) { |
434 | ret = btrfs_next_leaf(root, &path); | 455 | ret = btrfs_next_leaf(root, path); |
435 | if (ret) | 456 | if (ret) |
436 | break; | 457 | break; |
437 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 458 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
438 | nritems = btrfs_header_nritems(&leaf->header); | 459 | nritems = btrfs_header_nritems(&leaf->header); |
439 | slot = path.slots[0]; | 460 | slot = path->slots[0]; |
440 | } else { | 461 | } else { |
441 | slot++; | 462 | slot++; |
442 | path.slots[0]++; | 463 | path->slots[0]++; |
443 | } | 464 | } |
444 | } | 465 | } |
445 | advance = 1; | 466 | advance = 1; |
@@ -465,7 +486,8 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
465 | } | 486 | } |
466 | ret = 0; | 487 | ret = 0; |
467 | err: | 488 | err: |
468 | btrfs_release_path(root, &path); | 489 | btrfs_release_path(root, path); |
490 | btrfs_free_path(path); | ||
469 | mutex_unlock(&root->fs_info->fs_mutex); | 491 | mutex_unlock(&root->fs_info->fs_mutex); |
470 | return ret; | 492 | return ret; |
471 | } | 493 | } |
@@ -548,26 +570,29 @@ static int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
548 | struct inode *inode) | 570 | struct inode *inode) |
549 | { | 571 | { |
550 | struct btrfs_inode_item *inode_item; | 572 | struct btrfs_inode_item *inode_item; |
551 | struct btrfs_path path; | 573 | struct btrfs_path *path; |
552 | int ret; | 574 | int ret; |
553 | 575 | ||
554 | btrfs_init_path(&path); | 576 | path = btrfs_alloc_path(); |
577 | BUG_ON(!path); | ||
578 | btrfs_init_path(path); | ||
555 | 579 | ||
556 | ret = btrfs_lookup_inode(trans, root, &path, inode->i_ino, 1); | 580 | ret = btrfs_lookup_inode(trans, root, path, inode->i_ino, 1); |
557 | if (ret) { | 581 | if (ret) { |
558 | if (ret > 0) | 582 | if (ret > 0) |
559 | ret = -ENOENT; | 583 | ret = -ENOENT; |
560 | goto failed; | 584 | goto failed; |
561 | } | 585 | } |
562 | 586 | ||
563 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), | 587 | inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), |
564 | path.slots[0], | 588 | path->slots[0], |
565 | struct btrfs_inode_item); | 589 | struct btrfs_inode_item); |
566 | 590 | ||
567 | fill_inode_item(inode_item, inode); | 591 | fill_inode_item(inode_item, inode); |
568 | btrfs_mark_buffer_dirty(path.nodes[0]); | 592 | btrfs_mark_buffer_dirty(path->nodes[0]); |
569 | failed: | 593 | failed: |
570 | btrfs_release_path(root, &path); | 594 | btrfs_release_path(root, path); |
595 | btrfs_free_path(path); | ||
571 | check_inode(inode); | 596 | check_inode(inode); |
572 | return 0; | 597 | return 0; |
573 | } | 598 | } |
@@ -799,38 +824,39 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock, | |||
799 | u64 extent_start = 0; | 824 | u64 extent_start = 0; |
800 | u64 extent_end = 0; | 825 | u64 extent_end = 0; |
801 | u64 objectid = inode->i_ino; | 826 | u64 objectid = inode->i_ino; |
802 | struct btrfs_path path; | 827 | struct btrfs_path *path; |
803 | struct btrfs_root *root = btrfs_sb(inode->i_sb); | 828 | struct btrfs_root *root = btrfs_sb(inode->i_sb); |
804 | struct btrfs_trans_handle *trans = NULL; | 829 | struct btrfs_trans_handle *trans = NULL; |
805 | struct btrfs_file_extent_item *item; | 830 | struct btrfs_file_extent_item *item; |
806 | struct btrfs_leaf *leaf; | 831 | struct btrfs_leaf *leaf; |
807 | struct btrfs_disk_key *found_key; | 832 | struct btrfs_disk_key *found_key; |
808 | 833 | ||
809 | btrfs_init_path(&path); | 834 | path = btrfs_alloc_path(); |
835 | BUG_ON(!path); | ||
836 | btrfs_init_path(path); | ||
810 | if (create) | 837 | if (create) |
811 | trans = btrfs_start_transaction(root, 1); | 838 | trans = btrfs_start_transaction(root, 1); |
812 | 839 | ||
813 | 840 | ||
814 | ret = btrfs_lookup_file_extent(trans, root, &path, | 841 | ret = btrfs_lookup_file_extent(trans, root, path, |
815 | inode->i_ino, | 842 | inode->i_ino, |
816 | iblock << inode->i_blkbits, 0); | 843 | iblock << inode->i_blkbits, 0); |
817 | if (ret < 0) { | 844 | if (ret < 0) { |
818 | btrfs_release_path(root, &path); | ||
819 | err = ret; | 845 | err = ret; |
820 | goto out; | 846 | goto out; |
821 | } | 847 | } |
822 | 848 | ||
823 | if (ret != 0) { | 849 | if (ret != 0) { |
824 | if (path.slots[0] == 0) { | 850 | if (path->slots[0] == 0) { |
825 | btrfs_release_path(root, &path); | 851 | btrfs_release_path(root, path); |
826 | goto allocate; | 852 | goto allocate; |
827 | } | 853 | } |
828 | path.slots[0]--; | 854 | path->slots[0]--; |
829 | } | 855 | } |
830 | 856 | ||
831 | item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], | 857 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
832 | struct btrfs_file_extent_item); | 858 | struct btrfs_file_extent_item); |
833 | leaf = btrfs_buffer_leaf(path.nodes[0]); | 859 | leaf = btrfs_buffer_leaf(path->nodes[0]); |
834 | blocknr = btrfs_file_extent_disk_blocknr(item); | 860 | blocknr = btrfs_file_extent_disk_blocknr(item); |
835 | blocknr += btrfs_file_extent_offset(item); | 861 | blocknr += btrfs_file_extent_offset(item); |
836 | 862 | ||
@@ -838,25 +864,23 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock, | |||
838 | if (ret == 0) { | 864 | if (ret == 0) { |
839 | err = 0; | 865 | err = 0; |
840 | map_bh(result, inode->i_sb, blocknr); | 866 | map_bh(result, inode->i_sb, blocknr); |
841 | btrfs_release_path(root, &path); | ||
842 | goto out; | 867 | goto out; |
843 | } | 868 | } |
844 | 869 | ||
845 | /* are we inside the extent that was found? */ | 870 | /* are we inside the extent that was found? */ |
846 | found_key = &leaf->items[path.slots[0]].key; | 871 | found_key = &leaf->items[path->slots[0]].key; |
847 | if (btrfs_disk_key_objectid(found_key) != objectid || | 872 | if (btrfs_disk_key_objectid(found_key) != objectid || |
848 | btrfs_disk_key_type(found_key) != BTRFS_EXTENT_DATA_KEY) { | 873 | btrfs_disk_key_type(found_key) != BTRFS_EXTENT_DATA_KEY) { |
849 | extent_end = 0; | 874 | extent_end = 0; |
850 | extent_start = 0; | 875 | extent_start = 0; |
851 | btrfs_release_path(root, &path); | 876 | btrfs_release_path(root, path); |
852 | goto allocate; | 877 | goto allocate; |
853 | } | 878 | } |
854 | 879 | ||
855 | extent_start = btrfs_disk_key_offset(&leaf->items[path.slots[0]].key); | 880 | extent_start = btrfs_disk_key_offset(&leaf->items[path->slots[0]].key); |
856 | extent_start = extent_start >> inode->i_blkbits; | 881 | extent_start = extent_start >> inode->i_blkbits; |
857 | extent_start += btrfs_file_extent_offset(item); | 882 | extent_start += btrfs_file_extent_offset(item); |
858 | extent_end = extent_start + btrfs_file_extent_num_blocks(item); | 883 | extent_end = extent_start + btrfs_file_extent_num_blocks(item); |
859 | btrfs_release_path(root, &path); | ||
860 | if (iblock >= extent_start && iblock < extent_end) { | 884 | if (iblock >= extent_start && iblock < extent_end) { |
861 | err = 0; | 885 | err = 0; |
862 | map_bh(result, inode->i_sb, blocknr + iblock - extent_start); | 886 | map_bh(result, inode->i_sb, blocknr + iblock - extent_start); |
@@ -880,6 +904,8 @@ allocate: | |||
880 | map_bh(result, inode->i_sb, blocknr); | 904 | map_bh(result, inode->i_sb, blocknr); |
881 | 905 | ||
882 | out: | 906 | out: |
907 | btrfs_release_path(root, path); | ||
908 | btrfs_free_path(path); | ||
883 | if (trans) | 909 | if (trans) |
884 | btrfs_end_transaction(trans, root); | 910 | btrfs_end_transaction(trans, root); |
885 | return err; | 911 | return err; |