diff options
author | Christoph Hellwig <hch@infradead.org> | 2014-02-20 18:32:38 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-02-21 11:58:49 -0500 |
commit | d6a25b31315327eef7785b895c354cc45c3f3742 (patch) | |
tree | f32ed70506c097efa67526ed4a1eb63482056046 | |
parent | feb71dae1f9e0aeb056f7f639a21e620d327fc66 (diff) |
blk-mq: support partial I/O completions
Add a new blk_mq_end_io_partial function to partially complete requests
as needed by the SCSI layer. We do this by reusing blk_update_request
to advance the bio instead of having a simplified version of it in
the blk-mq code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-mq.c | 37 | ||||
-rw-r--r-- | include/linux/blk-mq.h | 8 |
2 files changed, 12 insertions, 33 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 2af840594dc1..1b8b50df3655 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -283,38 +283,10 @@ void blk_mq_free_request(struct request *rq) | |||
283 | __blk_mq_free_request(hctx, ctx, rq); | 283 | __blk_mq_free_request(hctx, ctx, rq); |
284 | } | 284 | } |
285 | 285 | ||
286 | static void blk_mq_bio_endio(struct request *rq, struct bio *bio, int error) | 286 | bool blk_mq_end_io_partial(struct request *rq, int error, unsigned int nr_bytes) |
287 | { | 287 | { |
288 | if (error) | 288 | if (blk_update_request(rq, error, blk_rq_bytes(rq))) |
289 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | 289 | return true; |
290 | else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) | ||
291 | error = -EIO; | ||
292 | |||
293 | if (unlikely(rq->cmd_flags & REQ_QUIET)) | ||
294 | set_bit(BIO_QUIET, &bio->bi_flags); | ||
295 | |||
296 | /* don't actually finish bio if it's part of flush sequence */ | ||
297 | if (!(rq->cmd_flags & REQ_FLUSH_SEQ)) | ||
298 | bio_endio(bio, error); | ||
299 | } | ||
300 | |||
301 | void blk_mq_end_io(struct request *rq, int error) | ||
302 | { | ||
303 | struct bio *bio = rq->bio; | ||
304 | unsigned int bytes = 0; | ||
305 | |||
306 | trace_block_rq_complete(rq->q, rq); | ||
307 | |||
308 | while (bio) { | ||
309 | struct bio *next = bio->bi_next; | ||
310 | |||
311 | bio->bi_next = NULL; | ||
312 | bytes += bio->bi_iter.bi_size; | ||
313 | blk_mq_bio_endio(rq, bio, error); | ||
314 | bio = next; | ||
315 | } | ||
316 | |||
317 | blk_account_io_completion(rq, bytes); | ||
318 | 290 | ||
319 | blk_account_io_done(rq); | 291 | blk_account_io_done(rq); |
320 | 292 | ||
@@ -322,8 +294,9 @@ void blk_mq_end_io(struct request *rq, int error) | |||
322 | rq->end_io(rq, error); | 294 | rq->end_io(rq, error); |
323 | else | 295 | else |
324 | blk_mq_free_request(rq); | 296 | blk_mq_free_request(rq); |
297 | return false; | ||
325 | } | 298 | } |
326 | EXPORT_SYMBOL(blk_mq_end_io); | 299 | EXPORT_SYMBOL(blk_mq_end_io_partial); |
327 | 300 | ||
328 | static void __blk_mq_complete_request_remote(void *data) | 301 | static void __blk_mq_complete_request_remote(void *data) |
329 | { | 302 | { |
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index ff28fe37ddda..2ff2e8d982be 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
@@ -133,7 +133,13 @@ struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_ind | |||
133 | struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_reg *, unsigned int); | 133 | struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_reg *, unsigned int); |
134 | void blk_mq_free_single_hw_queue(struct blk_mq_hw_ctx *, unsigned int); | 134 | void blk_mq_free_single_hw_queue(struct blk_mq_hw_ctx *, unsigned int); |
135 | 135 | ||
136 | void blk_mq_end_io(struct request *rq, int error); | 136 | bool blk_mq_end_io_partial(struct request *rq, int error, |
137 | unsigned int nr_bytes); | ||
138 | static inline void blk_mq_end_io(struct request *rq, int error) | ||
139 | { | ||
140 | bool done = !blk_mq_end_io_partial(rq, error, blk_rq_bytes(rq)); | ||
141 | BUG_ON(!done); | ||
142 | } | ||
137 | 143 | ||
138 | void blk_mq_complete_request(struct request *rq); | 144 | void blk_mq_complete_request(struct request *rq); |
139 | 145 | ||