Patch from Nick Piggin <piggin@cyberone.com.au>




 drivers/block/as-iosched.c |   22 +++++++++++++++++++---
 1 files changed, 19 insertions(+), 3 deletions(-)

diff -puN drivers/block/as-iosched.c~as-np-reads-2 drivers/block/as-iosched.c
--- 25/drivers/block/as-iosched.c~as-np-reads-2	2003-03-18 01:43:53.000000000 -0800
+++ 25-akpm/drivers/block/as-iosched.c	2003-03-18 01:43:53.000000000 -0800
@@ -416,7 +416,7 @@ static struct as_rq *__as_add_arq_rb(str
 
 static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq);
 /*
- * Aad the request to the rb tree if it is unique.  If there is an alias (an
+ * Add the request to the rb tree if it is unique.  If there is an alias (an
  * existing request against the same sector), which can happen when using
  * direct IO, then move the alias to the dispatch list and then add the
  * request.
@@ -995,8 +995,8 @@ static void as_remove_request(request_qu
 	struct as_data *ad = q->elevator.elevator_data;
 	struct as_rq *arq = RQ_DATA(rq);
 
-	if (unlikely(!blk_fs_request(rq)))
-			return;
+	if (unlikely(!blk_fs_request(rq) || rq->flags & REQ_HARDBARRIER))
+		return;
 
 	if (arq) {
 		if (ON_RB(&arq->rb_node))
@@ -1246,6 +1246,22 @@ as_insert_request(request_queue_t *q, st
 	if (unlikely(rq->flags & REQ_HARDBARRIER)) {
 		AS_INVALIDATE_HASH(ad);
 		q->last_merge = NULL;
+
+		while (ad->next_arq[READ])
+			as_move_to_dispatch(ad, ad->next_arq[READ]);
+
+		while (ad->next_arq[WRITE])
+			as_move_to_dispatch(ad, ad->next_arq[WRITE]);
+
+		list_add_tail(&rq->queuelist, ad->dispatch);
+
+		/* Stop anticipating - let this request get through */
+		if (!list_empty(ad->dispatch) && rq_data_dir(rq) == READ
+			&& (ad->antic_status == ANTIC_WAIT_REQ
+				|| ad->antic_status == ANTIC_WAIT_NEXT))
+			as_antic_stop(ad);
+
+		return;
 	}
 
 	if (unlikely(!blk_fs_request(rq))) {

_