btrfs: improve error handling of btrfs_add_link
authorJohannes Thumshirn <jthumshirn@suse.de>
Wed, 12 Dec 2018 14:14:17 +0000 (15:14 +0100)
committerDavid Sterba <dsterba@suse.com>
Mon, 17 Dec 2018 13:51:50 +0000 (14:51 +0100)
In the error handling block, 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.

If the error handling in the error handling fails, there's not much left
to do and the abort either happened earlier in the callees or is
necessary here.

So if one of btrfs_del_root_ref() or btrfs_del_inode_ref() failed, abort
the transaction, but still return the original code of the failure
stored in 'ret' as this will be reported to the user.

Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index c5c27d5457cc613958d1292a0888fc71a9e31ec3..3d29505971fe23059b1cbb8adc814d2638a463d9 100644 (file)
@@ -6359,14 +6359,19 @@ fail_dir_item:
                err = btrfs_del_root_ref(trans, key.objectid,
                                         root->root_key.objectid, parent_ino,
                                         &local_index, name, name_len);
                err = btrfs_del_root_ref(trans, key.objectid,
                                         root->root_key.objectid, parent_ino,
                                         &local_index, name, name_len);
-
+               if (err)
+                       btrfs_abort_transaction(trans, err);
        } else if (add_backref) {
                u64 local_index;
                int err;
 
                err = btrfs_del_inode_ref(trans, root, name, name_len,
                                          ino, parent_ino, &local_index);
        } else if (add_backref) {
                u64 local_index;
                int err;
 
                err = btrfs_del_inode_ref(trans, root, name, name_len,
                                          ino, parent_ino, &local_index);
+               if (err)
+                       btrfs_abort_transaction(trans, err);
        }
        }
+
+       /* Return the original error code */
        return ret;
 }
 
        return ret;
 }