diff options
Diffstat (limited to 'block/blk-merge.c')
-rw-r--r-- | block/blk-merge.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c index e1999679a4d5..7c9ca01baa45 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -311,6 +311,36 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, | |||
311 | return 1; | 311 | return 1; |
312 | } | 312 | } |
313 | 313 | ||
314 | /** | ||
315 | * blk_rq_set_mixed_merge - mark a request as mixed merge | ||
316 | * @rq: request to mark as mixed merge | ||
317 | * | ||
318 | * Description: | ||
319 | * @rq is about to be mixed merged. Make sure the attributes | ||
320 | * which can be mixed are set in each bio and mark @rq as mixed | ||
321 | * merged. | ||
322 | */ | ||
323 | void blk_rq_set_mixed_merge(struct request *rq) | ||
324 | { | ||
325 | unsigned int ff = rq->cmd_flags & REQ_FAILFAST_MASK; | ||
326 | struct bio *bio; | ||
327 | |||
328 | if (rq->cmd_flags & REQ_MIXED_MERGE) | ||
329 | return; | ||
330 | |||
331 | /* | ||
332 | * @rq will no longer represent mixable attributes for all the | ||
333 | * contained bios. It will just track those of the first one. | ||
334 | * Distributes the attributs to each bio. | ||
335 | */ | ||
336 | for (bio = rq->bio; bio; bio = bio->bi_next) { | ||
337 | WARN_ON_ONCE((bio->bi_rw & REQ_FAILFAST_MASK) && | ||
338 | (bio->bi_rw & REQ_FAILFAST_MASK) != ff); | ||
339 | bio->bi_rw |= ff; | ||
340 | } | ||
341 | rq->cmd_flags |= REQ_MIXED_MERGE; | ||
342 | } | ||
343 | |||
314 | static void blk_account_io_merge(struct request *req) | 344 | static void blk_account_io_merge(struct request *req) |
315 | { | 345 | { |
316 | if (blk_do_io_stat(req)) { | 346 | if (blk_do_io_stat(req)) { |
@@ -366,6 +396,19 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
366 | return 0; | 396 | return 0; |
367 | 397 | ||
368 | /* | 398 | /* |
399 | * If failfast settings disagree or any of the two is already | ||
400 | * a mixed merge, mark both as mixed before proceeding. This | ||
401 | * makes sure that all involved bios have mixable attributes | ||
402 | * set properly. | ||
403 | */ | ||
404 | if ((req->cmd_flags | next->cmd_flags) & REQ_MIXED_MERGE || | ||
405 | (req->cmd_flags & REQ_FAILFAST_MASK) != | ||
406 | (next->cmd_flags & REQ_FAILFAST_MASK)) { | ||
407 | blk_rq_set_mixed_merge(req); | ||
408 | blk_rq_set_mixed_merge(next); | ||
409 | } | ||
410 | |||
411 | /* | ||
369 | * At this point we have either done a back merge | 412 | * At this point we have either done a back merge |
370 | * or front merge. We need the smaller start_time of | 413 | * or front merge. We need the smaller start_time of |
371 | * the merged requests to be the current request | 414 | * the merged requests to be the current request |