diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2010-05-31 04:14:17 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2010-10-14 08:52:53 -0400 |
commit | 265be2d09853d425ad14a61cda0ca63345613d0c (patch) | |
tree | cc2f419d8aaa41fd088f3d24ca134c4d7f51aa64 /drivers/block/drbd/drbd_req.c | |
parent | 905cd7d8ac9b18e1f122b90dbebe1246b1c364fd (diff) |
drbd: Finished the "on-no-data-accessible suspend-io;" functionality
When no data is accessible (no connection to the peer, nor a local disk)
allow the user to select to freeze all IO operations instead of getting
IO errors.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_req.c')
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 48647589aa0d..8259d4f77285 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -226,6 +226,8 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) | |||
226 | return; | 226 | return; |
227 | if (s & RQ_LOCAL_PENDING) | 227 | if (s & RQ_LOCAL_PENDING) |
228 | return; | 228 | return; |
229 | if (mdev->state.susp) | ||
230 | return; | ||
229 | 231 | ||
230 | if (req->master_bio) { | 232 | if (req->master_bio) { |
231 | /* this is data_received (remote read) | 233 | /* this is data_received (remote read) |
@@ -634,6 +636,28 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
634 | /* else: done by handed_over_to_network */ | 636 | /* else: done by handed_over_to_network */ |
635 | break; | 637 | break; |
636 | 638 | ||
639 | case fail_frozen_disk_io: | ||
640 | if (!(req->rq_state & RQ_LOCAL_COMPLETED)) | ||
641 | break; | ||
642 | |||
643 | _req_may_be_done(req, m); | ||
644 | break; | ||
645 | |||
646 | case restart_frozen_disk_io: | ||
647 | if (!(req->rq_state & RQ_LOCAL_COMPLETED)) | ||
648 | break; | ||
649 | |||
650 | req->rq_state &= ~RQ_LOCAL_COMPLETED; | ||
651 | |||
652 | rv = MR_READ; | ||
653 | if (bio_data_dir(req->master_bio) == WRITE) | ||
654 | rv = MR_WRITE; | ||
655 | |||
656 | get_ldev(mdev); | ||
657 | req->w.cb = w_restart_disk_io; | ||
658 | drbd_queue_work(&mdev->data.work, &req->w); | ||
659 | break; | ||
660 | |||
637 | case resend: | 661 | case resend: |
638 | /* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK | 662 | /* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK |
639 | before the connection loss; only P_BARRIER_ACK was missing. | 663 | before the connection loss; only P_BARRIER_ACK was missing. |