Merge branch 'for-linus' into for-2.6.40/core
authorJens Axboe <jaxboe@fusionio.com>
Fri, 20 May 2011 18:36:16 +0000 (20:36 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Fri, 20 May 2011 18:36:16 +0000 (20:36 +0200)
This patch merges in a fix that missed 2.6.39 final.

Conflicts:
block/blk.h

1  2 
block/blk.h

diff --cc block/blk.h
@@@ -61,27 -61,9 +61,29 @@@ static inline struct request *__elv_nex
                        rq = list_entry_rq(q->queue_head.next);
                        return rq;
                }
-               if (!q->elevator->ops->elevator_dispatch_fn(q, 0))
 +              /*
 +               * Flush request is running and flush request isn't queueable
 +               * in the drive, we can hold the queue till flush request is
 +               * finished. Even we don't do this, driver can't dispatch next
 +               * requests and will requeue them. And this can improve
 +               * throughput too. For example, we have request flush1, write1,
 +               * flush 2. flush1 is dispatched, then queue is hold, write1
 +               * isn't inserted to queue. After flush1 is finished, flush2
 +               * will be dispatched. Since disk cache is already clean,
 +               * flush2 will be finished very soon, so looks like flush2 is
 +               * folded to flush1.
 +               * Since the queue is hold, a flag is set to indicate the queue
 +               * should be restarted later. Please see flush_end_io() for
 +               * details.
 +               */
 +              if (q->flush_pending_idx != q->flush_running_idx &&
 +                              !queue_flush_queueable(q)) {
 +                      q->flush_queue_delayed = 1;
 +                      return NULL;
 +              }
+               if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags) ||
+                   !q->elevator->ops->elevator_dispatch_fn(q, 0))
                        return NULL;
        }
  }