btrfs: Fix transaction abort during failure in btrfs_rm_dev_item
authorNikolay Borisov <nborisov@suse.com>
Mon, 23 Oct 2017 06:58:46 +0000 (09:58 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 3 Feb 2018 16:38:54 +0000 (17:38 +0100)
[ Upstream commit 5e9f2ad5b2904a7e81df6d9a3dbef29478952eac ]

btrfs_rm_dev_item calls several function under an active transaction,
however it fails to abort it if an error happens. Fix this by adding
explicit btrfs_abort_transaction/btrfs_end_transaction calls.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/btrfs/volumes.c

index 0c11121..4006b2a 100644 (file)
@@ -1765,20 +1765,24 @@ static int btrfs_rm_dev_item(struct btrfs_fs_info *fs_info,
        key.offset = device->devid;
 
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
-       if (ret < 0)
-               goto out;
-
-       if (ret > 0) {
-               ret = -ENOENT;
+       if (ret) {
+               if (ret > 0)
+                       ret = -ENOENT;
+               btrfs_abort_transaction(trans, ret);
+               btrfs_end_transaction(trans);
                goto out;
        }
 
        ret = btrfs_del_item(trans, root, path);
-       if (ret)
-               goto out;
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               btrfs_end_transaction(trans);
+       }
+
 out:
        btrfs_free_path(path);
-       btrfs_commit_transaction(trans);
+       if (!ret)
+               ret = btrfs_commit_transaction(trans);
        return ret;
 }