summaryrefslogtreecommitdiffstats
path: root/0001-btrfs-fix-transaction-leak-in-btrfs_recover_relocati.patch
diff options
context:
space:
mode:
Diffstat (limited to '0001-btrfs-fix-transaction-leak-in-btrfs_recover_relocati.patch')
-rw-r--r--0001-btrfs-fix-transaction-leak-in-btrfs_recover_relocati.patch45
1 files changed, 45 insertions, 0 deletions
diff --git a/0001-btrfs-fix-transaction-leak-in-btrfs_recover_relocati.patch b/0001-btrfs-fix-transaction-leak-in-btrfs_recover_relocati.patch
new file mode 100644
index 000000000..52942ea7a
--- /dev/null
+++ b/0001-btrfs-fix-transaction-leak-in-btrfs_recover_relocati.patch
@@ -0,0 +1,45 @@
+From 1402d17dfd9657be0da8458b2079d03c2d61c86a Mon Sep 17 00:00:00 2001
+From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Date: Mon, 20 Apr 2020 13:39:39 +0800
+Subject: [PATCH] btrfs: fix transaction leak in btrfs_recover_relocation
+
+btrfs_recover_relocation() invokes btrfs_join_transaction(), which joins
+a btrfs_trans_handle object into transactions and returns a reference of
+it with increased refcount to "trans".
+
+When btrfs_recover_relocation() returns, "trans" becomes invalid, so the
+refcount should be decreased to keep refcount balanced.
+
+The reference counting issue happens in one exception handling path of
+btrfs_recover_relocation(). When read_fs_root() failed, the refcnt
+increased by btrfs_join_transaction() is not decreased, causing a refcnt
+leak.
+
+Fix this issue by calling btrfs_end_transaction() on this error path
+when read_fs_root() failed.
+
+Fixes: 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling")
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/relocation.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index d35936c934ab..03bc7134e8cb 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -4559,6 +4559,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
+ if (IS_ERR(fs_root)) {
+ err = PTR_ERR(fs_root);
+ list_add_tail(&reloc_root->root_list, &reloc_roots);
++ btrfs_end_transaction(trans);
+ goto out_unset;
+ }
+
+--
+2.26.2
+