return ret;
 }
 
+static bool reshape_inprogress(struct mddev *mddev)
+{
+       return test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+              test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
+              !test_bit(MD_RECOVERY_DONE, &mddev->recovery) &&
+              !test_bit(MD_RECOVERY_INTR, &mddev->recovery);
+}
+
+static bool reshape_disabled(struct mddev *mddev)
+{
+       return is_md_suspended(mddev) || !md_is_rdwr(mddev);
+}
+
 static enum stripe_result make_stripe_request(struct mddev *mddev,
                struct r5conf *conf, struct stripe_request_ctx *ctx,
                sector_t logical_sector, struct bio *bi)
                        if (ahead_of_reshape(mddev, logical_sector,
                                             conf->reshape_safe)) {
                                spin_unlock_irq(&conf->device_lock);
-                               return STRIPE_SCHEDULE_AND_RETRY;
+                               ret = STRIPE_SCHEDULE_AND_RETRY;
+                               goto out;
                        }
                }
                spin_unlock_irq(&conf->device_lock);
 
 out_release:
        raid5_release_stripe(sh);
+out:
+       if (ret == STRIPE_SCHEDULE_AND_RETRY && !reshape_inprogress(mddev) &&
+           reshape_disabled(mddev)) {
+               bi->bi_status = BLK_STS_IOERR;
+               ret = STRIPE_FAIL;
+               pr_err("md/raid456:%s: io failed across reshape position while reshape can't make progress.\n",
+                      mdname(mddev));
+       }
+
        return ret;
 }
 
        return r5l_start(conf->log);
 }
 
+static void raid5_prepare_suspend(struct mddev *mddev)
+{
+       struct r5conf *conf = mddev->private;
+
+       wait_event(mddev->sb_wait, !reshape_inprogress(mddev) ||
+                                   percpu_ref_is_zero(&mddev->active_io));
+       if (percpu_ref_is_zero(&mddev->active_io))
+               return;
+
+       /*
+        * Reshape is not in progress, and array is suspended, io that is
+        * waiting for reshpape can never be done.
+        */
+       wake_up(&conf->wait_for_overlap);
+}
+
 static struct md_personality raid6_personality =
 {
        .name           = "raid6",
        .check_reshape  = raid6_check_reshape,
        .start_reshape  = raid5_start_reshape,
        .finish_reshape = raid5_finish_reshape,
+       .prepare_suspend = raid5_prepare_suspend,
        .quiesce        = raid5_quiesce,
        .takeover       = raid6_takeover,
        .change_consistency_policy = raid5_change_consistency_policy,
        .check_reshape  = raid5_check_reshape,
        .start_reshape  = raid5_start_reshape,
        .finish_reshape = raid5_finish_reshape,
+       .prepare_suspend = raid5_prepare_suspend,
        .quiesce        = raid5_quiesce,
        .takeover       = raid5_takeover,
        .change_consistency_policy = raid5_change_consistency_policy,
        .check_reshape  = raid5_check_reshape,
        .start_reshape  = raid5_start_reshape,
        .finish_reshape = raid5_finish_reshape,
+       .prepare_suspend = raid5_prepare_suspend,
        .quiesce        = raid5_quiesce,
        .takeover       = raid4_takeover,
        .change_consistency_policy = raid5_change_consistency_policy,