diff options
author | Kiyoshi Ueda <k-ueda@ct.jp.nec.com> | 2008-09-18 10:45:09 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-10-09 02:56:18 -0400 |
commit | 32fab448e5e86694beade415e750363538ea5f49 (patch) | |
tree | 6eab6189afba893c302fa6acca1a89406fd620c6 /include | |
parent | e3335de94067dbebe22e3962632ead34e832cb60 (diff) |
block: add request update interface
This patch adds blk_update_request(), which updates struct request
with completing its data part, but doesn't complete the struct
request itself.
Though it looks like end_that_request_first() of older kernels,
blk_update_request() should be used only by request stacking drivers.
Request-based dm will use it in bio->bi_end_io callback to update
the original request when a data part of a cloned request completes.
Followings are additional background information of why request-based
dm needs this interface.
- Request stacking drivers can't use blk_end_request() directly from
the lower driver's completion context (bio->bi_end_io or rq->end_io),
because some device drivers (e.g. ide) may try to complete
their request with queue lock held, and it may cause deadlock.
See below for detailed description of possible deadlock:
<http://marc.info/?l=linux-kernel&m=120311479108569&w=2>
- To solve that, request-based dm offloads the completion of
cloned struct request to softirq context (i.e. using
blk_complete_request() from rq->end_io).
- Though it is possible to use the same solution from bio->bi_end_io,
it will delay the notification of bio completion to the original
submitter. Also, it will cause inefficient partial completion,
because the lower driver can't perform the cloned request anymore
and request-based dm needs to requeue and redispatch it to
the lower driver again later. That's not good.
- So request-based dm needs blk_update_request() to perform the bio
completion in the lower driver's completion context, which is more
efficient.
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')
-rw-r--r-- | include/linux/blkdev.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e23b838825b..e82a84c9f37 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -791,6 +791,8 @@ extern void blk_complete_request(struct request *); | |||
791 | extern void __blk_complete_request(struct request *); | 791 | extern void __blk_complete_request(struct request *); |
792 | extern void blk_abort_request(struct request *); | 792 | extern void blk_abort_request(struct request *); |
793 | extern void blk_abort_queue(struct request_queue *); | 793 | extern void blk_abort_queue(struct request_queue *); |
794 | extern void blk_update_request(struct request *rq, int error, | ||
795 | unsigned int nr_bytes); | ||
794 | 796 | ||
795 | /* | 797 | /* |
796 | * blk_end_request() takes bytes instead of sectors as a complete size. | 798 | * blk_end_request() takes bytes instead of sectors as a complete size. |