[BACK]Return to rf_sstf.c CVS log [TXT][DIR] Up to [local] / sys / dev / raidframe

Annotation of sys/dev/raidframe/rf_sstf.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb