diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-03-16 16:20:31 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-03-16 16:20:31 -0400 |
commit | e089f05c18ab36ed5fa7e2319052e03ab800d518 (patch) | |
tree | f20d727233bb23fa5a37fc050cf0cc5c9d5e7b48 /fs/btrfs/ctree.c | |
parent | 88fd146c27da0f34c512f47e2b3776a0762ecd81 (diff) |
Btrfs: transaction handles everywhere
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 204 |
1 files changed, 106 insertions, 98 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 13128b5ed65c..17a3ff2f1828 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -6,17 +6,18 @@ | |||
6 | #include "disk-io.h" | 6 | #include "disk-io.h" |
7 | #include "print-tree.h" | 7 | #include "print-tree.h" |
8 | 8 | ||
9 | static int split_node(struct btrfs_root *root, struct btrfs_path *path, | 9 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root |
10 | int level); | 10 | *root, struct btrfs_path *path, int level); |
11 | static int split_leaf(struct btrfs_root *root, struct btrfs_path *path, | 11 | static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root |
12 | int data_size); | 12 | *root, struct btrfs_path *path, int data_size); |
13 | static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst, | 13 | static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root |
14 | struct btrfs_buffer *src); | 14 | *root, struct btrfs_buffer *dst, struct btrfs_buffer |
15 | static int balance_node_right(struct btrfs_root *root, | 15 | *src); |
16 | struct btrfs_buffer *dst_buf, | 16 | static int balance_node_right(struct btrfs_trans_handle *trans, struct |
17 | btrfs_root *root, struct btrfs_buffer *dst_buf, | ||
17 | struct btrfs_buffer *src_buf); | 18 | struct btrfs_buffer *src_buf); |
18 | static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, | 19 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
19 | int slot); | 20 | struct btrfs_path *path, int level, int slot); |
20 | 21 | ||
21 | inline void btrfs_init_path(struct btrfs_path *p) | 22 | inline void btrfs_init_path(struct btrfs_path *p) |
22 | { | 23 | { |
@@ -34,11 +35,10 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) | |||
34 | memset(p, 0, sizeof(*p)); | 35 | memset(p, 0, sizeof(*p)); |
35 | } | 36 | } |
36 | 37 | ||
37 | static int btrfs_cow_block(struct btrfs_root *root, | 38 | static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root |
38 | struct btrfs_buffer *buf, | 39 | *root, struct btrfs_buffer *buf, struct btrfs_buffer |
39 | struct btrfs_buffer *parent, | 40 | *parent, int parent_slot, struct btrfs_buffer |
40 | int parent_slot, | 41 | **cow_ret) |
41 | struct btrfs_buffer **cow_ret) | ||
42 | { | 42 | { |
43 | struct btrfs_buffer *cow; | 43 | struct btrfs_buffer *cow; |
44 | 44 | ||
@@ -46,22 +46,22 @@ static int btrfs_cow_block(struct btrfs_root *root, | |||
46 | *cow_ret = buf; | 46 | *cow_ret = buf; |
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | cow = btrfs_alloc_free_block(root); | 49 | cow = btrfs_alloc_free_block(trans, root); |
50 | memcpy(&cow->node, &buf->node, root->blocksize); | 50 | memcpy(&cow->node, &buf->node, root->blocksize); |
51 | btrfs_set_header_blocknr(&cow->node.header, cow->blocknr); | 51 | btrfs_set_header_blocknr(&cow->node.header, cow->blocknr); |
52 | *cow_ret = cow; | 52 | *cow_ret = cow; |
53 | btrfs_inc_ref(root, buf); | 53 | btrfs_inc_ref(trans, root, buf); |
54 | if (buf == root->node) { | 54 | if (buf == root->node) { |
55 | root->node = cow; | 55 | root->node = cow; |
56 | cow->count++; | 56 | cow->count++; |
57 | if (buf != root->commit_root) | 57 | if (buf != root->commit_root) |
58 | btrfs_free_extent(root, buf->blocknr, 1, 1); | 58 | btrfs_free_extent(trans, root, buf->blocknr, 1, 1); |
59 | btrfs_block_release(root, buf); | 59 | btrfs_block_release(root, buf); |
60 | } else { | 60 | } else { |
61 | btrfs_set_node_blockptr(&parent->node, parent_slot, | 61 | btrfs_set_node_blockptr(&parent->node, parent_slot, |
62 | cow->blocknr); | 62 | cow->blocknr); |
63 | BUG_ON(list_empty(&parent->dirty)); | 63 | BUG_ON(list_empty(&parent->dirty)); |
64 | btrfs_free_extent(root, buf->blocknr, 1, 1); | 64 | btrfs_free_extent(trans, root, buf->blocknr, 1, 1); |
65 | } | 65 | } |
66 | btrfs_block_release(root, buf); | 66 | btrfs_block_release(root, buf); |
67 | return 0; | 67 | return 0; |
@@ -266,8 +266,8 @@ static struct btrfs_buffer *read_node_slot(struct btrfs_root *root, | |||
266 | return read_tree_block(root, btrfs_node_blockptr(node, slot)); | 266 | return read_tree_block(root, btrfs_node_blockptr(node, slot)); |
267 | } | 267 | } |
268 | 268 | ||
269 | static int balance_level(struct btrfs_root *root, struct btrfs_path *path, | 269 | static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root |
270 | int level) | 270 | *root, struct btrfs_path *path, int level) |
271 | { | 271 | { |
272 | struct btrfs_buffer *right_buf; | 272 | struct btrfs_buffer *right_buf; |
273 | struct btrfs_buffer *mid_buf; | 273 | struct btrfs_buffer *mid_buf; |
@@ -310,8 +310,8 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path, | |||
310 | btrfs_block_release(root, mid_buf); | 310 | btrfs_block_release(root, mid_buf); |
311 | /* once for the root ptr */ | 311 | /* once for the root ptr */ |
312 | btrfs_block_release(root, mid_buf); | 312 | btrfs_block_release(root, mid_buf); |
313 | clean_tree_block(root, mid_buf); | 313 | clean_tree_block(trans, root, mid_buf); |
314 | return btrfs_free_extent(root, blocknr, 1, 1); | 314 | return btrfs_free_extent(trans, root, blocknr, 1, 1); |
315 | } | 315 | } |
316 | parent = &parent_buf->node; | 316 | parent = &parent_buf->node; |
317 | 317 | ||
@@ -324,11 +324,11 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path, | |||
324 | 324 | ||
325 | /* first, try to make some room in the middle buffer */ | 325 | /* first, try to make some room in the middle buffer */ |
326 | if (left_buf) { | 326 | if (left_buf) { |
327 | btrfs_cow_block(root, left_buf, parent_buf, | 327 | btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1, |
328 | pslot - 1, &left_buf); | 328 | &left_buf); |
329 | left = &left_buf->node; | 329 | left = &left_buf->node; |
330 | orig_slot += btrfs_header_nritems(&left->header); | 330 | orig_slot += btrfs_header_nritems(&left->header); |
331 | wret = push_node_left(root, left_buf, mid_buf); | 331 | wret = push_node_left(trans, root, left_buf, mid_buf); |
332 | if (wret < 0) | 332 | if (wret < 0) |
333 | ret = wret; | 333 | ret = wret; |
334 | } | 334 | } |
@@ -337,22 +337,23 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path, | |||
337 | * then try to empty the right most buffer into the middle | 337 | * then try to empty the right most buffer into the middle |
338 | */ | 338 | */ |
339 | if (right_buf) { | 339 | if (right_buf) { |
340 | btrfs_cow_block(root, right_buf, parent_buf, | 340 | btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1, |
341 | pslot + 1, &right_buf); | 341 | &right_buf); |
342 | right = &right_buf->node; | 342 | right = &right_buf->node; |
343 | wret = push_node_left(root, mid_buf, right_buf); | 343 | wret = push_node_left(trans, root, mid_buf, right_buf); |
344 | if (wret < 0) | 344 | if (wret < 0) |
345 | ret = wret; | 345 | ret = wret; |
346 | if (btrfs_header_nritems(&right->header) == 0) { | 346 | if (btrfs_header_nritems(&right->header) == 0) { |
347 | u64 blocknr = right_buf->blocknr; | 347 | u64 blocknr = right_buf->blocknr; |
348 | btrfs_block_release(root, right_buf); | 348 | btrfs_block_release(root, right_buf); |
349 | clean_tree_block(root, right_buf); | 349 | clean_tree_block(trans, root, right_buf); |
350 | right_buf = NULL; | 350 | right_buf = NULL; |
351 | right = NULL; | 351 | right = NULL; |
352 | wret = del_ptr(root, path, level + 1, pslot + 1); | 352 | wret = del_ptr(trans, root, path, level + 1, pslot + |
353 | 1); | ||
353 | if (wret) | 354 | if (wret) |
354 | ret = wret; | 355 | ret = wret; |
355 | wret = btrfs_free_extent(root, blocknr, 1, 1); | 356 | wret = btrfs_free_extent(trans, root, blocknr, 1, 1); |
356 | if (wret) | 357 | if (wret) |
357 | ret = wret; | 358 | ret = wret; |
358 | } else { | 359 | } else { |
@@ -373,7 +374,7 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path, | |||
373 | * right | 374 | * right |
374 | */ | 375 | */ |
375 | BUG_ON(!left_buf); | 376 | BUG_ON(!left_buf); |
376 | wret = balance_node_right(root, mid_buf, left_buf); | 377 | wret = balance_node_right(trans, root, mid_buf, left_buf); |
377 | if (wret < 0) | 378 | if (wret < 0) |
378 | ret = wret; | 379 | ret = wret; |
379 | BUG_ON(wret == 1); | 380 | BUG_ON(wret == 1); |
@@ -382,13 +383,13 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path, | |||
382 | /* we've managed to empty the middle node, drop it */ | 383 | /* we've managed to empty the middle node, drop it */ |
383 | u64 blocknr = mid_buf->blocknr; | 384 | u64 blocknr = mid_buf->blocknr; |
384 | btrfs_block_release(root, mid_buf); | 385 | btrfs_block_release(root, mid_buf); |
385 | clean_tree_block(root, mid_buf); | 386 | clean_tree_block(trans, root, mid_buf); |
386 | mid_buf = NULL; | 387 | mid_buf = NULL; |
387 | mid = NULL; | 388 | mid = NULL; |
388 | wret = del_ptr(root, path, level + 1, pslot); | 389 | wret = del_ptr(trans, root, path, level + 1, pslot); |
389 | if (wret) | 390 | if (wret) |
390 | ret = wret; | 391 | ret = wret; |
391 | wret = btrfs_free_extent(root, blocknr, 1, 1); | 392 | wret = btrfs_free_extent(trans, root, blocknr, 1, 1); |
392 | if (wret) | 393 | if (wret) |
393 | ret = wret; | 394 | ret = wret; |
394 | } else { | 395 | } else { |
@@ -438,8 +439,9 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path, | |||
438 | * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if | 439 | * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if |
439 | * possible) | 440 | * possible) |
440 | */ | 441 | */ |
441 | int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key, | 442 | int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root |
442 | struct btrfs_path *p, int ins_len, int cow) | 443 | *root, struct btrfs_key *key, struct btrfs_path *p, int |
444 | ins_len, int cow) | ||
443 | { | 445 | { |
444 | struct btrfs_buffer *b; | 446 | struct btrfs_buffer *b; |
445 | struct btrfs_buffer *cow_buf; | 447 | struct btrfs_buffer *cow_buf; |
@@ -455,8 +457,9 @@ again: | |||
455 | level = btrfs_header_level(&b->node.header); | 457 | level = btrfs_header_level(&b->node.header); |
456 | if (cow) { | 458 | if (cow) { |
457 | int wret; | 459 | int wret; |
458 | wret = btrfs_cow_block(root, b, p->nodes[level + 1], | 460 | wret = btrfs_cow_block(trans, root, b, p->nodes[level + |
459 | p->slots[level + 1], &cow_buf); | 461 | 1], p->slots[level + 1], |
462 | &cow_buf); | ||
460 | b = cow_buf; | 463 | b = cow_buf; |
461 | } | 464 | } |
462 | BUG_ON(!cow && ins_len); | 465 | BUG_ON(!cow && ins_len); |
@@ -472,7 +475,7 @@ again: | |||
472 | p->slots[level] = slot; | 475 | p->slots[level] = slot; |
473 | if (ins_len > 0 && btrfs_header_nritems(&c->header) == | 476 | if (ins_len > 0 && btrfs_header_nritems(&c->header) == |
474 | BTRFS_NODEPTRS_PER_BLOCK(root)) { | 477 | BTRFS_NODEPTRS_PER_BLOCK(root)) { |
475 | int sret = split_node(root, p, level); | 478 | int sret = split_node(trans, root, p, level); |
476 | BUG_ON(sret > 0); | 479 | BUG_ON(sret > 0); |
477 | if (sret) | 480 | if (sret) |
478 | return sret; | 481 | return sret; |
@@ -480,7 +483,8 @@ again: | |||
480 | c = &b->node; | 483 | c = &b->node; |
481 | slot = p->slots[level]; | 484 | slot = p->slots[level]; |
482 | } else if (ins_len < 0) { | 485 | } else if (ins_len < 0) { |
483 | int sret = balance_level(root, p, level); | 486 | int sret = balance_level(trans, root, p, |
487 | level); | ||
484 | if (sret) | 488 | if (sret) |
485 | return sret; | 489 | return sret; |
486 | b = p->nodes[level]; | 490 | b = p->nodes[level]; |
@@ -496,7 +500,7 @@ again: | |||
496 | p->slots[level] = slot; | 500 | p->slots[level] = slot; |
497 | if (ins_len > 0 && btrfs_leaf_free_space(root, l) < | 501 | if (ins_len > 0 && btrfs_leaf_free_space(root, l) < |
498 | sizeof(struct btrfs_item) + ins_len) { | 502 | sizeof(struct btrfs_item) + ins_len) { |
499 | int sret = split_leaf(root, p, ins_len); | 503 | int sret = split_leaf(trans, root, p, ins_len); |
500 | BUG_ON(sret > 0); | 504 | BUG_ON(sret > 0); |
501 | if (sret) | 505 | if (sret) |
502 | return sret; | 506 | return sret; |
@@ -519,9 +523,9 @@ again: | |||
519 | * If this fails to write a tree block, it returns -1, but continues | 523 | * If this fails to write a tree block, it returns -1, but continues |
520 | * fixing up the blocks in ram so the tree is consistent. | 524 | * fixing up the blocks in ram so the tree is consistent. |
521 | */ | 525 | */ |
522 | static int fixup_low_keys(struct btrfs_root *root, | 526 | static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root |
523 | struct btrfs_path *path, struct btrfs_disk_key *key, | 527 | *root, struct btrfs_path *path, struct btrfs_disk_key |
524 | int level) | 528 | *key, int level) |
525 | { | 529 | { |
526 | int i; | 530 | int i; |
527 | int ret = 0; | 531 | int ret = 0; |
@@ -546,8 +550,9 @@ static int fixup_low_keys(struct btrfs_root *root, | |||
546 | * returns 0 if some ptrs were pushed left, < 0 if there was some horrible | 550 | * returns 0 if some ptrs were pushed left, < 0 if there was some horrible |
547 | * error, and > 0 if there was no room in the left hand block. | 551 | * error, and > 0 if there was no room in the left hand block. |
548 | */ | 552 | */ |
549 | static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf, | 553 | static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root |
550 | struct btrfs_buffer *src_buf) | 554 | *root, struct btrfs_buffer *dst_buf, struct |
555 | btrfs_buffer *src_buf) | ||
551 | { | 556 | { |
552 | struct btrfs_node *src = &src_buf->node; | 557 | struct btrfs_node *src = &src_buf->node; |
553 | struct btrfs_node *dst = &dst_buf->node; | 558 | struct btrfs_node *dst = &dst_buf->node; |
@@ -589,8 +594,8 @@ static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf, | |||
589 | * | 594 | * |
590 | * this will only push up to 1/2 the contents of the left node over | 595 | * this will only push up to 1/2 the contents of the left node over |
591 | */ | 596 | */ |
592 | static int balance_node_right(struct btrfs_root *root, | 597 | static int balance_node_right(struct btrfs_trans_handle *trans, struct |
593 | struct btrfs_buffer *dst_buf, | 598 | btrfs_root *root, struct btrfs_buffer *dst_buf, |
594 | struct btrfs_buffer *src_buf) | 599 | struct btrfs_buffer *src_buf) |
595 | { | 600 | { |
596 | struct btrfs_node *src = &src_buf->node; | 601 | struct btrfs_node *src = &src_buf->node; |
@@ -635,8 +640,8 @@ static int balance_node_right(struct btrfs_root *root, | |||
635 | * | 640 | * |
636 | * returns zero on success or < 0 on failure. | 641 | * returns zero on success or < 0 on failure. |
637 | */ | 642 | */ |
638 | static int insert_new_root(struct btrfs_root *root, | 643 | static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root |
639 | struct btrfs_path *path, int level) | 644 | *root, struct btrfs_path *path, int level) |
640 | { | 645 | { |
641 | struct btrfs_buffer *t; | 646 | struct btrfs_buffer *t; |
642 | struct btrfs_node *lower; | 647 | struct btrfs_node *lower; |
@@ -646,7 +651,7 @@ static int insert_new_root(struct btrfs_root *root, | |||
646 | BUG_ON(path->nodes[level]); | 651 | BUG_ON(path->nodes[level]); |
647 | BUG_ON(path->nodes[level-1] != root->node); | 652 | BUG_ON(path->nodes[level-1] != root->node); |
648 | 653 | ||
649 | t = btrfs_alloc_free_block(root); | 654 | t = btrfs_alloc_free_block(trans, root); |
650 | c = &t->node; | 655 | c = &t->node; |
651 | memset(c, 0, root->blocksize); | 656 | memset(c, 0, root->blocksize); |
652 | btrfs_set_header_nritems(&c->header, 1); | 657 | btrfs_set_header_nritems(&c->header, 1); |
@@ -679,9 +684,9 @@ static int insert_new_root(struct btrfs_root *root, | |||
679 | * | 684 | * |
680 | * returns zero on success and < 0 on any error | 685 | * returns zero on success and < 0 on any error |
681 | */ | 686 | */ |
682 | static int insert_ptr(struct btrfs_root *root, | 687 | static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root |
683 | struct btrfs_path *path, struct btrfs_disk_key *key, | 688 | *root, struct btrfs_path *path, struct btrfs_disk_key |
684 | u64 blocknr, int slot, int level) | 689 | *key, u64 blocknr, int slot, int level) |
685 | { | 690 | { |
686 | struct btrfs_node *lower; | 691 | struct btrfs_node *lower; |
687 | int nritems; | 692 | int nritems; |
@@ -713,8 +718,8 @@ static int insert_ptr(struct btrfs_root *root, | |||
713 | * | 718 | * |
714 | * returns 0 on success and < 0 on failure | 719 | * returns 0 on success and < 0 on failure |
715 | */ | 720 | */ |
716 | static int split_node(struct btrfs_root *root, struct btrfs_path *path, | 721 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root |
717 | int level) | 722 | *root, struct btrfs_path *path, int level) |
718 | { | 723 | { |
719 | struct btrfs_buffer *t; | 724 | struct btrfs_buffer *t; |
720 | struct btrfs_node *c; | 725 | struct btrfs_node *c; |
@@ -729,12 +734,12 @@ static int split_node(struct btrfs_root *root, struct btrfs_path *path, | |||
729 | c = &t->node; | 734 | c = &t->node; |
730 | if (t == root->node) { | 735 | if (t == root->node) { |
731 | /* trying to split the root, lets make a new one */ | 736 | /* trying to split the root, lets make a new one */ |
732 | ret = insert_new_root(root, path, level + 1); | 737 | ret = insert_new_root(trans, root, path, level + 1); |
733 | if (ret) | 738 | if (ret) |
734 | return ret; | 739 | return ret; |
735 | } | 740 | } |
736 | c_nritems = btrfs_header_nritems(&c->header); | 741 | c_nritems = btrfs_header_nritems(&c->header); |
737 | split_buffer = btrfs_alloc_free_block(root); | 742 | split_buffer = btrfs_alloc_free_block(trans, root); |
738 | split = &split_buffer->node; | 743 | split = &split_buffer->node; |
739 | btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); | 744 | btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); |
740 | btrfs_set_header_blocknr(&split->header, split_buffer->blocknr); | 745 | btrfs_set_header_blocknr(&split->header, split_buffer->blocknr); |
@@ -748,7 +753,7 @@ static int split_node(struct btrfs_root *root, struct btrfs_path *path, | |||
748 | ret = 0; | 753 | ret = 0; |
749 | 754 | ||
750 | BUG_ON(list_empty(&t->dirty)); | 755 | BUG_ON(list_empty(&t->dirty)); |
751 | wret = insert_ptr(root, path, &split->ptrs[0].key, | 756 | wret = insert_ptr(trans, root, path, &split->ptrs[0].key, |
752 | split_buffer->blocknr, path->slots[level + 1] + 1, | 757 | split_buffer->blocknr, path->slots[level + 1] + 1, |
753 | level + 1); | 758 | level + 1); |
754 | if (wret) | 759 | if (wret) |
@@ -790,8 +795,8 @@ static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) | |||
790 | * returns 1 if the push failed because the other node didn't have enough | 795 | * returns 1 if the push failed because the other node didn't have enough |
791 | * room, 0 if everything worked out and < 0 if there were major errors. | 796 | * room, 0 if everything worked out and < 0 if there were major errors. |
792 | */ | 797 | */ |
793 | static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path, | 798 | static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root |
794 | int data_size) | 799 | *root, struct btrfs_path *path, int data_size) |
795 | { | 800 | { |
796 | struct btrfs_buffer *left_buf = path->nodes[0]; | 801 | struct btrfs_buffer *left_buf = path->nodes[0]; |
797 | struct btrfs_leaf *left = &left_buf->leaf; | 802 | struct btrfs_leaf *left = &left_buf->leaf; |
@@ -824,7 +829,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path, | |||
824 | return 1; | 829 | return 1; |
825 | } | 830 | } |
826 | /* cow and double check */ | 831 | /* cow and double check */ |
827 | btrfs_cow_block(root, right_buf, upper, slot + 1, &right_buf); | 832 | btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf); |
828 | right = &right_buf->leaf; | 833 | right = &right_buf->leaf; |
829 | free_space = btrfs_leaf_free_space(root, right); | 834 | free_space = btrfs_leaf_free_space(root, right); |
830 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 835 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
@@ -897,8 +902,8 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path, | |||
897 | * push some data in the path leaf to the left, trying to free up at | 902 | * push some data in the path leaf to the left, trying to free up at |
898 | * least data_size bytes. returns zero if the push worked, nonzero otherwise | 903 | * least data_size bytes. returns zero if the push worked, nonzero otherwise |
899 | */ | 904 | */ |
900 | static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path, | 905 | static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root |
901 | int data_size) | 906 | *root, struct btrfs_path *path, int data_size) |
902 | { | 907 | { |
903 | struct btrfs_buffer *right_buf = path->nodes[0]; | 908 | struct btrfs_buffer *right_buf = path->nodes[0]; |
904 | struct btrfs_leaf *right = &right_buf->leaf; | 909 | struct btrfs_leaf *right = &right_buf->leaf; |
@@ -931,7 +936,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path, | |||
931 | } | 936 | } |
932 | 937 | ||
933 | /* cow and double check */ | 938 | /* cow and double check */ |
934 | btrfs_cow_block(root, t, path->nodes[1], slot - 1, &t); | 939 | btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); |
935 | left = &t->leaf; | 940 | left = &t->leaf; |
936 | free_space = btrfs_leaf_free_space(root, left); | 941 | free_space = btrfs_leaf_free_space(root, left); |
937 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 942 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
@@ -997,7 +1002,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path, | |||
997 | BUG_ON(list_empty(&t->dirty)); | 1002 | BUG_ON(list_empty(&t->dirty)); |
998 | BUG_ON(list_empty(&right_buf->dirty)); | 1003 | BUG_ON(list_empty(&right_buf->dirty)); |
999 | 1004 | ||
1000 | wret = fixup_low_keys(root, path, &right->items[0].key, 1); | 1005 | wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); |
1001 | if (wret) | 1006 | if (wret) |
1002 | ret = wret; | 1007 | ret = wret; |
1003 | 1008 | ||
@@ -1021,8 +1026,8 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path, | |||
1021 | * | 1026 | * |
1022 | * returns 0 if all went well and < 0 on failure. | 1027 | * returns 0 if all went well and < 0 on failure. |
1023 | */ | 1028 | */ |
1024 | static int split_leaf(struct btrfs_root *root, struct btrfs_path *path, | 1029 | static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root |
1025 | int data_size) | 1030 | *root, struct btrfs_path *path, int data_size) |
1026 | { | 1031 | { |
1027 | struct btrfs_buffer *l_buf; | 1032 | struct btrfs_buffer *l_buf; |
1028 | struct btrfs_leaf *l; | 1033 | struct btrfs_leaf *l; |
@@ -1038,11 +1043,11 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path, | |||
1038 | int ret; | 1043 | int ret; |
1039 | int wret; | 1044 | int wret; |
1040 | 1045 | ||
1041 | wret = push_leaf_left(root, path, data_size); | 1046 | wret = push_leaf_left(trans, root, path, data_size); |
1042 | if (wret < 0) | 1047 | if (wret < 0) |
1043 | return wret; | 1048 | return wret; |
1044 | if (wret) { | 1049 | if (wret) { |
1045 | wret = push_leaf_right(root, path, data_size); | 1050 | wret = push_leaf_right(trans, root, path, data_size); |
1046 | if (wret < 0) | 1051 | if (wret < 0) |
1047 | return wret; | 1052 | return wret; |
1048 | } | 1053 | } |
@@ -1055,14 +1060,14 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path, | |||
1055 | return 0; | 1060 | return 0; |
1056 | 1061 | ||
1057 | if (!path->nodes[1]) { | 1062 | if (!path->nodes[1]) { |
1058 | ret = insert_new_root(root, path, 1); | 1063 | ret = insert_new_root(trans, root, path, 1); |
1059 | if (ret) | 1064 | if (ret) |
1060 | return ret; | 1065 | return ret; |
1061 | } | 1066 | } |
1062 | slot = path->slots[0]; | 1067 | slot = path->slots[0]; |
1063 | nritems = btrfs_header_nritems(&l->header); | 1068 | nritems = btrfs_header_nritems(&l->header); |
1064 | mid = (nritems + 1)/ 2; | 1069 | mid = (nritems + 1)/ 2; |
1065 | right_buffer = btrfs_alloc_free_block(root); | 1070 | right_buffer = btrfs_alloc_free_block(trans, root); |
1066 | BUG_ON(!right_buffer); | 1071 | BUG_ON(!right_buffer); |
1067 | BUG_ON(mid == nritems); | 1072 | BUG_ON(mid == nritems); |
1068 | right = &right_buffer->leaf; | 1073 | right = &right_buffer->leaf; |
@@ -1100,7 +1105,7 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path, | |||
1100 | 1105 | ||
1101 | btrfs_set_header_nritems(&l->header, mid); | 1106 | btrfs_set_header_nritems(&l->header, mid); |
1102 | ret = 0; | 1107 | ret = 0; |
1103 | wret = insert_ptr(root, path, &right->items[0].key, | 1108 | wret = insert_ptr(trans, root, path, &right->items[0].key, |
1104 | right_buffer->blocknr, path->slots[1] + 1, 1); | 1109 | right_buffer->blocknr, path->slots[1] + 1, 1); |
1105 | if (wret) | 1110 | if (wret) |
1106 | ret = wret; | 1111 | ret = wret; |
@@ -1122,8 +1127,9 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path, | |||
1122 | * Given a key and some data, insert an item into the tree. | 1127 | * Given a key and some data, insert an item into the tree. |
1123 | * This does all the path init required, making room in the tree if needed. | 1128 | * This does all the path init required, making room in the tree if needed. |
1124 | */ | 1129 | */ |
1125 | int btrfs_insert_empty_item(struct btrfs_root *root, struct btrfs_path *path, | 1130 | int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root |
1126 | struct btrfs_key *cpu_key, u32 data_size) | 1131 | *root, struct btrfs_path *path, struct btrfs_key |
1132 | *cpu_key, u32 data_size) | ||
1127 | { | 1133 | { |
1128 | int ret = 0; | 1134 | int ret = 0; |
1129 | int slot; | 1135 | int slot; |
@@ -1139,7 +1145,7 @@ int btrfs_insert_empty_item(struct btrfs_root *root, struct btrfs_path *path, | |||
1139 | /* create a root if there isn't one */ | 1145 | /* create a root if there isn't one */ |
1140 | if (!root->node) | 1146 | if (!root->node) |
1141 | BUG(); | 1147 | BUG(); |
1142 | ret = btrfs_search_slot(root, cpu_key, path, data_size, 1); | 1148 | ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); |
1143 | if (ret == 0) { | 1149 | if (ret == 0) { |
1144 | btrfs_release_path(root, path); | 1150 | btrfs_release_path(root, path); |
1145 | return -EEXIST; | 1151 | return -EEXIST; |
@@ -1193,7 +1199,7 @@ int btrfs_insert_empty_item(struct btrfs_root *root, struct btrfs_path *path, | |||
1193 | 1199 | ||
1194 | ret = 0; | 1200 | ret = 0; |
1195 | if (slot == 0) | 1201 | if (slot == 0) |
1196 | ret = fixup_low_keys(root, path, &disk_key, 1); | 1202 | ret = fixup_low_keys(trans, root, path, &disk_key, 1); |
1197 | 1203 | ||
1198 | BUG_ON(list_empty(&leaf_buf->dirty)); | 1204 | BUG_ON(list_empty(&leaf_buf->dirty)); |
1199 | if (btrfs_leaf_free_space(root, leaf) < 0) | 1205 | if (btrfs_leaf_free_space(root, leaf) < 0) |
@@ -1207,15 +1213,16 @@ out: | |||
1207 | * Given a key and some data, insert an item into the tree. | 1213 | * Given a key and some data, insert an item into the tree. |
1208 | * This does all the path init required, making room in the tree if needed. | 1214 | * This does all the path init required, making room in the tree if needed. |
1209 | */ | 1215 | */ |
1210 | int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key, | 1216 | int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root |
1211 | void *data, u32 data_size) | 1217 | *root, struct btrfs_key *cpu_key, void *data, u32 |
1218 | data_size) | ||
1212 | { | 1219 | { |
1213 | int ret = 0; | 1220 | int ret = 0; |
1214 | struct btrfs_path path; | 1221 | struct btrfs_path path; |
1215 | u8 *ptr; | 1222 | u8 *ptr; |
1216 | 1223 | ||
1217 | btrfs_init_path(&path); | 1224 | btrfs_init_path(&path); |
1218 | ret = btrfs_insert_empty_item(root, &path, cpu_key, data_size); | 1225 | ret = btrfs_insert_empty_item(trans, root, &path, cpu_key, data_size); |
1219 | if (!ret) { | 1226 | if (!ret) { |
1220 | ptr = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0], u8); | 1227 | ptr = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0], u8); |
1221 | memcpy(ptr, data, data_size); | 1228 | memcpy(ptr, data, data_size); |
@@ -1231,8 +1238,8 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key, | |||
1231 | * continuing all the way the root if required. The root is converted into | 1238 | * continuing all the way the root if required. The root is converted into |
1232 | * a leaf if all the nodes are emptied. | 1239 | * a leaf if all the nodes are emptied. |
1233 | */ | 1240 | */ |
1234 | static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, | 1241 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1235 | int slot) | 1242 | struct btrfs_path *path, int level, int slot) |
1236 | { | 1243 | { |
1237 | struct btrfs_node *node; | 1244 | struct btrfs_node *node; |
1238 | struct btrfs_buffer *parent = path->nodes[level]; | 1245 | struct btrfs_buffer *parent = path->nodes[level]; |
@@ -1253,7 +1260,7 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, | |||
1253 | /* just turn the root into a leaf and break */ | 1260 | /* just turn the root into a leaf and break */ |
1254 | btrfs_set_header_level(&root->node->node.header, 0); | 1261 | btrfs_set_header_level(&root->node->node.header, 0); |
1255 | } else if (slot == 0) { | 1262 | } else if (slot == 0) { |
1256 | wret = fixup_low_keys(root, path, &node->ptrs[0].key, | 1263 | wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, |
1257 | level + 1); | 1264 | level + 1); |
1258 | if (wret) | 1265 | if (wret) |
1259 | ret = wret; | 1266 | ret = wret; |
@@ -1266,7 +1273,8 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, | |||
1266 | * delete the item at the leaf level in path. If that empties | 1273 | * delete the item at the leaf level in path. If that empties |
1267 | * the leaf, remove it from the tree | 1274 | * the leaf, remove it from the tree |
1268 | */ | 1275 | */ |
1269 | int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path) | 1276 | int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1277 | struct btrfs_path *path) | ||
1270 | { | 1278 | { |
1271 | int slot; | 1279 | int slot; |
1272 | struct btrfs_leaf *leaf; | 1280 | struct btrfs_leaf *leaf; |
@@ -1306,19 +1314,20 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path) | |||
1306 | btrfs_set_header_level(&leaf->header, 0); | 1314 | btrfs_set_header_level(&leaf->header, 0); |
1307 | BUG_ON(list_empty(&leaf_buf->dirty)); | 1315 | BUG_ON(list_empty(&leaf_buf->dirty)); |
1308 | } else { | 1316 | } else { |
1309 | clean_tree_block(root, leaf_buf); | 1317 | clean_tree_block(trans, root, leaf_buf); |
1310 | wret = del_ptr(root, path, 1, path->slots[1]); | 1318 | wret = del_ptr(trans, root, path, 1, path->slots[1]); |
1311 | if (wret) | 1319 | if (wret) |
1312 | ret = wret; | 1320 | ret = wret; |
1313 | wret = btrfs_free_extent(root, leaf_buf->blocknr, 1, 1); | 1321 | wret = btrfs_free_extent(trans, root, |
1322 | leaf_buf->blocknr, 1, 1); | ||
1314 | if (wret) | 1323 | if (wret) |
1315 | ret = wret; | 1324 | ret = wret; |
1316 | } | 1325 | } |
1317 | } else { | 1326 | } else { |
1318 | int used = leaf_space_used(leaf, 0, nritems); | 1327 | int used = leaf_space_used(leaf, 0, nritems); |
1319 | if (slot == 0) { | 1328 | if (slot == 0) { |
1320 | wret = fixup_low_keys(root, path, | 1329 | wret = fixup_low_keys(trans, root, path, |
1321 | &leaf->items[0].key, 1); | 1330 | &leaf->items[0].key, 1); |
1322 | if (wret) | 1331 | if (wret) |
1323 | ret = wret; | 1332 | ret = wret; |
1324 | } | 1333 | } |
@@ -1332,23 +1341,24 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path) | |||
1332 | */ | 1341 | */ |
1333 | slot = path->slots[1]; | 1342 | slot = path->slots[1]; |
1334 | leaf_buf->count++; | 1343 | leaf_buf->count++; |
1335 | wret = push_leaf_left(root, path, 1); | 1344 | wret = push_leaf_left(trans, root, path, 1); |
1336 | if (wret < 0) | 1345 | if (wret < 0) |
1337 | ret = wret; | 1346 | ret = wret; |
1338 | if (path->nodes[0] == leaf_buf && | 1347 | if (path->nodes[0] == leaf_buf && |
1339 | btrfs_header_nritems(&leaf->header)) { | 1348 | btrfs_header_nritems(&leaf->header)) { |
1340 | wret = push_leaf_right(root, path, 1); | 1349 | wret = push_leaf_right(trans, root, path, 1); |
1341 | if (wret < 0) | 1350 | if (wret < 0) |
1342 | ret = wret; | 1351 | ret = wret; |
1343 | } | 1352 | } |
1344 | if (btrfs_header_nritems(&leaf->header) == 0) { | 1353 | if (btrfs_header_nritems(&leaf->header) == 0) { |
1345 | u64 blocknr = leaf_buf->blocknr; | 1354 | u64 blocknr = leaf_buf->blocknr; |
1346 | clean_tree_block(root, leaf_buf); | 1355 | clean_tree_block(trans, root, leaf_buf); |
1347 | wret = del_ptr(root, path, 1, slot); | 1356 | wret = del_ptr(trans, root, path, 1, slot); |
1348 | if (wret) | 1357 | if (wret) |
1349 | ret = wret; | 1358 | ret = wret; |
1350 | btrfs_block_release(root, leaf_buf); | 1359 | btrfs_block_release(root, leaf_buf); |
1351 | wret = btrfs_free_extent(root, blocknr, 1, 1); | 1360 | wret = btrfs_free_extent(trans, root, blocknr, |
1361 | 1, 1); | ||
1352 | if (wret) | 1362 | if (wret) |
1353 | ret = wret; | 1363 | ret = wret; |
1354 | } else { | 1364 | } else { |
@@ -1401,5 +1411,3 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
1401 | } | 1411 | } |
1402 | return 0; | 1412 | return 0; |
1403 | } | 1413 | } |
1404 | |||
1405 | |||