4.13-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Shaohua Li <s...@fb.com>

commit 79bf31a3b2a7ca467cfec8ff97d359a77065d01f upstream.

md_submit_flush_data calls pers->make_request, which missed the suspend check.
Fix it with the new md_handle_request API.

Reported-by: Nate Dailey <nate.dai...@stratus.com>
Tested-by: Nate Dailey <nate.dai...@stratus.com>
Fix: cc27b0c78c79(md: fix deadlock between mddev_suspend() and md_write_start())
Reviewed-by: NeilBrown <ne...@suse.com>
Signed-off-by: Shaohua Li <s...@fb.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/md/md.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -439,16 +439,22 @@ static void md_submit_flush_data(struct
        struct mddev *mddev = container_of(ws, struct mddev, flush_work);
        struct bio *bio = mddev->flush_bio;
 
+       /*
+        * must reset flush_bio before calling into md_handle_request to avoid a
+        * deadlock, because other bios passed md_handle_request suspend check
+        * could wait for this and below md_handle_request could wait for those
+        * bios because of suspend check
+        */
+       mddev->flush_bio = NULL;
+       wake_up(&mddev->sb_wait);
+
        if (bio->bi_iter.bi_size == 0)
                /* an empty barrier - all done */
                bio_endio(bio);
        else {
                bio->bi_opf &= ~REQ_PREFLUSH;
-               mddev->pers->make_request(mddev, bio);
+               md_handle_request(mddev, bio);
        }
-
-       mddev->flush_bio = NULL;
-       wake_up(&mddev->sb_wait);
 }
 
 void md_flush_request(struct mddev *mddev, struct bio *bio)


Reply via email to