1 From fcc99734d1d4ced30167eb02e17f656735cb9928 Mon Sep 17 00:00:00 2001
2 From: Qu Wenruo <wqu@suse.com>
3 Date: Mon, 27 Apr 2020 14:50:14 +0800
4 Subject: btrfs: transaction: Avoid deadlock due to bad initialization timing of fs_info::journal_info
6 From: Qu Wenruo <wqu@suse.com>
8 commit fcc99734d1d4ced30167eb02e17f656735cb9928 upstream.
11 One run of btrfs/063 triggered the following lockdep warning:
12 ============================================
13 WARNING: possible recursive locking detected
14 5.6.0-rc7-custom+ #48 Not tainted
15 --------------------------------------------
16 kworker/u24:0/7 is trying to acquire lock:
17 ffff88817d3a46e0 (sb_internal#2){.+.+}, at: start_transaction+0x66c/0x890 [btrfs]
19 but task is already holding lock:
20 ffff88817d3a46e0 (sb_internal#2){.+.+}, at: start_transaction+0x66c/0x890 [btrfs]
22 other info that might help us debug this:
23 Possible unsafe locking scenario:
32 May be due to missing lock nesting notation
34 4 locks held by kworker/u24:0/7:
35 #0: ffff88817b495948 ((wq_completion)btrfs-endio-write){+.+.}, at: process_one_work+0x557/0xb80
36 #1: ffff888189ea7db8 ((work_completion)(&work->normal_work)){+.+.}, at: process_one_work+0x557/0xb80
37 #2: ffff88817d3a46e0 (sb_internal#2){.+.+}, at: start_transaction+0x66c/0x890 [btrfs]
38 #3: ffff888174ca4da8 (&fs_info->reloc_mutex){+.+.}, at: btrfs_record_root_in_trans+0x83/0xd0 [btrfs]
41 CPU: 0 PID: 7 Comm: kworker/u24:0 Not tainted 5.6.0-rc7-custom+ #48
42 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
43 Workqueue: btrfs-endio-write btrfs_work_helper [btrfs]
46 __lock_acquire.cold+0xce/0x214
47 lock_acquire+0xe6/0x210
48 __sb_start_write+0x14e/0x290
49 start_transaction+0x66c/0x890 [btrfs]
50 btrfs_join_transaction+0x1d/0x20 [btrfs]
51 find_free_extent+0x1504/0x1a50 [btrfs]
52 btrfs_reserve_extent+0xd5/0x1f0 [btrfs]
53 btrfs_alloc_tree_block+0x1ac/0x570 [btrfs]
54 btrfs_copy_root+0x213/0x580 [btrfs]
55 create_reloc_root+0x3bd/0x470 [btrfs]
56 btrfs_init_reloc_root+0x2d2/0x310 [btrfs]
57 record_root_in_trans+0x191/0x1d0 [btrfs]
58 btrfs_record_root_in_trans+0x90/0xd0 [btrfs]
59 start_transaction+0x16e/0x890 [btrfs]
60 btrfs_join_transaction+0x1d/0x20 [btrfs]
61 btrfs_finish_ordered_io+0x55d/0xcd0 [btrfs]
62 finish_ordered_fn+0x15/0x20 [btrfs]
63 btrfs_work_helper+0x116/0x9a0 [btrfs]
64 process_one_work+0x632/0xb80
65 worker_thread+0x80/0x690
67 ret_from_fork+0x27/0x50
69 It's pretty hard to reproduce, only one hit so far.
72 This is because we're calling btrfs_join_transaction() without re-using
73 the current running one:
75 btrfs_finish_ordered_io()
76 |- btrfs_join_transaction() <<< Call #1
77 |- btrfs_record_root_in_trans()
78 |- btrfs_reserve_extent()
79 |- btrfs_join_transaction() <<< Call #2
81 Normally such btrfs_join_transaction() call should re-use the existing
82 one, without trying to re-start a transaction.
84 But the problem is, in btrfs_join_transaction() call #1, we call
85 btrfs_record_root_in_trans() before initializing current::journal_info.
87 And in btrfs_join_transaction() call #2, we're relying on
88 current::journal_info to avoid such deadlock.
91 Call btrfs_record_root_in_trans() after we have initialized
92 current::journal_info.
94 CC: stable@vger.kernel.org # 4.4+
95 Signed-off-by: Qu Wenruo <wqu@suse.com>
96 Reviewed-by: David Sterba <dsterba@suse.com>
97 Signed-off-by: David Sterba <dsterba@suse.com>
98 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
101 fs/btrfs/transaction.c | 13 +++++++++++--
102 1 file changed, 11 insertions(+), 2 deletions(-)
104 --- a/fs/btrfs/transaction.c
105 +++ b/fs/btrfs/transaction.c
106 @@ -590,10 +590,19 @@ again:
110 - btrfs_record_root_in_trans(h, root);
112 if (!current->journal_info)
113 current->journal_info = h;
116 + * btrfs_record_root_in_trans() needs to alloc new extents, and may
117 + * call btrfs_join_transaction() while we're also starting a
120 + * Thus it need to be called after current->journal_info initialized,
121 + * or we can deadlock.
123 + btrfs_record_root_in_trans(h, root);