root/dev/raidframe/rf_sstf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rf_do_sstf_ord_q
  2. rf_closest_to_arm
  3. rf_SstfCreate
  4. rf_ScanCreate
  5. rf_CscanCreate
  6. rf_SstfEnqueue
  7. rf_do_dequeue
  8. rf_SstfDequeue
  9. rf_ScanDequeue
  10. rf_CscanDequeue
  11. rf_SstfPeek
  12. rf_ScanPeek
  13. rf_CscanPeek
  14. rf_SstfPromote

    1 /*      $OpenBSD: rf_sstf.c,v 1.4 2002/12/16 07:01:05 tdeval Exp $      */
    2 /*      $NetBSD: rf_sstf.c,v 1.4 2000/01/08 23:45:05 oster Exp $        */
    3 
    4 /*
    5  * Copyright (c) 1995 Carnegie-Mellon University.
    6  * All rights reserved.
    7  *
    8  * Author: Jim Zelenka
    9  *
   10  * Permission to use, copy, modify and distribute this software and
   11  * its documentation is hereby granted, provided that both the copyright
   12  * notice and this permission notice appear in all copies of the
   13  * software, derivative works or modified versions, and any portions
   14  * thereof, and that both notices appear in supporting documentation.
   15  *
   16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
   18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   19  *
   20  * Carnegie Mellon requests users of this software to return to
   21  *
   22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   23  *  School of Computer Science
   24  *  Carnegie Mellon University
   25  *  Pittsburgh PA 15213-3890
   26  *
   27  * any improvements or extensions that they make and grant Carnegie the
   28  * rights to redistribute these changes.
   29  */
   30 
   31 /*****************************************************************************
   32  *
   33  * sstf.c --  Prioritized shortest seek time first disk queueing code.
   34  *
   35  *****************************************************************************/
   36 
   37 #include "rf_alloclist.h"
   38 #include "rf_stripelocks.h"
   39 #include "rf_layout.h"
   40 #include "rf_diskqueue.h"
   41 #include "rf_sstf.h"
   42 #include "rf_debugMem.h"
   43 #include "rf_general.h"
   44 #include "rf_options.h"
   45 #include "rf_raid.h"
   46 #include "rf_types.h"
   47 
   48 #define DIR_LEFT        1
   49 #define DIR_RIGHT       2
   50 #define DIR_EITHER      3
   51 
   52 #define SNUM_DIFF(_a_,_b_)                                              \
   53         (((_a_) > (_b_)) ? ((_a_) - (_b_)) : ((_b_) - (_a_)))
   54 
   55 #define QSUM(_sstfq_)                                                   \
   56         (((_sstfq_)->lopri.qlen) + ((_sstfq_)->left.qlen) +             \
   57          ((_sstfq_)->right.qlen))
   58 
   59 
   60 void rf_do_sstf_ord_q(RF_DiskQueueData_t **, RF_DiskQueueData_t **,
   61         RF_DiskQueueData_t *);
   62 void rf_do_dequeue(RF_SstfQ_t *, RF_DiskQueueData_t *);
   63 RF_DiskQueueData_t *rf_closest_to_arm(RF_SstfQ_t *, RF_SectorNum_t,
   64         int *, int);
   65 
   66 
   67 void
   68 rf_do_sstf_ord_q(RF_DiskQueueData_t **queuep, RF_DiskQueueData_t **tailp,
   69     RF_DiskQueueData_t *req)
   70 {
   71         RF_DiskQueueData_t *r, *s;
   72 
   73         if (*queuep == NULL) {
   74                 *queuep = req;
   75                 *tailp = req;
   76                 req->next = NULL;
   77                 req->prev = NULL;
   78                 return;
   79         }
   80         if (req->sectorOffset <= (*queuep)->sectorOffset) {
   81                 req->next = *queuep;
   82                 req->prev = NULL;
   83                 (*queuep)->prev = req;
   84                 *queuep = req;
   85                 return;
   86         }
   87         if (req->sectorOffset > (*tailp)->sectorOffset) {
   88                 /* Optimization. */
   89                 r = NULL;
   90                 s = *tailp;
   91                 goto q_at_end;
   92         }
   93         for (s = NULL, r = *queuep; r; s = r, r = r->next) {
   94                 if (r->sectorOffset >= req->sectorOffset) {
   95                         /* Insert after s, before r. */
   96                         RF_ASSERT(s);
   97                         req->next = r;
   98                         r->prev = req;
   99                         s->next = req;
  100                         req->prev = s;
  101                         return;
  102                 }
  103         }
  104 q_at_end:
  105         /* Insert after s, at end of queue. */
  106         RF_ASSERT(r == NULL);
  107         RF_ASSERT(s);
  108         RF_ASSERT(s == (*tailp));
  109         req->next = NULL;
  110         req->prev = s;
  111         s->next = req;
  112         *tailp = req;
  113 }
  114 
  115 /* For removing from head-of-queue. */
  116 #define DO_HEAD_DEQ(_r_,_q_)                                            \
  117 do {                                                                    \
  118         _r_ = (_q_)->queue;                                             \
  119         RF_ASSERT((_r_) != NULL);                                       \
  120         (_q_)->queue = (_r_)->next;                                     \
  121         (_q_)->qlen--;                                                  \
  122         if ((_q_)->qlen == 0) {                                         \
  123                 RF_ASSERT((_r_) == (_q_)->qtail);                       \
  124                 RF_ASSERT((_q_)->queue == NULL);                        \
  125                 (_q_)->qtail = NULL;                                    \
  126         } else {                                                        \
  127                 RF_ASSERT((_q_)->queue->prev == (_r_));                 \
  128                 (_q_)->queue->prev = NULL;                              \
  129         }                                                               \
  130 } while (0)
  131 
  132 /* For removing from end-of-queue. */
  133 #define DO_TAIL_DEQ(_r_,_q_)                                            \
  134 do {                                                                    \
  135         _r_ = (_q_)->qtail;                                             \
  136         RF_ASSERT((_r_) != NULL);                                       \
  137         (_q_)->qtail = (_r_)->prev;                                     \
  138         (_q_)->qlen--;                                                  \
  139         if ((_q_)->qlen == 0) {                                         \
  140                 RF_ASSERT((_r_) == (_q_)->queue);                       \
  141                 RF_ASSERT((_q_)->qtail == NULL);                        \
  142                 (_q_)->queue = NULL;                                    \
  143         } else {                                                        \
  144                 RF_ASSERT((_q_)->qtail->next == (_r_));                 \
  145                 (_q_)->qtail->next = NULL;                              \
  146         }                                                               \
  147 } while (0)
  148 
  149 #define DO_BEST_DEQ(_l_,_r_,_q_)                                        \
  150 do {                                                                    \
  151         if (SNUM_DIFF((_q_)->queue->sectorOffset,_l_)                   \
  152                 < SNUM_DIFF((_q_)->qtail->sectorOffset,_l_))            \
  153         {                                                               \
  154                 DO_HEAD_DEQ(_r_,_q_);                                   \
  155         } else {                                                        \
  156                 DO_TAIL_DEQ(_r_,_q_);                                   \
  157         }                                                               \
  158 } while (0)
  159 
  160 RF_DiskQueueData_t *
  161 rf_closest_to_arm(RF_SstfQ_t *queue, RF_SectorNum_t arm_pos, int *dir,
  162     int allow_reverse)
  163 {
  164         RF_SectorNum_t best_pos_l = 0, this_pos_l = 0, last_pos = 0;
  165         RF_SectorNum_t best_pos_r = 0, this_pos_r = 0;
  166         RF_DiskQueueData_t *r, *best_l, *best_r;
  167 
  168         best_r = best_l = NULL;
  169         for (r = queue->queue; r; r = r->next) {
  170                 if (r->sectorOffset < arm_pos) {
  171                         if (best_l == NULL) {
  172                                 best_l = r;
  173                                 last_pos = best_pos_l = this_pos_l;
  174                         } else {
  175                                 this_pos_l = arm_pos - r->sectorOffset;
  176                                 if (this_pos_l < best_pos_l) {
  177                                         best_l = r;
  178                                         last_pos = best_pos_l = this_pos_l;
  179                                 } else {
  180                                         last_pos = this_pos_l;
  181                                 }
  182                         }
  183                 } else {
  184                         if (best_r == NULL) {
  185                                 best_r = r;
  186                                 last_pos = best_pos_r = this_pos_r;
  187                         } else {
  188                                 this_pos_r = r->sectorOffset - arm_pos;
  189                                 if (this_pos_r < best_pos_r) {
  190                                         best_r = r;
  191                                         last_pos = best_pos_r = this_pos_r;
  192                                 } else {
  193                                         last_pos = this_pos_r;
  194                                 }
  195                                 if (this_pos_r > last_pos) {
  196                                         /* Getting farther away. */
  197                                         break;
  198                                 }
  199                         }
  200                 }
  201         }
  202         if ((best_r == NULL) && (best_l == NULL))
  203                 return (NULL);
  204         if ((*dir == DIR_RIGHT) && best_r)
  205                 return (best_r);
  206         if ((*dir == DIR_LEFT) && best_l)
  207                 return (best_l);
  208         if (*dir == DIR_EITHER) {
  209                 if (best_l == NULL)
  210                         return (best_r);
  211                 if (best_r == NULL)
  212                         return (best_l);
  213                 if (best_pos_r < best_pos_l)
  214                         return (best_r);
  215                 else
  216                         return (best_l);
  217         }
  218         /*
  219          * Nothing in the direction we want to go. Reverse or
  220          * reset the arm. We know we have an I/O in the other
  221          * direction.
  222          */
  223         if (allow_reverse) {
  224                 if (*dir == DIR_RIGHT) {
  225                         *dir = DIR_LEFT;
  226                         return (best_l);
  227                 } else {
  228                         *dir = DIR_RIGHT;
  229                         return (best_r);
  230                 }
  231         }
  232         /*
  233          * Reset (beginning of queue).
  234          */
  235         RF_ASSERT(*dir == DIR_RIGHT);
  236         return (queue->queue);
  237 }
  238 
  239 void *
  240 rf_SstfCreate(RF_SectorCount_t sect_per_disk, RF_AllocListElem_t *cl_list,
  241     RF_ShutdownList_t **listp)
  242 {
  243         RF_Sstf_t *sstfq;
  244 
  245         RF_CallocAndAdd(sstfq, 1, sizeof(RF_Sstf_t), (RF_Sstf_t *), cl_list);
  246         sstfq->dir = DIR_EITHER;
  247         sstfq->allow_reverse = 1;
  248         return ((void *) sstfq);
  249 }
  250 
  251 void *
  252 rf_ScanCreate(RF_SectorCount_t sect_per_disk, RF_AllocListElem_t *cl_list,
  253     RF_ShutdownList_t **listp)
  254 {
  255         RF_Sstf_t *scanq;
  256 
  257         RF_CallocAndAdd(scanq, 1, sizeof(RF_Sstf_t), (RF_Sstf_t *), cl_list);
  258         scanq->dir = DIR_RIGHT;
  259         scanq->allow_reverse = 1;
  260         return ((void *) scanq);
  261 }
  262 
  263 void *
  264 rf_CscanCreate(RF_SectorCount_t sect_per_disk, RF_AllocListElem_t *cl_list,
  265     RF_ShutdownList_t **listp)
  266 {
  267         RF_Sstf_t *cscanq;
  268 
  269         RF_CallocAndAdd(cscanq, 1, sizeof(RF_Sstf_t), (RF_Sstf_t *), cl_list);
  270         cscanq->dir = DIR_RIGHT;
  271         return ((void *) cscanq);
  272 }
  273 
  274 void
  275 rf_SstfEnqueue(void *qptr, RF_DiskQueueData_t *req, int priority)
  276 {
  277         RF_Sstf_t *sstfq;
  278 
  279         sstfq = (RF_Sstf_t *) qptr;
  280 
  281         if (priority == RF_IO_LOW_PRIORITY) {
  282                 if (rf_sstfDebug || rf_scanDebug || rf_cscanDebug) {
  283                         RF_DiskQueue_t *dq;
  284                         dq = (RF_DiskQueue_t *) req->queue;
  285                         printf("raid%d: ENQ lopri %d,%d queues are %d,%d,%d.\n",
  286                                req->raidPtr->raidid, dq->row, dq->col,
  287                                sstfq->left.qlen, sstfq->right.qlen,
  288                                sstfq->lopri.qlen);
  289                 }
  290                 rf_do_sstf_ord_q(&sstfq->lopri.queue, &sstfq->lopri.qtail, req);
  291                 sstfq->lopri.qlen++;
  292         } else {
  293                 if (req->sectorOffset < sstfq->last_sector) {
  294                         rf_do_sstf_ord_q(&sstfq->left.queue,
  295                             &sstfq->left.qtail, req);
  296                         sstfq->left.qlen++;
  297                 } else {
  298                         rf_do_sstf_ord_q(&sstfq->right.queue,
  299                             &sstfq->right.qtail, req);
  300                         sstfq->right.qlen++;
  301                 }
  302         }
  303 }
  304 
  305 void
  306 rf_do_dequeue(RF_SstfQ_t *queue, RF_DiskQueueData_t *req)
  307 {
  308         RF_DiskQueueData_t *req2;
  309 
  310         if (rf_sstfDebug || rf_scanDebug || rf_cscanDebug) {
  311                 printf("raid%d: rf_do_dequeue.\n", req->raidPtr->raidid);
  312         }
  313         if (req == queue->queue) {
  314                 DO_HEAD_DEQ(req2, queue);
  315                 RF_ASSERT(req2 == req);
  316         } else
  317                 if (req == queue->qtail) {
  318                         DO_TAIL_DEQ(req2, queue);
  319                         RF_ASSERT(req2 == req);
  320                 } else {
  321                         /* Dequeue from middle of list. */
  322                         RF_ASSERT(req->next);
  323                         RF_ASSERT(req->prev);
  324                         queue->qlen--;
  325                         req->next->prev = req->prev;
  326                         req->prev->next = req->next;
  327                         req->next = req->prev = NULL;
  328                 }
  329 }
  330 
  331 RF_DiskQueueData_t *
  332 rf_SstfDequeue(void *qptr)
  333 {
  334         RF_DiskQueueData_t *req = NULL;
  335         RF_Sstf_t *sstfq;
  336 
  337         sstfq = (RF_Sstf_t *) qptr;
  338 
  339         if (rf_sstfDebug) {
  340                 RF_DiskQueue_t *dq;
  341                 dq = (RF_DiskQueue_t *) req->queue;
  342                 RF_ASSERT(QSUM(sstfq) == dq->queueLength);
  343                 printf("raid%d: sstf: Dequeue %d,%d queues are %d,%d,%d.\n",
  344                        req->raidPtr->raidid, dq->row, dq->col,
  345                        sstfq->left.qlen, sstfq->right.qlen, sstfq->lopri.qlen);
  346         }
  347         if (sstfq->left.queue == NULL) {
  348                 RF_ASSERT(sstfq->left.qlen == 0);
  349                 if (sstfq->right.queue == NULL) {
  350                         RF_ASSERT(sstfq->right.qlen == 0);
  351                         if (sstfq->lopri.queue == NULL) {
  352                                 RF_ASSERT(sstfq->lopri.qlen == 0);
  353                                 return (NULL);
  354                         }
  355                         if (rf_sstfDebug) {
  356                                 printf("raid%d: sstf: check for close lopri.\n",
  357                                        req->raidPtr->raidid);
  358                         }
  359                         req = rf_closest_to_arm(&sstfq->lopri,
  360                             sstfq->last_sector, &sstfq->dir,
  361                             sstfq->allow_reverse);
  362                         if (rf_sstfDebug) {
  363                                 printf("raid%d: sstf: rf_closest_to_arm said"
  364                                        " %lx.\n", req->raidPtr->raidid,
  365                                        (long) req);
  366                         }
  367                         if (req == NULL)
  368                                 return (NULL);
  369                         rf_do_dequeue(&sstfq->lopri, req);
  370                 } else {
  371                         DO_BEST_DEQ(sstfq->last_sector, req, &sstfq->right);
  372                 }
  373         } else {
  374                 if (sstfq->right.queue == NULL) {
  375                         RF_ASSERT(sstfq->right.qlen == 0);
  376                         DO_BEST_DEQ(sstfq->last_sector, req, &sstfq->left);
  377                 } else {
  378                         if (SNUM_DIFF(sstfq->last_sector,
  379                              sstfq->right.queue->sectorOffset) <
  380                             SNUM_DIFF(sstfq->last_sector,
  381                              sstfq->left.qtail->sectorOffset)) {
  382                                 DO_HEAD_DEQ(req, &sstfq->right);
  383                         } else {
  384                                 DO_TAIL_DEQ(req, &sstfq->left);
  385                         }
  386                 }
  387         }
  388         RF_ASSERT(req);
  389         sstfq->last_sector = req->sectorOffset;
  390         return (req);
  391 }
  392 
  393 RF_DiskQueueData_t *
  394 rf_ScanDequeue(void *qptr)
  395 {
  396         RF_DiskQueueData_t *req = NULL;
  397         RF_Sstf_t *scanq;
  398 
  399         scanq = (RF_Sstf_t *) qptr;
  400 
  401         if (rf_scanDebug) {
  402                 RF_DiskQueue_t *dq;
  403                 dq = (RF_DiskQueue_t *) req->queue;
  404                 RF_ASSERT(QSUM(scanq) == dq->queueLength);
  405                 printf("raid%d: scan: Dequeue %d,%d queues are %d,%d,%d.\n",
  406                        req->raidPtr->raidid, dq->row, dq->col,
  407                        scanq->left.qlen, scanq->right.qlen, scanq->lopri.qlen);
  408         }
  409         if (scanq->left.queue == NULL) {
  410                 RF_ASSERT(scanq->left.qlen == 0);
  411                 if (scanq->right.queue == NULL) {
  412                         RF_ASSERT(scanq->right.qlen == 0);
  413                         if (scanq->lopri.queue == NULL) {
  414                                 RF_ASSERT(scanq->lopri.qlen == 0);
  415                                 return (NULL);
  416                         }
  417                         req = rf_closest_to_arm(&scanq->lopri,
  418                             scanq->last_sector, &scanq->dir,
  419                             scanq->allow_reverse);
  420                         if (req == NULL)
  421                                 return (NULL);
  422                         rf_do_dequeue(&scanq->lopri, req);
  423                 } else {
  424                         scanq->dir = DIR_RIGHT;
  425                         DO_HEAD_DEQ(req, &scanq->right);
  426                 }
  427         } else
  428                 if (scanq->right.queue == NULL) {
  429                         RF_ASSERT(scanq->right.qlen == 0);
  430                         RF_ASSERT(scanq->left.queue);
  431                         scanq->dir = DIR_LEFT;
  432                         DO_TAIL_DEQ(req, &scanq->left);
  433                 } else {
  434                         RF_ASSERT(scanq->right.queue);
  435                         RF_ASSERT(scanq->left.queue);
  436                         if (scanq->dir == DIR_RIGHT) {
  437                                 DO_HEAD_DEQ(req, &scanq->right);
  438                         } else {
  439                                 DO_TAIL_DEQ(req, &scanq->left);
  440                         }
  441                 }
  442         RF_ASSERT(req);
  443         scanq->last_sector = req->sectorOffset;
  444         return (req);
  445 }
  446 
  447 RF_DiskQueueData_t *
  448 rf_CscanDequeue(void *qptr)
  449 {
  450         RF_DiskQueueData_t *req = NULL;
  451         RF_Sstf_t *cscanq;
  452 
  453         cscanq = (RF_Sstf_t *) qptr;
  454 
  455         RF_ASSERT(cscanq->dir == DIR_RIGHT);
  456         if (rf_cscanDebug) {
  457                 RF_DiskQueue_t *dq;
  458                 dq = (RF_DiskQueue_t *) req->queue;
  459                 RF_ASSERT(QSUM(cscanq) == dq->queueLength);
  460                 printf("raid%d: scan: Dequeue %d,%d queues are %d,%d,%d.\n",
  461                        req->raidPtr->raidid, dq->row, dq->col,
  462                        cscanq->left.qlen, cscanq->right.qlen,
  463                        cscanq->lopri.qlen);
  464         }
  465         if (cscanq->right.queue) {
  466                 DO_HEAD_DEQ(req, &cscanq->right);
  467         } else {
  468                 RF_ASSERT(cscanq->right.qlen == 0);
  469                 if (cscanq->left.queue == NULL) {
  470                         RF_ASSERT(cscanq->left.qlen == 0);
  471                         if (cscanq->lopri.queue == NULL) {
  472                                 RF_ASSERT(cscanq->lopri.qlen == 0);
  473                                 return (NULL);
  474                         }
  475                         req = rf_closest_to_arm(&cscanq->lopri,
  476                             cscanq->last_sector, &cscanq->dir,
  477                             cscanq->allow_reverse);
  478                         if (req == NULL)
  479                                 return (NULL);
  480                         rf_do_dequeue(&cscanq->lopri, req);
  481                 } else {
  482                         /*
  483                          * There's I/Os to the left of the arm. Swing
  484                          * on back (swap queues).
  485                          */
  486                         cscanq->right = cscanq->left;
  487                         cscanq->left.qlen = 0;
  488                         cscanq->left.queue = cscanq->left.qtail = NULL;
  489                         DO_HEAD_DEQ(req, &cscanq->right);
  490                 }
  491         }
  492         RF_ASSERT(req);
  493         cscanq->last_sector = req->sectorOffset;
  494         return (req);
  495 }
  496 
  497 RF_DiskQueueData_t *
  498 rf_SstfPeek(void *qptr)
  499 {
  500         RF_DiskQueueData_t *req;
  501         RF_Sstf_t *sstfq;
  502 
  503         sstfq = (RF_Sstf_t *) qptr;
  504 
  505         if ((sstfq->left.queue == NULL) && (sstfq->right.queue == NULL)) {
  506                 req = rf_closest_to_arm(&sstfq->lopri, sstfq->last_sector,
  507                     &sstfq->dir, sstfq->allow_reverse);
  508         } else {
  509                 if (sstfq->left.queue == NULL)
  510                         req = sstfq->right.queue;
  511                 else {
  512                         if (sstfq->right.queue == NULL)
  513                                 req = sstfq->left.queue;
  514                         else {
  515                                 if (SNUM_DIFF(sstfq->last_sector,
  516                                      sstfq->right.queue->sectorOffset) <
  517                                     SNUM_DIFF(sstfq->last_sector,
  518                                      sstfq->left.qtail->sectorOffset)) {
  519                                         req = sstfq->right.queue;
  520                                 } else {
  521                                         req = sstfq->left.qtail;
  522                                 }
  523                         }
  524                 }
  525         }
  526         if (req == NULL) {
  527                 RF_ASSERT(QSUM(sstfq) == 0);
  528         }
  529         return (req);
  530 }
  531 
  532 RF_DiskQueueData_t *
  533 rf_ScanPeek(void *qptr)
  534 {
  535         RF_DiskQueueData_t *req;
  536         RF_Sstf_t *scanq;
  537         int dir;
  538 
  539         scanq = (RF_Sstf_t *) qptr;
  540         dir = scanq->dir;
  541 
  542         if (scanq->left.queue == NULL) {
  543                 RF_ASSERT(scanq->left.qlen == 0);
  544                 if (scanq->right.queue == NULL) {
  545                         RF_ASSERT(scanq->right.qlen == 0);
  546                         if (scanq->lopri.queue == NULL) {
  547                                 RF_ASSERT(scanq->lopri.qlen == 0);
  548                                 return (NULL);
  549                         }
  550                         req = rf_closest_to_arm(&scanq->lopri,
  551                             scanq->last_sector, &dir, scanq->allow_reverse);
  552                 } else {
  553                         req = scanq->right.queue;
  554                 }
  555         } else
  556                 if (scanq->right.queue == NULL) {
  557                         RF_ASSERT(scanq->right.qlen == 0);
  558                         RF_ASSERT(scanq->left.queue);
  559                         req = scanq->left.qtail;
  560                 } else {
  561                         RF_ASSERT(scanq->right.queue);
  562                         RF_ASSERT(scanq->left.queue);
  563                         if (scanq->dir == DIR_RIGHT) {
  564                                 req = scanq->right.queue;
  565                         } else {
  566                                 req = scanq->left.qtail;
  567                         }
  568                 }
  569         if (req == NULL) {
  570                 RF_ASSERT(QSUM(scanq) == 0);
  571         }
  572         return (req);
  573 }
  574 
  575 RF_DiskQueueData_t *
  576 rf_CscanPeek(void *qptr)
  577 {
  578         RF_DiskQueueData_t *req;
  579         RF_Sstf_t *cscanq;
  580 
  581         cscanq = (RF_Sstf_t *) qptr;
  582 
  583         RF_ASSERT(cscanq->dir == DIR_RIGHT);
  584         if (cscanq->right.queue) {
  585                 req = cscanq->right.queue;
  586         } else {
  587                 RF_ASSERT(cscanq->right.qlen == 0);
  588                 if (cscanq->left.queue == NULL) {
  589                         RF_ASSERT(cscanq->left.qlen == 0);
  590                         if (cscanq->lopri.queue == NULL) {
  591                                 RF_ASSERT(cscanq->lopri.qlen == 0);
  592                                 return (NULL);
  593                         }
  594                         req = rf_closest_to_arm(&cscanq->lopri,
  595                             cscanq->last_sector, &cscanq->dir,
  596                             cscanq->allow_reverse);
  597                 } else {
  598                         /*
  599                          * There's I/Os to the left of the arm. We'll end
  600                          * up swinging on back.
  601                          */
  602                         req = cscanq->left.queue;
  603                 }
  604         }
  605         if (req == NULL) {
  606                 RF_ASSERT(QSUM(cscanq) == 0);
  607         }
  608         return (req);
  609 }
  610 
  611 int
  612 rf_SstfPromote(void *qptr, RF_StripeNum_t parityStripeID,
  613     RF_ReconUnitNum_t which_ru)
  614 {
  615         RF_DiskQueueData_t *r, *next;
  616         RF_Sstf_t *sstfq;
  617         int n;
  618 
  619         sstfq = (RF_Sstf_t *) qptr;
  620 
  621         n = 0;
  622         if (rf_sstfDebug || rf_scanDebug || rf_cscanDebug) {
  623                 printf("raid%d: promote %ld %d  queues are %d,%d,%d.\n",
  624                        r->raidPtr->raidid, (long) parityStripeID,
  625                        (int) which_ru, sstfq->left.qlen, sstfq->right.qlen,
  626                        sstfq->lopri.qlen);
  627         }
  628         for (r = sstfq->lopri.queue; r; r = next) {
  629                 next = r->next;
  630                 if (rf_sstfDebug || rf_scanDebug || rf_cscanDebug) {
  631                         printf("raid%d: check promote %lx.\n",
  632                                r->raidPtr->raidid, (long) r);
  633                 }
  634                 if ((r->parityStripeID == parityStripeID)
  635                     && (r->which_ru == which_ru)) {
  636                         rf_do_dequeue(&sstfq->lopri, r);
  637                         rf_SstfEnqueue(qptr, r, RF_IO_NORMAL_PRIORITY);
  638                         n++;
  639                 }
  640         }
  641         if (rf_sstfDebug || rf_scanDebug || rf_cscanDebug) {
  642                 printf("raid%d: promoted %d matching I/Os queues are"
  643                        " %d,%d,%d.\n", r->raidPtr->raidid, n, sstfq->left.qlen,
  644                        sstfq->right.qlen, sstfq->lopri.qlen);
  645         }
  646         return (n);
  647 }

/* [<][>][^][v][top][bottom][index][help] */