diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-10-15 16:15:53 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:56 -0400 |
commit | db94535db75e67fab12ccbb7f5ee548e33fed891 (patch) | |
tree | 1ad7dfc82b003294a94ee87d7329b24b902b369f /fs/btrfs/ctree.c | |
parent | 1a5bc167f6707542b79a55452075525620ed43f5 (diff) |
Btrfs: Allow tree blocks larger than the page size
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 319 |
1 files changed, 229 insertions, 90 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 50ef351ef6b3..34de83630ae9 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -83,16 +83,15 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
83 | 83 | ||
84 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); | 84 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); |
85 | 85 | ||
86 | cow = btrfs_alloc_free_block(trans, root, search_start, empty_size); | 86 | cow = btrfs_alloc_free_block(trans, root, buf->len, |
87 | search_start, empty_size); | ||
87 | if (IS_ERR(cow)) | 88 | if (IS_ERR(cow)) |
88 | return PTR_ERR(cow); | 89 | return PTR_ERR(cow); |
89 | 90 | ||
90 | cow->alloc_addr = (unsigned long)__builtin_return_address(0); | 91 | cow->alloc_addr = (unsigned long)__builtin_return_address(0); |
91 | if (buf->len != root->sectorsize || cow->len != root->sectorsize) | ||
92 | WARN_ON(1); | ||
93 | 92 | ||
94 | copy_extent_buffer(cow, buf, 0, 0, cow->len); | 93 | copy_extent_buffer(cow, buf, 0, 0, cow->len); |
95 | btrfs_set_header_blocknr(cow, extent_buffer_blocknr(cow)); | 94 | btrfs_set_header_bytenr(cow, cow->start); |
96 | btrfs_set_header_generation(cow, trans->transid); | 95 | btrfs_set_header_generation(cow, trans->transid); |
97 | btrfs_set_header_owner(cow, root->root_key.objectid); | 96 | btrfs_set_header_owner(cow, root->root_key.objectid); |
98 | 97 | ||
@@ -110,16 +109,16 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
110 | root->node = cow; | 109 | root->node = cow; |
111 | extent_buffer_get(cow); | 110 | extent_buffer_get(cow); |
112 | if (buf != root->commit_root) { | 111 | if (buf != root->commit_root) { |
113 | btrfs_free_extent(trans, root, | 112 | btrfs_free_extent(trans, root, buf->start, |
114 | extent_buffer_blocknr(buf), 1, 1); | 113 | buf->len, 1); |
115 | } | 114 | } |
116 | free_extent_buffer(buf); | 115 | free_extent_buffer(buf); |
117 | } else { | 116 | } else { |
118 | btrfs_set_node_blockptr(parent, parent_slot, | 117 | btrfs_set_node_blockptr(parent, parent_slot, |
119 | extent_buffer_blocknr(cow)); | 118 | cow->start); |
120 | btrfs_mark_buffer_dirty(parent); | 119 | btrfs_mark_buffer_dirty(parent); |
121 | WARN_ON(btrfs_header_generation(parent) != trans->transid); | 120 | WARN_ON(btrfs_header_generation(parent) != trans->transid); |
122 | btrfs_free_extent(trans, root, extent_buffer_blocknr(buf),1,1); | 121 | btrfs_free_extent(trans, root, buf->start, buf->len, 1); |
123 | } | 122 | } |
124 | free_extent_buffer(buf); | 123 | free_extent_buffer(buf); |
125 | btrfs_mark_buffer_dirty(cow); | 124 | btrfs_mark_buffer_dirty(cow); |
@@ -149,13 +148,14 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
149 | return 0; | 148 | return 0; |
150 | } | 149 | } |
151 | 150 | ||
152 | search_start = extent_buffer_blocknr(buf) & ~((u64)65535); | 151 | search_start = buf->start & ~((u64)BTRFS_BLOCK_GROUP_SIZE - 1); |
153 | ret = __btrfs_cow_block(trans, root, buf, parent, | 152 | ret = __btrfs_cow_block(trans, root, buf, parent, |
154 | parent_slot, cow_ret, search_start, 0); | 153 | parent_slot, cow_ret, search_start, 0); |
155 | (*cow_ret)->alloc_addr = (unsigned long)__builtin_return_address(0); | 154 | (*cow_ret)->alloc_addr = (unsigned long)__builtin_return_address(0); |
156 | return ret; | 155 | return ret; |
157 | } | 156 | } |
158 | 157 | ||
158 | #if 0 | ||
159 | static int close_blocks(u64 blocknr, u64 other) | 159 | static int close_blocks(u64 blocknr, u64 other) |
160 | { | 160 | { |
161 | if (blocknr < other && other - blocknr < 8) | 161 | if (blocknr < other && other - blocknr < 8) |
@@ -165,7 +165,6 @@ static int close_blocks(u64 blocknr, u64 other) | |||
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
168 | #if 0 | ||
169 | static int should_defrag_leaf(struct extent_buffer *eb) | 168 | static int should_defrag_leaf(struct extent_buffer *eb) |
170 | { | 169 | { |
171 | return 0; | 170 | return 0; |
@@ -355,7 +354,7 @@ static int check_node(struct btrfs_root *root, struct btrfs_path *path, | |||
355 | BUG_ON(memcmp(&parent_key, &node_key, | 354 | BUG_ON(memcmp(&parent_key, &node_key, |
356 | sizeof(struct btrfs_disk_key))); | 355 | sizeof(struct btrfs_disk_key))); |
357 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != | 356 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != |
358 | btrfs_header_blocknr(node)); | 357 | btrfs_header_bytenr(node)); |
359 | } | 358 | } |
360 | BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); | 359 | BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root)); |
361 | if (slot != 0) { | 360 | if (slot != 0) { |
@@ -398,7 +397,7 @@ static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, | |||
398 | BUG_ON(memcmp(&parent_key, &leaf_key, | 397 | BUG_ON(memcmp(&parent_key, &leaf_key, |
399 | sizeof(struct btrfs_disk_key))); | 398 | sizeof(struct btrfs_disk_key))); |
400 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != | 399 | BUG_ON(btrfs_node_blockptr(parent, parent_slot) != |
401 | btrfs_header_blocknr(leaf)); | 400 | btrfs_header_bytenr(leaf)); |
402 | } | 401 | } |
403 | #if 0 | 402 | #if 0 |
404 | for (i = 0; nritems > 1 && i < nritems - 2; i++) { | 403 | for (i = 0; nritems > 1 && i < nritems - 2; i++) { |
@@ -467,14 +466,16 @@ static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, | |||
467 | static int check_block(struct btrfs_root *root, struct btrfs_path *path, | 466 | static int check_block(struct btrfs_root *root, struct btrfs_path *path, |
468 | int level) | 467 | int level) |
469 | { | 468 | { |
469 | #if 0 | ||
470 | struct extent_buffer *buf = path->nodes[level]; | 470 | struct extent_buffer *buf = path->nodes[level]; |
471 | 471 | ||
472 | if (memcmp_extent_buffer(buf, root->fs_info->fsid, | 472 | if (memcmp_extent_buffer(buf, root->fs_info->fsid, |
473 | (unsigned long)btrfs_header_fsid(buf), | 473 | (unsigned long)btrfs_header_fsid(buf), |
474 | BTRFS_FSID_SIZE)) { | 474 | BTRFS_FSID_SIZE)) { |
475 | printk("warning bad block %Lu\n", buf->start); | 475 | printk("warning bad block %Lu\n", buf->start); |
476 | BUG(); | 476 | return 1; |
477 | } | 477 | } |
478 | #endif | ||
478 | if (level == 0) | 479 | if (level == 0) |
479 | return check_leaf(root, path, level); | 480 | return check_leaf(root, path, level); |
480 | return check_node(root, path, level); | 481 | return check_node(root, path, level); |
@@ -585,7 +586,8 @@ static struct extent_buffer *read_node_slot(struct btrfs_root *root, | |||
585 | return NULL; | 586 | return NULL; |
586 | if (slot >= btrfs_header_nritems(parent)) | 587 | if (slot >= btrfs_header_nritems(parent)) |
587 | return NULL; | 588 | return NULL; |
588 | return read_tree_block(root, btrfs_node_blockptr(parent, slot)); | 589 | return read_tree_block(root, btrfs_node_blockptr(parent, slot), |
590 | btrfs_level_size(root, btrfs_header_level(parent) - 1)); | ||
589 | } | 591 | } |
590 | 592 | ||
591 | static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | 593 | static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root |
@@ -618,7 +620,6 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
618 | */ | 620 | */ |
619 | if (!parent) { | 621 | if (!parent) { |
620 | struct extent_buffer *child; | 622 | struct extent_buffer *child; |
621 | u64 blocknr = extent_buffer_blocknr(mid); | ||
622 | 623 | ||
623 | if (btrfs_header_nritems(mid) != 1) | 624 | if (btrfs_header_nritems(mid) != 1) |
624 | return 0; | 625 | return 0; |
@@ -632,9 +633,10 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
632 | wait_on_tree_block_writeback(root, mid); | 633 | wait_on_tree_block_writeback(root, mid); |
633 | /* once for the path */ | 634 | /* once for the path */ |
634 | free_extent_buffer(mid); | 635 | free_extent_buffer(mid); |
636 | ret = btrfs_free_extent(trans, root, mid->start, mid->len, 1); | ||
635 | /* once for the root ptr */ | 637 | /* once for the root ptr */ |
636 | free_extent_buffer(mid); | 638 | free_extent_buffer(mid); |
637 | return btrfs_free_extent(trans, root, blocknr, 1, 1); | 639 | return ret; |
638 | } | 640 | } |
639 | if (btrfs_header_nritems(mid) > | 641 | if (btrfs_header_nritems(mid) > |
640 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) | 642 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) |
@@ -680,7 +682,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
680 | if (wret < 0 && wret != -ENOSPC) | 682 | if (wret < 0 && wret != -ENOSPC) |
681 | ret = wret; | 683 | ret = wret; |
682 | if (btrfs_header_nritems(right) == 0) { | 684 | if (btrfs_header_nritems(right) == 0) { |
683 | u64 blocknr = extent_buffer_blocknr(right); | 685 | u64 bytenr = right->start; |
686 | u32 blocksize = right->len; | ||
687 | |||
684 | clean_tree_block(trans, root, right); | 688 | clean_tree_block(trans, root, right); |
685 | wait_on_tree_block_writeback(root, right); | 689 | wait_on_tree_block_writeback(root, right); |
686 | free_extent_buffer(right); | 690 | free_extent_buffer(right); |
@@ -689,7 +693,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
689 | 1); | 693 | 1); |
690 | if (wret) | 694 | if (wret) |
691 | ret = wret; | 695 | ret = wret; |
692 | wret = btrfs_free_extent(trans, root, blocknr, 1, 1); | 696 | wret = btrfs_free_extent(trans, root, bytenr, |
697 | blocksize, 1); | ||
693 | if (wret) | 698 | if (wret) |
694 | ret = wret; | 699 | ret = wret; |
695 | } else { | 700 | } else { |
@@ -719,7 +724,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
719 | } | 724 | } |
720 | if (btrfs_header_nritems(mid) == 0) { | 725 | if (btrfs_header_nritems(mid) == 0) { |
721 | /* we've managed to empty the middle node, drop it */ | 726 | /* we've managed to empty the middle node, drop it */ |
722 | u64 blocknr = extent_buffer_blocknr(mid); | 727 | u64 bytenr = mid->start; |
728 | u32 blocksize = mid->len; | ||
723 | clean_tree_block(trans, root, mid); | 729 | clean_tree_block(trans, root, mid); |
724 | wait_on_tree_block_writeback(root, mid); | 730 | wait_on_tree_block_writeback(root, mid); |
725 | free_extent_buffer(mid); | 731 | free_extent_buffer(mid); |
@@ -727,7 +733,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
727 | wret = del_ptr(trans, root, path, level + 1, pslot); | 733 | wret = del_ptr(trans, root, path, level + 1, pslot); |
728 | if (wret) | 734 | if (wret) |
729 | ret = wret; | 735 | ret = wret; |
730 | wret = btrfs_free_extent(trans, root, blocknr, 1, 1); | 736 | wret = btrfs_free_extent(trans, root, bytenr, blocksize, 1); |
731 | if (wret) | 737 | if (wret) |
732 | ret = wret; | 738 | ret = wret; |
733 | } else { | 739 | } else { |
@@ -830,7 +836,6 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
830 | path->slots[level] = orig_slot; | 836 | path->slots[level] = orig_slot; |
831 | free_extent_buffer(left); | 837 | free_extent_buffer(left); |
832 | } | 838 | } |
833 | check_node(root, path, level); | ||
834 | return 0; | 839 | return 0; |
835 | } | 840 | } |
836 | free_extent_buffer(left); | 841 | free_extent_buffer(left); |
@@ -874,12 +879,10 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
874 | } else { | 879 | } else { |
875 | free_extent_buffer(right); | 880 | free_extent_buffer(right); |
876 | } | 881 | } |
877 | check_node(root, path, level); | ||
878 | return 0; | 882 | return 0; |
879 | } | 883 | } |
880 | free_extent_buffer(right); | 884 | free_extent_buffer(right); |
881 | } | 885 | } |
882 | check_node(root, path, level); | ||
883 | return 1; | 886 | return 1; |
884 | } | 887 | } |
885 | 888 | ||
@@ -889,19 +892,23 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
889 | static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, | 892 | static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, |
890 | int level, int slot) | 893 | int level, int slot) |
891 | { | 894 | { |
895 | return; | ||
896 | #if 0 | ||
892 | struct extent_buffer *node; | 897 | struct extent_buffer *node; |
893 | int i; | 898 | int i; |
894 | u32 nritems; | 899 | u32 nritems; |
895 | u64 blocknr; | 900 | u64 bytenr; |
896 | u64 search; | 901 | u64 search; |
897 | u64 cluster_start; | 902 | u64 cluster_start; |
898 | int ret; | 903 | int ret; |
899 | int nread = 0; | 904 | int nread = 0; |
900 | int direction = path->reada; | 905 | int direction = path->reada; |
906 | int level; | ||
901 | struct radix_tree_root found; | 907 | struct radix_tree_root found; |
902 | unsigned long gang[8]; | 908 | unsigned long gang[8]; |
903 | struct extent_buffer *eb; | 909 | struct extent_buffer *eb; |
904 | 910 | ||
911 | |||
905 | if (level == 0) | 912 | if (level == 0) |
906 | return; | 913 | return; |
907 | 914 | ||
@@ -918,8 +925,9 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, | |||
918 | 925 | ||
919 | init_bit_radix(&found); | 926 | init_bit_radix(&found); |
920 | nritems = btrfs_header_nritems(node); | 927 | nritems = btrfs_header_nritems(node); |
928 | level = btrfs_header_level(node) - 1; | ||
921 | for (i = slot; i < nritems; i++) { | 929 | for (i = slot; i < nritems; i++) { |
922 | blocknr = btrfs_node_blockptr(node, i); | 930 | bytenr = btrfs_node_blockptr(node, i); |
923 | set_radix_bit(&found, blocknr); | 931 | set_radix_bit(&found, blocknr); |
924 | } | 932 | } |
925 | if (direction > 0) { | 933 | if (direction > 0) { |
@@ -944,6 +952,7 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, | |||
944 | } | 952 | } |
945 | } | 953 | } |
946 | } | 954 | } |
955 | #endif | ||
947 | } | 956 | } |
948 | /* | 957 | /* |
949 | * look for key in the tree. path is filled in with nodes along the way | 958 | * look for key in the tree. path is filled in with nodes along the way |
@@ -963,7 +972,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
963 | ins_len, int cow) | 972 | ins_len, int cow) |
964 | { | 973 | { |
965 | struct extent_buffer *b; | 974 | struct extent_buffer *b; |
966 | u64 blocknr; | 975 | u64 bytenr; |
967 | int slot; | 976 | int slot; |
968 | int ret; | 977 | int ret; |
969 | int level; | 978 | int level; |
@@ -1027,10 +1036,11 @@ again: | |||
1027 | /* this is only true while dropping a snapshot */ | 1036 | /* this is only true while dropping a snapshot */ |
1028 | if (level == lowest_level) | 1037 | if (level == lowest_level) |
1029 | break; | 1038 | break; |
1030 | blocknr = btrfs_node_blockptr(b, slot); | 1039 | bytenr = btrfs_node_blockptr(b, slot); |
1031 | if (should_reada) | 1040 | if (should_reada) |
1032 | reada_for_search(root, p, level, slot); | 1041 | reada_for_search(root, p, level, slot); |
1033 | b = read_tree_block(root, btrfs_node_blockptr(b, slot)); | 1042 | b = read_tree_block(root, bytenr, |
1043 | btrfs_level_size(root, level - 1)); | ||
1034 | } else { | 1044 | } else { |
1035 | p->slots[level] = slot; | 1045 | p->slots[level] = slot; |
1036 | if (ins_len > 0 && btrfs_leaf_free_space(root, b) < | 1046 | if (ins_len > 0 && btrfs_leaf_free_space(root, b) < |
@@ -1193,14 +1203,14 @@ static int insert_new_root(struct btrfs_trans_handle *trans, | |||
1193 | BUG_ON(path->nodes[level]); | 1203 | BUG_ON(path->nodes[level]); |
1194 | BUG_ON(path->nodes[level-1] != root->node); | 1204 | BUG_ON(path->nodes[level-1] != root->node); |
1195 | 1205 | ||
1196 | c = btrfs_alloc_free_block(trans, root, | 1206 | c = btrfs_alloc_free_block(trans, root, root->nodesize, |
1197 | extent_buffer_blocknr(root->node), 0); | 1207 | root->node->start, 0); |
1198 | if (IS_ERR(c)) | 1208 | if (IS_ERR(c)) |
1199 | return PTR_ERR(c); | 1209 | return PTR_ERR(c); |
1200 | memset_extent_buffer(c, 0, 0, root->nodesize); | 1210 | memset_extent_buffer(c, 0, 0, root->nodesize); |
1201 | btrfs_set_header_nritems(c, 1); | 1211 | btrfs_set_header_nritems(c, 1); |
1202 | btrfs_set_header_level(c, level); | 1212 | btrfs_set_header_level(c, level); |
1203 | btrfs_set_header_blocknr(c, extent_buffer_blocknr(c)); | 1213 | btrfs_set_header_bytenr(c, c->start); |
1204 | btrfs_set_header_generation(c, trans->transid); | 1214 | btrfs_set_header_generation(c, trans->transid); |
1205 | btrfs_set_header_owner(c, root->root_key.objectid); | 1215 | btrfs_set_header_owner(c, root->root_key.objectid); |
1206 | lower = path->nodes[level-1]; | 1216 | lower = path->nodes[level-1]; |
@@ -1213,7 +1223,7 @@ static int insert_new_root(struct btrfs_trans_handle *trans, | |||
1213 | else | 1223 | else |
1214 | btrfs_node_key(lower, &lower_key, 0); | 1224 | btrfs_node_key(lower, &lower_key, 0); |
1215 | btrfs_set_node_key(c, &lower_key, 0); | 1225 | btrfs_set_node_key(c, &lower_key, 0); |
1216 | btrfs_set_node_blockptr(c, 0, extent_buffer_blocknr(lower)); | 1226 | btrfs_set_node_blockptr(c, 0, lower->start); |
1217 | 1227 | ||
1218 | btrfs_mark_buffer_dirty(c); | 1228 | btrfs_mark_buffer_dirty(c); |
1219 | 1229 | ||
@@ -1237,7 +1247,7 @@ static int insert_new_root(struct btrfs_trans_handle *trans, | |||
1237 | */ | 1247 | */ |
1238 | static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | 1248 | static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root |
1239 | *root, struct btrfs_path *path, struct btrfs_disk_key | 1249 | *root, struct btrfs_path *path, struct btrfs_disk_key |
1240 | *key, u64 blocknr, int slot, int level) | 1250 | *key, u64 bytenr, int slot, int level) |
1241 | { | 1251 | { |
1242 | struct extent_buffer *lower; | 1252 | struct extent_buffer *lower; |
1243 | int nritems; | 1253 | int nritems; |
@@ -1256,10 +1266,9 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1256 | (nritems - slot) * sizeof(struct btrfs_key_ptr)); | 1266 | (nritems - slot) * sizeof(struct btrfs_key_ptr)); |
1257 | } | 1267 | } |
1258 | btrfs_set_node_key(lower, key, slot); | 1268 | btrfs_set_node_key(lower, key, slot); |
1259 | btrfs_set_node_blockptr(lower, slot, blocknr); | 1269 | btrfs_set_node_blockptr(lower, slot, bytenr); |
1260 | btrfs_set_header_nritems(lower, nritems + 1); | 1270 | btrfs_set_header_nritems(lower, nritems + 1); |
1261 | btrfs_mark_buffer_dirty(lower); | 1271 | btrfs_mark_buffer_dirty(lower); |
1262 | check_node(root, path, level); | ||
1263 | return 0; | 1272 | return 0; |
1264 | } | 1273 | } |
1265 | 1274 | ||
@@ -1300,14 +1309,14 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1300 | } | 1309 | } |
1301 | 1310 | ||
1302 | c_nritems = btrfs_header_nritems(c); | 1311 | c_nritems = btrfs_header_nritems(c); |
1303 | split = btrfs_alloc_free_block(trans, root, | 1312 | split = btrfs_alloc_free_block(trans, root, root->nodesize, |
1304 | extent_buffer_blocknr(c), 0); | 1313 | c->start, 0); |
1305 | if (IS_ERR(split)) | 1314 | if (IS_ERR(split)) |
1306 | return PTR_ERR(split); | 1315 | return PTR_ERR(split); |
1307 | 1316 | ||
1308 | btrfs_set_header_flags(split, btrfs_header_flags(c)); | 1317 | btrfs_set_header_flags(split, btrfs_header_flags(c)); |
1309 | btrfs_set_header_level(split, btrfs_header_level(c)); | 1318 | btrfs_set_header_level(split, btrfs_header_level(c)); |
1310 | btrfs_set_header_blocknr(split, extent_buffer_blocknr(split)); | 1319 | btrfs_set_header_bytenr(split, split->start); |
1311 | btrfs_set_header_generation(split, trans->transid); | 1320 | btrfs_set_header_generation(split, trans->transid); |
1312 | btrfs_set_header_owner(split, root->root_key.objectid); | 1321 | btrfs_set_header_owner(split, root->root_key.objectid); |
1313 | write_extent_buffer(split, root->fs_info->fsid, | 1322 | write_extent_buffer(split, root->fs_info->fsid, |
@@ -1328,8 +1337,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1328 | btrfs_mark_buffer_dirty(split); | 1337 | btrfs_mark_buffer_dirty(split); |
1329 | 1338 | ||
1330 | btrfs_node_key(split, &disk_key, 0); | 1339 | btrfs_node_key(split, &disk_key, 0); |
1331 | wret = insert_ptr(trans, root, path, &disk_key, | 1340 | wret = insert_ptr(trans, root, path, &disk_key, split->start, |
1332 | extent_buffer_blocknr(split), | ||
1333 | path->slots[level + 1] + 1, | 1341 | path->slots[level + 1] + 1, |
1334 | level + 1); | 1342 | level + 1); |
1335 | if (wret) | 1343 | if (wret) |
@@ -1407,6 +1415,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1407 | u32 left_nritems; | 1415 | u32 left_nritems; |
1408 | u32 right_nritems; | 1416 | u32 right_nritems; |
1409 | u32 data_end; | 1417 | u32 data_end; |
1418 | u32 this_item_size; | ||
1410 | int ret; | 1419 | int ret; |
1411 | 1420 | ||
1412 | slot = path->slots[1]; | 1421 | slot = path->slots[1]; |
@@ -1417,7 +1426,8 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1417 | if (slot >= btrfs_header_nritems(upper) - 1) | 1426 | if (slot >= btrfs_header_nritems(upper) - 1) |
1418 | return 1; | 1427 | return 1; |
1419 | 1428 | ||
1420 | right = read_tree_block(root, btrfs_node_blockptr(upper, slot + 1)); | 1429 | right = read_tree_block(root, btrfs_node_blockptr(upper, slot + 1), |
1430 | root->leafsize); | ||
1421 | free_space = btrfs_leaf_free_space(root, right); | 1431 | free_space = btrfs_leaf_free_space(root, right); |
1422 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 1432 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
1423 | free_extent_buffer(right); | 1433 | free_extent_buffer(right); |
@@ -1445,13 +1455,27 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1445 | 1455 | ||
1446 | for (i = left_nritems - 1; i >= 1; i--) { | 1456 | for (i = left_nritems - 1; i >= 1; i--) { |
1447 | item = btrfs_item_nr(left, i); | 1457 | item = btrfs_item_nr(left, i); |
1458 | |||
1448 | if (path->slots[0] == i) | 1459 | if (path->slots[0] == i) |
1449 | push_space += data_size + sizeof(*item); | 1460 | push_space += data_size + sizeof(*item); |
1450 | if (btrfs_item_size(left, item) + sizeof(*item) + push_space > | 1461 | |
1451 | free_space) | 1462 | if (!left->map_token) { |
1463 | map_extent_buffer(left, (unsigned long)item, | ||
1464 | sizeof(struct btrfs_item), | ||
1465 | &left->map_token, &left->kaddr, | ||
1466 | &left->map_start, &left->map_len, | ||
1467 | KM_USER1); | ||
1468 | } | ||
1469 | |||
1470 | this_item_size = btrfs_item_size(left, item); | ||
1471 | if (this_item_size + sizeof(*item) + push_space > free_space) | ||
1452 | break; | 1472 | break; |
1453 | push_items++; | 1473 | push_items++; |
1454 | push_space += btrfs_item_size(left, item) + sizeof(*item); | 1474 | push_space += this_item_size + sizeof(*item); |
1475 | } | ||
1476 | if (left->map_token) { | ||
1477 | unmap_extent_buffer(left, left->map_token, KM_USER1); | ||
1478 | left->map_token = NULL; | ||
1455 | } | 1479 | } |
1456 | 1480 | ||
1457 | if (push_items == 0) { | 1481 | if (push_items == 0) { |
@@ -1493,11 +1517,23 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1493 | right_nritems += push_items; | 1517 | right_nritems += push_items; |
1494 | btrfs_set_header_nritems(right, right_nritems); | 1518 | btrfs_set_header_nritems(right, right_nritems); |
1495 | push_space = BTRFS_LEAF_DATA_SIZE(root); | 1519 | push_space = BTRFS_LEAF_DATA_SIZE(root); |
1520 | |||
1496 | for (i = 0; i < right_nritems; i++) { | 1521 | for (i = 0; i < right_nritems; i++) { |
1497 | item = btrfs_item_nr(right, i); | 1522 | item = btrfs_item_nr(right, i); |
1498 | btrfs_set_item_offset(right, item, push_space - | 1523 | if (!right->map_token) { |
1499 | btrfs_item_size(right, item)); | 1524 | map_extent_buffer(right, (unsigned long)item, |
1500 | push_space = btrfs_item_offset(right, item); | 1525 | sizeof(struct btrfs_item), |
1526 | &right->map_token, &right->kaddr, | ||
1527 | &right->map_start, &right->map_len, | ||
1528 | KM_USER1); | ||
1529 | } | ||
1530 | push_space -= btrfs_item_size(right, item); | ||
1531 | btrfs_set_item_offset(right, item, push_space); | ||
1532 | } | ||
1533 | |||
1534 | if (right->map_token) { | ||
1535 | unmap_extent_buffer(right, right->map_token, KM_USER1); | ||
1536 | right->map_token = NULL; | ||
1501 | } | 1537 | } |
1502 | left_nritems -= push_items; | 1538 | left_nritems -= push_items; |
1503 | btrfs_set_header_nritems(left, left_nritems); | 1539 | btrfs_set_header_nritems(left, left_nritems); |
@@ -1518,8 +1554,6 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1518 | } else { | 1554 | } else { |
1519 | free_extent_buffer(right); | 1555 | free_extent_buffer(right); |
1520 | } | 1556 | } |
1521 | if (path->nodes[1]) | ||
1522 | check_node(root, path, 1); | ||
1523 | return 0; | 1557 | return 0; |
1524 | } | 1558 | } |
1525 | /* | 1559 | /* |
@@ -1542,6 +1576,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1542 | u32 right_nritems; | 1576 | u32 right_nritems; |
1543 | int ret = 0; | 1577 | int ret = 0; |
1544 | int wret; | 1578 | int wret; |
1579 | u32 this_item_size; | ||
1580 | u32 old_left_item_size; | ||
1545 | 1581 | ||
1546 | slot = path->slots[1]; | 1582 | slot = path->slots[1]; |
1547 | if (slot == 0) | 1583 | if (slot == 0) |
@@ -1550,7 +1586,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1550 | return 1; | 1586 | return 1; |
1551 | 1587 | ||
1552 | left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1], | 1588 | left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1], |
1553 | slot - 1)); | 1589 | slot - 1), root->leafsize); |
1554 | free_space = btrfs_leaf_free_space(root, left); | 1590 | free_space = btrfs_leaf_free_space(root, left); |
1555 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 1591 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
1556 | free_extent_buffer(left); | 1592 | free_extent_buffer(left); |
@@ -1579,14 +1615,30 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1579 | 1615 | ||
1580 | for (i = 0; i < right_nritems - 1; i++) { | 1616 | for (i = 0; i < right_nritems - 1; i++) { |
1581 | item = btrfs_item_nr(right, i); | 1617 | item = btrfs_item_nr(right, i); |
1618 | if (!right->map_token) { | ||
1619 | map_extent_buffer(right, (unsigned long)item, | ||
1620 | sizeof(struct btrfs_item), | ||
1621 | &right->map_token, &right->kaddr, | ||
1622 | &right->map_start, &right->map_len, | ||
1623 | KM_USER1); | ||
1624 | } | ||
1625 | |||
1582 | if (path->slots[0] == i) | 1626 | if (path->slots[0] == i) |
1583 | push_space += data_size + sizeof(*item); | 1627 | push_space += data_size + sizeof(*item); |
1584 | if (btrfs_item_size(right, item) + sizeof(*item) + push_space > | 1628 | |
1585 | free_space) | 1629 | this_item_size = btrfs_item_size(right, item); |
1630 | if (this_item_size + sizeof(*item) + push_space > free_space) | ||
1586 | break; | 1631 | break; |
1632 | |||
1587 | push_items++; | 1633 | push_items++; |
1588 | push_space += btrfs_item_size(right, item) + sizeof(*item); | 1634 | push_space += this_item_size + sizeof(*item); |
1635 | } | ||
1636 | |||
1637 | if (right->map_token) { | ||
1638 | unmap_extent_buffer(right, right->map_token, KM_USER1); | ||
1639 | right->map_token = NULL; | ||
1589 | } | 1640 | } |
1641 | |||
1590 | if (push_items == 0) { | 1642 | if (push_items == 0) { |
1591 | free_extent_buffer(left); | 1643 | free_extent_buffer(left); |
1592 | return 1; | 1644 | return 1; |
@@ -1611,15 +1663,28 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1611 | old_left_nritems = btrfs_header_nritems(left); | 1663 | old_left_nritems = btrfs_header_nritems(left); |
1612 | BUG_ON(old_left_nritems < 0); | 1664 | BUG_ON(old_left_nritems < 0); |
1613 | 1665 | ||
1666 | old_left_item_size = btrfs_item_offset_nr(left, old_left_nritems - 1); | ||
1614 | for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { | 1667 | for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { |
1615 | u32 ioff; | 1668 | u32 ioff; |
1669 | |||
1616 | item = btrfs_item_nr(left, i); | 1670 | item = btrfs_item_nr(left, i); |
1671 | if (!left->map_token) { | ||
1672 | map_extent_buffer(left, (unsigned long)item, | ||
1673 | sizeof(struct btrfs_item), | ||
1674 | &left->map_token, &left->kaddr, | ||
1675 | &left->map_start, &left->map_len, | ||
1676 | KM_USER1); | ||
1677 | } | ||
1678 | |||
1617 | ioff = btrfs_item_offset(left, item); | 1679 | ioff = btrfs_item_offset(left, item); |
1618 | btrfs_set_item_offset(left, item, | 1680 | btrfs_set_item_offset(left, item, |
1619 | ioff - (BTRFS_LEAF_DATA_SIZE(root) - | 1681 | ioff - (BTRFS_LEAF_DATA_SIZE(root) - old_left_item_size)); |
1620 | btrfs_item_offset_nr(left, old_left_nritems - 1))); | ||
1621 | } | 1682 | } |
1622 | btrfs_set_header_nritems(left, old_left_nritems + push_items); | 1683 | btrfs_set_header_nritems(left, old_left_nritems + push_items); |
1684 | if (left->map_token) { | ||
1685 | unmap_extent_buffer(left, left->map_token, KM_USER1); | ||
1686 | left->map_token = NULL; | ||
1687 | } | ||
1623 | 1688 | ||
1624 | /* fixup right node */ | 1689 | /* fixup right node */ |
1625 | push_space = btrfs_item_offset_nr(right, push_items - 1) - | 1690 | push_space = btrfs_item_offset_nr(right, push_items - 1) - |
@@ -1640,9 +1705,21 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1640 | 1705 | ||
1641 | for (i = 0; i < right_nritems; i++) { | 1706 | for (i = 0; i < right_nritems; i++) { |
1642 | item = btrfs_item_nr(right, i); | 1707 | item = btrfs_item_nr(right, i); |
1643 | btrfs_set_item_offset(right, item, push_space - | 1708 | |
1644 | btrfs_item_size(right, item)); | 1709 | if (!right->map_token) { |
1645 | push_space = btrfs_item_offset(right, item); | 1710 | map_extent_buffer(right, (unsigned long)item, |
1711 | sizeof(struct btrfs_item), | ||
1712 | &right->map_token, &right->kaddr, | ||
1713 | &right->map_start, &right->map_len, | ||
1714 | KM_USER1); | ||
1715 | } | ||
1716 | |||
1717 | push_space = push_space - btrfs_item_size(right, item); | ||
1718 | btrfs_set_item_offset(right, item, push_space); | ||
1719 | } | ||
1720 | if (right->map_token) { | ||
1721 | unmap_extent_buffer(right, right->map_token, KM_USER1); | ||
1722 | right->map_token = NULL; | ||
1646 | } | 1723 | } |
1647 | 1724 | ||
1648 | btrfs_mark_buffer_dirty(left); | 1725 | btrfs_mark_buffer_dirty(left); |
@@ -1664,8 +1741,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1664 | path->slots[0] -= push_items; | 1741 | path->slots[0] -= push_items; |
1665 | } | 1742 | } |
1666 | BUG_ON(path->slots[0] < 0); | 1743 | BUG_ON(path->slots[0] < 0); |
1667 | if (path->nodes[1]) | ||
1668 | check_node(root, path, 1); | ||
1669 | return ret; | 1744 | return ret; |
1670 | } | 1745 | } |
1671 | 1746 | ||
@@ -1718,13 +1793,13 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1718 | nritems = btrfs_header_nritems(l); | 1793 | nritems = btrfs_header_nritems(l); |
1719 | mid = (nritems + 1)/ 2; | 1794 | mid = (nritems + 1)/ 2; |
1720 | 1795 | ||
1721 | right = btrfs_alloc_free_block(trans, root, | 1796 | right = btrfs_alloc_free_block(trans, root, root->leafsize, |
1722 | extent_buffer_blocknr(l), 0); | 1797 | l->start, 0); |
1723 | if (IS_ERR(right)) | 1798 | if (IS_ERR(right)) |
1724 | return PTR_ERR(right); | 1799 | return PTR_ERR(right); |
1725 | 1800 | ||
1726 | memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); | 1801 | memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); |
1727 | btrfs_set_header_blocknr(right, extent_buffer_blocknr(right)); | 1802 | btrfs_set_header_bytenr(right, right->start); |
1728 | btrfs_set_header_generation(right, trans->transid); | 1803 | btrfs_set_header_generation(right, trans->transid); |
1729 | btrfs_set_header_owner(right, root->root_key.objectid); | 1804 | btrfs_set_header_owner(right, root->root_key.objectid); |
1730 | btrfs_set_header_level(right, 0); | 1805 | btrfs_set_header_level(right, 0); |
@@ -1740,8 +1815,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1740 | btrfs_cpu_key_to_disk(&disk_key, ins_key); | 1815 | btrfs_cpu_key_to_disk(&disk_key, ins_key); |
1741 | btrfs_set_header_nritems(right, 0); | 1816 | btrfs_set_header_nritems(right, 0); |
1742 | wret = insert_ptr(trans, root, path, | 1817 | wret = insert_ptr(trans, root, path, |
1743 | &disk_key, | 1818 | &disk_key, right->start, |
1744 | extent_buffer_blocknr(right), | ||
1745 | path->slots[1] + 1, 1); | 1819 | path->slots[1] + 1, 1); |
1746 | if (wret) | 1820 | if (wret) |
1747 | ret = wret; | 1821 | ret = wret; |
@@ -1762,7 +1836,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1762 | btrfs_set_header_nritems(right, 0); | 1836 | btrfs_set_header_nritems(right, 0); |
1763 | wret = insert_ptr(trans, root, path, | 1837 | wret = insert_ptr(trans, root, path, |
1764 | &disk_key, | 1838 | &disk_key, |
1765 | extent_buffer_blocknr(right), | 1839 | right->start, |
1766 | path->slots[1], 1); | 1840 | path->slots[1], 1); |
1767 | if (wret) | 1841 | if (wret) |
1768 | ret = wret; | 1842 | ret = wret; |
@@ -1799,15 +1873,30 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1799 | 1873 | ||
1800 | for (i = 0; i < nritems; i++) { | 1874 | for (i = 0; i < nritems; i++) { |
1801 | struct btrfs_item *item = btrfs_item_nr(right, i); | 1875 | struct btrfs_item *item = btrfs_item_nr(right, i); |
1802 | u32 ioff = btrfs_item_offset(right, item); | 1876 | u32 ioff; |
1877 | |||
1878 | if (!right->map_token) { | ||
1879 | map_extent_buffer(right, (unsigned long)item, | ||
1880 | sizeof(struct btrfs_item), | ||
1881 | &right->map_token, &right->kaddr, | ||
1882 | &right->map_start, &right->map_len, | ||
1883 | KM_USER1); | ||
1884 | } | ||
1885 | |||
1886 | ioff = btrfs_item_offset(right, item); | ||
1803 | btrfs_set_item_offset(right, item, ioff + rt_data_off); | 1887 | btrfs_set_item_offset(right, item, ioff + rt_data_off); |
1804 | } | 1888 | } |
1805 | 1889 | ||
1890 | if (right->map_token) { | ||
1891 | unmap_extent_buffer(right, right->map_token, KM_USER1); | ||
1892 | right->map_token = NULL; | ||
1893 | } | ||
1894 | |||
1806 | btrfs_set_header_nritems(l, mid); | 1895 | btrfs_set_header_nritems(l, mid); |
1807 | ret = 0; | 1896 | ret = 0; |
1808 | btrfs_item_key(right, &disk_key, 0); | 1897 | btrfs_item_key(right, &disk_key, 0); |
1809 | wret = insert_ptr(trans, root, path, &disk_key, | 1898 | wret = insert_ptr(trans, root, path, &disk_key, right->start, |
1810 | extent_buffer_blocknr(right), path->slots[1] + 1, 1); | 1899 | path->slots[1] + 1, 1); |
1811 | if (wret) | 1900 | if (wret) |
1812 | ret = wret; | 1901 | ret = wret; |
1813 | 1902 | ||
@@ -1824,19 +1913,17 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1824 | free_extent_buffer(right); | 1913 | free_extent_buffer(right); |
1825 | 1914 | ||
1826 | BUG_ON(path->slots[0] < 0); | 1915 | BUG_ON(path->slots[0] < 0); |
1827 | check_node(root, path, 1); | ||
1828 | check_leaf(root, path, 0); | ||
1829 | 1916 | ||
1830 | if (!double_split) | 1917 | if (!double_split) |
1831 | return ret; | 1918 | return ret; |
1832 | 1919 | ||
1833 | right = btrfs_alloc_free_block(trans, root, | 1920 | right = btrfs_alloc_free_block(trans, root, root->leafsize, |
1834 | extent_buffer_blocknr(l), 0); | 1921 | l->start, 0); |
1835 | if (IS_ERR(right)) | 1922 | if (IS_ERR(right)) |
1836 | return PTR_ERR(right); | 1923 | return PTR_ERR(right); |
1837 | 1924 | ||
1838 | memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); | 1925 | memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); |
1839 | btrfs_set_header_blocknr(right, extent_buffer_blocknr(right)); | 1926 | btrfs_set_header_bytenr(right, right->start); |
1840 | btrfs_set_header_generation(right, trans->transid); | 1927 | btrfs_set_header_generation(right, trans->transid); |
1841 | btrfs_set_header_owner(right, root->root_key.objectid); | 1928 | btrfs_set_header_owner(right, root->root_key.objectid); |
1842 | btrfs_set_header_level(right, 0); | 1929 | btrfs_set_header_level(right, 0); |
@@ -1847,8 +1934,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1847 | btrfs_cpu_key_to_disk(&disk_key, ins_key); | 1934 | btrfs_cpu_key_to_disk(&disk_key, ins_key); |
1848 | btrfs_set_header_nritems(right, 0); | 1935 | btrfs_set_header_nritems(right, 0); |
1849 | wret = insert_ptr(trans, root, path, | 1936 | wret = insert_ptr(trans, root, path, |
1850 | &disk_key, | 1937 | &disk_key, right->start, |
1851 | extent_buffer_blocknr(right), | ||
1852 | path->slots[1], 1); | 1938 | path->slots[1], 1); |
1853 | if (wret) | 1939 | if (wret) |
1854 | ret = wret; | 1940 | ret = wret; |
@@ -1860,8 +1946,6 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1860 | free_extent_buffer(path->nodes[0]); | 1946 | free_extent_buffer(path->nodes[0]); |
1861 | path->nodes[0] = right; | 1947 | path->nodes[0] = right; |
1862 | path->slots[0] = 0; | 1948 | path->slots[0] = 0; |
1863 | check_node(root, path, 1); | ||
1864 | check_leaf(root, path, 0); | ||
1865 | return ret; | 1949 | return ret; |
1866 | } | 1950 | } |
1867 | 1951 | ||
@@ -1904,9 +1988,24 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
1904 | for (i = slot; i < nritems; i++) { | 1988 | for (i = slot; i < nritems; i++) { |
1905 | u32 ioff; | 1989 | u32 ioff; |
1906 | item = btrfs_item_nr(leaf, i); | 1990 | item = btrfs_item_nr(leaf, i); |
1991 | |||
1992 | if (!leaf->map_token) { | ||
1993 | map_extent_buffer(leaf, (unsigned long)item, | ||
1994 | sizeof(struct btrfs_item), | ||
1995 | &leaf->map_token, &leaf->kaddr, | ||
1996 | &leaf->map_start, &leaf->map_len, | ||
1997 | KM_USER1); | ||
1998 | } | ||
1999 | |||
1907 | ioff = btrfs_item_offset(leaf, item); | 2000 | ioff = btrfs_item_offset(leaf, item); |
1908 | btrfs_set_item_offset(leaf, item, ioff + size_diff); | 2001 | btrfs_set_item_offset(leaf, item, ioff + size_diff); |
1909 | } | 2002 | } |
2003 | |||
2004 | if (leaf->map_token) { | ||
2005 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); | ||
2006 | leaf->map_token = NULL; | ||
2007 | } | ||
2008 | |||
1910 | /* shift the data */ | 2009 | /* shift the data */ |
1911 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + | 2010 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + |
1912 | data_end + size_diff, btrfs_leaf_data(leaf) + | 2011 | data_end + size_diff, btrfs_leaf_data(leaf) + |
@@ -1921,7 +2020,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans, | |||
1921 | btrfs_print_leaf(root, leaf); | 2020 | btrfs_print_leaf(root, leaf); |
1922 | BUG(); | 2021 | BUG(); |
1923 | } | 2022 | } |
1924 | check_leaf(root, path, 0); | ||
1925 | return ret; | 2023 | return ret; |
1926 | } | 2024 | } |
1927 | 2025 | ||
@@ -1963,10 +2061,23 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, | |||
1963 | for (i = slot; i < nritems; i++) { | 2061 | for (i = slot; i < nritems; i++) { |
1964 | u32 ioff; | 2062 | u32 ioff; |
1965 | item = btrfs_item_nr(leaf, i); | 2063 | item = btrfs_item_nr(leaf, i); |
2064 | |||
2065 | if (!leaf->map_token) { | ||
2066 | map_extent_buffer(leaf, (unsigned long)item, | ||
2067 | sizeof(struct btrfs_item), | ||
2068 | &leaf->map_token, &leaf->kaddr, | ||
2069 | &leaf->map_start, &leaf->map_len, | ||
2070 | KM_USER1); | ||
2071 | } | ||
1966 | ioff = btrfs_item_offset(leaf, item); | 2072 | ioff = btrfs_item_offset(leaf, item); |
1967 | btrfs_set_item_offset(leaf, item, ioff - data_size); | 2073 | btrfs_set_item_offset(leaf, item, ioff - data_size); |
1968 | } | 2074 | } |
1969 | 2075 | ||
2076 | if (leaf->map_token) { | ||
2077 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); | ||
2078 | leaf->map_token = NULL; | ||
2079 | } | ||
2080 | |||
1970 | /* shift the data */ | 2081 | /* shift the data */ |
1971 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + | 2082 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + |
1972 | data_end - data_size, btrfs_leaf_data(leaf) + | 2083 | data_end - data_size, btrfs_leaf_data(leaf) + |
@@ -1983,7 +2094,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, | |||
1983 | btrfs_print_leaf(root, leaf); | 2094 | btrfs_print_leaf(root, leaf); |
1984 | BUG(); | 2095 | BUG(); |
1985 | } | 2096 | } |
1986 | check_leaf(root, path, 0); | ||
1987 | return ret; | 2097 | return ret; |
1988 | } | 2098 | } |
1989 | 2099 | ||
@@ -2046,12 +2156,26 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, | |||
2046 | * item0..itemN ... dataN.offset..dataN.size .. data0.size | 2156 | * item0..itemN ... dataN.offset..dataN.size .. data0.size |
2047 | */ | 2157 | */ |
2048 | /* first correct the data pointers */ | 2158 | /* first correct the data pointers */ |
2159 | WARN_ON(leaf->map_token); | ||
2049 | for (i = slot; i < nritems; i++) { | 2160 | for (i = slot; i < nritems; i++) { |
2050 | u32 ioff; | 2161 | u32 ioff; |
2162 | |||
2051 | item = btrfs_item_nr(leaf, i); | 2163 | item = btrfs_item_nr(leaf, i); |
2164 | if (!leaf->map_token) { | ||
2165 | map_extent_buffer(leaf, (unsigned long)item, | ||
2166 | sizeof(struct btrfs_item), | ||
2167 | &leaf->map_token, &leaf->kaddr, | ||
2168 | &leaf->map_start, &leaf->map_len, | ||
2169 | KM_USER1); | ||
2170 | } | ||
2171 | |||
2052 | ioff = btrfs_item_offset(leaf, item); | 2172 | ioff = btrfs_item_offset(leaf, item); |
2053 | btrfs_set_item_offset(leaf, item, ioff - data_size); | 2173 | btrfs_set_item_offset(leaf, item, ioff - data_size); |
2054 | } | 2174 | } |
2175 | if (leaf->map_token) { | ||
2176 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); | ||
2177 | leaf->map_token = NULL; | ||
2178 | } | ||
2055 | 2179 | ||
2056 | /* shift the items */ | 2180 | /* shift the items */ |
2057 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), | 2181 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), |
@@ -2081,7 +2205,6 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, | |||
2081 | btrfs_print_leaf(root, leaf); | 2205 | btrfs_print_leaf(root, leaf); |
2082 | BUG(); | 2206 | BUG(); |
2083 | } | 2207 | } |
2084 | check_leaf(root, path, 0); | ||
2085 | out: | 2208 | out: |
2086 | return ret; | 2209 | return ret; |
2087 | } | 2210 | } |
@@ -2186,10 +2309,24 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2186 | 2309 | ||
2187 | for (i = slot + 1; i < nritems; i++) { | 2310 | for (i = slot + 1; i < nritems; i++) { |
2188 | u32 ioff; | 2311 | u32 ioff; |
2312 | |||
2189 | item = btrfs_item_nr(leaf, i); | 2313 | item = btrfs_item_nr(leaf, i); |
2314 | if (!leaf->map_token) { | ||
2315 | map_extent_buffer(leaf, (unsigned long)item, | ||
2316 | sizeof(struct btrfs_item), | ||
2317 | &leaf->map_token, &leaf->kaddr, | ||
2318 | &leaf->map_start, &leaf->map_len, | ||
2319 | KM_USER1); | ||
2320 | } | ||
2190 | ioff = btrfs_item_offset(leaf, item); | 2321 | ioff = btrfs_item_offset(leaf, item); |
2191 | btrfs_set_item_offset(leaf, item, ioff + dsize); | 2322 | btrfs_set_item_offset(leaf, item, ioff + dsize); |
2192 | } | 2323 | } |
2324 | |||
2325 | if (leaf->map_token) { | ||
2326 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); | ||
2327 | leaf->map_token = NULL; | ||
2328 | } | ||
2329 | |||
2193 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot), | 2330 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot), |
2194 | btrfs_item_nr_offset(slot + 1), | 2331 | btrfs_item_nr_offset(slot + 1), |
2195 | sizeof(struct btrfs_item) * | 2332 | sizeof(struct btrfs_item) * |
@@ -2209,8 +2346,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2209 | if (wret) | 2346 | if (wret) |
2210 | ret = wret; | 2347 | ret = wret; |
2211 | wret = btrfs_free_extent(trans, root, | 2348 | wret = btrfs_free_extent(trans, root, |
2212 | extent_buffer_blocknr(leaf), | 2349 | leaf->start, leaf->len, 1); |
2213 | 1, 1); | ||
2214 | if (wret) | 2350 | if (wret) |
2215 | ret = wret; | 2351 | ret = wret; |
2216 | } | 2352 | } |
@@ -2247,7 +2383,8 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2247 | } | 2383 | } |
2248 | 2384 | ||
2249 | if (btrfs_header_nritems(leaf) == 0) { | 2385 | if (btrfs_header_nritems(leaf) == 0) { |
2250 | u64 blocknr = extent_buffer_blocknr(leaf); | 2386 | u64 bytenr = leaf->start; |
2387 | u32 blocksize = leaf->len; | ||
2251 | 2388 | ||
2252 | clean_tree_block(trans, root, leaf); | 2389 | clean_tree_block(trans, root, leaf); |
2253 | wait_on_tree_block_writeback(root, leaf); | 2390 | wait_on_tree_block_writeback(root, leaf); |
@@ -2257,8 +2394,8 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2257 | ret = wret; | 2394 | ret = wret; |
2258 | 2395 | ||
2259 | free_extent_buffer(leaf); | 2396 | free_extent_buffer(leaf); |
2260 | wret = btrfs_free_extent(trans, root, blocknr, | 2397 | wret = btrfs_free_extent(trans, root, bytenr, |
2261 | 1, 1); | 2398 | blocksize, 1); |
2262 | if (wret) | 2399 | if (wret) |
2263 | ret = wret; | 2400 | ret = wret; |
2264 | } else { | 2401 | } else { |
@@ -2281,7 +2418,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
2281 | { | 2418 | { |
2282 | int slot; | 2419 | int slot; |
2283 | int level = 1; | 2420 | int level = 1; |
2284 | u64 blocknr; | 2421 | u64 bytenr; |
2285 | struct extent_buffer *c; | 2422 | struct extent_buffer *c; |
2286 | struct extent_buffer *next = NULL; | 2423 | struct extent_buffer *next = NULL; |
2287 | 2424 | ||
@@ -2296,14 +2433,15 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
2296 | continue; | 2433 | continue; |
2297 | } | 2434 | } |
2298 | 2435 | ||
2299 | blocknr = btrfs_node_blockptr(c, slot); | 2436 | bytenr = btrfs_node_blockptr(c, slot); |
2300 | if (next) | 2437 | if (next) |
2301 | free_extent_buffer(next); | 2438 | free_extent_buffer(next); |
2302 | 2439 | ||
2303 | if (path->reada) | 2440 | if (path->reada) |
2304 | reada_for_search(root, path, level, slot); | 2441 | reada_for_search(root, path, level, slot); |
2305 | 2442 | ||
2306 | next = read_tree_block(root, blocknr); | 2443 | next = read_tree_block(root, bytenr, |
2444 | btrfs_level_size(root, level -1)); | ||
2307 | break; | 2445 | break; |
2308 | } | 2446 | } |
2309 | path->slots[level] = slot; | 2447 | path->slots[level] = slot; |
@@ -2317,7 +2455,8 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
2317 | break; | 2455 | break; |
2318 | if (path->reada) | 2456 | if (path->reada) |
2319 | reada_for_search(root, path, level, 0); | 2457 | reada_for_search(root, path, level, 0); |
2320 | next = read_tree_block(root, btrfs_node_blockptr(next, 0)); | 2458 | next = read_tree_block(root, btrfs_node_blockptr(next, 0), |
2459 | btrfs_level_size(root, level - 1)); | ||
2321 | } | 2460 | } |
2322 | return 0; | 2461 | return 0; |
2323 | } | 2462 | } |