Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 346215
b: refs/heads/master
c: 9a278a7
h: refs/heads/master
i:
  346213: 96e1dc8
  346211: eb38982
  346207: 572805e
v: v3
  • Loading branch information
Lars Ellenberg authored and Philipp Reisner committed Nov 8, 2012
1 parent 5fd691f commit 6744406
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 934722a2dbf87b43d39c787441e511157d5add94
refs/heads/master: 9a278a7906066a1b4f37fff9b5e27a92af0ca3ce
23 changes: 18 additions & 5 deletions trunk/drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2216,12 +2216,25 @@ static void do_retry(struct work_struct *ws)
struct drbd_conf *mdev = req->w.mdev;
struct bio *bio = req->master_bio;
unsigned long start_time = req->start_time;

/* We have exclusive access to this request object.
* If it had not been RQ_POSTPONED, the code path which queued
* it here would have completed and freed it already.
bool expected;

expected =
expect(atomic_read(&req->completion_ref) == 0) &&
expect(req->rq_state & RQ_POSTPONED) &&
expect((req->rq_state & RQ_LOCAL_PENDING) == 0 ||
(req->rq_state & RQ_LOCAL_ABORTED) != 0);

if (!expected)
dev_err(DEV, "req=%p completion_ref=%d rq_state=%x\n",
req, atomic_read(&req->completion_ref),
req->rq_state);

/* We still need to put one kref associated with the
* "completion_ref" going zero in the code path that queued it
* here. The request object may still be referenced by a
* frozen local req->private_bio, in case we force-detached.
*/
mempool_free(req, drbd_request_mempool);
kref_put(&req->kref, drbd_req_destroy);

/* A single suspended or otherwise blocking device may stall
* all others as well. Fortunately, this code path is to
Expand Down
19 changes: 10 additions & 9 deletions trunk/drivers/block/drbd/drbd_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ static struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
return req;
}

static void drbd_req_destroy(struct kref *kref)
void drbd_req_destroy(struct kref *kref)
{
struct drbd_request *req = container_of(kref, struct drbd_request, kref);
struct drbd_conf *mdev = req->w.mdev;
Expand Down Expand Up @@ -152,10 +152,7 @@ static void drbd_req_destroy(struct kref *kref)
}
}

if (s & RQ_POSTPONED)
drbd_restart_request(req);
else
mempool_free(req, drbd_request_mempool);
mempool_free(req, drbd_request_mempool);
}

static void wake_all_senders(struct drbd_tconn *tconn) {
Expand Down Expand Up @@ -292,10 +289,6 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
m->error = ok ? 0 : (error ?: -EIO);
m->bio = req->master_bio;
req->master_bio = NULL;
} else {
/* Assert that this will be drbd_req_destroy()ed
* with this very invokation. */
D_ASSERT(atomic_read(&req->kref.refcount) == 1);
}
}

Expand All @@ -320,6 +313,14 @@ static int drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_

/* else */
drbd_req_complete(req, m);

if (req->rq_state & RQ_POSTPONED) {
/* don't destroy the req object just yet,
* but queue it for retry */
drbd_restart_request(req);
return 0;
}

return 1;
}

Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/block/drbd/drbd_req.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ struct bio_and_error {
int error;
};

extern void drbd_req_destroy(struct kref *kref);
extern void _req_may_be_done(struct drbd_request *req,
struct bio_and_error *m);
extern int __req_mod(struct drbd_request *req, enum drbd_req_event what,
Expand Down

0 comments on commit 6744406

Please sign in to comment.