summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1997-09-21 22:10:49 +0000
committergibbs <gibbs@FreeBSD.org>1997-09-21 22:10:49 +0000
commitd135262f964d2b32c779fae2f1d4df9e893b882c (patch)
treea7f708576573ff887e676c340c0f682bea2c31d2 /sys/ufs
parent56f2bcb32f1fde52b375d829c522b8cb51369e96 (diff)
downloadFreeBSD-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.c133
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);
}
OpenPOWER on IntegriCloud