diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-03-22 12:13:20 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-03-22 12:13:20 -0400 |
commit | e20d96d64f9cf9288ffecc9ad4714e91c3b97ca8 (patch) | |
tree | fbe07d48bc7997226075169118ffa2a2e63f5d51 /fs/btrfs/ctree.c | |
parent | 2e635a278354a1a7951e16cfea4c247d6d0e7c99 (diff) |
Mountable btrfs, with readdir
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 273 |
1 files changed, 140 insertions, 133 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 9fbd07c37fde..e690e2bb47d2 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -7,11 +7,11 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
7 | static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | 7 | static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root |
8 | *root, struct btrfs_path *path, int data_size); | 8 | *root, struct btrfs_path *path, int data_size); |
9 | static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | 9 | static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root |
10 | *root, struct btrfs_buffer *dst, struct btrfs_buffer | 10 | *root, struct buffer_head *dst, struct buffer_head |
11 | *src); | 11 | *src); |
12 | static int balance_node_right(struct btrfs_trans_handle *trans, struct | 12 | static int balance_node_right(struct btrfs_trans_handle *trans, struct |
13 | btrfs_root *root, struct btrfs_buffer *dst_buf, | 13 | btrfs_root *root, struct buffer_head *dst_buf, |
14 | struct btrfs_buffer *src_buf); | 14 | struct buffer_head *src_buf); |
15 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 15 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
16 | struct btrfs_path *path, int level, int slot); | 16 | struct btrfs_path *path, int level, int slot); |
17 | 17 | ||
@@ -32,32 +32,34 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) | |||
32 | } | 32 | } |
33 | 33 | ||
34 | static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | 34 | static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root |
35 | *root, struct btrfs_buffer *buf, struct btrfs_buffer | 35 | *root, struct buffer_head *buf, struct buffer_head |
36 | *parent, int parent_slot, struct btrfs_buffer | 36 | *parent, int parent_slot, struct buffer_head |
37 | **cow_ret) | 37 | **cow_ret) |
38 | { | 38 | { |
39 | struct btrfs_buffer *cow; | 39 | struct buffer_head *cow; |
40 | struct btrfs_node *cow_node; | ||
40 | 41 | ||
41 | if (!list_empty(&buf->dirty)) { | 42 | if (!buffer_dirty(buf)) { |
42 | *cow_ret = buf; | 43 | *cow_ret = buf; |
43 | return 0; | 44 | return 0; |
44 | } | 45 | } |
45 | cow = btrfs_alloc_free_block(trans, root); | 46 | cow = btrfs_alloc_free_block(trans, root); |
46 | memcpy(&cow->node, &buf->node, root->blocksize); | 47 | cow_node = btrfs_buffer_node(cow); |
47 | btrfs_set_header_blocknr(&cow->node.header, cow->blocknr); | 48 | memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); |
49 | btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr); | ||
48 | *cow_ret = cow; | 50 | *cow_ret = cow; |
49 | btrfs_inc_ref(trans, root, buf); | 51 | btrfs_inc_ref(trans, root, buf); |
50 | if (buf == root->node) { | 52 | if (buf == root->node) { |
51 | root->node = cow; | 53 | root->node = cow; |
52 | cow->count++; | 54 | get_bh(cow); |
53 | if (buf != root->commit_root) | 55 | if (buf != root->commit_root) |
54 | btrfs_free_extent(trans, root, buf->blocknr, 1, 1); | 56 | btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1); |
55 | btrfs_block_release(root, buf); | 57 | btrfs_block_release(root, buf); |
56 | } else { | 58 | } else { |
57 | btrfs_set_node_blockptr(&parent->node, parent_slot, | 59 | btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, |
58 | cow->blocknr); | 60 | cow->b_blocknr); |
59 | BUG_ON(list_empty(&parent->dirty)); | 61 | BUG_ON(!buffer_dirty(parent)); |
60 | btrfs_free_extent(trans, root, buf->blocknr, 1, 1); | 62 | btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1); |
61 | } | 63 | } |
62 | btrfs_block_release(root, buf); | 64 | btrfs_block_release(root, buf); |
63 | return 0; | 65 | return 0; |
@@ -119,12 +121,12 @@ static int check_node(struct btrfs_root *root, struct btrfs_path *path, | |||
119 | { | 121 | { |
120 | int i; | 122 | int i; |
121 | struct btrfs_node *parent = NULL; | 123 | struct btrfs_node *parent = NULL; |
122 | struct btrfs_node *node = &path->nodes[level]->node; | 124 | struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]); |
123 | int parent_slot; | 125 | int parent_slot; |
124 | u32 nritems = btrfs_header_nritems(&node->header); | 126 | u32 nritems = btrfs_header_nritems(&node->header); |
125 | 127 | ||
126 | if (path->nodes[level + 1]) | 128 | if (path->nodes[level + 1]) |
127 | parent = &path->nodes[level + 1]->node; | 129 | parent = btrfs_buffer_node(path->nodes[level + 1]); |
128 | parent_slot = path->slots[level + 1]; | 130 | parent_slot = path->slots[level + 1]; |
129 | BUG_ON(nritems == 0); | 131 | BUG_ON(nritems == 0); |
130 | if (parent) { | 132 | if (parent) { |
@@ -148,13 +150,13 @@ static int check_leaf(struct btrfs_root *root, struct btrfs_path *path, | |||
148 | int level) | 150 | int level) |
149 | { | 151 | { |
150 | int i; | 152 | int i; |
151 | struct btrfs_leaf *leaf = &path->nodes[level]->leaf; | 153 | struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]); |
152 | struct btrfs_node *parent = NULL; | 154 | struct btrfs_node *parent = NULL; |
153 | int parent_slot; | 155 | int parent_slot; |
154 | u32 nritems = btrfs_header_nritems(&leaf->header); | 156 | u32 nritems = btrfs_header_nritems(&leaf->header); |
155 | 157 | ||
156 | if (path->nodes[level + 1]) | 158 | if (path->nodes[level + 1]) |
157 | parent = &path->nodes[level + 1]->node; | 159 | parent = btrfs_buffer_node(path->nodes[level + 1]); |
158 | parent_slot = path->slots[level + 1]; | 160 | parent_slot = path->slots[level + 1]; |
159 | BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); | 161 | BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); |
160 | 162 | ||
@@ -250,11 +252,11 @@ static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot) | |||
250 | return -1; | 252 | return -1; |
251 | } | 253 | } |
252 | 254 | ||
253 | static struct btrfs_buffer *read_node_slot(struct btrfs_root *root, | 255 | static struct buffer_head *read_node_slot(struct btrfs_root *root, |
254 | struct btrfs_buffer *parent_buf, | 256 | struct buffer_head *parent_buf, |
255 | int slot) | 257 | int slot) |
256 | { | 258 | { |
257 | struct btrfs_node *node = &parent_buf->node; | 259 | struct btrfs_node *node = btrfs_buffer_node(parent_buf); |
258 | if (slot < 0) | 260 | if (slot < 0) |
259 | return NULL; | 261 | return NULL; |
260 | if (slot >= btrfs_header_nritems(&node->header)) | 262 | if (slot >= btrfs_header_nritems(&node->header)) |
@@ -265,10 +267,10 @@ static struct btrfs_buffer *read_node_slot(struct btrfs_root *root, | |||
265 | static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | 267 | static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root |
266 | *root, struct btrfs_path *path, int level) | 268 | *root, struct btrfs_path *path, int level) |
267 | { | 269 | { |
268 | struct btrfs_buffer *right_buf; | 270 | struct buffer_head *right_buf; |
269 | struct btrfs_buffer *mid_buf; | 271 | struct buffer_head *mid_buf; |
270 | struct btrfs_buffer *left_buf; | 272 | struct buffer_head *left_buf; |
271 | struct btrfs_buffer *parent_buf = NULL; | 273 | struct buffer_head *parent_buf = NULL; |
272 | struct btrfs_node *right = NULL; | 274 | struct btrfs_node *right = NULL; |
273 | struct btrfs_node *mid; | 275 | struct btrfs_node *mid; |
274 | struct btrfs_node *left = NULL; | 276 | struct btrfs_node *left = NULL; |
@@ -283,7 +285,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
283 | return 0; | 285 | return 0; |
284 | 286 | ||
285 | mid_buf = path->nodes[level]; | 287 | mid_buf = path->nodes[level]; |
286 | mid = &mid_buf->node; | 288 | mid = btrfs_buffer_node(mid_buf); |
287 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); | 289 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); |
288 | 290 | ||
289 | if (level < BTRFS_MAX_LEVEL - 1) | 291 | if (level < BTRFS_MAX_LEVEL - 1) |
@@ -295,8 +297,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
295 | * by promoting the node below to a root | 297 | * by promoting the node below to a root |
296 | */ | 298 | */ |
297 | if (!parent_buf) { | 299 | if (!parent_buf) { |
298 | struct btrfs_buffer *child; | 300 | struct buffer_head *child; |
299 | u64 blocknr = mid_buf->blocknr; | 301 | u64 blocknr = mid_buf->b_blocknr; |
300 | 302 | ||
301 | if (btrfs_header_nritems(&mid->header) != 1) | 303 | if (btrfs_header_nritems(&mid->header) != 1) |
302 | return 0; | 304 | return 0; |
@@ -313,7 +315,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
313 | clean_tree_block(trans, root, mid_buf); | 315 | clean_tree_block(trans, root, mid_buf); |
314 | return btrfs_free_extent(trans, root, blocknr, 1, 1); | 316 | return btrfs_free_extent(trans, root, blocknr, 1, 1); |
315 | } | 317 | } |
316 | parent = &parent_buf->node; | 318 | parent = btrfs_buffer_node(parent_buf); |
317 | 319 | ||
318 | if (btrfs_header_nritems(&mid->header) > | 320 | if (btrfs_header_nritems(&mid->header) > |
319 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) | 321 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) |
@@ -326,7 +328,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
326 | if (left_buf) { | 328 | if (left_buf) { |
327 | btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1, | 329 | btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1, |
328 | &left_buf); | 330 | &left_buf); |
329 | left = &left_buf->node; | 331 | left = btrfs_buffer_node(left_buf); |
330 | orig_slot += btrfs_header_nritems(&left->header); | 332 | orig_slot += btrfs_header_nritems(&left->header); |
331 | wret = push_node_left(trans, root, left_buf, mid_buf); | 333 | wret = push_node_left(trans, root, left_buf, mid_buf); |
332 | if (wret < 0) | 334 | if (wret < 0) |
@@ -339,12 +341,12 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
339 | if (right_buf) { | 341 | if (right_buf) { |
340 | btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1, | 342 | btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1, |
341 | &right_buf); | 343 | &right_buf); |
342 | right = &right_buf->node; | 344 | right = btrfs_buffer_node(right_buf); |
343 | wret = push_node_left(trans, root, mid_buf, right_buf); | 345 | wret = push_node_left(trans, root, mid_buf, right_buf); |
344 | if (wret < 0) | 346 | if (wret < 0) |
345 | ret = wret; | 347 | ret = wret; |
346 | if (btrfs_header_nritems(&right->header) == 0) { | 348 | if (btrfs_header_nritems(&right->header) == 0) { |
347 | u64 blocknr = right_buf->blocknr; | 349 | u64 blocknr = right_buf->b_blocknr; |
348 | btrfs_block_release(root, right_buf); | 350 | btrfs_block_release(root, right_buf); |
349 | clean_tree_block(trans, root, right_buf); | 351 | clean_tree_block(trans, root, right_buf); |
350 | right_buf = NULL; | 352 | right_buf = NULL; |
@@ -360,7 +362,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
360 | memcpy(&parent->ptrs[pslot + 1].key, | 362 | memcpy(&parent->ptrs[pslot + 1].key, |
361 | &right->ptrs[0].key, | 363 | &right->ptrs[0].key, |
362 | sizeof(struct btrfs_disk_key)); | 364 | sizeof(struct btrfs_disk_key)); |
363 | BUG_ON(list_empty(&parent_buf->dirty)); | 365 | BUG_ON(!buffer_dirty(parent_buf)); |
364 | } | 366 | } |
365 | } | 367 | } |
366 | if (btrfs_header_nritems(&mid->header) == 1) { | 368 | if (btrfs_header_nritems(&mid->header) == 1) { |
@@ -381,7 +383,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
381 | } | 383 | } |
382 | if (btrfs_header_nritems(&mid->header) == 0) { | 384 | if (btrfs_header_nritems(&mid->header) == 0) { |
383 | /* we've managed to empty the middle node, drop it */ | 385 | /* we've managed to empty the middle node, drop it */ |
384 | u64 blocknr = mid_buf->blocknr; | 386 | u64 blocknr = mid_buf->b_blocknr; |
385 | btrfs_block_release(root, mid_buf); | 387 | btrfs_block_release(root, mid_buf); |
386 | clean_tree_block(trans, root, mid_buf); | 388 | clean_tree_block(trans, root, mid_buf); |
387 | mid_buf = NULL; | 389 | mid_buf = NULL; |
@@ -396,13 +398,13 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
396 | /* update the parent key to reflect our changes */ | 398 | /* update the parent key to reflect our changes */ |
397 | memcpy(&parent->ptrs[pslot].key, &mid->ptrs[0].key, | 399 | memcpy(&parent->ptrs[pslot].key, &mid->ptrs[0].key, |
398 | sizeof(struct btrfs_disk_key)); | 400 | sizeof(struct btrfs_disk_key)); |
399 | BUG_ON(list_empty(&parent_buf->dirty)); | 401 | BUG_ON(!buffer_dirty(parent_buf)); |
400 | } | 402 | } |
401 | 403 | ||
402 | /* update the path */ | 404 | /* update the path */ |
403 | if (left_buf) { | 405 | if (left_buf) { |
404 | if (btrfs_header_nritems(&left->header) > orig_slot) { | 406 | if (btrfs_header_nritems(&left->header) > orig_slot) { |
405 | left_buf->count++; // released below | 407 | get_bh(left_buf); |
406 | path->nodes[level] = left_buf; | 408 | path->nodes[level] = left_buf; |
407 | path->slots[level + 1] -= 1; | 409 | path->slots[level + 1] -= 1; |
408 | path->slots[level] = orig_slot; | 410 | path->slots[level] = orig_slot; |
@@ -415,8 +417,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
415 | } | 417 | } |
416 | /* double check we haven't messed things up */ | 418 | /* double check we haven't messed things up */ |
417 | check_block(root, path, level); | 419 | check_block(root, path, level); |
418 | if (orig_ptr != btrfs_node_blockptr(&path->nodes[level]->node, | 420 | if (orig_ptr != |
419 | path->slots[level])) | 421 | btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), |
422 | path->slots[level])) | ||
420 | BUG(); | 423 | BUG(); |
421 | 424 | ||
422 | if (right_buf) | 425 | if (right_buf) |
@@ -443,8 +446,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
443 | *root, struct btrfs_key *key, struct btrfs_path *p, int | 446 | *root, struct btrfs_key *key, struct btrfs_path *p, int |
444 | ins_len, int cow) | 447 | ins_len, int cow) |
445 | { | 448 | { |
446 | struct btrfs_buffer *b; | 449 | struct buffer_head *b; |
447 | struct btrfs_buffer *cow_buf; | 450 | struct buffer_head *cow_buf; |
448 | struct btrfs_node *c; | 451 | struct btrfs_node *c; |
449 | int slot; | 452 | int slot; |
450 | int ret; | 453 | int ret; |
@@ -452,18 +455,20 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
452 | 455 | ||
453 | again: | 456 | again: |
454 | b = root->node; | 457 | b = root->node; |
455 | b->count++; | 458 | get_bh(b); |
456 | while (b) { | 459 | while (b) { |
457 | level = btrfs_header_level(&b->node.header); | 460 | c = btrfs_buffer_node(b); |
461 | level = btrfs_header_level(&c->header); | ||
458 | if (cow) { | 462 | if (cow) { |
459 | int wret; | 463 | int wret; |
460 | wret = btrfs_cow_block(trans, root, b, p->nodes[level + | 464 | wret = btrfs_cow_block(trans, root, b, |
461 | 1], p->slots[level + 1], | 465 | p->nodes[level + 1], |
466 | p->slots[level + 1], | ||
462 | &cow_buf); | 467 | &cow_buf); |
463 | b = cow_buf; | 468 | b = cow_buf; |
464 | } | 469 | } |
465 | BUG_ON(!cow && ins_len); | 470 | BUG_ON(!cow && ins_len); |
466 | c = &b->node; | 471 | c = btrfs_buffer_node(b); |
467 | p->nodes[level] = b; | 472 | p->nodes[level] = b; |
468 | ret = check_block(root, p, level); | 473 | ret = check_block(root, p, level); |
469 | if (ret) | 474 | if (ret) |
@@ -480,7 +485,7 @@ again: | |||
480 | if (sret) | 485 | if (sret) |
481 | return sret; | 486 | return sret; |
482 | b = p->nodes[level]; | 487 | b = p->nodes[level]; |
483 | c = &b->node; | 488 | c = btrfs_buffer_node(b); |
484 | slot = p->slots[level]; | 489 | slot = p->slots[level]; |
485 | } else if (ins_len < 0) { | 490 | } else if (ins_len < 0) { |
486 | int sret = balance_level(trans, root, p, | 491 | int sret = balance_level(trans, root, p, |
@@ -490,7 +495,7 @@ again: | |||
490 | b = p->nodes[level]; | 495 | b = p->nodes[level]; |
491 | if (!b) | 496 | if (!b) |
492 | goto again; | 497 | goto again; |
493 | c = &b->node; | 498 | c = btrfs_buffer_node(b); |
494 | slot = p->slots[level]; | 499 | slot = p->slots[level]; |
495 | BUG_ON(btrfs_header_nritems(&c->header) == 1); | 500 | BUG_ON(btrfs_header_nritems(&c->header) == 1); |
496 | } | 501 | } |
@@ -505,11 +510,9 @@ again: | |||
505 | if (sret) | 510 | if (sret) |
506 | return sret; | 511 | return sret; |
507 | } | 512 | } |
508 | BUG_ON(root->node->count == 1); | ||
509 | return ret; | 513 | return ret; |
510 | } | 514 | } |
511 | } | 515 | } |
512 | BUG_ON(root->node->count == 1); | ||
513 | return 1; | 516 | return 1; |
514 | } | 517 | } |
515 | 518 | ||
@@ -534,9 +537,9 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root | |||
534 | int tslot = path->slots[i]; | 537 | int tslot = path->slots[i]; |
535 | if (!path->nodes[i]) | 538 | if (!path->nodes[i]) |
536 | break; | 539 | break; |
537 | t = &path->nodes[i]->node; | 540 | t = btrfs_buffer_node(path->nodes[i]); |
538 | memcpy(&t->ptrs[tslot].key, key, sizeof(*key)); | 541 | memcpy(&t->ptrs[tslot].key, key, sizeof(*key)); |
539 | BUG_ON(list_empty(&path->nodes[i]->dirty)); | 542 | BUG_ON(!buffer_dirty(path->nodes[i])); |
540 | if (tslot != 0) | 543 | if (tslot != 0) |
541 | break; | 544 | break; |
542 | } | 545 | } |
@@ -551,11 +554,11 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root | |||
551 | * error, and > 0 if there was no room in the left hand block. | 554 | * error, and > 0 if there was no room in the left hand block. |
552 | */ | 555 | */ |
553 | static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | 556 | static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root |
554 | *root, struct btrfs_buffer *dst_buf, struct | 557 | *root, struct buffer_head *dst_buf, struct |
555 | btrfs_buffer *src_buf) | 558 | buffer_head *src_buf) |
556 | { | 559 | { |
557 | struct btrfs_node *src = &src_buf->node; | 560 | struct btrfs_node *src = btrfs_buffer_node(src_buf); |
558 | struct btrfs_node *dst = &dst_buf->node; | 561 | struct btrfs_node *dst = btrfs_buffer_node(dst_buf); |
559 | int push_items = 0; | 562 | int push_items = 0; |
560 | int src_nritems; | 563 | int src_nritems; |
561 | int dst_nritems; | 564 | int dst_nritems; |
@@ -580,8 +583,8 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
580 | } | 583 | } |
581 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); | 584 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); |
582 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); | 585 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); |
583 | BUG_ON(list_empty(&src_buf->dirty)); | 586 | BUG_ON(!buffer_dirty(src_buf)); |
584 | BUG_ON(list_empty(&dst_buf->dirty)); | 587 | BUG_ON(!buffer_dirty(dst_buf)); |
585 | return ret; | 588 | return ret; |
586 | } | 589 | } |
587 | 590 | ||
@@ -595,11 +598,11 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
595 | * this will only push up to 1/2 the contents of the left node over | 598 | * this will only push up to 1/2 the contents of the left node over |
596 | */ | 599 | */ |
597 | static int balance_node_right(struct btrfs_trans_handle *trans, struct | 600 | static int balance_node_right(struct btrfs_trans_handle *trans, struct |
598 | btrfs_root *root, struct btrfs_buffer *dst_buf, | 601 | btrfs_root *root, struct buffer_head *dst_buf, |
599 | struct btrfs_buffer *src_buf) | 602 | struct buffer_head *src_buf) |
600 | { | 603 | { |
601 | struct btrfs_node *src = &src_buf->node; | 604 | struct btrfs_node *src = btrfs_buffer_node(src_buf); |
602 | struct btrfs_node *dst = &dst_buf->node; | 605 | struct btrfs_node *dst = btrfs_buffer_node(dst_buf); |
603 | int push_items = 0; | 606 | int push_items = 0; |
604 | int max_push; | 607 | int max_push; |
605 | int src_nritems; | 608 | int src_nritems; |
@@ -628,8 +631,8 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct | |||
628 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); | 631 | btrfs_set_header_nritems(&src->header, src_nritems - push_items); |
629 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); | 632 | btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); |
630 | 633 | ||
631 | BUG_ON(list_empty(&src_buf->dirty)); | 634 | BUG_ON(!buffer_dirty(src_buf)); |
632 | BUG_ON(list_empty(&dst_buf->dirty)); | 635 | BUG_ON(!buffer_dirty(dst_buf)); |
633 | return ret; | 636 | return ret; |
634 | } | 637 | } |
635 | 638 | ||
@@ -643,7 +646,7 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct | |||
643 | static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root | 646 | static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root |
644 | *root, struct btrfs_path *path, int level) | 647 | *root, struct btrfs_path *path, int level) |
645 | { | 648 | { |
646 | struct btrfs_buffer *t; | 649 | struct buffer_head *t; |
647 | struct btrfs_node *lower; | 650 | struct btrfs_node *lower; |
648 | struct btrfs_node *c; | 651 | struct btrfs_node *c; |
649 | struct btrfs_disk_key *lower_key; | 652 | struct btrfs_disk_key *lower_key; |
@@ -652,24 +655,24 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root | |||
652 | BUG_ON(path->nodes[level-1] != root->node); | 655 | BUG_ON(path->nodes[level-1] != root->node); |
653 | 656 | ||
654 | t = btrfs_alloc_free_block(trans, root); | 657 | t = btrfs_alloc_free_block(trans, root); |
655 | c = &t->node; | 658 | c = btrfs_buffer_node(t); |
656 | memset(c, 0, root->blocksize); | 659 | memset(c, 0, root->blocksize); |
657 | btrfs_set_header_nritems(&c->header, 1); | 660 | btrfs_set_header_nritems(&c->header, 1); |
658 | btrfs_set_header_level(&c->header, level); | 661 | btrfs_set_header_level(&c->header, level); |
659 | btrfs_set_header_blocknr(&c->header, t->blocknr); | 662 | btrfs_set_header_blocknr(&c->header, t->b_blocknr); |
660 | btrfs_set_header_parentid(&c->header, | 663 | btrfs_set_header_parentid(&c->header, |
661 | btrfs_header_parentid(&root->node->node.header)); | 664 | btrfs_header_parentid(btrfs_buffer_header(root->node))); |
662 | lower = &path->nodes[level-1]->node; | 665 | lower = btrfs_buffer_node(path->nodes[level-1]); |
663 | if (btrfs_is_leaf(lower)) | 666 | if (btrfs_is_leaf(lower)) |
664 | lower_key = &((struct btrfs_leaf *)lower)->items[0].key; | 667 | lower_key = &((struct btrfs_leaf *)lower)->items[0].key; |
665 | else | 668 | else |
666 | lower_key = &lower->ptrs[0].key; | 669 | lower_key = &lower->ptrs[0].key; |
667 | memcpy(&c->ptrs[0].key, lower_key, sizeof(struct btrfs_disk_key)); | 670 | memcpy(&c->ptrs[0].key, lower_key, sizeof(struct btrfs_disk_key)); |
668 | btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->blocknr); | 671 | btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->b_blocknr); |
669 | /* the super has an extra ref to root->node */ | 672 | /* the super has an extra ref to root->node */ |
670 | btrfs_block_release(root, root->node); | 673 | btrfs_block_release(root, root->node); |
671 | root->node = t; | 674 | root->node = t; |
672 | t->count++; | 675 | get_bh(t); |
673 | path->nodes[level] = t; | 676 | path->nodes[level] = t; |
674 | path->slots[level] = 0; | 677 | path->slots[level] = 0; |
675 | return 0; | 678 | return 0; |
@@ -692,7 +695,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | |||
692 | int nritems; | 695 | int nritems; |
693 | 696 | ||
694 | BUG_ON(!path->nodes[level]); | 697 | BUG_ON(!path->nodes[level]); |
695 | lower = &path->nodes[level]->node; | 698 | lower = btrfs_buffer_node(path->nodes[level]); |
696 | nritems = btrfs_header_nritems(&lower->header); | 699 | nritems = btrfs_header_nritems(&lower->header); |
697 | if (slot > nritems) | 700 | if (slot > nritems) |
698 | BUG(); | 701 | BUG(); |
@@ -705,7 +708,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | |||
705 | memcpy(&lower->ptrs[slot].key, key, sizeof(struct btrfs_disk_key)); | 708 | memcpy(&lower->ptrs[slot].key, key, sizeof(struct btrfs_disk_key)); |
706 | btrfs_set_node_blockptr(lower, slot, blocknr); | 709 | btrfs_set_node_blockptr(lower, slot, blocknr); |
707 | btrfs_set_header_nritems(&lower->header, nritems + 1); | 710 | btrfs_set_header_nritems(&lower->header, nritems + 1); |
708 | BUG_ON(list_empty(&path->nodes[level]->dirty)); | 711 | BUG_ON(!buffer_dirty(path->nodes[level])); |
709 | return 0; | 712 | return 0; |
710 | } | 713 | } |
711 | 714 | ||
@@ -721,9 +724,9 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | |||
721 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | 724 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root |
722 | *root, struct btrfs_path *path, int level) | 725 | *root, struct btrfs_path *path, int level) |
723 | { | 726 | { |
724 | struct btrfs_buffer *t; | 727 | struct buffer_head *t; |
725 | struct btrfs_node *c; | 728 | struct btrfs_node *c; |
726 | struct btrfs_buffer *split_buffer; | 729 | struct buffer_head *split_buffer; |
727 | struct btrfs_node *split; | 730 | struct btrfs_node *split; |
728 | int mid; | 731 | int mid; |
729 | int ret; | 732 | int ret; |
@@ -731,7 +734,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
731 | u32 c_nritems; | 734 | u32 c_nritems; |
732 | 735 | ||
733 | t = path->nodes[level]; | 736 | t = path->nodes[level]; |
734 | c = &t->node; | 737 | c = btrfs_buffer_node(t); |
735 | if (t == root->node) { | 738 | if (t == root->node) { |
736 | /* trying to split the root, lets make a new one */ | 739 | /* trying to split the root, lets make a new one */ |
737 | ret = insert_new_root(trans, root, path, level + 1); | 740 | ret = insert_new_root(trans, root, path, level + 1); |
@@ -740,11 +743,11 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
740 | } | 743 | } |
741 | c_nritems = btrfs_header_nritems(&c->header); | 744 | c_nritems = btrfs_header_nritems(&c->header); |
742 | split_buffer = btrfs_alloc_free_block(trans, root); | 745 | split_buffer = btrfs_alloc_free_block(trans, root); |
743 | split = &split_buffer->node; | 746 | split = btrfs_buffer_node(split_buffer); |
744 | btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); | 747 | btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); |
745 | btrfs_set_header_blocknr(&split->header, split_buffer->blocknr); | 748 | btrfs_set_header_blocknr(&split->header, split_buffer->b_blocknr); |
746 | btrfs_set_header_parentid(&split->header, | 749 | btrfs_set_header_parentid(&split->header, |
747 | btrfs_header_parentid(&root->node->node.header)); | 750 | btrfs_header_parentid(btrfs_buffer_header(root->node))); |
748 | mid = (c_nritems + 1) / 2; | 751 | mid = (c_nritems + 1) / 2; |
749 | memcpy(split->ptrs, c->ptrs + mid, | 752 | memcpy(split->ptrs, c->ptrs + mid, |
750 | (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); | 753 | (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); |
@@ -752,9 +755,9 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
752 | btrfs_set_header_nritems(&c->header, mid); | 755 | btrfs_set_header_nritems(&c->header, mid); |
753 | ret = 0; | 756 | ret = 0; |
754 | 757 | ||
755 | BUG_ON(list_empty(&t->dirty)); | 758 | BUG_ON(!buffer_dirty(t)); |
756 | wret = insert_ptr(trans, root, path, &split->ptrs[0].key, | 759 | wret = insert_ptr(trans, root, path, &split->ptrs[0].key, |
757 | split_buffer->blocknr, path->slots[level + 1] + 1, | 760 | split_buffer->b_blocknr, path->slots[level + 1] + 1, |
758 | level + 1); | 761 | level + 1); |
759 | if (wret) | 762 | if (wret) |
760 | ret = wret; | 763 | ret = wret; |
@@ -798,11 +801,12 @@ static int leaf_space_used(struct btrfs_leaf *l, int start, int nr) | |||
798 | static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | 801 | static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root |
799 | *root, struct btrfs_path *path, int data_size) | 802 | *root, struct btrfs_path *path, int data_size) |
800 | { | 803 | { |
801 | struct btrfs_buffer *left_buf = path->nodes[0]; | 804 | struct buffer_head *left_buf = path->nodes[0]; |
802 | struct btrfs_leaf *left = &left_buf->leaf; | 805 | struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf); |
803 | struct btrfs_leaf *right; | 806 | struct btrfs_leaf *right; |
804 | struct btrfs_buffer *right_buf; | 807 | struct buffer_head *right_buf; |
805 | struct btrfs_buffer *upper; | 808 | struct buffer_head *upper; |
809 | struct btrfs_node *upper_node; | ||
806 | int slot; | 810 | int slot; |
807 | int i; | 811 | int i; |
808 | int free_space; | 812 | int free_space; |
@@ -817,12 +821,13 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
817 | return 1; | 821 | return 1; |
818 | } | 822 | } |
819 | upper = path->nodes[1]; | 823 | upper = path->nodes[1]; |
820 | if (slot >= btrfs_header_nritems(&upper->node.header) - 1) { | 824 | upper_node = btrfs_buffer_node(upper); |
825 | if (slot >= btrfs_header_nritems(&upper_node->header) - 1) { | ||
821 | return 1; | 826 | return 1; |
822 | } | 827 | } |
823 | right_buf = read_tree_block(root, btrfs_node_blockptr(&upper->node, | 828 | right_buf = read_tree_block(root, |
824 | slot + 1)); | 829 | btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1)); |
825 | right = &right_buf->leaf; | 830 | right = btrfs_buffer_leaf(right_buf); |
826 | free_space = btrfs_leaf_free_space(root, right); | 831 | free_space = btrfs_leaf_free_space(root, right); |
827 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 832 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
828 | btrfs_block_release(root, right_buf); | 833 | btrfs_block_release(root, right_buf); |
@@ -830,7 +835,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
830 | } | 835 | } |
831 | /* cow and double check */ | 836 | /* cow and double check */ |
832 | btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf); | 837 | btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf); |
833 | right = &right_buf->leaf; | 838 | right = btrfs_buffer_leaf(right_buf); |
834 | free_space = btrfs_leaf_free_space(root, right); | 839 | free_space = btrfs_leaf_free_space(root, right); |
835 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 840 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
836 | btrfs_block_release(root, right_buf); | 841 | btrfs_block_release(root, right_buf); |
@@ -881,11 +886,11 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
881 | left_nritems -= push_items; | 886 | left_nritems -= push_items; |
882 | btrfs_set_header_nritems(&left->header, left_nritems); | 887 | btrfs_set_header_nritems(&left->header, left_nritems); |
883 | 888 | ||
884 | BUG_ON(list_empty(&left_buf->dirty)); | 889 | BUG_ON(!buffer_dirty(left_buf)); |
885 | BUG_ON(list_empty(&right_buf->dirty)); | 890 | BUG_ON(!buffer_dirty(right_buf)); |
886 | memcpy(&upper->node.ptrs[slot + 1].key, | 891 | memcpy(&upper_node->ptrs[slot + 1].key, |
887 | &right->items[0].key, sizeof(struct btrfs_disk_key)); | 892 | &right->items[0].key, sizeof(struct btrfs_disk_key)); |
888 | BUG_ON(list_empty(&upper->dirty)); | 893 | BUG_ON(!buffer_dirty(upper)); |
889 | 894 | ||
890 | /* then fixup the leaf pointer in the path */ | 895 | /* then fixup the leaf pointer in the path */ |
891 | if (path->slots[0] >= left_nritems) { | 896 | if (path->slots[0] >= left_nritems) { |
@@ -905,9 +910,9 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
905 | static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | 910 | static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root |
906 | *root, struct btrfs_path *path, int data_size) | 911 | *root, struct btrfs_path *path, int data_size) |
907 | { | 912 | { |
908 | struct btrfs_buffer *right_buf = path->nodes[0]; | 913 | struct buffer_head *right_buf = path->nodes[0]; |
909 | struct btrfs_leaf *right = &right_buf->leaf; | 914 | struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf); |
910 | struct btrfs_buffer *t; | 915 | struct buffer_head *t; |
911 | struct btrfs_leaf *left; | 916 | struct btrfs_leaf *left; |
912 | int slot; | 917 | int slot; |
913 | int i; | 918 | int i; |
@@ -926,9 +931,9 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
926 | if (!path->nodes[1]) { | 931 | if (!path->nodes[1]) { |
927 | return 1; | 932 | return 1; |
928 | } | 933 | } |
929 | t = read_tree_block(root, btrfs_node_blockptr(&path->nodes[1]->node, | 934 | t = read_tree_block(root, |
930 | slot - 1)); | 935 | btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1)); |
931 | left = &t->leaf; | 936 | left = btrfs_buffer_leaf(t); |
932 | free_space = btrfs_leaf_free_space(root, left); | 937 | free_space = btrfs_leaf_free_space(root, left); |
933 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 938 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
934 | btrfs_block_release(root, t); | 939 | btrfs_block_release(root, t); |
@@ -937,7 +942,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
937 | 942 | ||
938 | /* cow and double check */ | 943 | /* cow and double check */ |
939 | btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); | 944 | btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); |
940 | left = &t->leaf; | 945 | left = btrfs_buffer_leaf(t); |
941 | free_space = btrfs_leaf_free_space(root, left); | 946 | free_space = btrfs_leaf_free_space(root, left); |
942 | if (free_space < data_size + sizeof(struct btrfs_item)) { | 947 | if (free_space < data_size + sizeof(struct btrfs_item)) { |
943 | btrfs_block_release(root, t); | 948 | btrfs_block_release(root, t); |
@@ -999,8 +1004,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
999 | push_space = btrfs_item_offset(right->items + i); | 1004 | push_space = btrfs_item_offset(right->items + i); |
1000 | } | 1005 | } |
1001 | 1006 | ||
1002 | BUG_ON(list_empty(&t->dirty)); | 1007 | BUG_ON(!buffer_dirty(t)); |
1003 | BUG_ON(list_empty(&right_buf->dirty)); | 1008 | BUG_ON(!buffer_dirty(right_buf)); |
1004 | 1009 | ||
1005 | wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); | 1010 | wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); |
1006 | if (wret) | 1011 | if (wret) |
@@ -1029,13 +1034,13 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1029 | static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | 1034 | static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root |
1030 | *root, struct btrfs_path *path, int data_size) | 1035 | *root, struct btrfs_path *path, int data_size) |
1031 | { | 1036 | { |
1032 | struct btrfs_buffer *l_buf; | 1037 | struct buffer_head *l_buf; |
1033 | struct btrfs_leaf *l; | 1038 | struct btrfs_leaf *l; |
1034 | u32 nritems; | 1039 | u32 nritems; |
1035 | int mid; | 1040 | int mid; |
1036 | int slot; | 1041 | int slot; |
1037 | struct btrfs_leaf *right; | 1042 | struct btrfs_leaf *right; |
1038 | struct btrfs_buffer *right_buffer; | 1043 | struct buffer_head *right_buffer; |
1039 | int space_needed = data_size + sizeof(struct btrfs_item); | 1044 | int space_needed = data_size + sizeof(struct btrfs_item); |
1040 | int data_copy_size; | 1045 | int data_copy_size; |
1041 | int rt_data_off; | 1046 | int rt_data_off; |
@@ -1053,7 +1058,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1053 | return wret; | 1058 | return wret; |
1054 | } | 1059 | } |
1055 | l_buf = path->nodes[0]; | 1060 | l_buf = path->nodes[0]; |
1056 | l = &l_buf->leaf; | 1061 | l = btrfs_buffer_leaf(l_buf); |
1057 | 1062 | ||
1058 | /* did the pushes work? */ | 1063 | /* did the pushes work? */ |
1059 | if (btrfs_leaf_free_space(root, l) >= | 1064 | if (btrfs_leaf_free_space(root, l) >= |
@@ -1071,7 +1076,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1071 | right_buffer = btrfs_alloc_free_block(trans, root); | 1076 | right_buffer = btrfs_alloc_free_block(trans, root); |
1072 | BUG_ON(!right_buffer); | 1077 | BUG_ON(!right_buffer); |
1073 | BUG_ON(mid == nritems); | 1078 | BUG_ON(mid == nritems); |
1074 | right = &right_buffer->leaf; | 1079 | right = btrfs_buffer_leaf(right_buffer); |
1075 | memset(&right->header, 0, sizeof(right->header)); | 1080 | memset(&right->header, 0, sizeof(right->header)); |
1076 | if (mid <= slot) { | 1081 | if (mid <= slot) { |
1077 | /* FIXME, just alloc a new leaf here */ | 1082 | /* FIXME, just alloc a new leaf here */ |
@@ -1085,10 +1090,10 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1085 | BUG(); | 1090 | BUG(); |
1086 | } | 1091 | } |
1087 | btrfs_set_header_nritems(&right->header, nritems - mid); | 1092 | btrfs_set_header_nritems(&right->header, nritems - mid); |
1088 | btrfs_set_header_blocknr(&right->header, right_buffer->blocknr); | 1093 | btrfs_set_header_blocknr(&right->header, right_buffer->b_blocknr); |
1089 | btrfs_set_header_level(&right->header, 0); | 1094 | btrfs_set_header_level(&right->header, 0); |
1090 | btrfs_set_header_parentid(&right->header, | 1095 | btrfs_set_header_parentid(&right->header, |
1091 | btrfs_header_parentid(&root->node->node.header)); | 1096 | btrfs_header_parentid(btrfs_buffer_header(root->node))); |
1092 | data_copy_size = btrfs_item_end(l->items + mid) - | 1097 | data_copy_size = btrfs_item_end(l->items + mid) - |
1093 | leaf_data_end(root, l); | 1098 | leaf_data_end(root, l); |
1094 | memcpy(right->items, l->items + mid, | 1099 | memcpy(right->items, l->items + mid, |
@@ -1107,11 +1112,11 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1107 | btrfs_set_header_nritems(&l->header, mid); | 1112 | btrfs_set_header_nritems(&l->header, mid); |
1108 | ret = 0; | 1113 | ret = 0; |
1109 | wret = insert_ptr(trans, root, path, &right->items[0].key, | 1114 | wret = insert_ptr(trans, root, path, &right->items[0].key, |
1110 | right_buffer->blocknr, path->slots[1] + 1, 1); | 1115 | right_buffer->b_blocknr, path->slots[1] + 1, 1); |
1111 | if (wret) | 1116 | if (wret) |
1112 | ret = wret; | 1117 | ret = wret; |
1113 | BUG_ON(list_empty(&right_buffer->dirty)); | 1118 | BUG_ON(!buffer_dirty(right_buffer)); |
1114 | BUG_ON(list_empty(&l_buf->dirty)); | 1119 | BUG_ON(!buffer_dirty(l_buf)); |
1115 | BUG_ON(path->slots[0] != slot); | 1120 | BUG_ON(path->slots[0] != slot); |
1116 | if (mid <= slot) { | 1121 | if (mid <= slot) { |
1117 | btrfs_block_release(root, path->nodes[0]); | 1122 | btrfs_block_release(root, path->nodes[0]); |
@@ -1136,7 +1141,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1136 | int slot; | 1141 | int slot; |
1137 | int slot_orig; | 1142 | int slot_orig; |
1138 | struct btrfs_leaf *leaf; | 1143 | struct btrfs_leaf *leaf; |
1139 | struct btrfs_buffer *leaf_buf; | 1144 | struct buffer_head *leaf_buf; |
1140 | u32 nritems; | 1145 | u32 nritems; |
1141 | unsigned int data_end; | 1146 | unsigned int data_end; |
1142 | struct btrfs_disk_key disk_key; | 1147 | struct btrfs_disk_key disk_key; |
@@ -1156,7 +1161,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1156 | 1161 | ||
1157 | slot_orig = path->slots[0]; | 1162 | slot_orig = path->slots[0]; |
1158 | leaf_buf = path->nodes[0]; | 1163 | leaf_buf = path->nodes[0]; |
1159 | leaf = &leaf_buf->leaf; | 1164 | leaf = btrfs_buffer_leaf(leaf_buf); |
1160 | 1165 | ||
1161 | nritems = btrfs_header_nritems(&leaf->header); | 1166 | nritems = btrfs_header_nritems(&leaf->header); |
1162 | data_end = leaf_data_end(root, leaf); | 1167 | data_end = leaf_data_end(root, leaf); |
@@ -1202,7 +1207,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1202 | if (slot == 0) | 1207 | if (slot == 0) |
1203 | ret = fixup_low_keys(trans, root, path, &disk_key, 1); | 1208 | ret = fixup_low_keys(trans, root, path, &disk_key, 1); |
1204 | 1209 | ||
1205 | BUG_ON(list_empty(&leaf_buf->dirty)); | 1210 | BUG_ON(!buffer_dirty(leaf_buf)); |
1206 | if (btrfs_leaf_free_space(root, leaf) < 0) | 1211 | if (btrfs_leaf_free_space(root, leaf) < 0) |
1207 | BUG(); | 1212 | BUG(); |
1208 | check_leaf(root, path, 0); | 1213 | check_leaf(root, path, 0); |
@@ -1225,7 +1230,8 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1225 | btrfs_init_path(&path); | 1230 | btrfs_init_path(&path); |
1226 | ret = btrfs_insert_empty_item(trans, root, &path, cpu_key, data_size); | 1231 | ret = btrfs_insert_empty_item(trans, root, &path, cpu_key, data_size); |
1227 | if (!ret) { | 1232 | if (!ret) { |
1228 | ptr = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0], u8); | 1233 | ptr = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), |
1234 | path.slots[0], u8); | ||
1229 | memcpy(ptr, data, data_size); | 1235 | memcpy(ptr, data, data_size); |
1230 | } | 1236 | } |
1231 | btrfs_release_path(root, &path); | 1237 | btrfs_release_path(root, &path); |
@@ -1243,12 +1249,12 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1243 | struct btrfs_path *path, int level, int slot) | 1249 | struct btrfs_path *path, int level, int slot) |
1244 | { | 1250 | { |
1245 | struct btrfs_node *node; | 1251 | struct btrfs_node *node; |
1246 | struct btrfs_buffer *parent = path->nodes[level]; | 1252 | struct buffer_head *parent = path->nodes[level]; |
1247 | u32 nritems; | 1253 | u32 nritems; |
1248 | int ret = 0; | 1254 | int ret = 0; |
1249 | int wret; | 1255 | int wret; |
1250 | 1256 | ||
1251 | node = &parent->node; | 1257 | node = btrfs_buffer_node(parent); |
1252 | nritems = btrfs_header_nritems(&node->header); | 1258 | nritems = btrfs_header_nritems(&node->header); |
1253 | if (slot != nritems -1) { | 1259 | if (slot != nritems -1) { |
1254 | memmove(node->ptrs + slot, node->ptrs + slot + 1, | 1260 | memmove(node->ptrs + slot, node->ptrs + slot + 1, |
@@ -1257,16 +1263,17 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1257 | nritems--; | 1263 | nritems--; |
1258 | btrfs_set_header_nritems(&node->header, nritems); | 1264 | btrfs_set_header_nritems(&node->header, nritems); |
1259 | if (nritems == 0 && parent == root->node) { | 1265 | if (nritems == 0 && parent == root->node) { |
1260 | BUG_ON(btrfs_header_level(&root->node->node.header) != 1); | 1266 | struct btrfs_header *header = btrfs_buffer_header(root->node); |
1267 | BUG_ON(btrfs_header_level(header) != 1); | ||
1261 | /* just turn the root into a leaf and break */ | 1268 | /* just turn the root into a leaf and break */ |
1262 | btrfs_set_header_level(&root->node->node.header, 0); | 1269 | btrfs_set_header_level(header, 0); |
1263 | } else if (slot == 0) { | 1270 | } else if (slot == 0) { |
1264 | wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, | 1271 | wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, |
1265 | level + 1); | 1272 | level + 1); |
1266 | if (wret) | 1273 | if (wret) |
1267 | ret = wret; | 1274 | ret = wret; |
1268 | } | 1275 | } |
1269 | BUG_ON(list_empty(&parent->dirty)); | 1276 | BUG_ON(!buffer_dirty(parent)); |
1270 | return ret; | 1277 | return ret; |
1271 | } | 1278 | } |
1272 | 1279 | ||
@@ -1279,7 +1286,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1279 | { | 1286 | { |
1280 | int slot; | 1287 | int slot; |
1281 | struct btrfs_leaf *leaf; | 1288 | struct btrfs_leaf *leaf; |
1282 | struct btrfs_buffer *leaf_buf; | 1289 | struct buffer_head *leaf_buf; |
1283 | int doff; | 1290 | int doff; |
1284 | int dsize; | 1291 | int dsize; |
1285 | int ret = 0; | 1292 | int ret = 0; |
@@ -1287,7 +1294,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1287 | u32 nritems; | 1294 | u32 nritems; |
1288 | 1295 | ||
1289 | leaf_buf = path->nodes[0]; | 1296 | leaf_buf = path->nodes[0]; |
1290 | leaf = &leaf_buf->leaf; | 1297 | leaf = btrfs_buffer_leaf(leaf_buf); |
1291 | slot = path->slots[0]; | 1298 | slot = path->slots[0]; |
1292 | doff = btrfs_item_offset(leaf->items + slot); | 1299 | doff = btrfs_item_offset(leaf->items + slot); |
1293 | dsize = btrfs_item_size(leaf->items + slot); | 1300 | dsize = btrfs_item_size(leaf->items + slot); |
@@ -1313,14 +1320,13 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1313 | if (nritems == 0) { | 1320 | if (nritems == 0) { |
1314 | if (leaf_buf == root->node) { | 1321 | if (leaf_buf == root->node) { |
1315 | btrfs_set_header_level(&leaf->header, 0); | 1322 | btrfs_set_header_level(&leaf->header, 0); |
1316 | BUG_ON(list_empty(&leaf_buf->dirty)); | ||
1317 | } else { | 1323 | } else { |
1318 | clean_tree_block(trans, root, leaf_buf); | 1324 | clean_tree_block(trans, root, leaf_buf); |
1319 | wret = del_ptr(trans, root, path, 1, path->slots[1]); | 1325 | wret = del_ptr(trans, root, path, 1, path->slots[1]); |
1320 | if (wret) | 1326 | if (wret) |
1321 | ret = wret; | 1327 | ret = wret; |
1322 | wret = btrfs_free_extent(trans, root, | 1328 | wret = btrfs_free_extent(trans, root, |
1323 | leaf_buf->blocknr, 1, 1); | 1329 | leaf_buf->b_blocknr, 1, 1); |
1324 | if (wret) | 1330 | if (wret) |
1325 | ret = wret; | 1331 | ret = wret; |
1326 | } | 1332 | } |
@@ -1332,7 +1338,6 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1332 | if (wret) | 1338 | if (wret) |
1333 | ret = wret; | 1339 | ret = wret; |
1334 | } | 1340 | } |
1335 | BUG_ON(list_empty(&leaf_buf->dirty)); | ||
1336 | 1341 | ||
1337 | /* delete the leaf if it is mostly empty */ | 1342 | /* delete the leaf if it is mostly empty */ |
1338 | if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { | 1343 | if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { |
@@ -1341,7 +1346,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1341 | * for possible call to del_ptr below | 1346 | * for possible call to del_ptr below |
1342 | */ | 1347 | */ |
1343 | slot = path->slots[1]; | 1348 | slot = path->slots[1]; |
1344 | leaf_buf->count++; | 1349 | get_bh(leaf_buf); |
1345 | wret = push_leaf_left(trans, root, path, 1); | 1350 | wret = push_leaf_left(trans, root, path, 1); |
1346 | if (wret < 0) | 1351 | if (wret < 0) |
1347 | ret = wret; | 1352 | ret = wret; |
@@ -1352,7 +1357,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1352 | ret = wret; | 1357 | ret = wret; |
1353 | } | 1358 | } |
1354 | if (btrfs_header_nritems(&leaf->header) == 0) { | 1359 | if (btrfs_header_nritems(&leaf->header) == 0) { |
1355 | u64 blocknr = leaf_buf->blocknr; | 1360 | u64 blocknr = leaf_buf->b_blocknr; |
1356 | clean_tree_block(trans, root, leaf_buf); | 1361 | clean_tree_block(trans, root, leaf_buf); |
1357 | wret = del_ptr(trans, root, path, 1, slot); | 1362 | wret = del_ptr(trans, root, path, 1, slot); |
1358 | if (wret) | 1363 | if (wret) |
@@ -1380,19 +1385,21 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
1380 | int slot; | 1385 | int slot; |
1381 | int level = 1; | 1386 | int level = 1; |
1382 | u64 blocknr; | 1387 | u64 blocknr; |
1383 | struct btrfs_buffer *c; | 1388 | struct buffer_head *c; |
1384 | struct btrfs_buffer *next = NULL; | 1389 | struct btrfs_node *c_node; |
1390 | struct buffer_head *next = NULL; | ||
1385 | 1391 | ||
1386 | while(level < BTRFS_MAX_LEVEL) { | 1392 | while(level < BTRFS_MAX_LEVEL) { |
1387 | if (!path->nodes[level]) | 1393 | if (!path->nodes[level]) |
1388 | return 1; | 1394 | return 1; |
1389 | slot = path->slots[level] + 1; | 1395 | slot = path->slots[level] + 1; |
1390 | c = path->nodes[level]; | 1396 | c = path->nodes[level]; |
1391 | if (slot >= btrfs_header_nritems(&c->node.header)) { | 1397 | c_node = btrfs_buffer_node(c); |
1398 | if (slot >= btrfs_header_nritems(&c_node->header)) { | ||
1392 | level++; | 1399 | level++; |
1393 | continue; | 1400 | continue; |
1394 | } | 1401 | } |
1395 | blocknr = btrfs_node_blockptr(&c->node, slot); | 1402 | blocknr = btrfs_node_blockptr(c_node, slot); |
1396 | if (next) | 1403 | if (next) |
1397 | btrfs_block_release(root, next); | 1404 | btrfs_block_release(root, next); |
1398 | next = read_tree_block(root, blocknr); | 1405 | next = read_tree_block(root, blocknr); |
@@ -1408,7 +1415,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
1408 | if (!level) | 1415 | if (!level) |
1409 | break; | 1416 | break; |
1410 | next = read_tree_block(root, | 1417 | next = read_tree_block(root, |
1411 | btrfs_node_blockptr(&next->node, 0)); | 1418 | btrfs_node_blockptr(btrfs_buffer_node(next), 0)); |
1412 | } | 1419 | } |
1413 | return 0; | 1420 | return 0; |
1414 | } | 1421 | } |