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

This elevator completion notifier seems to be the correct
generic half of the AS / completion thingy. Might need
changing if bugs turn up though...

This is the same as the last version I have posted. Jens
says it looks alright.



 drivers/block/elevator.c  |    9 +++++++++
 drivers/block/ll_rw_blk.c |    2 ++
 include/linux/elevator.h  |    3 +++
 3 files changed, 14 insertions(+)

diff -puN drivers/block/elevator.c~elevator-completion-api drivers/block/elevator.c
--- 25/drivers/block/elevator.c~elevator-completion-api	2003-06-18 00:13:21.000000000 -0700
+++ 25-akpm/drivers/block/elevator.c	2003-06-18 00:13:21.000000000 -0700
@@ -371,6 +371,14 @@ int elv_may_queue(request_queue_t *q, in
 	return 1;
 }
 
+void elv_completed_request(request_queue_t *q, struct request *rq)
+{
+	elevator_t *e = &q->elevator;
+
+	if (e->elevator_completed_req_fn)
+		e->elevator_completed_req_fn(q, rq);
+}
+
 int elv_register_queue(struct gendisk *disk)
 {
 	request_queue_t *q = disk->queue;
@@ -418,5 +426,6 @@ EXPORT_SYMBOL(__elv_add_request);
 EXPORT_SYMBOL(elv_next_request);
 EXPORT_SYMBOL(elv_remove_request);
 EXPORT_SYMBOL(elv_queue_empty);
+EXPORT_SYMBOL(elv_completed_request);
 EXPORT_SYMBOL(elevator_exit);
 EXPORT_SYMBOL(elevator_init);
diff -puN drivers/block/ll_rw_blk.c~elevator-completion-api drivers/block/ll_rw_blk.c
--- 25/drivers/block/ll_rw_blk.c~elevator-completion-api	2003-06-18 00:13:21.000000000 -0700
+++ 25-akpm/drivers/block/ll_rw_blk.c	2003-06-18 00:13:21.000000000 -0700
@@ -1510,6 +1510,8 @@ void __blk_put_request(request_queue_t *
 	if (unlikely(--req->ref_count))
 		return;
 
+	elv_completed_request(req->q, req);
+
 	req->rq_status = RQ_INACTIVE;
 	req->q = NULL;
 	req->rl = NULL;
diff -puN include/linux/elevator.h~elevator-completion-api include/linux/elevator.h
--- 25/include/linux/elevator.h~elevator-completion-api	2003-06-18 00:13:21.000000000 -0700
+++ 25-akpm/include/linux/elevator.h	2003-06-18 00:13:21.000000000 -0700
@@ -15,6 +15,7 @@ typedef int (elevator_queue_empty_fn) (r
 typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
 typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
 typedef struct list_head *(elevator_get_sort_head_fn) (request_queue_t *, struct request *);
+typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
 typedef int (elevator_may_queue_fn) (request_queue_t *, int);
 
 typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, int);
@@ -34,6 +35,7 @@ struct elevator_s
 	elevator_remove_req_fn *elevator_remove_req_fn;
 
 	elevator_queue_empty_fn *elevator_queue_empty_fn;
+	elevator_completed_req_fn *elevator_completed_req_fn;
 
 	elevator_request_list_fn *elevator_former_req_fn;
 	elevator_request_list_fn *elevator_latter_req_fn;
@@ -69,6 +71,7 @@ extern struct request *elv_latter_reques
 extern int elv_register_queue(struct gendisk *);
 extern void elv_unregister_queue(struct gendisk *);
 extern int elv_may_queue(request_queue_t *, int);
+extern void elv_completed_request(request_queue_t *, struct request *);
 extern int elv_set_request(request_queue_t *, struct request *, int);
 extern void elv_put_request(request_queue_t *, struct request *);
 

_