Commit a115413d authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Jens Axboe

drbd: fix for spin_lock_irqsave in endio callback

In commit 9b7f76dc37919ea36caa9680a3f765e5b19b25fb,
 Author: Lars Ellenberg <lars.ellenberg@linbit.com>
 Date:   Wed Aug 11 23:40:24 2010 +0200

    drbd: new configuration parameter c-min-rate

a bad chunk slipped through, which is now reverted as well,
restoring the correct irqsave for the endio callback.

This patch also add comments at both req_mod()
and in the endio callback so it should not happen again.
Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent c13f7e1a
...@@ -339,7 +339,8 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what) ...@@ -339,7 +339,8 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what)
} }
/* completion of master bio is outside of spinlock. /* completion of master bio is outside of spinlock.
* If you need it irqsave, do it your self! */ * If you need it irqsave, do it your self!
* Which means: don't use from bio endio callback. */
static inline int req_mod(struct drbd_request *req, static inline int req_mod(struct drbd_request *req,
enum drbd_req_event what) enum drbd_req_event what)
{ {
......
...@@ -193,8 +193,10 @@ void drbd_endio_sec(struct bio *bio, int error) ...@@ -193,8 +193,10 @@ void drbd_endio_sec(struct bio *bio, int error)
*/ */
void drbd_endio_pri(struct bio *bio, int error) void drbd_endio_pri(struct bio *bio, int error)
{ {
unsigned long flags;
struct drbd_request *req = bio->bi_private; struct drbd_request *req = bio->bi_private;
struct drbd_conf *mdev = req->mdev; struct drbd_conf *mdev = req->mdev;
struct bio_and_error m;
enum drbd_req_event what; enum drbd_req_event what;
int uptodate = bio_flagged(bio, BIO_UPTODATE); int uptodate = bio_flagged(bio, BIO_UPTODATE);
...@@ -220,7 +222,13 @@ void drbd_endio_pri(struct bio *bio, int error) ...@@ -220,7 +222,13 @@ void drbd_endio_pri(struct bio *bio, int error)
bio_put(req->private_bio); bio_put(req->private_bio);
req->private_bio = ERR_PTR(error); req->private_bio = ERR_PTR(error);
req_mod(req, what); /* not req_mod(), we need irqsave here! */
spin_lock_irqsave(&mdev->req_lock, flags);
__req_mod(req, what, &m);
spin_unlock_irqrestore(&mdev->req_lock, flags);
if (m.bio)
complete_master_bio(mdev, &m);
} }
int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment