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

This is pretty well correct I think. If we get a write from the
process we are anticipating a read from, then the read isn't sync,
right?

I still don't think this will help the Oracle load, however.



 drivers/block/as-iosched.c |   68 ++++++++++++++++++++++++---------------------
 1 files changed, 37 insertions(+), 31 deletions(-)

diff -puN drivers/block/as-iosched.c~as-break-anticipation-on-write drivers/block/as-iosched.c
--- 25/drivers/block/as-iosched.c~as-break-anticipation-on-write	Mon Feb 24 15:09:23 2003
+++ 25-akpm/drivers/block/as-iosched.c	Mon Feb 24 15:09:23 2003
@@ -33,6 +33,7 @@ struct ant_stats {
 	int expired_fifo_writes;
 	int close_requests;
 	int matching_ids;
+	int broken_by_write;
 
 	int ant_delay_hist[100];	/* milliseconds */
 
@@ -749,17 +750,23 @@ elevator_wrap:
 }
 
 /*
- * as_antic_req, has @ad been anticipating this @arq?
+ * as_antic_req returns true if we have been anticipating this request.
+ *
+ * It also returns true if the process against which we are anticipating
+ * submits a write - that's presumably an fsync, O_SYNC write, etc. We want to
+ * dispatch it ASAP, because we know that application will not be submitting
+ * any new reads.
  */
-static int
-as_antic_req(struct as_data *ad, struct as_rq *arq)
+static int as_antic_req(struct as_data *ad, struct as_rq *arq)
 {
-	if (as_close_req(ad, arq)) {
+	if (rq_data_dir(arq->request) == READ && as_close_req(ad, arq)) {
 		ant_stats.close_requests++;
 		return 1;
 	}
 	if (ad->current_id == arq->request_id) {
 		ant_stats.matching_ids++;
+		if (rq_data_dir(arq->request) == WRITE)
+			ant_stats.broken_by_write++;
 		return 1;
 	}
 	return 0;
@@ -770,12 +777,10 @@ as_antic_req(struct as_data *ad, struct 
  * the sort_list. This function keeps caches up to date, and checks if the
  * request might be one we are "anticipating"
  */
-static void
-as_update_arq(struct as_data *ad, struct as_rq *arq)
+static void as_update_arq(struct as_data *ad, struct as_rq *arq)
 {
 	const int data_dir = rq_data_dir(arq->request);
 
-
 	if (data_dir == READ)
 		ant_stats.reads++;
 	else
@@ -784,11 +789,12 @@ as_update_arq(struct as_data *ad, struct
 	/* keep the next_arq cache up to date */
 	ad->next_arq[data_dir] = as_choose_req(ad, arq, ad->next_arq[data_dir]);
 
-	/* have we been anticipating this request? */
-	if (ad->antic_status != ANTIC_OFF && data_dir == READ
-			&& as_antic_req(ad, arq)) {
-
-		/* statistics stuff */
+	/*
+	 * have we been anticipating this request?
+	 * or does it come from the same process as the one we are anticipating
+	 * for?
+	 */
+	if (ad->antic_status != ANTIC_OFF && as_antic_req(ad, arq)) {
 		sector_t last = ad->last_sector[data_dir];
 		sector_t this = arq->request->sector;
 		unsigned long delay = jiffies - ad->antic_start;
@@ -796,24 +802,25 @@ as_update_arq(struct as_data *ad, struct
 		int neg;
 		int log2;
 
-		if (delay >= ARRAY_SIZE(ant_stats.ant_delay_hist))
-			delay = ARRAY_SIZE(ant_stats.ant_delay_hist) - 1;
-		ant_stats.ant_delay_hist[delay]++;
-		ant_stats.anticipate_hits++;
-
-		lba_offset = this - last;
-		neg = 0;
-		if (lba_offset < 0) {
-			lba_offset = -lba_offset;
-			neg = 1;
+		if (data_dir == READ) {
+			if (delay >= ARRAY_SIZE(ant_stats.ant_delay_hist))
+				delay = ARRAY_SIZE(ant_stats.ant_delay_hist)-1;
+			ant_stats.ant_delay_hist[delay]++;
+			ant_stats.anticipate_hits++;
+
+			lba_offset = this - last;
+			neg = 0;
+			if (lba_offset < 0) {
+				lba_offset = -lba_offset;
+				neg = 1;
+			}
+			log2 = ffs(lba_offset);
+			BUG_ON(log2 >= 32);
+			if (neg)
+				ant_stats.lba_backward_offsets[log2]++;
+			else
+				ant_stats.lba_forward_offsets[log2]++;
 		}
-		log2 = ffs(lba_offset);
-		BUG_ON(log2 >= 32);
-		if (neg)
-			ant_stats.lba_backward_offsets[log2]++;
-		else
-			ant_stats.lba_forward_offsets[log2]++;
-
 		del_timer(&ad->antic_timer);
 		ad->antic_status = ANTIC_FINISHED;
 		if (arq)
@@ -826,8 +833,7 @@ as_update_arq(struct as_data *ad, struct
  * can_start_anticipation indicates weather we should either run arq
  * or keep anticipating a better request.
  */
-static int
-can_start_anticipation(struct as_data *ad, struct as_rq *arq)
+static int can_start_anticipation(struct as_data *ad, struct as_rq *arq)
 {
 	if (ad->antic_status == ANTIC_FINISHED)
 		/*

_