diff options
author | Kiyoshi Ueda <k-ueda@ct.jp.nec.com> | 2007-12-11 17:40:30 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-01-28 04:35:53 -0500 |
commit | 336cdb4003200a90f4fc52a4e9ccc2baa570fffb (patch) | |
tree | dcb7f736738232c0e853a1ba796ca35d5b18c503 /include/linux | |
parent | 91525300baf162e83e923b09ca286f9205e21522 (diff) |
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 <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>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/blkdev.h | 4 |
1 files changed, 4 insertions, 0 deletions
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 { | |||
537 | #define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA) | 537 | #define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA) |
538 | #define blk_bidi_rq(rq) ((rq)->next_rq != NULL) | 538 | #define blk_bidi_rq(rq) ((rq)->next_rq != NULL) |
539 | #define blk_empty_barrier(rq) (blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors) | 539 | #define blk_empty_barrier(rq) (blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors) |
540 | /* rq->queuelist of dequeued request must be list_empty() */ | ||
541 | #define blk_queued_rq(rq) (!list_empty(&(rq)->queuelist)) | ||
540 | 542 | ||
541 | #define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist) | 543 | #define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist) |
542 | 544 | ||
@@ -724,6 +726,8 @@ static inline void blk_run_address_space(struct address_space *mapping) | |||
724 | * for parts of the original function. This prevents | 726 | * for parts of the original function. This prevents |
725 | * code duplication in drivers. | 727 | * code duplication in drivers. |
726 | */ | 728 | */ |
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); | ||
727 | extern int end_that_request_first(struct request *, int, int); | 731 | extern int end_that_request_first(struct request *, int, int); |
728 | extern int end_that_request_chunk(struct request *, int, int); | 732 | extern int end_that_request_chunk(struct request *, int, int); |
729 | extern void end_that_request_last(struct request *, int); | 733 | extern void end_that_request_last(struct request *, int); |