summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_req.c
diff options
context:
space:
mode:
authorLars Ellenberg2011-01-21 17:10:37 +0100
committerPhilipp Reisner2011-03-10 11:48:06 +0100
commite636db5b956950b8b9bfbeb766a637f84bae1e3b (patch)
tree6b6b05d69c2baaf4ea4ec1dee5cd399aed85eb88 /drivers/block/drbd/drbd_req.c
parentdrbd: silence some noisy log messages during disconnect (diff)
downloadkernel-qcow2-linux-e636db5b956950b8b9bfbeb766a637f84bae1e3b.tar.gz
kernel-qcow2-linux-e636db5b956950b8b9bfbeb766a637f84bae1e3b.tar.xz
kernel-qcow2-linux-e636db5b956950b8b9bfbeb766a637f84bae1e3b.zip
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>
Diffstat (limited to 'drivers/block/drbd/drbd_req.c')
-rw-r--r--drivers/block/drbd/drbd_req.c9
1 files changed, 5 insertions, 4 deletions
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,
dev_err(DEV, "FIXME (barrier_acked but pending)\n");
list_move(&req->tl_requests, &mdev->out_of_sequence_requests);
}
- D_ASSERT(req->rq_state & RQ_NET_SENT);
- req->rq_state |= RQ_NET_DONE;
- if (mdev->net_conf->wire_protocol == DRBD_PROT_A)
- atomic_sub(req->size>>9, &mdev->ap_in_flight);
+ if ((req->rq_state & RQ_NET_MASK) != 0) {
+ req->rq_state |= RQ_NET_DONE;
+ if (mdev->net_conf->wire_protocol == DRBD_PROT_A)
+ atomic_sub(req->size>>9, &mdev->ap_in_flight);
+ }
_req_may_be_done(req, m); /* Allowed while state.susp */
break;