diff options
Diffstat (limited to 'block/blk-merge.c')
-rw-r--r-- | block/blk-merge.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c index cfcc37cb222b..160035f54882 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -471,3 +471,40 @@ int blk_attempt_req_merge(struct request_queue *q, struct request *rq, | |||
471 | { | 471 | { |
472 | return attempt_merge(q, rq, next); | 472 | return attempt_merge(q, rq, next); |
473 | } | 473 | } |
474 | |||
475 | bool blk_rq_merge_ok(struct request *rq, struct bio *bio) | ||
476 | { | ||
477 | if (!rq_mergeable(rq)) | ||
478 | return false; | ||
479 | |||
480 | /* don't merge file system requests and discard requests */ | ||
481 | if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD)) | ||
482 | return false; | ||
483 | |||
484 | /* don't merge discard requests and secure discard requests */ | ||
485 | if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE)) | ||
486 | return false; | ||
487 | |||
488 | /* different data direction or already started, don't merge */ | ||
489 | if (bio_data_dir(bio) != rq_data_dir(rq)) | ||
490 | return false; | ||
491 | |||
492 | /* must be same device and not a special request */ | ||
493 | if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special) | ||
494 | return false; | ||
495 | |||
496 | /* only merge integrity protected bio into ditto rq */ | ||
497 | if (bio_integrity(bio) != blk_integrity_rq(rq)) | ||
498 | return false; | ||
499 | |||
500 | return true; | ||
501 | } | ||
502 | |||
503 | int blk_try_merge(struct request *rq, struct bio *bio) | ||
504 | { | ||
505 | if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_sector) | ||
506 | return ELEVATOR_BACK_MERGE; | ||
507 | else if (blk_rq_pos(rq) - bio_sectors(bio) == bio->bi_sector) | ||
508 | return ELEVATOR_FRONT_MERGE; | ||
509 | return ELEVATOR_NO_MERGE; | ||
510 | } | ||