diff options
Diffstat (limited to 'block/elevator.c')
-rw-r--r-- | block/elevator.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/block/elevator.c b/block/elevator.c index ed6f8f32d27..4f5127054e3 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -75,6 +75,12 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio) return 0; /* + * Don't merge file system requests and discard requests + */ + if (bio_discard(bio) != bio_discard(rq->bio)) + return 0; + + /* * different data direction or already started, don't merge */ if (bio_data_dir(bio) != rq_data_dir(rq)) @@ -438,6 +444,8 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) list_for_each_prev(entry, &q->queue_head) { struct request *pos = list_entry_rq(entry); + if (blk_discard_rq(rq) != blk_discard_rq(pos)) + break; if (rq_data_dir(rq) != rq_data_dir(pos)) break; if (pos->cmd_flags & stop_flags) @@ -607,7 +615,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) break; case ELEVATOR_INSERT_SORT: - BUG_ON(!blk_fs_request(rq)); + BUG_ON(!blk_fs_request(rq) && !blk_discard_rq(rq)); rq->cmd_flags |= REQ_SORTED; q->nr_sorted++; if (rq_mergeable(rq)) { @@ -692,7 +700,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where, * this request is scheduling boundary, update * end_sector */ - if (blk_fs_request(rq)) { + if (blk_fs_request(rq) || blk_discard_rq(rq)) { q->end_sector = rq_end_sector(rq); q->boundary_rq = rq; } |