25-akpm/drivers/block/as-iosched.c |   94 ++++++++++++++++++-------------------
 1 files changed, 46 insertions(+), 48 deletions(-)

diff -puN drivers/block/as-iosched.c~as-iosched-dyn drivers/block/as-iosched.c
--- 25/drivers/block/as-iosched.c~as-iosched-dyn	Wed Apr 30 15:22:55 2003
+++ 25-akpm/drivers/block/as-iosched.c	Wed Apr 30 15:22:55 2003
@@ -117,6 +117,7 @@ struct as_data {
 	unsigned long current_batch_expires;
 	unsigned long last_check_fifo[2];
 	int batch_data_dir;		/* current/last batch READ or WRITE */
+	mempool_t *arq_pool;
 
 	int antic_status;
 	unsigned long antic_start;	/* jiffies: when it started */
@@ -1442,12 +1443,42 @@ static void as_work_handler(void *data)
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
+static void as_put_request(request_queue_t *q, struct request *rq)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	struct as_rq *arq = RQ_DATA(rq);
+
+	if (arq) {
+		mempool_free(arq, ad->arq_pool);
+		rq->elevator_private = NULL;
+	}
+}
+
+static int as_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
+
+	if (arq) {
+		RB_CLEAR(&arq->rb_node);
+		arq->request = rq;
+
+		arq->as_io_context = NULL;
+		INIT_LIST_HEAD(&arq->hash);
+		arq->hash_valid_count = 0;
+
+		INIT_LIST_HEAD(&arq->fifo);
+
+		rq->elevator_private = arq;
+		return 0;
+	}
+
+	return 1;
+}
+
 static void as_exit(request_queue_t *q, elevator_t *e)
 {
 	struct as_data *ad = e->elevator_data;
-	struct as_rq *arq;
-	struct request *rq;
-	int i;
 
 	del_timer_sync(&ad->antic_timer);
 	kblockd_flush();
@@ -1455,21 +1486,7 @@ static void as_exit(request_queue_t *q, 
 	BUG_ON(!list_empty(&ad->fifo_list[READ]));
 	BUG_ON(!list_empty(&ad->fifo_list[WRITE]));
 
-	for (i = READ; i <= WRITE; i++) {
-		struct request_list *rl = &q->rq[i];
-		struct list_head *entry;
-
-		list_for_each(entry, &rl->free) {
-			rq = list_entry_rq(entry);
-
-			if ((arq = RQ_DATA(rq)) == NULL)
-				continue;
-
-			rq->elevator_private = NULL;
-			kmem_cache_free(arq_pool, arq);
-		}
-	}
-
+	mempool_destroy(ad->arq_pool);
 	put_as_io_context(&ad->as_io_context);
 	kfree(ad->hash);
 	kfree(ad);
@@ -1482,9 +1499,7 @@ static void as_exit(request_queue_t *q, 
 static int as_init(request_queue_t *q, elevator_t *e)
 {
 	struct as_data *ad;
-	struct as_rq *arq;
-	struct request *rq;
-	int i, ret = 0;
+	int i;
 
 	if (!arq_pool)
 		return -ENOMEM;
@@ -1502,6 +1517,13 @@ static int as_init(request_queue_t *q, e
 		return -ENOMEM;
 	}
 
+	ad->arq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, arq_pool);
+	if (!ad->arq_pool) {
+		kfree(ad->hash);
+		kfree(ad);
+		return -ENOMEM;
+	}
+
 	/* anticipatory scheduling helpers */
 	ad->antic_timer.function = as_antic_timeout;
 	ad->antic_timer.data = (unsigned long)q;
@@ -1525,33 +1547,7 @@ static int as_init(request_queue_t *q, e
 	e->elevator_data = ad;
 
 	ad->current_batch_expires = jiffies + ad->batch_expire[READ];
-
-	for (i = READ; i <= WRITE; i++) {
-		struct request_list *rl = &q->rq[i];
-		struct list_head *entry;
-
-		list_for_each(entry, &rl->free) {
-			rq = list_entry_rq(entry);
-
-			arq = kmem_cache_alloc(arq_pool, GFP_KERNEL);
-			if (!arq) {
-				ret = -ENOMEM;
-				break;
-			}
-
-			memset(arq, 0, sizeof(*arq));
-			INIT_LIST_HEAD(&arq->fifo);
-			INIT_LIST_HEAD(&arq->hash);
-			RB_CLEAR(&arq->rb_node);
-			arq->request = rq;
-			rq->elevator_private = arq;
-		}
-	}
-
-	if (ret)
-		as_exit(q, e);
-
-	return ret;
+	return 0;
 }
 
 /*
@@ -1705,6 +1701,8 @@ elevator_t iosched_as = {
 	.elevator_completed_req_fn =	as_completed_request,
 	.elevator_former_req_fn =	as_former_request,
 	.elevator_latter_req_fn =	as_latter_request,
+	.elevator_set_req_fn =		as_set_request,
+	.elevator_put_req_fn =		as_put_request,
 	.elevator_init_fn =		as_init,
 	.elevator_exit_fn =		as_exit,
 

_