don't close, binval on failed mount because already mounted.
[unix-history] / usr / src / sys / ufs / ffs / ufs_disksubr.c
index da5dcb2..232d579 100644 (file)
@@ -1,21 +1,43 @@
-/*     ufs_disksubr.c  3.2     %G%     */
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)ufs_disksubr.c      6.3 (Berkeley) %G%
+ */
 
 /*
 
 /*
- * generalized seek sort for disk
+ * Seek sort for disks.  We depend on the driver
+ * which calls us using b_resid as the current cylinder number.
+ *
+ * The argument dp structure holds a b_actf activity chain pointer
+ * on which we keep two queues, sorted in ascending cylinder order.
+ * The first queue holds those requests which are positioned after
+ * the current cylinder (in the first request); the second holds
+ * requests which came in after their cylinder 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.
  */
 
  */
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/buf.h"
+#include "param.h"
+#include "systm.h"
+#include "buf.h"
 
 #define        b_cylin b_resid
 
 disksort(dp, bp)
 
 #define        b_cylin b_resid
 
 disksort(dp, bp)
-register struct buf *dp, *bp;
+       register struct buf *dp, *bp;
 {
        register struct buf *ap;
 {
        register struct buf *ap;
-       struct buf *tp;
 
 
+       /*
+        * If nothing on the activity queue, then
+        * we become the only thing.
+        */
        ap = dp->b_actf;
        if(ap == NULL) {
                dp->b_actf = bp;
        ap = dp->b_actf;
        if(ap == NULL) {
                dp->b_actf = bp;
@@ -23,23 +45,64 @@ register struct buf *dp, *bp;
                bp->av_forw = NULL;
                return;
        }
                bp->av_forw = NULL;
                return;
        }
-       tp = NULL;
-       for(; ap != NULL; ap = ap->av_forw) {
-               if ((bp->b_flags&B_READ) && (ap->b_flags&B_READ) == 0) {
-                       if (tp == NULL)
-                               tp = ap;
-                       break;
+       /*
+        * 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_cylin < ap->b_cylin) {
+               while (ap->av_forw) {
+                       /*
+                        * Check for an ``inversion'' in the
+                        * normally ascending cylinder numbers,
+                        * indicating the start of the second request list.
+                        */
+                       if (ap->av_forw->b_cylin < ap->b_cylin) {
+                               /*
+                                * 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_cylin < ap->av_forw->b_cylin)
+                                               goto insert;
+                                       ap = ap->av_forw;
+                               } while (ap->av_forw);
+                               goto insert;            /* after last */
+                       }
+                       ap = ap->av_forw;
                }
                }
-               if ((bp->b_flags&B_READ) == 0 && (ap->b_flags&B_READ))
-                       continue;
-               if(ap->b_cylin <= bp->b_cylin)
-                       if(tp == NULL || ap->b_cylin >= tp->b_cylin)
-                               tp = ap;
+               /*
+                * 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 (ap->av_forw) {
+               /*
+                * 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 (ap->av_forw->b_cylin < ap->b_cylin ||
+                   bp->b_cylin < ap->av_forw->b_cylin)
+                       goto insert;
+               ap = ap->av_forw;
        }
        }
-       if(tp == NULL)
-               tp = dp->b_actl;
-       bp->av_forw = tp->av_forw;
-       tp->av_forw = bp;
-       if(tp == dp->b_actl)
+       /*
+        * 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:
+       bp->av_forw = ap->av_forw;
+       ap->av_forw = bp;
+       if (ap == dp->b_actl)
                dp->b_actl = bp;
 }
                dp->b_actl = bp;
 }