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>
This commit is contained in:
committed by
Jens Axboe
parent
e597cd09f7
commit
28018c242a
@@ -608,6 +608,7 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn,
|
|||||||
|
|
||||||
q->request_fn = rfn;
|
q->request_fn = rfn;
|
||||||
q->prep_rq_fn = NULL;
|
q->prep_rq_fn = NULL;
|
||||||
|
q->unprep_rq_fn = NULL;
|
||||||
q->unplug_fn = generic_unplug_device;
|
q->unplug_fn = generic_unplug_device;
|
||||||
q->queue_flags = QUEUE_FLAG_DEFAULT;
|
q->queue_flags = QUEUE_FLAG_DEFAULT;
|
||||||
q->queue_lock = lock;
|
q->queue_lock = lock;
|
||||||
@@ -2133,6 +2134,26 @@ static bool blk_update_bidi_request(struct request *rq, int error,
|
|||||||
return false;
|
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
|
* queue lock must be held
|
||||||
*/
|
*/
|
||||||
@@ -2148,6 +2169,10 @@ static void blk_finish_request(struct request *req, int error)
|
|||||||
|
|
||||||
blk_delete_timer(req);
|
blk_delete_timer(req);
|
||||||
|
|
||||||
|
if (req->cmd_flags & REQ_DONTPREP)
|
||||||
|
blk_unprep_request(req);
|
||||||
|
|
||||||
|
|
||||||
blk_account_io_done(req);
|
blk_account_io_done(req);
|
||||||
|
|
||||||
if (req->end_io)
|
if (req->end_io)
|
||||||
|
@@ -36,6 +36,23 @@ void blk_queue_prep_rq(struct request_queue *q, prep_rq_fn *pfn)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(blk_queue_prep_rq);
|
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
|
* blk_queue_merge_bvec - set a merge_bvec function for queue
|
||||||
* @q: queue
|
* @q: queue
|
||||||
|
@@ -85,7 +85,7 @@ static void scsi_unprep_request(struct request *req)
|
|||||||
{
|
{
|
||||||
struct scsi_cmnd *cmd = req->special;
|
struct scsi_cmnd *cmd = req->special;
|
||||||
|
|
||||||
req->cmd_flags &= ~REQ_DONTPREP;
|
blk_unprep_request(req);
|
||||||
req->special = NULL;
|
req->special = NULL;
|
||||||
|
|
||||||
scsi_put_command(cmd);
|
scsi_put_command(cmd);
|
||||||
|
@@ -200,6 +200,7 @@ struct request_pm_state
|
|||||||
typedef void (request_fn_proc) (struct request_queue *q);
|
typedef void (request_fn_proc) (struct request_queue *q);
|
||||||
typedef int (make_request_fn) (struct request_queue *q, struct bio *bio);
|
typedef int (make_request_fn) (struct request_queue *q, struct bio *bio);
|
||||||
typedef int (prep_rq_fn) (struct request_queue *, struct request *);
|
typedef int (prep_rq_fn) (struct request_queue *, struct request *);
|
||||||
|
typedef void (unprep_rq_fn) (struct request_queue *, struct request *);
|
||||||
typedef void (unplug_fn) (struct request_queue *);
|
typedef void (unplug_fn) (struct request_queue *);
|
||||||
|
|
||||||
struct bio_vec;
|
struct bio_vec;
|
||||||
@@ -282,6 +283,7 @@ struct request_queue
|
|||||||
request_fn_proc *request_fn;
|
request_fn_proc *request_fn;
|
||||||
make_request_fn *make_request_fn;
|
make_request_fn *make_request_fn;
|
||||||
prep_rq_fn *prep_rq_fn;
|
prep_rq_fn *prep_rq_fn;
|
||||||
|
unprep_rq_fn *unprep_rq_fn;
|
||||||
unplug_fn *unplug_fn;
|
unplug_fn *unplug_fn;
|
||||||
merge_bvec_fn *merge_bvec_fn;
|
merge_bvec_fn *merge_bvec_fn;
|
||||||
prepare_flush_fn *prepare_flush_fn;
|
prepare_flush_fn *prepare_flush_fn;
|
||||||
@@ -841,6 +843,7 @@ extern void blk_complete_request(struct request *);
|
|||||||
extern void __blk_complete_request(struct request *);
|
extern void __blk_complete_request(struct request *);
|
||||||
extern void blk_abort_request(struct request *);
|
extern void blk_abort_request(struct request *);
|
||||||
extern void blk_abort_queue(struct request_queue *);
|
extern void blk_abort_queue(struct request_queue *);
|
||||||
|
extern void blk_unprep_request(struct request *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access functions for manipulating queue properties
|
* Access functions for manipulating queue properties
|
||||||
@@ -885,6 +888,7 @@ extern int blk_queue_dma_drain(struct request_queue *q,
|
|||||||
extern void blk_queue_lld_busy(struct request_queue *q, lld_busy_fn *fn);
|
extern void blk_queue_lld_busy(struct request_queue *q, lld_busy_fn *fn);
|
||||||
extern void blk_queue_segment_boundary(struct request_queue *, unsigned long);
|
extern void blk_queue_segment_boundary(struct request_queue *, unsigned long);
|
||||||
extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn);
|
extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn);
|
||||||
|
extern void blk_queue_unprep_rq(struct request_queue *, unprep_rq_fn *ufn);
|
||||||
extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
|
extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
|
||||||
extern void blk_queue_dma_alignment(struct request_queue *, int);
|
extern void blk_queue_dma_alignment(struct request_queue *, int);
|
||||||
extern void blk_queue_update_dma_alignment(struct request_queue *, int);
|
extern void blk_queue_update_dma_alignment(struct request_queue *, int);
|
||||||
|
Reference in New Issue
Block a user