md: fix deadlock error in recent patch.
authorNeilBrown <neilb@suse.com>
Thu, 5 Oct 2017 05:23:16 +0000 (16:23 +1100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Nov 2017 08:40:47 +0000 (08:40 +0000)
commit d47c8ad261f787af22a220ffcc2d07afba809223 upstream.

A recent patch aimed to cause md_write_start() to fail (rather than
block) when the mddev was suspending, so as to avoid deadlocks.
Unfortunately the test in wait_event() was wrong, and it didn't change
behaviour at all.

We wait_event() must wait until the metadata is written OR the array is
suspending.

Fixes: cc27b0c78c79 ("md: fix deadlock between mddev_suspend() and md_write_start()")
Reported-by: Xiao Ni <xni@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Shaohua Li <shli@fb.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/md/md.c

index 0ff1bbf6c90e5cebc782268313ce39f8c66f7270..8b2eb0f4122fb74544825412b95ceb3e2f47089e 100644 (file)
@@ -8039,7 +8039,8 @@ bool md_write_start(struct mddev *mddev, struct bio *bi)
        if (did_change)
                sysfs_notify_dirent_safe(mddev->sysfs_state);
        wait_event(mddev->sb_wait,
-                  !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) && !mddev->suspended);
+                  !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) ||
+                  mddev->suspended);
        if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) {
                percpu_ref_put(&mddev->writes_pending);
                return false;