2007-01-10 22:50:14

by Kiyoshi Ueda

[permalink] [raw]
Subject: [RFC PATCH 1/3] blk_end_request: helper interface for end_that_request_* callers

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 <[email protected]>
Signed-off-by: Jun'ichi Nomura <[email protected]>
---
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);