summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/delayed-inode.c
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2019-07-16 05:00:32 -0400
committerDavid Sterba <dsterba@suse.com>2019-09-09 08:59:01 -0400
commit933c22a7512c5c09b1fdc46b557384efe8d03233 (patch)
treecf109c43a22ced9f7254dc77cbe8b169cf09a6c7 /fs/btrfs/delayed-inode.c
parent112974d4067ba29ae59f94e0bc79f19bf9db1a53 (diff)
btrfs: delayed-inode: Kill the BUG_ON() in btrfs_delete_delayed_dir_index()
There is one report of fuzzed image which leads to BUG_ON() in btrfs_delete_delayed_dir_index(). Although that fuzzed image can already be addressed by enhanced extent-tree error handler, it's still better to hunt down more BUG_ON(). This patch will hunt down two BUG_ON()s in btrfs_delete_delayed_dir_index(): - One for error from btrfs_delayed_item_reserve_metadata() Instead of BUG_ON(), we output an error message and free the item. And return the error. All callers of this function handles the error by aborting current trasaction. - One for possible EEXIST from __btrfs_add_delayed_deletion_item() That function can return -EEXIST. We already have a good enough error message for that, only need to clean up the reserved metadata space and allocated item. To help above cleanup, also modifiy __btrfs_remove_delayed_item() called in btrfs_release_delayed_item(), to skip unassociated item. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203253 Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
-rw-r--r--fs/btrfs/delayed-inode.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 43fdb2992956..6858a05606dd 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -474,6 +474,9 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
474 struct rb_root_cached *root; 474 struct rb_root_cached *root;
475 struct btrfs_delayed_root *delayed_root; 475 struct btrfs_delayed_root *delayed_root;
476 476
477 /* Not associated with any delayed_node */
478 if (!delayed_item->delayed_node)
479 return;
477 delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root; 480 delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root;
478 481
479 BUG_ON(!delayed_root); 482 BUG_ON(!delayed_root);
@@ -1525,7 +1528,12 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
1525 * we have reserved enough space when we start a new transaction, 1528 * we have reserved enough space when we start a new transaction,
1526 * so reserving metadata failure is impossible. 1529 * so reserving metadata failure is impossible.
1527 */ 1530 */
1528 BUG_ON(ret); 1531 if (ret < 0) {
1532 btrfs_err(trans->fs_info,
1533"metadata reservation failed for delayed dir item deltiona, should have been reserved");
1534 btrfs_release_delayed_item(item);
1535 goto end;
1536 }
1529 1537
1530 mutex_lock(&node->mutex); 1538 mutex_lock(&node->mutex);
1531 ret = __btrfs_add_delayed_deletion_item(node, item); 1539 ret = __btrfs_add_delayed_deletion_item(node, item);
@@ -1534,7 +1542,8 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
1534 "err add delayed dir index item(index: %llu) into the deletion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)", 1542 "err add delayed dir index item(index: %llu) into the deletion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)",
1535 index, node->root->root_key.objectid, 1543 index, node->root->root_key.objectid,
1536 node->inode_id, ret); 1544 node->inode_id, ret);
1537 BUG(); 1545 btrfs_delayed_item_release_metadata(dir->root, item);
1546 btrfs_release_delayed_item(item);
1538 } 1547 }
1539 mutex_unlock(&node->mutex); 1548 mutex_unlock(&node->mutex);
1540end: 1549end: