Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
[linux-2.6-microblaze.git] / block / elevator.c
index 440699c..52ada14 100644 (file)
@@ -350,9 +350,11 @@ enum elv_merge elv_merge(struct request_queue *q, struct request **req,
  * we can append 'rq' to an existing request, so we can throw 'rq' away
  * afterwards.
  *
- * Returns true if we merged, false otherwise
+ * Returns true if we merged, false otherwise. 'free' will contain all
+ * requests that need to be freed.
  */
-bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq)
+bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq,
+                             struct list_head *free)
 {
        struct request *__rq;
        bool ret;
@@ -363,8 +365,10 @@ bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq)
        /*
         * First try one-hit cache.
         */
-       if (q->last_merge && blk_attempt_req_merge(q, q->last_merge, rq))
+       if (q->last_merge && blk_attempt_req_merge(q, q->last_merge, rq)) {
+               list_add(&rq->queuelist, free);
                return true;
+       }
 
        if (blk_queue_noxmerges(q))
                return false;
@@ -378,6 +382,7 @@ bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq)
                if (!__rq || !blk_attempt_req_merge(q, __rq, rq))
                        break;
 
+               list_add(&rq->queuelist, free);
                /* The merged request could be merged with others, try again */
                ret = true;
                rq = __rq;
@@ -522,6 +527,10 @@ void elv_unregister_queue(struct request_queue *q)
 
 int elv_register(struct elevator_type *e)
 {
+       /* insert_requests and dispatch_request are mandatory */
+       if (WARN_ON_ONCE(!e->ops.insert_requests || !e->ops.dispatch_request))
+               return -EINVAL;
+
        /* create icq_cache if requested */
        if (e->icq_size) {
                if (WARN_ON(e->icq_size < sizeof(struct io_cq)) ||
@@ -693,7 +702,7 @@ void elevator_init_mq(struct request_queue *q)
                elevator_put(e);
        }
 }
-
+EXPORT_SYMBOL_GPL(elevator_init_mq); /* only for dm-rq */
 
 /*
  * switch to new_e io scheduler. be careful not to introduce deadlocks -