From: Nick Piggin This fixes a bug in deadline and AS that causes insert_here to be ignored on blk_fs_requests. This has been causing problems with SCSI requeueing code. It makes elevator insertion more correct as advertised wrt insert_here and REQ_SOFTBARRIER. It also fixes a buglet in the as_requeue code where the request wasn't being put into the front of the list (in rare cases). drivers/block/as-iosched.c | 36 ++++++++++++++++++------------------ drivers/block/deadline-iosched.c | 16 ++++++++++------ drivers/block/elevator.c | 6 +++--- 3 files changed, 31 insertions(+), 27 deletions(-) diff -puN drivers/block/as-iosched.c~elv-insertion-fix drivers/block/as-iosched.c --- 25/drivers/block/as-iosched.c~elv-insertion-fix 2003-09-01 11:13:29.000000000 -0700 +++ 25-akpm/drivers/block/as-iosched.c 2003-09-01 11:13:29.000000000 -0700 @@ -910,12 +910,7 @@ static void as_completed_request(request struct as_rq *arq = RQ_DATA(rq); struct as_io_context *aic; - if (unlikely(!blk_fs_request(rq))) - return; - - WARN_ON(blk_fs_request(rq) && arq->state == AS_RQ_NEW); - - if (arq->state != AS_RQ_DISPATCHED) + if (unlikely(arq->state != AS_RQ_DISPATCHED)) return; if (ad->changed_batch && ad->nr_dispatched == 1) { @@ -1035,7 +1030,7 @@ static void as_remove_request(request_qu { struct as_rq *arq = RQ_DATA(rq); - if (unlikely(!blk_fs_request(rq))) + if (unlikely(arq->state == AS_RQ_NEW)) return; if (!arq) { @@ -1341,9 +1336,9 @@ static void as_requeue_request(request_q atomic_inc(&arq->io_context->aic->nr_dispatched); } else WARN_ON(blk_fs_request(rq) - && (!(rq->flags & REQ_HARDBARRIER)) ); + && (!(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) ); - list_add_tail(&rq->queuelist, ad->dispatch); + list_add(&rq->queuelist, ad->dispatch); /* Stop anticipating - let this request get through */ as_antic_stop(ad); @@ -1358,26 +1353,31 @@ as_insert_request(request_queue_t *q, st struct as_data *ad = q->elevator.elevator_data; struct as_rq *arq = RQ_DATA(rq); - if (unlikely(rq->flags & REQ_HARDBARRIER)) { + if (unlikely(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) { q->last_merge = NULL; - while (ad->next_arq[REQ_SYNC]) - as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]); + if (insert_here != ad->dispatch) { + while (ad->next_arq[REQ_SYNC]) + as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]); + + while (ad->next_arq[REQ_ASYNC]) + as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]); + } - while (ad->next_arq[REQ_ASYNC]) - as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]); + if (!insert_here) + insert_here = ad->dispatch->prev; } if (unlikely(!blk_fs_request(rq))) { if (!insert_here) - insert_here = ad->dispatch->prev; + insert_here = ad->dispatch; + } + if (insert_here) { list_add(&rq->queuelist, insert_here); /* Stop anticipating - let this request get through */ - if (!list_empty(ad->dispatch) - && (ad->antic_status == ANTIC_WAIT_REQ - || ad->antic_status == ANTIC_WAIT_NEXT)) + if (list_empty(ad->dispatch)) as_antic_stop(ad); return; diff -puN drivers/block/deadline-iosched.c~elv-insertion-fix drivers/block/deadline-iosched.c --- 25/drivers/block/deadline-iosched.c~elv-insertion-fix 2003-09-01 11:13:29.000000000 -0700 +++ 25-akpm/drivers/block/deadline-iosched.c 2003-09-01 11:13:29.000000000 -0700 @@ -627,21 +627,25 @@ deadline_insert_request(request_queue_t struct deadline_data *dd = q->elevator.elevator_data; struct deadline_rq *drq = RQ_DATA(rq); - if (unlikely(rq->flags & REQ_HARDBARRIER)) { + if (unlikely(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) { DL_INVALIDATE_HASH(dd); q->last_merge = NULL; - while (deadline_dispatch_requests(dd)) - ; + if (insert_here != dd->dispatch) { + while (deadline_dispatch_requests(dd)) + ; + } - list_add_tail(&rq->queuelist, dd->dispatch); - return; + if (!insert_here) + insert_here = dd->dispatch->prev; } if (unlikely(!blk_fs_request(rq))) { if (!insert_here) - insert_here = dd->dispatch->prev; + insert_here = dd->dispatch; + } + if (insert_here) { list_add(&rq->queuelist, insert_here); return; } diff -puN drivers/block/elevator.c~elv-insertion-fix drivers/block/elevator.c --- 25/drivers/block/elevator.c~elv-insertion-fix 2003-09-01 11:13:29.000000000 -0700 +++ 25-akpm/drivers/block/elevator.c 2003-09-01 11:13:29.000000000 -0700 @@ -162,10 +162,10 @@ void elv_requeue_request(request_queue_t void __elv_add_request(request_queue_t *q, struct request *rq, int at_end, int plug) { - struct list_head *insert = &q->queue_head; + struct list_head *insert = NULL; - if (at_end) - insert = insert->prev; + if (!at_end) + insert = &q->queue_head; if (plug) blk_plug_device(q); _