The problem is that a task completes a read and then submits a write. But it still has readahead in flight. We start anticipation on the back of that readahead, but fail to notice that this task has just submitted a write. block/as-iosched.c | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff -puN drivers/block/as-iosched.c~as-break-if-readahead drivers/block/as-iosched.c --- 25/drivers/block/as-iosched.c~as-break-if-readahead 2003-02-23 22:39:06.000000000 -0800 +++ 25-akpm/drivers/block/as-iosched.c 2003-02-23 22:39:06.000000000 -0800 @@ -750,14 +750,14 @@ elevator_wrap: } /* - * as_antic_req returns true if we have been anticipating this request. + * as_break_anticipation returns true if we have been anticipating this request. * * It also returns true if the process against which we are anticipating * submits a write - that's presumably an fsync, O_SYNC write, etc. We want to * dispatch it ASAP, because we know that application will not be submitting * any new reads. */ -static int as_antic_req(struct as_data *ad, struct as_rq *arq) +static int as_break_anticipation(struct as_data *ad, struct as_rq *arq) { if (rq_data_dir(arq->request) == READ && as_close_req(ad, arq)) { ant_stats.close_requests++; @@ -794,7 +794,8 @@ static void as_update_arq(struct as_data * or does it come from the same process as the one we are anticipating * for? */ - if (ad->antic_status != ANTIC_OFF && as_antic_req(ad, arq)) { + if (ad->antic_status != ANTIC_FINISHED + && as_break_anticipation(ad, arq)) { sector_t last = ad->last_sector[data_dir]; sector_t this = arq->request->sector; unsigned long delay = jiffies - ad->antic_start; @@ -821,10 +822,12 @@ static void as_update_arq(struct as_data else ant_stats.lba_forward_offsets[log2]++; } - del_timer(&ad->antic_timer); + if (ad->antic_status == ANTIC_WAIT) { + del_timer(&ad->antic_timer); + blk_remove_plug(arq->request->q); + schedule_work(&ad->antic_work); + } ad->antic_status = ANTIC_FINISHED; - blk_remove_plug(arq->request->q); - schedule_work(&ad->antic_work); } } @@ -852,7 +855,7 @@ static int can_start_anticipation(struct return 0; } - if (arq && as_antic_req(ad, arq)) + if (arq && as_break_anticipation(ad, arq)) /* * This request is a good candidate. Don't keep anticipating, * run it. _