Commit 790c1b8c authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: do proper error handling in create_reloc_inode

We already handle some errors in this function, and the callers do the
correct error handling, so clean up the rest of the function to do the
appropriate error handling.

There's a little extra work that needs to be done here, as we create the
inode item before we create the orphan item.  We could potentially add
the orphan item, but if we failed to create the inode item we would have
to abort the transaction.

Instead add a helper to delete the inode item we created in the case
that we're unable to look up the inode (this would likely be caused by
an ENOMEM), which if it succeeds means we can avoid a transaction abort
in this particular error case.
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 24cd6389
...@@ -3653,6 +3653,35 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans, ...@@ -3653,6 +3653,35 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans,
return ret; return ret;
} }
static void delete_orphan_inode(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 objectid)
{
struct btrfs_path *path;
struct btrfs_key key;
int ret = 0;
path = btrfs_alloc_path();
if (!path) {
ret = -ENOMEM;
goto out;
}
key.objectid = objectid;
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
if (ret) {
if (ret > 0)
ret = -ENOENT;
goto out;
}
ret = btrfs_del_item(trans, root, path);
out:
if (ret)
btrfs_abort_transaction(trans, ret);
btrfs_free_path(path);
}
/* /*
* helper to create inode for data relocation. * helper to create inode for data relocation.
* the inode is in data relocation tree and its link count is 0 * the inode is in data relocation tree and its link count is 0
...@@ -3679,10 +3708,16 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info, ...@@ -3679,10 +3708,16 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
goto out; goto out;
err = __insert_orphan_inode(trans, root, objectid); err = __insert_orphan_inode(trans, root, objectid);
BUG_ON(err); if (err)
goto out;
inode = btrfs_iget(fs_info->sb, objectid, root); inode = btrfs_iget(fs_info->sb, objectid, root);
BUG_ON(IS_ERR(inode)); if (IS_ERR(inode)) {
delete_orphan_inode(trans, root, objectid);
err = PTR_ERR(inode);
inode = NULL;
goto out;
}
BTRFS_I(inode)->index_cnt = group->start; BTRFS_I(inode)->index_cnt = group->start;
err = btrfs_orphan_add(trans, BTRFS_I(inode)); err = btrfs_orphan_add(trans, BTRFS_I(inode));
......
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