]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.16.7/btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.16.7 / btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch
1 From 12b894cb288d57292b01cf158177b6d5c89a6272 Mon Sep 17 00:00:00 2001
2 From: Qu Wenruo <quwenruo@cn.fujitsu.com>
3 Date: Wed, 20 Aug 2014 16:10:15 +0800
4 Subject: btrfs: Fix a deadlock in btrfs_dev_replace_finishing()
5
6 From: Qu Wenruo <quwenruo@cn.fujitsu.com>
7
8 commit 12b894cb288d57292b01cf158177b6d5c89a6272 upstream.
9
10 btrfs-transacion:5657
11 [stack snip]
12 btrfs_bio_map()
13 btrfs_bio_counter_inc_blocked()
14 percpu_counter_inc(&fs_info->bio_counter) ###bio_counter > 0(A)
15 __btrfs_bio_map()
16 btrfs_dev_replace_lock()
17 mutex_lock(dev_replace->lock) ###wait mutex(B)
18
19 btrfs:32612
20 [stack snip]
21 btrfs_dev_replace_start()
22 btrfs_dev_replace_lock()
23 mutex_lock(dev_replace->lock) ###hold mutex(B)
24 btrfs_dev_replace_finishing()
25 btrfs_rm_dev_replace_blocked()
26 wait until percpu_counter_sum == 0 ###wait on bio_counter(A)
27
28 This bug can be triggered quite easily by the following test script:
29 http://pastebin.com/MQmb37Cy
30
31 This patch will fix the ABBA problem by calling
32 btrfs_dev_replace_unlock() before btrfs_rm_dev_replace_blocked().
33
34 The consistency of btrfs devices list and their superblocks is protected
35 by device_list_mutex, not btrfs_dev_replace_lock/unlock().
36 So it is safe the move btrfs_dev_replace_unlock() before
37 btrfs_rm_dev_replace_blocked().
38
39 Reported-by: Zhao Lei <zhaolei@cn.fujitsu.com>
40 Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
41 Cc: Stefan Behrens <sbehrens@giantdisaster.de>
42 Signed-off-by: Chris Mason <clm@fb.com>
43 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
44
45 ---
46 fs/btrfs/dev-replace.c | 3 ++-
47 1 file changed, 2 insertions(+), 1 deletion(-)
48
49 --- a/fs/btrfs/dev-replace.c
50 +++ b/fs/btrfs/dev-replace.c
51 @@ -567,6 +567,8 @@ static int btrfs_dev_replace_finishing(s
52 btrfs_kobj_rm_device(fs_info, src_device);
53 btrfs_kobj_add_device(fs_info, tgt_device);
54
55 + btrfs_dev_replace_unlock(dev_replace);
56 +
57 btrfs_rm_dev_replace_blocked(fs_info);
58
59 btrfs_rm_dev_replace_srcdev(fs_info, src_device);
60 @@ -580,7 +582,6 @@ static int btrfs_dev_replace_finishing(s
61 * superblock is scratched out so that it is no longer marked to
62 * belong to this filesystem.
63 */
64 - btrfs_dev_replace_unlock(dev_replace);
65 mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
66 mutex_unlock(&root->fs_info->chunk_mutex);
67