diff options
author | Kiyoshi Ueda <k-ueda@ct.jp.nec.com> | 2007-12-11 17:51:02 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-01-28 04:37:04 -0500 |
commit | e19a3ab058fe91c8c54d43dc56dccf7eb386478e (patch) | |
tree | f62d5af2338484e8a3eec1dc453dec4f949024a7 | |
parent | 5e36bb6ee8d5ff6c6114b60d2aaa1c70d4275f4e (diff) |
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 <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 | 72 | ||||
-rw-r--r-- | include/linux/blkdev.h | 2 |
2 files changed, 68 insertions, 6 deletions
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) | |||
3825 | } | 3825 | } |
3826 | 3826 | ||
3827 | /** | 3827 | /** |
3828 | * blk_end_request - Helper function for drivers to complete the request. | 3828 | * blk_end_io - Generic end_io function to complete a request. |
3829 | * @rq: the request being processed | 3829 | * @rq: the request being processed |
3830 | * @error: 0 for success, < 0 for error | 3830 | * @error: 0 for success, < 0 for error |
3831 | * @nr_bytes: number of bytes to complete | 3831 | * @nr_bytes: number of bytes to complete |
3832 | * @drv_callback: function called between completion of bios in the request | ||
3833 | * and completion of the request. | ||
3834 | * If the callback returns non 0, this helper returns without | ||
3835 | * completion of the request. | ||
3832 | * | 3836 | * |
3833 | * Description: | 3837 | * Description: |
3834 | * Ends I/O on a number of bytes attached to @rq. | 3838 | * Ends I/O on a number of bytes attached to @rq. |
@@ -3836,9 +3840,10 @@ static void complete_request(struct request *rq, int error) | |||
3836 | * | 3840 | * |
3837 | * Return: | 3841 | * Return: |
3838 | * 0 - we are done with this request | 3842 | * 0 - we are done with this request |
3839 | * 1 - still buffers pending for this request | 3843 | * 1 - this request is not freed yet, it still has pending buffers. |
3840 | **/ | 3844 | **/ |
3841 | int blk_end_request(struct request *rq, int error, int nr_bytes) | 3845 | static int blk_end_io(struct request *rq, int error, int nr_bytes, |
3846 | int (drv_callback)(struct request *)) | ||
3842 | { | 3847 | { |
3843 | struct request_queue *q = rq->q; | 3848 | struct request_queue *q = rq->q; |
3844 | unsigned long flags = 0UL; | 3849 | unsigned long flags = 0UL; |
@@ -3855,6 +3860,10 @@ int blk_end_request(struct request *rq, int error, int nr_bytes) | |||
3855 | return 1; | 3860 | return 1; |
3856 | } | 3861 | } |
3857 | 3862 | ||
3863 | /* Special feature for tricky drivers */ | ||
3864 | if (drv_callback && drv_callback(rq)) | ||
3865 | return 1; | ||
3866 | |||
3858 | add_disk_randomness(rq->rq_disk); | 3867 | add_disk_randomness(rq->rq_disk); |
3859 | 3868 | ||
3860 | spin_lock_irqsave(q->queue_lock, flags); | 3869 | spin_lock_irqsave(q->queue_lock, flags); |
@@ -3863,6 +3872,25 @@ int blk_end_request(struct request *rq, int error, int nr_bytes) | |||
3863 | 3872 | ||
3864 | return 0; | 3873 | return 0; |
3865 | } | 3874 | } |
3875 | |||
3876 | /** | ||
3877 | * blk_end_request - Helper function for drivers to complete the request. | ||
3878 | * @rq: the request being processed | ||
3879 | * @error: 0 for success, < 0 for error | ||
3880 | * @nr_bytes: number of bytes to complete | ||
3881 | * | ||
3882 | * Description: | ||
3883 | * Ends I/O on a number of bytes attached to @rq. | ||
3884 | * If @rq has leftover, sets it up for the next range of segments. | ||
3885 | * | ||
3886 | * Return: | ||
3887 | * 0 - we are done with this request | ||
3888 | * 1 - still buffers pending for this request | ||
3889 | **/ | ||
3890 | int blk_end_request(struct request *rq, int error, int nr_bytes) | ||
3891 | { | ||
3892 | return blk_end_io(rq, error, nr_bytes, NULL); | ||
3893 | } | ||
3866 | EXPORT_SYMBOL_GPL(blk_end_request); | 3894 | EXPORT_SYMBOL_GPL(blk_end_request); |
3867 | 3895 | ||
3868 | /** | 3896 | /** |
@@ -3901,6 +3929,38 @@ int __blk_end_request(struct request *rq, int error, int nr_bytes) | |||
3901 | } | 3929 | } |
3902 | EXPORT_SYMBOL_GPL(__blk_end_request); | 3930 | EXPORT_SYMBOL_GPL(__blk_end_request); |
3903 | 3931 | ||
3932 | /** | ||
3933 | * blk_end_request_callback - Special helper function for tricky drivers | ||
3934 | * @rq: the request being processed | ||
3935 | * @error: 0 for success, < 0 for error | ||
3936 | * @nr_bytes: number of bytes to complete | ||
3937 | * @drv_callback: function called between completion of bios in the request | ||
3938 | * and completion of the request. | ||
3939 | * If the callback returns non 0, this helper returns without | ||
3940 | * completion of the request. | ||
3941 | * | ||
3942 | * Description: | ||
3943 | * Ends I/O on a number of bytes attached to @rq. | ||
3944 | * If @rq has leftover, sets it up for the next range of segments. | ||
3945 | * | ||
3946 | * This special helper function is used only for existing tricky drivers. | ||
3947 | * (e.g. cdrom_newpc_intr() of ide-cd) | ||
3948 | * This interface will be removed when such drivers are rewritten. | ||
3949 | * Don't use this interface in other places anymore. | ||
3950 | * | ||
3951 | * Return: | ||
3952 | * 0 - we are done with this request | ||
3953 | * 1 - this request is not freed yet. | ||
3954 | * this request still has pending buffers or | ||
3955 | * the driver doesn't want to finish this request yet. | ||
3956 | **/ | ||
3957 | int blk_end_request_callback(struct request *rq, int error, int nr_bytes, | ||
3958 | int (drv_callback)(struct request *)) | ||
3959 | { | ||
3960 | return blk_end_io(rq, error, nr_bytes, drv_callback); | ||
3961 | } | ||
3962 | EXPORT_SYMBOL_GPL(blk_end_request_callback); | ||
3963 | |||
3904 | static void blk_rq_bio_prep(struct request_queue *q, struct request *rq, | 3964 | static void blk_rq_bio_prep(struct request_queue *q, struct request *rq, |
3905 | struct bio *bio) | 3965 | struct bio *bio) |
3906 | { | 3966 | { |
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); | |||
734 | extern void end_request(struct request *, int); | 734 | extern void end_request(struct request *, int); |
735 | extern void end_queued_request(struct request *, int); | 735 | extern void end_queued_request(struct request *, int); |
736 | extern void end_dequeued_request(struct request *, int); | 736 | extern void end_dequeued_request(struct request *, int); |
737 | extern int blk_end_request_callback(struct request *rq, int error, int nr_bytes, | ||
738 | int (drv_callback)(struct request *)); | ||
737 | extern void blk_complete_request(struct request *); | 739 | extern void blk_complete_request(struct request *); |
738 | 740 | ||
739 | /* | 741 | /* |