From: Jens Axboe It seems that a request sometimes has lost its direction bit at the very end of its life cycle, at least that's the only thing that can explain the bug report from wli. This patch caches this info in the crq so it'll never be a problem for any driver. Signed-off-by: Jens Axboe Signed-off-by: Andrew Morton --- 25-akpm/drivers/block/cfq-iosched.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff -puN drivers/block/cfq-iosched.c~cfq-fix-allocated-counts drivers/block/cfq-iosched.c --- 25/drivers/block/cfq-iosched.c~cfq-fix-allocated-counts 2004-09-15 23:04:11.719638464 -0700 +++ 25-akpm/drivers/block/cfq-iosched.c 2004-09-15 23:04:11.724637704 -0700 @@ -193,6 +193,7 @@ struct cfq_rq { unsigned int in_flight : 1; unsigned int accounted : 1; unsigned int is_sync : 1; + unsigned int is_write : 1; }; static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned long); @@ -1381,7 +1382,6 @@ static void cfq_put_request(request_queu { struct cfq_data *cfqd = q->elevator.elevator_data; struct cfq_rq *crq = RQ_DATA(rq); - const int rw = rq_data_dir(rq); if (crq) { struct cfq_queue *cfqq = crq->cfq_queue; @@ -1392,12 +1392,12 @@ static void cfq_put_request(request_queu if (crq->io_context) put_io_context(crq->io_context->ioc); + BUG_ON(!cfqq->allocated[crq->is_write]); + cfqq->allocated[crq->is_write]--; + mempool_free(crq, cfqd->crq_pool); rq->elevator_private = NULL; - BUG_ON(!cfqq->allocated[rw]); - cfqq->allocated[rw]--; - smp_mb(); cfq_check_waiters(q, cfqq); cfq_put_queue(cfqq); @@ -1454,6 +1454,7 @@ static int cfq_set_request(request_queue crq->io_context = cic; crq->service_start = crq->queue_start = 0; crq->in_flight = crq->accounted = crq->is_sync = 0; + crq->is_write = rw; rq->elevator_private = crq; cfqq->allocated[rw]++; cfqq->alloc_limit[rw] = 0; _