]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.14.53/btrfs-fix-return-value-on-rename-exchange-failure.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.53 / btrfs-fix-return-value-on-rename-exchange-failure.patch
CommitLineData
db28afd3
GKH
1From c5b4a50b74018b3677098151ec5f4fce07d5e6a0 Mon Sep 17 00:00:00 2001
2From: Filipe Manana <fdmanana@suse.com>
3Date: Mon, 11 Jun 2018 19:24:16 +0100
4Subject: Btrfs: fix return value on rename exchange failure
5
6From: Filipe Manana <fdmanana@suse.com>
7
8commit c5b4a50b74018b3677098151ec5f4fce07d5e6a0 upstream.
9
10If we failed during a rename exchange operation after starting/joining a
11transaction, we would end up replacing the return value, stored in the
12local 'ret' variable, with the return value from btrfs_end_transaction().
13So this could end up returning 0 (success) to user space despite the
14operation having failed and aborted the transaction, because if there are
15multiple tasks having a reference on the transaction at the time
16btrfs_end_transaction() is called by the rename exchange, that function
17returns 0 (otherwise it returns -EIO and not the original error value).
18So fix this by not overwriting the return value on error after getting
19a transaction handle.
20
21Fixes: cdd1fedf8261 ("btrfs: add support for RENAME_EXCHANGE and RENAME_WHITEOUT")
22CC: stable@vger.kernel.org # 4.9+
23Signed-off-by: Filipe Manana <fdmanana@suse.com>
24Reviewed-by: David Sterba <dsterba@suse.com>
25Signed-off-by: David Sterba <dsterba@suse.com>
26Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
27
28---
29 fs/btrfs/inode.c | 4 +++-
30 1 file changed, 3 insertions(+), 1 deletion(-)
31
32--- a/fs/btrfs/inode.c
33+++ b/fs/btrfs/inode.c
34@@ -9769,6 +9769,7 @@ static int btrfs_rename_exchange(struct
35 u64 new_idx = 0;
36 u64 root_objectid;
37 int ret;
38+ int ret2;
39 bool root_log_pinned = false;
40 bool dest_log_pinned = false;
41
42@@ -9965,7 +9966,8 @@ out_fail:
43 dest_log_pinned = false;
44 }
45 }
46- ret = btrfs_end_transaction(trans);
47+ ret2 = btrfs_end_transaction(trans);
48+ ret = ret ? ret : ret2;
49 out_notrans:
50 if (new_ino == BTRFS_FIRST_FREE_OBJECTID)
51 up_read(&fs_info->subvol_sem);