aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-12 16:22:34 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-12 16:22:34 -0400
commite2fa7227cdf132d72e7410dd0679dc573a1c2618 (patch)
tree2f739ce2f7f7735c81a86c209290c050efa85ade /fs/btrfs/ctree.c
parentbb492bb0a5453222109a72859353728959c2539d (diff)
Btrfs: struct key endian fixes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c92
1 files changed, 54 insertions, 38 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index e43c827e0dfd..489019ac04b8 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -95,19 +95,23 @@ int leaf_free_space(struct leaf *leaf)
95/* 95/*
96 * compare two keys in a memcmp fashion 96 * compare two keys in a memcmp fashion
97 */ 97 */
98int comp_keys(struct key *k1, struct key *k2) 98int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
99{ 99{
100 if (k1->objectid > k2->objectid) 100 struct btrfs_key k1;
101
102 btrfs_disk_key_to_cpu(&k1, disk);
103
104 if (k1.objectid > k2->objectid)
101 return 1; 105 return 1;
102 if (k1->objectid < k2->objectid) 106 if (k1.objectid < k2->objectid)
103 return -1; 107 return -1;
104 if (k1->flags > k2->flags) 108 if (k1.flags > k2->flags)
105 return 1; 109 return 1;
106 if (k1->flags < k2->flags) 110 if (k1.flags < k2->flags)
107 return -1; 111 return -1;
108 if (k1->offset > k2->offset) 112 if (k1.offset > k2->offset)
109 return 1; 113 return 1;
110 if (k1->offset < k2->offset) 114 if (k1.offset < k2->offset)
111 return -1; 115 return -1;
112 return 0; 116 return 0;
113} 117}
@@ -125,15 +129,18 @@ int check_node(struct ctree_path *path, int level)
125 parent_slot = path->slots[level + 1]; 129 parent_slot = path->slots[level + 1];
126 BUG_ON(nritems == 0); 130 BUG_ON(nritems == 0);
127 if (parent) { 131 if (parent) {
128 struct key *parent_key; 132 struct btrfs_disk_key *parent_key;
129 parent_key = &parent->keys[parent_slot]; 133 parent_key = &parent->keys[parent_slot];
130 BUG_ON(memcmp(parent_key, node->keys, sizeof(struct key))); 134 BUG_ON(memcmp(parent_key, node->keys,
135 sizeof(struct btrfs_disk_key)));
131 BUG_ON(parent->blockptrs[parent_slot] != 136 BUG_ON(parent->blockptrs[parent_slot] !=
132 btrfs_header_blocknr(&node->header)); 137 btrfs_header_blocknr(&node->header));
133 } 138 }
134 BUG_ON(nritems > NODEPTRS_PER_BLOCK); 139 BUG_ON(nritems > NODEPTRS_PER_BLOCK);
135 for (i = 0; nritems > 1 && i < nritems - 2; i++) { 140 for (i = 0; nritems > 1 && i < nritems - 2; i++) {
136 BUG_ON(comp_keys(&node->keys[i], &node->keys[i+1]) >= 0); 141 struct btrfs_key cpukey;
142 btrfs_disk_key_to_cpu(&cpukey, &node->keys[i + 1]);
143 BUG_ON(comp_keys(&node->keys[i], &cpukey) >= 0);
137 } 144 }
138 return 0; 145 return 0;
139} 146}
@@ -155,16 +162,18 @@ int check_leaf(struct ctree_path *path, int level)
155 return 0; 162 return 0;
156 163
157 if (parent) { 164 if (parent) {
158 struct key *parent_key; 165 struct btrfs_disk_key *parent_key;
159 parent_key = &parent->keys[parent_slot]; 166 parent_key = &parent->keys[parent_slot];
160 BUG_ON(memcmp(parent_key, &leaf->items[0].key, 167 BUG_ON(memcmp(parent_key, &leaf->items[0].key,
161 sizeof(struct key))); 168 sizeof(struct btrfs_disk_key)));
162 BUG_ON(parent->blockptrs[parent_slot] != 169 BUG_ON(parent->blockptrs[parent_slot] !=
163 btrfs_header_blocknr(&leaf->header)); 170 btrfs_header_blocknr(&leaf->header));
164 } 171 }
165 for (i = 0; nritems > 1 && i < nritems - 2; i++) { 172 for (i = 0; nritems > 1 && i < nritems - 2; i++) {
173 struct btrfs_key cpukey;
174 btrfs_disk_key_to_cpu(&cpukey, &leaf->items[i + 1].key);
166 BUG_ON(comp_keys(&leaf->items[i].key, 175 BUG_ON(comp_keys(&leaf->items[i].key,
167 &leaf->items[i+1].key) >= 0); 176 &cpukey) >= 0);
168 BUG_ON(leaf->items[i].offset != leaf->items[i + 1].offset + 177 BUG_ON(leaf->items[i].offset != leaf->items[i + 1].offset +
169 leaf->items[i + 1].size); 178 leaf->items[i + 1].size);
170 if (i == 0) { 179 if (i == 0) {
@@ -191,18 +200,18 @@ int check_block(struct ctree_path *path, int level)
191 * 200 *
192 * slot may point to max if the key is bigger than all of the keys 201 * slot may point to max if the key is bigger than all of the keys
193 */ 202 */
194int generic_bin_search(char *p, int item_size, struct key *key, 203int generic_bin_search(char *p, int item_size, struct btrfs_key *key,
195 int max, int *slot) 204 int max, int *slot)
196{ 205{
197 int low = 0; 206 int low = 0;
198 int high = max; 207 int high = max;
199 int mid; 208 int mid;
200 int ret; 209 int ret;
201 struct key *tmp; 210 struct btrfs_disk_key *tmp;
202 211
203 while(low < high) { 212 while(low < high) {
204 mid = (low + high) / 2; 213 mid = (low + high) / 2;
205 tmp = (struct key *)(p + mid * item_size); 214 tmp = (struct btrfs_disk_key *)(p + mid * item_size);
206 ret = comp_keys(tmp, key); 215 ret = comp_keys(tmp, key);
207 216
208 if (ret < 0) 217 if (ret < 0)
@@ -222,7 +231,7 @@ int generic_bin_search(char *p, int item_size, struct key *key,
222 * simple bin_search frontend that does the right thing for 231 * simple bin_search frontend that does the right thing for
223 * leaves vs nodes 232 * leaves vs nodes
224 */ 233 */
225int bin_search(struct node *c, struct key *key, int *slot) 234int bin_search(struct node *c, struct btrfs_key *key, int *slot)
226{ 235{
227 if (btrfs_is_leaf(c)) { 236 if (btrfs_is_leaf(c)) {
228 struct leaf *l = (struct leaf *)c; 237 struct leaf *l = (struct leaf *)c;
@@ -230,7 +239,8 @@ int bin_search(struct node *c, struct key *key, int *slot)
230 key, btrfs_header_nritems(&c->header), 239 key, btrfs_header_nritems(&c->header),
231 slot); 240 slot);
232 } else { 241 } else {
233 return generic_bin_search((void *)c->keys, sizeof(struct key), 242 return generic_bin_search((void *)c->keys,
243 sizeof(struct btrfs_disk_key),
234 key, btrfs_header_nritems(&c->header), 244 key, btrfs_header_nritems(&c->header),
235 slot); 245 slot);
236 } 246 }
@@ -339,7 +349,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
339 ret = wret; 349 ret = wret;
340 } else { 350 } else {
341 memcpy(parent->keys + pslot + 1, right->keys, 351 memcpy(parent->keys + pslot + 1, right->keys,
342 sizeof(struct key)); 352 sizeof(struct btrfs_disk_key));
343 BUG_ON(list_empty(&parent_buf->dirty)); 353 BUG_ON(list_empty(&parent_buf->dirty));
344 } 354 }
345 } 355 }
@@ -374,7 +384,8 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
374 ret = wret; 384 ret = wret;
375 } else { 385 } else {
376 /* update the parent key to reflect our changes */ 386 /* update the parent key to reflect our changes */
377 memcpy(parent->keys + pslot, mid->keys, sizeof(struct key)); 387 memcpy(parent->keys + pslot, mid->keys,
388 sizeof(struct btrfs_disk_key));
378 BUG_ON(list_empty(&parent_buf->dirty)); 389 BUG_ON(list_empty(&parent_buf->dirty));
379 } 390 }
380 391
@@ -417,7 +428,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
417 * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if 428 * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if
418 * possible) 429 * possible)
419 */ 430 */
420int search_slot(struct ctree_root *root, struct key *key, 431int search_slot(struct ctree_root *root, struct btrfs_key *key,
421 struct ctree_path *p, int ins_len, int cow) 432 struct ctree_path *p, int ins_len, int cow)
422{ 433{
423 struct tree_buffer *b; 434 struct tree_buffer *b;
@@ -499,7 +510,7 @@ again:
499 * fixing up the blocks in ram so the tree is consistent. 510 * fixing up the blocks in ram so the tree is consistent.
500 */ 511 */
501static int fixup_low_keys(struct ctree_root *root, 512static int fixup_low_keys(struct ctree_root *root,
502 struct ctree_path *path, struct key *key, 513 struct ctree_path *path, struct btrfs_disk_key *key,
503 int level) 514 int level)
504{ 515{
505 int i; 516 int i;
@@ -546,12 +557,13 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
546 push_items = src_nritems; 557 push_items = src_nritems;
547 558
548 memcpy(dst->keys + dst_nritems, src->keys, 559 memcpy(dst->keys + dst_nritems, src->keys,
549 push_items * sizeof(struct key)); 560 push_items * sizeof(struct btrfs_disk_key));
550 memcpy(dst->blockptrs + dst_nritems, src->blockptrs, 561 memcpy(dst->blockptrs + dst_nritems, src->blockptrs,
551 push_items * sizeof(u64)); 562 push_items * sizeof(u64));
552 if (push_items < src_nritems) { 563 if (push_items < src_nritems) {
553 memmove(src->keys, src->keys + push_items, 564 memmove(src->keys, src->keys + push_items,
554 (src_nritems - push_items) * sizeof(struct key)); 565 (src_nritems - push_items) *
566 sizeof(struct btrfs_disk_key));
555 memmove(src->blockptrs, src->blockptrs + push_items, 567 memmove(src->blockptrs, src->blockptrs + push_items,
556 (src_nritems - push_items) * sizeof(u64)); 568 (src_nritems - push_items) * sizeof(u64));
557 } 569 }
@@ -598,11 +610,11 @@ static int balance_node_right(struct ctree_root *root,
598 push_items = max_push; 610 push_items = max_push;
599 611
600 memmove(dst->keys + push_items, dst->keys, 612 memmove(dst->keys + push_items, dst->keys,
601 dst_nritems * sizeof(struct key)); 613 dst_nritems * sizeof(struct btrfs_disk_key));
602 memmove(dst->blockptrs + push_items, dst->blockptrs, 614 memmove(dst->blockptrs + push_items, dst->blockptrs,
603 dst_nritems * sizeof(u64)); 615 dst_nritems * sizeof(u64));
604 memcpy(dst->keys, src->keys + src_nritems - push_items, 616 memcpy(dst->keys, src->keys + src_nritems - push_items,
605 push_items * sizeof(struct key)); 617 push_items * sizeof(struct btrfs_disk_key));
606 memcpy(dst->blockptrs, src->blockptrs + src_nritems - push_items, 618 memcpy(dst->blockptrs, src->blockptrs + src_nritems - push_items,
607 push_items * sizeof(u64)); 619 push_items * sizeof(u64));
608 620
@@ -627,7 +639,7 @@ static int insert_new_root(struct ctree_root *root,
627 struct tree_buffer *t; 639 struct tree_buffer *t;
628 struct node *lower; 640 struct node *lower;
629 struct node *c; 641 struct node *c;
630 struct key *lower_key; 642 struct btrfs_disk_key *lower_key;
631 643
632 BUG_ON(path->nodes[level]); 644 BUG_ON(path->nodes[level]);
633 BUG_ON(path->nodes[level-1] != root->node); 645 BUG_ON(path->nodes[level-1] != root->node);
@@ -645,7 +657,7 @@ static int insert_new_root(struct ctree_root *root,
645 lower_key = &((struct leaf *)lower)->items[0].key; 657 lower_key = &((struct leaf *)lower)->items[0].key;
646 else 658 else
647 lower_key = lower->keys; 659 lower_key = lower->keys;
648 memcpy(c->keys, lower_key, sizeof(struct key)); 660 memcpy(c->keys, lower_key, sizeof(struct btrfs_disk_key));
649 c->blockptrs[0] = path->nodes[level-1]->blocknr; 661 c->blockptrs[0] = path->nodes[level-1]->blocknr;
650 /* the super has an extra ref to root->node */ 662 /* the super has an extra ref to root->node */
651 tree_block_release(root, root->node); 663 tree_block_release(root, root->node);
@@ -666,7 +678,7 @@ static int insert_new_root(struct ctree_root *root,
666 * returns zero on success and < 0 on any error 678 * returns zero on success and < 0 on any error
667 */ 679 */
668static int insert_ptr(struct ctree_root *root, 680static int insert_ptr(struct ctree_root *root,
669 struct ctree_path *path, struct key *key, 681 struct ctree_path *path, struct btrfs_disk_key *key,
670 u64 blocknr, int slot, int level) 682 u64 blocknr, int slot, int level)
671{ 683{
672 struct node *lower; 684 struct node *lower;
@@ -681,11 +693,11 @@ static int insert_ptr(struct ctree_root *root,
681 BUG(); 693 BUG();
682 if (slot != nritems) { 694 if (slot != nritems) {
683 memmove(lower->keys + slot + 1, lower->keys + slot, 695 memmove(lower->keys + slot + 1, lower->keys + slot,
684 (nritems - slot) * sizeof(struct key)); 696 (nritems - slot) * sizeof(struct btrfs_disk_key));
685 memmove(lower->blockptrs + slot + 1, lower->blockptrs + slot, 697 memmove(lower->blockptrs + slot + 1, lower->blockptrs + slot,
686 (nritems - slot) * sizeof(u64)); 698 (nritems - slot) * sizeof(u64));
687 } 699 }
688 memcpy(lower->keys + slot, key, sizeof(struct key)); 700 memcpy(lower->keys + slot, key, sizeof(struct btrfs_disk_key));
689 lower->blockptrs[slot] = blocknr; 701 lower->blockptrs[slot] = blocknr;
690 btrfs_set_header_nritems(&lower->header, nritems + 1); 702 btrfs_set_header_nritems(&lower->header, nritems + 1);
691 if (lower->keys[1].objectid == 0) 703 if (lower->keys[1].objectid == 0)
@@ -732,7 +744,7 @@ static int split_node(struct ctree_root *root, struct ctree_path *path,
732 btrfs_header_parentid(&root->node->node.header)); 744 btrfs_header_parentid(&root->node->node.header));
733 mid = (c_nritems + 1) / 2; 745 mid = (c_nritems + 1) / 2;
734 memcpy(split->keys, c->keys + mid, 746 memcpy(split->keys, c->keys + mid,
735 (c_nritems - mid) * sizeof(struct key)); 747 (c_nritems - mid) * sizeof(struct btrfs_disk_key));
736 memcpy(split->blockptrs, c->blockptrs + mid, 748 memcpy(split->blockptrs, c->blockptrs + mid,
737 (c_nritems - mid) * sizeof(u64)); 749 (c_nritems - mid) * sizeof(u64));
738 btrfs_set_header_nritems(&split->header, c_nritems - mid); 750 btrfs_set_header_nritems(&split->header, c_nritems - mid);
@@ -869,7 +881,7 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
869 BUG_ON(list_empty(&left_buf->dirty)); 881 BUG_ON(list_empty(&left_buf->dirty));
870 BUG_ON(list_empty(&right_buf->dirty)); 882 BUG_ON(list_empty(&right_buf->dirty));
871 memcpy(upper->node.keys + slot + 1, 883 memcpy(upper->node.keys + slot + 1,
872 &right->items[0].key, sizeof(struct key)); 884 &right->items[0].key, sizeof(struct btrfs_disk_key));
873 BUG_ON(list_empty(&upper->dirty)); 885 BUG_ON(list_empty(&upper->dirty));
874 886
875 /* then fixup the leaf pointer in the path */ 887 /* then fixup the leaf pointer in the path */
@@ -1090,7 +1102,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
1090 * Given a key and some data, insert an item into the tree. 1102 * Given a key and some data, insert an item into the tree.
1091 * This does all the path init required, making room in the tree if needed. 1103 * This does all the path init required, making room in the tree if needed.
1092 */ 1104 */
1093int insert_item(struct ctree_root *root, struct key *key, 1105int insert_item(struct ctree_root *root, struct btrfs_key *cpu_key,
1094 void *data, int data_size) 1106 void *data, int data_size)
1095{ 1107{
1096 int ret = 0; 1108 int ret = 0;
@@ -1101,12 +1113,15 @@ int insert_item(struct ctree_root *root, struct key *key,
1101 u32 nritems; 1113 u32 nritems;
1102 unsigned int data_end; 1114 unsigned int data_end;
1103 struct ctree_path path; 1115 struct ctree_path path;
1116 struct btrfs_disk_key disk_key;
1117
1118 btrfs_cpu_key_to_disk(&disk_key, cpu_key);
1104 1119
1105 /* create a root if there isn't one */ 1120 /* create a root if there isn't one */
1106 if (!root->node) 1121 if (!root->node)
1107 BUG(); 1122 BUG();
1108 init_path(&path); 1123 init_path(&path);
1109 ret = search_slot(root, key, &path, data_size, 1); 1124 ret = search_slot(root, cpu_key, &path, data_size, 1);
1110 if (ret == 0) { 1125 if (ret == 0) {
1111 release_path(root, &path); 1126 release_path(root, &path);
1112 return -EEXIST; 1127 return -EEXIST;
@@ -1148,7 +1163,8 @@ int insert_item(struct ctree_root *root, struct key *key,
1148 data_end = old_data; 1163 data_end = old_data;
1149 } 1164 }
1150 /* copy the new data in */ 1165 /* copy the new data in */
1151 memcpy(&leaf->items[slot].key, key, sizeof(struct key)); 1166 memcpy(&leaf->items[slot].key, &disk_key,
1167 sizeof(struct btrfs_disk_key));
1152 leaf->items[slot].offset = data_end - data_size; 1168 leaf->items[slot].offset = data_end - data_size;
1153 leaf->items[slot].size = data_size; 1169 leaf->items[slot].size = data_size;
1154 memcpy(leaf->data + data_end - data_size, data, data_size); 1170 memcpy(leaf->data + data_end - data_size, data, data_size);
@@ -1156,7 +1172,7 @@ int insert_item(struct ctree_root *root, struct key *key,
1156 1172
1157 ret = 0; 1173 ret = 0;
1158 if (slot == 0) 1174 if (slot == 0)
1159 ret = fixup_low_keys(root, &path, key, 1); 1175 ret = fixup_low_keys(root, &path, &disk_key, 1);
1160 1176
1161 BUG_ON(list_empty(&leaf_buf->dirty)); 1177 BUG_ON(list_empty(&leaf_buf->dirty));
1162 if (leaf_free_space(leaf) < 0) 1178 if (leaf_free_space(leaf) < 0)
@@ -1187,7 +1203,7 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
1187 nritems = btrfs_header_nritems(&node->header); 1203 nritems = btrfs_header_nritems(&node->header);
1188 if (slot != nritems -1) { 1204 if (slot != nritems -1) {
1189 memmove(node->keys + slot, node->keys + slot + 1, 1205 memmove(node->keys + slot, node->keys + slot + 1,
1190 sizeof(struct key) * (nritems - slot - 1)); 1206 sizeof(struct btrfs_disk_key) * (nritems - slot - 1));
1191 memmove(node->blockptrs + slot, 1207 memmove(node->blockptrs + slot,
1192 node->blockptrs + slot + 1, 1208 node->blockptrs + slot + 1,
1193 sizeof(u64) * (nritems - slot - 1)); 1209 sizeof(u64) * (nritems - slot - 1));