diff options
author | Christoph Hellwig <hch@infradead.org> | 2014-02-20 18:32:38 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-03-21 10:57:55 -0400 |
commit | 7237c740b04fd173cb24391d3e5be79ebd8d485f (patch) | |
tree | 5855d3450ef4062a05399aa991c8439712c3e703 /block | |
parent | eeabc850b79336575da7be3dbe186a2da4de8293 (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>
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-mq.c | 37 |
1 files changed, 5 insertions, 32 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 81ff7879bac8..3c2804879a90 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, blk_rq_bytes(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 | { |