diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2011-03-14 08:01:50 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-05-09 04:16:04 -0400 |
commit | 2b4dd36fbae7203a0d503a6cede1f4ce17aa72ac (patch) | |
tree | 09ad826a0203980e3ae54c1917a3a6badf51b773 /drivers/block/drbd/drbd_req.c | |
parent | 6d7e32f56806ad58006720ed98a433b2047444da (diff) |
drbd: Immediately allow completion of IOs, that wait for IO completions on a failed disk
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 | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 4a0f314086e5..1a8aac4b0c2f 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -214,8 +214,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) | |||
214 | { | 214 | { |
215 | const unsigned long s = req->rq_state; | 215 | const unsigned long s = req->rq_state; |
216 | struct drbd_conf *mdev = req->mdev; | 216 | struct drbd_conf *mdev = req->mdev; |
217 | /* only WRITES may end up here without a master bio (on barrier ack) */ | 217 | int rw = req->rq_state & RQ_WRITE ? WRITE : READ; |
218 | int rw = req->master_bio ? bio_data_dir(req->master_bio) : WRITE; | ||
219 | 218 | ||
220 | /* we must not complete the master bio, while it is | 219 | /* we must not complete the master bio, while it is |
221 | * still being processed by _drbd_send_zc_bio (drbd_send_dblock) | 220 | * still being processed by _drbd_send_zc_bio (drbd_send_dblock) |
@@ -230,7 +229,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) | |||
230 | return; | 229 | return; |
231 | if (s & RQ_NET_PENDING) | 230 | if (s & RQ_NET_PENDING) |
232 | return; | 231 | return; |
233 | if (s & RQ_LOCAL_PENDING) | 232 | if (s & RQ_LOCAL_PENDING && !(s & RQ_LOCAL_ABORTED)) |
234 | return; | 233 | return; |
235 | 234 | ||
236 | if (req->master_bio) { | 235 | if (req->master_bio) { |
@@ -277,6 +276,9 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) | |||
277 | req->master_bio = NULL; | 276 | req->master_bio = NULL; |
278 | } | 277 | } |
279 | 278 | ||
279 | if (s & RQ_LOCAL_PENDING) | ||
280 | return; | ||
281 | |||
280 | if ((s & RQ_NET_MASK) == 0 || (s & RQ_NET_DONE)) { | 282 | if ((s & RQ_NET_MASK) == 0 || (s & RQ_NET_DONE)) { |
281 | /* this is disconnected (local only) operation, | 283 | /* this is disconnected (local only) operation, |
282 | * or protocol C P_WRITE_ACK, | 284 | * or protocol C P_WRITE_ACK, |
@@ -429,7 +431,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
429 | break; | 431 | break; |
430 | 432 | ||
431 | case completed_ok: | 433 | case completed_ok: |
432 | if (bio_data_dir(req->master_bio) == WRITE) | 434 | if (req->rq_state & RQ_WRITE) |
433 | mdev->writ_cnt += req->size>>9; | 435 | mdev->writ_cnt += req->size>>9; |
434 | else | 436 | else |
435 | mdev->read_cnt += req->size>>9; | 437 | mdev->read_cnt += req->size>>9; |
@@ -441,6 +443,14 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
441 | put_ldev(mdev); | 443 | put_ldev(mdev); |
442 | break; | 444 | break; |
443 | 445 | ||
446 | case abort_disk_io: | ||
447 | req->rq_state |= RQ_LOCAL_ABORTED; | ||
448 | if (req->rq_state & RQ_WRITE) | ||
449 | _req_may_be_done_not_susp(req, m); | ||
450 | else | ||
451 | goto goto_queue_for_net_read; | ||
452 | break; | ||
453 | |||
444 | case write_completed_with_error: | 454 | case write_completed_with_error: |
445 | req->rq_state |= RQ_LOCAL_COMPLETED; | 455 | req->rq_state |= RQ_LOCAL_COMPLETED; |
446 | req->rq_state &= ~RQ_LOCAL_PENDING; | 456 | req->rq_state &= ~RQ_LOCAL_PENDING; |
@@ -469,6 +479,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
469 | __drbd_chk_io_error(mdev, false); | 479 | __drbd_chk_io_error(mdev, false); |
470 | put_ldev(mdev); | 480 | put_ldev(mdev); |
471 | 481 | ||
482 | goto_queue_for_net_read: | ||
483 | |||
472 | /* no point in retrying if there is no good remote data, | 484 | /* no point in retrying if there is no good remote data, |
473 | * or we have no connection. */ | 485 | * or we have no connection. */ |
474 | if (mdev->state.pdsk != D_UP_TO_DATE) { | 486 | if (mdev->state.pdsk != D_UP_TO_DATE) { |