--- blkdev/drivers/block/ll_rw_blk.c.~1~ Mon Oct 23 21:52:09 2000 +++ blkdev/drivers/block/ll_rw_blk.c Tue Oct 24 01:00:36 2000 @@ -585,10 +585,9 @@ void make_request(int major, int rw, struct buffer_head * bh) { unsigned int sector, count; - struct request * req, * prev; + struct request * req, * prev, * freereq = NULL; int rw_ahead, max_req, max_sectors, max_segments; unsigned long flags; - int back, front; count = bh->b_size >> 9; sector = bh->b_rsector; @@ -667,6 +666,7 @@ max_sectors = get_max_sectors(bh->b_rdev); max_segments = get_max_segments(bh->b_rdev); + again: /* * Now we acquire the request spinlock, we have to be mega careful * not to schedule or do something nonatomic @@ -700,29 +700,23 @@ req = seek_to_not_starving_chunk(req); prev = NULL; - back = front = 0; do { if (req->cmd != rw) continue; if (req->rq_dev != bh->b_rdev) continue; - if (req->sector + req->nr_sectors == sector) - back = 1; - else if (req->sector - count == sector) - front = 1; - if (req->nr_sectors + count > max_sectors) continue; if (req->sem) continue; /* Can we add it to the end of this request? */ - if (back) { + if (req->sector + req->nr_sectors == sector) { if (req->bhtail->b_data + req->bhtail->b_size != bh->b_data) { if (req->nr_segments < max_segments) req->nr_segments++; - else break; + else continue; } req->bhtail->b_reqnext = bh; req->bhtail = bh; @@ -733,19 +727,19 @@ /* Can we now merge this req with the next? */ attempt_merge(req, max_sectors, max_segments); /* or to the beginning? */ - } else if (front) { + } else if (req->sector - count == sector) { /* * Check that we didn't seek on a starving request, * that could happen only at the first pass, thus * do that only if prev is NULL. */ if (!prev && ((req->cmd != READ && req->cmd != WRITE) || !req->elevator_latency)) - break; + continue; if (bh->b_data + bh->b_size != req->bh->b_data) { if (req->nr_segments < max_segments) req->nr_segments++; - else break; + else continue; } bh->b_reqnext = req->bh; req->bh = bh; @@ -765,15 +759,22 @@ continue; mark_buffer_clean(bh); + if (freereq) { + freereq->rq_status = RQ_INACTIVE; + wake_up(&wait_for_request); + } spin_unlock_irqrestore(&io_request_lock,flags); return; - } while (prev = req, - !front && !back && (req = req->next) != NULL); + } while (prev = req, (req = req->next) != NULL); } /* find an unused request. */ - req = get_request(max_req, bh->b_rdev); + if (freereq) { + req = freereq; + freereq = NULL; + } else + req = get_request(max_req, bh->b_rdev); spin_unlock_irqrestore(&io_request_lock,flags); @@ -781,7 +782,8 @@ if (!req) { if (rw_ahead) goto end_io; - req = __get_request_wait(max_req, bh->b_rdev); + freereq = __get_request_wait(max_req, bh->b_rdev); + goto again; } /* fill up the request-info, and add it to the queue */