From: Nick Piggin 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-04-17 21:25:34.000000000 -0700 +++ 25-akpm/drivers/block/elevator.c 2003-04-17 21:25:34.000000000 -0700 @@ -418,6 +418,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; @@ -465,5 +473,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-04-17 21:25:34.000000000 -0700 +++ 25-akpm/drivers/block/ll_rw_blk.c 2003-04-17 21:25:34.000000000 -0700 @@ -1534,6 +1534,8 @@ void __blk_put_request(request_queue_t * if (unlikely(!q)) 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-04-17 21:25:34.000000000 -0700 +++ 25-akpm/include/linux/elevator.h 2003-04-17 21:25:34.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_init_fn) (request_queue_t *, elevator_t *); @@ -31,6 +32,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; @@ -62,6 +64,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 *); #define __elv_add_request_pos(q, rq, pos) \ (q)->elevator.elevator_add_req_fn((q), (rq), (pos)) _