summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_req.c
diff options
context:
space:
mode:
authorPhilipp Reisner2012-08-28 14:39:44 +0200
committerPhilipp Reisner2012-11-09 14:08:24 +0100
commitd76440181d0e05826f228189b74b4dbf64b68981 (patch)
tree1cd13320a3174aea469984a3a584d4df025a77ec /drivers/block/drbd/drbd_req.c
parentdrbd: Imporve the error reporting of failed conn state changes (diff)
downloadkernel-qcow2-linux-d76440181d0e05826f228189b74b4dbf64b68981.tar.gz
kernel-qcow2-linux-d76440181d0e05826f228189b74b4dbf64b68981.tar.xz
kernel-qcow2-linux-d76440181d0e05826f228189b74b4dbf64b68981.zip
drbd: Fix postponed requests
* Postponed requests should not set or clear out-of-sync marks * When a request gets postponed we need to drop its reference mdev->local_cnt (put_ldev()). 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.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 5ddb01edd933..57cbef2ecee1 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -123,11 +123,13 @@ void drbd_req_destroy(struct kref *kref)
* (local only or remote failed).
* Other places where we set out-of-sync:
* READ with local io-error */
- if (!(s & RQ_NET_OK) || !(s & RQ_LOCAL_OK))
- drbd_set_out_of_sync(mdev, req->i.sector, req->i.size);
+ if (!(s & RQ_POSTPONED)) {
+ if (!(s & RQ_NET_OK) || !(s & RQ_LOCAL_OK))
+ drbd_set_out_of_sync(mdev, req->i.sector, req->i.size);
- if ((s & RQ_NET_OK) && (s & RQ_LOCAL_OK) && (s & RQ_NET_SIS))
- drbd_set_in_sync(mdev, req->i.sector, req->i.size);
+ if ((s & RQ_NET_OK) && (s & RQ_LOCAL_OK) && (s & RQ_NET_SIS))
+ drbd_set_in_sync(mdev, req->i.sector, req->i.size);
+ }
/* one might be tempted to move the drbd_al_complete_io
* to the local io completion callback drbd_request_endio.
@@ -1046,6 +1048,7 @@ void __drbd_make_request(struct drbd_conf *mdev, struct bio *bio, unsigned long
if (req->private_bio) {
bio_put(req->private_bio);
req->private_bio = NULL;
+ put_ldev(mdev);
}
goto out;
}