summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_disklabel.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1995-11-23 07:24:41 +0000
committerdyson <dyson@FreeBSD.org>1995-11-23 07:24:41 +0000
commit711711e9f3d02ef8f5958392d4774ca0baddadb9 (patch)
tree6a96e9d2332ea78c99473115ebf81d080f0536cd /sys/kern/subr_disklabel.c
parent262d14803690c3c8f394da8917b4a04d8f187c70 (diff)
downloadFreeBSD-src-711711e9f3d02ef8f5958392d4774ca0baddadb9.zip
FreeBSD-src-711711e9f3d02ef8f5958392d4774ca0baddadb9.tar.gz
Update the wd.c driver to use the new TAILQ scheme for device
buffer queue. Also, create a new subroutine 'tqdisksort' that is an improved version of the original disksort that also uses TAILQs.
Diffstat (limited to 'sys/kern/subr_disklabel.c')
-rw-r--r--sys/kern/subr_disklabel.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/sys/kern/subr_disklabel.c b/sys/kern/subr_disklabel.c
index be8e81a..3598a69 100644
--- a/sys/kern/subr_disklabel.c
+++ b/sys/kern/subr_disklabel.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94
- * $Id: ufs_disksubr.c,v 1.18 1995/08/28 16:09:11 bde Exp $
+ * $Id: ufs_disksubr.c,v 1.19 1995/09/16 17:04:06 bde Exp $
*/
#include <sys/param.h>
@@ -69,6 +69,99 @@
#define b_cylinder b_resid
void
+tqdisksort(ap, bp)
+ struct buf_queue_head *ap;
+ register struct buf *bp;
+{
+ register 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);
+ return;
+ }
+
+#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;
+ }
+ 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 (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;
+ }
+ /*
+ * No inversions... we will go after the last, and
+ * be the first request in the second request list.
+ */
+ goto insert;
+ }
+ /*
+ * Request is at/after the current request...
+ * sort in the first request list.
+ */
+ while (bn = bq->b_act.tqe_next) {
+ /*
+ * 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.
+ */
+ if (bn->b_pblkno < bq->b_pblkno ||
+ bp->b_pblkno < bn->b_pblkno)
+ goto insert;
+ 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);
+}
+
+void
disksort(ap, bp)
register struct buf *ap, *bp;
{
OpenPOWER on IntegriCloud