diff options
author | Kiyoshi Ueda <k-ueda@ct.jp.nec.com> | 2007-12-11 17:51:46 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-01-28 04:37:08 -0500 |
commit | e3a04fe34a3ec81ddeddb6c73fb7299716cffbb0 (patch) | |
tree | 080d1ec1cc3d78b3aef4e95f5334f5b4c3da3498 | |
parent | aaa04c28cb9a1efd42541fdb7ab648231c2a2263 (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.c | 40 | ||||
-rw-r--r-- | include/linux/blkdev.h | 2 |
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 | **/ |
3845 | static int blk_end_io(struct request *rq, int error, int nr_bytes, | 3849 | static 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 | **/ |
3890 | int blk_end_request(struct request *rq, int error, int nr_bytes) | 3899 | int 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 | } |
3894 | EXPORT_SYMBOL_GPL(blk_end_request); | 3903 | EXPORT_SYMBOL_GPL(blk_end_request); |
3895 | 3904 | ||
@@ -3930,6 +3939,27 @@ int __blk_end_request(struct request *rq, int error, int nr_bytes) | |||
3930 | EXPORT_SYMBOL_GPL(__blk_end_request); | 3939 | EXPORT_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 | **/ | ||
3955 | int 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 | } | ||
3960 | EXPORT_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); | |||
3957 | int blk_end_request_callback(struct request *rq, int error, int nr_bytes, | 3987 | int 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 | } |
3962 | EXPORT_SYMBOL_GPL(blk_end_request_callback); | 3992 | EXPORT_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 | */ |
729 | extern int blk_end_request(struct request *rq, int error, int nr_bytes); | 729 | extern int blk_end_request(struct request *rq, int error, int nr_bytes); |
730 | extern int __blk_end_request(struct request *rq, int error, int nr_bytes); | 730 | extern int __blk_end_request(struct request *rq, int error, int nr_bytes); |
731 | extern int blk_end_bidi_request(struct request *rq, int error, int nr_bytes, | ||
732 | int bidi_bytes); | ||
731 | extern int end_that_request_first(struct request *, int, int); | 733 | extern int end_that_request_first(struct request *, int, int); |
732 | extern int end_that_request_chunk(struct request *, int, int); | 734 | extern int end_that_request_chunk(struct request *, int, int); |
733 | extern void end_that_request_last(struct request *, int); | 735 | extern void end_that_request_last(struct request *, int); |