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 | } | ||
