From 336cdb4003200a90f4fc52a4e9ccc2baa570fffb Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Tue, 11 Dec 2007 17:40:30 -0500 Subject: blk_end_request: add new request completion interface (take 4) This patch adds 2 new interfaces for request completion: o blk_end_request() : called without queue lock o __blk_end_request() : called with queue lock held blk_end_request takes 'error' as an argument instead of 'uptodate', which current end_that_request_* take. The meanings of values are below and the value is used when bio is completed. 0 : success < 0 : error Some device drivers call some generic functions below between end_that_request_{first/chunk} and end_that_request_last(). o add_disk_randomness() o blk_queue_end_tag() o blkdev_dequeue_request() These are called in the blk_end_request interfaces as a part of generic request completion. So all device drivers become to call above functions. To decide whether to call blkdev_dequeue_request(), blk_end_request uses list_empty(&rq->queuelist) (blk_queued_rq() macro is added for it). So drivers must re-initialize it using list_init() or so before calling blk_end_request if drivers use it for its specific purpose. (Currently, there is no driver which completes request without re-initializing the queuelist after used it. So rq->queuelist can be used for the purpose above.) "Normal" drivers can be converted to use blk_end_request() in a standard way shown below. a) end_that_request_{chunk/first} spin_lock_irqsave() (add_disk_randomness(), blk_queue_end_tag(), blkdev_dequeue_request()) end_that_request_last() spin_unlock_irqrestore() => blk_end_request() b) spin_lock_irqsave() end_that_request_{chunk/first} (add_disk_randomness(), blk_queue_end_tag(), blkdev_dequeue_request()) end_that_request_last() spin_unlock_irqrestore() => spin_lock_irqsave() __blk_end_request() spin_unlock_irqsave() c) spin_lock_irqsave() (add_disk_randomness(), blk_queue_end_tag(), blkdev_dequeue_request()) end_that_request_last() spin_unlock_irqrestore() => blk_end_request() or spin_lock_irqsave() __blk_end_request() spin_unlock_irqrestore() Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 49b7a4c31a6d..3b212f02db8d 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -537,6 +537,8 @@ enum { #define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA) #define blk_bidi_rq(rq) ((rq)->next_rq != NULL) #define blk_empty_barrier(rq) (blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors) +/* rq->queuelist of dequeued request must be list_empty() */ +#define blk_queued_rq(rq) (!list_empty(&(rq)->queuelist)) #define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist) @@ -724,6 +726,8 @@ static inline void blk_run_address_space(struct address_space *mapping) * for parts of the original function. This prevents * code duplication in drivers. */ +extern int blk_end_request(struct request *rq, int error, int nr_bytes); +extern int __blk_end_request(struct request *rq, int error, int nr_bytes); 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); -- cgit v1.2.3-59-g8ed1b From 3b11313a6c2a42425bf06e92528bda6affd58dec Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Tue, 11 Dec 2007 17:41:17 -0500 Subject: blk_end_request: add/export functions to get request size (take 4) This patch adds/exports functions to get the size of request in bytes. They are useful because blk_end_request interfaces take bytes as a completed I/O size instead of sectors. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- block/ll_rw_blk.c | 25 ++++++++++++++++++++++--- include/linux/blkdev.h | 8 ++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 5c01911af47c..8b2b2509f60e 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -3723,13 +3723,32 @@ static inline void __end_request(struct request *rq, int uptodate, } } -static unsigned int rq_byte_size(struct request *rq) +/** + * blk_rq_bytes - Returns bytes left to complete in the entire request + **/ +unsigned int blk_rq_bytes(struct request *rq) { if (blk_fs_request(rq)) return rq->hard_nr_sectors << 9; return rq->data_len; } +EXPORT_SYMBOL_GPL(blk_rq_bytes); + +/** + * blk_rq_cur_bytes - Returns bytes left to complete in the current segment + **/ +unsigned int blk_rq_cur_bytes(struct request *rq) +{ + if (blk_fs_request(rq)) + return rq->current_nr_sectors << 9; + + if (rq->bio) + return rq->bio->bi_size; + + return rq->data_len; +} +EXPORT_SYMBOL_GPL(blk_rq_cur_bytes); /** * end_queued_request - end all I/O on a queued request @@ -3744,7 +3763,7 @@ static unsigned int rq_byte_size(struct request *rq) **/ void end_queued_request(struct request *rq, int uptodate) { - __end_request(rq, uptodate, rq_byte_size(rq), 1); + __end_request(rq, uptodate, blk_rq_bytes(rq), 1); } EXPORT_SYMBOL(end_queued_request); @@ -3761,7 +3780,7 @@ EXPORT_SYMBOL(end_queued_request); **/ void end_dequeued_request(struct request *rq, int uptodate) { - __end_request(rq, uptodate, rq_byte_size(rq), 0); + __end_request(rq, uptodate, blk_rq_bytes(rq), 0); } EXPORT_SYMBOL(end_dequeued_request); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 3b212f02db8d..aa2341df7932 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -736,6 +736,14 @@ extern void end_queued_request(struct request *, int); extern void end_dequeued_request(struct request *, int); extern void blk_complete_request(struct request *); +/* + * blk_end_request() takes bytes instead of sectors as a complete size. + * blk_rq_bytes() returns bytes left to complete in the entire request. + * blk_rq_cur_bytes() returns bytes left to complete in the current segment. + */ +extern unsigned int blk_rq_bytes(struct request *rq); +extern unsigned int blk_rq_cur_bytes(struct request *rq); + /* * end_that_request_first/chunk() takes an uptodate argument. we account * any value <= as an io error. 0 means -EIO for compatability reasons, -- cgit v1.2.3-59-g8ed1b From e19a3ab058fe91c8c54d43dc56dccf7eb386478e Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Tue, 11 Dec 2007 17:51:02 -0500 Subject: blk_end_request: add callback feature (take 4) This patch adds a variant of the interface, blk_end_request_callback(), which has driver callback feature. Drivers may need to do special works between end_that_request_first() and end_that_request_last(). For such drivers, blk_end_request_callback() allows it to pass a callback function which is called between end_that_request_first() and end_that_request_last(). This interface is only for fallback of other blk_end_request interfaces. Drivers should avoid their tricky behaviors and use other interfaces as much as possible. Currently, only one driver, ide-cd, needs this interface. So this interface should/will be removed, after the driver removes such tricky behaviors. o ide-cd (cdrom_newpc_intr()) In PIO mode, cdrom_newpc_intr() needs to defer end_that_request_last() until the device clears DRQ_STAT and raises an interrupt after end_that_request_first(). So end_that_request_first() and end_that_request_last() are called separately in cdrom_newpc_intr(). This means blk_end_request_callback() has to return without completing request even if no leftover in the request. To satisfy the requirement, callback function has return value so that drivers can tell blk_end_request_callback() to return without completing request. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- block/ll_rw_blk.c | 72 +++++++++++++++++++++++++++++++++++++++++++++----- include/linux/blkdev.h | 2 ++ 2 files changed, 68 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index fb951198c70e..919e4baf478b 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -3825,10 +3825,14 @@ static void complete_request(struct request *rq, int error) } /** - * blk_end_request - Helper function for drivers to complete the request. - * @rq: the request being processed - * @error: 0 for success, < 0 for error - * @nr_bytes: number of bytes to complete + * blk_end_io - Generic end_io function to complete a request. + * @rq: the request being processed + * @error: 0 for success, < 0 for error + * @nr_bytes: number of bytes to complete + * @drv_callback: function called between completion of bios in the request + * and completion of the request. + * If the callback returns non 0, this helper returns without + * completion of the request. * * Description: * Ends I/O on a number of bytes attached to @rq. @@ -3836,9 +3840,10 @@ static void complete_request(struct request *rq, int error) * * Return: * 0 - we are done with this request - * 1 - still buffers pending for this request + * 1 - this request is not freed yet, it still has pending buffers. **/ -int blk_end_request(struct request *rq, int error, int nr_bytes) +static int blk_end_io(struct request *rq, int error, int nr_bytes, + int (drv_callback)(struct request *)) { struct request_queue *q = rq->q; unsigned long flags = 0UL; @@ -3855,6 +3860,10 @@ int blk_end_request(struct request *rq, int error, int nr_bytes) return 1; } + /* Special feature for tricky drivers */ + if (drv_callback && drv_callback(rq)) + return 1; + add_disk_randomness(rq->rq_disk); spin_lock_irqsave(q->queue_lock, flags); @@ -3863,6 +3872,25 @@ int blk_end_request(struct request *rq, int error, int nr_bytes) return 0; } + +/** + * blk_end_request - Helper function for drivers to complete the request. + * @rq: the request being processed + * @error: 0 for success, < 0 for error + * @nr_bytes: number of bytes to complete + * + * 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 error, int nr_bytes) +{ + return blk_end_io(rq, error, nr_bytes, NULL); +} EXPORT_SYMBOL_GPL(blk_end_request); /** @@ -3901,6 +3929,38 @@ int __blk_end_request(struct request *rq, int error, int nr_bytes) } EXPORT_SYMBOL_GPL(__blk_end_request); +/** + * blk_end_request_callback - Special helper function for tricky drivers + * @rq: the request being processed + * @error: 0 for success, < 0 for error + * @nr_bytes: number of bytes to complete + * @drv_callback: function called between completion of bios in the request + * and completion of the request. + * If the callback returns non 0, this helper returns without + * completion of the request. + * + * 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. + * + * This special helper function is used only for existing tricky drivers. + * (e.g. cdrom_newpc_intr() of ide-cd) + * This interface will be removed when such drivers are rewritten. + * Don't use this interface in other places anymore. + * + * Return: + * 0 - we are done with this request + * 1 - this request is not freed yet. + * this request still has pending buffers or + * the driver doesn't want to finish this request yet. + **/ +int blk_end_request_callback(struct request *rq, int error, int nr_bytes, + int (drv_callback)(struct request *)) +{ + return blk_end_io(rq, error, nr_bytes, drv_callback); +} +EXPORT_SYMBOL_GPL(blk_end_request_callback); + static void blk_rq_bio_prep(struct request_queue *q, struct request *rq, struct bio *bio) { diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index aa2341df7932..63fe7542b3fa 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -734,6 +734,8 @@ extern void end_that_request_last(struct request *, int); extern void end_request(struct request *, int); extern void end_queued_request(struct request *, int); extern void end_dequeued_request(struct request *, int); +extern int blk_end_request_callback(struct request *rq, int error, int nr_bytes, + int (drv_callback)(struct request *)); extern void blk_complete_request(struct request *); /* -- cgit v1.2.3-59-g8ed1b From e3a04fe34a3ec81ddeddb6c73fb7299716cffbb0 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Tue, 11 Dec 2007 17:51:46 -0500 Subject: blk_end_request: add bidi completion interface (take 4) This patch adds a variant of the interface, blk_end_bidi_request(), which completes a bidi request. Bidi request must be completed as a whole, both rq and rq->next_rq at once. So the interface has 2 arguments for completion size. As for ->end_io, only rq->end_io is called (rq->next_rq->end_io is not called). So if special completion handling is needed, the handler must be set to rq->end_io. And the handler must take care of freeing next_rq too, since the interface doesn't care of it if rq->end_io is not NULL. Cc: Boaz Harrosh Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- block/ll_rw_blk.c | 40 +++++++++++++++++++++++++++++++++++----- include/linux/blkdev.h | 2 ++ 2 files changed, 37 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 919e4baf478b..4889f7a8c2b7 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -3821,6 +3821,9 @@ static void complete_request(struct request *rq, int error) if (blk_queued_rq(rq)) blkdev_dequeue_request(rq); + if (blk_bidi_rq(rq) && !rq->end_io) + __blk_put_request(rq->next_rq->q, rq->next_rq); + end_that_request_last(rq, uptodate); } @@ -3828,14 +3831,15 @@ static void complete_request(struct request *rq, int error) * blk_end_io - Generic end_io function to complete a request. * @rq: the request being processed * @error: 0 for success, < 0 for error - * @nr_bytes: number of bytes to complete + * @nr_bytes: number of bytes to complete @rq + * @bidi_bytes: number of bytes to complete @rq->next_rq * @drv_callback: function called between completion of bios in the request * and completion of the request. * If the callback returns non 0, this helper returns without * completion of the request. * * Description: - * Ends I/O on a number of bytes attached to @rq. + * Ends I/O on a number of bytes attached to @rq and @rq->next_rq. * If @rq has leftover, sets it up for the next range of segments. * * Return: @@ -3843,7 +3847,7 @@ static void complete_request(struct request *rq, int error) * 1 - this request is not freed yet, it still has pending buffers. **/ static int blk_end_io(struct request *rq, int error, int nr_bytes, - int (drv_callback)(struct request *)) + int bidi_bytes, int (drv_callback)(struct request *)) { struct request_queue *q = rq->q; unsigned long flags = 0UL; @@ -3858,6 +3862,11 @@ static int blk_end_io(struct request *rq, int error, int nr_bytes, if (blk_fs_request(rq) || blk_pc_request(rq)) { if (__end_that_request_first(rq, uptodate, nr_bytes)) return 1; + + /* Bidi request must be completed as a whole */ + if (blk_bidi_rq(rq) && + __end_that_request_first(rq->next_rq, uptodate, bidi_bytes)) + return 1; } /* Special feature for tricky drivers */ @@ -3889,7 +3898,7 @@ static int blk_end_io(struct request *rq, int error, int nr_bytes, **/ int blk_end_request(struct request *rq, int error, int nr_bytes) { - return blk_end_io(rq, error, nr_bytes, NULL); + return blk_end_io(rq, error, nr_bytes, 0, NULL); } EXPORT_SYMBOL_GPL(blk_end_request); @@ -3929,6 +3938,27 @@ int __blk_end_request(struct request *rq, int error, int nr_bytes) } EXPORT_SYMBOL_GPL(__blk_end_request); +/** + * blk_end_bidi_request - Helper function for drivers to complete bidi request. + * @rq: the bidi request being processed + * @error: 0 for success, < 0 for error + * @nr_bytes: number of bytes to complete @rq + * @bidi_bytes: number of bytes to complete @rq->next_rq + * + * Description: + * Ends I/O on a number of bytes attached to @rq and @rq->next_rq. + * + * Return: + * 0 - we are done with this request + * 1 - still buffers pending for this request + **/ +int blk_end_bidi_request(struct request *rq, int error, int nr_bytes, + int bidi_bytes) +{ + return blk_end_io(rq, error, nr_bytes, bidi_bytes, NULL); +} +EXPORT_SYMBOL_GPL(blk_end_bidi_request); + /** * blk_end_request_callback - Special helper function for tricky drivers * @rq: the request being processed @@ -3957,7 +3987,7 @@ EXPORT_SYMBOL_GPL(__blk_end_request); int blk_end_request_callback(struct request *rq, int error, int nr_bytes, int (drv_callback)(struct request *)) { - return blk_end_io(rq, error, nr_bytes, drv_callback); + return blk_end_io(rq, error, nr_bytes, 0, drv_callback); } EXPORT_SYMBOL_GPL(blk_end_request_callback); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 63fe7542b3fa..029b7097f9e5 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -728,6 +728,8 @@ static inline void blk_run_address_space(struct address_space *mapping) */ extern int blk_end_request(struct request *rq, int error, int nr_bytes); extern int __blk_end_request(struct request *rq, int error, int nr_bytes); +extern int blk_end_bidi_request(struct request *rq, int error, int nr_bytes, + int bidi_bytes); 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); -- cgit v1.2.3-59-g8ed1b From 3bcddeac1c4c7e6fb90531b80f236b1a05dfe514 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Tue, 11 Dec 2007 17:52:28 -0500 Subject: blk_end_request: remove/unexport end_that_request_* (take 4) This patch removes the following functions: o end_that_request_first() o end_that_request_chunk() and stops exporting the functions below: o end_that_request_last() Cc: Boaz Harrosh Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- block/ll_rw_blk.c | 61 +++++++++++++------------------------------------- include/linux/blkdev.h | 13 +++++------ 2 files changed, 20 insertions(+), 54 deletions(-) (limited to 'include') diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 4889f7a8c2b7..4bd1803919ce 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -3432,6 +3432,20 @@ static void blk_recalc_rq_sectors(struct request *rq, int nsect) } } +/** + * __end_that_request_first - end I/O on a request + * @req: the request being processed + * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error + * @nr_bytes: number of bytes to complete + * + * Description: + * Ends I/O on a number of bytes attached to @req, and sets it up + * for the next range of segments (if any) in the cluster. + * + * Return: + * 0 - we are done with this request, call end_that_request_last() + * 1 - still buffers pending for this request + **/ static int __end_that_request_first(struct request *req, int uptodate, int nr_bytes) { @@ -3548,49 +3562,6 @@ static int __end_that_request_first(struct request *req, int uptodate, return 1; } -/** - * end_that_request_first - end I/O on a request - * @req: the request being processed - * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error - * @nr_sectors: number of sectors to end I/O on - * - * Description: - * Ends I/O on a number of sectors attached to @req, and sets it up - * for the next range of segments (if any) in the cluster. - * - * Return: - * 0 - we are done with this request, call end_that_request_last() - * 1 - still buffers pending for this request - **/ -int end_that_request_first(struct request *req, int uptodate, int nr_sectors) -{ - return __end_that_request_first(req, uptodate, nr_sectors << 9); -} - -EXPORT_SYMBOL(end_that_request_first); - -/** - * end_that_request_chunk - end I/O on a request - * @req: the request being processed - * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error - * @nr_bytes: number of bytes to complete - * - * Description: - * Ends I/O on a number of bytes attached to @req, and sets it up - * for the next range of segments (if any). Like end_that_request_first(), - * but deals with bytes instead of sectors. - * - * Return: - * 0 - we are done with this request, call end_that_request_last() - * 1 - still buffers pending for this request - **/ -int end_that_request_chunk(struct request *req, int uptodate, int nr_bytes) -{ - return __end_that_request_first(req, uptodate, nr_bytes); -} - -EXPORT_SYMBOL(end_that_request_chunk); - /* * splice the completion data to a local structure and hand off to * process_completion_queue() to complete the requests @@ -3670,7 +3641,7 @@ EXPORT_SYMBOL(blk_complete_request); /* * queue lock must be held */ -void end_that_request_last(struct request *req, int uptodate) +static void end_that_request_last(struct request *req, int uptodate) { struct gendisk *disk = req->rq_disk; int error; @@ -3705,8 +3676,6 @@ void end_that_request_last(struct request *req, int uptodate) __blk_put_request(req->q, req); } -EXPORT_SYMBOL(end_that_request_last); - static inline void __end_request(struct request *rq, int uptodate, unsigned int nr_bytes) { diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 029b7097f9e5..0c39ac75bed4 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -718,21 +718,18 @@ static inline void blk_run_address_space(struct address_space *mapping) } /* - * end_request() and friends. Must be called with the request queue spinlock - * acquired. All functions called within end_request() _must_be_ atomic. + * blk_end_request() and friends. + * __blk_end_request() and end_request() must be called with + * the request queue spinlock acquired. * * 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 *rq, int error, int nr_bytes); extern int __blk_end_request(struct request *rq, int error, int nr_bytes); extern int blk_end_bidi_request(struct request *rq, int error, int nr_bytes, int bidi_bytes); -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); extern void end_request(struct request *, int); extern void end_queued_request(struct request *, int); extern void end_dequeued_request(struct request *, int); -- cgit v1.2.3-59-g8ed1b From 5450d3e1d68f10be087f0855d8bad5458b50ecbe Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Tue, 11 Dec 2007 17:53:03 -0500 Subject: blk_end_request: cleanup 'uptodate' related code (take 4) This patch converts 'uptodate' arguments of no longer exported interfaces, end_that_request_first/last, to 'error', and removes internal conversions for it in blk_end_request interfaces. Also, this patch removes no longer needed end_io_error(). Cc: Boaz Harrosh Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- block/ll_rw_blk.c | 56 ++++++++------------------------------------------ include/linux/blkdev.h | 8 -------- 2 files changed, 9 insertions(+), 55 deletions(-) (limited to 'include') diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 4bd1803919ce..f5e091bc027d 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -3435,7 +3435,7 @@ static void blk_recalc_rq_sectors(struct request *rq, int nsect) /** * __end_that_request_first - end I/O on a request * @req: the request being processed - * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error + * @error: 0 for success, < 0 for error * @nr_bytes: number of bytes to complete * * Description: @@ -3446,21 +3446,14 @@ static void blk_recalc_rq_sectors(struct request *rq, int nsect) * 0 - we are done with this request, call end_that_request_last() * 1 - still buffers pending for this request **/ -static int __end_that_request_first(struct request *req, int uptodate, +static int __end_that_request_first(struct request *req, int error, int nr_bytes) { - int total_bytes, bio_nbytes, error, next_idx = 0; + int total_bytes, bio_nbytes, next_idx = 0; struct bio *bio; blk_add_trace_rq(req->q, req, BLK_TA_COMPLETE); - /* - * extend uptodate bool to allow < 0 value to be direct io error - */ - error = 0; - if (end_io_error(uptodate)) - error = !uptodate ? -EIO : uptodate; - /* * for a REQ_BLOCK_PC request, we want to carry any eventual * sense key with us all the way through @@ -3468,7 +3461,7 @@ static int __end_that_request_first(struct request *req, int uptodate, if (!blk_pc_request(req)) req->errors = 0; - if (!uptodate) { + if (error) { if (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET)) printk("end_request: I/O error, dev %s, sector %llu\n", req->rq_disk ? req->rq_disk->disk_name : "?", @@ -3641,17 +3634,9 @@ EXPORT_SYMBOL(blk_complete_request); /* * queue lock must be held */ -static void end_that_request_last(struct request *req, int uptodate) +static void end_that_request_last(struct request *req, int error) { struct gendisk *disk = req->rq_disk; - int error; - - /* - * extend uptodate bool to allow < 0 value to be direct io error - */ - error = 0; - if (end_io_error(uptodate)) - error = !uptodate ? -EIO : uptodate; if (unlikely(laptop_mode) && blk_fs_request(req)) laptop_io_completion(); @@ -3776,14 +3761,6 @@ EXPORT_SYMBOL(end_request); static void complete_request(struct request *rq, int error) { - /* - * REMOVEME: This conversion is transitional and will be removed - * when old end_that_request_* are unexported. - */ - int uptodate = 1; - if (error) - uptodate = (error == -EIO) ? 0 : error; - if (blk_rq_tagged(rq)) blk_queue_end_tag(rq->q, rq); @@ -3793,7 +3770,7 @@ static void complete_request(struct request *rq, int error) if (blk_bidi_rq(rq) && !rq->end_io) __blk_put_request(rq->next_rq->q, rq->next_rq); - end_that_request_last(rq, uptodate); + end_that_request_last(rq, error); } /** @@ -3820,21 +3797,14 @@ static int blk_end_io(struct request *rq, int error, int nr_bytes, { struct request_queue *q = rq->q; unsigned long flags = 0UL; - /* - * REMOVEME: This conversion is transitional and will be removed - * when old end_that_request_* are unexported. - */ - int uptodate = 1; - if (error) - uptodate = (error == -EIO) ? 0 : error; if (blk_fs_request(rq) || blk_pc_request(rq)) { - if (__end_that_request_first(rq, uptodate, nr_bytes)) + if (__end_that_request_first(rq, error, nr_bytes)) return 1; /* Bidi request must be completed as a whole */ if (blk_bidi_rq(rq) && - __end_that_request_first(rq->next_rq, uptodate, bidi_bytes)) + __end_that_request_first(rq->next_rq, error, bidi_bytes)) return 1; } @@ -3886,16 +3856,8 @@ EXPORT_SYMBOL_GPL(blk_end_request); **/ int __blk_end_request(struct request *rq, int error, int nr_bytes) { - /* - * REMOVEME: This conversion is transitional and will be removed - * when old end_that_request_* are unexported. - */ - int uptodate = 1; - if (error) - uptodate = (error == -EIO) ? 0 : error; - if (blk_fs_request(rq) || blk_pc_request(rq)) { - if (__end_that_request_first(rq, uptodate, nr_bytes)) + if (__end_that_request_first(rq, error, nr_bytes)) return 1; } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 0c39ac75bed4..0ea82d222046 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -745,14 +745,6 @@ extern void blk_complete_request(struct request *); extern unsigned int blk_rq_bytes(struct request *rq); extern unsigned int blk_rq_cur_bytes(struct request *rq); -/* - * end_that_request_first/chunk() takes an uptodate argument. we account - * any value <= as an io error. 0 means -EIO for compatability reasons, - * any other < 0 value is the direct error type. An uptodate value of - * 1 indicates successful io completion - */ -#define end_io_error(uptodate) (unlikely((uptodate) <= 0)) - static inline void blkdev_dequeue_request(struct request *req) { elv_dequeue_request(req->q, req); -- cgit v1.2.3-59-g8ed1b