int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
                          struct request *next)
 {
+       struct elevator_queue *e = q->elevator;
+
+       if (e->type->ops.elevator_allow_rq_merge_fn)
+               if (!e->type->ops.elevator_allow_rq_merge_fn(q, rq, next))
+                       return 0;
+
        return attempt_merge(q, rq, next);
 }
 
 
        struct request *__rq;
 
        __rq = cfq_find_rq_fmerge(cfqd, bio);
-       if (__rq && elv_rq_merge_ok(__rq, bio)) {
+       if (__rq && elv_bio_merge_ok(__rq, bio)) {
                *req = __rq;
                return ELEVATOR_FRONT_MERGE;
        }
                cfq_del_cfqq_rr(cfqd, cfqq);
 }
 
-static int cfq_allow_merge(struct request_queue *q, struct request *rq,
-                          struct bio *bio)
+static int cfq_allow_bio_merge(struct request_queue *q, struct request *rq,
+                              struct bio *bio)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct cfq_io_cq *cic;
        return cfqq == RQ_CFQQ(rq);
 }
 
+static int cfq_allow_rq_merge(struct request_queue *q, struct request *rq,
+                             struct request *next)
+{
+       return RQ_CFQQ(rq) == RQ_CFQQ(next);
+}
+
 static inline void cfq_del_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
        hrtimer_try_to_cancel(&cfqd->idle_slice_timer);
                .elevator_merge_fn =            cfq_merge,
                .elevator_merged_fn =           cfq_merged_request,
                .elevator_merge_req_fn =        cfq_merged_requests,
-               .elevator_allow_merge_fn =      cfq_allow_merge,
+               .elevator_allow_bio_merge_fn =  cfq_allow_bio_merge,
+               .elevator_allow_rq_merge_fn =   cfq_allow_rq_merge,
                .elevator_bio_merged_fn =       cfq_bio_merged,
                .elevator_dispatch_fn =         cfq_dispatch_requests,
                .elevator_add_req_fn =          cfq_insert_request,
 
                if (__rq) {
                        BUG_ON(sector != blk_rq_pos(__rq));
 
-                       if (elv_rq_merge_ok(__rq, bio)) {
+                       if (elv_bio_merge_ok(__rq, bio)) {
                                ret = ELEVATOR_FRONT_MERGE;
                                goto out;
                        }
 
  * Query io scheduler to see if the current process issuing bio may be
  * merged with rq.
  */
-static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
+static int elv_iosched_allow_bio_merge(struct request *rq, struct bio *bio)
 {
        struct request_queue *q = rq->q;
        struct elevator_queue *e = q->elevator;
 
-       if (e->type->ops.elevator_allow_merge_fn)
-               return e->type->ops.elevator_allow_merge_fn(q, rq, bio);
+       if (e->type->ops.elevator_allow_bio_merge_fn)
+               return e->type->ops.elevator_allow_bio_merge_fn(q, rq, bio);
 
        return 1;
 }
 /*
  * can we safely merge with this request?
  */
-bool elv_rq_merge_ok(struct request *rq, struct bio *bio)
+bool elv_bio_merge_ok(struct request *rq, struct bio *bio)
 {
        if (!blk_rq_merge_ok(rq, bio))
-               return 0;
+               return false;
 
-       if (!elv_iosched_allow_merge(rq, bio))
-               return 0;
+       if (!elv_iosched_allow_bio_merge(rq, bio))
+               return false;
 
-       return 1;
+       return true;
 }
-EXPORT_SYMBOL(elv_rq_merge_ok);
+EXPORT_SYMBOL(elv_bio_merge_ok);
 
 static struct elevator_type *elevator_find(const char *name)
 {
        /*
         * First try one-hit cache.
         */
-       if (q->last_merge && elv_rq_merge_ok(q->last_merge, bio)) {
+       if (q->last_merge && elv_bio_merge_ok(q->last_merge, bio)) {
                ret = blk_try_merge(q->last_merge, bio);
                if (ret != ELEVATOR_NO_MERGE) {
                        *req = q->last_merge;
         * See if our hash lookup can find a potential backmerge.
         */
        __rq = elv_rqhash_find(q, bio->bi_iter.bi_sector);
-       if (__rq && elv_rq_merge_ok(__rq, bio)) {
+       if (__rq && elv_bio_merge_ok(__rq, bio)) {
                *req = __rq;
                return ELEVATOR_BACK_MERGE;
        }
 
 
 typedef void (elevator_merged_fn) (struct request_queue *, struct request *, int);
 
-typedef int (elevator_allow_merge_fn) (struct request_queue *, struct request *, struct bio *);
+typedef int (elevator_allow_bio_merge_fn) (struct request_queue *,
+                                          struct request *, struct bio *);
+
+typedef int (elevator_allow_rq_merge_fn) (struct request_queue *,
+                                         struct request *, struct request *);
 
 typedef void (elevator_bio_merged_fn) (struct request_queue *,
                                                struct request *, struct bio *);
        elevator_merge_fn *elevator_merge_fn;
        elevator_merged_fn *elevator_merged_fn;
        elevator_merge_req_fn *elevator_merge_req_fn;
-       elevator_allow_merge_fn *elevator_allow_merge_fn;
+       elevator_allow_bio_merge_fn *elevator_allow_bio_merge_fn;
+       elevator_allow_rq_merge_fn *elevator_allow_rq_merge_fn;
        elevator_bio_merged_fn *elevator_bio_merged_fn;
 
        elevator_dispatch_fn *elevator_dispatch_fn;
 extern int elevator_init(struct request_queue *, char *);
 extern void elevator_exit(struct elevator_queue *);
 extern int elevator_change(struct request_queue *, const char *);
-extern bool elv_rq_merge_ok(struct request *, struct bio *);
+extern bool elv_bio_merge_ok(struct request *, struct bio *);
 extern struct elevator_queue *elevator_alloc(struct request_queue *,
                                        struct elevator_type *);