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

Reply via email to