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 | |
parent | 1a5bc167f6707542b79a55452075525620ed43f5 (diff) |
Btrfs: Allow tree blocks larger than the page size
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r-- | fs/btrfs/ctree.c | 319 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 112 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 92 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 9 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 285 | ||||
-rw-r--r-- | fs/btrfs/extent_map.c | 91 | ||||
-rw-r--r-- | fs/btrfs/extent_map.h | 10 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 10 | ||||
-rw-r--r-- | fs/btrfs/file.c | 126 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 90 | ||||
-rw-r--r-- | fs/btrfs/print-tree.c | 23 | ||||
-rw-r--r-- | fs/btrfs/super.c | 6 | ||||
-rw-r--r-- | fs/btrfs/sysfs.c | 5 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 39 | ||||
-rw-r--r-- | fs/btrfs/tree-defrag.c | 18 |
15 files changed, 738 insertions, 497 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 | } |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 256689551eb0..4d05456ec32f 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -96,7 +96,7 @@ struct btrfs_key { | |||
96 | struct btrfs_header { | 96 | struct btrfs_header { |
97 | u8 csum[BTRFS_CSUM_SIZE]; | 97 | u8 csum[BTRFS_CSUM_SIZE]; |
98 | u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ | 98 | u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ |
99 | __le64 blocknr; /* which block this node is supposed to live in */ | 99 | __le64 bytenr; /* which block this node is supposed to live in */ |
100 | __le64 generation; | 100 | __le64 generation; |
101 | __le64 owner; | 101 | __le64 owner; |
102 | __le32 nritems; | 102 | __le32 nritems; |
@@ -122,16 +122,17 @@ struct btrfs_super_block { | |||
122 | u8 csum[BTRFS_CSUM_SIZE]; | 122 | u8 csum[BTRFS_CSUM_SIZE]; |
123 | /* the first 3 fields must match struct btrfs_header */ | 123 | /* the first 3 fields must match struct btrfs_header */ |
124 | u8 fsid[16]; /* FS specific uuid */ | 124 | u8 fsid[16]; /* FS specific uuid */ |
125 | __le64 blocknr; /* this block number */ | 125 | __le64 bytenr; /* this block number */ |
126 | __le64 magic; | 126 | __le64 magic; |
127 | __le64 generation; | 127 | __le64 generation; |
128 | __le64 root; | 128 | __le64 root; |
129 | __le64 total_blocks; | 129 | __le64 total_bytes; |
130 | __le64 blocks_used; | 130 | __le64 bytes_used; |
131 | __le64 root_dir_objectid; | 131 | __le64 root_dir_objectid; |
132 | __le32 sectorsize; | 132 | __le32 sectorsize; |
133 | __le32 nodesize; | 133 | __le32 nodesize; |
134 | __le32 leafsize; | 134 | __le32 leafsize; |
135 | u8 root_level; | ||
135 | } __attribute__ ((__packed__)); | 136 | } __attribute__ ((__packed__)); |
136 | 137 | ||
137 | /* | 138 | /* |
@@ -231,13 +232,14 @@ struct btrfs_dir_item { | |||
231 | struct btrfs_root_item { | 232 | struct btrfs_root_item { |
232 | struct btrfs_inode_item inode; | 233 | struct btrfs_inode_item inode; |
233 | __le64 root_dirid; | 234 | __le64 root_dirid; |
234 | __le64 blocknr; | 235 | __le64 bytenr; |
235 | __le64 block_limit; | 236 | __le64 byte_limit; |
236 | __le64 blocks_used; | 237 | __le64 bytes_used; |
237 | __le32 flags; | 238 | __le32 flags; |
238 | __le32 refs; | 239 | __le32 refs; |
239 | struct btrfs_disk_key drop_progress; | 240 | struct btrfs_disk_key drop_progress; |
240 | u8 drop_level; | 241 | u8 drop_level; |
242 | u8 level; | ||
241 | } __attribute__ ((__packed__)); | 243 | } __attribute__ ((__packed__)); |
242 | 244 | ||
243 | #define BTRFS_FILE_EXTENT_REG 0 | 245 | #define BTRFS_FILE_EXTENT_REG 0 |
@@ -250,8 +252,8 @@ struct btrfs_file_extent_item { | |||
250 | * disk space consumed by the extent, checksum blocks are included | 252 | * disk space consumed by the extent, checksum blocks are included |
251 | * in these numbers | 253 | * in these numbers |
252 | */ | 254 | */ |
253 | __le64 disk_blocknr; | 255 | __le64 disk_bytenr; |
254 | __le64 disk_num_blocks; | 256 | __le64 disk_num_bytes; |
255 | /* | 257 | /* |
256 | * the logical offset in file blocks (no csums) | 258 | * the logical offset in file blocks (no csums) |
257 | * this extent record is for. This allows a file extent to point | 259 | * this extent record is for. This allows a file extent to point |
@@ -263,7 +265,7 @@ struct btrfs_file_extent_item { | |||
263 | /* | 265 | /* |
264 | * the logical number of file blocks (no csums included) | 266 | * the logical number of file blocks (no csums included) |
265 | */ | 267 | */ |
266 | __le64 num_blocks; | 268 | __le64 num_bytes; |
267 | } __attribute__ ((__packed__)); | 269 | } __attribute__ ((__packed__)); |
268 | 270 | ||
269 | struct btrfs_csum_item { | 271 | struct btrfs_csum_item { |
@@ -429,6 +431,7 @@ static inline u##bits btrfs_##name(struct extent_buffer *eb, \ | |||
429 | int err; \ | 431 | int err; \ |
430 | char *map_token; \ | 432 | char *map_token; \ |
431 | char *kaddr; \ | 433 | char *kaddr; \ |
434 | int unmap_on_exit = (eb->map_token == NULL); \ | ||
432 | unsigned long map_start; \ | 435 | unsigned long map_start; \ |
433 | unsigned long map_len; \ | 436 | unsigned long map_len; \ |
434 | unsigned long offset = (unsigned long)s + \ | 437 | unsigned long offset = (unsigned long)s + \ |
@@ -436,12 +439,13 @@ static inline u##bits btrfs_##name(struct extent_buffer *eb, \ | |||
436 | err = map_extent_buffer(eb, offset, \ | 439 | err = map_extent_buffer(eb, offset, \ |
437 | sizeof(((type *)0)->member), \ | 440 | sizeof(((type *)0)->member), \ |
438 | &map_token, &kaddr, \ | 441 | &map_token, &kaddr, \ |
439 | &map_start, &map_len, KM_USER0); \ | 442 | &map_start, &map_len, KM_USER1); \ |
440 | if (!err) { \ | 443 | if (!err) { \ |
441 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ | 444 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ |
442 | map_start); \ | 445 | map_start); \ |
443 | u##bits res = le##bits##_to_cpu(*tmp); \ | 446 | u##bits res = le##bits##_to_cpu(*tmp); \ |
444 | unmap_extent_buffer(eb, map_token, KM_USER0); \ | 447 | if (unmap_on_exit) \ |
448 | unmap_extent_buffer(eb, map_token, KM_USER1); \ | ||
445 | return res; \ | 449 | return res; \ |
446 | } else { \ | 450 | } else { \ |
447 | __le##bits res; \ | 451 | __le##bits res; \ |
@@ -457,17 +461,19 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, \ | |||
457 | char *kaddr; \ | 461 | char *kaddr; \ |
458 | unsigned long map_start; \ | 462 | unsigned long map_start; \ |
459 | unsigned long map_len; \ | 463 | unsigned long map_len; \ |
464 | int unmap_on_exit = (eb->map_token == NULL); \ | ||
460 | unsigned long offset = (unsigned long)s + \ | 465 | unsigned long offset = (unsigned long)s + \ |
461 | offsetof(type, member); \ | 466 | offsetof(type, member); \ |
462 | err = map_extent_buffer(eb, offset, \ | 467 | err = map_extent_buffer(eb, offset, \ |
463 | sizeof(((type *)0)->member), \ | 468 | sizeof(((type *)0)->member), \ |
464 | &map_token, &kaddr, \ | 469 | &map_token, &kaddr, \ |
465 | &map_start, &map_len, KM_USER0); \ | 470 | &map_start, &map_len, KM_USER1); \ |
466 | if (!err) { \ | 471 | if (!err) { \ |
467 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ | 472 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ |
468 | map_start); \ | 473 | map_start); \ |
469 | *tmp = cpu_to_le##bits(val); \ | 474 | *tmp = cpu_to_le##bits(val); \ |
470 | unmap_extent_buffer(eb, map_token, KM_USER0); \ | 475 | if (unmap_on_exit) \ |
476 | unmap_extent_buffer(eb, map_token, KM_USER1); \ | ||
471 | } else { \ | 477 | } else { \ |
472 | val = cpu_to_le##bits(val); \ | 478 | val = cpu_to_le##bits(val); \ |
473 | write_eb_member(eb, s, type, member, &val); \ | 479 | write_eb_member(eb, s, type, member, &val); \ |
@@ -483,15 +489,17 @@ static inline u##bits btrfs_##name(struct extent_buffer *eb) \ | |||
483 | unsigned long map_start; \ | 489 | unsigned long map_start; \ |
484 | unsigned long map_len; \ | 490 | unsigned long map_len; \ |
485 | unsigned long offset = offsetof(type, member); \ | 491 | unsigned long offset = offsetof(type, member); \ |
492 | int unmap_on_exit = (eb->map_token == NULL); \ | ||
486 | err = map_extent_buffer(eb, offset, \ | 493 | err = map_extent_buffer(eb, offset, \ |
487 | sizeof(((type *)0)->member), \ | 494 | sizeof(((type *)0)->member), \ |
488 | &map_token, &kaddr, \ | 495 | &map_token, &kaddr, \ |
489 | &map_start, &map_len, KM_USER0); \ | 496 | &map_start, &map_len, KM_USER1); \ |
490 | if (!err) { \ | 497 | if (!err) { \ |
491 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ | 498 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ |
492 | map_start); \ | 499 | map_start); \ |
493 | u##bits res = le##bits##_to_cpu(*tmp); \ | 500 | u##bits res = le##bits##_to_cpu(*tmp); \ |
494 | unmap_extent_buffer(eb, map_token, KM_USER0); \ | 501 | if (unmap_on_exit) \ |
502 | unmap_extent_buffer(eb, map_token, KM_USER1); \ | ||
495 | return res; \ | 503 | return res; \ |
496 | } else { \ | 504 | } else { \ |
497 | __le##bits res; \ | 505 | __le##bits res; \ |
@@ -508,15 +516,17 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, \ | |||
508 | unsigned long map_start; \ | 516 | unsigned long map_start; \ |
509 | unsigned long map_len; \ | 517 | unsigned long map_len; \ |
510 | unsigned long offset = offsetof(type, member); \ | 518 | unsigned long offset = offsetof(type, member); \ |
519 | int unmap_on_exit = (eb->map_token == NULL); \ | ||
511 | err = map_extent_buffer(eb, offset, \ | 520 | err = map_extent_buffer(eb, offset, \ |
512 | sizeof(((type *)0)->member), \ | 521 | sizeof(((type *)0)->member), \ |
513 | &map_token, &kaddr, \ | 522 | &map_token, &kaddr, \ |
514 | &map_start, &map_len, KM_USER0); \ | 523 | &map_start, &map_len, KM_USER1); \ |
515 | if (!err) { \ | 524 | if (!err) { \ |
516 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ | 525 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ |
517 | map_start); \ | 526 | map_start); \ |
518 | *tmp = cpu_to_le##bits(val); \ | 527 | *tmp = cpu_to_le##bits(val); \ |
519 | unmap_extent_buffer(eb, map_token, KM_USER0); \ | 528 | if (unmap_on_exit) \ |
529 | unmap_extent_buffer(eb, map_token, KM_USER1); \ | ||
520 | } else { \ | 530 | } else { \ |
521 | val = cpu_to_le##bits(val); \ | 531 | val = cpu_to_le##bits(val); \ |
522 | write_eb_member(eb, NULL, type, member, &val); \ | 532 | write_eb_member(eb, NULL, type, member, &val); \ |
@@ -769,7 +779,7 @@ static inline void btrfs_set_key_type(struct btrfs_key *key, u8 val) | |||
769 | } | 779 | } |
770 | 780 | ||
771 | /* struct btrfs_header */ | 781 | /* struct btrfs_header */ |
772 | BTRFS_SETGET_HEADER_FUNCS(header_blocknr, struct btrfs_header, blocknr, 64); | 782 | BTRFS_SETGET_HEADER_FUNCS(header_bytenr, struct btrfs_header, bytenr, 64); |
773 | BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header, | 783 | BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header, |
774 | generation, 64); | 784 | generation, 64); |
775 | BTRFS_SETGET_HEADER_FUNCS(header_owner, struct btrfs_header, owner, 64); | 785 | BTRFS_SETGET_HEADER_FUNCS(header_owner, struct btrfs_header, owner, 64); |
@@ -817,24 +827,28 @@ static inline int btrfs_is_leaf(struct extent_buffer *eb) | |||
817 | 827 | ||
818 | /* struct btrfs_root_item */ | 828 | /* struct btrfs_root_item */ |
819 | BTRFS_SETGET_FUNCS(disk_root_refs, struct btrfs_root_item, refs, 32); | 829 | BTRFS_SETGET_FUNCS(disk_root_refs, struct btrfs_root_item, refs, 32); |
820 | BTRFS_SETGET_FUNCS(disk_root_blocknr, struct btrfs_root_item, blocknr, 64); | 830 | BTRFS_SETGET_FUNCS(disk_root_bytenr, struct btrfs_root_item, bytenr, 64); |
831 | BTRFS_SETGET_FUNCS(disk_root_level, struct btrfs_root_item, level, 8); | ||
821 | 832 | ||
822 | BTRFS_SETGET_STACK_FUNCS(root_blocknr, struct btrfs_root_item, blocknr, 64); | 833 | BTRFS_SETGET_STACK_FUNCS(root_bytenr, struct btrfs_root_item, bytenr, 64); |
834 | BTRFS_SETGET_STACK_FUNCS(root_level, struct btrfs_root_item, level, 8); | ||
823 | BTRFS_SETGET_STACK_FUNCS(root_dirid, struct btrfs_root_item, root_dirid, 64); | 835 | BTRFS_SETGET_STACK_FUNCS(root_dirid, struct btrfs_root_item, root_dirid, 64); |
824 | BTRFS_SETGET_STACK_FUNCS(root_refs, struct btrfs_root_item, refs, 32); | 836 | BTRFS_SETGET_STACK_FUNCS(root_refs, struct btrfs_root_item, refs, 32); |
825 | BTRFS_SETGET_STACK_FUNCS(root_flags, struct btrfs_root_item, flags, 32); | 837 | BTRFS_SETGET_STACK_FUNCS(root_flags, struct btrfs_root_item, flags, 32); |
826 | BTRFS_SETGET_STACK_FUNCS(root_used, struct btrfs_root_item, blocks_used, 64); | 838 | BTRFS_SETGET_STACK_FUNCS(root_used, struct btrfs_root_item, bytes_used, 64); |
827 | BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, block_limit, 64); | 839 | BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, byte_limit, 64); |
828 | 840 | ||
829 | /* struct btrfs_super_block */ | 841 | /* struct btrfs_super_block */ |
830 | BTRFS_SETGET_STACK_FUNCS(super_blocknr, struct btrfs_super_block, blocknr, 64); | 842 | BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64); |
831 | BTRFS_SETGET_STACK_FUNCS(super_generation, struct btrfs_super_block, | 843 | BTRFS_SETGET_STACK_FUNCS(super_generation, struct btrfs_super_block, |
832 | generation, 64); | 844 | generation, 64); |
833 | BTRFS_SETGET_STACK_FUNCS(super_root, struct btrfs_super_block, root, 64); | 845 | BTRFS_SETGET_STACK_FUNCS(super_root, struct btrfs_super_block, root, 64); |
834 | BTRFS_SETGET_STACK_FUNCS(super_total_blocks, struct btrfs_super_block, | 846 | BTRFS_SETGET_STACK_FUNCS(super_root_level, struct btrfs_super_block, |
835 | total_blocks, 64); | 847 | root_level, 8); |
836 | BTRFS_SETGET_STACK_FUNCS(super_blocks_used, struct btrfs_super_block, | 848 | BTRFS_SETGET_STACK_FUNCS(super_total_bytes, struct btrfs_super_block, |
837 | blocks_used, 64); | 849 | total_bytes, 64); |
850 | BTRFS_SETGET_STACK_FUNCS(super_bytes_used, struct btrfs_super_block, | ||
851 | bytes_used, 64); | ||
838 | BTRFS_SETGET_STACK_FUNCS(super_sectorsize, struct btrfs_super_block, | 852 | BTRFS_SETGET_STACK_FUNCS(super_sectorsize, struct btrfs_super_block, |
839 | sectorsize, 32); | 853 | sectorsize, 32); |
840 | BTRFS_SETGET_STACK_FUNCS(super_nodesize, struct btrfs_super_block, | 854 | BTRFS_SETGET_STACK_FUNCS(super_nodesize, struct btrfs_super_block, |
@@ -856,33 +870,33 @@ static inline unsigned long btrfs_file_extent_inline_start(struct | |||
856 | btrfs_file_extent_item *e) | 870 | btrfs_file_extent_item *e) |
857 | { | 871 | { |
858 | unsigned long offset = (unsigned long)e; | 872 | unsigned long offset = (unsigned long)e; |
859 | offset += offsetof(struct btrfs_file_extent_item, disk_blocknr); | 873 | offset += offsetof(struct btrfs_file_extent_item, disk_bytenr); |
860 | return offset; | 874 | return offset; |
861 | } | 875 | } |
862 | 876 | ||
863 | static inline u32 btrfs_file_extent_calc_inline_size(u32 datasize) | 877 | static inline u32 btrfs_file_extent_calc_inline_size(u32 datasize) |
864 | { | 878 | { |
865 | return offsetof(struct btrfs_file_extent_item, disk_blocknr) + datasize; | 879 | return offsetof(struct btrfs_file_extent_item, disk_bytenr) + datasize; |
866 | } | 880 | } |
867 | 881 | ||
868 | static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, | 882 | static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, |
869 | struct btrfs_item *e) | 883 | struct btrfs_item *e) |
870 | { | 884 | { |
871 | unsigned long offset; | 885 | unsigned long offset; |
872 | offset = offsetof(struct btrfs_file_extent_item, disk_blocknr); | 886 | offset = offsetof(struct btrfs_file_extent_item, disk_bytenr); |
873 | return btrfs_item_size(eb, e) - offset; | 887 | return btrfs_item_size(eb, e) - offset; |
874 | } | 888 | } |
875 | 889 | ||
876 | BTRFS_SETGET_FUNCS(file_extent_disk_blocknr, struct btrfs_file_extent_item, | 890 | BTRFS_SETGET_FUNCS(file_extent_disk_bytenr, struct btrfs_file_extent_item, |
877 | disk_blocknr, 64); | 891 | disk_bytenr, 64); |
878 | BTRFS_SETGET_FUNCS(file_extent_generation, struct btrfs_file_extent_item, | 892 | BTRFS_SETGET_FUNCS(file_extent_generation, struct btrfs_file_extent_item, |
879 | generation, 64); | 893 | generation, 64); |
880 | BTRFS_SETGET_FUNCS(file_extent_disk_num_blocks, struct btrfs_file_extent_item, | 894 | BTRFS_SETGET_FUNCS(file_extent_disk_num_bytes, struct btrfs_file_extent_item, |
881 | disk_num_blocks, 64); | 895 | disk_num_bytes, 64); |
882 | BTRFS_SETGET_FUNCS(file_extent_offset, struct btrfs_file_extent_item, | 896 | BTRFS_SETGET_FUNCS(file_extent_offset, struct btrfs_file_extent_item, |
883 | offset, 64); | 897 | offset, 64); |
884 | BTRFS_SETGET_FUNCS(file_extent_num_blocks, struct btrfs_file_extent_item, | 898 | BTRFS_SETGET_FUNCS(file_extent_num_bytes, struct btrfs_file_extent_item, |
885 | num_blocks, 64); | 899 | num_bytes, 64); |
886 | 900 | ||
887 | static inline struct btrfs_root *btrfs_sb(struct super_block *sb) | 901 | static inline struct btrfs_root *btrfs_sb(struct super_block *sb) |
888 | { | 902 | { |
@@ -906,6 +920,12 @@ static inline int btrfs_set_root_name(struct btrfs_root *root, | |||
906 | return 0; | 920 | return 0; |
907 | } | 921 | } |
908 | 922 | ||
923 | static inline u32 btrfs_level_size(struct btrfs_root *root, int level) { | ||
924 | if (level == 0) | ||
925 | return root->leafsize; | ||
926 | return root->nodesize; | ||
927 | } | ||
928 | |||
909 | /* helper function to cast into the data area of the leaf. */ | 929 | /* helper function to cast into the data area of the leaf. */ |
910 | #define btrfs_item_ptr(leaf, slot, type) \ | 930 | #define btrfs_item_ptr(leaf, slot, type) \ |
911 | ((type *)(btrfs_leaf_data(leaf) + \ | 931 | ((type *)(btrfs_leaf_data(leaf) + \ |
@@ -927,7 +947,7 @@ int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | |||
927 | int btrfs_copy_pinned(struct btrfs_root *root, struct extent_map_tree *copy); | 947 | int btrfs_copy_pinned(struct btrfs_root *root, struct extent_map_tree *copy); |
928 | struct btrfs_block_group_cache *btrfs_lookup_block_group(struct | 948 | struct btrfs_block_group_cache *btrfs_lookup_block_group(struct |
929 | btrfs_fs_info *info, | 949 | btrfs_fs_info *info, |
930 | u64 blocknr); | 950 | u64 bytenr); |
931 | struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | 951 | struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, |
932 | struct btrfs_block_group_cache | 952 | struct btrfs_block_group_cache |
933 | *hint, u64 search_start, | 953 | *hint, u64 search_start, |
@@ -935,22 +955,22 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | |||
935 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | 955 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, |
936 | struct btrfs_root *root); | 956 | struct btrfs_root *root); |
937 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 957 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
938 | struct btrfs_root *root, u64 hint, | 958 | struct btrfs_root *root, u32 size, |
939 | u64 empty_size); | 959 | u64 hint, u64 empty_size); |
940 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | 960 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
941 | struct btrfs_root *root, u64 owner, | 961 | struct btrfs_root *root, u64 owner, |
942 | u64 num_blocks, u64 empty_size, u64 search_start, | 962 | u64 num_bytes, u64 empty_size, u64 search_start, |
943 | u64 search_end, struct btrfs_key *ins, int data); | 963 | u64 search_end, struct btrfs_key *ins, int data); |
944 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 964 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
945 | struct extent_buffer *buf); | 965 | struct extent_buffer *buf); |
946 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 966 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
947 | *root, u64 blocknr, u64 num_blocks, int pin); | 967 | *root, u64 bytenr, u64 num_bytes, int pin); |
948 | int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | 968 | int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, |
949 | struct btrfs_root *root, | 969 | struct btrfs_root *root, |
950 | struct extent_map_tree *unpin); | 970 | struct extent_map_tree *unpin); |
951 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 971 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
952 | struct btrfs_root *root, | 972 | struct btrfs_root *root, |
953 | u64 blocknr, u64 num_blocks); | 973 | u64 bytenr, u64 num_bytes); |
954 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | 974 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, |
955 | struct btrfs_root *root); | 975 | struct btrfs_root *root); |
956 | int btrfs_free_block_groups(struct btrfs_fs_info *info); | 976 | int btrfs_free_block_groups(struct btrfs_fs_info *info); |
@@ -1040,12 +1060,12 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1040 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | 1060 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, |
1041 | struct btrfs_root *root, | 1061 | struct btrfs_root *root, |
1042 | u64 objectid, u64 pos, u64 offset, | 1062 | u64 objectid, u64 pos, u64 offset, |
1043 | u64 disk_num_blocks, | 1063 | u64 disk_num_bytes, |
1044 | u64 num_blocks); | 1064 | u64 num_bytes); |
1045 | int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, | 1065 | int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, |
1046 | struct btrfs_root *root, | 1066 | struct btrfs_root *root, |
1047 | struct btrfs_path *path, u64 objectid, | 1067 | struct btrfs_path *path, u64 objectid, |
1048 | u64 blocknr, int mod); | 1068 | u64 bytenr, int mod); |
1049 | int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | 1069 | int btrfs_csum_file_block(struct btrfs_trans_handle *trans, |
1050 | struct btrfs_root *root, | 1070 | struct btrfs_root *root, |
1051 | u64 objectid, u64 offset, | 1071 | u64 objectid, u64 offset, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 2b86a1d779b7..fad9298c6962 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "disk-io.h" | 28 | #include "disk-io.h" |
29 | #include "transaction.h" | 29 | #include "transaction.h" |
30 | #include "btrfs_inode.h" | 30 | #include "btrfs_inode.h" |
31 | #include "print-tree.h" | ||
31 | 32 | ||
32 | #if 0 | 33 | #if 0 |
33 | static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf) | 34 | static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf) |
@@ -43,26 +44,25 @@ static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf) | |||
43 | #endif | 44 | #endif |
44 | 45 | ||
45 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, | 46 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, |
46 | u64 blocknr) | 47 | u64 bytenr, u32 blocksize) |
47 | { | 48 | { |
48 | struct inode *btree_inode = root->fs_info->btree_inode; | 49 | struct inode *btree_inode = root->fs_info->btree_inode; |
49 | struct extent_buffer *eb; | 50 | struct extent_buffer *eb; |
50 | eb = find_extent_buffer(&BTRFS_I(btree_inode)->extent_tree, | 51 | eb = find_extent_buffer(&BTRFS_I(btree_inode)->extent_tree, |
51 | blocknr * root->sectorsize, | 52 | bytenr, blocksize, GFP_NOFS); |
52 | root->sectorsize, GFP_NOFS); | ||
53 | if (eb) | 53 | if (eb) |
54 | eb->alloc_addr = (unsigned long)__builtin_return_address(0); | 54 | eb->alloc_addr = (unsigned long)__builtin_return_address(0); |
55 | return eb; | 55 | return eb; |
56 | } | 56 | } |
57 | 57 | ||
58 | struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, | 58 | struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, |
59 | u64 blocknr) | 59 | u64 bytenr, u32 blocksize) |
60 | { | 60 | { |
61 | struct inode *btree_inode = root->fs_info->btree_inode; | 61 | struct inode *btree_inode = root->fs_info->btree_inode; |
62 | struct extent_buffer *eb; | 62 | struct extent_buffer *eb; |
63 | |||
63 | eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->extent_tree, | 64 | eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->extent_tree, |
64 | blocknr * root->sectorsize, | 65 | bytenr, blocksize, GFP_NOFS); |
65 | root->sectorsize, GFP_NOFS); | ||
66 | eb->alloc_addr = (unsigned long)__builtin_return_address(0); | 66 | eb->alloc_addr = (unsigned long)__builtin_return_address(0); |
67 | return eb; | 67 | return eb; |
68 | } | 68 | } |
@@ -208,13 +208,13 @@ static struct address_space_operations btree_aops = { | |||
208 | .sync_page = block_sync_page, | 208 | .sync_page = block_sync_page, |
209 | }; | 209 | }; |
210 | 210 | ||
211 | int readahead_tree_block(struct btrfs_root *root, u64 blocknr) | 211 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize) |
212 | { | 212 | { |
213 | struct extent_buffer *buf = NULL; | 213 | struct extent_buffer *buf = NULL; |
214 | struct inode *btree_inode = root->fs_info->btree_inode; | 214 | struct inode *btree_inode = root->fs_info->btree_inode; |
215 | int ret = 0; | 215 | int ret = 0; |
216 | 216 | ||
217 | buf = btrfs_find_create_tree_block(root, blocknr); | 217 | buf = btrfs_find_create_tree_block(root, bytenr, blocksize); |
218 | if (!buf) | 218 | if (!buf) |
219 | return 0; | 219 | return 0; |
220 | read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree, | 220 | read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree, |
@@ -223,12 +223,13 @@ int readahead_tree_block(struct btrfs_root *root, u64 blocknr) | |||
223 | return ret; | 223 | return ret; |
224 | } | 224 | } |
225 | 225 | ||
226 | struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr) | 226 | struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, |
227 | u32 blocksize) | ||
227 | { | 228 | { |
228 | struct extent_buffer *buf = NULL; | 229 | struct extent_buffer *buf = NULL; |
229 | struct inode *btree_inode = root->fs_info->btree_inode; | 230 | struct inode *btree_inode = root->fs_info->btree_inode; |
230 | 231 | ||
231 | buf = btrfs_find_create_tree_block(root, blocknr); | 232 | buf = btrfs_find_create_tree_block(root, bytenr, blocksize); |
232 | if (!buf) | 233 | if (!buf) |
233 | return NULL; | 234 | return NULL; |
234 | read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree, | 235 | read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree, |
@@ -261,7 +262,7 @@ int set_tree_block_dirty(struct btrfs_root *root, struct extent_buffer *buf) | |||
261 | return 0; | 262 | return 0; |
262 | } | 263 | } |
263 | 264 | ||
264 | static int __setup_root(int blocksize, | 265 | static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, |
265 | struct btrfs_root *root, | 266 | struct btrfs_root *root, |
266 | struct btrfs_fs_info *fs_info, | 267 | struct btrfs_fs_info *fs_info, |
267 | u64 objectid) | 268 | u64 objectid) |
@@ -269,9 +270,9 @@ static int __setup_root(int blocksize, | |||
269 | root->node = NULL; | 270 | root->node = NULL; |
270 | root->inode = NULL; | 271 | root->inode = NULL; |
271 | root->commit_root = NULL; | 272 | root->commit_root = NULL; |
272 | root->sectorsize = blocksize; | 273 | root->sectorsize = sectorsize; |
273 | root->nodesize = blocksize; | 274 | root->nodesize = nodesize; |
274 | root->leafsize = blocksize; | 275 | root->leafsize = leafsize; |
275 | root->ref_cows = 0; | 276 | root->ref_cows = 0; |
276 | root->fs_info = fs_info; | 277 | root->fs_info = fs_info; |
277 | root->objectid = objectid; | 278 | root->objectid = objectid; |
@@ -291,21 +292,23 @@ static int __setup_root(int blocksize, | |||
291 | return 0; | 292 | return 0; |
292 | } | 293 | } |
293 | 294 | ||
294 | static int find_and_setup_root(int blocksize, | 295 | static int find_and_setup_root(struct btrfs_root *tree_root, |
295 | struct btrfs_root *tree_root, | ||
296 | struct btrfs_fs_info *fs_info, | 296 | struct btrfs_fs_info *fs_info, |
297 | u64 objectid, | 297 | u64 objectid, |
298 | struct btrfs_root *root) | 298 | struct btrfs_root *root) |
299 | { | 299 | { |
300 | int ret; | 300 | int ret; |
301 | u32 blocksize; | ||
301 | 302 | ||
302 | __setup_root(blocksize, root, fs_info, objectid); | 303 | __setup_root(tree_root->nodesize, tree_root->leafsize, |
304 | tree_root->sectorsize, root, fs_info, objectid); | ||
303 | ret = btrfs_find_last_root(tree_root, objectid, | 305 | ret = btrfs_find_last_root(tree_root, objectid, |
304 | &root->root_item, &root->root_key); | 306 | &root->root_item, &root->root_key); |
305 | BUG_ON(ret); | 307 | BUG_ON(ret); |
306 | 308 | ||
307 | root->node = read_tree_block(root, | 309 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); |
308 | btrfs_root_blocknr(&root->root_item)); | 310 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), |
311 | blocksize); | ||
309 | BUG_ON(!root->node); | 312 | BUG_ON(!root->node); |
310 | return 0; | 313 | return 0; |
311 | } | 314 | } |
@@ -318,14 +321,14 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info, | |||
318 | struct btrfs_path *path; | 321 | struct btrfs_path *path; |
319 | struct extent_buffer *l; | 322 | struct extent_buffer *l; |
320 | u64 highest_inode; | 323 | u64 highest_inode; |
324 | u32 blocksize; | ||
321 | int ret = 0; | 325 | int ret = 0; |
322 | 326 | ||
323 | root = kzalloc(sizeof(*root), GFP_NOFS); | 327 | root = kzalloc(sizeof(*root), GFP_NOFS); |
324 | if (!root) | 328 | if (!root) |
325 | return ERR_PTR(-ENOMEM); | 329 | return ERR_PTR(-ENOMEM); |
326 | if (location->offset == (u64)-1) { | 330 | if (location->offset == (u64)-1) { |
327 | ret = find_and_setup_root(fs_info->sb->s_blocksize, | 331 | ret = find_and_setup_root(tree_root, fs_info, |
328 | fs_info->tree_root, fs_info, | ||
329 | location->objectid, root); | 332 | location->objectid, root); |
330 | if (ret) { | 333 | if (ret) { |
331 | kfree(root); | 334 | kfree(root); |
@@ -334,7 +337,8 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info, | |||
334 | goto insert; | 337 | goto insert; |
335 | } | 338 | } |
336 | 339 | ||
337 | __setup_root(fs_info->sb->s_blocksize, root, fs_info, | 340 | __setup_root(tree_root->nodesize, tree_root->leafsize, |
341 | tree_root->sectorsize, root, fs_info, | ||
338 | location->objectid); | 342 | location->objectid); |
339 | 343 | ||
340 | path = btrfs_alloc_path(); | 344 | path = btrfs_alloc_path(); |
@@ -357,8 +361,9 @@ out: | |||
357 | kfree(root); | 361 | kfree(root); |
358 | return ERR_PTR(ret); | 362 | return ERR_PTR(ret); |
359 | } | 363 | } |
360 | root->node = read_tree_block(root, | 364 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); |
361 | btrfs_root_blocknr(&root->root_item)); | 365 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), |
366 | blocksize); | ||
362 | BUG_ON(!root->node); | 367 | BUG_ON(!root->node); |
363 | insert: | 368 | insert: |
364 | root->ref_cows = 1; | 369 | root->ref_cows = 1; |
@@ -418,6 +423,10 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | |||
418 | 423 | ||
419 | struct btrfs_root *open_ctree(struct super_block *sb) | 424 | struct btrfs_root *open_ctree(struct super_block *sb) |
420 | { | 425 | { |
426 | u32 sectorsize; | ||
427 | u32 nodesize; | ||
428 | u32 leafsize; | ||
429 | u32 blocksize; | ||
421 | struct btrfs_root *extent_root = kmalloc(sizeof(struct btrfs_root), | 430 | struct btrfs_root *extent_root = kmalloc(sizeof(struct btrfs_root), |
422 | GFP_NOFS); | 431 | GFP_NOFS); |
423 | struct btrfs_root *tree_root = kmalloc(sizeof(struct btrfs_root), | 432 | struct btrfs_root *tree_root = kmalloc(sizeof(struct btrfs_root), |
@@ -474,12 +483,12 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
474 | mutex_init(&fs_info->trans_mutex); | 483 | mutex_init(&fs_info->trans_mutex); |
475 | mutex_init(&fs_info->fs_mutex); | 484 | mutex_init(&fs_info->fs_mutex); |
476 | 485 | ||
477 | __setup_root(sb->s_blocksize, tree_root, | 486 | __setup_root(512, 512, 512, tree_root, |
478 | fs_info, BTRFS_ROOT_TREE_OBJECTID); | 487 | fs_info, BTRFS_ROOT_TREE_OBJECTID); |
479 | 488 | ||
480 | fs_info->sb_buffer = read_tree_block(tree_root, | 489 | fs_info->sb_buffer = read_tree_block(tree_root, |
481 | BTRFS_SUPER_INFO_OFFSET / | 490 | BTRFS_SUPER_INFO_OFFSET, |
482 | sb->s_blocksize); | 491 | 512); |
483 | 492 | ||
484 | if (!fs_info->sb_buffer) | 493 | if (!fs_info->sb_buffer) |
485 | goto fail_iput; | 494 | goto fail_iput; |
@@ -494,9 +503,15 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
494 | if (!btrfs_super_root(disk_super)) | 503 | if (!btrfs_super_root(disk_super)) |
495 | goto fail_sb_buffer; | 504 | goto fail_sb_buffer; |
496 | 505 | ||
506 | nodesize = btrfs_super_nodesize(disk_super); | ||
507 | leafsize = btrfs_super_leafsize(disk_super); | ||
508 | sectorsize = btrfs_super_sectorsize(disk_super); | ||
509 | tree_root->nodesize = nodesize; | ||
510 | tree_root->leafsize = leafsize; | ||
511 | tree_root->sectorsize = sectorsize; | ||
512 | |||
497 | i_size_write(fs_info->btree_inode, | 513 | i_size_write(fs_info->btree_inode, |
498 | btrfs_super_total_blocks(disk_super) << | 514 | btrfs_super_total_bytes(disk_super)); |
499 | fs_info->btree_inode->i_blkbits); | ||
500 | 515 | ||
501 | 516 | ||
502 | if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC, | 517 | if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC, |
@@ -504,13 +519,22 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
504 | printk("btrfs: valid FS not found on %s\n", sb->s_id); | 519 | printk("btrfs: valid FS not found on %s\n", sb->s_id); |
505 | goto fail_sb_buffer; | 520 | goto fail_sb_buffer; |
506 | } | 521 | } |
522 | blocksize = btrfs_level_size(tree_root, | ||
523 | btrfs_super_root_level(disk_super)); | ||
507 | tree_root->node = read_tree_block(tree_root, | 524 | tree_root->node = read_tree_block(tree_root, |
508 | btrfs_super_root(disk_super)); | 525 | btrfs_super_root(disk_super), |
526 | blocksize); | ||
509 | if (!tree_root->node) | 527 | if (!tree_root->node) |
510 | goto fail_sb_buffer; | 528 | goto fail_sb_buffer; |
511 | 529 | ||
530 | #if 0 | ||
531 | btrfs_print_leaf(tree_root, tree_root->node); | ||
532 | err = -EIO; | ||
533 | goto fail_tree_root; | ||
534 | #endif | ||
512 | mutex_lock(&fs_info->fs_mutex); | 535 | mutex_lock(&fs_info->fs_mutex); |
513 | ret = find_and_setup_root(sb->s_blocksize, tree_root, fs_info, | 536 | |
537 | ret = find_and_setup_root(tree_root, fs_info, | ||
514 | BTRFS_EXTENT_TREE_OBJECTID, extent_root); | 538 | BTRFS_EXTENT_TREE_OBJECTID, extent_root); |
515 | if (ret) { | 539 | if (ret) { |
516 | mutex_unlock(&fs_info->fs_mutex); | 540 | mutex_unlock(&fs_info->fs_mutex); |
@@ -611,11 +635,11 @@ int close_ctree(struct btrfs_root *root) | |||
611 | free_extent_buffer(fs_info->tree_root->node); | 635 | free_extent_buffer(fs_info->tree_root->node); |
612 | 636 | ||
613 | free_extent_buffer(fs_info->sb_buffer); | 637 | free_extent_buffer(fs_info->sb_buffer); |
614 | truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); | ||
615 | iput(fs_info->btree_inode); | ||
616 | 638 | ||
617 | btrfs_free_block_groups(root->fs_info); | 639 | btrfs_free_block_groups(root->fs_info); |
618 | del_fs_roots(fs_info); | 640 | del_fs_roots(fs_info); |
641 | truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); | ||
642 | iput(fs_info->btree_inode); | ||
619 | kfree(fs_info->extent_root); | 643 | kfree(fs_info->extent_root); |
620 | kfree(fs_info->tree_root); | 644 | kfree(fs_info->tree_root); |
621 | return 0; | 645 | return 0; |
@@ -642,7 +666,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | |||
642 | 666 | ||
643 | if (transid != root->fs_info->generation) { | 667 | if (transid != root->fs_info->generation) { |
644 | printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n", | 668 | printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n", |
645 | (unsigned long long)extent_buffer_blocknr(buf), | 669 | (unsigned long long)buf->start, |
646 | transid, root->fs_info->generation); | 670 | transid, root->fs_info->generation); |
647 | WARN_ON(1); | 671 | WARN_ON(1); |
648 | } | 672 | } |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 70d9413c599f..fd4db5f810cf 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
@@ -21,10 +21,11 @@ | |||
21 | 21 | ||
22 | #define BTRFS_SUPER_INFO_OFFSET (16 * 1024) | 22 | #define BTRFS_SUPER_INFO_OFFSET (16 * 1024) |
23 | 23 | ||
24 | struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr); | 24 | struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, |
25 | int readahead_tree_block(struct btrfs_root *root, u64 blocknr); | 25 | u32 blocksize); |
26 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize); | ||
26 | struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, | 27 | struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, |
27 | u64 blocknr); | 28 | u64 bytenr, u32 blocksize); |
28 | int clean_tree_block(struct btrfs_trans_handle *trans, | 29 | int clean_tree_block(struct btrfs_trans_handle *trans, |
29 | struct btrfs_root *root, struct extent_buffer *buf); | 30 | struct btrfs_root *root, struct extent_buffer *buf); |
30 | struct btrfs_root *open_ctree(struct super_block *sb); | 31 | struct btrfs_root *open_ctree(struct super_block *sb); |
@@ -32,7 +33,7 @@ int close_ctree(struct btrfs_root *root); | |||
32 | int write_ctree_super(struct btrfs_trans_handle *trans, | 33 | int write_ctree_super(struct btrfs_trans_handle *trans, |
33 | struct btrfs_root *root); | 34 | struct btrfs_root *root); |
34 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, | 35 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, |
35 | u64 blocknr); | 36 | u64 bytenr, u32 blocksize); |
36 | struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | 37 | struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, |
37 | struct btrfs_key *location, | 38 | struct btrfs_key *location, |
38 | const char *name, int namelen); | 39 | const char *name, int namelen); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 477466d167a4..1be8f9f04a13 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -129,7 +129,7 @@ err: | |||
129 | 129 | ||
130 | struct btrfs_block_group_cache *btrfs_lookup_block_group(struct | 130 | struct btrfs_block_group_cache *btrfs_lookup_block_group(struct |
131 | btrfs_fs_info *info, | 131 | btrfs_fs_info *info, |
132 | u64 blocknr) | 132 | u64 bytenr) |
133 | { | 133 | { |
134 | struct extent_map_tree *block_group_cache; | 134 | struct extent_map_tree *block_group_cache; |
135 | struct btrfs_block_group_cache *block_group = NULL; | 135 | struct btrfs_block_group_cache *block_group = NULL; |
@@ -140,7 +140,7 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct | |||
140 | 140 | ||
141 | block_group_cache = &info->block_group_cache; | 141 | block_group_cache = &info->block_group_cache; |
142 | ret = find_first_extent_bit(block_group_cache, | 142 | ret = find_first_extent_bit(block_group_cache, |
143 | blocknr, &start, &end, | 143 | bytenr, &start, &end, |
144 | BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA); | 144 | BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA); |
145 | if (ret) { | 145 | if (ret) { |
146 | return NULL; | 146 | return NULL; |
@@ -152,7 +152,7 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct | |||
152 | block_group = (struct btrfs_block_group_cache *)ptr; | 152 | block_group = (struct btrfs_block_group_cache *)ptr; |
153 | 153 | ||
154 | 154 | ||
155 | if (block_group->key.objectid <= blocknr && blocknr <= | 155 | if (block_group->key.objectid <= bytenr && bytenr <= |
156 | block_group->key.objectid + block_group->key.offset) | 156 | block_group->key.objectid + block_group->key.offset) |
157 | return block_group; | 157 | return block_group; |
158 | 158 | ||
@@ -315,7 +315,7 @@ found: | |||
315 | 315 | ||
316 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 316 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
317 | struct btrfs_root *root, | 317 | struct btrfs_root *root, |
318 | u64 blocknr, u64 num_blocks) | 318 | u64 bytenr, u64 num_bytes) |
319 | { | 319 | { |
320 | struct btrfs_path *path; | 320 | struct btrfs_path *path; |
321 | int ret; | 321 | int ret; |
@@ -324,13 +324,14 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
324 | struct btrfs_extent_item *item; | 324 | struct btrfs_extent_item *item; |
325 | u32 refs; | 325 | u32 refs; |
326 | 326 | ||
327 | WARN_ON(num_bytes < root->sectorsize); | ||
327 | path = btrfs_alloc_path(); | 328 | path = btrfs_alloc_path(); |
328 | if (!path) | 329 | if (!path) |
329 | return -ENOMEM; | 330 | return -ENOMEM; |
330 | 331 | ||
331 | key.objectid = blocknr; | 332 | key.objectid = bytenr; |
332 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 333 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
333 | key.offset = num_blocks; | 334 | key.offset = num_bytes; |
334 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, | 335 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, |
335 | 0, 1); | 336 | 0, 1); |
336 | if (ret < 0) | 337 | if (ret < 0) |
@@ -361,8 +362,8 @@ int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | |||
361 | } | 362 | } |
362 | 363 | ||
363 | static int lookup_extent_ref(struct btrfs_trans_handle *trans, | 364 | static int lookup_extent_ref(struct btrfs_trans_handle *trans, |
364 | struct btrfs_root *root, u64 blocknr, | 365 | struct btrfs_root *root, u64 bytenr, |
365 | u64 num_blocks, u32 *refs) | 366 | u64 num_bytes, u32 *refs) |
366 | { | 367 | { |
367 | struct btrfs_path *path; | 368 | struct btrfs_path *path; |
368 | int ret; | 369 | int ret; |
@@ -370,9 +371,10 @@ static int lookup_extent_ref(struct btrfs_trans_handle *trans, | |||
370 | struct extent_buffer *l; | 371 | struct extent_buffer *l; |
371 | struct btrfs_extent_item *item; | 372 | struct btrfs_extent_item *item; |
372 | 373 | ||
374 | WARN_ON(num_bytes < root->sectorsize); | ||
373 | path = btrfs_alloc_path(); | 375 | path = btrfs_alloc_path(); |
374 | key.objectid = blocknr; | 376 | key.objectid = bytenr; |
375 | key.offset = num_blocks; | 377 | key.offset = num_bytes; |
376 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 378 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
377 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, | 379 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, |
378 | 0, 0); | 380 | 0, 0); |
@@ -380,7 +382,7 @@ static int lookup_extent_ref(struct btrfs_trans_handle *trans, | |||
380 | goto out; | 382 | goto out; |
381 | if (ret != 0) { | 383 | if (ret != 0) { |
382 | btrfs_print_leaf(root, path->nodes[0]); | 384 | btrfs_print_leaf(root, path->nodes[0]); |
383 | printk("failed to find block number %Lu\n", blocknr); | 385 | printk("failed to find block number %Lu\n", bytenr); |
384 | BUG(); | 386 | BUG(); |
385 | } | 387 | } |
386 | l = path->nodes[0]; | 388 | l = path->nodes[0]; |
@@ -394,19 +396,19 @@ out: | |||
394 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | 396 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, |
395 | struct btrfs_root *root) | 397 | struct btrfs_root *root) |
396 | { | 398 | { |
397 | return btrfs_inc_extent_ref(trans, root, | 399 | return btrfs_inc_extent_ref(trans, root, root->node->start, |
398 | extent_buffer_blocknr(root->node), 1); | 400 | root->node->len); |
399 | } | 401 | } |
400 | 402 | ||
401 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 403 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
402 | struct extent_buffer *buf) | 404 | struct extent_buffer *buf) |
403 | { | 405 | { |
404 | u64 blocknr; | 406 | u64 bytenr; |
405 | u32 nritems; | 407 | u32 nritems; |
406 | struct btrfs_key key; | 408 | struct btrfs_key key; |
407 | struct btrfs_file_extent_item *fi; | 409 | struct btrfs_file_extent_item *fi; |
408 | int i; | 410 | int i; |
409 | int leaf; | 411 | int level; |
410 | int ret; | 412 | int ret; |
411 | int faili; | 413 | int faili; |
412 | int err; | 414 | int err; |
@@ -414,11 +416,11 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
414 | if (!root->ref_cows) | 416 | if (!root->ref_cows) |
415 | return 0; | 417 | return 0; |
416 | 418 | ||
417 | leaf = btrfs_is_leaf(buf); | 419 | level = btrfs_header_level(buf); |
418 | nritems = btrfs_header_nritems(buf); | 420 | nritems = btrfs_header_nritems(buf); |
419 | for (i = 0; i < nritems; i++) { | 421 | for (i = 0; i < nritems; i++) { |
420 | if (leaf) { | 422 | if (level == 0) { |
421 | u64 disk_blocknr; | 423 | u64 disk_bytenr; |
422 | btrfs_item_key_to_cpu(buf, &key, i); | 424 | btrfs_item_key_to_cpu(buf, &key, i); |
423 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 425 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
424 | continue; | 426 | continue; |
@@ -427,18 +429,19 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
427 | if (btrfs_file_extent_type(buf, fi) == | 429 | if (btrfs_file_extent_type(buf, fi) == |
428 | BTRFS_FILE_EXTENT_INLINE) | 430 | BTRFS_FILE_EXTENT_INLINE) |
429 | continue; | 431 | continue; |
430 | disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi); | 432 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); |
431 | if (disk_blocknr == 0) | 433 | if (disk_bytenr == 0) |
432 | continue; | 434 | continue; |
433 | ret = btrfs_inc_extent_ref(trans, root, disk_blocknr, | 435 | ret = btrfs_inc_extent_ref(trans, root, disk_bytenr, |
434 | btrfs_file_extent_disk_num_blocks(buf, fi)); | 436 | btrfs_file_extent_disk_num_bytes(buf, fi)); |
435 | if (ret) { | 437 | if (ret) { |
436 | faili = i; | 438 | faili = i; |
437 | goto fail; | 439 | goto fail; |
438 | } | 440 | } |
439 | } else { | 441 | } else { |
440 | blocknr = btrfs_node_blockptr(buf, i); | 442 | bytenr = btrfs_node_blockptr(buf, i); |
441 | ret = btrfs_inc_extent_ref(trans, root, blocknr, 1); | 443 | ret = btrfs_inc_extent_ref(trans, root, bytenr, |
444 | btrfs_level_size(root, level - 1)); | ||
442 | if (ret) { | 445 | if (ret) { |
443 | faili = i; | 446 | faili = i; |
444 | goto fail; | 447 | goto fail; |
@@ -449,8 +452,8 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
449 | fail: | 452 | fail: |
450 | WARN_ON(1); | 453 | WARN_ON(1); |
451 | for (i =0; i < faili; i++) { | 454 | for (i =0; i < faili; i++) { |
452 | if (leaf) { | 455 | if (level == 0) { |
453 | u64 disk_blocknr; | 456 | u64 disk_bytenr; |
454 | btrfs_item_key_to_cpu(buf, &key, i); | 457 | btrfs_item_key_to_cpu(buf, &key, i); |
455 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 458 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
456 | continue; | 459 | continue; |
@@ -459,16 +462,17 @@ fail: | |||
459 | if (btrfs_file_extent_type(buf, fi) == | 462 | if (btrfs_file_extent_type(buf, fi) == |
460 | BTRFS_FILE_EXTENT_INLINE) | 463 | BTRFS_FILE_EXTENT_INLINE) |
461 | continue; | 464 | continue; |
462 | disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi); | 465 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); |
463 | if (disk_blocknr == 0) | 466 | if (disk_bytenr == 0) |
464 | continue; | 467 | continue; |
465 | err = btrfs_free_extent(trans, root, disk_blocknr, | 468 | err = btrfs_free_extent(trans, root, disk_bytenr, |
466 | btrfs_file_extent_disk_num_blocks(buf, | 469 | btrfs_file_extent_disk_num_bytes(buf, |
467 | fi), 0); | 470 | fi), 0); |
468 | BUG_ON(err); | 471 | BUG_ON(err); |
469 | } else { | 472 | } else { |
470 | blocknr = btrfs_node_blockptr(buf, i); | 473 | bytenr = btrfs_node_blockptr(buf, i); |
471 | err = btrfs_free_extent(trans, root, blocknr, 1, 0); | 474 | err = btrfs_free_extent(trans, root, bytenr, |
475 | btrfs_level_size(root, level - 1), 0); | ||
472 | BUG_ON(err); | 476 | BUG_ON(err); |
473 | } | 477 | } |
474 | } | 478 | } |
@@ -558,31 +562,31 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | |||
558 | 562 | ||
559 | static int update_block_group(struct btrfs_trans_handle *trans, | 563 | static int update_block_group(struct btrfs_trans_handle *trans, |
560 | struct btrfs_root *root, | 564 | struct btrfs_root *root, |
561 | u64 blocknr, u64 num, int alloc, int mark_free, | 565 | u64 bytenr, u64 num_bytes, int alloc, |
562 | int data) | 566 | int mark_free, int data) |
563 | { | 567 | { |
564 | struct btrfs_block_group_cache *cache; | 568 | struct btrfs_block_group_cache *cache; |
565 | struct btrfs_fs_info *info = root->fs_info; | 569 | struct btrfs_fs_info *info = root->fs_info; |
566 | u64 total = num; | 570 | u64 total = num_bytes; |
567 | u64 old_val; | 571 | u64 old_val; |
568 | u64 block_in_group; | 572 | u64 byte_in_group; |
569 | u64 start; | 573 | u64 start; |
570 | u64 end; | 574 | u64 end; |
571 | 575 | ||
572 | while(total) { | 576 | while(total) { |
573 | cache = btrfs_lookup_block_group(info, blocknr); | 577 | cache = btrfs_lookup_block_group(info, bytenr); |
574 | if (!cache) { | 578 | if (!cache) { |
575 | return -1; | 579 | return -1; |
576 | } | 580 | } |
577 | block_in_group = blocknr - cache->key.objectid; | 581 | byte_in_group = bytenr - cache->key.objectid; |
578 | WARN_ON(block_in_group > cache->key.offset); | 582 | WARN_ON(byte_in_group > cache->key.offset); |
579 | start = cache->key.objectid; | 583 | start = cache->key.objectid; |
580 | end = start + cache->key.offset - 1; | 584 | end = start + cache->key.offset - 1; |
581 | set_extent_bits(&info->block_group_cache, start, end, | 585 | set_extent_bits(&info->block_group_cache, start, end, |
582 | BLOCK_GROUP_DIRTY, GFP_NOFS); | 586 | BLOCK_GROUP_DIRTY, GFP_NOFS); |
583 | 587 | ||
584 | old_val = btrfs_block_group_used(&cache->item); | 588 | old_val = btrfs_block_group_used(&cache->item); |
585 | num = min(total, cache->key.offset - block_in_group); | 589 | num_bytes = min(total, cache->key.offset - byte_in_group); |
586 | if (alloc) { | 590 | if (alloc) { |
587 | if (cache->data != data && | 591 | if (cache->data != data && |
588 | old_val < (cache->key.offset >> 1)) { | 592 | old_val < (cache->key.offset >> 1)) { |
@@ -608,18 +612,18 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
608 | start, end, bit_to_set, | 612 | start, end, bit_to_set, |
609 | GFP_NOFS); | 613 | GFP_NOFS); |
610 | } | 614 | } |
611 | old_val += num; | 615 | old_val += num_bytes; |
612 | } else { | 616 | } else { |
613 | old_val -= num; | 617 | old_val -= num_bytes; |
614 | if (mark_free) { | 618 | if (mark_free) { |
615 | set_extent_dirty(&info->free_space_cache, | 619 | set_extent_dirty(&info->free_space_cache, |
616 | blocknr, blocknr + num - 1, | 620 | bytenr, bytenr + num_bytes - 1, |
617 | GFP_NOFS); | 621 | GFP_NOFS); |
618 | } | 622 | } |
619 | } | 623 | } |
620 | btrfs_set_block_group_used(&cache->item, old_val); | 624 | btrfs_set_block_group_used(&cache->item, old_val); |
621 | total -= num; | 625 | total -= num_bytes; |
622 | blocknr += num; | 626 | bytenr += num_bytes; |
623 | } | 627 | } |
624 | return 0; | 628 | return 0; |
625 | } | 629 | } |
@@ -701,13 +705,14 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct | |||
701 | return 0; | 705 | return 0; |
702 | } | 706 | } |
703 | 707 | ||
704 | static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) | 708 | static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, |
709 | int pending) | ||
705 | { | 710 | { |
706 | int err = 0; | 711 | int err = 0; |
707 | struct extent_buffer *buf; | 712 | struct extent_buffer *buf; |
708 | 713 | ||
709 | if (!pending) { | 714 | if (!pending) { |
710 | buf = btrfs_find_tree_block(root, blocknr); | 715 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); |
711 | if (buf) { | 716 | if (buf) { |
712 | if (btrfs_buffer_uptodate(buf)) { | 717 | if (btrfs_buffer_uptodate(buf)) { |
713 | u64 transid = | 718 | u64 transid = |
@@ -720,10 +725,11 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) | |||
720 | free_extent_buffer(buf); | 725 | free_extent_buffer(buf); |
721 | } | 726 | } |
722 | set_extent_dirty(&root->fs_info->pinned_extents, | 727 | set_extent_dirty(&root->fs_info->pinned_extents, |
723 | blocknr, blocknr, GFP_NOFS); | 728 | bytenr, bytenr + num_bytes - 1, GFP_NOFS); |
724 | } else { | 729 | } else { |
725 | set_extent_bits(&root->fs_info->pending_del, | 730 | set_extent_bits(&root->fs_info->pending_del, |
726 | blocknr, blocknr, EXTENT_LOCKED, GFP_NOFS); | 731 | bytenr, bytenr + num_bytes - 1, |
732 | EXTENT_LOCKED, GFP_NOFS); | ||
727 | } | 733 | } |
728 | BUG_ON(err < 0); | 734 | BUG_ON(err < 0); |
729 | return 0; | 735 | return 0; |
@@ -733,7 +739,7 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) | |||
733 | * remove an extent from the root, returns 0 on success | 739 | * remove an extent from the root, returns 0 on success |
734 | */ | 740 | */ |
735 | static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 741 | static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
736 | *root, u64 blocknr, u64 num_blocks, int pin, | 742 | *root, u64 bytenr, u64 num_bytes, int pin, |
737 | int mark_free) | 743 | int mark_free) |
738 | { | 744 | { |
739 | struct btrfs_path *path; | 745 | struct btrfs_path *path; |
@@ -745,9 +751,9 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
745 | struct btrfs_extent_item *ei; | 751 | struct btrfs_extent_item *ei; |
746 | u32 refs; | 752 | u32 refs; |
747 | 753 | ||
748 | key.objectid = blocknr; | 754 | key.objectid = bytenr; |
749 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 755 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
750 | key.offset = num_blocks; | 756 | key.offset = num_bytes; |
751 | 757 | ||
752 | path = btrfs_alloc_path(); | 758 | path = btrfs_alloc_path(); |
753 | if (!path) | 759 | if (!path) |
@@ -768,28 +774,29 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
768 | btrfs_mark_buffer_dirty(leaf); | 774 | btrfs_mark_buffer_dirty(leaf); |
769 | 775 | ||
770 | if (refs == 0) { | 776 | if (refs == 0) { |
771 | u64 super_blocks_used, root_blocks_used; | 777 | u64 super_used; |
778 | u64 root_used; | ||
772 | 779 | ||
773 | if (pin) { | 780 | if (pin) { |
774 | ret = pin_down_block(root, blocknr, 0); | 781 | ret = pin_down_bytes(root, bytenr, num_bytes, 0); |
775 | BUG_ON(ret); | 782 | BUG_ON(ret); |
776 | } | 783 | } |
777 | 784 | ||
778 | /* block accounting for super block */ | 785 | /* block accounting for super block */ |
779 | super_blocks_used = btrfs_super_blocks_used(&info->super_copy); | 786 | super_used = btrfs_super_bytes_used(&info->super_copy); |
780 | btrfs_set_super_blocks_used(&info->super_copy, | 787 | btrfs_set_super_bytes_used(&info->super_copy, |
781 | super_blocks_used - num_blocks); | 788 | super_used - num_bytes); |
782 | 789 | ||
783 | /* block accounting for root item */ | 790 | /* block accounting for root item */ |
784 | root_blocks_used = btrfs_root_used(&root->root_item); | 791 | root_used = btrfs_root_used(&root->root_item); |
785 | btrfs_set_root_used(&root->root_item, | 792 | btrfs_set_root_used(&root->root_item, |
786 | root_blocks_used - num_blocks); | 793 | root_used - num_bytes); |
787 | 794 | ||
788 | ret = btrfs_del_item(trans, extent_root, path); | 795 | ret = btrfs_del_item(trans, extent_root, path); |
789 | if (ret) { | 796 | if (ret) { |
790 | return ret; | 797 | return ret; |
791 | } | 798 | } |
792 | ret = update_block_group(trans, root, blocknr, num_blocks, 0, | 799 | ret = update_block_group(trans, root, bytenr, num_bytes, 0, |
793 | mark_free, 0); | 800 | mark_free, 0); |
794 | BUG_ON(ret); | 801 | BUG_ON(ret); |
795 | } | 802 | } |
@@ -836,17 +843,18 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct | |||
836 | * remove an extent from the root, returns 0 on success | 843 | * remove an extent from the root, returns 0 on success |
837 | */ | 844 | */ |
838 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 845 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
839 | *root, u64 blocknr, u64 num_blocks, int pin) | 846 | *root, u64 bytenr, u64 num_bytes, int pin) |
840 | { | 847 | { |
841 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 848 | struct btrfs_root *extent_root = root->fs_info->extent_root; |
842 | int pending_ret; | 849 | int pending_ret; |
843 | int ret; | 850 | int ret; |
844 | 851 | ||
852 | WARN_ON(num_bytes < root->sectorsize); | ||
845 | if (root == extent_root) { | 853 | if (root == extent_root) { |
846 | pin_down_block(root, blocknr, 1); | 854 | pin_down_bytes(root, bytenr, num_bytes, 1); |
847 | return 0; | 855 | return 0; |
848 | } | 856 | } |
849 | ret = __free_extent(trans, root, blocknr, num_blocks, pin, pin == 0); | 857 | ret = __free_extent(trans, root, bytenr, num_bytes, pin, pin == 0); |
850 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); | 858 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); |
851 | return ret ? ret : pending_ret; | 859 | return ret ? ret : pending_ret; |
852 | } | 860 | } |
@@ -860,8 +868,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
860 | * Any available blocks before search_start are skipped. | 868 | * Any available blocks before search_start are skipped. |
861 | */ | 869 | */ |
862 | static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 870 | static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
863 | *orig_root, u64 num_blocks, u64 empty_size, | 871 | *orig_root, u64 num_bytes, u64 empty_size, |
864 | u64 search_start, u64 search_end, u64 hint_block, | 872 | u64 search_start, u64 search_end, u64 hint_byte, |
865 | struct btrfs_key *ins, u64 exclude_start, | 873 | struct btrfs_key *ins, u64 exclude_start, |
866 | u64 exclude_nr, int data) | 874 | u64 exclude_nr, int data) |
867 | { | 875 | { |
@@ -870,30 +878,29 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
870 | int ret; | 878 | int ret; |
871 | u64 hole_size = 0; | 879 | u64 hole_size = 0; |
872 | int slot = 0; | 880 | int slot = 0; |
873 | u64 last_block = 0; | 881 | u64 last_byte = 0; |
874 | u64 orig_search_start = search_start; | 882 | u64 orig_search_start = search_start; |
875 | int start_found; | 883 | int start_found; |
876 | struct extent_buffer *l; | 884 | struct extent_buffer *l; |
877 | struct btrfs_root * root = orig_root->fs_info->extent_root; | 885 | struct btrfs_root * root = orig_root->fs_info->extent_root; |
878 | struct btrfs_fs_info *info = root->fs_info; | 886 | struct btrfs_fs_info *info = root->fs_info; |
879 | int total_needed = num_blocks; | 887 | u64 total_needed = num_bytes; |
880 | int level; | 888 | int level; |
881 | struct btrfs_block_group_cache *block_group; | 889 | struct btrfs_block_group_cache *block_group; |
882 | int full_scan = 0; | 890 | int full_scan = 0; |
883 | int wrapped = 0; | 891 | int wrapped = 0; |
884 | u64 cached_search_start = 0; | ||
885 | 892 | ||
886 | WARN_ON(num_blocks < 1); | 893 | WARN_ON(num_bytes < root->sectorsize); |
887 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); | 894 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); |
888 | 895 | ||
889 | level = btrfs_header_level(root->node); | 896 | level = btrfs_header_level(root->node); |
890 | 897 | ||
891 | if (search_end == (u64)-1) | 898 | if (search_end == (u64)-1) |
892 | search_end = btrfs_super_total_blocks(&info->super_copy); | 899 | search_end = btrfs_super_total_bytes(&info->super_copy); |
893 | if (hint_block) { | 900 | if (hint_byte) { |
894 | block_group = btrfs_lookup_block_group(info, hint_block); | 901 | block_group = btrfs_lookup_block_group(info, hint_byte); |
895 | block_group = btrfs_find_block_group(root, block_group, | 902 | block_group = btrfs_find_block_group(root, block_group, |
896 | hint_block, data, 1); | 903 | hint_byte, data, 1); |
897 | } else { | 904 | } else { |
898 | block_group = btrfs_find_block_group(root, | 905 | block_group = btrfs_find_block_group(root, |
899 | trans->block_group, 0, | 906 | trans->block_group, 0, |
@@ -906,7 +913,6 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
906 | check_failed: | 913 | check_failed: |
907 | search_start = find_search_start(root, &block_group, | 914 | search_start = find_search_start(root, &block_group, |
908 | search_start, total_needed, data); | 915 | search_start, total_needed, data); |
909 | cached_search_start = search_start; | ||
910 | 916 | ||
911 | btrfs_init_path(path); | 917 | btrfs_init_path(path); |
912 | ins->objectid = search_start; | 918 | ins->objectid = search_start; |
@@ -958,27 +964,27 @@ check_failed: | |||
958 | start_found = 1; | 964 | start_found = 1; |
959 | goto check_pending; | 965 | goto check_pending; |
960 | } | 966 | } |
961 | ins->objectid = last_block > search_start ? | 967 | ins->objectid = last_byte > search_start ? |
962 | last_block : search_start; | 968 | last_byte : search_start; |
963 | ins->offset = search_end - ins->objectid; | 969 | ins->offset = search_end - ins->objectid; |
964 | goto check_pending; | 970 | goto check_pending; |
965 | } | 971 | } |
966 | btrfs_item_key_to_cpu(l, &key, slot); | 972 | btrfs_item_key_to_cpu(l, &key, slot); |
967 | 973 | ||
968 | if (key.objectid >= search_start && key.objectid > last_block && | 974 | if (key.objectid >= search_start && key.objectid > last_byte && |
969 | start_found) { | 975 | start_found) { |
970 | if (last_block < search_start) | 976 | if (last_byte < search_start) |
971 | last_block = search_start; | 977 | last_byte = search_start; |
972 | hole_size = key.objectid - last_block; | 978 | hole_size = key.objectid - last_byte; |
973 | if (hole_size >= num_blocks) { | 979 | if (hole_size >= num_bytes) { |
974 | ins->objectid = last_block; | 980 | ins->objectid = last_byte; |
975 | ins->offset = hole_size; | 981 | ins->offset = hole_size; |
976 | goto check_pending; | 982 | goto check_pending; |
977 | } | 983 | } |
978 | } | 984 | } |
979 | if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) { | 985 | if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) { |
980 | if (!start_found) { | 986 | if (!start_found) { |
981 | last_block = key.objectid; | 987 | last_byte = key.objectid; |
982 | start_found = 1; | 988 | start_found = 1; |
983 | } | 989 | } |
984 | goto next; | 990 | goto next; |
@@ -986,9 +992,9 @@ check_failed: | |||
986 | 992 | ||
987 | 993 | ||
988 | start_found = 1; | 994 | start_found = 1; |
989 | last_block = key.objectid + key.offset; | 995 | last_byte = key.objectid + key.offset; |
990 | 996 | ||
991 | if (!full_scan && last_block >= block_group->key.objectid + | 997 | if (!full_scan && last_byte >= block_group->key.objectid + |
992 | block_group->key.offset) { | 998 | block_group->key.offset) { |
993 | btrfs_release_path(root, path); | 999 | btrfs_release_path(root, path); |
994 | search_start = block_group->key.objectid + | 1000 | search_start = block_group->key.objectid + |
@@ -1006,20 +1012,20 @@ check_pending: | |||
1006 | btrfs_release_path(root, path); | 1012 | btrfs_release_path(root, path); |
1007 | BUG_ON(ins->objectid < search_start); | 1013 | BUG_ON(ins->objectid < search_start); |
1008 | 1014 | ||
1009 | if (ins->objectid + num_blocks >= search_end) | 1015 | if (ins->objectid + num_bytes >= search_end) |
1010 | goto enospc; | 1016 | goto enospc; |
1011 | 1017 | ||
1012 | if (test_range_bit(&info->extent_ins, ins->objectid, | 1018 | if (test_range_bit(&info->extent_ins, ins->objectid, |
1013 | ins->objectid + num_blocks -1, EXTENT_LOCKED, 0)) { | 1019 | ins->objectid + num_bytes -1, EXTENT_LOCKED, 0)) { |
1014 | search_start = ins->objectid + num_blocks; | 1020 | search_start = ins->objectid + num_bytes; |
1015 | goto new_group; | 1021 | goto new_group; |
1016 | } | 1022 | } |
1017 | if (test_range_bit(&info->pinned_extents, ins->objectid, | 1023 | if (test_range_bit(&info->pinned_extents, ins->objectid, |
1018 | ins->objectid + num_blocks -1, EXTENT_DIRTY, 0)) { | 1024 | ins->objectid + num_bytes -1, EXTENT_DIRTY, 0)) { |
1019 | search_start = ins->objectid + num_blocks; | 1025 | search_start = ins->objectid + num_bytes; |
1020 | goto new_group; | 1026 | goto new_group; |
1021 | } | 1027 | } |
1022 | if (exclude_nr > 0 && (ins->objectid + num_blocks > exclude_start && | 1028 | if (exclude_nr > 0 && (ins->objectid + num_bytes > exclude_start && |
1023 | ins->objectid < exclude_start + exclude_nr)) { | 1029 | ins->objectid < exclude_start + exclude_nr)) { |
1024 | search_start = exclude_start + exclude_nr; | 1030 | search_start = exclude_start + exclude_nr; |
1025 | goto new_group; | 1031 | goto new_group; |
@@ -1029,12 +1035,12 @@ check_pending: | |||
1029 | if (block_group) | 1035 | if (block_group) |
1030 | trans->block_group = block_group; | 1036 | trans->block_group = block_group; |
1031 | } | 1037 | } |
1032 | ins->offset = num_blocks; | 1038 | ins->offset = num_bytes; |
1033 | btrfs_free_path(path); | 1039 | btrfs_free_path(path); |
1034 | return 0; | 1040 | return 0; |
1035 | 1041 | ||
1036 | new_group: | 1042 | new_group: |
1037 | if (search_start + num_blocks >= search_end) { | 1043 | if (search_start + num_bytes >= search_end) { |
1038 | enospc: | 1044 | enospc: |
1039 | search_start = orig_search_start; | 1045 | search_start = orig_search_start; |
1040 | if (full_scan) { | 1046 | if (full_scan) { |
@@ -1069,12 +1075,12 @@ error: | |||
1069 | */ | 1075 | */ |
1070 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | 1076 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
1071 | struct btrfs_root *root, u64 owner, | 1077 | struct btrfs_root *root, u64 owner, |
1072 | u64 num_blocks, u64 empty_size, u64 hint_block, | 1078 | u64 num_bytes, u64 empty_size, u64 hint_byte, |
1073 | u64 search_end, struct btrfs_key *ins, int data) | 1079 | u64 search_end, struct btrfs_key *ins, int data) |
1074 | { | 1080 | { |
1075 | int ret; | 1081 | int ret; |
1076 | int pending_ret; | 1082 | int pending_ret; |
1077 | u64 super_blocks_used, root_blocks_used; | 1083 | u64 super_used, root_used; |
1078 | u64 search_start = 0; | 1084 | u64 search_start = 0; |
1079 | struct btrfs_fs_info *info = root->fs_info; | 1085 | struct btrfs_fs_info *info = root->fs_info; |
1080 | struct btrfs_root *extent_root = info->extent_root; | 1086 | struct btrfs_root *extent_root = info->extent_root; |
@@ -1083,9 +1089,9 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
1083 | btrfs_set_stack_extent_refs(&extent_item, 1); | 1089 | btrfs_set_stack_extent_refs(&extent_item, 1); |
1084 | btrfs_set_stack_extent_owner(&extent_item, owner); | 1090 | btrfs_set_stack_extent_owner(&extent_item, owner); |
1085 | 1091 | ||
1086 | WARN_ON(num_blocks < 1); | 1092 | WARN_ON(num_bytes < root->sectorsize); |
1087 | ret = find_free_extent(trans, root, num_blocks, empty_size, | 1093 | ret = find_free_extent(trans, root, num_bytes, empty_size, |
1088 | search_start, search_end, hint_block, ins, | 1094 | search_start, search_end, hint_byte, ins, |
1089 | trans->alloc_exclude_start, | 1095 | trans->alloc_exclude_start, |
1090 | trans->alloc_exclude_nr, data); | 1096 | trans->alloc_exclude_nr, data); |
1091 | BUG_ON(ret); | 1097 | BUG_ON(ret); |
@@ -1093,21 +1099,18 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
1093 | return ret; | 1099 | return ret; |
1094 | 1100 | ||
1095 | /* block accounting for super block */ | 1101 | /* block accounting for super block */ |
1096 | super_blocks_used = btrfs_super_blocks_used(&info->super_copy); | 1102 | super_used = btrfs_super_bytes_used(&info->super_copy); |
1097 | btrfs_set_super_blocks_used(&info->super_copy, super_blocks_used + | 1103 | btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes); |
1098 | num_blocks); | ||
1099 | 1104 | ||
1100 | /* block accounting for root item */ | 1105 | /* block accounting for root item */ |
1101 | root_blocks_used = btrfs_root_used(&root->root_item); | 1106 | root_used = btrfs_root_used(&root->root_item); |
1102 | btrfs_set_root_used(&root->root_item, root_blocks_used + | 1107 | btrfs_set_root_used(&root->root_item, root_used + num_bytes); |
1103 | num_blocks); | ||
1104 | 1108 | ||
1105 | clear_extent_dirty(&root->fs_info->free_space_cache, | 1109 | clear_extent_dirty(&root->fs_info->free_space_cache, |
1106 | ins->objectid, ins->objectid + ins->offset - 1, | 1110 | ins->objectid, ins->objectid + ins->offset - 1, |
1107 | GFP_NOFS); | 1111 | GFP_NOFS); |
1108 | 1112 | ||
1109 | if (root == extent_root) { | 1113 | if (root == extent_root) { |
1110 | BUG_ON(num_blocks != 1); | ||
1111 | set_extent_bits(&root->fs_info->extent_ins, ins->objectid, | 1114 | set_extent_bits(&root->fs_info->extent_ins, ins->objectid, |
1112 | ins->objectid + ins->offset - 1, | 1115 | ins->objectid + ins->offset - 1, |
1113 | EXTENT_LOCKED, GFP_NOFS); | 1116 | EXTENT_LOCKED, GFP_NOFS); |
@@ -1146,7 +1149,8 @@ update_block: | |||
1146 | * returns the tree buffer or NULL. | 1149 | * returns the tree buffer or NULL. |
1147 | */ | 1150 | */ |
1148 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 1151 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
1149 | struct btrfs_root *root, u64 hint, | 1152 | struct btrfs_root *root, |
1153 | u32 blocksize, u64 hint, | ||
1150 | u64 empty_size) | 1154 | u64 empty_size) |
1151 | { | 1155 | { |
1152 | struct btrfs_key ins; | 1156 | struct btrfs_key ins; |
@@ -1154,14 +1158,15 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
1154 | struct extent_buffer *buf; | 1158 | struct extent_buffer *buf; |
1155 | 1159 | ||
1156 | ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, | 1160 | ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, |
1157 | 1, empty_size, hint, (u64)-1, &ins, 0); | 1161 | blocksize, empty_size, hint, |
1162 | (u64)-1, &ins, 0); | ||
1158 | if (ret) { | 1163 | if (ret) { |
1159 | BUG_ON(ret > 0); | 1164 | BUG_ON(ret > 0); |
1160 | return ERR_PTR(ret); | 1165 | return ERR_PTR(ret); |
1161 | } | 1166 | } |
1162 | buf = btrfs_find_create_tree_block(root, ins.objectid); | 1167 | buf = btrfs_find_create_tree_block(root, ins.objectid, blocksize); |
1163 | if (!buf) { | 1168 | if (!buf) { |
1164 | btrfs_free_extent(trans, root, ins.objectid, 1, 0); | 1169 | btrfs_free_extent(trans, root, ins.objectid, blocksize, 0); |
1165 | return ERR_PTR(-ENOMEM); | 1170 | return ERR_PTR(-ENOMEM); |
1166 | } | 1171 | } |
1167 | btrfs_set_buffer_uptodate(buf); | 1172 | btrfs_set_buffer_uptodate(buf); |
@@ -1191,7 +1196,7 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
1191 | BUG_ON(!btrfs_is_leaf(leaf)); | 1196 | BUG_ON(!btrfs_is_leaf(leaf)); |
1192 | nritems = btrfs_header_nritems(leaf); | 1197 | nritems = btrfs_header_nritems(leaf); |
1193 | for (i = 0; i < nritems; i++) { | 1198 | for (i = 0; i < nritems; i++) { |
1194 | u64 disk_blocknr; | 1199 | u64 disk_bytenr; |
1195 | 1200 | ||
1196 | btrfs_item_key_to_cpu(leaf, &key, i); | 1201 | btrfs_item_key_to_cpu(leaf, &key, i); |
1197 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 1202 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
@@ -1204,11 +1209,11 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
1204 | * FIXME make sure to insert a trans record that | 1209 | * FIXME make sure to insert a trans record that |
1205 | * repeats the snapshot del on crash | 1210 | * repeats the snapshot del on crash |
1206 | */ | 1211 | */ |
1207 | disk_blocknr = btrfs_file_extent_disk_blocknr(leaf, fi); | 1212 | disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); |
1208 | if (disk_blocknr == 0) | 1213 | if (disk_bytenr == 0) |
1209 | continue; | 1214 | continue; |
1210 | ret = btrfs_free_extent(trans, root, disk_blocknr, | 1215 | ret = btrfs_free_extent(trans, root, disk_bytenr, |
1211 | btrfs_file_extent_disk_num_blocks(leaf, fi), 0); | 1216 | btrfs_file_extent_disk_num_bytes(leaf, fi), 0); |
1212 | BUG_ON(ret); | 1217 | BUG_ON(ret); |
1213 | } | 1218 | } |
1214 | return 0; | 1219 | return 0; |
@@ -1219,19 +1224,23 @@ static void reada_walk_down(struct btrfs_root *root, | |||
1219 | { | 1224 | { |
1220 | int i; | 1225 | int i; |
1221 | u32 nritems; | 1226 | u32 nritems; |
1222 | u64 blocknr; | 1227 | u64 bytenr; |
1223 | int ret; | 1228 | int ret; |
1224 | u32 refs; | 1229 | u32 refs; |
1230 | int level; | ||
1231 | u32 blocksize; | ||
1225 | 1232 | ||
1226 | nritems = btrfs_header_nritems(node); | 1233 | nritems = btrfs_header_nritems(node); |
1234 | level = btrfs_header_level(node); | ||
1227 | for (i = 0; i < nritems; i++) { | 1235 | for (i = 0; i < nritems; i++) { |
1228 | blocknr = btrfs_node_blockptr(node, i); | 1236 | bytenr = btrfs_node_blockptr(node, i); |
1229 | ret = lookup_extent_ref(NULL, root, blocknr, 1, &refs); | 1237 | blocksize = btrfs_level_size(root, level - 1); |
1238 | ret = lookup_extent_ref(NULL, root, bytenr, blocksize, &refs); | ||
1230 | BUG_ON(ret); | 1239 | BUG_ON(ret); |
1231 | if (refs != 1) | 1240 | if (refs != 1) |
1232 | continue; | 1241 | continue; |
1233 | mutex_unlock(&root->fs_info->fs_mutex); | 1242 | mutex_unlock(&root->fs_info->fs_mutex); |
1234 | ret = readahead_tree_block(root, blocknr); | 1243 | ret = readahead_tree_block(root, bytenr, blocksize); |
1235 | cond_resched(); | 1244 | cond_resched(); |
1236 | mutex_lock(&root->fs_info->fs_mutex); | 1245 | mutex_lock(&root->fs_info->fs_mutex); |
1237 | if (ret) | 1246 | if (ret) |
@@ -1248,15 +1257,16 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1248 | { | 1257 | { |
1249 | struct extent_buffer *next; | 1258 | struct extent_buffer *next; |
1250 | struct extent_buffer *cur; | 1259 | struct extent_buffer *cur; |
1251 | u64 blocknr; | 1260 | u64 bytenr; |
1261 | u32 blocksize; | ||
1252 | int ret; | 1262 | int ret; |
1253 | u32 refs; | 1263 | u32 refs; |
1254 | 1264 | ||
1255 | WARN_ON(*level < 0); | 1265 | WARN_ON(*level < 0); |
1256 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 1266 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
1257 | ret = lookup_extent_ref(trans, root, | 1267 | ret = lookup_extent_ref(trans, root, |
1258 | extent_buffer_blocknr(path->nodes[*level]), | 1268 | path->nodes[*level]->start, |
1259 | 1, &refs); | 1269 | path->nodes[*level]->len, &refs); |
1260 | BUG_ON(ret); | 1270 | BUG_ON(ret); |
1261 | if (refs > 1) | 1271 | if (refs > 1) |
1262 | goto out; | 1272 | goto out; |
@@ -1283,30 +1293,33 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1283 | BUG_ON(ret); | 1293 | BUG_ON(ret); |
1284 | break; | 1294 | break; |
1285 | } | 1295 | } |
1286 | blocknr = btrfs_node_blockptr(cur, path->slots[*level]); | 1296 | bytenr = btrfs_node_blockptr(cur, path->slots[*level]); |
1287 | ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); | 1297 | blocksize = btrfs_level_size(root, *level - 1); |
1298 | ret = lookup_extent_ref(trans, root, bytenr, blocksize, &refs); | ||
1288 | BUG_ON(ret); | 1299 | BUG_ON(ret); |
1289 | if (refs != 1) { | 1300 | if (refs != 1) { |
1290 | path->slots[*level]++; | 1301 | path->slots[*level]++; |
1291 | ret = btrfs_free_extent(trans, root, blocknr, 1, 1); | 1302 | ret = btrfs_free_extent(trans, root, bytenr, |
1303 | blocksize, 1); | ||
1292 | BUG_ON(ret); | 1304 | BUG_ON(ret); |
1293 | continue; | 1305 | continue; |
1294 | } | 1306 | } |
1295 | next = btrfs_find_tree_block(root, blocknr); | 1307 | next = btrfs_find_tree_block(root, bytenr, blocksize); |
1296 | if (!next || !btrfs_buffer_uptodate(next)) { | 1308 | if (!next || !btrfs_buffer_uptodate(next)) { |
1297 | free_extent_buffer(next); | 1309 | free_extent_buffer(next); |
1298 | mutex_unlock(&root->fs_info->fs_mutex); | 1310 | mutex_unlock(&root->fs_info->fs_mutex); |
1299 | next = read_tree_block(root, blocknr); | 1311 | next = read_tree_block(root, bytenr, blocksize); |
1300 | mutex_lock(&root->fs_info->fs_mutex); | 1312 | mutex_lock(&root->fs_info->fs_mutex); |
1301 | 1313 | ||
1302 | /* we dropped the lock, check one more time */ | 1314 | /* we dropped the lock, check one more time */ |
1303 | ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); | 1315 | ret = lookup_extent_ref(trans, root, bytenr, |
1316 | blocksize, &refs); | ||
1304 | BUG_ON(ret); | 1317 | BUG_ON(ret); |
1305 | if (refs != 1) { | 1318 | if (refs != 1) { |
1306 | path->slots[*level]++; | 1319 | path->slots[*level]++; |
1307 | free_extent_buffer(next); | 1320 | free_extent_buffer(next); |
1308 | ret = btrfs_free_extent(trans, root, | 1321 | ret = btrfs_free_extent(trans, root, |
1309 | blocknr, 1, 1); | 1322 | bytenr, blocksize, 1); |
1310 | BUG_ON(ret); | 1323 | BUG_ON(ret); |
1311 | continue; | 1324 | continue; |
1312 | } | 1325 | } |
@@ -1321,8 +1334,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1321 | out: | 1334 | out: |
1322 | WARN_ON(*level < 0); | 1335 | WARN_ON(*level < 0); |
1323 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 1336 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
1324 | ret = btrfs_free_extent(trans, root, | 1337 | ret = btrfs_free_extent(trans, root, path->nodes[*level]->start, |
1325 | extent_buffer_blocknr(path->nodes[*level]), 1, 1); | 1338 | path->nodes[*level]->len, 1); |
1326 | free_extent_buffer(path->nodes[*level]); | 1339 | free_extent_buffer(path->nodes[*level]); |
1327 | path->nodes[*level] = NULL; | 1340 | path->nodes[*level] = NULL; |
1328 | *level += 1; | 1341 | *level += 1; |
@@ -1359,8 +1372,8 @@ static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1359 | return 0; | 1372 | return 0; |
1360 | } else { | 1373 | } else { |
1361 | ret = btrfs_free_extent(trans, root, | 1374 | ret = btrfs_free_extent(trans, root, |
1362 | extent_buffer_blocknr(path->nodes[*level]), | 1375 | path->nodes[*level]->start, |
1363 | 1, 1); | 1376 | path->nodes[*level]->len, 1); |
1364 | BUG_ON(ret); | 1377 | BUG_ON(ret); |
1365 | free_extent_buffer(path->nodes[*level]); | 1378 | free_extent_buffer(path->nodes[*level]); |
1366 | path->nodes[*level] = NULL; | 1379 | path->nodes[*level] = NULL; |
@@ -1476,16 +1489,12 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1476 | struct btrfs_key key; | 1489 | struct btrfs_key key; |
1477 | struct btrfs_key found_key; | 1490 | struct btrfs_key found_key; |
1478 | struct extent_buffer *leaf; | 1491 | struct extent_buffer *leaf; |
1479 | u64 group_size_blocks; | ||
1480 | 1492 | ||
1481 | block_group_cache = &info->block_group_cache; | 1493 | block_group_cache = &info->block_group_cache; |
1482 | 1494 | ||
1483 | group_size_blocks = BTRFS_BLOCK_GROUP_SIZE >> | ||
1484 | info->sb->s_blocksize_bits; | ||
1485 | |||
1486 | root = info->extent_root; | 1495 | root = info->extent_root; |
1487 | key.objectid = 0; | 1496 | key.objectid = 0; |
1488 | key.offset = group_size_blocks; | 1497 | key.offset = BTRFS_BLOCK_GROUP_SIZE; |
1489 | btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); | 1498 | btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); |
1490 | 1499 | ||
1491 | path = btrfs_alloc_path(); | 1500 | path = btrfs_alloc_path(); |
@@ -1532,7 +1541,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1532 | (u64)cache); | 1541 | (u64)cache); |
1533 | 1542 | ||
1534 | if (key.objectid >= | 1543 | if (key.objectid >= |
1535 | btrfs_super_total_blocks(&info->super_copy)) | 1544 | btrfs_super_total_bytes(&info->super_copy)) |
1536 | break; | 1545 | break; |
1537 | } | 1546 | } |
1538 | 1547 | ||
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index e081558d52ff..f658703c42e6 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -1963,18 +1963,27 @@ static inline struct page *extent_buffer_page(struct extent_buffer *eb, int i) | |||
1963 | struct page *p; | 1963 | struct page *p; |
1964 | if (i == 0) | 1964 | if (i == 0) |
1965 | return eb->first_page; | 1965 | return eb->first_page; |
1966 | |||
1966 | i += eb->start >> PAGE_CACHE_SHIFT; | 1967 | i += eb->start >> PAGE_CACHE_SHIFT; |
1968 | if (eb->last_page && eb->last_page->index == i) | ||
1969 | return eb->last_page; | ||
1970 | |||
1967 | p = find_get_page(eb->first_page->mapping, i); | 1971 | p = find_get_page(eb->first_page->mapping, i); |
1968 | page_cache_release(p); | 1972 | page_cache_release(p); |
1973 | eb->last_page = p; | ||
1969 | return p; | 1974 | return p; |
1970 | } | 1975 | } |
1971 | 1976 | ||
1977 | static inline unsigned long num_extent_pages(u64 start, u64 len) | ||
1978 | { | ||
1979 | return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) - | ||
1980 | (start >> PAGE_CACHE_SHIFT); | ||
1981 | } | ||
1972 | struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | 1982 | struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, |
1973 | u64 start, unsigned long len, | 1983 | u64 start, unsigned long len, |
1974 | gfp_t mask) | 1984 | gfp_t mask) |
1975 | { | 1985 | { |
1976 | unsigned long num_pages = ((start + len - 1) >> PAGE_CACHE_SHIFT) - | 1986 | unsigned long num_pages = num_extent_pages(start, len); |
1977 | (start >> PAGE_CACHE_SHIFT) + 1; | ||
1978 | unsigned long i; | 1987 | unsigned long i; |
1979 | unsigned long index = start >> PAGE_CACHE_SHIFT; | 1988 | unsigned long index = start >> PAGE_CACHE_SHIFT; |
1980 | struct extent_buffer *eb; | 1989 | struct extent_buffer *eb; |
@@ -1986,7 +1995,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | |||
1986 | if (!eb || IS_ERR(eb)) | 1995 | if (!eb || IS_ERR(eb)) |
1987 | return NULL; | 1996 | return NULL; |
1988 | 1997 | ||
1989 | eb->alloc_addr = __builtin_return_address(0); | 1998 | eb->alloc_addr = (unsigned long)__builtin_return_address(0); |
1990 | eb->start = start; | 1999 | eb->start = start; |
1991 | eb->len = len; | 2000 | eb->len = len; |
1992 | atomic_set(&eb->refs, 1); | 2001 | atomic_set(&eb->refs, 1); |
@@ -1994,6 +2003,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | |||
1994 | for (i = 0; i < num_pages; i++, index++) { | 2003 | for (i = 0; i < num_pages; i++, index++) { |
1995 | p = find_or_create_page(mapping, index, mask | __GFP_HIGHMEM); | 2004 | p = find_or_create_page(mapping, index, mask | __GFP_HIGHMEM); |
1996 | if (!p) { | 2005 | if (!p) { |
2006 | WARN_ON(1); | ||
1997 | /* make sure the free only frees the pages we've | 2007 | /* make sure the free only frees the pages we've |
1998 | * grabbed a reference on | 2008 | * grabbed a reference on |
1999 | */ | 2009 | */ |
@@ -2021,8 +2031,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, | |||
2021 | u64 start, unsigned long len, | 2031 | u64 start, unsigned long len, |
2022 | gfp_t mask) | 2032 | gfp_t mask) |
2023 | { | 2033 | { |
2024 | unsigned long num_pages = ((start + len - 1) >> PAGE_CACHE_SHIFT) - | 2034 | unsigned long num_pages = num_extent_pages(start, len); |
2025 | (start >> PAGE_CACHE_SHIFT) + 1; | ||
2026 | unsigned long i; | 2035 | unsigned long i; |
2027 | unsigned long index = start >> PAGE_CACHE_SHIFT; | 2036 | unsigned long index = start >> PAGE_CACHE_SHIFT; |
2028 | struct extent_buffer *eb; | 2037 | struct extent_buffer *eb; |
@@ -2033,7 +2042,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, | |||
2033 | if (!eb || IS_ERR(eb)) | 2042 | if (!eb || IS_ERR(eb)) |
2034 | return NULL; | 2043 | return NULL; |
2035 | 2044 | ||
2036 | eb->alloc_addr = __builtin_return_address(0); | 2045 | eb->alloc_addr = (unsigned long)__builtin_return_address(0); |
2037 | eb->start = start; | 2046 | eb->start = start; |
2038 | eb->len = len; | 2047 | eb->len = len; |
2039 | atomic_set(&eb->refs, 1); | 2048 | atomic_set(&eb->refs, 1); |
@@ -2070,8 +2079,7 @@ void free_extent_buffer(struct extent_buffer *eb) | |||
2070 | if (!atomic_dec_and_test(&eb->refs)) | 2079 | if (!atomic_dec_and_test(&eb->refs)) |
2071 | return; | 2080 | return; |
2072 | 2081 | ||
2073 | num_pages = ((eb->start + eb->len - 1) >> PAGE_CACHE_SHIFT) - | 2082 | num_pages = num_extent_pages(eb->start, eb->len); |
2074 | (eb->start >> PAGE_CACHE_SHIFT) + 1; | ||
2075 | 2083 | ||
2076 | if (eb->first_page) | 2084 | if (eb->first_page) |
2077 | page_cache_release(eb->first_page); | 2085 | page_cache_release(eb->first_page); |
@@ -2094,8 +2102,7 @@ int clear_extent_buffer_dirty(struct extent_map_tree *tree, | |||
2094 | u64 end = start + eb->len - 1; | 2102 | u64 end = start + eb->len - 1; |
2095 | 2103 | ||
2096 | set = clear_extent_dirty(tree, start, end, GFP_NOFS); | 2104 | set = clear_extent_dirty(tree, start, end, GFP_NOFS); |
2097 | num_pages = ((eb->start + eb->len - 1) >> PAGE_CACHE_SHIFT) - | 2105 | num_pages = num_extent_pages(eb->start, eb->len); |
2098 | (eb->start >> PAGE_CACHE_SHIFT) + 1; | ||
2099 | 2106 | ||
2100 | for (i = 0; i < num_pages; i++) { | 2107 | for (i = 0; i < num_pages; i++) { |
2101 | page = extent_buffer_page(eb, i); | 2108 | page = extent_buffer_page(eb, i); |
@@ -2145,8 +2152,7 @@ int set_extent_buffer_uptodate(struct extent_map_tree *tree, | |||
2145 | struct page *page; | 2152 | struct page *page; |
2146 | unsigned long num_pages; | 2153 | unsigned long num_pages; |
2147 | 2154 | ||
2148 | num_pages = ((eb->start + eb->len - 1) >> PAGE_CACHE_SHIFT) - | 2155 | num_pages = num_extent_pages(eb->start, eb->len); |
2149 | (eb->start >> PAGE_CACHE_SHIFT) + 1; | ||
2150 | 2156 | ||
2151 | set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, | 2157 | set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, |
2152 | GFP_NOFS); | 2158 | GFP_NOFS); |
@@ -2191,8 +2197,7 @@ int read_extent_buffer_pages(struct extent_map_tree *tree, | |||
2191 | return 0; | 2197 | return 0; |
2192 | } | 2198 | } |
2193 | 2199 | ||
2194 | num_pages = ((eb->start + eb->len - 1) >> PAGE_CACHE_SHIFT) - | 2200 | num_pages = num_extent_pages(eb->start, eb->len); |
2195 | (eb->start >> PAGE_CACHE_SHIFT) + 1; | ||
2196 | for (i = 0; i < num_pages; i++) { | 2201 | for (i = 0; i < num_pages; i++) { |
2197 | page = extent_buffer_page(eb, i); | 2202 | page = extent_buffer_page(eb, i); |
2198 | if (PageUptodate(page)) { | 2203 | if (PageUptodate(page)) { |
@@ -2267,14 +2272,14 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, | |||
2267 | } | 2272 | } |
2268 | EXPORT_SYMBOL(read_extent_buffer); | 2273 | EXPORT_SYMBOL(read_extent_buffer); |
2269 | 2274 | ||
2270 | int map_extent_buffer(struct extent_buffer *eb, unsigned long start, | 2275 | static int __map_extent_buffer(struct extent_buffer *eb, unsigned long start, |
2271 | unsigned long min_len, | 2276 | unsigned long min_len, char **token, char **map, |
2272 | char **token, char **map, | 2277 | unsigned long *map_start, |
2273 | unsigned long *map_start, | 2278 | unsigned long *map_len, int km) |
2274 | unsigned long *map_len, int km) | ||
2275 | { | 2279 | { |
2276 | size_t offset = start & (PAGE_CACHE_SIZE - 1); | 2280 | size_t offset = start & (PAGE_CACHE_SIZE - 1); |
2277 | char *kaddr; | 2281 | char *kaddr; |
2282 | struct page *p; | ||
2278 | size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); | 2283 | size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); |
2279 | unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; | 2284 | unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; |
2280 | unsigned long end_i = (start_offset + start + min_len) >> | 2285 | unsigned long end_i = (start_offset + start + min_len) >> |
@@ -2283,21 +2288,59 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start, | |||
2283 | if (i != end_i) | 2288 | if (i != end_i) |
2284 | return -EINVAL; | 2289 | return -EINVAL; |
2285 | 2290 | ||
2286 | WARN_ON(start > eb->len); | 2291 | if (start >= eb->len) { |
2292 | printk("bad start in map eb start %Lu len %lu caller start %lu min %lu\n", eb->start, eb->len, start, min_len); | ||
2293 | WARN_ON(1); | ||
2294 | } | ||
2287 | 2295 | ||
2288 | if (i == 0) { | 2296 | if (i == 0) { |
2289 | offset = start_offset; | 2297 | offset = start_offset; |
2290 | *map_start = 0; | 2298 | *map_start = 0; |
2291 | } else { | 2299 | } else { |
2300 | offset = 0; | ||
2292 | *map_start = (i << PAGE_CACHE_SHIFT) - start_offset; | 2301 | *map_start = (i << PAGE_CACHE_SHIFT) - start_offset; |
2293 | } | 2302 | } |
2294 | 2303 | ||
2295 | kaddr = kmap_atomic(extent_buffer_page(eb, i), km); | 2304 | p = extent_buffer_page(eb, i); |
2305 | WARN_ON(!PageUptodate(p)); | ||
2306 | kaddr = kmap_atomic(p, km); | ||
2296 | *token = kaddr; | 2307 | *token = kaddr; |
2297 | *map = kaddr + offset; | 2308 | *map = kaddr + offset; |
2298 | *map_len = PAGE_CACHE_SIZE - offset; | 2309 | *map_len = PAGE_CACHE_SIZE - offset; |
2299 | return 0; | 2310 | return 0; |
2300 | } | 2311 | } |
2312 | |||
2313 | int map_extent_buffer(struct extent_buffer *eb, unsigned long start, | ||
2314 | unsigned long min_len, | ||
2315 | char **token, char **map, | ||
2316 | unsigned long *map_start, | ||
2317 | unsigned long *map_len, int km) | ||
2318 | { | ||
2319 | int err; | ||
2320 | int save = 0; | ||
2321 | if (eb->map_token) { | ||
2322 | if (start >= eb->map_start && | ||
2323 | start + min_len <= eb->map_start + eb->map_len) { | ||
2324 | *token = eb->map_token; | ||
2325 | *map = eb->kaddr; | ||
2326 | *map_start = eb->map_start; | ||
2327 | *map_len = eb->map_len; | ||
2328 | return 0; | ||
2329 | } | ||
2330 | unmap_extent_buffer(eb, eb->map_token, km); | ||
2331 | eb->map_token = NULL; | ||
2332 | save = 1; | ||
2333 | } | ||
2334 | err = __map_extent_buffer(eb, start, min_len, token, map, | ||
2335 | map_start, map_len, km); | ||
2336 | if (!err && save) { | ||
2337 | eb->map_token = *token; | ||
2338 | eb->kaddr = *map; | ||
2339 | eb->map_start = *map_start; | ||
2340 | eb->map_len = *map_len; | ||
2341 | } | ||
2342 | return err; | ||
2343 | } | ||
2301 | EXPORT_SYMBOL(map_extent_buffer); | 2344 | EXPORT_SYMBOL(map_extent_buffer); |
2302 | 2345 | ||
2303 | void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km) | 2346 | void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km) |
@@ -2574,7 +2617,6 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | |||
2574 | ((unsigned long)PAGE_CACHE_SIZE - 1); | 2617 | ((unsigned long)PAGE_CACHE_SIZE - 1); |
2575 | src_off_in_page = src_end & | 2618 | src_off_in_page = src_end & |
2576 | ((unsigned long)PAGE_CACHE_SIZE - 1); | 2619 | ((unsigned long)PAGE_CACHE_SIZE - 1); |
2577 | |||
2578 | if (src_i == 0) | 2620 | if (src_i == 0) |
2579 | src_off_in_page += start_offset; | 2621 | src_off_in_page += start_offset; |
2580 | if (dst_i == 0) | 2622 | if (dst_i == 0) |
@@ -2582,14 +2624,13 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | |||
2582 | 2624 | ||
2583 | cur = min(len, src_off_in_page + 1); | 2625 | cur = min(len, src_off_in_page + 1); |
2584 | cur = min(cur, dst_off_in_page + 1); | 2626 | cur = min(cur, dst_off_in_page + 1); |
2585 | |||
2586 | move_pages(extent_buffer_page(dst, dst_i), | 2627 | move_pages(extent_buffer_page(dst, dst_i), |
2587 | extent_buffer_page(dst, src_i), | 2628 | extent_buffer_page(dst, src_i), |
2588 | dst_off_in_page - cur + 1, | 2629 | dst_off_in_page - cur + 1, |
2589 | src_off_in_page - cur + 1, cur); | 2630 | src_off_in_page - cur + 1, cur); |
2590 | 2631 | ||
2591 | dst_end -= cur - 1; | 2632 | dst_end -= cur; |
2592 | src_end -= cur - 1; | 2633 | src_end -= cur; |
2593 | len -= cur; | 2634 | len -= cur; |
2594 | } | 2635 | } |
2595 | } | 2636 | } |
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 75dc600dc0f9..4ef8bdd68348 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h | |||
@@ -70,7 +70,12 @@ struct extent_buffer { | |||
70 | struct list_head list; | 70 | struct list_head list; |
71 | struct list_head leak_list; | 71 | struct list_head leak_list; |
72 | struct page *first_page; | 72 | struct page *first_page; |
73 | struct page *last_page; | ||
73 | unsigned long alloc_addr; | 74 | unsigned long alloc_addr; |
75 | char *map_token; | ||
76 | char *kaddr; | ||
77 | unsigned long map_start; | ||
78 | unsigned long map_len; | ||
74 | }; | 79 | }; |
75 | 80 | ||
76 | typedef struct extent_map *(get_extent_t)(struct inode *inode, | 81 | typedef struct extent_map *(get_extent_t)(struct inode *inode, |
@@ -147,11 +152,6 @@ static inline void extent_buffer_get(struct extent_buffer *eb) | |||
147 | atomic_inc(&eb->refs); | 152 | atomic_inc(&eb->refs); |
148 | } | 153 | } |
149 | 154 | ||
150 | static inline u64 extent_buffer_blocknr(struct extent_buffer *eb) | ||
151 | { | ||
152 | return eb->start / 4096; | ||
153 | } | ||
154 | |||
155 | int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, | 155 | int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, |
156 | unsigned long start, | 156 | unsigned long start, |
157 | unsigned long len); | 157 | unsigned long len); |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 226f6d028c3f..9a65e97a4e28 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -27,8 +27,8 @@ | |||
27 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | 27 | int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, |
28 | struct btrfs_root *root, | 28 | struct btrfs_root *root, |
29 | u64 objectid, u64 pos, | 29 | u64 objectid, u64 pos, |
30 | u64 offset, u64 disk_num_blocks, | 30 | u64 offset, u64 disk_num_bytes, |
31 | u64 num_blocks) | 31 | u64 num_bytes) |
32 | { | 32 | { |
33 | int ret = 0; | 33 | int ret = 0; |
34 | struct btrfs_file_extent_item *item; | 34 | struct btrfs_file_extent_item *item; |
@@ -50,10 +50,10 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | |||
50 | leaf = path->nodes[0]; | 50 | leaf = path->nodes[0]; |
51 | item = btrfs_item_ptr(leaf, path->slots[0], | 51 | item = btrfs_item_ptr(leaf, path->slots[0], |
52 | struct btrfs_file_extent_item); | 52 | struct btrfs_file_extent_item); |
53 | btrfs_set_file_extent_disk_blocknr(leaf, item, offset); | 53 | btrfs_set_file_extent_disk_bytenr(leaf, item, offset); |
54 | btrfs_set_file_extent_disk_num_blocks(leaf, item, disk_num_blocks); | 54 | btrfs_set_file_extent_disk_num_bytes(leaf, item, disk_num_bytes); |
55 | btrfs_set_file_extent_offset(leaf, item, 0); | 55 | btrfs_set_file_extent_offset(leaf, item, 0); |
56 | btrfs_set_file_extent_num_blocks(leaf, item, num_blocks); | 56 | btrfs_set_file_extent_num_bytes(leaf, item, num_bytes); |
57 | btrfs_set_file_extent_generation(leaf, item, trans->transid); | 57 | btrfs_set_file_extent_generation(leaf, item, trans->transid); |
58 | btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG); | 58 | btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG); |
59 | btrfs_mark_buffer_dirty(leaf); | 59 | btrfs_mark_buffer_dirty(leaf); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 1734ca695555..844d8807e44a 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -120,9 +120,9 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, | |||
120 | btrfs_set_file_extent_type(leaf, ei, BTRFS_FILE_EXTENT_INLINE); | 120 | btrfs_set_file_extent_type(leaf, ei, BTRFS_FILE_EXTENT_INLINE); |
121 | ptr = btrfs_file_extent_inline_start(ei); | 121 | ptr = btrfs_file_extent_inline_start(ei); |
122 | 122 | ||
123 | kaddr = kmap_atomic(page, KM_USER0); | 123 | kaddr = kmap_atomic(page, KM_USER1); |
124 | write_extent_buffer(leaf, kaddr + page_offset, ptr, size); | 124 | write_extent_buffer(leaf, kaddr + page_offset, ptr, size); |
125 | kunmap_atomic(kaddr, KM_USER0); | 125 | kunmap_atomic(kaddr, KM_USER1); |
126 | btrfs_mark_buffer_dirty(leaf); | 126 | btrfs_mark_buffer_dirty(leaf); |
127 | fail: | 127 | fail: |
128 | btrfs_free_path(path); | 128 | btrfs_free_path(path); |
@@ -142,11 +142,12 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
142 | struct inode *inode = file->f_path.dentry->d_inode; | 142 | struct inode *inode = file->f_path.dentry->d_inode; |
143 | struct extent_map *em; | 143 | struct extent_map *em; |
144 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 144 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
145 | u64 hint_block; | 145 | u64 hint_byte; |
146 | u64 num_blocks; | 146 | u64 num_bytes; |
147 | u64 start_pos; | 147 | u64 start_pos; |
148 | u64 end_of_last_block; | 148 | u64 end_of_last_block; |
149 | u64 end_pos = pos + write_bytes; | 149 | u64 end_pos = pos + write_bytes; |
150 | u32 inline_size; | ||
150 | loff_t isize = i_size_read(inode); | 151 | loff_t isize = i_size_read(inode); |
151 | 152 | ||
152 | em = alloc_extent_map(GFP_NOFS); | 153 | em = alloc_extent_map(GFP_NOFS); |
@@ -156,11 +157,12 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
156 | em->bdev = inode->i_sb->s_bdev; | 157 | em->bdev = inode->i_sb->s_bdev; |
157 | 158 | ||
158 | start_pos = pos & ~((u64)root->sectorsize - 1); | 159 | start_pos = pos & ~((u64)root->sectorsize - 1); |
159 | num_blocks = (write_bytes + pos - start_pos + root->sectorsize - 1) >> | 160 | num_bytes = (write_bytes + pos - start_pos + |
160 | inode->i_blkbits; | 161 | root->sectorsize - 1) & ~((u64)root->sectorsize - 1); |
161 | 162 | ||
162 | down_read(&BTRFS_I(inode)->root->snap_sem); | 163 | down_read(&BTRFS_I(inode)->root->snap_sem); |
163 | end_of_last_block = start_pos + (num_blocks << inode->i_blkbits) - 1; | 164 | end_of_last_block = start_pos + num_bytes - 1; |
165 | |||
164 | lock_extent(em_tree, start_pos, end_of_last_block, GFP_NOFS); | 166 | lock_extent(em_tree, start_pos, end_of_last_block, GFP_NOFS); |
165 | mutex_lock(&root->fs_info->fs_mutex); | 167 | mutex_lock(&root->fs_info->fs_mutex); |
166 | trans = btrfs_start_transaction(root, 1); | 168 | trans = btrfs_start_transaction(root, 1); |
@@ -169,8 +171,8 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
169 | goto out_unlock; | 171 | goto out_unlock; |
170 | } | 172 | } |
171 | btrfs_set_trans_block_group(trans, inode); | 173 | btrfs_set_trans_block_group(trans, inode); |
172 | inode->i_blocks += num_blocks << 3; | 174 | inode->i_blocks += num_bytes >> 9; |
173 | hint_block = 0; | 175 | hint_byte = 0; |
174 | 176 | ||
175 | if ((end_of_last_block & 4095) == 0) { | 177 | if ((end_of_last_block & 4095) == 0) { |
176 | printk("strange end of last %Lu %zu %Lu\n", start_pos, write_bytes, end_of_last_block); | 178 | printk("strange end of last %Lu %zu %Lu\n", start_pos, write_bytes, end_of_last_block); |
@@ -191,11 +193,10 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
191 | err = btrfs_drop_extents(trans, root, inode, | 193 | err = btrfs_drop_extents(trans, root, inode, |
192 | last_pos_in_file, | 194 | last_pos_in_file, |
193 | last_pos_in_file + hole_size, | 195 | last_pos_in_file + hole_size, |
194 | &hint_block); | 196 | &hint_byte); |
195 | if (err) | 197 | if (err) |
196 | goto failed; | 198 | goto failed; |
197 | 199 | ||
198 | hole_size >>= inode->i_blkbits; | ||
199 | err = btrfs_insert_file_extent(trans, root, | 200 | err = btrfs_insert_file_extent(trans, root, |
200 | inode->i_ino, | 201 | inode->i_ino, |
201 | last_pos_in_file, | 202 | last_pos_in_file, |
@@ -209,8 +210,10 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
209 | * either allocate an extent for the new bytes or setup the key | 210 | * either allocate an extent for the new bytes or setup the key |
210 | * to show we are doing inline data in the extent | 211 | * to show we are doing inline data in the extent |
211 | */ | 212 | */ |
213 | inline_size = end_pos - start_pos; | ||
212 | if (isize >= PAGE_CACHE_SIZE || pos + write_bytes < inode->i_size || | 214 | if (isize >= PAGE_CACHE_SIZE || pos + write_bytes < inode->i_size || |
213 | pos + write_bytes - start_pos > BTRFS_MAX_INLINE_DATA_SIZE(root)) { | 215 | inline_size >= BTRFS_MAX_INLINE_DATA_SIZE(root) || |
216 | inline_size >= PAGE_CACHE_SIZE) { | ||
214 | u64 last_end; | 217 | u64 last_end; |
215 | for (i = 0; i < num_pages; i++) { | 218 | for (i = 0; i < num_pages; i++) { |
216 | struct page *p = pages[i]; | 219 | struct page *p = pages[i]; |
@@ -224,10 +227,9 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
224 | } else { | 227 | } else { |
225 | struct page *p = pages[0]; | 228 | struct page *p = pages[0]; |
226 | /* step one, delete the existing extents in this range */ | 229 | /* step one, delete the existing extents in this range */ |
227 | /* FIXME blocksize != pagesize */ | ||
228 | err = btrfs_drop_extents(trans, root, inode, start_pos, | 230 | err = btrfs_drop_extents(trans, root, inode, start_pos, |
229 | (pos + write_bytes + root->sectorsize -1) & | 231 | (pos + write_bytes + root->sectorsize -1) & |
230 | ~((u64)root->sectorsize - 1), &hint_block); | 232 | ~((u64)root->sectorsize - 1), &hint_byte); |
231 | if (err) | 233 | if (err) |
232 | goto failed; | 234 | goto failed; |
233 | 235 | ||
@@ -283,7 +285,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end) | |||
283 | */ | 285 | */ |
284 | int btrfs_drop_extents(struct btrfs_trans_handle *trans, | 286 | int btrfs_drop_extents(struct btrfs_trans_handle *trans, |
285 | struct btrfs_root *root, struct inode *inode, | 287 | struct btrfs_root *root, struct inode *inode, |
286 | u64 start, u64 end, u64 *hint_block) | 288 | u64 start, u64 end, u64 *hint_byte) |
287 | { | 289 | { |
288 | int ret; | 290 | int ret; |
289 | struct btrfs_key key; | 291 | struct btrfs_key key; |
@@ -346,8 +348,7 @@ next_slot: | |||
346 | found_type = btrfs_file_extent_type(leaf, extent); | 348 | found_type = btrfs_file_extent_type(leaf, extent); |
347 | if (found_type == BTRFS_FILE_EXTENT_REG) { | 349 | if (found_type == BTRFS_FILE_EXTENT_REG) { |
348 | extent_end = key.offset + | 350 | extent_end = key.offset + |
349 | (btrfs_file_extent_num_blocks(leaf, extent) << | 351 | btrfs_file_extent_num_bytes(leaf, extent); |
350 | inode->i_blkbits); | ||
351 | found_extent = 1; | 352 | found_extent = 1; |
352 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { | 353 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { |
353 | struct btrfs_item *item; | 354 | struct btrfs_item *item; |
@@ -386,17 +387,17 @@ next_slot: | |||
386 | 387 | ||
387 | if (end < extent_end && end >= key.offset) { | 388 | if (end < extent_end && end >= key.offset) { |
388 | if (found_extent) { | 389 | if (found_extent) { |
389 | u64 disk_blocknr = | 390 | u64 disk_bytenr = |
390 | btrfs_file_extent_disk_blocknr(leaf,extent); | 391 | btrfs_file_extent_disk_bytenr(leaf, extent); |
391 | u64 disk_num_blocks = | 392 | u64 disk_num_bytes = |
392 | btrfs_file_extent_disk_num_blocks(leaf, | 393 | btrfs_file_extent_disk_num_bytes(leaf, |
393 | extent); | 394 | extent); |
394 | read_extent_buffer(leaf, &old, | 395 | read_extent_buffer(leaf, &old, |
395 | (unsigned long)extent, | 396 | (unsigned long)extent, |
396 | sizeof(old)); | 397 | sizeof(old)); |
397 | if (disk_blocknr != 0) { | 398 | if (disk_bytenr != 0) { |
398 | ret = btrfs_inc_extent_ref(trans, root, | 399 | ret = btrfs_inc_extent_ref(trans, root, |
399 | disk_blocknr, disk_num_blocks); | 400 | disk_bytenr, disk_num_bytes); |
400 | BUG_ON(ret); | 401 | BUG_ON(ret); |
401 | } | 402 | } |
402 | } | 403 | } |
@@ -410,21 +411,19 @@ next_slot: | |||
410 | keep = 1; | 411 | keep = 1; |
411 | WARN_ON(start & (root->sectorsize - 1)); | 412 | WARN_ON(start & (root->sectorsize - 1)); |
412 | if (found_extent) { | 413 | if (found_extent) { |
413 | new_num = (start - key.offset) >> | 414 | new_num = start - key.offset; |
414 | inode->i_blkbits; | 415 | old_num = btrfs_file_extent_num_bytes(leaf, |
415 | old_num = btrfs_file_extent_num_blocks(leaf, | 416 | extent); |
416 | extent); | 417 | *hint_byte = |
417 | *hint_block = | 418 | btrfs_file_extent_disk_bytenr(leaf, |
418 | btrfs_file_extent_disk_blocknr(leaf, | 419 | extent); |
419 | extent); | 420 | if (btrfs_file_extent_disk_bytenr(leaf, |
420 | if (btrfs_file_extent_disk_blocknr(leaf, | 421 | extent)) { |
421 | extent)) { | ||
422 | inode->i_blocks -= | 422 | inode->i_blocks -= |
423 | (old_num - new_num) << 3; | 423 | (old_num - new_num) >> 9; |
424 | } | 424 | } |
425 | btrfs_set_file_extent_num_blocks(leaf, | 425 | btrfs_set_file_extent_num_bytes(leaf, extent, |
426 | extent, | 426 | new_num); |
427 | new_num); | ||
428 | btrfs_mark_buffer_dirty(leaf); | 427 | btrfs_mark_buffer_dirty(leaf); |
429 | } else { | 428 | } else { |
430 | WARN_ON(1); | 429 | WARN_ON(1); |
@@ -432,33 +431,32 @@ next_slot: | |||
432 | } | 431 | } |
433 | /* delete the entire extent */ | 432 | /* delete the entire extent */ |
434 | if (!keep) { | 433 | if (!keep) { |
435 | u64 disk_blocknr = 0; | 434 | u64 disk_bytenr = 0; |
436 | u64 disk_num_blocks = 0; | 435 | u64 disk_num_bytes = 0; |
437 | u64 extent_num_blocks = 0; | 436 | u64 extent_num_bytes = 0; |
438 | if (found_extent) { | 437 | if (found_extent) { |
439 | disk_blocknr = | 438 | disk_bytenr = |
440 | btrfs_file_extent_disk_blocknr(leaf, | 439 | btrfs_file_extent_disk_bytenr(leaf, |
441 | extent); | 440 | extent); |
442 | disk_num_blocks = | 441 | disk_num_bytes = |
443 | btrfs_file_extent_disk_num_blocks(leaf, | 442 | btrfs_file_extent_disk_num_bytes(leaf, |
444 | extent); | ||
445 | extent_num_blocks = | ||
446 | btrfs_file_extent_num_blocks(leaf, | ||
447 | extent); | ||
448 | *hint_block = | ||
449 | btrfs_file_extent_disk_blocknr(leaf, | ||
450 | extent); | 443 | extent); |
444 | extent_num_bytes = | ||
445 | btrfs_file_extent_num_bytes(leaf, extent); | ||
446 | *hint_byte = | ||
447 | btrfs_file_extent_disk_bytenr(leaf, | ||
448 | extent); | ||
451 | } | 449 | } |
452 | ret = btrfs_del_item(trans, root, path); | 450 | ret = btrfs_del_item(trans, root, path); |
453 | /* TODO update progress marker and return */ | 451 | /* TODO update progress marker and return */ |
454 | BUG_ON(ret); | 452 | BUG_ON(ret); |
455 | btrfs_release_path(root, path); | 453 | btrfs_release_path(root, path); |
456 | extent = NULL; | 454 | extent = NULL; |
457 | if (found_extent && disk_blocknr != 0) { | 455 | if (found_extent && disk_bytenr != 0) { |
458 | inode->i_blocks -= extent_num_blocks << 3; | 456 | inode->i_blocks -= extent_num_bytes >> 9; |
459 | ret = btrfs_free_extent(trans, root, | 457 | ret = btrfs_free_extent(trans, root, |
460 | disk_blocknr, | 458 | disk_bytenr, |
461 | disk_num_blocks, 0); | 459 | disk_num_bytes, 0); |
462 | } | 460 | } |
463 | 461 | ||
464 | BUG_ON(ret); | 462 | BUG_ON(ret); |
@@ -491,20 +489,19 @@ next_slot: | |||
491 | (unsigned long)extent, sizeof(old)); | 489 | (unsigned long)extent, sizeof(old)); |
492 | 490 | ||
493 | btrfs_set_file_extent_offset(leaf, extent, | 491 | btrfs_set_file_extent_offset(leaf, extent, |
494 | le64_to_cpu(old.offset) + | 492 | le64_to_cpu(old.offset) + end - key.offset); |
495 | ((end - key.offset) >> inode->i_blkbits)); | 493 | WARN_ON(le64_to_cpu(old.num_bytes) < |
496 | WARN_ON(le64_to_cpu(old.num_blocks) < | 494 | (extent_end - end)); |
497 | (extent_end - end) >> inode->i_blkbits); | 495 | btrfs_set_file_extent_num_bytes(leaf, extent, |
498 | btrfs_set_file_extent_num_blocks(leaf, extent, | 496 | extent_end - end); |
499 | (extent_end - end) >> inode->i_blkbits); | ||
500 | |||
501 | btrfs_set_file_extent_type(leaf, extent, | 497 | btrfs_set_file_extent_type(leaf, extent, |
502 | BTRFS_FILE_EXTENT_REG); | 498 | BTRFS_FILE_EXTENT_REG); |
499 | |||
503 | btrfs_mark_buffer_dirty(path->nodes[0]); | 500 | btrfs_mark_buffer_dirty(path->nodes[0]); |
504 | if (le64_to_cpu(old.disk_blocknr) != 0) { | 501 | if (le64_to_cpu(old.disk_bytenr) != 0) { |
505 | inode->i_blocks += | 502 | inode->i_blocks += |
506 | btrfs_file_extent_num_blocks(leaf, | 503 | btrfs_file_extent_num_bytes(leaf, |
507 | extent) << 3; | 504 | extent) >> 9; |
508 | } | 505 | } |
509 | ret = 0; | 506 | ret = 0; |
510 | goto out; | 507 | goto out; |
@@ -531,12 +528,9 @@ static int prepare_pages(struct btrfs_root *root, | |||
531 | unsigned long index = pos >> PAGE_CACHE_SHIFT; | 528 | unsigned long index = pos >> PAGE_CACHE_SHIFT; |
532 | struct inode *inode = file->f_path.dentry->d_inode; | 529 | struct inode *inode = file->f_path.dentry->d_inode; |
533 | int err = 0; | 530 | int err = 0; |
534 | u64 num_blocks; | ||
535 | u64 start_pos; | 531 | u64 start_pos; |
536 | 532 | ||
537 | start_pos = pos & ~((u64)root->sectorsize - 1); | 533 | start_pos = pos & ~((u64)root->sectorsize - 1); |
538 | num_blocks = (write_bytes + pos - start_pos + root->sectorsize - 1) >> | ||
539 | inode->i_blkbits; | ||
540 | 534 | ||
541 | memset(pages, 0, num_pages * sizeof(struct page *)); | 535 | memset(pages, 0, num_pages * sizeof(struct page *)); |
542 | 536 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fbe2836364e0..d6b3a55ed8e0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -77,19 +77,19 @@ static int run_delalloc_range(struct inode *inode, u64 start, u64 end) | |||
77 | struct btrfs_trans_handle *trans; | 77 | struct btrfs_trans_handle *trans; |
78 | struct btrfs_key ins; | 78 | struct btrfs_key ins; |
79 | u64 alloc_hint = 0; | 79 | u64 alloc_hint = 0; |
80 | u64 num_blocks; | 80 | u64 num_bytes; |
81 | int ret; | 81 | int ret; |
82 | u64 blocksize = 1 << inode->i_blkbits; | 82 | u64 blocksize = root->sectorsize; |
83 | 83 | ||
84 | mutex_lock(&root->fs_info->fs_mutex); | 84 | mutex_lock(&root->fs_info->fs_mutex); |
85 | trans = btrfs_start_transaction(root, 1); | 85 | trans = btrfs_start_transaction(root, 1); |
86 | btrfs_set_trans_block_group(trans, inode); | 86 | btrfs_set_trans_block_group(trans, inode); |
87 | BUG_ON(!trans); | 87 | BUG_ON(!trans); |
88 | num_blocks = (end - start + blocksize) & ~(blocksize - 1); | 88 | num_bytes = (end - start + blocksize) & ~(blocksize - 1); |
89 | ret = btrfs_drop_extents(trans, root, inode, | 89 | ret = btrfs_drop_extents(trans, root, inode, |
90 | start, start + num_blocks, &alloc_hint); | 90 | start, start + num_bytes, &alloc_hint); |
91 | num_blocks = num_blocks >> inode->i_blkbits; | 91 | |
92 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, num_blocks, 0, | 92 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, num_bytes, 0, |
93 | alloc_hint, (u64)-1, &ins, 1); | 93 | alloc_hint, (u64)-1, &ins, 1); |
94 | if (ret) { | 94 | if (ret) { |
95 | WARN_ON(1); | 95 | WARN_ON(1); |
@@ -186,7 +186,8 @@ int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end) | |||
186 | zeroit: | 186 | zeroit: |
187 | printk("btrfs csum failed ino %lu off %llu\n", | 187 | printk("btrfs csum failed ino %lu off %llu\n", |
188 | page->mapping->host->i_ino, (unsigned long long)start); | 188 | page->mapping->host->i_ino, (unsigned long long)start); |
189 | memset(kaddr + offset, 1, end - start + 1); flush_dcache_page(page); | 189 | memset(kaddr + offset, 1, end - start + 1); |
190 | flush_dcache_page(page); | ||
190 | kunmap_atomic(kaddr, KM_IRQ0); | 191 | kunmap_atomic(kaddr, KM_IRQ0); |
191 | return 0; | 192 | return 0; |
192 | } | 193 | } |
@@ -547,7 +548,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
547 | struct extent_buffer *leaf; | 548 | struct extent_buffer *leaf; |
548 | struct btrfs_file_extent_item *fi; | 549 | struct btrfs_file_extent_item *fi; |
549 | u64 extent_start = 0; | 550 | u64 extent_start = 0; |
550 | u64 extent_num_blocks = 0; | 551 | u64 extent_num_bytes = 0; |
551 | u64 item_end = 0; | 552 | u64 item_end = 0; |
552 | int found_extent; | 553 | int found_extent; |
553 | int del_item; | 554 | int del_item; |
@@ -593,8 +594,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
593 | if (btrfs_file_extent_type(leaf, fi) != | 594 | if (btrfs_file_extent_type(leaf, fi) != |
594 | BTRFS_FILE_EXTENT_INLINE) { | 595 | BTRFS_FILE_EXTENT_INLINE) { |
595 | item_end += | 596 | item_end += |
596 | btrfs_file_extent_num_blocks(leaf, fi) << | 597 | btrfs_file_extent_num_bytes(leaf, fi); |
597 | inode->i_blkbits; | ||
598 | } | 598 | } |
599 | } | 599 | } |
600 | if (found_type == BTRFS_CSUM_ITEM_KEY) { | 600 | if (found_type == BTRFS_CSUM_ITEM_KEY) { |
@@ -626,28 +626,27 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
626 | btrfs_file_extent_type(leaf, fi) != | 626 | btrfs_file_extent_type(leaf, fi) != |
627 | BTRFS_FILE_EXTENT_INLINE) { | 627 | BTRFS_FILE_EXTENT_INLINE) { |
628 | u64 num_dec; | 628 | u64 num_dec; |
629 | extent_start = btrfs_file_extent_disk_blocknr(leaf, fi); | 629 | extent_start = btrfs_file_extent_disk_bytenr(leaf, fi); |
630 | if (!del_item) { | 630 | if (!del_item) { |
631 | u64 orig_num_blocks = | 631 | u64 orig_num_bytes = |
632 | btrfs_file_extent_num_blocks(leaf, fi); | 632 | btrfs_file_extent_num_bytes(leaf, fi); |
633 | extent_num_blocks = inode->i_size - | 633 | extent_num_bytes = inode->i_size - |
634 | found_key.offset + root->sectorsize - 1; | 634 | found_key.offset + root->sectorsize - 1; |
635 | extent_num_blocks >>= inode->i_blkbits; | 635 | btrfs_set_file_extent_num_bytes(leaf, fi, |
636 | btrfs_set_file_extent_num_blocks(leaf, fi, | 636 | extent_num_bytes); |
637 | extent_num_blocks); | 637 | num_dec = (orig_num_bytes - |
638 | num_dec = (orig_num_blocks - | 638 | extent_num_bytes) >> 9; |
639 | extent_num_blocks) << 3; | ||
640 | if (extent_start != 0) { | 639 | if (extent_start != 0) { |
641 | inode->i_blocks -= num_dec; | 640 | inode->i_blocks -= num_dec; |
642 | } | 641 | } |
643 | btrfs_mark_buffer_dirty(leaf); | 642 | btrfs_mark_buffer_dirty(leaf); |
644 | } else { | 643 | } else { |
645 | extent_num_blocks = | 644 | extent_num_bytes = |
646 | btrfs_file_extent_disk_num_blocks(leaf, | 645 | btrfs_file_extent_disk_num_bytes(leaf, |
647 | fi); | 646 | fi); |
648 | /* FIXME blocksize != 4096 */ | 647 | /* FIXME blocksize != 4096 */ |
649 | num_dec = btrfs_file_extent_num_blocks(leaf, | 648 | num_dec = btrfs_file_extent_num_bytes(leaf, |
650 | fi) << 3; | 649 | fi) >> 9; |
651 | if (extent_start != 0) { | 650 | if (extent_start != 0) { |
652 | found_extent = 1; | 651 | found_extent = 1; |
653 | inode->i_blocks -= num_dec; | 652 | inode->i_blocks -= num_dec; |
@@ -664,7 +663,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
664 | btrfs_release_path(root, path); | 663 | btrfs_release_path(root, path); |
665 | if (found_extent) { | 664 | if (found_extent) { |
666 | ret = btrfs_free_extent(trans, root, extent_start, | 665 | ret = btrfs_free_extent(trans, root, extent_start, |
667 | extent_num_blocks, 0); | 666 | extent_num_bytes, 0); |
668 | BUG_ON(ret); | 667 | BUG_ON(ret); |
669 | } | 668 | } |
670 | } | 669 | } |
@@ -709,7 +708,8 @@ static int btrfs_cow_one_page(struct inode *inode, struct page *page, | |||
709 | static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | 708 | static int btrfs_truncate_page(struct address_space *mapping, loff_t from) |
710 | { | 709 | { |
711 | struct inode *inode = mapping->host; | 710 | struct inode *inode = mapping->host; |
712 | unsigned blocksize = 1 << inode->i_blkbits; | 711 | struct btrfs_root *root = BTRFS_I(inode)->root; |
712 | u32 blocksize = root->sectorsize; | ||
713 | pgoff_t index = from >> PAGE_CACHE_SHIFT; | 713 | pgoff_t index = from >> PAGE_CACHE_SHIFT; |
714 | unsigned offset = from & (PAGE_CACHE_SIZE-1); | 714 | unsigned offset = from & (PAGE_CACHE_SIZE-1); |
715 | struct page *page; | 715 | struct page *page; |
@@ -719,7 +719,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | |||
719 | if ((offset & (blocksize - 1)) == 0) | 719 | if ((offset & (blocksize - 1)) == 0) |
720 | goto out; | 720 | goto out; |
721 | 721 | ||
722 | down_read(&BTRFS_I(inode)->root->snap_sem); | 722 | down_read(&root->snap_sem); |
723 | ret = -ENOMEM; | 723 | ret = -ENOMEM; |
724 | page = grab_cache_page(mapping, index); | 724 | page = grab_cache_page(mapping, index); |
725 | if (!page) | 725 | if (!page) |
@@ -778,8 +778,6 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
778 | err = btrfs_drop_extents(trans, root, inode, | 778 | err = btrfs_drop_extents(trans, root, inode, |
779 | pos, pos + hole_size, &alloc_hint); | 779 | pos, pos + hole_size, &alloc_hint); |
780 | 780 | ||
781 | hole_size >>= inode->i_blkbits; | ||
782 | |||
783 | err = btrfs_insert_file_extent(trans, root, inode->i_ino, | 781 | err = btrfs_insert_file_extent(trans, root, inode->i_ino, |
784 | pos, 0, 0, hole_size); | 782 | pos, 0, 0, hole_size); |
785 | btrfs_end_transaction(trans, root); | 783 | btrfs_end_transaction(trans, root); |
@@ -1490,7 +1488,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
1490 | { | 1488 | { |
1491 | int ret; | 1489 | int ret; |
1492 | int err = 0; | 1490 | int err = 0; |
1493 | u64 blocknr; | 1491 | u64 bytenr; |
1494 | u64 extent_start = 0; | 1492 | u64 extent_start = 0; |
1495 | u64 extent_end = 0; | 1493 | u64 extent_end = 0; |
1496 | u64 objectid = inode->i_ino; | 1494 | u64 objectid = inode->i_ino; |
@@ -1540,10 +1538,6 @@ again: | |||
1540 | leaf = path->nodes[0]; | 1538 | leaf = path->nodes[0]; |
1541 | item = btrfs_item_ptr(leaf, path->slots[0], | 1539 | item = btrfs_item_ptr(leaf, path->slots[0], |
1542 | struct btrfs_file_extent_item); | 1540 | struct btrfs_file_extent_item); |
1543 | |||
1544 | blocknr = btrfs_file_extent_disk_blocknr(leaf, item); | ||
1545 | blocknr += btrfs_file_extent_offset(leaf, item); | ||
1546 | |||
1547 | /* are we inside the extent that was found? */ | 1541 | /* are we inside the extent that was found? */ |
1548 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | 1542 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
1549 | found_type = btrfs_key_type(&found_key); | 1543 | found_type = btrfs_key_type(&found_key); |
@@ -1556,8 +1550,7 @@ again: | |||
1556 | extent_start = found_key.offset; | 1550 | extent_start = found_key.offset; |
1557 | if (found_type == BTRFS_FILE_EXTENT_REG) { | 1551 | if (found_type == BTRFS_FILE_EXTENT_REG) { |
1558 | extent_end = extent_start + | 1552 | extent_end = extent_start + |
1559 | (btrfs_file_extent_num_blocks(leaf, item) << | 1553 | btrfs_file_extent_num_bytes(leaf, item); |
1560 | inode->i_blkbits); | ||
1561 | err = 0; | 1554 | err = 0; |
1562 | if (start < extent_start || start >= extent_end) { | 1555 | if (start < extent_start || start >= extent_end) { |
1563 | em->start = start; | 1556 | em->start = start; |
@@ -1570,17 +1563,18 @@ again: | |||
1570 | } | 1563 | } |
1571 | goto not_found_em; | 1564 | goto not_found_em; |
1572 | } | 1565 | } |
1573 | if (btrfs_file_extent_disk_blocknr(leaf, item) == 0) { | 1566 | bytenr = btrfs_file_extent_disk_bytenr(leaf, item); |
1567 | if (bytenr == 0) { | ||
1574 | em->start = extent_start; | 1568 | em->start = extent_start; |
1575 | em->end = extent_end - 1; | 1569 | em->end = extent_end - 1; |
1576 | em->block_start = EXTENT_MAP_HOLE; | 1570 | em->block_start = EXTENT_MAP_HOLE; |
1577 | em->block_end = EXTENT_MAP_HOLE; | 1571 | em->block_end = EXTENT_MAP_HOLE; |
1578 | goto insert; | 1572 | goto insert; |
1579 | } | 1573 | } |
1580 | em->block_start = blocknr << inode->i_blkbits; | 1574 | bytenr += btrfs_file_extent_offset(leaf, item); |
1575 | em->block_start = bytenr; | ||
1581 | em->block_end = em->block_start + | 1576 | em->block_end = em->block_start + |
1582 | (btrfs_file_extent_num_blocks(leaf, item) << | 1577 | btrfs_file_extent_num_bytes(leaf, item) - 1; |
1583 | inode->i_blkbits) - 1; | ||
1584 | em->start = extent_start; | 1578 | em->start = extent_start; |
1585 | em->end = extent_end - 1; | 1579 | em->end = extent_end - 1; |
1586 | goto insert; | 1580 | goto insert; |
@@ -1592,7 +1586,8 @@ again: | |||
1592 | size = btrfs_file_extent_inline_len(leaf, btrfs_item_nr(leaf, | 1586 | size = btrfs_file_extent_inline_len(leaf, btrfs_item_nr(leaf, |
1593 | path->slots[0])); | 1587 | path->slots[0])); |
1594 | 1588 | ||
1595 | extent_end = extent_start | ((u64)root->sectorsize - 1); | 1589 | extent_end = (extent_start + size) | |
1590 | ((u64)root->sectorsize - 1); | ||
1596 | if (start < extent_start || start >= extent_end) { | 1591 | if (start < extent_start || start >= extent_end) { |
1597 | em->start = start; | 1592 | em->start = start; |
1598 | if (start < extent_start) { | 1593 | if (start < extent_start) { |
@@ -1617,8 +1612,10 @@ again: | |||
1617 | ptr = btrfs_file_extent_inline_start(item); | 1612 | ptr = btrfs_file_extent_inline_start(item); |
1618 | map = kmap(page); | 1613 | map = kmap(page); |
1619 | read_extent_buffer(leaf, map + page_offset, ptr, size); | 1614 | read_extent_buffer(leaf, map + page_offset, ptr, size); |
1615 | /* | ||
1620 | memset(map + page_offset + size, 0, | 1616 | memset(map + page_offset + size, 0, |
1621 | root->sectorsize - (page_offset + size)); | 1617 | root->sectorsize - (page_offset + size)); |
1618 | */ | ||
1622 | flush_dcache_page(page); | 1619 | flush_dcache_page(page); |
1623 | kunmap(page); | 1620 | kunmap(page); |
1624 | set_extent_uptodate(em_tree, extent_start, | 1621 | set_extent_uptodate(em_tree, extent_start, |
@@ -1836,13 +1833,13 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1836 | trans = btrfs_start_transaction(root, 1); | 1833 | trans = btrfs_start_transaction(root, 1); |
1837 | BUG_ON(!trans); | 1834 | BUG_ON(!trans); |
1838 | 1835 | ||
1839 | leaf = btrfs_alloc_free_block(trans, root, 0, 0); | 1836 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, 0); |
1840 | if (IS_ERR(leaf)) | 1837 | if (IS_ERR(leaf)) |
1841 | return PTR_ERR(leaf); | 1838 | return PTR_ERR(leaf); |
1842 | 1839 | ||
1843 | btrfs_set_header_nritems(leaf, 0); | 1840 | btrfs_set_header_nritems(leaf, 0); |
1844 | btrfs_set_header_level(leaf, 0); | 1841 | btrfs_set_header_level(leaf, 0); |
1845 | btrfs_set_header_blocknr(leaf, extent_buffer_blocknr(leaf)); | 1842 | btrfs_set_header_bytenr(leaf, leaf->start); |
1846 | btrfs_set_header_generation(leaf, trans->transid); | 1843 | btrfs_set_header_generation(leaf, trans->transid); |
1847 | btrfs_set_header_owner(leaf, root->root_key.objectid); | 1844 | btrfs_set_header_owner(leaf, root->root_key.objectid); |
1848 | write_extent_buffer(leaf, root->fs_info->fsid, | 1845 | write_extent_buffer(leaf, root->fs_info->fsid, |
@@ -1858,7 +1855,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1858 | inode_item->nblocks = cpu_to_le64(1); | 1855 | inode_item->nblocks = cpu_to_le64(1); |
1859 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | 1856 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); |
1860 | 1857 | ||
1861 | btrfs_set_root_blocknr(&root_item, extent_buffer_blocknr(leaf)); | 1858 | btrfs_set_root_bytenr(&root_item, leaf->start); |
1859 | btrfs_set_root_level(&root_item, 0); | ||
1862 | btrfs_set_root_refs(&root_item, 1); | 1860 | btrfs_set_root_refs(&root_item, 1); |
1863 | btrfs_set_root_used(&root_item, 0); | 1861 | btrfs_set_root_used(&root_item, 0); |
1864 | 1862 | ||
@@ -1971,8 +1969,8 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
1971 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 1969 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
1972 | 1970 | ||
1973 | btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); | 1971 | btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); |
1974 | btrfs_set_root_blocknr(&new_root_item, | 1972 | btrfs_set_root_bytenr(&new_root_item, root->node->start); |
1975 | extent_buffer_blocknr(root->node)); | 1973 | btrfs_set_root_level(&new_root_item, btrfs_header_level(root->node)); |
1976 | 1974 | ||
1977 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 1975 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
1978 | &new_root_item); | 1976 | &new_root_item); |
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index a825ce078a54..9f8696c8a8e8 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c | |||
@@ -36,7 +36,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) | |||
36 | u32 type; | 36 | u32 type; |
37 | 37 | ||
38 | printk("leaf %llu total ptrs %d free space %d\n", | 38 | printk("leaf %llu total ptrs %d free space %d\n", |
39 | (unsigned long long)btrfs_header_blocknr(l), nr, | 39 | (unsigned long long)btrfs_header_bytenr(l), nr, |
40 | btrfs_leaf_free_space(root, l)); | 40 | btrfs_leaf_free_space(root, l)); |
41 | for (i = 0 ; i < nr ; i++) { | 41 | for (i = 0 ; i < nr ; i++) { |
42 | item = btrfs_item_nr(l, i); | 42 | item = btrfs_item_nr(l, i); |
@@ -65,8 +65,8 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) | |||
65 | break; | 65 | break; |
66 | case BTRFS_ROOT_ITEM_KEY: | 66 | case BTRFS_ROOT_ITEM_KEY: |
67 | ri = btrfs_item_ptr(l, i, struct btrfs_root_item); | 67 | ri = btrfs_item_ptr(l, i, struct btrfs_root_item); |
68 | printk("\t\troot data blocknr %llu refs %u\n", | 68 | printk("\t\troot data bytenr %llu refs %u\n", |
69 | (unsigned long long)btrfs_disk_root_blocknr(l, ri), | 69 | (unsigned long long)btrfs_disk_root_bytenr(l, ri), |
70 | btrfs_disk_root_refs(l, ri)); | 70 | btrfs_disk_root_refs(l, ri)); |
71 | break; | 71 | break; |
72 | case BTRFS_EXTENT_ITEM_KEY: | 72 | case BTRFS_EXTENT_ITEM_KEY: |
@@ -84,12 +84,12 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) | |||
84 | btrfs_file_extent_inline_len(l, item)); | 84 | btrfs_file_extent_inline_len(l, item)); |
85 | break; | 85 | break; |
86 | } | 86 | } |
87 | printk("\t\textent data disk block %llu nr %llu\n", | 87 | printk("\t\textent data disk bytenr %llu nr %llu\n", |
88 | (unsigned long long)btrfs_file_extent_disk_blocknr(l, fi), | 88 | (unsigned long long)btrfs_file_extent_disk_bytenr(l, fi), |
89 | (unsigned long long)btrfs_file_extent_disk_num_blocks(l, fi)); | 89 | (unsigned long long)btrfs_file_extent_disk_num_bytes(l, fi)); |
90 | printk("\t\textent data offset %llu nr %llu\n", | 90 | printk("\t\textent data offset %llu nr %llu\n", |
91 | (unsigned long long)btrfs_file_extent_offset(l, fi), | 91 | (unsigned long long)btrfs_file_extent_offset(l, fi), |
92 | (unsigned long long)btrfs_file_extent_num_blocks(l, fi)); | 92 | (unsigned long long)btrfs_file_extent_num_bytes(l, fi)); |
93 | break; | 93 | break; |
94 | case BTRFS_BLOCK_GROUP_ITEM_KEY: | 94 | case BTRFS_BLOCK_GROUP_ITEM_KEY: |
95 | bi = btrfs_item_ptr(l, i, | 95 | bi = btrfs_item_ptr(l, i, |
@@ -106,16 +106,18 @@ void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c) | |||
106 | int i; | 106 | int i; |
107 | u32 nr; | 107 | u32 nr; |
108 | struct btrfs_key key; | 108 | struct btrfs_key key; |
109 | int level; | ||
109 | 110 | ||
110 | if (!c) | 111 | if (!c) |
111 | return; | 112 | return; |
112 | nr = btrfs_header_nritems(c); | 113 | nr = btrfs_header_nritems(c); |
113 | if (btrfs_is_leaf(c)) { | 114 | level = btrfs_header_level(c); |
115 | if (level == 0) { | ||
114 | btrfs_print_leaf(root, c); | 116 | btrfs_print_leaf(root, c); |
115 | return; | 117 | return; |
116 | } | 118 | } |
117 | printk("node %llu level %d total ptrs %d free spc %u\n", | 119 | printk("node %llu level %d total ptrs %d free spc %u\n", |
118 | (unsigned long long)btrfs_header_blocknr(c), | 120 | (unsigned long long)btrfs_header_bytenr(c), |
119 | btrfs_header_level(c), nr, | 121 | btrfs_header_level(c), nr, |
120 | (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr); | 122 | (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr); |
121 | for (i = 0; i < nr; i++) { | 123 | for (i = 0; i < nr; i++) { |
@@ -129,7 +131,8 @@ void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c) | |||
129 | } | 131 | } |
130 | for (i = 0; i < nr; i++) { | 132 | for (i = 0; i < nr; i++) { |
131 | struct extent_buffer *next = read_tree_block(root, | 133 | struct extent_buffer *next = read_tree_block(root, |
132 | btrfs_node_blockptr(c, i)); | 134 | btrfs_node_blockptr(c, i), |
135 | btrfs_level_size(root, level - 1)); | ||
133 | if (btrfs_is_leaf(next) && | 136 | if (btrfs_is_leaf(next) && |
134 | btrfs_header_level(c) != 1) | 137 | btrfs_header_level(c) != 1) |
135 | BUG(); | 138 | BUG(); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 39a1435c68f1..5c4370f3a5b8 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -303,10 +303,12 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
303 | { | 303 | { |
304 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); | 304 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); |
305 | struct btrfs_super_block *disk_super = &root->fs_info->super_copy; | 305 | struct btrfs_super_block *disk_super = &root->fs_info->super_copy; |
306 | int bits = dentry->d_sb->s_blocksize_bits; | ||
306 | 307 | ||
307 | buf->f_namelen = BTRFS_NAME_LEN; | 308 | buf->f_namelen = BTRFS_NAME_LEN; |
308 | buf->f_blocks = btrfs_super_total_blocks(disk_super); | 309 | buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits; |
309 | buf->f_bfree = buf->f_blocks - btrfs_super_blocks_used(disk_super); | 310 | buf->f_bfree = buf->f_blocks - |
311 | (btrfs_super_bytes_used(disk_super) >> bits); | ||
310 | buf->f_bavail = buf->f_bfree; | 312 | buf->f_bavail = buf->f_bfree; |
311 | buf->f_bsize = dentry->d_sb->s_blocksize; | 313 | buf->f_bsize = dentry->d_sb->s_blocksize; |
312 | buf->f_type = BTRFS_SUPER_MAGIC; | 314 | buf->f_type = BTRFS_SUPER_MAGIC; |
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 9654e90eec89..0bd1fd3d29df 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c | |||
@@ -42,14 +42,15 @@ static ssize_t root_block_limit_show(struct btrfs_root *root, char *buf) | |||
42 | 42 | ||
43 | static ssize_t super_blocks_used_show(struct btrfs_fs_info *fs, char *buf) | 43 | static ssize_t super_blocks_used_show(struct btrfs_fs_info *fs, char *buf) |
44 | { | 44 | { |
45 | |||
45 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 46 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
46 | (unsigned long long)btrfs_super_blocks_used(&fs->super_copy)); | 47 | (unsigned long long)btrfs_super_bytes_used(&fs->super_copy)); |
47 | } | 48 | } |
48 | 49 | ||
49 | static ssize_t super_total_blocks_show(struct btrfs_fs_info *fs, char *buf) | 50 | static ssize_t super_total_blocks_show(struct btrfs_fs_info *fs, char *buf) |
50 | { | 51 | { |
51 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 52 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
52 | (unsigned long long)btrfs_super_total_blocks(&fs->super_copy)); | 53 | (unsigned long long)btrfs_super_total_bytes(&fs->super_copy)); |
53 | } | 54 | } |
54 | 55 | ||
55 | static ssize_t super_blocksize_show(struct btrfs_fs_info *fs, char *buf) | 56 | static ssize_t super_blocksize_show(struct btrfs_fs_info *fs, char *buf) |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 55289b71056e..60f61345a8d0 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -205,12 +205,13 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | |||
205 | 205 | ||
206 | btrfs_write_dirty_block_groups(trans, extent_root); | 206 | btrfs_write_dirty_block_groups(trans, extent_root); |
207 | while(1) { | 207 | while(1) { |
208 | old_extent_block = btrfs_root_blocknr(&extent_root->root_item); | 208 | old_extent_block = btrfs_root_bytenr(&extent_root->root_item); |
209 | if (old_extent_block == | 209 | if (old_extent_block == extent_root->node->start) |
210 | extent_buffer_blocknr(extent_root->node)) | ||
211 | break; | 210 | break; |
212 | btrfs_set_root_blocknr(&extent_root->root_item, | 211 | btrfs_set_root_bytenr(&extent_root->root_item, |
213 | extent_buffer_blocknr(extent_root->node)); | 212 | extent_root->node->start); |
213 | btrfs_set_root_level(&extent_root->root_item, | ||
214 | btrfs_header_level(extent_root->node)); | ||
214 | ret = btrfs_update_root(trans, tree_root, | 215 | ret = btrfs_update_root(trans, tree_root, |
215 | &extent_root->root_key, | 216 | &extent_root->root_key, |
216 | &extent_root->root_item); | 217 | &extent_root->root_item); |
@@ -284,8 +285,8 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans, | |||
284 | (unsigned long)root->root_key.objectid, | 285 | (unsigned long)root->root_key.objectid, |
285 | BTRFS_ROOT_TRANS_TAG); | 286 | BTRFS_ROOT_TRANS_TAG); |
286 | if (root->commit_root == root->node) { | 287 | if (root->commit_root == root->node) { |
287 | WARN_ON(extent_buffer_blocknr(root->node) != | 288 | WARN_ON(root->node->start != |
288 | btrfs_root_blocknr(&root->root_item)); | 289 | btrfs_root_bytenr(&root->root_item)); |
289 | free_extent_buffer(root->commit_root); | 290 | free_extent_buffer(root->commit_root); |
290 | root->commit_root = NULL; | 291 | root->commit_root = NULL; |
291 | 292 | ||
@@ -314,8 +315,10 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans, | |||
314 | root->commit_root = NULL; | 315 | root->commit_root = NULL; |
315 | 316 | ||
316 | root->root_key.offset = root->fs_info->generation; | 317 | root->root_key.offset = root->fs_info->generation; |
317 | btrfs_set_root_blocknr(&root->root_item, | 318 | btrfs_set_root_bytenr(&root->root_item, |
318 | extent_buffer_blocknr(root->node)); | 319 | root->node->start); |
320 | btrfs_set_root_level(&root->root_item, | ||
321 | btrfs_header_level(root->node)); | ||
319 | err = btrfs_insert_root(trans, root->fs_info->tree_root, | 322 | err = btrfs_insert_root(trans, root->fs_info->tree_root, |
320 | &root->root_key, | 323 | &root->root_key, |
321 | &root->root_item); | 324 | &root->root_item); |
@@ -407,8 +410,8 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
407 | struct dirty_root *dirty; | 410 | struct dirty_root *dirty; |
408 | struct btrfs_trans_handle *trans; | 411 | struct btrfs_trans_handle *trans; |
409 | unsigned long nr; | 412 | unsigned long nr; |
410 | u64 num_blocks; | 413 | u64 num_bytes; |
411 | u64 blocks_used; | 414 | u64 bytes_used; |
412 | int ret = 0; | 415 | int ret = 0; |
413 | int err; | 416 | int err; |
414 | 417 | ||
@@ -419,7 +422,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
419 | dirty = list_entry(list->next, struct dirty_root, list); | 422 | dirty = list_entry(list->next, struct dirty_root, list); |
420 | list_del_init(&dirty->list); | 423 | list_del_init(&dirty->list); |
421 | 424 | ||
422 | num_blocks = btrfs_root_used(&dirty->root->root_item); | 425 | num_bytes = btrfs_root_used(&dirty->root->root_item); |
423 | root = dirty->latest_root; | 426 | root = dirty->latest_root; |
424 | 427 | ||
425 | while(1) { | 428 | while(1) { |
@@ -446,12 +449,12 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
446 | } | 449 | } |
447 | BUG_ON(ret); | 450 | BUG_ON(ret); |
448 | 451 | ||
449 | num_blocks -= btrfs_root_used(&dirty->root->root_item); | 452 | num_bytes -= btrfs_root_used(&dirty->root->root_item); |
450 | blocks_used = btrfs_root_used(&root->root_item); | 453 | bytes_used = btrfs_root_used(&root->root_item); |
451 | if (num_blocks) { | 454 | if (num_bytes) { |
452 | record_root_in_trans(root); | 455 | record_root_in_trans(root); |
453 | btrfs_set_root_used(&root->root_item, | 456 | btrfs_set_root_used(&root->root_item, |
454 | blocks_used - num_blocks); | 457 | bytes_used - num_bytes); |
455 | } | 458 | } |
456 | ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key); | 459 | ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key); |
457 | if (ret) { | 460 | if (ret) { |
@@ -560,7 +563,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
560 | btrfs_set_super_generation(&root->fs_info->super_copy, | 563 | btrfs_set_super_generation(&root->fs_info->super_copy, |
561 | cur_trans->transid); | 564 | cur_trans->transid); |
562 | btrfs_set_super_root(&root->fs_info->super_copy, | 565 | btrfs_set_super_root(&root->fs_info->super_copy, |
563 | extent_buffer_blocknr(root->fs_info->tree_root->node)); | 566 | root->fs_info->tree_root->node->start); |
567 | btrfs_set_super_root_level(&root->fs_info->super_copy, | ||
568 | btrfs_header_level(root->fs_info->tree_root->node)); | ||
564 | 569 | ||
565 | write_extent_buffer(root->fs_info->sb_buffer, | 570 | write_extent_buffer(root->fs_info->sb_buffer, |
566 | &root->fs_info->super_copy, 0, | 571 | &root->fs_info->super_copy, 0, |
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c index daf019afa0a1..3feac2f28628 100644 --- a/fs/btrfs/tree-defrag.c +++ b/fs/btrfs/tree-defrag.c | |||
@@ -27,13 +27,15 @@ static void reada_defrag(struct btrfs_root *root, | |||
27 | { | 27 | { |
28 | int i; | 28 | int i; |
29 | u32 nritems; | 29 | u32 nritems; |
30 | u64 blocknr; | 30 | u64 bytenr; |
31 | u32 blocksize; | ||
31 | int ret; | 32 | int ret; |
32 | 33 | ||
34 | blocksize = btrfs_level_size(root, btrfs_header_level(node) - 1); | ||
33 | nritems = btrfs_header_nritems(node); | 35 | nritems = btrfs_header_nritems(node); |
34 | for (i = 0; i < nritems; i++) { | 36 | for (i = 0; i < nritems; i++) { |
35 | blocknr = btrfs_node_blockptr(node, i); | 37 | bytenr = btrfs_node_blockptr(node, i); |
36 | ret = readahead_tree_block(root, blocknr); | 38 | ret = readahead_tree_block(root, bytenr, blocksize); |
37 | if (ret) | 39 | if (ret) |
38 | break; | 40 | break; |
39 | } | 41 | } |
@@ -46,7 +48,7 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans, | |||
46 | { | 48 | { |
47 | struct extent_buffer *next; | 49 | struct extent_buffer *next; |
48 | struct extent_buffer *cur; | 50 | struct extent_buffer *cur; |
49 | u64 blocknr; | 51 | u64 bytenr; |
50 | int ret = 0; | 52 | int ret = 0; |
51 | int is_extent = 0; | 53 | int is_extent = 0; |
52 | 54 | ||
@@ -80,10 +82,11 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans, | |||
80 | 82 | ||
81 | break; | 83 | break; |
82 | } | 84 | } |
83 | blocknr = btrfs_node_blockptr(cur, path->slots[*level]); | 85 | bytenr = btrfs_node_blockptr(cur, path->slots[*level]); |
84 | 86 | ||
85 | if (cache_only) { | 87 | if (cache_only) { |
86 | next = btrfs_find_tree_block(root, blocknr); | 88 | next = btrfs_find_tree_block(root, bytenr, |
89 | btrfs_level_size(root, *level - 1)); | ||
87 | /* FIXME, test for defrag */ | 90 | /* FIXME, test for defrag */ |
88 | if (!next || !btrfs_buffer_uptodate(next)) { | 91 | if (!next || !btrfs_buffer_uptodate(next)) { |
89 | free_extent_buffer(next); | 92 | free_extent_buffer(next); |
@@ -91,7 +94,8 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans, | |||
91 | continue; | 94 | continue; |
92 | } | 95 | } |
93 | } else { | 96 | } else { |
94 | next = read_tree_block(root, blocknr); | 97 | next = read_tree_block(root, bytenr, |
98 | btrfs_level_size(root, *level - 1)); | ||
95 | } | 99 | } |
96 | ret = btrfs_cow_block(trans, root, next, path->nodes[*level], | 100 | ret = btrfs_cow_block(trans, root, next, path->nodes[*level], |
97 | path->slots[*level], &next); | 101 | path->slots[*level], &next); |