aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-06-22 14:16:25 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-06-22 14:16:25 -0400
commit54aa1f4dfdacd60a19c4471220b24e581be6f774 (patch)
tree1462277822cc63c00ad31b522457363a5c6be6ab /fs/btrfs/ctree.c
parent11bd143fc8243cf48c934dc1c4479a5aacf58ce3 (diff)
Btrfs: Audit callers and return codes to make sure -ENOSPC gets up the stack
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c106
1 files changed, 82 insertions, 24 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 498dea0854c1..606a19b5916d 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -73,6 +73,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
73{ 73{
74 struct buffer_head *cow; 74 struct buffer_head *cow;
75 struct btrfs_node *cow_node; 75 struct btrfs_node *cow_node;
76 int ret;
76 77
77 if (btrfs_header_generation(btrfs_buffer_header(buf)) == 78 if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
78 trans->transid) { 79 trans->transid) {
@@ -80,6 +81,8 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
80 return 0; 81 return 0;
81 } 82 }
82 cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr); 83 cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr);
84 if (IS_ERR(cow))
85 return PTR_ERR(cow);
83 cow_node = btrfs_buffer_node(cow); 86 cow_node = btrfs_buffer_node(cow);
84 if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) 87 if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
85 WARN_ON(1); 88 WARN_ON(1);
@@ -87,7 +90,9 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
87 btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); 90 btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow));
88 btrfs_set_header_generation(&cow_node->header, trans->transid); 91 btrfs_set_header_generation(&cow_node->header, trans->transid);
89 btrfs_set_header_owner(&cow_node->header, root->root_key.objectid); 92 btrfs_set_header_owner(&cow_node->header, root->root_key.objectid);
90 btrfs_inc_ref(trans, root, buf); 93 ret = btrfs_inc_ref(trans, root, buf);
94 if (ret)
95 return ret;
91 if (buf == root->node) { 96 if (buf == root->node) {
92 root->node = cow; 97 root->node = cow;
93 get_bh(cow); 98 get_bh(cow);
@@ -320,6 +325,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
320 int wret; 325 int wret;
321 int pslot; 326 int pslot;
322 int orig_slot = path->slots[level]; 327 int orig_slot = path->slots[level];
328 int err_on_enospc = 0;
323 u64 orig_ptr; 329 u64 orig_ptr;
324 330
325 if (level == 0) 331 if (level == 0)
@@ -363,29 +369,43 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
363 BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 369 BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
364 return 0; 370 return 0;
365 371
372 if (btrfs_header_nritems(&mid->header) < 2)
373 err_on_enospc = 1;
374
366 left_buf = read_node_slot(root, parent_buf, pslot - 1); 375 left_buf = read_node_slot(root, parent_buf, pslot - 1);
367 right_buf = read_node_slot(root, parent_buf, pslot + 1); 376 right_buf = read_node_slot(root, parent_buf, pslot + 1);
368 377
369 /* first, try to make some room in the middle buffer */ 378 /* first, try to make some room in the middle buffer */
370 if (left_buf) { 379 if (left_buf) {
371 btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1, 380 wret = btrfs_cow_block(trans, root, left_buf,
372 &left_buf); 381 parent_buf, pslot - 1, &left_buf);
382 if (wret) {
383 ret = wret;
384 goto enospc;
385 }
373 left = btrfs_buffer_node(left_buf); 386 left = btrfs_buffer_node(left_buf);
374 orig_slot += btrfs_header_nritems(&left->header); 387 orig_slot += btrfs_header_nritems(&left->header);
375 wret = push_node_left(trans, root, left_buf, mid_buf); 388 wret = push_node_left(trans, root, left_buf, mid_buf);
376 if (wret < 0) 389 if (wret < 0)
377 ret = wret; 390 ret = wret;
391 if (btrfs_header_nritems(&mid->header) < 2)
392 err_on_enospc = 1;
378 } 393 }
379 394
380 /* 395 /*
381 * then try to empty the right most buffer into the middle 396 * then try to empty the right most buffer into the middle
382 */ 397 */
383 if (right_buf) { 398 if (right_buf) {
384 btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1, 399 wret = btrfs_cow_block(trans, root, right_buf,
385 &right_buf); 400 parent_buf, pslot + 1, &right_buf);
401 if (wret) {
402 ret = wret;
403 goto enospc;
404 }
405
386 right = btrfs_buffer_node(right_buf); 406 right = btrfs_buffer_node(right_buf);
387 wret = push_node_left(trans, root, mid_buf, right_buf); 407 wret = push_node_left(trans, root, mid_buf, right_buf);
388 if (wret < 0) 408 if (wret < 0 && wret != -ENOSPC)
389 ret = wret; 409 ret = wret;
390 if (btrfs_header_nritems(&right->header) == 0) { 410 if (btrfs_header_nritems(&right->header) == 0) {
391 u64 blocknr = bh_blocknr(right_buf); 411 u64 blocknr = bh_blocknr(right_buf);
@@ -421,8 +441,10 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
421 */ 441 */
422 BUG_ON(!left_buf); 442 BUG_ON(!left_buf);
423 wret = balance_node_right(trans, root, mid_buf, left_buf); 443 wret = balance_node_right(trans, root, mid_buf, left_buf);
424 if (wret < 0) 444 if (wret < 0) {
425 ret = wret; 445 ret = wret;
446 goto enospc;
447 }
426 BUG_ON(wret == 1); 448 BUG_ON(wret == 1);
427 } 449 }
428 if (btrfs_header_nritems(&mid->header) == 0) { 450 if (btrfs_header_nritems(&mid->header) == 0) {
@@ -467,7 +489,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
467 btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]), 489 btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
468 path->slots[level])) 490 path->slots[level]))
469 BUG(); 491 BUG();
470 492enospc:
471 if (right_buf) 493 if (right_buf)
472 btrfs_block_release(root, right_buf); 494 btrfs_block_release(root, right_buf);
473 if (left_buf) 495 if (left_buf)
@@ -519,10 +541,15 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
519 if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 541 if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
520 wret = 1; 542 wret = 1;
521 } else { 543 } else {
522 btrfs_cow_block(trans, root, left_buf, parent_buf, 544 ret = btrfs_cow_block(trans, root, left_buf, parent_buf,
523 pslot - 1, &left_buf); 545 pslot - 1, &left_buf);
524 left = btrfs_buffer_node(left_buf); 546 if (ret)
525 wret = push_node_left(trans, root, left_buf, mid_buf); 547 wret = 1;
548 else {
549 left = btrfs_buffer_node(left_buf);
550 wret = push_node_left(trans, root,
551 left_buf, mid_buf);
552 }
526 } 553 }
527 if (wret < 0) 554 if (wret < 0)
528 ret = wret; 555 ret = wret;
@@ -561,11 +588,16 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
561 if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { 588 if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
562 wret = 1; 589 wret = 1;
563 } else { 590 } else {
564 btrfs_cow_block(trans, root, right_buf, 591 ret = btrfs_cow_block(trans, root, right_buf,
565 parent_buf, pslot + 1, &right_buf); 592 parent_buf, pslot + 1,
566 right = btrfs_buffer_node(right_buf); 593 &right_buf);
567 wret = balance_node_right(trans, root, 594 if (ret)
568 right_buf, mid_buf); 595 wret = 1;
596 else {
597 right = btrfs_buffer_node(right_buf);
598 wret = balance_node_right(trans, root,
599 right_buf, mid_buf);
600 }
569 } 601 }
570 if (wret < 0) 602 if (wret < 0)
571 ret = wret; 603 ret = wret;
@@ -631,6 +663,10 @@ again:
631 p->nodes[level + 1], 663 p->nodes[level + 1],
632 p->slots[level + 1], 664 p->slots[level + 1],
633 &cow_buf); 665 &cow_buf);
666 if (wret) {
667 btrfs_block_release(root, cow_buf);
668 return wret;
669 }
634 b = cow_buf; 670 b = cow_buf;
635 c = btrfs_buffer_node(b); 671 c = btrfs_buffer_node(b);
636 } 672 }
@@ -737,6 +773,7 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
737 src_nritems = btrfs_header_nritems(&src->header); 773 src_nritems = btrfs_header_nritems(&src->header);
738 dst_nritems = btrfs_header_nritems(&dst->header); 774 dst_nritems = btrfs_header_nritems(&dst->header);
739 push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; 775 push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
776
740 if (push_items <= 0) { 777 if (push_items <= 0) {
741 return 1; 778 return 1;
742 } 779 }
@@ -827,6 +864,8 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
827 BUG_ON(path->nodes[level-1] != root->node); 864 BUG_ON(path->nodes[level-1] != root->node);
828 865
829 t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr); 866 t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr);
867 if (IS_ERR(t))
868 return PTR_ERR(t);
830 c = btrfs_buffer_node(t); 869 c = btrfs_buffer_node(t);
831 memset(c, 0, root->blocksize); 870 memset(c, 0, root->blocksize);
832 btrfs_set_header_nritems(&c->header, 1); 871 btrfs_set_header_nritems(&c->header, 1);
@@ -929,10 +968,15 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
929 btrfs_header_nritems(&c->header) < 968 btrfs_header_nritems(&c->header) <
930 BTRFS_NODEPTRS_PER_BLOCK(root) - 1) 969 BTRFS_NODEPTRS_PER_BLOCK(root) - 1)
931 return 0; 970 return 0;
971 if (ret < 0)
972 return ret;
932 } 973 }
933 974
934 c_nritems = btrfs_header_nritems(&c->header); 975 c_nritems = btrfs_header_nritems(&c->header);
935 split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr); 976 split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr);
977 if (IS_ERR(split_buffer))
978 return PTR_ERR(split_buffer);
979
936 split = btrfs_buffer_node(split_buffer); 980 split = btrfs_buffer_node(split_buffer);
937 btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 981 btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
938 btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); 982 btrfs_set_header_level(&split->header, btrfs_header_level(&c->header));
@@ -1022,6 +1066,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
1022 struct btrfs_item *item; 1066 struct btrfs_item *item;
1023 u32 left_nritems; 1067 u32 left_nritems;
1024 u32 right_nritems; 1068 u32 right_nritems;
1069 int ret;
1025 1070
1026 slot = path->slots[1]; 1071 slot = path->slots[1];
1027 if (!path->nodes[1]) { 1072 if (!path->nodes[1]) {
@@ -1041,7 +1086,12 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
1041 return 1; 1086 return 1;
1042 } 1087 }
1043 /* cow and double check */ 1088 /* cow and double check */
1044 btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf); 1089 ret = btrfs_cow_block(trans, root, right_buf, upper,
1090 slot + 1, &right_buf);
1091 if (ret) {
1092 btrfs_block_release(root, right_buf);
1093 return 1;
1094 }
1045 right = btrfs_buffer_leaf(right_buf); 1095 right = btrfs_buffer_leaf(right_buf);
1046 free_space = btrfs_leaf_free_space(root, right); 1096 free_space = btrfs_leaf_free_space(root, right);
1047 if (free_space < data_size + sizeof(struct btrfs_item)) { 1097 if (free_space < data_size + sizeof(struct btrfs_item)) {
@@ -1162,7 +1212,11 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
1162 } 1212 }
1163 1213
1164 /* cow and double check */ 1214 /* cow and double check */
1165 btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 1215 ret = btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
1216 if (ret) {
1217 /* we hit -ENOSPC, but it isn't fatal here */
1218 return 1;
1219 }
1166 left = btrfs_buffer_leaf(t); 1220 left = btrfs_buffer_leaf(t);
1167 free_space = btrfs_leaf_free_space(root, left); 1221 free_space = btrfs_leaf_free_space(root, left);
1168 if (free_space < data_size + sizeof(struct btrfs_item)) { 1222 if (free_space < data_size + sizeof(struct btrfs_item)) {
@@ -1309,8 +1363,11 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1309 slot = path->slots[0]; 1363 slot = path->slots[0];
1310 nritems = btrfs_header_nritems(&l->header); 1364 nritems = btrfs_header_nritems(&l->header);
1311 mid = (nritems + 1)/ 2; 1365 mid = (nritems + 1)/ 2;
1366
1312 right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 1367 right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
1313 BUG_ON(!right_buffer); 1368 if (IS_ERR(right_buffer))
1369 return PTR_ERR(right_buffer);
1370
1314 right = btrfs_buffer_leaf(right_buffer); 1371 right = btrfs_buffer_leaf(right_buffer);
1315 memset(&right->header, 0, sizeof(right->header)); 1372 memset(&right->header, 0, sizeof(right->header));
1316 btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1373 btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
@@ -1407,7 +1464,9 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1407 if (!double_split) 1464 if (!double_split)
1408 return ret; 1465 return ret;
1409 right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); 1466 right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr);
1410 BUG_ON(!right_buffer); 1467 if (IS_ERR(right_buffer))
1468 return PTR_ERR(right_buffer);
1469
1411 right = btrfs_buffer_leaf(right_buffer); 1470 right = btrfs_buffer_leaf(right_buffer);
1412 memset(&right->header, 0, sizeof(right->header)); 1471 memset(&right->header, 0, sizeof(right->header));
1413 btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); 1472 btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer));
@@ -1655,7 +1714,6 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
1655 ptr, data, data_size); 1714 ptr, data, data_size);
1656 btrfs_mark_buffer_dirty(path->nodes[0]); 1715 btrfs_mark_buffer_dirty(path->nodes[0]);
1657 } 1716 }
1658 btrfs_release_path(root, path);
1659 btrfs_free_path(path); 1717 btrfs_free_path(path);
1660 return ret; 1718 return ret;
1661} 1719}
@@ -1775,12 +1833,12 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1775 slot = path->slots[1]; 1833 slot = path->slots[1];
1776 get_bh(leaf_buf); 1834 get_bh(leaf_buf);
1777 wret = push_leaf_left(trans, root, path, 1); 1835 wret = push_leaf_left(trans, root, path, 1);
1778 if (wret < 0) 1836 if (wret < 0 && wret != -ENOSPC)
1779 ret = wret; 1837 ret = wret;
1780 if (path->nodes[0] == leaf_buf && 1838 if (path->nodes[0] == leaf_buf &&
1781 btrfs_header_nritems(&leaf->header)) { 1839 btrfs_header_nritems(&leaf->header)) {
1782 wret = push_leaf_right(trans, root, path, 1); 1840 wret = push_leaf_right(trans, root, path, 1);
1783 if (wret < 0) 1841 if (wret < 0 && wret != -ENOSPC)
1784 ret = wret; 1842 ret = wret;
1785 } 1843 }
1786 if (btrfs_header_nritems(&leaf->header) == 0) { 1844 if (btrfs_header_nritems(&leaf->header) == 0) {