diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-03-30 14:27:56 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-03-30 14:27:56 -0400 |
commit | d6025579531b7ea170ba283b171ff7a6bf7d0e12 (patch) | |
tree | c3b742fda3a6ac8541c06011bb3c26635db99212 /fs/btrfs/ctree.c | |
parent | 22b0ebda6c63a1ad66b6a9e806bd226a4a03a049 (diff) |
Btrfs: corruption hunt continues
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 201 |
1 files changed, 114 insertions, 87 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index b7f3fcb72c62..a0dfa2d6cb9b 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -51,7 +51,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | |||
51 | btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr); | 51 | btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr); |
52 | btrfs_set_header_generation(&cow_node->header, trans->transid); | 52 | btrfs_set_header_generation(&cow_node->header, trans->transid); |
53 | *cow_ret = cow; | 53 | *cow_ret = cow; |
54 | mark_buffer_dirty(cow); | 54 | btrfs_mark_buffer_dirty(cow); |
55 | btrfs_inc_ref(trans, root, buf); | 55 | btrfs_inc_ref(trans, root, buf); |
56 | if (buf == root->node) { | 56 | if (buf == root->node) { |
57 | root->node = cow; | 57 | root->node = cow; |
@@ -62,7 +62,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | |||
62 | } else { | 62 | } else { |
63 | btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, | 63 | btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, |
64 | cow->b_blocknr); | 64 | cow->b_blocknr); |
65 | mark_buffer_dirty(parent); | 65 | btrfs_mark_buffer_dirty(parent); |
66 | btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1); | 66 | btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1); |
67 | } | 67 | } |
68 | btrfs_block_release(root, buf); | 68 | btrfs_block_release(root, buf); |
@@ -312,11 +312,12 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
312 | BUG_ON(!child); | 312 | BUG_ON(!child); |
313 | root->node = child; | 313 | root->node = child; |
314 | path->nodes[level] = NULL; | 314 | path->nodes[level] = NULL; |
315 | clean_tree_block(trans, root, mid_buf); | ||
316 | wait_on_buffer(mid_buf); | ||
315 | /* once for the path */ | 317 | /* once for the path */ |
316 | btrfs_block_release(root, mid_buf); | 318 | btrfs_block_release(root, mid_buf); |
317 | /* once for the root ptr */ | 319 | /* once for the root ptr */ |
318 | btrfs_block_release(root, mid_buf); | 320 | btrfs_block_release(root, mid_buf); |
319 | clean_tree_block(trans, root, mid_buf); | ||
320 | return btrfs_free_extent(trans, root, blocknr, 1, 1); | 321 | return btrfs_free_extent(trans, root, blocknr, 1, 1); |
321 | } | 322 | } |
322 | parent = btrfs_buffer_node(parent_buf); | 323 | parent = btrfs_buffer_node(parent_buf); |
@@ -351,8 +352,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
351 | ret = wret; | 352 | ret = wret; |
352 | if (btrfs_header_nritems(&right->header) == 0) { | 353 | if (btrfs_header_nritems(&right->header) == 0) { |
353 | u64 blocknr = right_buf->b_blocknr; | 354 | u64 blocknr = right_buf->b_blocknr; |
354 | btrfs_block_release(root, right_buf); | ||
355 | clean_tree_block(trans, root, right_buf); | 355 | clean_tree_block(trans, root, right_buf); |
356 | wait_on_buffer(right_buf); | ||
357 | btrfs_block_release(root, right_buf); | ||
356 | right_buf = NULL; | 358 | right_buf = NULL; |
357 | right = NULL; | 359 | right = NULL; |
358 | wret = del_ptr(trans, root, path, level + 1, pslot + | 360 | wret = del_ptr(trans, root, path, level + 1, pslot + |
@@ -363,10 +365,11 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
363 | if (wret) | 365 | if (wret) |
364 | ret = wret; | 366 | ret = wret; |
365 | } else { | 367 | } else { |
366 | memcpy(&parent->ptrs[pslot + 1].key, | 368 | btrfs_memcpy(root, parent, |
367 | &right->ptrs[0].key, | 369 | &parent->ptrs[pslot + 1].key, |
368 | sizeof(struct btrfs_disk_key)); | 370 | &right->ptrs[0].key, |
369 | mark_buffer_dirty(parent_buf); | 371 | sizeof(struct btrfs_disk_key)); |
372 | btrfs_mark_buffer_dirty(parent_buf); | ||
370 | } | 373 | } |
371 | } | 374 | } |
372 | if (btrfs_header_nritems(&mid->header) == 1) { | 375 | if (btrfs_header_nritems(&mid->header) == 1) { |
@@ -388,8 +391,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
388 | if (btrfs_header_nritems(&mid->header) == 0) { | 391 | if (btrfs_header_nritems(&mid->header) == 0) { |
389 | /* we've managed to empty the middle node, drop it */ | 392 | /* we've managed to empty the middle node, drop it */ |
390 | u64 blocknr = mid_buf->b_blocknr; | 393 | u64 blocknr = mid_buf->b_blocknr; |
391 | btrfs_block_release(root, mid_buf); | ||
392 | clean_tree_block(trans, root, mid_buf); | 394 | clean_tree_block(trans, root, mid_buf); |
395 | wait_on_buffer(mid_buf); | ||
396 | btrfs_block_release(root, mid_buf); | ||
393 | mid_buf = NULL; | 397 | mid_buf = NULL; |
394 | mid = NULL; | 398 | mid = NULL; |
395 | wret = del_ptr(trans, root, path, level + 1, pslot); | 399 | wret = del_ptr(trans, root, path, level + 1, pslot); |
@@ -400,9 +404,10 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
400 | ret = wret; | 404 | ret = wret; |
401 | } else { | 405 | } else { |
402 | /* update the parent key to reflect our changes */ | 406 | /* update the parent key to reflect our changes */ |
403 | memcpy(&parent->ptrs[pslot].key, &mid->ptrs[0].key, | 407 | btrfs_memcpy(root, parent, |
404 | sizeof(struct btrfs_disk_key)); | 408 | &parent->ptrs[pslot].key, &mid->ptrs[0].key, |
405 | mark_buffer_dirty(parent_buf); | 409 | sizeof(struct btrfs_disk_key)); |
410 | btrfs_mark_buffer_dirty(parent_buf); | ||
406 | } | 411 | } |
407 | 412 | ||
408 | /* update the path */ | 413 | /* update the path */ |
@@ -544,8 +549,8 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root | |||
544 | if (!path->nodes[i]) | 549 | if (!path->nodes[i]) |
545 | break; | 550 | break; |
546 | t = btrfs_buffer_node(path->nodes[i]); | 551 | t = btrfs_buffer_node(path->nodes[i]); |
547 | memcpy(&t->ptrs[tslot].key, key, sizeof(*key)); | 552 | btrfs_memcpy(root, t, &t->ptrs[tslot].key, key, sizeof(*key)); |
548 | mark_buffer_dirty(path->nodes[i]); | 553 | btrfs_mark_buffer_dirty(path->nodes[i]); |
549 | if (tslot != 0) | 554 | if (tslot != 0) |
550 | break; | 555 | break; |
551 | } | 556 | } |
@@ -580,17 +585,17 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
580 | if (src_nritems < push_items) | 585 | if (src_nritems < push_items) |
581 | push_items = src_nritems; | 586 | push_items = src_nritems; |
582 | 587 | ||
583 | memcpy(dst->ptrs + dst_nritems, src->ptrs, | 588 | btrfs_memcpy(root, dst, dst->ptrs + dst_nritems, src->ptrs, |
584 | push_items * sizeof(struct btrfs_key_ptr)); | 589 | push_items * sizeof(struct btrfs_key_ptr)); |
585 | if (push_items < src_nritems) { | 590 | if (push_items < src_nritems) { |
586 | memmove(src->ptrs, src->ptrs + push_items, | 591 | btrfs_memmove(root, src, src->ptrs, src->ptrs + push_items, |
587 | (src_nritems - push_items) * | 592 | (src_nritems - push_items) * |
588 | sizeof(struct btrfs_key_ptr)); | 593 | sizeof(struct btrfs_key_ptr)); |
589 | } | 594 | } |
590 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); | 595 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); |
591 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); | 596 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); |
592 | mark_buffer_dirty(src_buf); | 597 | btrfs_mark_buffer_dirty(src_buf); |
593 | mark_buffer_dirty(dst_buf); | 598 | btrfs_mark_buffer_dirty(dst_buf); |
594 | return ret; | 599 | return ret; |
595 | } | 600 | } |
596 | 601 | ||
@@ -629,16 +634,18 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct | |||
629 | if (max_push < push_items) | 634 | if (max_push < push_items) |
630 | push_items = max_push; | 635 | push_items = max_push; |
631 | 636 | ||
632 | memmove(dst->ptrs + push_items, dst->ptrs, | 637 | btrfs_memmove(root, dst, dst->ptrs + push_items, dst->ptrs, |
633 | dst_nritems * sizeof(struct btrfs_key_ptr)); | 638 | dst_nritems * sizeof(struct btrfs_key_ptr)); |
634 | memcpy(dst->ptrs, src->ptrs + src_nritems - push_items, | 639 | |
635 | push_items * sizeof(struct btrfs_key_ptr)); | 640 | btrfs_memcpy(root, dst, dst->ptrs, |
641 | src->ptrs + src_nritems - push_items, | ||
642 | push_items * sizeof(struct btrfs_key_ptr)); | ||
636 | 643 | ||
637 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); | 644 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); |
638 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); | 645 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); |
639 | 646 | ||
640 | mark_buffer_dirty(src_buf); | 647 | btrfs_mark_buffer_dirty(src_buf); |
641 | mark_buffer_dirty(dst_buf); | 648 | btrfs_mark_buffer_dirty(dst_buf); |
642 | return ret; | 649 | return ret; |
643 | } | 650 | } |
644 | 651 | ||
@@ -674,10 +681,11 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root | |||
674 | lower_key = &((struct btrfs_leaf *)lower)->items[0].key; | 681 | lower_key = &((struct btrfs_leaf *)lower)->items[0].key; |
675 | else | 682 | else |
676 | lower_key = &lower->ptrs[0].key; | 683 | lower_key = &lower->ptrs[0].key; |
677 | memcpy(&c->ptrs[0].key, lower_key, sizeof(struct btrfs_disk_key)); | 684 | btrfs_memcpy(root, c, &c->ptrs[0].key, lower_key, |
685 | sizeof(struct btrfs_disk_key)); | ||
678 | btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->b_blocknr); | 686 | btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->b_blocknr); |
679 | 687 | ||
680 | mark_buffer_dirty(t); | 688 | btrfs_mark_buffer_dirty(t); |
681 | 689 | ||
682 | /* the super has an extra ref to root->node */ | 690 | /* the super has an extra ref to root->node */ |
683 | btrfs_block_release(root, root->node); | 691 | btrfs_block_release(root, root->node); |
@@ -712,13 +720,15 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | |||
712 | if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) | 720 | if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) |
713 | BUG(); | 721 | BUG(); |
714 | if (slot != nritems) { | 722 | if (slot != nritems) { |
715 | memmove(lower->ptrs + slot + 1, lower->ptrs + slot, | 723 | btrfs_memmove(root, lower, lower->ptrs + slot + 1, |
716 | (nritems - slot) * sizeof(struct btrfs_key_ptr)); | 724 | lower->ptrs + slot, |
725 | (nritems - slot) * sizeof(struct btrfs_key_ptr)); | ||
717 | } | 726 | } |
718 | memcpy(&lower->ptrs[slot].key, key, sizeof(struct btrfs_disk_key)); | 727 | btrfs_memcpy(root, lower, &lower->ptrs[slot].key, |
728 | key, sizeof(struct btrfs_disk_key)); | ||
719 | btrfs_set_node_blockptr(lower, slot, blocknr); | 729 | btrfs_set_node_blockptr(lower, slot, blocknr); |
720 | btrfs_set_header_nritems(&lower->header, nritems + 1); | 730 | btrfs_set_header_nritems(&lower->header, nritems + 1); |
721 | mark_buffer_dirty(path->nodes[level]); | 731 | btrfs_mark_buffer_dirty(path->nodes[level]); |
722 | return 0; | 732 | return 0; |
723 | } | 733 | } |
724 | 734 | ||
@@ -761,14 +771,14 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
761 | btrfs_set_header_parentid(&split->header, | 771 | btrfs_set_header_parentid(&split->header, |
762 | btrfs_header_parentid(btrfs_buffer_header(root->node))); | 772 | btrfs_header_parentid(btrfs_buffer_header(root->node))); |
763 | mid = (c_nritems + 1) / 2; | 773 | mid = (c_nritems + 1) / 2; |
764 | memcpy(split->ptrs, c->ptrs + mid, | 774 | btrfs_memcpy(root, split, split->ptrs, c->ptrs + mid, |
765 | (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); | 775 | (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); |
766 | btrfs_set_header_nritems(&split->header, c_nritems - mid); | 776 | btrfs_set_header_nritems(&split->header, c_nritems - mid); |
767 | btrfs_set_header_nritems(&c->header, mid); | 777 | btrfs_set_header_nritems(&c->header, mid); |
768 | ret = 0; | 778 | ret = 0; |
769 | 779 | ||
770 | mark_buffer_dirty(t); | 780 | btrfs_mark_buffer_dirty(t); |
771 | mark_buffer_dirty(split_buffer); | 781 | btrfs_mark_buffer_dirty(split_buffer); |
772 | wret = insert_ptr(trans, root, path, &split->ptrs[0].key, | 782 | wret = insert_ptr(trans, root, path, &split->ptrs[0].key, |
773 | split_buffer->b_blocknr, path->slots[level + 1] + 1, | 783 | split_buffer->b_blocknr, path->slots[level + 1] + 1, |
774 | level + 1); | 784 | level + 1); |
@@ -875,17 +885,22 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
875 | push_space = btrfs_item_end(left->items + left_nritems - push_items); | 885 | push_space = btrfs_item_end(left->items + left_nritems - push_items); |
876 | push_space -= leaf_data_end(root, left); | 886 | push_space -= leaf_data_end(root, left); |
877 | /* make room in the right data area */ | 887 | /* make room in the right data area */ |
878 | memmove(btrfs_leaf_data(right) + leaf_data_end(root, right) - | 888 | btrfs_memmove(root, right, btrfs_leaf_data(right) + |
879 | push_space, btrfs_leaf_data(right) + leaf_data_end(root, right), | 889 | leaf_data_end(root, right) - push_space, |
880 | BTRFS_LEAF_DATA_SIZE(root) - leaf_data_end(root, right)); | 890 | btrfs_leaf_data(right) + |
891 | leaf_data_end(root, right), BTRFS_LEAF_DATA_SIZE(root) - | ||
892 | leaf_data_end(root, right)); | ||
881 | /* copy from the left data area */ | 893 | /* copy from the left data area */ |
882 | memcpy(btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - push_space, | 894 | btrfs_memcpy(root, right, btrfs_leaf_data(right) + |
883 | btrfs_leaf_data(left) + leaf_data_end(root, left), push_space); | 895 | BTRFS_LEAF_DATA_SIZE(root) - push_space, |
884 | memmove(right->items + push_items, right->items, | 896 | btrfs_leaf_data(left) + leaf_data_end(root, left), |
897 | push_space); | ||
898 | btrfs_memmove(root, right, right->items + push_items, right->items, | ||
885 | right_nritems * sizeof(struct btrfs_item)); | 899 | right_nritems * sizeof(struct btrfs_item)); |
886 | /* copy the items from left to right */ | 900 | /* copy the items from left to right */ |
887 | memcpy(right->items, left->items + left_nritems - push_items, | 901 | btrfs_memcpy(root, right, right->items, left->items + |
888 | push_items * sizeof(struct btrfs_item)); | 902 | left_nritems - push_items, |
903 | push_items * sizeof(struct btrfs_item)); | ||
889 | 904 | ||
890 | /* update the item pointers */ | 905 | /* update the item pointers */ |
891 | right_nritems += push_items; | 906 | right_nritems += push_items; |
@@ -899,11 +914,11 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
899 | left_nritems -= push_items; | 914 | left_nritems -= push_items; |
900 | btrfs_set_header_nritems(&left->header, left_nritems); | 915 | btrfs_set_header_nritems(&left->header, left_nritems); |
901 | 916 | ||
902 | mark_buffer_dirty(left_buf); | 917 | btrfs_mark_buffer_dirty(left_buf); |
903 | mark_buffer_dirty(right_buf); | 918 | btrfs_mark_buffer_dirty(right_buf); |
904 | memcpy(&upper_node->ptrs[slot + 1].key, | 919 | btrfs_memcpy(root, upper_node, &upper_node->ptrs[slot + 1].key, |
905 | &right->items[0].key, sizeof(struct btrfs_disk_key)); | 920 | &right->items[0].key, sizeof(struct btrfs_disk_key)); |
906 | mark_buffer_dirty(upper); | 921 | btrfs_mark_buffer_dirty(upper); |
907 | 922 | ||
908 | /* then fixup the leaf pointer in the path */ | 923 | /* then fixup the leaf pointer in the path */ |
909 | if (path->slots[0] >= left_nritems) { | 924 | if (path->slots[0] >= left_nritems) { |
@@ -977,14 +992,16 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
977 | return 1; | 992 | return 1; |
978 | } | 993 | } |
979 | /* push data from right to left */ | 994 | /* push data from right to left */ |
980 | memcpy(left->items + btrfs_header_nritems(&left->header), | 995 | btrfs_memcpy(root, left, left->items + |
981 | right->items, push_items * sizeof(struct btrfs_item)); | 996 | btrfs_header_nritems(&left->header), |
997 | right->items, push_items * sizeof(struct btrfs_item)); | ||
982 | push_space = BTRFS_LEAF_DATA_SIZE(root) - | 998 | push_space = BTRFS_LEAF_DATA_SIZE(root) - |
983 | btrfs_item_offset(right->items + push_items -1); | 999 | btrfs_item_offset(right->items + push_items -1); |
984 | memcpy(btrfs_leaf_data(left) + leaf_data_end(root, left) - push_space, | 1000 | btrfs_memcpy(root, left, btrfs_leaf_data(left) + |
985 | btrfs_leaf_data(right) + | 1001 | leaf_data_end(root, left) - push_space, |
986 | btrfs_item_offset(right->items + push_items - 1), | 1002 | btrfs_leaf_data(right) + |
987 | push_space); | 1003 | btrfs_item_offset(right->items + push_items - 1), |
1004 | push_space); | ||
988 | old_left_nritems = btrfs_header_nritems(&left->header); | 1005 | old_left_nritems = btrfs_header_nritems(&left->header); |
989 | BUG_ON(old_left_nritems < 0); | 1006 | BUG_ON(old_left_nritems < 0); |
990 | 1007 | ||
@@ -1000,10 +1017,11 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1000 | /* fixup right node */ | 1017 | /* fixup right node */ |
1001 | push_space = btrfs_item_offset(right->items + push_items - 1) - | 1018 | push_space = btrfs_item_offset(right->items + push_items - 1) - |
1002 | leaf_data_end(root, right); | 1019 | leaf_data_end(root, right); |
1003 | memmove(btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - | 1020 | btrfs_memmove(root, right, btrfs_leaf_data(right) + |
1004 | push_space, btrfs_leaf_data(right) + | 1021 | BTRFS_LEAF_DATA_SIZE(root) - push_space, |
1005 | leaf_data_end(root, right), push_space); | 1022 | btrfs_leaf_data(right) + |
1006 | memmove(right->items, right->items + push_items, | 1023 | leaf_data_end(root, right), push_space); |
1024 | btrfs_memmove(root, right, right->items, right->items + push_items, | ||
1007 | (btrfs_header_nritems(&right->header) - push_items) * | 1025 | (btrfs_header_nritems(&right->header) - push_items) * |
1008 | sizeof(struct btrfs_item)); | 1026 | sizeof(struct btrfs_item)); |
1009 | btrfs_set_header_nritems(&right->header, | 1027 | btrfs_set_header_nritems(&right->header, |
@@ -1017,8 +1035,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1017 | push_space = btrfs_item_offset(right->items + i); | 1035 | push_space = btrfs_item_offset(right->items + i); |
1018 | } | 1036 | } |
1019 | 1037 | ||
1020 | mark_buffer_dirty(t); | 1038 | btrfs_mark_buffer_dirty(t); |
1021 | mark_buffer_dirty(right_buf); | 1039 | btrfs_mark_buffer_dirty(right_buf); |
1022 | 1040 | ||
1023 | wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); | 1041 | wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); |
1024 | if (wret) | 1042 | if (wret) |
@@ -1110,11 +1128,12 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1110 | btrfs_header_parentid(btrfs_buffer_header(root->node))); | 1128 | btrfs_header_parentid(btrfs_buffer_header(root->node))); |
1111 | data_copy_size = btrfs_item_end(l->items + mid) - | 1129 | data_copy_size = btrfs_item_end(l->items + mid) - |
1112 | leaf_data_end(root, l); | 1130 | leaf_data_end(root, l); |
1113 | memcpy(right->items, l->items + mid, | 1131 | btrfs_memcpy(root, right, right->items, l->items + mid, |
1114 | (nritems - mid) * sizeof(struct btrfs_item)); | 1132 | (nritems - mid) * sizeof(struct btrfs_item)); |
1115 | memcpy(btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - | 1133 | btrfs_memcpy(root, right, |
1116 | data_copy_size, btrfs_leaf_data(l) + | 1134 | btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - |
1117 | leaf_data_end(root, l), data_copy_size); | 1135 | data_copy_size, btrfs_leaf_data(l) + |
1136 | leaf_data_end(root, l), data_copy_size); | ||
1118 | rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - | 1137 | rt_data_off = BTRFS_LEAF_DATA_SIZE(root) - |
1119 | btrfs_item_end(l->items + mid); | 1138 | btrfs_item_end(l->items + mid); |
1120 | 1139 | ||
@@ -1129,8 +1148,8 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1129 | right_buffer->b_blocknr, path->slots[1] + 1, 1); | 1148 | right_buffer->b_blocknr, path->slots[1] + 1, 1); |
1130 | if (wret) | 1149 | if (wret) |
1131 | ret = wret; | 1150 | ret = wret; |
1132 | mark_buffer_dirty(right_buffer); | 1151 | btrfs_mark_buffer_dirty(right_buffer); |
1133 | mark_buffer_dirty(l_buf); | 1152 | btrfs_mark_buffer_dirty(l_buf); |
1134 | BUG_ON(path->slots[0] != slot); | 1153 | BUG_ON(path->slots[0] != slot); |
1135 | if (mid <= slot) { | 1154 | if (mid <= slot) { |
1136 | btrfs_block_release(root, path->nodes[0]); | 1155 | btrfs_block_release(root, path->nodes[0]); |
@@ -1200,22 +1219,23 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1200 | } | 1219 | } |
1201 | 1220 | ||
1202 | /* shift the items */ | 1221 | /* shift the items */ |
1203 | memmove(leaf->items + slot + 1, leaf->items + slot, | 1222 | btrfs_memmove(root, leaf, leaf->items + slot + 1, |
1204 | (nritems - slot) * sizeof(struct btrfs_item)); | 1223 | leaf->items + slot, |
1224 | (nritems - slot) * sizeof(struct btrfs_item)); | ||
1205 | 1225 | ||
1206 | /* shift the data */ | 1226 | /* shift the data */ |
1207 | memmove(btrfs_leaf_data(leaf) + data_end - data_size, | 1227 | btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + |
1208 | btrfs_leaf_data(leaf) + | 1228 | data_end - data_size, btrfs_leaf_data(leaf) + |
1209 | data_end, old_data - data_end); | 1229 | data_end, old_data - data_end); |
1210 | data_end = old_data; | 1230 | data_end = old_data; |
1211 | } | 1231 | } |
1212 | /* setup the item for the new data */ | 1232 | /* setup the item for the new data */ |
1213 | memcpy(&leaf->items[slot].key, &disk_key, | 1233 | btrfs_memcpy(root, leaf, &leaf->items[slot].key, &disk_key, |
1214 | sizeof(struct btrfs_disk_key)); | 1234 | sizeof(struct btrfs_disk_key)); |
1215 | btrfs_set_item_offset(leaf->items + slot, data_end - data_size); | 1235 | btrfs_set_item_offset(leaf->items + slot, data_end - data_size); |
1216 | btrfs_set_item_size(leaf->items + slot, data_size); | 1236 | btrfs_set_item_size(leaf->items + slot, data_size); |
1217 | btrfs_set_header_nritems(&leaf->header, nritems + 1); | 1237 | btrfs_set_header_nritems(&leaf->header, nritems + 1); |
1218 | mark_buffer_dirty(leaf_buf); | 1238 | btrfs_mark_buffer_dirty(leaf_buf); |
1219 | 1239 | ||
1220 | ret = 0; | 1240 | ret = 0; |
1221 | if (slot == 0) | 1241 | if (slot == 0) |
@@ -1245,8 +1265,9 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1245 | if (!ret) { | 1265 | if (!ret) { |
1246 | ptr = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), | 1266 | ptr = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), |
1247 | path.slots[0], u8); | 1267 | path.slots[0], u8); |
1248 | memcpy(ptr, data, data_size); | 1268 | btrfs_memcpy(root, path.nodes[0]->b_data, |
1249 | mark_buffer_dirty(path.nodes[0]); | 1269 | ptr, data, data_size); |
1270 | btrfs_mark_buffer_dirty(path.nodes[0]); | ||
1250 | } | 1271 | } |
1251 | btrfs_release_path(root, &path); | 1272 | btrfs_release_path(root, &path); |
1252 | return ret; | 1273 | return ret; |
@@ -1271,8 +1292,10 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1271 | node = btrfs_buffer_node(parent); | 1292 | node = btrfs_buffer_node(parent); |
1272 | nritems = btrfs_header_nritems(&node->header); | 1293 | nritems = btrfs_header_nritems(&node->header); |
1273 | if (slot != nritems -1) { | 1294 | if (slot != nritems -1) { |
1274 | memmove(node->ptrs + slot, node->ptrs + slot + 1, | 1295 | btrfs_memmove(root, node, node->ptrs + slot, |
1275 | sizeof(struct btrfs_key_ptr) * (nritems - slot - 1)); | 1296 | node->ptrs + slot + 1, |
1297 | sizeof(struct btrfs_key_ptr) * | ||
1298 | (nritems - slot - 1)); | ||
1276 | } | 1299 | } |
1277 | nritems--; | 1300 | nritems--; |
1278 | btrfs_set_header_nritems(&node->header, nritems); | 1301 | btrfs_set_header_nritems(&node->header, nritems); |
@@ -1287,7 +1310,7 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1287 | if (wret) | 1310 | if (wret) |
1288 | ret = wret; | 1311 | ret = wret; |
1289 | } | 1312 | } |
1290 | mark_buffer_dirty(parent); | 1313 | btrfs_mark_buffer_dirty(parent); |
1291 | return ret; | 1314 | return ret; |
1292 | } | 1315 | } |
1293 | 1316 | ||
@@ -1317,16 +1340,18 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1317 | if (slot != nritems - 1) { | 1340 | if (slot != nritems - 1) { |
1318 | int i; | 1341 | int i; |
1319 | int data_end = leaf_data_end(root, leaf); | 1342 | int data_end = leaf_data_end(root, leaf); |
1320 | memmove(btrfs_leaf_data(leaf) + data_end + dsize, | 1343 | btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + |
1321 | btrfs_leaf_data(leaf) + data_end, | 1344 | data_end + dsize, |
1322 | doff - data_end); | 1345 | btrfs_leaf_data(leaf) + data_end, |
1346 | doff - data_end); | ||
1323 | for (i = slot + 1; i < nritems; i++) { | 1347 | for (i = slot + 1; i < nritems; i++) { |
1324 | u32 ioff = btrfs_item_offset(leaf->items + i); | 1348 | u32 ioff = btrfs_item_offset(leaf->items + i); |
1325 | btrfs_set_item_offset(leaf->items + i, ioff + dsize); | 1349 | btrfs_set_item_offset(leaf->items + i, ioff + dsize); |
1326 | } | 1350 | } |
1327 | memmove(leaf->items + slot, leaf->items + slot + 1, | 1351 | btrfs_memmove(root, leaf, leaf->items + slot, |
1328 | sizeof(struct btrfs_item) * | 1352 | leaf->items + slot + 1, |
1329 | (nritems - slot - 1)); | 1353 | sizeof(struct btrfs_item) * |
1354 | (nritems - slot - 1)); | ||
1330 | } | 1355 | } |
1331 | btrfs_set_header_nritems(&leaf->header, nritems - 1); | 1356 | btrfs_set_header_nritems(&leaf->header, nritems - 1); |
1332 | nritems--; | 1357 | nritems--; |
@@ -1336,6 +1361,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1336 | btrfs_set_header_level(&leaf->header, 0); | 1361 | btrfs_set_header_level(&leaf->header, 0); |
1337 | } else { | 1362 | } else { |
1338 | clean_tree_block(trans, root, leaf_buf); | 1363 | clean_tree_block(trans, root, leaf_buf); |
1364 | wait_on_buffer(leaf_buf); | ||
1339 | wret = del_ptr(trans, root, path, 1, path->slots[1]); | 1365 | wret = del_ptr(trans, root, path, 1, path->slots[1]); |
1340 | if (wret) | 1366 | if (wret) |
1341 | ret = wret; | 1367 | ret = wret; |
@@ -1373,6 +1399,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1373 | if (btrfs_header_nritems(&leaf->header) == 0) { | 1399 | if (btrfs_header_nritems(&leaf->header) == 0) { |
1374 | u64 blocknr = leaf_buf->b_blocknr; | 1400 | u64 blocknr = leaf_buf->b_blocknr; |
1375 | clean_tree_block(trans, root, leaf_buf); | 1401 | clean_tree_block(trans, root, leaf_buf); |
1402 | wait_on_buffer(leaf_buf); | ||
1376 | wret = del_ptr(trans, root, path, 1, slot); | 1403 | wret = del_ptr(trans, root, path, 1, slot); |
1377 | if (wret) | 1404 | if (wret) |
1378 | ret = wret; | 1405 | ret = wret; |
@@ -1382,11 +1409,11 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1382 | if (wret) | 1409 | if (wret) |
1383 | ret = wret; | 1410 | ret = wret; |
1384 | } else { | 1411 | } else { |
1385 | mark_buffer_dirty(leaf_buf); | 1412 | btrfs_mark_buffer_dirty(leaf_buf); |
1386 | btrfs_block_release(root, leaf_buf); | 1413 | btrfs_block_release(root, leaf_buf); |
1387 | } | 1414 | } |
1388 | } else { | 1415 | } else { |
1389 | mark_buffer_dirty(leaf_buf); | 1416 | btrfs_mark_buffer_dirty(leaf_buf); |
1390 | } | 1417 | } |
1391 | } | 1418 | } |
1392 | return ret; | 1419 | return ret; |