Merge branch 'for_paulus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerp...
[powerpc.git] / block / elevator.c
index 8ccd163..f6dafa8 100644 (file)
@@ -50,6 +50,21 @@ static const int elv_hash_shift = 6;
 #define rq_hash_key(rq)                ((rq)->sector + (rq)->nr_sectors)
 #define ELV_ON_HASH(rq)                (!hlist_unhashed(&(rq)->hash))
 
+/*
+ * 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)
+{
+       request_queue_t *q = rq->q;
+       elevator_t *e = q->elevator;
+
+       if (e->ops->elevator_allow_merge_fn)
+               return e->ops->elevator_allow_merge_fn(q, rq, bio);
+
+       return 1;
+}
+
 /*
  * can we safely merge with this request?
  */
@@ -65,12 +80,15 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
                return 0;
 
        /*
-        * same device and no special stuff set, merge is ok
+        * must be same device and not a special request
         */
-       if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special)
-               return 1;
+       if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
+               return 0;
 
-       return 0;
+       if (!elv_iosched_allow_merge(rq, bio))
+               return 0;
+
+       return 1;
 }
 EXPORT_SYMBOL(elv_rq_merge_ok);
 
@@ -129,7 +147,7 @@ static struct elevator_type *elevator_get(const char *name)
 
 static void *elevator_init_queue(request_queue_t *q, struct elevator_queue *eq)
 {
-       return eq->ops->elevator_init_fn(q, eq);
+       return eq->ops->elevator_init_fn(q);
 }
 
 static void elevator_attach(request_queue_t *q, struct elevator_queue *eq,
@@ -572,6 +590,12 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
                 */
                rq->cmd_flags |= REQ_SOFTBARRIER;
 
+               /*
+                * Most requeues happen because of a busy condition,
+                * don't force unplug of the queue for that case.
+                */
+               unplug_it = 0;
+
                if (q->ordseq == 0) {
                        list_add(&rq->queuelist, &q->queue_head);
                        break;
@@ -586,11 +610,6 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
                }
 
                list_add_tail(&rq->queuelist, pos);
-               /*
-                * most requeues happen because of a busy condition, don't
-                * force unplug of the queue for that case.
-                */
-               unplug_it = 0;
                break;
 
        default:
@@ -810,7 +829,7 @@ void elv_put_request(request_queue_t *q, struct request *rq)
        elevator_t *e = q->elevator;
 
        if (e->ops->elevator_put_req_fn)
-               e->ops->elevator_put_req_fn(q, rq);
+               e->ops->elevator_put_req_fn(rq);
 }
 
 int elv_may_queue(request_queue_t *q, int rw)