diff options
author | Jeff Mahoney <jeffm@suse.com> | 2012-03-12 16:03:00 +0100 |
---|---|---|
committer | David Sterba <dsterba@suse.cz> | 2012-03-22 11:52:54 +0100 |
commit | 79787eaab46121d4713ed03c8fc63b9ec3eaec76 (patch) | |
tree | ee6b17d0811ee54ab74a03aa4e0bb92769d2f12a /fs/btrfs/inode-map.c | |
parent | 49b25e0540904be0bf558b84475c69d72e4de66e (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.c | 19 |
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) tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n", root->root_key.objectid); - BUG_ON(IS_ERR(tsk)); + BUG_ON(IS_ERR(tsk)); /* -ENOMEM */ } int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid) @@ -271,7 +271,7 @@ void btrfs_unpin_free_ino(struct btrfs_root *root) break; info = rb_entry(n, struct btrfs_free_space, offset_index); - BUG_ON(info->bitmap); + BUG_ON(info->bitmap); /* Logic error */ if (info->offset > root->cache_progress) goto free; @@ -443,13 +443,13 @@ int btrfs_save_ino_cache(struct btrfs_root *root, trans->bytes_reserved, 1); again: inode = lookup_free_ino_inode(root, path); - if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { + if (IS_ERR(inode) && (PTR_ERR(inode) != -ENOENT || retry)) { ret = PTR_ERR(inode); goto out_release; } if (IS_ERR(inode)) { - BUG_ON(retry); + BUG_ON(retry); /* Logic error */ retry = true; ret = create_free_ino_inode(root, trans, path); @@ -460,12 +460,17 @@ again: BTRFS_I(inode)->generation = 0; ret = btrfs_update_inode(trans, root, inode); - WARN_ON(ret); + if (ret) { + btrfs_abort_transaction(trans, root, ret); + goto out_put; + } if (i_size_read(inode) > 0) { ret = btrfs_truncate_free_space_cache(root, trans, path, inode); - if (ret) + if (ret) { + btrfs_abort_transaction(trans, root, ret); goto out_put; + } } spin_lock(&root->cache_lock); @@ -532,7 +537,7 @@ static int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid) ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); if (ret < 0) goto error; - BUG_ON(ret == 0); + BUG_ON(ret == 0); /* Corruption */ if (path->slots[0] > 0) { slot = path->slots[0] - 1; l = path->nodes[0]; |