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: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
parent
c13f7e1a94
commit
a115413de1
2 changed files with 11 additions and 2 deletions
|
@ -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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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)
|
||||||
|
|
Loading…
Reference in a new issue