Changing the role of ->end_io() of struct request to a full I/O completion handler. blk_end_request() is added as a helper function to call the full completion handler from drivers and others. Signed-off-by: Kiyoshi Ueda <k-ueda@xxxxxxxxxxxxx> Signed-off-by: Jun'ichi Nomura <j-nomura@xxxxxxxxxxxxx> --- block/ll_rw_blk.c | 30 ++++++++++++++++++++++++++++++ include/linux/blkdev.h | 10 ++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff -rupN 2.6.19.1/block/ll_rw_blk.c 1-blk-end-request-helper/block/ll_rw_blk.c --- 2.6.19.1/block/ll_rw_blk.c 2006-12-11 14:32:53.000000000 -0500 +++ 1-blk-end-request-helper/block/ll_rw_blk.c 2007-01-10 11:02:46.000000000 -0500 @@ -3484,6 +3484,36 @@ void end_request(struct request *req, in EXPORT_SYMBOL(end_request); +/* + * blk_end_request - Helper function for drivers to complete the request + * @rq: the request being processed + * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error + * @nr_bytes: number of bytes to complete + * @locked: 0 for taking queue lock when end_that_request_last() is called, + * 1 for not taking the lock + * @callback: function called between end_that_request_chunk() and + * end_that_request_last(). + * If @callback returns non 0, this helper returns without + * completion of @rq. + * @arg: argument for @callback + * + * Description: + * Ends I/O on a number of bytes attached to @rq. + * If @rq has leftover, sets it up for the next range of segments. + * + * Return: + * 0 - we are done with this request + * 1 - still buffers pending for this request + */ +int blk_end_request(struct request *rq, int uptodate, int nr_bytes, + int locked, int (callback)(void *), void *arg) +{ + BUG_ON(!rq->end_io); + + return rq->end_io(rq, uptodate, nr_bytes, locked, callback, arg); +} +EXPORT_SYMBOL_GPL(blk_end_request); + void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio) { /* first two bits are identical in rq->cmd_flags and bio->bi_rw */ diff -rupN 2.6.19.1/include/linux/blkdev.h 1-blk-end-request-helper/include/linux/blkdev.h --- 2.6.19.1/include/linux/blkdev.h 2006-12-11 14:32:53.000000000 -0500 +++ 1-blk-end-request-helper/include/linux/blkdev.h 2007-01-10 11:05:51.000000000 -0500 @@ -126,7 +126,8 @@ void copy_io_context(struct io_context * void swap_io_context(struct io_context **ioc1, struct io_context **ioc2); struct request; -typedef void (rq_end_io_fn)(struct request *, int); +typedef int (rq_end_io_fn)(struct request *, int, int, int, int (void *), + void *); struct request_list { int count[2]; @@ -710,10 +711,11 @@ static inline void blk_run_address_space * acquired. All functions called within end_request() _must_be_ atomic. * * Several drivers define their own end_request and call - * end_that_request_first() and end_that_request_last() - * for parts of the original function. This prevents - * code duplication in drivers. + * blk_end_request() for parts of the original function. + * This prevents code duplication in drivers. */ +extern int blk_end_request(struct request *, int, int, int, int (void *), + void *); extern int end_that_request_first(struct request *, int, int); extern int end_that_request_chunk(struct request *, int, int); extern void end_that_request_last(struct request *, int); - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html