summaryrefslogtreecommitdiffstats
path: root/queue-3.17/btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-10-20 07:08:43 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-10-20 07:08:43 +0800
commit2792dbfd1e02a70a8eef7e0cc3f44cb77d6c100f (patch)
tree144197a1ba646cd9a50dd6a992c4772dd71d2e95 /queue-3.17/btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch
parent50bcc3fa4ae09ca5b72814b701ddd1d5432c303a (diff)
downloadstable-queue-2792dbfd1e02a70a8eef7e0cc3f44cb77d6c100f.tar.gz
3.17-stable patches
added patches: btrfs-add-missing-compression-property-remove-in-btrfs_ioctl_setflags.patch btrfs-cleanup-error-handling-in-build_backref_tree.patch btrfs-don-t-do-async-reclaim-during-log-replay.patch btrfs-don-t-go-readonly-on-existing-qgroup-items.patch btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch btrfs-fix-and-enhance-merge_extent_mapping-to-insert-best-fitted-extent-map.patch btrfs-fix-build_backref_tree-issue-with-multiple-shared-blocks.patch btrfs-fix-race-in-wait_sync-ioctl.patch btrfs-fix-the-wrong-condition-judgment-about-subset-extent-map.patch btrfs-fix-up-bounds-checking-in-lseek.patch btrfs-try-not-to-enospc-on-log-replay.patch btrfs-wake-up-transaction-thread-from-sync_fs-ioctl.patch revert-btrfs-race-free-update-of-commit-root-for-ro-snapshots.patch
Diffstat (limited to 'queue-3.17/btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch')
-rw-r--r--queue-3.17/btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch67
1 files changed, 67 insertions, 0 deletions
diff --git a/queue-3.17/btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch b/queue-3.17/btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch
new file mode 100644
index 000000000000..c1315402907f
--- /dev/null
+++ b/queue-3.17/btrfs-fix-a-deadlock-in-btrfs_dev_replace_finishing.patch
@@ -0,0 +1,67 @@
+From 12b894cb288d57292b01cf158177b6d5c89a6272 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <quwenruo@cn.fujitsu.com>
+Date: Wed, 20 Aug 2014 16:10:15 +0800
+Subject: btrfs: Fix a deadlock in btrfs_dev_replace_finishing()
+
+From: Qu Wenruo <quwenruo@cn.fujitsu.com>
+
+commit 12b894cb288d57292b01cf158177b6d5c89a6272 upstream.
+
+btrfs-transacion:5657
+[stack snip]
+btrfs_bio_map()
+ btrfs_bio_counter_inc_blocked()
+ percpu_counter_inc(&fs_info->bio_counter) ###bio_counter > 0(A)
+ __btrfs_bio_map()
+ btrfs_dev_replace_lock()
+ mutex_lock(dev_replace->lock) ###wait mutex(B)
+
+btrfs:32612
+[stack snip]
+btrfs_dev_replace_start()
+ btrfs_dev_replace_lock()
+ mutex_lock(dev_replace->lock) ###hold mutex(B)
+ btrfs_dev_replace_finishing()
+ btrfs_rm_dev_replace_blocked()
+ wait until percpu_counter_sum == 0 ###wait on bio_counter(A)
+
+This bug can be triggered quite easily by the following test script:
+http://pastebin.com/MQmb37Cy
+
+This patch will fix the ABBA problem by calling
+btrfs_dev_replace_unlock() before btrfs_rm_dev_replace_blocked().
+
+The consistency of btrfs devices list and their superblocks is protected
+by device_list_mutex, not btrfs_dev_replace_lock/unlock().
+So it is safe the move btrfs_dev_replace_unlock() before
+btrfs_rm_dev_replace_blocked().
+
+Reported-by: Zhao Lei <zhaolei@cn.fujitsu.com>
+Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
+Cc: Stefan Behrens <sbehrens@giantdisaster.de>
+Signed-off-by: Chris Mason <clm@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/dev-replace.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/dev-replace.c
++++ b/fs/btrfs/dev-replace.c
+@@ -567,6 +567,8 @@ static int btrfs_dev_replace_finishing(s
+ btrfs_kobj_rm_device(fs_info, src_device);
+ btrfs_kobj_add_device(fs_info, tgt_device);
+
++ btrfs_dev_replace_unlock(dev_replace);
++
+ btrfs_rm_dev_replace_blocked(fs_info);
+
+ btrfs_rm_dev_replace_srcdev(fs_info, src_device);
+@@ -580,7 +582,6 @@ static int btrfs_dev_replace_finishing(s
+ * superblock is scratched out so that it is no longer marked to
+ * belong to this filesystem.
+ */
+- btrfs_dev_replace_unlock(dev_replace);
+ mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
+ mutex_unlock(&root->fs_info->chunk_mutex);
+