Commit 933c22a7 authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba

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=203253Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 112974d4
...@@ -474,6 +474,9 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) ...@@ -474,6 +474,9 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
struct rb_root_cached *root; struct rb_root_cached *root;
struct btrfs_delayed_root *delayed_root; struct btrfs_delayed_root *delayed_root;
/* Not associated with any delayed_node */
if (!delayed_item->delayed_node)
return;
delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root; delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root;
BUG_ON(!delayed_root); BUG_ON(!delayed_root);
...@@ -1525,7 +1528,12 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans, ...@@ -1525,7 +1528,12 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
* we have reserved enough space when we start a new transaction, * we have reserved enough space when we start a new transaction,
* so reserving metadata failure is impossible. * so reserving metadata failure is impossible.
*/ */
BUG_ON(ret); if (ret < 0) {
btrfs_err(trans->fs_info,
"metadata reservation failed for delayed dir item deltiona, should have been reserved");
btrfs_release_delayed_item(item);
goto end;
}
mutex_lock(&node->mutex); mutex_lock(&node->mutex);
ret = __btrfs_add_delayed_deletion_item(node, item); ret = __btrfs_add_delayed_deletion_item(node, item);
...@@ -1534,7 +1542,8 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans, ...@@ -1534,7 +1542,8 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
"err add delayed dir index item(index: %llu) into the deletion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)", "err add delayed dir index item(index: %llu) into the deletion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)",
index, node->root->root_key.objectid, index, node->root->root_key.objectid,
node->inode_id, ret); node->inode_id, ret);
BUG(); btrfs_delayed_item_release_metadata(dir->root, item);
btrfs_release_delayed_item(item);
} }
mutex_unlock(&node->mutex); mutex_unlock(&node->mutex);
end: end:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment