diff options
author | gibbs <gibbs@FreeBSD.org> | 1997-09-21 22:10:49 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 1997-09-21 22:10:49 +0000 |
commit | d135262f964d2b32c779fae2f1d4df9e893b882c (patch) | |
tree | a7f708576573ff887e676c340c0f682bea2c31d2 /sys/ufs | |
parent | 56f2bcb32f1fde52b375d829c522b8cb51369e96 (diff) | |
download | FreeBSD-src-d135262f964d2b32c779fae2f1d4df9e893b882c.zip FreeBSD-src-d135262f964d2b32c779fae2f1d4df9e893b882c.tar.gz |
Convert tqdisksort to bufqdisksort. Honor the B_ORDERED buffer flag
so that meta-data writes go out to the device in the right order.
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ufs/ufs_disksubr.c | 133 |
1 files changed, 56 insertions, 77 deletions
diff --git a/sys/ufs/ufs/ufs_disksubr.c b/sys/ufs/ufs/ufs_disksubr.c index abb14c7..0ca4f47 100644 --- a/sys/ufs/ufs/ufs_disksubr.c +++ b/sys/ufs/ufs/ufs_disksubr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94 - * $Id: ufs_disksubr.c,v 1.30 1997/02/22 09:47:45 peter Exp $ + * $Id: ufs_disksubr.c,v 1.31 1997/07/13 15:53:20 bde Exp $ */ #include <sys/param.h> @@ -50,109 +50,88 @@ /* * Seek sort for disks. * - * The argument ap structure holds a b_actf activity chain pointer on which we - * keep two queues, sorted in ascending block order. The first queue holds - * those requests which are positioned after the current block (in the first - * request); the second holds requests which came in after their block number - * was passed. Thus we implement a one way scan, retracting after reaching the - * end of the drive to the first request on the second queue, at which time it - * becomes the first queue. + * The buf_queue keep two queues, sorted in ascending block order. The first + * queue holds those requests which are positioned after the current block + * (in the first request); the second, which starts at queue->switch_point, + * holds requests which came in after their block number was passed. Thus + * we implement a one way scan, retracting after reaching the end of the drive + * to the first request on the second queue, at which time it becomes the + * first queue. * * A one-way scan is natural because of the way UNIX read-ahead blocks are * allocated. */ void -tqdisksort(ap, bp) - struct buf_queue_head *ap; - register struct buf *bp; +bufqdisksort(bufq, bp) + struct buf_queue_head *bufq; + struct buf *bp; { - register struct buf *bq; + struct buf *bq; struct buf *bn; - - /* If the queue is empty, then it's easy. */ - if ((bq = ap->tqh_first) == NULL) { - TAILQ_INSERT_HEAD(ap, bp, b_act); + int count; + + /* + * If the queue is empty or we are an + * ordered transaction, then it's easy. + */ + if ((bq = bufq_first(bufq)) == NULL + || (bp->b_flags & B_ORDERED) != 0) { + bufq_insert_tail(bufq, bp); return; - } + } else if (bufq->insert_point != NULL) { -#if 1 - /* Put new writes after all reads */ - if ((bp->b_flags & B_READ) == 0) { - while (bn = bq->b_act.tqe_next) { - if ((bq->b_flags & B_READ) == 0) - break; - bq = bn; - } - } else { - while (bn = bq->b_act.tqe_next) { - if ((bq->b_flags & B_READ) == 0) { - if (ap->tqh_first != bq) { - bq = *bq->b_act.tqe_prev; - } - break; - } - bq = bn; + /* + * A certain portion of the list is + * "locked" to preserve ordering, so + * we can only insert after the insert + * point. + */ + bq = TAILQ_NEXT(bufq->insert_point, b_act); + if (bq == NULL) { + bufq_insert_tail(bufq, bp); + return; } - goto insert; } -#endif /* - * If we lie after the first (currently active) request, then we - * must locate the second request list and add ourselves to it. + * If we lie before the first (currently active) request, then we + * must add ourselves to the second request list. */ if (bp->b_pblkno < bq->b_pblkno) { - while (bn = bq->b_act.tqe_next) { - /* - * Check for an ``inversion'' in the normally ascending - * cylinder numbers, indicating the start of the second - * request list. - */ - if (bn->b_pblkno < bq->b_pblkno) { - /* - * Search the second request list for the first - * request at a larger cylinder number. We go - * before that; if there is no such request, we - * go at end. - */ - do { - if (bp->b_pblkno < bn->b_pblkno) - goto insert; - bq = bn; - } while (bn = bq->b_act.tqe_next); - goto insert; /* after last */ - } - bq = bn; - } + + bq = bufq->switch_point; /* - * No inversions... we will go after the last, and - * be the first request in the second request list. + * If we are starting a new secondary list, then it's easy. */ - goto insert; + if (bq == NULL) { + bufq->switch_point = bp; + bufq_insert_tail(bufq, bp); + return; + } + if (bp->b_pblkno < bq->b_pblkno) { + bufq->switch_point = bp; + TAILQ_INSERT_BEFORE(bq, bp, b_act); + return; + } } /* * Request is at/after the current request... * sort in the first request list. */ - while (bn = bq->b_act.tqe_next) { + while ((bn = TAILQ_NEXT(bq, b_act)) != NULL) { + /* - * We want to go after the current request if there is an - * inversion after it (i.e. it is the end of the first - * request list), or if the next request is a larger cylinder - * than our request. + * We want to go after the current request if it is the end + * of the first request list, or if the next request is a + * larger cylinder than our request. */ - if (bn->b_pblkno < bq->b_pblkno || - bp->b_pblkno < bn->b_pblkno) - goto insert; + if (bn == bufq->switch_point + || bp->b_pblkno < bn->b_pblkno) + break; bq = bn; } - /* - * Neither a second list nor a larger request... we go at the end of - * the first list, which is the same as the end of the whole schebang. - */ -insert: - TAILQ_INSERT_AFTER(ap, bq, bp, b_act); + TAILQ_INSERT_AFTER(&bufq->queue, bq, bp, b_act); } |