err holds the return value of either btrfs_del_root_ref() or btrfs_del_inode_ref() but it hasn't been checked since it's introduction with commit fe66a05a0679 (Btrfs: improve error handling for btrfs_insert_dir_item callers) in 2012.
The first attempt in removing the variable was rejected, so instead of removing 'err', start handling the errors of btrfs_del_root_ref()/btrfs_del_inode_ref() by aborting the transaction in btrfs_add_link() directly instead of the call-sites. Link: https://lore.kernel.org/linux-btrfs/20181119141323.gc24...@twin.jikos.cz/ Signed-off-by: Johannes Thumshirn <jthumsh...@suse.de> --- fs/btrfs/inode.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9becf8543489..314142ea9d80 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6351,6 +6351,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, struct btrfs_root *root = parent_inode->root; u64 ino = btrfs_ino(inode); u64 parent_ino = btrfs_ino(parent_inode); + int err = 0; if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) { memcpy(&key, &inode->root->root_key, sizeof(key)); @@ -6395,18 +6396,20 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, fail_dir_item: if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) { u64 local_index; - int err; + err = btrfs_del_root_ref(trans, key.objectid, root->root_key.objectid, parent_ino, &local_index, name, name_len); } else if (add_backref) { u64 local_index; - int err; err = btrfs_del_inode_ref(trans, root, name, name_len, ino, parent_ino, &local_index); } + + btrfs_abort_transaction(trans, err ? err : ret); + return ret; } @@ -9502,18 +9505,14 @@ static int btrfs_rename_exchange(struct inode *old_dir, ret = btrfs_add_link(trans, BTRFS_I(new_dir), BTRFS_I(old_inode), new_dentry->d_name.name, new_dentry->d_name.len, 0, old_idx); - if (ret) { - btrfs_abort_transaction(trans, ret); + if (ret) goto out_fail; - } ret = btrfs_add_link(trans, BTRFS_I(old_dir), BTRFS_I(new_inode), old_dentry->d_name.name, old_dentry->d_name.len, 0, new_idx); - if (ret) { - btrfs_abort_transaction(trans, ret); + if (ret) goto out_fail; - } if (old_inode->i_nlink == 1) BTRFS_I(old_inode)->dir_index = old_idx; @@ -9822,10 +9821,8 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, ret = btrfs_add_link(trans, BTRFS_I(new_dir), BTRFS_I(old_inode), new_dentry->d_name.name, new_dentry->d_name.len, 0, index); - if (ret) { - btrfs_abort_transaction(trans, ret); + if (ret) goto out_fail; - } if (old_inode->i_nlink == 1) BTRFS_I(old_inode)->dir_index = index; -- 2.16.4