summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ufs
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2000-04-02 19:08:05 +0000
committerphk <phk@FreeBSD.org>2000-04-02 19:08:05 +0000
commitf37bdf3ad759a1a7c2f5d9e22b035b7d5e4cf986 (patch)
tree96b413b4ed6fdfd5384f273b83cb4aad74e58dd2 /sys/ufs/ufs
parent6fa0b056f4d7bd22bab81ea7d5cf5ea523c12846 (diff)
downloadFreeBSD-src-f37bdf3ad759a1a7c2f5d9e22b035b7d5e4cf986.zip
FreeBSD-src-f37bdf3ad759a1a7c2f5d9e22b035b7d5e4cf986.tar.gz
Clone bio versions of certain bits of infrastructure:
devstat_end_transaction_bio() bioq_* versions of bufq_* incl bioqdisksort() the corresponding "buf" versions will disappear when no longer used. Move b_offset, b_data and b_bcount to struct bio. Add BIO_FORMAT as a hack for fd.c etc. We are now largely ready to start converting drivers to use struct bio instead of struct buf.
Diffstat (limited to 'sys/ufs/ufs')
-rw-r--r--sys/ufs/ufs/ufs_disksubr.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/sys/ufs/ufs/ufs_disksubr.c b/sys/ufs/ufs/ufs_disksubr.c
index fb2064a..551652f 100644
--- a/sys/ufs/ufs/ufs_disksubr.c
+++ b/sys/ufs/ufs/ufs_disksubr.c
@@ -160,6 +160,104 @@ bufqdisksort(bufq, bp)
}
+void
+bioqdisksort(bioq, bp)
+ struct bio_queue_head *bioq;
+ struct bio *bp;
+{
+ struct bio *bq;
+ struct bio *bn;
+ struct bio *be;
+
+ be = TAILQ_LAST(&bioq->queue, bio_queue);
+ /*
+ * If the queue is empty or we are an
+ * ordered transaction, then it's easy.
+ */
+ if ((bq = bioq_first(bioq)) == NULL
+ || (bp->bio_flags & BIO_ORDERED) != 0) {
+ bioq_insert_tail(bioq, bp);
+ return;
+ } else if (bioq->insert_point != NULL) {
+
+ /*
+ * A certain portion of the list is
+ * "locked" to preserve ordering, so
+ * we can only insert after the insert
+ * point.
+ */
+ bq = bioq->insert_point;
+ } else {
+
+ /*
+ * If we lie before the last removed (currently active)
+ * request, and are not inserting ourselves into the
+ * "locked" portion of the list, then we must add ourselves
+ * to the second request list.
+ */
+ if (bp->bio_pblkno < bioq->last_pblkno) {
+
+ bq = bioq->switch_point;
+ /*
+ * If we are starting a new secondary list,
+ * then it's easy.
+ */
+ if (bq == NULL) {
+ bioq->switch_point = bp;
+ bioq_insert_tail(bioq, bp);
+ return;
+ }
+ /*
+ * If we lie ahead of the current switch point,
+ * insert us before the switch point and move
+ * the switch point.
+ */
+ if (bp->bio_pblkno < bq->bio_pblkno) {
+ bioq->switch_point = bp;
+ TAILQ_INSERT_BEFORE(bq, bp, bio_queue);
+ return;
+ }
+ } else {
+ if (bioq->switch_point != NULL)
+ be = TAILQ_PREV(bioq->switch_point,
+ bio_queue, bio_queue);
+ /*
+ * If we lie between last_pblkno and bq,
+ * insert before bq.
+ */
+ if (bp->bio_pblkno < bq->bio_pblkno) {
+ TAILQ_INSERT_BEFORE(bq, bp, bio_queue);
+ return;
+ }
+ }
+ }
+
+ /*
+ * Request is at/after our current position in the list.
+ * Optimize for sequential I/O by seeing if we go at the tail.
+ */
+ if (bp->bio_pblkno > be->bio_pblkno) {
+ TAILQ_INSERT_AFTER(&bioq->queue, be, bp, bio_queue);
+ return;
+ }
+
+ /* Otherwise, insertion sort */
+ while ((bn = TAILQ_NEXT(bq, bio_queue)) != NULL) {
+
+ /*
+ * 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 == bioq->switch_point
+ || bp->bio_pblkno < bn->bio_pblkno)
+ break;
+ bq = bn;
+ }
+ TAILQ_INSERT_AFTER(&bioq->queue, bq, bp, bio_queue);
+}
+
+
/*
* Attempt to read a disk label from a device using the indicated strategy
* routine. The label must be partly set up before this: secpercyl, secsize
OpenPOWER on IntegriCloud