diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 224 |
1 files changed, 126 insertions, 98 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 729d4ddb3746..e43c827e0dfd 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -48,7 +48,7 @@ int btrfs_cow_block(struct ctree_root *root, | |||
48 | } | 48 | } |
49 | cow = alloc_free_block(root); | 49 | cow = alloc_free_block(root); |
50 | memcpy(&cow->node, &buf->node, sizeof(buf->node)); | 50 | memcpy(&cow->node, &buf->node, sizeof(buf->node)); |
51 | cow->node.header.blocknr = cow->blocknr; | 51 | btrfs_set_header_blocknr(&cow->node.header, cow->blocknr); |
52 | *cow_ret = cow; | 52 | *cow_ret = cow; |
53 | btrfs_inc_ref(root, buf); | 53 | btrfs_inc_ref(root, buf); |
54 | if (buf == root->node) { | 54 | if (buf == root->node) { |
@@ -73,7 +73,7 @@ int btrfs_cow_block(struct ctree_root *root, | |||
73 | */ | 73 | */ |
74 | static inline unsigned int leaf_data_end(struct leaf *leaf) | 74 | static inline unsigned int leaf_data_end(struct leaf *leaf) |
75 | { | 75 | { |
76 | unsigned int nr = leaf->header.nritems; | 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 leaf->items[nr-1].offset; |
@@ -87,7 +87,7 @@ static inline unsigned int leaf_data_end(struct leaf *leaf) | |||
87 | int leaf_free_space(struct leaf *leaf) | 87 | int leaf_free_space(struct leaf *leaf) |
88 | { | 88 | { |
89 | int data_end = leaf_data_end(leaf); | 89 | int data_end = leaf_data_end(leaf); |
90 | int nritems = leaf->header.nritems; | 90 | int nritems = btrfs_header_nritems(&leaf->header); |
91 | char *items_end = (char *)(leaf->items + nritems + 1); | 91 | char *items_end = (char *)(leaf->items + nritems + 1); |
92 | return (char *)(leaf->data + data_end) - (char *)items_end; | 92 | return (char *)(leaf->data + data_end) - (char *)items_end; |
93 | } | 93 | } |
@@ -118,18 +118,21 @@ int check_node(struct ctree_path *path, int level) | |||
118 | struct node *parent = NULL; | 118 | struct node *parent = NULL; |
119 | struct node *node = &path->nodes[level]->node; | 119 | struct node *node = &path->nodes[level]->node; |
120 | int parent_slot; | 120 | int parent_slot; |
121 | u32 nritems = btrfs_header_nritems(&node->header); | ||
121 | 122 | ||
122 | if (path->nodes[level + 1]) | 123 | if (path->nodes[level + 1]) |
123 | parent = &path->nodes[level + 1]->node; | 124 | parent = &path->nodes[level + 1]->node; |
124 | parent_slot = path->slots[level + 1]; | 125 | parent_slot = path->slots[level + 1]; |
125 | if (parent && node->header.nritems > 0) { | 126 | BUG_ON(nritems == 0); |
127 | if (parent) { | ||
126 | struct key *parent_key; | 128 | struct key *parent_key; |
127 | parent_key = &parent->keys[parent_slot]; | 129 | parent_key = &parent->keys[parent_slot]; |
128 | BUG_ON(memcmp(parent_key, node->keys, sizeof(struct key))); | 130 | BUG_ON(memcmp(parent_key, node->keys, sizeof(struct key))); |
129 | BUG_ON(parent->blockptrs[parent_slot] != node->header.blocknr); | 131 | BUG_ON(parent->blockptrs[parent_slot] != |
132 | btrfs_header_blocknr(&node->header)); | ||
130 | } | 133 | } |
131 | BUG_ON(node->header.nritems > NODEPTRS_PER_BLOCK); | 134 | BUG_ON(nritems > NODEPTRS_PER_BLOCK); |
132 | for (i = 0; i < node->header.nritems - 2; i++) { | 135 | for (i = 0; nritems > 1 && i < nritems - 2; i++) { |
133 | BUG_ON(comp_keys(&node->keys[i], &node->keys[i+1]) >= 0); | 136 | BUG_ON(comp_keys(&node->keys[i], &node->keys[i+1]) >= 0); |
134 | } | 137 | } |
135 | return 0; | 138 | return 0; |
@@ -141,18 +144,25 @@ int check_leaf(struct ctree_path *path, int level) | |||
141 | struct leaf *leaf = &path->nodes[level]->leaf; | 144 | struct leaf *leaf = &path->nodes[level]->leaf; |
142 | struct node *parent = NULL; | 145 | struct node *parent = NULL; |
143 | int parent_slot; | 146 | int parent_slot; |
147 | u32 nritems = btrfs_header_nritems(&leaf->header); | ||
144 | 148 | ||
145 | if (path->nodes[level + 1]) | 149 | if (path->nodes[level + 1]) |
146 | parent = &path->nodes[level + 1]->node; | 150 | parent = &path->nodes[level + 1]->node; |
147 | parent_slot = path->slots[level + 1]; | 151 | parent_slot = path->slots[level + 1]; |
148 | if (parent && leaf->header.nritems > 0) { | 152 | BUG_ON(leaf_free_space(leaf) < 0); |
153 | |||
154 | if (nritems == 0) | ||
155 | return 0; | ||
156 | |||
157 | if (parent) { | ||
149 | struct key *parent_key; | 158 | struct key *parent_key; |
150 | parent_key = &parent->keys[parent_slot]; | 159 | parent_key = &parent->keys[parent_slot]; |
151 | BUG_ON(memcmp(parent_key, &leaf->items[0].key, | 160 | BUG_ON(memcmp(parent_key, &leaf->items[0].key, |
152 | sizeof(struct key))); | 161 | sizeof(struct key))); |
153 | BUG_ON(parent->blockptrs[parent_slot] != leaf->header.blocknr); | 162 | BUG_ON(parent->blockptrs[parent_slot] != |
163 | btrfs_header_blocknr(&leaf->header)); | ||
154 | } | 164 | } |
155 | for (i = 0; i < leaf->header.nritems - 2; i++) { | 165 | for (i = 0; nritems > 1 && i < nritems - 2; i++) { |
156 | BUG_ON(comp_keys(&leaf->items[i].key, | 166 | BUG_ON(comp_keys(&leaf->items[i].key, |
157 | &leaf->items[i+1].key) >= 0); | 167 | &leaf->items[i+1].key) >= 0); |
158 | BUG_ON(leaf->items[i].offset != leaf->items[i + 1].offset + | 168 | BUG_ON(leaf->items[i].offset != leaf->items[i + 1].offset + |
@@ -162,7 +172,6 @@ int check_leaf(struct ctree_path *path, int level) | |||
162 | LEAF_DATA_SIZE); | 172 | LEAF_DATA_SIZE); |
163 | } | 173 | } |
164 | } | 174 | } |
165 | BUG_ON(leaf_free_space(leaf) < 0); | ||
166 | return 0; | 175 | return 0; |
167 | } | 176 | } |
168 | 177 | ||
@@ -215,13 +224,15 @@ int generic_bin_search(char *p, int item_size, struct key *key, | |||
215 | */ | 224 | */ |
216 | int bin_search(struct node *c, struct key *key, int *slot) | 225 | int bin_search(struct node *c, struct key *key, int *slot) |
217 | { | 226 | { |
218 | if (is_leaf(c->header.flags)) { | 227 | if (btrfs_is_leaf(c)) { |
219 | struct leaf *l = (struct leaf *)c; | 228 | struct leaf *l = (struct leaf *)c; |
220 | return generic_bin_search((void *)l->items, sizeof(struct item), | 229 | return generic_bin_search((void *)l->items, sizeof(struct item), |
221 | key, c->header.nritems, slot); | 230 | key, btrfs_header_nritems(&c->header), |
231 | slot); | ||
222 | } else { | 232 | } else { |
223 | return generic_bin_search((void *)c->keys, sizeof(struct key), | 233 | return generic_bin_search((void *)c->keys, sizeof(struct key), |
224 | key, c->header.nritems, slot); | 234 | key, btrfs_header_nritems(&c->header), |
235 | slot); | ||
225 | } | 236 | } |
226 | return -1; | 237 | return -1; |
227 | } | 238 | } |
@@ -233,7 +244,7 @@ struct tree_buffer *read_node_slot(struct ctree_root *root, | |||
233 | struct node *node = &parent_buf->node; | 244 | struct node *node = &parent_buf->node; |
234 | if (slot < 0) | 245 | if (slot < 0) |
235 | return NULL; | 246 | return NULL; |
236 | if (slot >= node->header.nritems) | 247 | if (slot >= btrfs_header_nritems(&node->header)) |
237 | return NULL; | 248 | return NULL; |
238 | return read_tree_block(root, node->blockptrs[slot]); | 249 | return read_tree_block(root, node->blockptrs[slot]); |
239 | } | 250 | } |
@@ -270,7 +281,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path, | |||
270 | struct tree_buffer *child; | 281 | struct tree_buffer *child; |
271 | u64 blocknr = mid_buf->blocknr; | 282 | u64 blocknr = mid_buf->blocknr; |
272 | 283 | ||
273 | if (mid->header.nritems != 1) | 284 | if (btrfs_header_nritems(&mid->header) != 1) |
274 | return 0; | 285 | return 0; |
275 | 286 | ||
276 | /* promote the child to a root */ | 287 | /* promote the child to a root */ |
@@ -287,7 +298,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path, | |||
287 | } | 298 | } |
288 | parent = &parent_buf->node; | 299 | parent = &parent_buf->node; |
289 | 300 | ||
290 | if (mid->header.nritems > NODEPTRS_PER_BLOCK / 4) | 301 | if (btrfs_header_nritems(&mid->header) > NODEPTRS_PER_BLOCK / 4) |
291 | return 0; | 302 | return 0; |
292 | 303 | ||
293 | left_buf = read_node_slot(root, parent_buf, pslot - 1); | 304 | left_buf = read_node_slot(root, parent_buf, pslot - 1); |
@@ -298,7 +309,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path, | |||
298 | btrfs_cow_block(root, left_buf, parent_buf, | 309 | btrfs_cow_block(root, left_buf, parent_buf, |
299 | pslot - 1, &left_buf); | 310 | pslot - 1, &left_buf); |
300 | left = &left_buf->node; | 311 | left = &left_buf->node; |
301 | orig_slot += left->header.nritems; | 312 | orig_slot += btrfs_header_nritems(&left->header); |
302 | wret = push_node_left(root, left_buf, mid_buf); | 313 | wret = push_node_left(root, left_buf, mid_buf); |
303 | if (wret < 0) | 314 | if (wret < 0) |
304 | ret = wret; | 315 | ret = wret; |
@@ -314,7 +325,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path, | |||
314 | wret = push_node_left(root, mid_buf, right_buf); | 325 | wret = push_node_left(root, mid_buf, right_buf); |
315 | if (wret < 0) | 326 | if (wret < 0) |
316 | ret = wret; | 327 | ret = wret; |
317 | if (right->header.nritems == 0) { | 328 | if (btrfs_header_nritems(&right->header) == 0) { |
318 | u64 blocknr = right_buf->blocknr; | 329 | u64 blocknr = right_buf->blocknr; |
319 | tree_block_release(root, right_buf); | 330 | tree_block_release(root, right_buf); |
320 | clean_tree_block(root, right_buf); | 331 | clean_tree_block(root, right_buf); |
@@ -332,7 +343,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path, | |||
332 | BUG_ON(list_empty(&parent_buf->dirty)); | 343 | BUG_ON(list_empty(&parent_buf->dirty)); |
333 | } | 344 | } |
334 | } | 345 | } |
335 | if (mid->header.nritems == 1) { | 346 | if (btrfs_header_nritems(&mid->header) == 1) { |
336 | /* | 347 | /* |
337 | * we're not allowed to leave a node with one item in the | 348 | * we're not allowed to leave a node with one item in the |
338 | * tree during a delete. A deletion from lower in the tree | 349 | * tree during a delete. A deletion from lower in the tree |
@@ -348,7 +359,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path, | |||
348 | ret = wret; | 359 | ret = wret; |
349 | BUG_ON(wret == 1); | 360 | BUG_ON(wret == 1); |
350 | } | 361 | } |
351 | if (mid->header.nritems == 0) { | 362 | if (btrfs_header_nritems(&mid->header) == 0) { |
352 | /* we've managed to empty the middle node, drop it */ | 363 | /* we've managed to empty the middle node, drop it */ |
353 | u64 blocknr = mid_buf->blocknr; | 364 | u64 blocknr = mid_buf->blocknr; |
354 | tree_block_release(root, mid_buf); | 365 | tree_block_release(root, mid_buf); |
@@ -369,7 +380,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path, | |||
369 | 380 | ||
370 | /* update the path */ | 381 | /* update the path */ |
371 | if (left_buf) { | 382 | if (left_buf) { |
372 | if (left->header.nritems > orig_slot) { | 383 | if (btrfs_header_nritems(&left->header) > orig_slot) { |
373 | left_buf->count++; // released below | 384 | left_buf->count++; // released below |
374 | path->nodes[level] = left_buf; | 385 | path->nodes[level] = left_buf; |
375 | path->slots[level + 1] -= 1; | 386 | path->slots[level + 1] -= 1; |
@@ -377,7 +388,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path, | |||
377 | if (mid_buf) | 388 | if (mid_buf) |
378 | tree_block_release(root, mid_buf); | 389 | tree_block_release(root, mid_buf); |
379 | } else { | 390 | } else { |
380 | orig_slot -= left->header.nritems; | 391 | orig_slot -= btrfs_header_nritems(&left->header); |
381 | path->slots[level] = orig_slot; | 392 | path->slots[level] = orig_slot; |
382 | } | 393 | } |
383 | } | 394 | } |
@@ -420,7 +431,7 @@ again: | |||
420 | b = root->node; | 431 | b = root->node; |
421 | b->count++; | 432 | b->count++; |
422 | while (b) { | 433 | while (b) { |
423 | level = node_level(b->node.header.flags); | 434 | level = btrfs_header_level(&b->node.header); |
424 | if (cow) { | 435 | if (cow) { |
425 | int wret; | 436 | int wret; |
426 | wret = btrfs_cow_block(root, b, p->nodes[level + 1], | 437 | wret = btrfs_cow_block(root, b, p->nodes[level + 1], |
@@ -434,12 +445,12 @@ again: | |||
434 | if (ret) | 445 | if (ret) |
435 | return -1; | 446 | return -1; |
436 | ret = bin_search(c, key, &slot); | 447 | ret = bin_search(c, key, &slot); |
437 | if (!is_leaf(c->header.flags)) { | 448 | if (!btrfs_is_leaf(c)) { |
438 | if (ret && slot > 0) | 449 | if (ret && slot > 0) |
439 | slot -= 1; | 450 | slot -= 1; |
440 | p->slots[level] = slot; | 451 | p->slots[level] = slot; |
441 | if (ins_len > 0 && | 452 | if (ins_len > 0 && btrfs_header_nritems(&c->header) == |
442 | c->header.nritems == NODEPTRS_PER_BLOCK) { | 453 | NODEPTRS_PER_BLOCK) { |
443 | int sret = split_node(root, p, level); | 454 | int sret = split_node(root, p, level); |
444 | BUG_ON(sret > 0); | 455 | BUG_ON(sret > 0); |
445 | if (sret) | 456 | if (sret) |
@@ -456,7 +467,7 @@ again: | |||
456 | goto again; | 467 | goto again; |
457 | c = &b->node; | 468 | c = &b->node; |
458 | slot = p->slots[level]; | 469 | slot = p->slots[level]; |
459 | BUG_ON(c->header.nritems == 1); | 470 | BUG_ON(btrfs_header_nritems(&c->header) == 1); |
460 | } | 471 | } |
461 | b = read_tree_block(root, c->blockptrs[slot]); | 472 | b = read_tree_block(root, c->blockptrs[slot]); |
462 | } else { | 473 | } else { |
@@ -524,8 +535,8 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf, | |||
524 | int dst_nritems; | 535 | int dst_nritems; |
525 | int ret = 0; | 536 | int ret = 0; |
526 | 537 | ||
527 | src_nritems = src->header.nritems; | 538 | src_nritems = btrfs_header_nritems(&src->header); |
528 | dst_nritems = dst->header.nritems; | 539 | dst_nritems = btrfs_header_nritems(&dst->header); |
529 | push_items = NODEPTRS_PER_BLOCK - dst_nritems; | 540 | push_items = NODEPTRS_PER_BLOCK - dst_nritems; |
530 | if (push_items <= 0) { | 541 | if (push_items <= 0) { |
531 | return 1; | 542 | return 1; |
@@ -544,9 +555,8 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf, | |||
544 | memmove(src->blockptrs, src->blockptrs + push_items, | 555 | memmove(src->blockptrs, src->blockptrs + push_items, |
545 | (src_nritems - push_items) * sizeof(u64)); | 556 | (src_nritems - push_items) * sizeof(u64)); |
546 | } | 557 | } |
547 | src->header.nritems -= push_items; | 558 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); |
548 | dst->header.nritems += push_items; | 559 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); |
549 | |||
550 | BUG_ON(list_empty(&src_buf->dirty)); | 560 | BUG_ON(list_empty(&src_buf->dirty)); |
551 | BUG_ON(list_empty(&dst_buf->dirty)); | 561 | BUG_ON(list_empty(&dst_buf->dirty)); |
552 | return ret; | 562 | return ret; |
@@ -573,8 +583,8 @@ static int balance_node_right(struct ctree_root *root, | |||
573 | int dst_nritems; | 583 | int dst_nritems; |
574 | int ret = 0; | 584 | int ret = 0; |
575 | 585 | ||
576 | src_nritems = src->header.nritems; | 586 | src_nritems = btrfs_header_nritems(&src->header); |
577 | dst_nritems = dst->header.nritems; | 587 | dst_nritems = btrfs_header_nritems(&dst->header); |
578 | push_items = NODEPTRS_PER_BLOCK - dst_nritems; | 588 | push_items = NODEPTRS_PER_BLOCK - dst_nritems; |
579 | if (push_items <= 0) { | 589 | if (push_items <= 0) { |
580 | return 1; | 590 | return 1; |
@@ -596,8 +606,8 @@ static int balance_node_right(struct ctree_root *root, | |||
596 | memcpy(dst->blockptrs, src->blockptrs + src_nritems - push_items, | 606 | memcpy(dst->blockptrs, src->blockptrs + src_nritems - push_items, |
597 | push_items * sizeof(u64)); | 607 | push_items * sizeof(u64)); |
598 | 608 | ||
599 | src->header.nritems -= push_items; | 609 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); |
600 | dst->header.nritems += push_items; | 610 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); |
601 | 611 | ||
602 | BUG_ON(list_empty(&src_buf->dirty)); | 612 | BUG_ON(list_empty(&src_buf->dirty)); |
603 | BUG_ON(list_empty(&dst_buf->dirty)); | 613 | BUG_ON(list_empty(&dst_buf->dirty)); |
@@ -625,12 +635,13 @@ static int insert_new_root(struct ctree_root *root, | |||
625 | t = alloc_free_block(root); | 635 | t = alloc_free_block(root); |
626 | c = &t->node; | 636 | c = &t->node; |
627 | memset(c, 0, sizeof(c)); | 637 | memset(c, 0, sizeof(c)); |
628 | c->header.nritems = 1; | 638 | btrfs_set_header_nritems(&c->header, 1); |
629 | c->header.flags = node_level(level); | 639 | btrfs_set_header_level(&c->header, level); |
630 | c->header.blocknr = t->blocknr; | 640 | btrfs_set_header_blocknr(&c->header, t->blocknr); |
631 | c->header.parentid = root->node->node.header.parentid; | 641 | btrfs_set_header_parentid(&c->header, |
642 | btrfs_header_parentid(&root->node->node.header)); | ||
632 | lower = &path->nodes[level-1]->node; | 643 | lower = &path->nodes[level-1]->node; |
633 | if (is_leaf(lower->header.flags)) | 644 | if (btrfs_is_leaf(lower)) |
634 | lower_key = &((struct leaf *)lower)->items[0].key; | 645 | lower_key = &((struct leaf *)lower)->items[0].key; |
635 | else | 646 | else |
636 | lower_key = lower->keys; | 647 | lower_key = lower->keys; |
@@ -663,7 +674,7 @@ static int insert_ptr(struct ctree_root *root, | |||
663 | 674 | ||
664 | BUG_ON(!path->nodes[level]); | 675 | BUG_ON(!path->nodes[level]); |
665 | lower = &path->nodes[level]->node; | 676 | lower = &path->nodes[level]->node; |
666 | nritems = lower->header.nritems; | 677 | nritems = btrfs_header_nritems(&lower->header); |
667 | if (slot > nritems) | 678 | if (slot > nritems) |
668 | BUG(); | 679 | BUG(); |
669 | if (nritems == NODEPTRS_PER_BLOCK) | 680 | if (nritems == NODEPTRS_PER_BLOCK) |
@@ -676,7 +687,7 @@ static int insert_ptr(struct ctree_root *root, | |||
676 | } | 687 | } |
677 | memcpy(lower->keys + slot, key, sizeof(struct key)); | 688 | memcpy(lower->keys + slot, key, sizeof(struct key)); |
678 | lower->blockptrs[slot] = blocknr; | 689 | lower->blockptrs[slot] = blocknr; |
679 | lower->header.nritems++; | 690 | btrfs_set_header_nritems(&lower->header, nritems + 1); |
680 | if (lower->keys[1].objectid == 0) | 691 | if (lower->keys[1].objectid == 0) |
681 | BUG(); | 692 | BUG(); |
682 | BUG_ON(list_empty(&path->nodes[level]->dirty)); | 693 | BUG_ON(list_empty(&path->nodes[level]->dirty)); |
@@ -702,6 +713,7 @@ static int split_node(struct ctree_root *root, struct ctree_path *path, | |||
702 | int mid; | 713 | int mid; |
703 | int ret; | 714 | int ret; |
704 | int wret; | 715 | int wret; |
716 | u32 c_nritems; | ||
705 | 717 | ||
706 | t = path->nodes[level]; | 718 | t = path->nodes[level]; |
707 | c = &t->node; | 719 | c = &t->node; |
@@ -711,18 +723,20 @@ static int split_node(struct ctree_root *root, struct ctree_path *path, | |||
711 | if (ret) | 723 | if (ret) |
712 | return ret; | 724 | return ret; |
713 | } | 725 | } |
726 | c_nritems = btrfs_header_nritems(&c->header); | ||
714 | split_buffer = alloc_free_block(root); | 727 | split_buffer = alloc_free_block(root); |
715 | split = &split_buffer->node; | 728 | split = &split_buffer->node; |
716 | split->header.flags = c->header.flags; | 729 | btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); |
717 | split->header.blocknr = split_buffer->blocknr; | 730 | btrfs_set_header_blocknr(&split->header, split_buffer->blocknr); |
718 | split->header.parentid = root->node->node.header.parentid; | 731 | btrfs_set_header_parentid(&split->header, |
719 | mid = (c->header.nritems + 1) / 2; | 732 | btrfs_header_parentid(&root->node->node.header)); |
733 | mid = (c_nritems + 1) / 2; | ||
720 | memcpy(split->keys, c->keys + mid, | 734 | memcpy(split->keys, c->keys + mid, |
721 | (c->header.nritems - mid) * sizeof(struct key)); | 735 | (c_nritems - mid) * sizeof(struct key)); |
722 | memcpy(split->blockptrs, c->blockptrs + mid, | 736 | memcpy(split->blockptrs, c->blockptrs + mid, |
723 | (c->header.nritems - mid) * sizeof(u64)); | 737 | (c_nritems - mid) * sizeof(u64)); |
724 | split->header.nritems = c->header.nritems - mid; | 738 | btrfs_set_header_nritems(&split->header, c_nritems - mid); |
725 | c->header.nritems = mid; | 739 | btrfs_set_header_nritems(&c->header, mid); |
726 | ret = 0; | 740 | ret = 0; |
727 | 741 | ||
728 | BUG_ON(list_empty(&t->dirty)); | 742 | BUG_ON(list_empty(&t->dirty)); |
@@ -781,13 +795,15 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
781 | int push_space = 0; | 795 | int push_space = 0; |
782 | int push_items = 0; | 796 | int push_items = 0; |
783 | struct item *item; | 797 | struct item *item; |
798 | u32 left_nritems; | ||
799 | u32 right_nritems; | ||
784 | 800 | ||
785 | slot = path->slots[1]; | 801 | slot = path->slots[1]; |
786 | if (!path->nodes[1]) { | 802 | if (!path->nodes[1]) { |
787 | return 1; | 803 | return 1; |
788 | } | 804 | } |
789 | upper = path->nodes[1]; | 805 | upper = path->nodes[1]; |
790 | if (slot >= upper->node.header.nritems - 1) { | 806 | if (slot >= btrfs_header_nritems(&upper->node.header) - 1) { |
791 | return 1; | 807 | return 1; |
792 | } | 808 | } |
793 | right_buf = read_tree_block(root, upper->node.blockptrs[slot + 1]); | 809 | right_buf = read_tree_block(root, upper->node.blockptrs[slot + 1]); |
@@ -806,7 +822,8 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
806 | return 1; | 822 | return 1; |
807 | } | 823 | } |
808 | 824 | ||
809 | for (i = left->header.nritems - 1; i >= 0; i--) { | 825 | left_nritems = btrfs_header_nritems(&left->header); |
826 | for (i = left_nritems - 1; i >= 0; i--) { | ||
810 | item = left->items + i; | 827 | item = left->items + i; |
811 | if (path->slots[0] == i) | 828 | if (path->slots[0] == i) |
812 | push_space += data_size + sizeof(*item); | 829 | push_space += data_size + sizeof(*item); |
@@ -819,9 +836,10 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
819 | tree_block_release(root, right_buf); | 836 | tree_block_release(root, right_buf); |
820 | return 1; | 837 | return 1; |
821 | } | 838 | } |
839 | right_nritems = btrfs_header_nritems(&right->header); | ||
822 | /* push left to right */ | 840 | /* push left to right */ |
823 | push_space = left->items[left->header.nritems - push_items].offset + | 841 | push_space = left->items[left_nritems - push_items].offset + |
824 | left->items[left->header.nritems - push_items].size; | 842 | left->items[left_nritems - push_items].size; |
825 | push_space -= leaf_data_end(left); | 843 | push_space -= leaf_data_end(left); |
826 | /* make room in the right data area */ | 844 | /* make room in the right data area */ |
827 | memmove(right->data + leaf_data_end(right) - push_space, | 845 | memmove(right->data + leaf_data_end(right) - push_space, |
@@ -832,19 +850,21 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
832 | left->data + leaf_data_end(left), | 850 | left->data + leaf_data_end(left), |
833 | push_space); | 851 | push_space); |
834 | memmove(right->items + push_items, right->items, | 852 | memmove(right->items + push_items, right->items, |
835 | right->header.nritems * sizeof(struct item)); | 853 | right_nritems * sizeof(struct item)); |
836 | /* copy the items from left to right */ | 854 | /* copy the items from left to right */ |
837 | memcpy(right->items, left->items + left->header.nritems - push_items, | 855 | memcpy(right->items, left->items + left_nritems - push_items, |
838 | push_items * sizeof(struct item)); | 856 | push_items * sizeof(struct item)); |
839 | 857 | ||
840 | /* update the item pointers */ | 858 | /* update the item pointers */ |
841 | right->header.nritems += push_items; | 859 | right_nritems += push_items; |
860 | btrfs_set_header_nritems(&right->header, right_nritems); | ||
842 | push_space = LEAF_DATA_SIZE; | 861 | push_space = LEAF_DATA_SIZE; |
843 | for (i = 0; i < right->header.nritems; i++) { | 862 | for (i = 0; i < right_nritems; i++) { |
844 | right->items[i].offset = push_space - right->items[i].size; | 863 | right->items[i].offset = push_space - right->items[i].size; |
845 | push_space = right->items[i].offset; | 864 | push_space = right->items[i].offset; |
846 | } | 865 | } |
847 | left->header.nritems -= push_items; | 866 | left_nritems -= push_items; |
867 | btrfs_set_header_nritems(&left->header, left_nritems); | ||
848 | 868 | ||
849 | BUG_ON(list_empty(&left_buf->dirty)); | 869 | BUG_ON(list_empty(&left_buf->dirty)); |
850 | BUG_ON(list_empty(&right_buf->dirty)); | 870 | BUG_ON(list_empty(&right_buf->dirty)); |
@@ -853,8 +873,8 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path, | |||
853 | BUG_ON(list_empty(&upper->dirty)); | 873 | BUG_ON(list_empty(&upper->dirty)); |
854 | 874 | ||
855 | /* then fixup the leaf pointer in the path */ | 875 | /* then fixup the leaf pointer in the path */ |
856 | if (path->slots[0] >= left->header.nritems) { | 876 | if (path->slots[0] >= left_nritems) { |
857 | path->slots[0] -= left->header.nritems; | 877 | path->slots[0] -= left_nritems; |
858 | tree_block_release(root, path->nodes[0]); | 878 | tree_block_release(root, path->nodes[0]); |
859 | path->nodes[0] = right_buf; | 879 | path->nodes[0] = right_buf; |
860 | path->slots[1] += 1; | 880 | path->slots[1] += 1; |
@@ -880,7 +900,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path, | |||
880 | int push_space = 0; | 900 | int push_space = 0; |
881 | int push_items = 0; | 901 | int push_items = 0; |
882 | struct item *item; | 902 | struct item *item; |
883 | int old_left_nritems; | 903 | u32 old_left_nritems; |
884 | int ret = 0; | 904 | int ret = 0; |
885 | int wret; | 905 | int wret; |
886 | 906 | ||
@@ -908,7 +928,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path, | |||
908 | return 1; | 928 | return 1; |
909 | } | 929 | } |
910 | 930 | ||
911 | for (i = 0; i < right->header.nritems; i++) { | 931 | for (i = 0; i < btrfs_header_nritems(&right->header); i++) { |
912 | item = right->items + i; | 932 | item = right->items + i; |
913 | if (path->slots[0] == i) | 933 | if (path->slots[0] == i) |
914 | push_space += data_size + sizeof(*item); | 934 | push_space += data_size + sizeof(*item); |
@@ -922,31 +942,34 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path, | |||
922 | return 1; | 942 | return 1; |
923 | } | 943 | } |
924 | /* push data from right to left */ | 944 | /* push data from right to left */ |
925 | memcpy(left->items + left->header.nritems, | 945 | memcpy(left->items + btrfs_header_nritems(&left->header), |
926 | right->items, push_items * sizeof(struct item)); | 946 | right->items, push_items * sizeof(struct item)); |
927 | push_space = LEAF_DATA_SIZE - right->items[push_items -1].offset; | 947 | push_space = LEAF_DATA_SIZE - right->items[push_items -1].offset; |
928 | memcpy(left->data + leaf_data_end(left) - push_space, | 948 | memcpy(left->data + leaf_data_end(left) - push_space, |
929 | right->data + right->items[push_items - 1].offset, | 949 | right->data + right->items[push_items - 1].offset, |
930 | push_space); | 950 | push_space); |
931 | old_left_nritems = left->header.nritems; | 951 | old_left_nritems = btrfs_header_nritems(&left->header); |
932 | BUG_ON(old_left_nritems < 0); | 952 | BUG_ON(old_left_nritems < 0); |
933 | 953 | ||
934 | for(i = old_left_nritems; i < old_left_nritems + push_items; i++) { | 954 | for(i = old_left_nritems; i < old_left_nritems + push_items; i++) { |
935 | left->items[i].offset -= LEAF_DATA_SIZE - | 955 | left->items[i].offset -= LEAF_DATA_SIZE - |
936 | left->items[old_left_nritems -1].offset; | 956 | left->items[old_left_nritems -1].offset; |
937 | } | 957 | } |
938 | left->header.nritems += push_items; | 958 | btrfs_set_header_nritems(&left->header, old_left_nritems + push_items); |
939 | 959 | ||
940 | /* fixup right node */ | 960 | /* fixup right node */ |
941 | push_space = right->items[push_items-1].offset - leaf_data_end(right); | 961 | push_space = right->items[push_items-1].offset - leaf_data_end(right); |
942 | memmove(right->data + LEAF_DATA_SIZE - push_space, right->data + | 962 | memmove(right->data + LEAF_DATA_SIZE - push_space, right->data + |
943 | leaf_data_end(right), push_space); | 963 | leaf_data_end(right), push_space); |
944 | memmove(right->items, right->items + push_items, | 964 | memmove(right->items, right->items + push_items, |
945 | (right->header.nritems - push_items) * sizeof(struct item)); | 965 | (btrfs_header_nritems(&right->header) - push_items) * |
946 | right->header.nritems -= push_items; | 966 | sizeof(struct item)); |
967 | btrfs_set_header_nritems(&right->header, | ||
968 | btrfs_header_nritems(&right->header) - | ||
969 | push_items); | ||
947 | push_space = LEAF_DATA_SIZE; | 970 | push_space = LEAF_DATA_SIZE; |
948 | 971 | ||
949 | for (i = 0; i < right->header.nritems; i++) { | 972 | for (i = 0; i < btrfs_header_nritems(&right->header); i++) { |
950 | right->items[i].offset = push_space - right->items[i].size; | 973 | right->items[i].offset = push_space - right->items[i].size; |
951 | push_space = right->items[i].offset; | 974 | push_space = right->items[i].offset; |
952 | } | 975 | } |
@@ -983,7 +1006,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path, | |||
983 | { | 1006 | { |
984 | struct tree_buffer *l_buf; | 1007 | struct tree_buffer *l_buf; |
985 | struct leaf *l; | 1008 | struct leaf *l; |
986 | int nritems; | 1009 | u32 nritems; |
987 | int mid; | 1010 | int mid; |
988 | int slot; | 1011 | int slot; |
989 | struct leaf *right; | 1012 | struct leaf *right; |
@@ -1008,7 +1031,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path, | |||
1008 | return ret; | 1031 | return ret; |
1009 | } | 1032 | } |
1010 | slot = path->slots[0]; | 1033 | slot = path->slots[0]; |
1011 | nritems = l->header.nritems; | 1034 | nritems = btrfs_header_nritems(&l->header); |
1012 | mid = (nritems + 1)/ 2; | 1035 | mid = (nritems + 1)/ 2; |
1013 | right_buffer = alloc_free_block(root); | 1036 | right_buffer = alloc_free_block(root); |
1014 | BUG_ON(!right_buffer); | 1037 | BUG_ON(!right_buffer); |
@@ -1026,10 +1049,11 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path, | |||
1026 | LEAF_DATA_SIZE) | 1049 | LEAF_DATA_SIZE) |
1027 | BUG(); | 1050 | BUG(); |
1028 | } | 1051 | } |
1029 | right->header.nritems = nritems - mid; | 1052 | btrfs_set_header_nritems(&right->header, nritems - mid); |
1030 | right->header.blocknr = right_buffer->blocknr; | 1053 | btrfs_set_header_blocknr(&right->header, right_buffer->blocknr); |
1031 | right->header.flags = node_level(0); | 1054 | btrfs_set_header_level(&right->header, 0); |
1032 | right->header.parentid = root->node->node.header.parentid; | 1055 | btrfs_set_header_parentid(&right->header, |
1056 | btrfs_header_parentid(&root->node->node.header)); | ||
1033 | data_copy_size = l->items[mid].offset + l->items[mid].size - | 1057 | data_copy_size = l->items[mid].offset + l->items[mid].size - |
1034 | leaf_data_end(l); | 1058 | leaf_data_end(l); |
1035 | memcpy(right->items, l->items + mid, | 1059 | memcpy(right->items, l->items + mid, |
@@ -1039,10 +1063,10 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path, | |||
1039 | rt_data_off = LEAF_DATA_SIZE - | 1063 | rt_data_off = LEAF_DATA_SIZE - |
1040 | (l->items[mid].offset + l->items[mid].size); | 1064 | (l->items[mid].offset + l->items[mid].size); |
1041 | 1065 | ||
1042 | for (i = 0; i < right->header.nritems; i++) | 1066 | for (i = 0; i < btrfs_header_nritems(&right->header); i++) |
1043 | right->items[i].offset += rt_data_off; | 1067 | right->items[i].offset += rt_data_off; |
1044 | 1068 | ||
1045 | l->header.nritems = mid; | 1069 | btrfs_set_header_nritems(&l->header, mid); |
1046 | ret = 0; | 1070 | ret = 0; |
1047 | wret = insert_ptr(root, path, &right->items[0].key, | 1071 | wret = insert_ptr(root, path, &right->items[0].key, |
1048 | right_buffer->blocknr, path->slots[1] + 1, 1); | 1072 | right_buffer->blocknr, path->slots[1] + 1, 1); |
@@ -1074,7 +1098,7 @@ int insert_item(struct ctree_root *root, struct key *key, | |||
1074 | int slot_orig; | 1098 | int slot_orig; |
1075 | struct leaf *leaf; | 1099 | struct leaf *leaf; |
1076 | struct tree_buffer *leaf_buf; | 1100 | struct tree_buffer *leaf_buf; |
1077 | unsigned int nritems; | 1101 | u32 nritems; |
1078 | unsigned int data_end; | 1102 | unsigned int data_end; |
1079 | struct ctree_path path; | 1103 | struct ctree_path path; |
1080 | 1104 | ||
@@ -1094,7 +1118,7 @@ int insert_item(struct ctree_root *root, struct key *key, | |||
1094 | leaf_buf = path.nodes[0]; | 1118 | leaf_buf = path.nodes[0]; |
1095 | leaf = &leaf_buf->leaf; | 1119 | leaf = &leaf_buf->leaf; |
1096 | 1120 | ||
1097 | nritems = leaf->header.nritems; | 1121 | nritems = btrfs_header_nritems(&leaf->header); |
1098 | data_end = leaf_data_end(leaf); | 1122 | data_end = leaf_data_end(leaf); |
1099 | 1123 | ||
1100 | if (leaf_free_space(leaf) < sizeof(struct item) + data_size) | 1124 | if (leaf_free_space(leaf) < sizeof(struct item) + data_size) |
@@ -1128,7 +1152,7 @@ int insert_item(struct ctree_root *root, struct key *key, | |||
1128 | leaf->items[slot].offset = data_end - data_size; | 1152 | leaf->items[slot].offset = data_end - data_size; |
1129 | leaf->items[slot].size = data_size; | 1153 | leaf->items[slot].size = data_size; |
1130 | memcpy(leaf->data + data_end - data_size, data, data_size); | 1154 | memcpy(leaf->data + data_end - data_size, data, data_size); |
1131 | leaf->header.nritems += 1; | 1155 | btrfs_set_header_nritems(&leaf->header, nritems + 1); |
1132 | 1156 | ||
1133 | ret = 0; | 1157 | ret = 0; |
1134 | if (slot == 0) | 1158 | if (slot == 0) |
@@ -1155,12 +1179,12 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level, | |||
1155 | { | 1179 | { |
1156 | struct node *node; | 1180 | struct node *node; |
1157 | struct tree_buffer *parent = path->nodes[level]; | 1181 | struct tree_buffer *parent = path->nodes[level]; |
1158 | int nritems; | 1182 | u32 nritems; |
1159 | int ret = 0; | 1183 | int ret = 0; |
1160 | int wret; | 1184 | int wret; |
1161 | 1185 | ||
1162 | node = &parent->node; | 1186 | node = &parent->node; |
1163 | nritems = node->header.nritems; | 1187 | nritems = btrfs_header_nritems(&node->header); |
1164 | if (slot != nritems -1) { | 1188 | if (slot != nritems -1) { |
1165 | memmove(node->keys + slot, node->keys + slot + 1, | 1189 | memmove(node->keys + slot, node->keys + slot + 1, |
1166 | sizeof(struct key) * (nritems - slot - 1)); | 1190 | sizeof(struct key) * (nritems - slot - 1)); |
@@ -1168,11 +1192,12 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level, | |||
1168 | node->blockptrs + slot + 1, | 1192 | node->blockptrs + slot + 1, |
1169 | sizeof(u64) * (nritems - slot - 1)); | 1193 | sizeof(u64) * (nritems - slot - 1)); |
1170 | } | 1194 | } |
1171 | node->header.nritems--; | 1195 | nritems--; |
1172 | if (node->header.nritems == 0 && parent == root->node) { | 1196 | btrfs_set_header_nritems(&node->header, nritems); |
1173 | BUG_ON(node_level(root->node->node.header.flags) != 1); | 1197 | if (nritems == 0 && parent == root->node) { |
1198 | BUG_ON(btrfs_header_level(&root->node->node.header) != 1); | ||
1174 | /* just turn the root into a leaf and break */ | 1199 | /* just turn the root into a leaf and break */ |
1175 | root->node->node.header.flags = node_level(0); | 1200 | btrfs_set_header_level(&root->node->node.header, 0); |
1176 | } else if (slot == 0) { | 1201 | } else if (slot == 0) { |
1177 | wret = fixup_low_keys(root, path, node->keys, level + 1); | 1202 | wret = fixup_low_keys(root, path, node->keys, level + 1); |
1178 | if (wret) | 1203 | if (wret) |
@@ -1195,30 +1220,33 @@ int del_item(struct ctree_root *root, struct ctree_path *path) | |||
1195 | int dsize; | 1220 | int dsize; |
1196 | int ret = 0; | 1221 | int ret = 0; |
1197 | int wret; | 1222 | int wret; |
1223 | u32 nritems; | ||
1198 | 1224 | ||
1199 | leaf_buf = path->nodes[0]; | 1225 | leaf_buf = path->nodes[0]; |
1200 | leaf = &leaf_buf->leaf; | 1226 | leaf = &leaf_buf->leaf; |
1201 | slot = path->slots[0]; | 1227 | slot = path->slots[0]; |
1202 | doff = leaf->items[slot].offset; | 1228 | doff = leaf->items[slot].offset; |
1203 | dsize = leaf->items[slot].size; | 1229 | dsize = leaf->items[slot].size; |
1230 | nritems = btrfs_header_nritems(&leaf->header); | ||
1204 | 1231 | ||
1205 | if (slot != leaf->header.nritems - 1) { | 1232 | if (slot != nritems - 1) { |
1206 | int i; | 1233 | int i; |
1207 | int data_end = leaf_data_end(leaf); | 1234 | int data_end = leaf_data_end(leaf); |
1208 | memmove(leaf->data + data_end + dsize, | 1235 | memmove(leaf->data + data_end + dsize, |
1209 | leaf->data + data_end, | 1236 | leaf->data + data_end, |
1210 | doff - data_end); | 1237 | doff - data_end); |
1211 | for (i = slot + 1; i < leaf->header.nritems; i++) | 1238 | for (i = slot + 1; i < nritems; i++) |
1212 | leaf->items[i].offset += dsize; | 1239 | leaf->items[i].offset += dsize; |
1213 | memmove(leaf->items + slot, leaf->items + slot + 1, | 1240 | memmove(leaf->items + slot, leaf->items + slot + 1, |
1214 | sizeof(struct item) * | 1241 | sizeof(struct item) * |
1215 | (leaf->header.nritems - slot - 1)); | 1242 | (nritems - slot - 1)); |
1216 | } | 1243 | } |
1217 | leaf->header.nritems -= 1; | 1244 | btrfs_set_header_nritems(&leaf->header, nritems - 1); |
1245 | nritems--; | ||
1218 | /* delete the leaf if we've emptied it */ | 1246 | /* delete the leaf if we've emptied it */ |
1219 | if (leaf->header.nritems == 0) { | 1247 | if (nritems == 0) { |
1220 | if (leaf_buf == root->node) { | 1248 | if (leaf_buf == root->node) { |
1221 | leaf->header.flags = node_level(0); | 1249 | btrfs_set_header_level(&leaf->header, 0); |
1222 | BUG_ON(list_empty(&leaf_buf->dirty)); | 1250 | BUG_ON(list_empty(&leaf_buf->dirty)); |
1223 | } else { | 1251 | } else { |
1224 | clean_tree_block(root, leaf_buf); | 1252 | clean_tree_block(root, leaf_buf); |
@@ -1230,7 +1258,7 @@ int del_item(struct ctree_root *root, struct ctree_path *path) | |||
1230 | ret = wret; | 1258 | ret = wret; |
1231 | } | 1259 | } |
1232 | } else { | 1260 | } else { |
1233 | int used = leaf_space_used(leaf, 0, leaf->header.nritems); | 1261 | int used = leaf_space_used(leaf, 0, nritems); |
1234 | if (slot == 0) { | 1262 | if (slot == 0) { |
1235 | wret = fixup_low_keys(root, path, | 1263 | wret = fixup_low_keys(root, path, |
1236 | &leaf->items[0].key, 1); | 1264 | &leaf->items[0].key, 1); |
@@ -1251,12 +1279,12 @@ int del_item(struct ctree_root *root, struct ctree_path *path) | |||
1251 | if (wret < 0) | 1279 | if (wret < 0) |
1252 | ret = wret; | 1280 | ret = wret; |
1253 | if (path->nodes[0] == leaf_buf && | 1281 | if (path->nodes[0] == leaf_buf && |
1254 | leaf->header.nritems) { | 1282 | btrfs_header_nritems(&leaf->header)) { |
1255 | wret = push_leaf_right(root, path, 1); | 1283 | wret = push_leaf_right(root, path, 1); |
1256 | if (wret < 0) | 1284 | if (wret < 0) |
1257 | ret = wret; | 1285 | ret = wret; |
1258 | } | 1286 | } |
1259 | if (leaf->header.nritems == 0) { | 1287 | if (btrfs_header_nritems(&leaf->header) == 0) { |
1260 | u64 blocknr = leaf_buf->blocknr; | 1288 | u64 blocknr = leaf_buf->blocknr; |
1261 | clean_tree_block(root, leaf_buf); | 1289 | clean_tree_block(root, leaf_buf); |
1262 | wret = del_ptr(root, path, 1, slot); | 1290 | wret = del_ptr(root, path, 1, slot); |
@@ -1292,7 +1320,7 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path) | |||
1292 | return 1; | 1320 | return 1; |
1293 | slot = path->slots[level] + 1; | 1321 | slot = path->slots[level] + 1; |
1294 | c = path->nodes[level]; | 1322 | c = path->nodes[level]; |
1295 | if (slot >= c->node.header.nritems) { | 1323 | if (slot >= btrfs_header_nritems(&c->node.header)) { |
1296 | level++; | 1324 | level++; |
1297 | continue; | 1325 | continue; |
1298 | } | 1326 | } |