mirror of https://gitee.com/openkylin/linux.git
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: Josef Bacik <josef@toxicpanda.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
24cd638902
commit
790c1b8cd4
|
@ -3653,6 +3653,35 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans,
|
|||
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.
|
||||
* 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,
|
|||
goto out;
|
||||
|
||||
err = __insert_orphan_inode(trans, root, objectid);
|
||||
BUG_ON(err);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
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;
|
||||
|
||||
err = btrfs_orphan_add(trans, BTRFS_I(inode));
|
||||
|
|
Loading…
Reference in New Issue