diff options
author | James Bottomley <James.Bottomley@suse.de> | 2010-07-01 19:49:17 +0900 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-08-07 18:23:47 +0200 |
commit | 28018c242a4ec7017bbbf81d2d3952f820a27118 (patch) | |
tree | 03732bef20d0e4dad30d81d9b9ad9ffcf5a2e41c /block | |
parent | e597cd09f711b28b8466ebdc2f12e55b44fa81e4 (diff) | |
download | linux-28018c242a4ec7017bbbf81d2d3952f820a27118.tar.gz linux-28018c242a4ec7017bbbf81d2d3952f820a27118.tar.bz2 linux-28018c242a4ec7017bbbf81d2d3952f820a27118.zip |
block: implement an unprep function corresponding directly to prep
Reviewed-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-core.c | 25 | ||||
-rw-r--r-- | block/blk-settings.c | 17 |
2 files changed, 42 insertions, 0 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 3c3789492c10..5ab3ac22930c 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -608,6 +608,7 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn, q->request_fn = rfn; q->prep_rq_fn = NULL; + q->unprep_rq_fn = NULL; q->unplug_fn = generic_unplug_device; q->queue_flags = QUEUE_FLAG_DEFAULT; q->queue_lock = lock; @@ -2133,6 +2134,26 @@ static bool blk_update_bidi_request(struct request *rq, int error, return false; } +/** + * blk_unprep_request - unprepare a request + * @req: the request + * + * This function makes a request ready for complete resubmission (or + * completion). It happens only after all error handling is complete, + * so represents the appropriate moment to deallocate any resources + * that were allocated to the request in the prep_rq_fn. The queue + * lock is held when calling this. + */ +void blk_unprep_request(struct request *req) +{ + struct request_queue *q = req->q; + + req->cmd_flags &= ~REQ_DONTPREP; + if (q->unprep_rq_fn) + q->unprep_rq_fn(q, req); +} +EXPORT_SYMBOL_GPL(blk_unprep_request); + /* * queue lock must be held */ @@ -2148,6 +2169,10 @@ static void blk_finish_request(struct request *req, int error) blk_delete_timer(req); + if (req->cmd_flags & REQ_DONTPREP) + blk_unprep_request(req); + + blk_account_io_done(req); if (req->end_io) diff --git a/block/blk-settings.c b/block/blk-settings.c index f5ed5a1187ba..a234f4bf1d6f 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -37,6 +37,23 @@ void blk_queue_prep_rq(struct request_queue *q, prep_rq_fn *pfn) EXPORT_SYMBOL(blk_queue_prep_rq); /** + * blk_queue_unprep_rq - set an unprepare_request function for queue + * @q: queue + * @ufn: unprepare_request function + * + * It's possible for a queue to register an unprepare_request callback + * which is invoked before the request is finally completed. The goal + * of the function is to deallocate any data that was allocated in the + * prepare_request callback. + * + */ +void blk_queue_unprep_rq(struct request_queue *q, unprep_rq_fn *ufn) +{ + q->unprep_rq_fn = ufn; +} +EXPORT_SYMBOL(blk_queue_unprep_rq); + +/** * blk_queue_merge_bvec - set a merge_bvec function for queue * @q: queue * @mbfn: merge_bvec_fn |