diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2012-08-28 14:39:44 +0200 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-09 14:08:24 +0100 |
commit | d76440181d0e05826f228189b74b4dbf64b68981 (patch) | |
tree | 1cd13320a3174aea469984a3a584d4df025a77ec | |
parent | 4ae98b4db3d0e9336d0b771636b7d053a1460805 (diff) | |
download | linux-d76440181d0e05826f228189b74b4dbf64b68981.tar.bz2 |
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>
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 11 |
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; } |