diff options
-rw-r--r-- | fs/btrfs/ctree.c | 129 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 34 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 12 | ||||
-rw-r--r-- | fs/btrfs/mkfs.c | 36 | ||||
-rw-r--r-- | fs/btrfs/print-tree.c | 15 | ||||
-rw-r--r-- | fs/btrfs/random-test.c | 5 |
6 files changed, 141 insertions, 90 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 489019ac04b8..105556470055 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -76,7 +76,7 @@ static inline unsigned int leaf_data_end(struct leaf *leaf) | |||
76 | u32 nr = btrfs_header_nritems(&leaf->header); | 76 | u32 nr = btrfs_header_nritems(&leaf->header); |
77 | if (nr == 0) | 77 | if (nr == 0) |
78 | return sizeof(leaf->data); | 78 | return sizeof(leaf->data); |
79 | return leaf->items[nr-1].offset; | 79 | return btrfs_item_offset(leaf->items + nr - 1); |
80 | } | 80 | } |
81 | 81 | ||
82 | /* | 82 | /* |
@@ -174,11 +174,12 @@ int check_leaf(struct ctree_path *path, int level) | |||
174 | btrfs_disk_key_to_cpu(&cpukey, &leaf->items[i + 1].key); | 174 | btrfs_disk_key_to_cpu(&cpukey, &leaf->items[i + 1].key); |
175 | BUG_ON(comp_keys(&leaf->items[i].key, | 175 | BUG_ON(comp_keys(&leaf->items[i].key, |
176 | &cpukey) >= 0); | 176 | &cpukey) >= 0); |
177 | BUG_ON(leaf->items[i].offset != leaf->items[i + 1].offset + | 177 | BUG_ON(btrfs_item_offset(leaf->items + i) != |
178 | leaf->items[i + 1].size); | 178 | btrfs_item_end(leaf->items + i + 1)); |
179 | if (i == 0) { | 179 | if (i == 0) { |
180 | BUG_ON(leaf->items[i].offset + leaf->items[i].size != | 180 | BUG_ON(btrfs_item_offset(leaf->items + i) + |
181 | LEAF_DATA_SIZE); | 181 | btrfs_item_size(leaf->items + i) != |
182 | LEAF_DATA_SIZE); | ||
182 | } | 183 | } |
183 | } | 184 | } |
184 | return 0; | 185 | return 0; |
@@ -235,7 +236,8 @@ int bin_search(struct node *c, struct btrfs_key *key, int *slot) | |||
235 | { | 236 | { |
236 | if (btrfs_is_leaf(c)) { | 237 | if (btrfs_is_leaf(c)) { |
237 | struct leaf *l = (struct leaf *)c; | 238 | struct leaf *l = (struct leaf *)c; |
238 | return generic_bin_search((void *)l->items, sizeof(struct item), | 239 | return generic_bin_search((void *)l->items, |
240 | sizeof(struct btrfs_item), | ||
239 | key, btrfs_header_nritems(&c->header), | 241 | key, btrfs_header_nritems(&c->header), |
240 | slot); | 242 | slot); |
241 | } else { | 243 | } else { |
@@ -485,7 +487,7 @@ again: | |||
485 | struct leaf *l = (struct leaf *)c; | 487 | struct leaf *l = (struct leaf *)c; |
486 | p->slots[level] = slot; | 488 | p->slots[level] = slot; |
487 | if (ins_len > 0 && leaf_free_space(l) < | 489 | if (ins_len > 0 && leaf_free_space(l) < |
488 | sizeof(struct item) + ins_len) { | 490 | sizeof(struct btrfs_item) + ins_len) { |
489 | int sret = split_leaf(root, p, ins_len); | 491 | int sret = split_leaf(root, p, ins_len); |
490 | BUG_ON(sret > 0); | 492 | BUG_ON(sret > 0); |
491 | if (sret) | 493 | if (sret) |
@@ -780,9 +782,9 @@ static int leaf_space_used(struct leaf *l, int start, int nr) | |||
780 | 782 | ||
781 | if (!nr) | 783 | if (!nr) |
782 | return 0; | 784 | return 0; |
783 | data_len = l->items[start].offset + l->items[start].size; | 785 | data_len = btrfs_item_end(l->items + start); |
784 | data_len = data_len - l->items[end].offset; | 786 | data_len = data_len - btrfs_item_offset(l->items + end); |
785 | data_len += sizeof(struct item) * nr; | 787 | data_len += sizeof(struct btrfs_item) * nr; |
786 | return data_len; | 788 | return data_len; |
787 | } | 789 | } |
788 | 790 | ||
@@ -806,7 +808,7 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
806 | int free_space; | 808 | int free_space; |
807 | int push_space = 0; | 809 | int push_space = 0; |
808 | int push_items = 0; | 810 | int push_items = 0; |
809 | struct item *item; | 811 | struct btrfs_item *item; |
810 | u32 left_nritems; | 812 | u32 left_nritems; |
811 | u32 right_nritems; | 813 | u32 right_nritems; |
812 | 814 | ||
@@ -821,7 +823,7 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
821 | right_buf = read_tree_block(root, upper->node.blockptrs[slot + 1]); | 823 | right_buf = read_tree_block(root, upper->node.blockptrs[slot + 1]); |
822 | right = &right_buf->leaf; | 824 | right = &right_buf->leaf; |
823 | free_space = leaf_free_space(right); | 825 | free_space = leaf_free_space(right); |
824 | if (free_space < data_size + sizeof(struct item)) { | 826 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
825 | tree_block_release(root, right_buf); | 827 | tree_block_release(root, right_buf); |
826 | return 1; | 828 | return 1; |
827 | } | 829 | } |
@@ -829,7 +831,7 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
829 | btrfs_cow_block(root, right_buf, upper, slot + 1, &right_buf); | 831 | btrfs_cow_block(root, right_buf, upper, slot + 1, &right_buf); |
830 | right = &right_buf->leaf; | 832 | right = &right_buf->leaf; |
831 | free_space = leaf_free_space(right); | 833 | free_space = leaf_free_space(right); |
832 | if (free_space < data_size + sizeof(struct item)) { | 834 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
833 | tree_block_release(root, right_buf); | 835 | tree_block_release(root, right_buf); |
834 | return 1; | 836 | return 1; |
835 | } | 837 | } |
@@ -839,10 +841,11 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
839 | item = left->items + i; | 841 | item = left->items + i; |
840 | if (path->slots[0] == i) | 842 | if (path->slots[0] == i) |
841 | push_space += data_size + sizeof(*item); | 843 | push_space += data_size + sizeof(*item); |
842 | if (item->size + sizeof(*item) + push_space > free_space) | 844 | if (btrfs_item_size(item) + sizeof(*item) + push_space > |
845 | free_space) | ||
843 | break; | 846 | break; |
844 | push_items++; | 847 | push_items++; |
845 | push_space += item->size + sizeof(*item); | 848 | push_space += btrfs_item_size(item) + sizeof(*item); |
846 | } | 849 | } |
847 | if (push_items == 0) { | 850 | if (push_items == 0) { |
848 | tree_block_release(root, right_buf); | 851 | tree_block_release(root, right_buf); |
@@ -850,8 +853,7 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
850 | } | 853 | } |
851 | right_nritems = btrfs_header_nritems(&right->header); | 854 | right_nritems = btrfs_header_nritems(&right->header); |
852 | /* push left to right */ | 855 | /* push left to right */ |
853 | push_space = left->items[left_nritems - push_items].offset + | 856 | push_space = btrfs_item_end(left->items + left_nritems - push_items); |
854 | left->items[left_nritems - push_items].size; | ||
855 | push_space -= leaf_data_end(left); | 857 | push_space -= leaf_data_end(left); |
856 | /* make room in the right data area */ | 858 | /* make room in the right data area */ |
857 | memmove(right->data + leaf_data_end(right) - push_space, | 859 | memmove(right->data + leaf_data_end(right) - push_space, |
@@ -862,18 +864,19 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
862 | left->data + leaf_data_end(left), | 864 | left->data + leaf_data_end(left), |
863 | push_space); | 865 | push_space); |
864 | memmove(right->items + push_items, right->items, | 866 | memmove(right->items + push_items, right->items, |
865 | right_nritems * sizeof(struct item)); | 867 | right_nritems * sizeof(struct btrfs_item)); |
866 | /* copy the items from left to right */ | 868 | /* copy the items from left to right */ |
867 | memcpy(right->items, left->items + left_nritems - push_items, | 869 | memcpy(right->items, left->items + left_nritems - push_items, |
868 | push_items * sizeof(struct item)); | 870 | push_items * sizeof(struct btrfs_item)); |
869 | 871 | ||
870 | /* update the item pointers */ | 872 | /* update the item pointers */ |
871 | right_nritems += push_items; | 873 | right_nritems += push_items; |
872 | btrfs_set_header_nritems(&right->header, right_nritems); | 874 | btrfs_set_header_nritems(&right->header, right_nritems); |
873 | push_space = LEAF_DATA_SIZE; | 875 | push_space = LEAF_DATA_SIZE; |
874 | for (i = 0; i < right_nritems; i++) { | 876 | for (i = 0; i < right_nritems; i++) { |
875 | right->items[i].offset = push_space - right->items[i].size; | 877 | btrfs_set_item_offset(right->items + i, push_space - |
876 | push_space = right->items[i].offset; | 878 | btrfs_item_size(right->items + i)); |
879 | push_space = btrfs_item_offset(right->items + i); | ||
877 | } | 880 | } |
878 | left_nritems -= push_items; | 881 | left_nritems -= push_items; |
879 | btrfs_set_header_nritems(&left->header, left_nritems); | 882 | btrfs_set_header_nritems(&left->header, left_nritems); |
@@ -911,7 +914,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path, | |||
911 | int free_space; | 914 | int free_space; |
912 | int push_space = 0; | 915 | int push_space = 0; |
913 | int push_items = 0; | 916 | int push_items = 0; |
914 | struct item *item; | 917 | struct btrfs_item *item; |
915 | u32 old_left_nritems; | 918 | u32 old_left_nritems; |
916 | int ret = 0; | 919 | int ret = 0; |
917 | int wret; | 920 | int wret; |
@@ -926,7 +929,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path, | |||
926 | t = read_tree_block(root, path->nodes[1]->node.blockptrs[slot - 1]); | 929 | t = read_tree_block(root, path->nodes[1]->node.blockptrs[slot - 1]); |
927 | left = &t->leaf; | 930 | left = &t->leaf; |
928 | free_space = leaf_free_space(left); | 931 | free_space = leaf_free_space(left); |
929 | if (free_space < data_size + sizeof(struct item)) { | 932 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
930 | tree_block_release(root, t); | 933 | tree_block_release(root, t); |
931 | return 1; | 934 | return 1; |
932 | } | 935 | } |
@@ -935,7 +938,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path, | |||
935 | btrfs_cow_block(root, t, path->nodes[1], slot - 1, &t); | 938 | btrfs_cow_block(root, t, path->nodes[1], slot - 1, &t); |
936 | left = &t->leaf; | 939 | left = &t->leaf; |
937 | free_space = leaf_free_space(left); | 940 | free_space = leaf_free_space(left); |
938 | if (free_space < data_size + sizeof(struct item)) { | 941 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
939 | tree_block_release(root, t); | 942 | tree_block_release(root, t); |
940 | return 1; | 943 | return 1; |
941 | } | 944 | } |
@@ -944,10 +947,11 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path, | |||
944 | item = right->items + i; | 947 | item = right->items + i; |
945 | if (path->slots[0] == i) | 948 | if (path->slots[0] == i) |
946 | push_space += data_size + sizeof(*item); | 949 | push_space += data_size + sizeof(*item); |
947 | if (item->size + sizeof(*item) + push_space > free_space) | 950 | if (btrfs_item_size(item) + sizeof(*item) + push_space > |
951 | free_space) | ||
948 | break; | 952 | break; |
949 | push_items++; | 953 | push_items++; |
950 | push_space += item->size + sizeof(*item); | 954 | push_space += btrfs_item_size(item) + sizeof(*item); |
951 | } | 955 | } |
952 | if (push_items == 0) { | 956 | if (push_items == 0) { |
953 | tree_block_release(root, t); | 957 | tree_block_release(root, t); |
@@ -955,35 +959,40 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path, | |||
955 | } | 959 | } |
956 | /* push data from right to left */ | 960 | /* push data from right to left */ |
957 | memcpy(left->items + btrfs_header_nritems(&left->header), | 961 | memcpy(left->items + btrfs_header_nritems(&left->header), |
958 | right->items, push_items * sizeof(struct item)); | 962 | right->items, push_items * sizeof(struct btrfs_item)); |
959 | push_space = LEAF_DATA_SIZE - right->items[push_items -1].offset; | 963 | push_space = LEAF_DATA_SIZE - |
964 | btrfs_item_offset(right->items + push_items -1); | ||
960 | memcpy(left->data + leaf_data_end(left) - push_space, | 965 | memcpy(left->data + leaf_data_end(left) - push_space, |
961 | right->data + right->items[push_items - 1].offset, | 966 | right->data + btrfs_item_offset(right->items + push_items - 1), |
962 | push_space); | 967 | push_space); |
963 | old_left_nritems = btrfs_header_nritems(&left->header); | 968 | old_left_nritems = btrfs_header_nritems(&left->header); |
964 | BUG_ON(old_left_nritems < 0); | 969 | BUG_ON(old_left_nritems < 0); |
965 | 970 | ||
966 | for(i = old_left_nritems; i < old_left_nritems + push_items; i++) { | 971 | for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { |
967 | left->items[i].offset -= LEAF_DATA_SIZE - | 972 | u16 ioff = btrfs_item_offset(left->items + i); |
968 | left->items[old_left_nritems -1].offset; | 973 | btrfs_set_item_offset(left->items + i, ioff - (LEAF_DATA_SIZE - |
974 | btrfs_item_offset(left->items + | ||
975 | old_left_nritems - 1))); | ||
969 | } | 976 | } |
970 | btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); | 977 | btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); |
971 | 978 | ||
972 | /* fixup right node */ | 979 | /* fixup right node */ |
973 | push_space = right->items[push_items-1].offset - leaf_data_end(right); | 980 | push_space = btrfs_item_offset(right->items + push_items - 1) - |
981 | leaf_data_end(right); | ||
974 | memmove(right->data + LEAF_DATA_SIZE - push_space, right->data + | 982 | memmove(right->data + LEAF_DATA_SIZE - push_space, right->data + |
975 | leaf_data_end(right), push_space); | 983 | leaf_data_end(right), push_space); |
976 | memmove(right->items, right->items + push_items, | 984 | memmove(right->items, right->items + push_items, |
977 | (btrfs_header_nritems(&right->header) - push_items) * | 985 | (btrfs_header_nritems(&right->header) - push_items) * |
978 | sizeof(struct item)); | 986 | sizeof(struct btrfs_item)); |
979 | btrfs_set_header_nritems(&right->header, | 987 | btrfs_set_header_nritems(&right->header, |
980 | btrfs_header_nritems(&right->header) - | 988 | btrfs_header_nritems(&right->header) - |
981 | push_items); | 989 | push_items); |
982 | push_space = LEAF_DATA_SIZE; | 990 | push_space = LEAF_DATA_SIZE; |
983 | 991 | ||
984 | for (i = 0; i < btrfs_header_nritems(&right->header); i++) { | 992 | for (i = 0; i < btrfs_header_nritems(&right->header); i++) { |
985 | right->items[i].offset = push_space - right->items[i].size; | 993 | btrfs_set_item_offset(right->items + i, push_space - |
986 | push_space = right->items[i].offset; | 994 | btrfs_item_size(right->items + i)); |
995 | push_space = btrfs_item_offset(right->items + i); | ||
987 | } | 996 | } |
988 | 997 | ||
989 | BUG_ON(list_empty(&t->dirty)); | 998 | BUG_ON(list_empty(&t->dirty)); |
@@ -1023,7 +1032,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path, | |||
1023 | int slot; | 1032 | int slot; |
1024 | struct leaf *right; | 1033 | struct leaf *right; |
1025 | struct tree_buffer *right_buffer; | 1034 | struct tree_buffer *right_buffer; |
1026 | int space_needed = data_size + sizeof(struct item); | 1035 | int space_needed = data_size + sizeof(struct btrfs_item); |
1027 | int data_copy_size; | 1036 | int data_copy_size; |
1028 | int rt_data_off; | 1037 | int rt_data_off; |
1029 | int i; | 1038 | int i; |
@@ -1034,7 +1043,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path, | |||
1034 | l = &l_buf->leaf; | 1043 | l = &l_buf->leaf; |
1035 | 1044 | ||
1036 | /* did the pushes work? */ | 1045 | /* did the pushes work? */ |
1037 | if (leaf_free_space(l) >= sizeof(struct item) + data_size) | 1046 | if (leaf_free_space(l) >= sizeof(struct btrfs_item) + data_size) |
1038 | return 0; | 1047 | return 0; |
1039 | 1048 | ||
1040 | if (!path->nodes[1]) { | 1049 | if (!path->nodes[1]) { |
@@ -1066,17 +1075,17 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path, | |||
1066 | btrfs_set_header_level(&right->header, 0); | 1075 | btrfs_set_header_level(&right->header, 0); |
1067 | btrfs_set_header_parentid(&right->header, | 1076 | btrfs_set_header_parentid(&right->header, |
1068 | btrfs_header_parentid(&root->node->node.header)); | 1077 | btrfs_header_parentid(&root->node->node.header)); |
1069 | data_copy_size = l->items[mid].offset + l->items[mid].size - | 1078 | data_copy_size = btrfs_item_end(l->items + mid) - leaf_data_end(l); |
1070 | leaf_data_end(l); | ||
1071 | memcpy(right->items, l->items + mid, | 1079 | memcpy(right->items, l->items + mid, |
1072 | (nritems - mid) * sizeof(struct item)); | 1080 | (nritems - mid) * sizeof(struct btrfs_item)); |
1073 | memcpy(right->data + LEAF_DATA_SIZE - data_copy_size, | 1081 | memcpy(right->data + LEAF_DATA_SIZE - data_copy_size, |
1074 | l->data + leaf_data_end(l), data_copy_size); | 1082 | l->data + leaf_data_end(l), data_copy_size); |
1075 | rt_data_off = LEAF_DATA_SIZE - | 1083 | rt_data_off = LEAF_DATA_SIZE - btrfs_item_end(l->items + mid); |
1076 | (l->items[mid].offset + l->items[mid].size); | ||
1077 | 1084 | ||
1078 | for (i = 0; i < btrfs_header_nritems(&right->header); i++) | 1085 | for (i = 0; i < btrfs_header_nritems(&right->header); i++) { |
1079 | right->items[i].offset += rt_data_off; | 1086 | u16 ioff = btrfs_item_offset(right->items + i); |
1087 | btrfs_set_item_offset(right->items + i, ioff + rt_data_off); | ||
1088 | } | ||
1080 | 1089 | ||
1081 | btrfs_set_header_nritems(&l->header, mid); | 1090 | btrfs_set_header_nritems(&l->header, mid); |
1082 | ret = 0; | 1091 | ret = 0; |
@@ -1136,26 +1145,28 @@ int insert_item(struct ctree_root *root, struct btrfs_key *cpu_key, | |||
1136 | nritems = btrfs_header_nritems(&leaf->header); | 1145 | nritems = btrfs_header_nritems(&leaf->header); |
1137 | data_end = leaf_data_end(leaf); | 1146 | data_end = leaf_data_end(leaf); |
1138 | 1147 | ||
1139 | if (leaf_free_space(leaf) < sizeof(struct item) + data_size) | 1148 | if (leaf_free_space(leaf) < sizeof(struct btrfs_item) + data_size) |
1140 | BUG(); | 1149 | BUG(); |
1141 | 1150 | ||
1142 | slot = path.slots[0]; | 1151 | slot = path.slots[0]; |
1143 | BUG_ON(slot < 0); | 1152 | BUG_ON(slot < 0); |
1144 | if (slot != nritems) { | 1153 | if (slot != nritems) { |
1145 | int i; | 1154 | int i; |
1146 | unsigned int old_data = leaf->items[slot].offset + | 1155 | unsigned int old_data = btrfs_item_end(leaf->items + slot); |
1147 | leaf->items[slot].size; | ||
1148 | 1156 | ||
1149 | /* | 1157 | /* |
1150 | * item0..itemN ... dataN.offset..dataN.size .. data0.size | 1158 | * item0..itemN ... dataN.offset..dataN.size .. data0.size |
1151 | */ | 1159 | */ |
1152 | /* first correct the data pointers */ | 1160 | /* first correct the data pointers */ |
1153 | for (i = slot; i < nritems; i++) | 1161 | for (i = slot; i < nritems; i++) { |
1154 | leaf->items[i].offset -= data_size; | 1162 | u16 ioff = btrfs_item_offset(leaf->items + i); |
1163 | btrfs_set_item_offset(leaf->items + i, | ||
1164 | ioff - data_size); | ||
1165 | } | ||
1155 | 1166 | ||
1156 | /* shift the items */ | 1167 | /* shift the items */ |
1157 | memmove(leaf->items + slot + 1, leaf->items + slot, | 1168 | memmove(leaf->items + slot + 1, leaf->items + slot, |
1158 | (nritems - slot) * sizeof(struct item)); | 1169 | (nritems - slot) * sizeof(struct btrfs_item)); |
1159 | 1170 | ||
1160 | /* shift the data */ | 1171 | /* shift the data */ |
1161 | memmove(leaf->data + data_end - data_size, leaf->data + | 1172 | memmove(leaf->data + data_end - data_size, leaf->data + |
@@ -1165,8 +1176,8 @@ int insert_item(struct ctree_root *root, struct btrfs_key *cpu_key, | |||
1165 | /* copy the new data in */ | 1176 | /* copy the new data in */ |
1166 | memcpy(&leaf->items[slot].key, &disk_key, | 1177 | memcpy(&leaf->items[slot].key, &disk_key, |
1167 | sizeof(struct btrfs_disk_key)); | 1178 | sizeof(struct btrfs_disk_key)); |
1168 | leaf->items[slot].offset = data_end - data_size; | 1179 | btrfs_set_item_offset(leaf->items + slot, data_end - data_size); |
1169 | leaf->items[slot].size = data_size; | 1180 | btrfs_set_item_size(leaf->items + slot, data_size); |
1170 | memcpy(leaf->data + data_end - data_size, data, data_size); | 1181 | memcpy(leaf->data + data_end - data_size, data, data_size); |
1171 | btrfs_set_header_nritems(&leaf->header, nritems + 1); | 1182 | btrfs_set_header_nritems(&leaf->header, nritems + 1); |
1172 | 1183 | ||
@@ -1241,8 +1252,8 @@ int del_item(struct ctree_root *root, struct ctree_path *path) | |||
1241 | leaf_buf = path->nodes[0]; | 1252 | leaf_buf = path->nodes[0]; |
1242 | leaf = &leaf_buf->leaf; | 1253 | leaf = &leaf_buf->leaf; |
1243 | slot = path->slots[0]; | 1254 | slot = path->slots[0]; |
1244 | doff = leaf->items[slot].offset; | 1255 | doff = btrfs_item_offset(leaf->items + slot); |
1245 | dsize = leaf->items[slot].size; | 1256 | dsize = btrfs_item_size(leaf->items + slot); |
1246 | nritems = btrfs_header_nritems(&leaf->header); | 1257 | nritems = btrfs_header_nritems(&leaf->header); |
1247 | 1258 | ||
1248 | if (slot != nritems - 1) { | 1259 | if (slot != nritems - 1) { |
@@ -1251,10 +1262,12 @@ int del_item(struct ctree_root *root, struct ctree_path *path) | |||
1251 | memmove(leaf->data + data_end + dsize, | 1262 | memmove(leaf->data + data_end + dsize, |
1252 | leaf->data + data_end, | 1263 | leaf->data + data_end, |
1253 | doff - data_end); | 1264 | doff - data_end); |
1254 | for (i = slot + 1; i < nritems; i++) | 1265 | for (i = slot + 1; i < nritems; i++) { |
1255 | leaf->items[i].offset += dsize; | 1266 | u16 ioff = btrfs_item_offset(leaf->items + i); |
1267 | btrfs_set_item_offset(leaf->items + i, ioff + dsize); | ||
1268 | } | ||
1256 | memmove(leaf->items + slot, leaf->items + slot + 1, | 1269 | memmove(leaf->items + slot, leaf->items + slot + 1, |
1257 | sizeof(struct item) * | 1270 | sizeof(struct btrfs_item) * |
1258 | (nritems - slot - 1)); | 1271 | (nritems - slot - 1)); |
1259 | } | 1272 | } |
1260 | btrfs_set_header_nritems(&leaf->header, nritems - 1); | 1273 | btrfs_set_header_nritems(&leaf->header, nritems - 1); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 58e03e90f23a..b03df154dcdb 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -98,10 +98,10 @@ struct ctree_super_block { | |||
98 | * the key flags parameter. offset and size tell us where to find | 98 | * the key flags parameter. offset and size tell us where to find |
99 | * the item in the leaf (relative to the start of the data area) | 99 | * the item in the leaf (relative to the start of the data area) |
100 | */ | 100 | */ |
101 | struct item { | 101 | struct btrfs_item { |
102 | struct btrfs_disk_key key; | 102 | struct btrfs_disk_key key; |
103 | u16 offset; | 103 | __le16 offset; |
104 | u16 size; | 104 | __le16 size; |
105 | } __attribute__ ((__packed__)); | 105 | } __attribute__ ((__packed__)); |
106 | 106 | ||
107 | /* | 107 | /* |
@@ -115,7 +115,8 @@ struct item { | |||
115 | struct leaf { | 115 | struct leaf { |
116 | struct btrfs_header header; | 116 | struct btrfs_header header; |
117 | union { | 117 | union { |
118 | struct item items[LEAF_DATA_SIZE/sizeof(struct item)]; | 118 | struct btrfs_item items[LEAF_DATA_SIZE/ |
119 | sizeof(struct btrfs_item)]; | ||
119 | u8 data[CTREE_BLOCKSIZE-sizeof(struct btrfs_header)]; | 120 | u8 data[CTREE_BLOCKSIZE-sizeof(struct btrfs_header)]; |
120 | }; | 121 | }; |
121 | } __attribute__ ((__packed__)); | 122 | } __attribute__ ((__packed__)); |
@@ -152,6 +153,31 @@ struct ctree_path { | |||
152 | int slots[MAX_LEVEL]; | 153 | int slots[MAX_LEVEL]; |
153 | }; | 154 | }; |
154 | 155 | ||
156 | static inline u16 btrfs_item_offset(struct btrfs_item *item) | ||
157 | { | ||
158 | return le16_to_cpu(item->offset); | ||
159 | } | ||
160 | |||
161 | static inline void btrfs_set_item_offset(struct btrfs_item *item, u16 val) | ||
162 | { | ||
163 | item->offset = cpu_to_le16(val); | ||
164 | } | ||
165 | |||
166 | static inline u16 btrfs_item_end(struct btrfs_item *item) | ||
167 | { | ||
168 | return le16_to_cpu(item->offset) + le16_to_cpu(item->size); | ||
169 | } | ||
170 | |||
171 | static inline u16 btrfs_item_size(struct btrfs_item *item) | ||
172 | { | ||
173 | return le16_to_cpu(item->size); | ||
174 | } | ||
175 | |||
176 | static inline void btrfs_set_item_size(struct btrfs_item *item, u16 val) | ||
177 | { | ||
178 | item->size = cpu_to_le16(val); | ||
179 | } | ||
180 | |||
155 | static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu, | 181 | static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu, |
156 | struct btrfs_disk_key *disk) | 182 | struct btrfs_disk_key *disk) |
157 | { | 183 | { |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 475e72215964..fdf95bd07f90 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -40,8 +40,8 @@ static int inc_block_ref(struct ctree_root *root, u64 blocknr) | |||
40 | BUG(); | 40 | BUG(); |
41 | BUG_ON(ret != 0); | 41 | BUG_ON(ret != 0); |
42 | l = &path.nodes[0]->leaf; | 42 | l = &path.nodes[0]->leaf; |
43 | item = (struct extent_item *)(l->data + | 43 | item = (struct extent_item *)(l->data + btrfs_item_offset(l->items + |
44 | l->items[path.slots[0]].offset); | 44 | path.slots[0])); |
45 | item->refs++; | 45 | item->refs++; |
46 | 46 | ||
47 | BUG_ON(list_empty(&path.nodes[0]->dirty)); | 47 | BUG_ON(list_empty(&path.nodes[0]->dirty)); |
@@ -67,7 +67,8 @@ static int lookup_block_ref(struct ctree_root *root, u64 blocknr, u32 *refs) | |||
67 | BUG(); | 67 | BUG(); |
68 | l = &path.nodes[0]->leaf; | 68 | l = &path.nodes[0]->leaf; |
69 | item = (struct extent_item *)(l->data + | 69 | item = (struct extent_item *)(l->data + |
70 | l->items[path.slots[0]].offset); | 70 | btrfs_item_offset(l->items + |
71 | path.slots[0])); | ||
71 | *refs = item->refs; | 72 | *refs = item->refs; |
72 | release_path(root->extent_root, &path); | 73 | release_path(root->extent_root, &path); |
73 | return 0; | 74 | return 0; |
@@ -144,7 +145,7 @@ int __free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks) | |||
144 | struct btrfs_key key; | 145 | struct btrfs_key key; |
145 | struct ctree_root *extent_root = root->extent_root; | 146 | struct ctree_root *extent_root = root->extent_root; |
146 | int ret; | 147 | int ret; |
147 | struct item *item; | 148 | struct btrfs_item *item; |
148 | struct extent_item *ei; | 149 | struct extent_item *ei; |
149 | struct btrfs_key ins; | 150 | struct btrfs_key ins; |
150 | 151 | ||
@@ -162,7 +163,8 @@ int __free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks) | |||
162 | BUG(); | 163 | BUG(); |
163 | } | 164 | } |
164 | item = path.nodes[0]->leaf.items + path.slots[0]; | 165 | item = path.nodes[0]->leaf.items + path.slots[0]; |
165 | ei = (struct extent_item *)(path.nodes[0]->leaf.data + item->offset); | 166 | ei = (struct extent_item *)(path.nodes[0]->leaf.data + |
167 | btrfs_item_offset(item)); | ||
166 | BUG_ON(ei->refs == 0); | 168 | BUG_ON(ei->refs == 0); |
167 | ei->refs--; | 169 | ei->refs--; |
168 | if (ei->refs == 0) { | 170 | if (ei->refs == 0) { |
diff --git a/fs/btrfs/mkfs.c b/fs/btrfs/mkfs.c index 5290423343f8..0f77babcd306 100644 --- a/fs/btrfs/mkfs.c +++ b/fs/btrfs/mkfs.c | |||
@@ -14,7 +14,7 @@ int mkfs(int fd) | |||
14 | { | 14 | { |
15 | struct ctree_root_info info[2]; | 15 | struct ctree_root_info info[2]; |
16 | struct leaf empty_leaf; | 16 | struct leaf empty_leaf; |
17 | struct item item; | 17 | struct btrfs_item item; |
18 | struct extent_item extent_item; | 18 | struct extent_item extent_item; |
19 | int ret; | 19 | int ret; |
20 | 20 | ||
@@ -45,31 +45,37 @@ int mkfs(int fd) | |||
45 | btrfs_set_header_nritems(&empty_leaf.header, 3); | 45 | btrfs_set_header_nritems(&empty_leaf.header, 3); |
46 | 46 | ||
47 | /* item1, reserve blocks 0-16 */ | 47 | /* item1, reserve blocks 0-16 */ |
48 | item.key.objectid = cpu_to_le64(0); | 48 | btrfs_set_key_objectid(&item.key, 0); |
49 | item.key.offset = cpu_to_le64(17); | 49 | btrfs_set_key_offset(&item.key, 17); |
50 | item.key.flags = cpu_to_le32(0); | 50 | btrfs_set_key_flags(&item.key, 0); |
51 | item.offset = LEAF_DATA_SIZE - sizeof(struct extent_item); | 51 | btrfs_set_item_offset(&item, |
52 | item.size = sizeof(struct extent_item); | 52 | LEAF_DATA_SIZE - sizeof(struct extent_item)); |
53 | btrfs_set_item_size(&item, sizeof(struct extent_item)); | ||
53 | extent_item.refs = 1; | 54 | extent_item.refs = 1; |
54 | extent_item.owner = 0; | 55 | extent_item.owner = 0; |
55 | memcpy(empty_leaf.items, &item, sizeof(item)); | 56 | memcpy(empty_leaf.items, &item, sizeof(item)); |
56 | memcpy(empty_leaf.data + item.offset, &extent_item, item.size); | 57 | memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, |
58 | btrfs_item_size(&item)); | ||
57 | 59 | ||
58 | /* item2, give block 17 to the root */ | 60 | /* item2, give block 17 to the root */ |
59 | item.key.objectid = cpu_to_le64(17); | 61 | btrfs_set_key_objectid(&item.key, 17); |
60 | item.key.offset = cpu_to_le64(1); | 62 | btrfs_set_key_offset(&item.key, 1); |
61 | item.offset = LEAF_DATA_SIZE - sizeof(struct extent_item) * 2; | 63 | btrfs_set_item_offset(&item, |
64 | LEAF_DATA_SIZE - sizeof(struct extent_item) * 2); | ||
62 | extent_item.owner = 1; | 65 | extent_item.owner = 1; |
63 | memcpy(empty_leaf.items + 1, &item, sizeof(item)); | 66 | memcpy(empty_leaf.items + 1, &item, sizeof(item)); |
64 | memcpy(empty_leaf.data + item.offset, &extent_item, item.size); | 67 | memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, |
68 | btrfs_item_size(&item)); | ||
65 | 69 | ||
66 | /* item3, give block 18 for the extent root */ | 70 | /* item3, give block 18 for the extent root */ |
67 | item.key.objectid = cpu_to_le64(18); | 71 | btrfs_set_key_objectid(&item.key, 18); |
68 | item.key.offset = cpu_to_le64(1); | 72 | btrfs_set_key_offset(&item.key, 1); |
69 | item.offset = LEAF_DATA_SIZE - sizeof(struct extent_item) * 3; | 73 | btrfs_set_item_offset(&item, |
74 | LEAF_DATA_SIZE - sizeof(struct extent_item) * 3); | ||
70 | extent_item.owner = 2; | 75 | extent_item.owner = 2; |
71 | memcpy(empty_leaf.items + 2, &item, sizeof(item)); | 76 | memcpy(empty_leaf.items + 2, &item, sizeof(item)); |
72 | memcpy(empty_leaf.data + item.offset, &extent_item, item.size); | 77 | memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, |
78 | btrfs_item_size(&item)); | ||
73 | ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 18 * CTREE_BLOCKSIZE); | 79 | ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 18 * CTREE_BLOCKSIZE); |
74 | if (ret != sizeof(empty_leaf)) | 80 | if (ret != sizeof(empty_leaf)) |
75 | return -1; | 81 | return -1; |
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index 7df16b1e4733..33f5ee4052c1 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c | |||
@@ -9,7 +9,7 @@ void print_leaf(struct leaf *l) | |||
9 | { | 9 | { |
10 | int i; | 10 | int i; |
11 | u32 nr = btrfs_header_nritems(&l->header); | 11 | u32 nr = btrfs_header_nritems(&l->header); |
12 | struct item *item; | 12 | struct btrfs_item *item; |
13 | struct extent_item *ei; | 13 | struct extent_item *ei; |
14 | printf("leaf %Lu total ptrs %d free space %d\n", | 14 | printf("leaf %Lu total ptrs %d free space %d\n", |
15 | btrfs_header_blocknr(&l->header), nr, leaf_free_space(l)); | 15 | btrfs_header_blocknr(&l->header), nr, leaf_free_space(l)); |
@@ -18,12 +18,15 @@ void print_leaf(struct leaf *l) | |||
18 | item = l->items + i; | 18 | item = l->items + i; |
19 | printf("\titem %d key (%Lu %u %Lu) itemoff %d itemsize %d\n", | 19 | printf("\titem %d key (%Lu %u %Lu) itemoff %d itemsize %d\n", |
20 | i, | 20 | i, |
21 | item->key.objectid, item->key.flags, item->key.offset, | 21 | btrfs_key_objectid(&item->key), |
22 | item->offset, item->size); | 22 | btrfs_key_flags(&item->key), |
23 | btrfs_key_offset(&item->key), | ||
24 | btrfs_item_offset(item), | ||
25 | btrfs_item_size(item)); | ||
23 | fflush(stdout); | 26 | fflush(stdout); |
24 | printf("\t\titem data %.*s\n", item->size, | 27 | printf("\t\titem data %.*s\n", btrfs_item_size(item), |
25 | l->data+item->offset); | 28 | l->data + btrfs_item_offset(item)); |
26 | ei = (struct extent_item *)(l->data + item->offset); | 29 | ei = (struct extent_item *)(l->data + btrfs_item_offset(item)); |
27 | printf("\t\textent data refs %u owner %Lu\n", ei->refs, | 30 | printf("\t\textent data refs %u owner %Lu\n", ei->refs, |
28 | ei->owner); | 31 | ei->owner); |
29 | fflush(stdout); | 32 | fflush(stdout); |
diff --git a/fs/btrfs/random-test.c b/fs/btrfs/random-test.c index 34a15841ebd3..e767528bc521 100644 --- a/fs/btrfs/random-test.c +++ b/fs/btrfs/random-test.c | |||
@@ -173,7 +173,7 @@ static int empty_tree(struct ctree_root *root, struct radix_tree_root *radix, | |||
173 | path.slots[0] -= 1; | 173 | path.slots[0] -= 1; |
174 | } | 174 | } |
175 | slot = path.slots[0]; | 175 | slot = path.slots[0]; |
176 | found = path.nodes[0]->leaf.items[slot].key.objectid; | 176 | found=btrfs_key_objectid(&path.nodes[0]->leaf.items[slot].key); |
177 | ret = del_item(root, &path); | 177 | ret = del_item(root, &path); |
178 | count++; | 178 | count++; |
179 | if (ret) { | 179 | if (ret) { |
@@ -274,7 +274,8 @@ static int fill_radix(struct ctree_root *root, struct radix_tree_root *radix) | |||
274 | slot -= 1; | 274 | slot -= 1; |
275 | } | 275 | } |
276 | for (i = slot; i >= 0; i--) { | 276 | for (i = slot; i >= 0; i--) { |
277 | found = path.nodes[0]->leaf.items[i].key.objectid; | 277 | found = btrfs_key_objectid(&path.nodes[0]-> |
278 | leaf.items[i].key); | ||
278 | radix_tree_preload(GFP_KERNEL); | 279 | radix_tree_preload(GFP_KERNEL); |
279 | ret = radix_tree_insert(radix, found, (void *)found); | 280 | ret = radix_tree_insert(radix, found, (void *)found); |
280 | if (ret) { | 281 | if (ret) { |