Commit b9d8a459 authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

[PATCH] AS fix

This picks up another place where aliases where getting lost.  And adds
a couple of checks.  I can't hang the osdl database thingy anymore.

The transfer alias list loops could probably quite nicely be changed to

	if (unlikely(!list_empty( old_queuelist )))
	    __list_splice( old_queuelist, new_queuelist.prev);
parent 611fe944
...@@ -914,6 +914,8 @@ static void as_completed_request(request_queue_t *q, struct request *rq) ...@@ -914,6 +914,8 @@ static void as_completed_request(request_queue_t *q, struct request *rq)
struct as_rq *arq = RQ_DATA(rq); struct as_rq *arq = RQ_DATA(rq);
struct as_io_context *aic; struct as_io_context *aic;
WARN_ON(!list_empty(&rq->queuelist));
if (unlikely(arq->state != AS_RQ_DISPATCHED)) if (unlikely(arq->state != AS_RQ_DISPATCHED))
return; return;
...@@ -926,6 +928,7 @@ static void as_completed_request(request_queue_t *q, struct request *rq) ...@@ -926,6 +928,7 @@ static void as_completed_request(request_queue_t *q, struct request *rq)
if (ad->batch_data_dir == REQ_SYNC) if (ad->batch_data_dir == REQ_SYNC)
ad->new_batch = 1; ad->new_batch = 1;
} }
WARN_ON(ad->nr_dispatched == 0);
ad->nr_dispatched--; ad->nr_dispatched--;
/* /*
...@@ -1140,8 +1143,6 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq) ...@@ -1140,8 +1143,6 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
/* /*
* take it off the sort and fifo list, add to dispatch queue * take it off the sort and fifo list, add to dispatch queue
*/ */
as_remove_queued_request(ad->q, rq);
insert = ad->dispatch->prev; insert = ad->dispatch->prev;
while (!list_empty(&rq->queuelist)) { while (!list_empty(&rq->queuelist)) {
...@@ -1159,6 +1160,7 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq) ...@@ -1159,6 +1160,7 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
ad->nr_dispatched++; ad->nr_dispatched++;
} }
as_remove_queued_request(ad->q, rq);
list_add(&rq->queuelist, insert); list_add(&rq->queuelist, insert);
if (arq->io_context && arq->io_context->aic) if (arq->io_context && arq->io_context->aic)
atomic_inc(&arq->io_context->aic->nr_dispatched); atomic_inc(&arq->io_context->aic->nr_dispatched);
...@@ -1325,12 +1327,27 @@ static struct request *as_next_request(request_queue_t *q) ...@@ -1325,12 +1327,27 @@ static struct request *as_next_request(request_queue_t *q)
static inline void static inline void
as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alias) as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alias)
{ {
struct request *req = arq->request;
struct list_head *insert = alias->request->queuelist.prev;
/*
* Transfer list of aliases
*/
while (!list_empty(&req->queuelist)) {
struct request *__rq = list_entry_rq(req->queuelist.next);
struct as_rq *__arq = RQ_DATA(__rq);
list_move_tail(&__rq->queuelist, &alias->request->queuelist);
WARN_ON(__arq->state != AS_RQ_QUEUED);
}
/* /*
* Another request with the same start sector on the rbtree. * Another request with the same start sector on the rbtree.
* Link this request to that sector. They are untangled in * Link this request to that sector. They are untangled in
* as_move_to_dispatch * as_move_to_dispatch
*/ */
list_add_tail(&arq->request->queuelist, &alias->request->queuelist); list_add(&arq->request->queuelist, insert);
/* /*
* Don't want to have to handle merges. * Don't want to have to handle merges.
...@@ -1390,9 +1407,6 @@ static void as_add_request(struct as_data *ad, struct as_rq *arq) ...@@ -1390,9 +1407,6 @@ static void as_add_request(struct as_data *ad, struct as_rq *arq)
} }
} }
arq->state = AS_RQ_QUEUED; arq->state = AS_RQ_QUEUED;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment