aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2011-01-21 11:10:37 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-03-10 05:48:06 -0500
commite636db5b956950b8b9bfbeb766a637f84bae1e3b (patch)
tree6b6b05d69c2baaf4ea4ec1dee5cd399aed85eb88
parent0ddc5549f88dfc4a4c919693e9a86095e89e080b (diff)
drbd: fix potential imbalance of ap_in_flight
When we receive a barrier ack, we walk the ring list of drbd requests in the transfer log of the respective epoch, do some housekeeping, and free those objects. We tried to keep epochs of mirrored and unmirrored drbd requests separate, and assert that no local-only requests are present in a barrier_acked epoch. It turns out that this has quite a number of corner cases and would add bloated code without functional benefit. We now revert the (insufficient) commits drbd: Fixed an issue with AHEAD -> SYNC_SOURCE transitions drbd: Ensure that an epoch contains only requests of one kind and instead fix the processing of barrier acks to cope with a mix of local-only and mirrored requests. 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_main.c25
-rw-r--r--drivers/block/drbd/drbd_req.c9
2 files changed, 5 insertions, 29 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index c3760f33d52c..9043772de400 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -337,23 +337,6 @@ bail:
337} 337}
338 338
339 339
340/* In C_AHEAD mode only out_of_sync packets are sent for requests. Detach
341 * those requests from the newsest barrier when changing to an other cstate.
342 *
343 * That headless list vanishes when the last request finished its write or
344 * send out_of_sync packet. */
345static void tl_forget(struct drbd_conf *mdev)
346{
347 struct drbd_tl_epoch *b;
348
349 if (test_bit(CREATE_BARRIER, &mdev->flags))
350 return;
351
352 b = mdev->newest_tle;
353 list_del(&b->requests);
354 _tl_add_barrier(mdev, b);
355}
356
357/** 340/**
358 * _tl_restart() - Walks the transfer log, and applies an action to all requests 341 * _tl_restart() - Walks the transfer log, and applies an action to all requests
359 * @mdev: DRBD device. 342 * @mdev: DRBD device.
@@ -1265,14 +1248,6 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
1265 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) 1248 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
1266 drbd_resume_al(mdev); 1249 drbd_resume_al(mdev);
1267 1250
1268 /* Start a new epoch in case we start to mirror write requests */
1269 if (!drbd_should_do_remote(os) && drbd_should_do_remote(ns))
1270 tl_forget(mdev);
1271
1272 /* Do not add local-only requests to an epoch with mirrored requests */
1273 if (drbd_should_do_remote(os) && !drbd_should_do_remote(ns))
1274 set_bit(CREATE_BARRIER, &mdev->flags);
1275
1276 ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC); 1251 ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC);
1277 if (ascw) { 1252 if (ascw) {
1278 ascw->os = os; 1253 ascw->os = os;
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 336937a14d3f..c28be4e5e57c 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -712,10 +712,11 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
712 dev_err(DEV, "FIXME (barrier_acked but pending)\n"); 712 dev_err(DEV, "FIXME (barrier_acked but pending)\n");
713 list_move(&req->tl_requests, &mdev->out_of_sequence_requests); 713 list_move(&req->tl_requests, &mdev->out_of_sequence_requests);
714 } 714 }
715 D_ASSERT(req->rq_state & RQ_NET_SENT); 715 if ((req->rq_state & RQ_NET_MASK) != 0) {
716 req->rq_state |= RQ_NET_DONE; 716 req->rq_state |= RQ_NET_DONE;
717 if (mdev->net_conf->wire_protocol == DRBD_PROT_A) 717 if (mdev->net_conf->wire_protocol == DRBD_PROT_A)
718 atomic_sub(req->size>>9, &mdev->ap_in_flight); 718 atomic_sub(req->size>>9, &mdev->ap_in_flight);
719 }
719 _req_may_be_done(req, m); /* Allowed while state.susp */ 720 _req_may_be_done(req, m); /* Allowed while state.susp */
720 break; 721 break;
721 722