From: Nick Piggin <piggin@cyberone.com.au>

Comments, cleanups, sanity.


 drivers/block/as-iosched.c |   67 ++++++++++++++++++++++++++++-----------------
 1 files changed, 43 insertions(+), 24 deletions(-)

diff -puN drivers/block/as-iosched.c~as-np-1 drivers/block/as-iosched.c
--- 25/drivers/block/as-iosched.c~as-np-1	2003-03-16 13:59:01.000000000 -0800
+++ 25-akpm/drivers/block/as-iosched.c	2003-03-16 13:59:01.000000000 -0800
@@ -81,12 +81,14 @@ static unsigned long write_batch_expire 
  */
 static unsigned long antic_expire = HZ / 100;
 
-#define ANTIC_OFF	0	/* Not anticipating (normal operation)	*/
-#define ANTIC_WAIT_REQ	1	/* The last read has not yet completed  */
-#define ANTIC_WAIT_NEXT	2	/* Currently anticipating a request vs
+enum anticipation_states {
+	ANTIC_OFF=0,		/* Not anticipating (normal operation)	*/
+	ANTIC_WAIT_REQ,		/* The last read has not yet completed  */
+	ANTIC_WAIT_NEXT,	/* Currently anticipating a request vs
 				   last read (which has completed) */
-#define ANTIC_FINISHED	3	/* Anticipating but have found a candidate
+	ANTIC_FINISHED,		/* Anticipating but have found a candidate
 				   or timed out	*/
+};
 
 /*
  * This is the per-process anticipatory I/O scheduler state.  It is refcounted
@@ -156,9 +158,13 @@ struct as_data {
 	unsigned long antic_expire;
 };
 
-#define AS_RQ_NEW		0
-#define AS_RQ_QUEUED		1
-#define AS_RQ_DISPATCHED	2
+enum arq_states {
+	AS_RQ_NEW=0,		/* New - not referenced and not on any lists */
+	AS_RQ_QUEUED,		/* In the request queue. It belongs to the
+				   scheduler */
+	AS_RQ_DISPATCHED,	/* On the dispatch list. It belongs to the
+				   driver now */
+};
 
 /*
  * per-request data.
@@ -909,21 +915,22 @@ static void as_antic_waitnext(struct as_
 
 /*
  * This is executed in a "deferred" context.  Either in a timer handler or
- * in tasklet.  It tries to move a request into the dispatch queue (which is
- * not a queue at all!  FIXME!) and then calls the driver's request_fn so the
- * driver can submit that request.
+ * in tasklet. It calls the driver's request_fn so the driver can submit
+ * that request. IMPORTANT! This guy will reenter the elevator, so setup
+ * all queue global state before calling, and don't rely on any state over
+ * calls.
+ *
+ * FIXME! dispatch queue is not a queue at all!
+ * Andrew! as_queue_notready does not _try_ to move a request to dispatch
+ * list, in fact it tries not to! Unfortunately it sometimes must in order
+ * to guarantee elv_next_request will return !NULL after a ready indication.
  */
 static void __as_antic_stop(struct as_data *ad)
 {
-	int status = ad->antic_status;
+	struct request_queue *q = ad->q;
 
-	ad->antic_status = ANTIC_FINISHED;
-	if (status == ANTIC_WAIT_REQ || status == ANTIC_WAIT_NEXT) {
-		struct request_queue *q = ad->q;
-
-		if (!as_queue_notready(q))
-			q->request_fn(q);
-	}
+	if (!as_queue_notready(q))
+		q->request_fn(q);
 }
 
 /*
@@ -946,8 +953,15 @@ static void __as_bottom_half(unsigned lo
  */
 static void as_antic_timeout(unsigned long data)
 {
+	struct request_queue *q = (struct request_queue *)data;
+	struct as_data *ad = q->elevator.elevator_data;
+	int status = ad->antic_status;
+
 	ant_stats.timeouts++;
-	__as_bottom_half(data);
+	if (status == ANTIC_WAIT_REQ || status == ANTIC_WAIT_NEXT) {
+		ad->antic_status = ANTIC_FINISHED;
+		__as_bottom_half(data);
+	}
 }
 
 /*
@@ -966,9 +980,14 @@ static void as_tasklet_handler(unsigned 
  */
 static void as_antic_stop(struct as_data *ad)
 {
-	if (ad->antic_status == ANTIC_WAIT_NEXT) 
-		del_timer(&ad->antic_timer);
-	tasklet_schedule(&ad->tasklet);
+	int status = ad->antic_status;
+
+	if (status == ANTIC_WAIT_REQ || status == ANTIC_WAIT_NEXT) {
+		if (status == ANTIC_WAIT_NEXT)
+			del_timer(&ad->antic_timer);
+		ad->antic_status = ANTIC_FINISHED;
+		tasklet_schedule(&ad->tasklet);
+	}
 }
 
 /*
@@ -1119,8 +1138,8 @@ static void as_update_arq(struct as_data
  */
 static int as_can_anticipate(struct as_data *ad, struct as_rq *arq)
 {
-//	BUG_ON(ad->antic_status == ANTIC_WAIT_REQ ||
-//		ad->antic_status == ANTIC_WAIT_NEXT);
+	BUG_ON(ad->antic_status == ANTIC_WAIT_REQ ||
+		ad->antic_status == ANTIC_WAIT_NEXT);
 
 	if (!ad->as_io_context)
 		/*

_