block: recursive merge requests
[linux-2.6.git] / block / elevator.c
index 91e18f8..99838f4 100644 (file)
@@ -515,6 +515,7 @@ static bool elv_attempt_insert_merge(struct request_queue *q,
                                     struct request *rq)
 {
        struct request *__rq;
+       bool ret;
 
        if (blk_queue_nomerges(q))
                return false;
@@ -528,14 +529,21 @@ static bool elv_attempt_insert_merge(struct request_queue *q,
        if (blk_queue_noxmerges(q))
                return false;
 
+       ret = false;
        /*
         * See if our hash lookup can find a potential backmerge.
         */
-       __rq = elv_rqhash_find(q, blk_rq_pos(rq));
-       if (__rq && blk_attempt_req_merge(q, __rq, rq))
-               return true;
+       while (1) {
+               __rq = elv_rqhash_find(q, blk_rq_pos(rq));
+               if (!__rq || !blk_attempt_req_merge(q, __rq, rq))
+                       break;
 
-       return false;
+               /* The merged request could be merged with others, try again */
+               ret = true;
+               rq = __rq;
+       }
+
+       return ret;
 }
 
 void elv_merged_request(struct request_queue *q, struct request *rq, int type)