aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2012-03-12 11:03:00 -0400
committerDavid Sterba <dsterba@suse.cz>2012-03-22 06:52:54 -0400
commit79787eaab46121d4713ed03c8fc63b9ec3eaec76 (patch)
treeee6b17d0811ee54ab74a03aa4e0bb92769d2f12a /fs/btrfs/ctree.c
parent49b25e0540904be0bf558b84475c69d72e4de66e (diff)
btrfs: replace many BUG_ONs with proper error handling
btrfs currently handles most errors with BUG_ON. This patch is a work-in- progress but aims to handle most errors other than internal logic errors and ENOMEM more gracefully. This iteration prevents most crashes but can run into lockups with the page lock on occasion when the timing "works out." Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 651a26a6c651..e697afd18159 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -356,14 +356,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
356 root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && 356 root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) &&
357 !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { 357 !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) {
358 ret = btrfs_inc_ref(trans, root, buf, 1, 1); 358 ret = btrfs_inc_ref(trans, root, buf, 1, 1);
359 BUG_ON(ret); 359 BUG_ON(ret); /* -ENOMEM */
360 360
361 if (root->root_key.objectid == 361 if (root->root_key.objectid ==
362 BTRFS_TREE_RELOC_OBJECTID) { 362 BTRFS_TREE_RELOC_OBJECTID) {
363 ret = btrfs_dec_ref(trans, root, buf, 0, 1); 363 ret = btrfs_dec_ref(trans, root, buf, 0, 1);
364 BUG_ON(ret); 364 BUG_ON(ret); /* -ENOMEM */
365 ret = btrfs_inc_ref(trans, root, cow, 1, 1); 365 ret = btrfs_inc_ref(trans, root, cow, 1, 1);
366 BUG_ON(ret); 366 BUG_ON(ret); /* -ENOMEM */
367 } 367 }
368 new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; 368 new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF;
369 } else { 369 } else {
@@ -373,7 +373,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
373 ret = btrfs_inc_ref(trans, root, cow, 1, 1); 373 ret = btrfs_inc_ref(trans, root, cow, 1, 1);
374 else 374 else
375 ret = btrfs_inc_ref(trans, root, cow, 0, 1); 375 ret = btrfs_inc_ref(trans, root, cow, 0, 1);
376 BUG_ON(ret); 376 BUG_ON(ret); /* -ENOMEM */
377 } 377 }
378 if (new_flags != 0) { 378 if (new_flags != 0) {
379 ret = btrfs_set_disk_extent_flags(trans, root, 379 ret = btrfs_set_disk_extent_flags(trans, root,
@@ -390,9 +390,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
390 ret = btrfs_inc_ref(trans, root, cow, 1, 1); 390 ret = btrfs_inc_ref(trans, root, cow, 1, 1);
391 else 391 else
392 ret = btrfs_inc_ref(trans, root, cow, 0, 1); 392 ret = btrfs_inc_ref(trans, root, cow, 0, 1);
393 BUG_ON(ret); 393 BUG_ON(ret); /* -ENOMEM */
394 ret = btrfs_dec_ref(trans, root, buf, 1, 1); 394 ret = btrfs_dec_ref(trans, root, buf, 1, 1);
395 BUG_ON(ret); 395 BUG_ON(ret); /* -ENOMEM */
396 } 396 }
397 clean_tree_block(trans, root, buf); 397 clean_tree_block(trans, root, buf);
398 *last_ref = 1; 398 *last_ref = 1;
@@ -475,7 +475,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
475 475
476 ret = update_ref_for_cow(trans, root, buf, cow, &last_ref); 476 ret = update_ref_for_cow(trans, root, buf, cow, &last_ref);
477 if (ret) { 477 if (ret) {
478 btrfs_std_error(root->fs_info, ret); 478 btrfs_abort_transaction(trans, root, ret);
479 return ret; 479 return ret;
480 } 480 }
481 481
@@ -2713,7 +2713,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
2713 path->nodes[1], slot - 1, &left); 2713 path->nodes[1], slot - 1, &left);
2714 if (ret) { 2714 if (ret) {
2715 /* we hit -ENOSPC, but it isn't fatal here */ 2715 /* we hit -ENOSPC, but it isn't fatal here */
2716 ret = 1; 2716 if (ret == -ENOSPC)
2717 ret = 1;
2717 goto out; 2718 goto out;
2718 } 2719 }
2719 2720
@@ -4017,7 +4018,7 @@ find_next_key:
4017 } 4018 }
4018 btrfs_set_path_blocking(path); 4019 btrfs_set_path_blocking(path);
4019 cur = read_node_slot(root, cur, slot); 4020 cur = read_node_slot(root, cur, slot);
4020 BUG_ON(!cur); 4021 BUG_ON(!cur); /* -ENOMEM */
4021 4022
4022 btrfs_tree_read_lock(cur); 4023 btrfs_tree_read_lock(cur);
4023 4024