aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKiyoshi Ueda <k-ueda@ct.jp.nec.com>2007-12-11 17:51:46 -0500
committerJens Axboe <jens.axboe@oracle.com>2008-01-28 04:37:08 -0500
commite3a04fe34a3ec81ddeddb6c73fb7299716cffbb0 (patch)
tree080d1ec1cc3d78b3aef4e95f5334f5b4c3da3498
parentaaa04c28cb9a1efd42541fdb7ab648231c2a2263 (diff)
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 <bharrosh@panasas.com> Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com> Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--block/ll_rw_blk.c40
-rw-r--r--include/linux/blkdev.h2
2 files changed, 37 insertions, 5 deletions
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)
3821 if (blk_queued_rq(rq)) 3821 if (blk_queued_rq(rq))
3822 blkdev_dequeue_request(rq); 3822 blkdev_dequeue_request(rq);
3823 3823
3824 if (blk_bidi_rq(rq) && !rq->end_io)
3825 __blk_put_request(rq->next_rq->q, rq->next_rq);
3826
3824 end_that_request_last(rq, uptodate); 3827 end_that_request_last(rq, uptodate);
3825} 3828}
3826 3829
@@ -3828,14 +3831,15 @@ static void complete_request(struct request *rq, int error)
3828 * blk_end_io - Generic end_io function to complete a request. 3831 * blk_end_io - Generic end_io function to complete a request.
3829 * @rq: the request being processed 3832 * @rq: the request being processed
3830 * @error: 0 for success, < 0 for error 3833 * @error: 0 for success, < 0 for error
3831 * @nr_bytes: number of bytes to complete 3834 * @nr_bytes: number of bytes to complete @rq
3835 * @bidi_bytes: number of bytes to complete @rq->next_rq
3832 * @drv_callback: function called between completion of bios in the request 3836 * @drv_callback: function called between completion of bios in the request
3833 * and completion of the request. 3837 * and completion of the request.
3834 * If the callback returns non 0, this helper returns without 3838 * If the callback returns non 0, this helper returns without
3835 * completion of the request. 3839 * completion of the request.
3836 * 3840 *
3837 * Description: 3841 * Description:
3838 * Ends I/O on a number of bytes attached to @rq. 3842 * Ends I/O on a number of bytes attached to @rq and @rq->next_rq.
3839 * If @rq has leftover, sets it up for the next range of segments. 3843 * If @rq has leftover, sets it up for the next range of segments.
3840 * 3844 *
3841 * Return: 3845 * Return:
@@ -3843,7 +3847,7 @@ static void complete_request(struct request *rq, int error)
3843 * 1 - this request is not freed yet, it still has pending buffers. 3847 * 1 - this request is not freed yet, it still has pending buffers.
3844 **/ 3848 **/
3845static int blk_end_io(struct request *rq, int error, int nr_bytes, 3849static int blk_end_io(struct request *rq, int error, int nr_bytes,
3846 int (drv_callback)(struct request *)) 3850 int bidi_bytes, int (drv_callback)(struct request *))
3847{ 3851{
3848 struct request_queue *q = rq->q; 3852 struct request_queue *q = rq->q;
3849 unsigned long flags = 0UL; 3853 unsigned long flags = 0UL;
@@ -3858,6 +3862,11 @@ static int blk_end_io(struct request *rq, int error, int nr_bytes,
3858 if (blk_fs_request(rq) || blk_pc_request(rq)) { 3862 if (blk_fs_request(rq) || blk_pc_request(rq)) {
3859 if (__end_that_request_first(rq, uptodate, nr_bytes)) 3863 if (__end_that_request_first(rq, uptodate, nr_bytes))
3860 return 1; 3864 return 1;
3865
3866 /* Bidi request must be completed as a whole */
3867 if (blk_bidi_rq(rq) &&
3868 __end_that_request_first(rq->next_rq, uptodate, bidi_bytes))
3869 return 1;
3861 } 3870 }
3862 3871
3863 /* Special feature for tricky drivers */ 3872 /* Special feature for tricky drivers */
@@ -3889,7 +3898,7 @@ static int blk_end_io(struct request *rq, int error, int nr_bytes,
3889 **/ 3898 **/
3890int blk_end_request(struct request *rq, int error, int nr_bytes) 3899int blk_end_request(struct request *rq, int error, int nr_bytes)
3891{ 3900{
3892 return blk_end_io(rq, error, nr_bytes, NULL); 3901 return blk_end_io(rq, error, nr_bytes, 0, NULL);
3893} 3902}
3894EXPORT_SYMBOL_GPL(blk_end_request); 3903EXPORT_SYMBOL_GPL(blk_end_request);
3895 3904
@@ -3930,6 +3939,27 @@ int __blk_end_request(struct request *rq, int error, int nr_bytes)
3930EXPORT_SYMBOL_GPL(__blk_end_request); 3939EXPORT_SYMBOL_GPL(__blk_end_request);
3931 3940
3932/** 3941/**
3942 * blk_end_bidi_request - Helper function for drivers to complete bidi request.
3943 * @rq: the bidi request being processed
3944 * @error: 0 for success, < 0 for error
3945 * @nr_bytes: number of bytes to complete @rq
3946 * @bidi_bytes: number of bytes to complete @rq->next_rq
3947 *
3948 * Description:
3949 * Ends I/O on a number of bytes attached to @rq and @rq->next_rq.
3950 *
3951 * Return:
3952 * 0 - we are done with this request
3953 * 1 - still buffers pending for this request
3954 **/
3955int blk_end_bidi_request(struct request *rq, int error, int nr_bytes,
3956 int bidi_bytes)
3957{
3958 return blk_end_io(rq, error, nr_bytes, bidi_bytes, NULL);
3959}
3960EXPORT_SYMBOL_GPL(blk_end_bidi_request);
3961
3962/**
3933 * blk_end_request_callback - Special helper function for tricky drivers 3963 * blk_end_request_callback - Special helper function for tricky drivers
3934 * @rq: the request being processed 3964 * @rq: the request being processed
3935 * @error: 0 for success, < 0 for error 3965 * @error: 0 for success, < 0 for error
@@ -3957,7 +3987,7 @@ EXPORT_SYMBOL_GPL(__blk_end_request);
3957int blk_end_request_callback(struct request *rq, int error, int nr_bytes, 3987int blk_end_request_callback(struct request *rq, int error, int nr_bytes,
3958 int (drv_callback)(struct request *)) 3988 int (drv_callback)(struct request *))
3959{ 3989{
3960 return blk_end_io(rq, error, nr_bytes, drv_callback); 3990 return blk_end_io(rq, error, nr_bytes, 0, drv_callback);
3961} 3991}
3962EXPORT_SYMBOL_GPL(blk_end_request_callback); 3992EXPORT_SYMBOL_GPL(blk_end_request_callback);
3963 3993
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)
728 */ 728 */
729extern int blk_end_request(struct request *rq, int error, int nr_bytes); 729extern int blk_end_request(struct request *rq, int error, int nr_bytes);
730extern int __blk_end_request(struct request *rq, int error, int nr_bytes); 730extern int __blk_end_request(struct request *rq, int error, int nr_bytes);
731extern int blk_end_bidi_request(struct request *rq, int error, int nr_bytes,
732 int bidi_bytes);
731extern int end_that_request_first(struct request *, int, int); 733extern int end_that_request_first(struct request *, int, int);
732extern int end_that_request_chunk(struct request *, int, int); 734extern int end_that_request_chunk(struct request *, int, int);
733extern void end_that_request_last(struct request *, int); 735extern void end_that_request_last(struct request *, int);