summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode-map.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/inode-map.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/inode-map.c')
-rw-r--r--fs/btrfs/inode-map.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index ee15d88b33d2..7ca46e6e11ae 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -178,7 +178,7 @@ static void start_caching(struct btrfs_root *root)
178 178
179 tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n", 179 tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n",
180 root->root_key.objectid); 180 root->root_key.objectid);
181 BUG_ON(IS_ERR(tsk)); 181 BUG_ON(IS_ERR(tsk)); /* -ENOMEM */
182} 182}
183 183
184int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid) 184int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid)
@@ -271,7 +271,7 @@ void btrfs_unpin_free_ino(struct btrfs_root *root)
271 break; 271 break;
272 272
273 info = rb_entry(n, struct btrfs_free_space, offset_index); 273 info = rb_entry(n, struct btrfs_free_space, offset_index);
274 BUG_ON(info->bitmap); 274 BUG_ON(info->bitmap); /* Logic error */
275 275
276 if (info->offset > root->cache_progress) 276 if (info->offset > root->cache_progress)
277 goto free; 277 goto free;
@@ -443,13 +443,13 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
443 trans->bytes_reserved, 1); 443 trans->bytes_reserved, 1);
444again: 444again:
445 inode = lookup_free_ino_inode(root, path); 445 inode = lookup_free_ino_inode(root, path);
446 if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { 446 if (IS_ERR(inode) && (PTR_ERR(inode) != -ENOENT || retry)) {
447 ret = PTR_ERR(inode); 447 ret = PTR_ERR(inode);
448 goto out_release; 448 goto out_release;
449 } 449 }
450 450
451 if (IS_ERR(inode)) { 451 if (IS_ERR(inode)) {
452 BUG_ON(retry); 452 BUG_ON(retry); /* Logic error */
453 retry = true; 453 retry = true;
454 454
455 ret = create_free_ino_inode(root, trans, path); 455 ret = create_free_ino_inode(root, trans, path);
@@ -460,12 +460,17 @@ again:
460 460
461 BTRFS_I(inode)->generation = 0; 461 BTRFS_I(inode)->generation = 0;
462 ret = btrfs_update_inode(trans, root, inode); 462 ret = btrfs_update_inode(trans, root, inode);
463 WARN_ON(ret); 463 if (ret) {
464 btrfs_abort_transaction(trans, root, ret);
465 goto out_put;
466 }
464 467
465 if (i_size_read(inode) > 0) { 468 if (i_size_read(inode) > 0) {
466 ret = btrfs_truncate_free_space_cache(root, trans, path, inode); 469 ret = btrfs_truncate_free_space_cache(root, trans, path, inode);
467 if (ret) 470 if (ret) {
471 btrfs_abort_transaction(trans, root, ret);
468 goto out_put; 472 goto out_put;
473 }
469 } 474 }
470 475
471 spin_lock(&root->cache_lock); 476 spin_lock(&root->cache_lock);
@@ -532,7 +537,7 @@ static int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid)
532 ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); 537 ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
533 if (ret < 0) 538 if (ret < 0)
534 goto error; 539 goto error;
535 BUG_ON(ret == 0); 540 BUG_ON(ret == 0); /* Corruption */
536 if (path->slots[0] > 0) { 541 if (path->slots[0] > 0) {
537 slot = path->slots[0] - 1; 542 slot = path->slots[0] - 1;
538 l = path->nodes[0]; 543 l = path->nodes[0];