From d9ab34777f5a5ee74135c0197f3f6def1c295212 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 31 Mar 2009 20:05:29 +0300 Subject: [PATCH] --- yaml --- r: 142091 b: refs/heads/master c: 8c0baccadc86d9f07e663dd255751dd70e461ba3 h: refs/heads/master i: 142089: 18874ccccdac7863ce7f6b24aaee14b4d90786ab 142087: de1064c13953252590969bb13274ad2980369f24 v: v3 --- [refs] | 2 +- trunk/drivers/scsi/osd/osd_initiator.c | 42 +++++++++++++++----------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/[refs] b/[refs] index b4489d334c60..7e1d98e26efd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a9bddd74630b2a1f2dedc537417c372b2d9edc76 +refs/heads/master: 8c0baccadc86d9f07e663dd255751dd70e461ba3 diff --git a/trunk/drivers/scsi/osd/osd_initiator.c b/trunk/drivers/scsi/osd/osd_initiator.c index 552f58b655d1..2a5f0777148d 100644 --- a/trunk/drivers/scsi/osd/osd_initiator.c +++ b/trunk/drivers/scsi/osd/osd_initiator.c @@ -338,20 +338,6 @@ struct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp) } EXPORT_SYMBOL(osd_start_request); -/* - * If osd_finalize_request() was called but the request was not executed through - * the block layer, then we must release BIOs. - */ -static void _abort_unexecuted_bios(struct request *rq) -{ - struct bio *bio; - - while ((bio = rq->bio) != NULL) { - rq->bio = bio->bi_next; - bio_endio(bio, 0); - } -} - static void _osd_free_seg(struct osd_request *or __unused, struct _osd_req_data_segment *seg) { @@ -363,9 +349,30 @@ static void _osd_free_seg(struct osd_request *or __unused, seg->alloc_size = 0; } +static void _put_request(struct request *rq , bool is_async) +{ + if (is_async) { + WARN_ON(rq->bio); + __blk_put_request(rq->q, rq); + } else { + /* + * If osd_finalize_request() was called but the request was not + * executed through the block layer, then we must release BIOs. + * TODO: Keep error code in or->async_error. Need to audit all + * code paths. + */ + if (unlikely(rq->bio)) + blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq)); + else + blk_put_request(rq); + } +} + void osd_end_request(struct osd_request *or) { struct request *rq = or->request; + /* IMPORTANT: make sure this agrees with osd_execute_request_async */ + bool is_async = (or->request->end_io_data == or); _osd_free_seg(or, &or->set_attr); _osd_free_seg(or, &or->enc_get_attr); @@ -373,12 +380,11 @@ void osd_end_request(struct osd_request *or) if (rq) { if (rq->next_rq) { - _abort_unexecuted_bios(rq->next_rq); - blk_put_request(rq->next_rq); + _put_request(rq->next_rq, is_async); + rq->next_rq = NULL; } - _abort_unexecuted_bios(rq); - blk_put_request(rq); + _put_request(rq, is_async); } _osd_request_free(or); }