summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-06-08 14:09:54 +0200
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-06-12 14:34:51 +0200
commit1ed25b269e3dd5ecc64f17beef9ea21745c39ca6 (patch)
treea311e656c28d4946ddb0849f1a4e42839706e990
parent4eccc579795290a58e2262fa4e9d083d7672e699 (diff)
drbd: fix list corruption by failing but already aborted reads
If a read is aborted due to force-detach of a supposedly unresponsive local backing device, and retried on the peer, it can happen that the local request later still completes (hopefully with an error). As it may already have been completed to upper layers meanwhile, it must not be retried again now. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r--drivers/block/drbd/drbd_req.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 9c5c84946b05..773f4e2d3c1b 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -472,12 +472,17 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
req->rq_state |= RQ_LOCAL_COMPLETED;
req->rq_state &= ~RQ_LOCAL_PENDING;
- D_ASSERT(!(req->rq_state & RQ_NET_MASK));
+ if (req->rq_state & RQ_LOCAL_ABORTED) {
+ _req_may_be_done(req, m);
+ break;
+ }
__drbd_chk_io_error(mdev, false);
goto_queue_for_net_read:
+ D_ASSERT(!(req->rq_state & RQ_NET_MASK));
+
/* no point in retrying if there is no good remote data,
* or we have no connection. */
if (mdev->state.pdsk != D_UP_TO_DATE) {