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

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

1.1       nbrk        1: /*     $OpenBSD: rf_aselect.c,v 1.3 2002/12/16 07:01:03 tdeval Exp $   */
                      2: /*     $NetBSD: rf_aselect.c,v 1.3 1999/02/05 00:06:06 oster Exp $     */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Carnegie-Mellon University.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Author: Mark Holland, William V. Courtright II
                      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:  * aselect.c -- algorithm selection code
                     34:  *
                     35:  *****************************************************************************/
                     36:
                     37:
                     38: #include "rf_archs.h"
                     39: #include "rf_types.h"
                     40: #include "rf_raid.h"
                     41: #include "rf_dag.h"
                     42: #include "rf_dagutils.h"
                     43: #include "rf_dagfuncs.h"
                     44: #include "rf_general.h"
                     45: #include "rf_desc.h"
                     46: #include "rf_map.h"
                     47:
                     48: #if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)
                     49: /* The function below is not used... so don't define it! */
                     50: #else
                     51: void rf_TransferDagMemory(RF_DagHeader_t *, RF_DagHeader_t *);
                     52: #endif
                     53:
                     54: int  rf_InitHdrNode(RF_DagHeader_t **, RF_Raid_t *, int);
                     55: void rf_UpdateNodeHdrPtr(RF_DagHeader_t *, RF_DagNode_t *);
                     56: int  rf_SelectAlgorithm(RF_RaidAccessDesc_t *, RF_RaidAccessFlags_t);
                     57:
                     58:
                     59: /*****************************************************************************
                     60:  *
                     61:  * Create and Initialize a dag header and termination node.
                     62:  *
                     63:  *****************************************************************************/
                     64: int
                     65: rf_InitHdrNode(RF_DagHeader_t **hdr, RF_Raid_t *raidPtr, int memChunkEnable)
                     66: {
                     67:        /* Create and initialize dag hdr. */
                     68:        *hdr = rf_AllocDAGHeader();
                     69:        rf_MakeAllocList((*hdr)->allocList);
                     70:        if ((*hdr)->allocList == NULL) {
                     71:                rf_FreeDAGHeader(*hdr);
                     72:                return (ENOMEM);
                     73:        }
                     74:        (*hdr)->status = rf_enable;
                     75:        (*hdr)->numSuccedents = 0;
                     76:        (*hdr)->raidPtr = raidPtr;
                     77:        (*hdr)->next = NULL;
                     78:        return (0);
                     79: }
                     80:
                     81:
                     82: /*****************************************************************************
                     83:  *
                     84:  * Transfer allocation list and mem chunks from one dag to another.
                     85:  *
                     86:  *****************************************************************************/
                     87: #if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)
                     88: /* The function below is not used... so don't define it! */
                     89: #else
                     90: void
                     91: rf_TransferDagMemory(RF_DagHeader_t *daga, RF_DagHeader_t *dagb)
                     92: {
                     93:        RF_AccessStripeMapHeader_t *end;
                     94:        RF_AllocListElem_t *p;
                     95:        int i, memChunksXfrd = 0, xtraChunksXfrd = 0;
                     96:
                     97:        /* Transfer allocList from dagb to daga. */
                     98:        for (p = dagb->allocList; p; p = p->next) {
                     99:                for (i = 0; i < p->numPointers; i++) {
                    100:                        rf_AddToAllocList(daga->allocList, p->pointers[i],
                    101:                            p->sizes[i]);
                    102:                        p->pointers[i] = NULL;
                    103:                        p->sizes[i] = 0;
                    104:                }
                    105:                p->numPointers = 0;
                    106:        }
                    107:
                    108:        /* Transfer chunks from dagb to daga. */
                    109:        while ((memChunksXfrd + xtraChunksXfrd <
                    110:            dagb->chunkIndex + dagb->xtraChunkIndex) &&
                    111:            (daga->chunkIndex < RF_MAXCHUNKS)) {
                    112:                /* Stuff chunks into daga's memChunk array. */
                    113:                if (memChunksXfrd < dagb->chunkIndex) {
                    114:                        daga->memChunk[daga->chunkIndex++] =
                    115:                            dagb->memChunk[memChunksXfrd];
                    116:                        dagb->memChunk[memChunksXfrd++] = NULL;
                    117:                } else {
                    118:                        daga->memChunk[daga->xtraChunkIndex++] =
                    119:                            dagb->xtraMemChunk[xtraChunksXfrd];
                    120:                        dagb->xtraMemChunk[xtraChunksXfrd++] = NULL;
                    121:                }
                    122:        }
                    123:        /* Use escape hatch to hold excess chunks. */
                    124:        while (memChunksXfrd + xtraChunksXfrd <
                    125:            dagb->chunkIndex + dagb->xtraChunkIndex) {
                    126:                if (memChunksXfrd < dagb->chunkIndex) {
                    127:                        daga->xtraMemChunk[daga->xtraChunkIndex++] =
                    128:                            dagb->memChunk[memChunksXfrd];
                    129:                        dagb->memChunk[memChunksXfrd++] = NULL;
                    130:                } else {
                    131:                        daga->xtraMemChunk[daga->xtraChunkIndex++] =
                    132:                            dagb->xtraMemChunk[xtraChunksXfrd];
                    133:                        dagb->xtraMemChunk[xtraChunksXfrd++] = NULL;
                    134:                }
                    135:        }
                    136:        RF_ASSERT((memChunksXfrd == dagb->chunkIndex) &&
                    137:            (xtraChunksXfrd == dagb->xtraChunkIndex));
                    138:        RF_ASSERT(daga->chunkIndex <= RF_MAXCHUNKS);
                    139:        RF_ASSERT(daga->xtraChunkIndex <= daga->xtraChunkCnt);
                    140:        dagb->chunkIndex = 0;
                    141:        dagb->xtraChunkIndex = 0;
                    142:
                    143:        /* Transfer asmList from dagb to daga. */
                    144:        if (dagb->asmList) {
                    145:                if (daga->asmList) {
                    146:                        end = daga->asmList;
                    147:                        while (end->next)
                    148:                                end = end->next;
                    149:                        end->next = dagb->asmList;
                    150:                } else
                    151:                        daga->asmList = dagb->asmList;
                    152:                dagb->asmList = NULL;
                    153:        }
                    154: }
                    155: #endif /* __NetBSD__ || __OpenBSD__ */
                    156:
                    157:
                    158: /*****************************************************************************
                    159:  *
                    160:  * Ensure that all node->dagHdr fields in a dag are consistent.
                    161:  *
                    162:  * IMPORTANT: This routine recursively searches all succedents of the node.
                    163:  * If a succedent is encountered whose dagHdr ptr does not require adjusting,
                    164:  * that node's succedents WILL NOT BE EXAMINED.
                    165:  *
                    166:  *****************************************************************************/
                    167: void
                    168: rf_UpdateNodeHdrPtr(RF_DagHeader_t *hdr, RF_DagNode_t *node)
                    169: {
                    170:        int i;
                    171:        RF_ASSERT(hdr != NULL && node != NULL);
                    172:        for (i = 0; i < node->numSuccedents; i++)
                    173:                if (node->succedents[i]->dagHdr != hdr)
                    174:                        rf_UpdateNodeHdrPtr(hdr, node->succedents[i]);
                    175:        node->dagHdr = hdr;
                    176: }
                    177:
                    178:
                    179: /*****************************************************************************
                    180:  *
                    181:  * Create a DAG to do a read or write operation.
                    182:  *
                    183:  * Create an array of dagLists, one list per parity stripe.
                    184:  * Return the lists in the array desc->dagArray.
                    185:  *
                    186:  * Normally, each list contains one dag for the entire stripe.  In some
                    187:  * tricky cases, we break this into multiple dags, either one per stripe
                    188:  * unit or one per block (sector).  When this occurs, these dags are returned
                    189:  * as a linked list (dagList) which is executed sequentially (to preserve
                    190:  * atomic parity updates in the stripe).
                    191:  *
                    192:  * Dags that operate on independent parity goups (stripes) are returned in
                    193:  * independent dagLists (distinct elements in desc->dagArray) and may be
                    194:  * executed concurrently.
                    195:  *
                    196:  * Finally, if the SelectionFunc fails to create a dag for a block, we punt
                    197:  * and return 1.
                    198:  *
                    199:  * The above process is performed in two phases:
                    200:  *   1) create an array(s) of creation functions (eg stripeFuncs)
                    201:  *   2) create dags and concatenate/merge to form the final dag.
                    202:  *
                    203:  * Because dag's are basic blocks (single entry, single exit, unconditional
                    204:  * control flow), we can add the following optimizations (future work):
                    205:  *   first-pass optimizer to allow max concurrency (need all data dependencies)
                    206:  *   second-pass optimizer to eliminate common subexpressions (need true
                    207:  *       data dependencies)
                    208:  *   third-pass optimizer to eliminate dead code (need true data dependencies)
                    209:  *****************************************************************************/
                    210:
                    211: #define        MAXNSTRIPES     50
                    212:
                    213: int
                    214: rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
                    215: {
                    216:        RF_AccessStripeMapHeader_t *asm_h = desc->asmap;
                    217:        RF_IoType_t type = desc->type;
                    218:        RF_Raid_t *raidPtr = desc->raidPtr;
                    219:        void *bp = desc->bp;
                    220:
                    221:        RF_AccessStripeMap_t *asmap = asm_h->stripeMap;
                    222:        RF_AccessStripeMap_t *asm_p;
                    223:        RF_DagHeader_t *dag_h = NULL, *tempdag_h, *lastdag_h;
                    224:        int i, j, k;
                    225:        RF_VoidFuncPtr *stripeFuncs, normalStripeFuncs[MAXNSTRIPES];
                    226:        RF_AccessStripeMap_t *asm_up, *asm_bp;
                    227:        RF_AccessStripeMapHeader_t ***asmh_u, *endASMList;
                    228:        RF_AccessStripeMapHeader_t ***asmh_b;
                    229:        RF_VoidFuncPtr **stripeUnitFuncs, uFunc;
                    230:        RF_VoidFuncPtr **blockFuncs, bFunc;
                    231:        int numStripesBailed = 0, cantCreateDAGs = RF_FALSE;
                    232:        int numStripeUnitsBailed = 0;
                    233:        int stripeNum, numUnitDags = 0, stripeUnitNum, numBlockDags = 0;
                    234:        RF_StripeNum_t numStripeUnits;
                    235:        RF_SectorNum_t numBlocks;
                    236:        RF_RaidAddr_t address;
                    237:        int length;
                    238:        RF_PhysDiskAddr_t *physPtr;
                    239:        caddr_t buffer;
                    240:
                    241:        lastdag_h = NULL;
                    242:        asmh_u = asmh_b = NULL;
                    243:        stripeUnitFuncs = NULL;
                    244:        blockFuncs = NULL;
                    245:
                    246:        /*
                    247:         * Get an array of dag-function creation pointers.
                    248:         * Try to avoid calling malloc.
                    249:         */
                    250:        if (asm_h->numStripes <= MAXNSTRIPES)
                    251:                stripeFuncs = normalStripeFuncs;
                    252:        else
                    253:                RF_Calloc(stripeFuncs, asm_h->numStripes,
                    254:                    sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr *));
                    255:
                    256:        /*
                    257:         * Walk through the asm list once collecting information.
                    258:         * Attempt to find a single creation function for each stripe.
                    259:         */
                    260:        desc->numStripes = 0;
                    261:        for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
                    262:                desc->numStripes++;
                    263:                (raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_p,
                    264:                    &stripeFuncs[i]);
                    265:                /* Check to see if we found a creation func for this stripe. */
                    266:                if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) {
                    267:                        /*
                    268:                         * Could not find creation function for entire stripe.
                    269:                         * So, let's see if we can find one for each stripe
                    270:                         * unit in the stripe.
                    271:                         */
                    272:
                    273:                        if (numStripesBailed == 0) {
                    274:                                /*
                    275:                                 * One stripe map header for each stripe we
                    276:                                 * bail on.
                    277:                                 */
                    278:                                RF_Malloc(asmh_u,
                    279:                                    sizeof(RF_AccessStripeMapHeader_t **) *
                    280:                                    asm_h->numStripes,
                    281:                                    (RF_AccessStripeMapHeader_t ***));
                    282:                                /*
                    283:                                 * Create an array of ptrs to arrays of
                    284:                                 * stripeFuncs.
                    285:                                 */
                    286:                                RF_Calloc(stripeUnitFuncs, asm_h->numStripes,
                    287:                                    sizeof(RF_VoidFuncPtr),
                    288:                                    (RF_VoidFuncPtr **));
                    289:                        }
                    290:                        /*
                    291:                         * Create an array of creation funcs (called
                    292:                         * stripeFuncs) for this stripe.
                    293:                         */
                    294:                        numStripeUnits = asm_p->numStripeUnitsAccessed;
                    295:                        RF_Calloc(stripeUnitFuncs[numStripesBailed],
                    296:                            numStripeUnits, sizeof(RF_VoidFuncPtr),
                    297:                            (RF_VoidFuncPtr *));
                    298:                        RF_Malloc(asmh_u[numStripesBailed], numStripeUnits *
                    299:                            sizeof(RF_AccessStripeMapHeader_t *),
                    300:                            (RF_AccessStripeMapHeader_t **));
                    301:
                    302:                        /* Lookup array of stripeUnitFuncs for this stripe. */
                    303:                        for (j = 0, physPtr = asm_p->physInfo; physPtr;
                    304:                            physPtr = physPtr->next, j++) {
                    305:                                /*
                    306:                                 * Remap for series of single stripe-unit
                    307:                                 * accesses.
                    308:                                 */
                    309:                                address = physPtr->raidAddress;
                    310:                                length = physPtr->numSector;
                    311:                                buffer = physPtr->bufPtr;
                    312:
                    313:                                asmh_u[numStripesBailed][j] =
                    314:                                    rf_MapAccess(raidPtr, address, length,
                    315:                                        buffer, RF_DONT_REMAP);
                    316:                                asm_up = asmh_u[numStripesBailed][j]->stripeMap;
                    317:
                    318:                                /*
                    319:                                 * Get the creation func for this
                    320:                                 * stripe unit.
                    321:                                 */
                    322:                                (raidPtr->Layout.map->SelectionFunc) (raidPtr,
                    323:                                    type, asm_up,
                    324:                                    &(stripeUnitFuncs[numStripesBailed][j]));
                    325:
                    326:                                /*
                    327:                                 * Check to see if we found a creation func
                    328:                                 * for this stripe unit.
                    329:                                 */
                    330:                                if (stripeUnitFuncs[numStripesBailed][j] ==
                    331:                                    (RF_VoidFuncPtr) NULL) {
                    332:                                        /*
                    333:                                         * Could not find creation function
                    334:                                         * for stripe unit.  So, let's see if
                    335:                                         * we can find one for each block in
                    336:                                         * the stripe unit.
                    337:                                         */
                    338:                                        if (numStripeUnitsBailed == 0) {
                    339:                                                /*
                    340:                                                 * one stripe map header for
                    341:                                                 * each stripe unit we bail on.
                    342:                                                 */
                    343:                                                RF_Malloc(asmh_b,
                    344:                                    sizeof(RF_AccessStripeMapHeader_t **) *
                    345:                                    asm_h->numStripes *
                    346:                                    raidPtr->Layout.numDataCol,
                    347:                                    (RF_AccessStripeMapHeader_t ***));
                    348:                                                /*
                    349:                                                 * Create an array of ptrs to
                    350:                                                 * arrays of blockFuncs.
                    351:                                                 */
                    352:                                                RF_Calloc(blockFuncs,
                    353:                                                    asm_h->numStripes *
                    354:                                                    raidPtr->Layout.numDataCol,
                    355:                                                    sizeof(RF_VoidFuncPtr),
                    356:                                                    (RF_VoidFuncPtr **));
                    357:                                        }
                    358:                                        /*
                    359:                                         * Create an array of creation funcs
                    360:                                         * (called blockFuncs) for this stripe
                    361:                                         * unit.
                    362:                                         */
                    363:                                        numBlocks = physPtr->numSector;
                    364:                                        numBlockDags += numBlocks;
                    365:                                        RF_Calloc(
                    366:                                            blockFuncs[numStripeUnitsBailed],
                    367:                                            numBlocks, sizeof(RF_VoidFuncPtr),
                    368:                                            (RF_VoidFuncPtr *));
                    369:                                        RF_Malloc(asmh_b[numStripeUnitsBailed],
                    370:                                    numBlocks *
                    371:                                    sizeof(RF_AccessStripeMapHeader_t *),
                    372:                                    (RF_AccessStripeMapHeader_t **));
                    373:
                    374:                                        /*
                    375:                                         * Lookup array of blockFuncs for this
                    376:                                         * stripe unit.
                    377:                                         */
                    378:                                        for (k = 0; k < numBlocks; k++) {
                    379:                                                /*
                    380:                                                 * Remap for series of single
                    381:                                                 * stripe-unit accesses.
                    382:                                                 */
                    383:                                                address = physPtr->raidAddress
                    384:                                                    + k;
                    385:                                                length = 1;
                    386:                                                buffer = physPtr->bufPtr +
                    387:                                            (k * (1 <<
                    388:                                            raidPtr->logBytesPerSector));
                    389:
                    390:                                                asmh_b[numStripeUnitsBailed][k]
                    391:                                                    = rf_MapAccess(raidPtr,
                    392:                                                    address, length, buffer,
                    393:                                                    RF_DONT_REMAP);
                    394:                                                asm_bp =
                    395:                                    asmh_b[numStripeUnitsBailed][k]->stripeMap;
                    396:
                    397:                                                /*
                    398:                                                 * Get the creation func for
                    399:                                                 * this stripe unit.
                    400:                                                 */
                    401:                                                (raidPtr->Layout.map->
                    402:                                    SelectionFunc) (raidPtr,
                    403:                                        type, asm_bp,
                    404:                                        &(blockFuncs[numStripeUnitsBailed][k]));
                    405:
                    406:                                                /*
                    407:                                                 * Check to see if we found a
                    408:                                                 * creation func for this
                    409:                                                 * stripe unit.
                    410:                                                 */
                    411:                                                if (blockFuncs
                    412:                                                    [numStripeUnitsBailed][k]
                    413:                                                    == NULL)
                    414:                                                        cantCreateDAGs =
                    415:                                                            RF_TRUE;
                    416:                                        }
                    417:                                        numStripeUnitsBailed++;
                    418:                                } else {
                    419:                                        numUnitDags++;
                    420:                                }
                    421:                        }
                    422:                        RF_ASSERT(j == numStripeUnits);
                    423:                        numStripesBailed++;
                    424:                }
                    425:        }
                    426:
                    427:        if (cantCreateDAGs) {
                    428:                /* Free memory and punt. */
                    429:                if (asm_h->numStripes > MAXNSTRIPES)
                    430:                        RF_Free(stripeFuncs, asm_h->numStripes *
                    431:                            sizeof(RF_VoidFuncPtr));
                    432:                if (numStripesBailed > 0) {
                    433:                        stripeNum = 0;
                    434:                        for (i = 0, asm_p = asmap; asm_p;
                    435:                            asm_p = asm_p->next, i++)
                    436:                                if (stripeFuncs[i] == NULL) {
                    437:                                        numStripeUnits =
                    438:                                            asm_p->numStripeUnitsAccessed;
                    439:                                        for (j = 0; j < numStripeUnits; j++)
                    440:                                                rf_FreeAccessStripeMap(
                    441:                                                    asmh_u[stripeNum][j]);
                    442:                                        RF_Free(asmh_u[stripeNum],
                    443:                                    numStripeUnits *
                    444:                                    sizeof(RF_AccessStripeMapHeader_t *));
                    445:                                        RF_Free(stripeUnitFuncs[stripeNum],
                    446:                                            numStripeUnits *
                    447:                                            sizeof(RF_VoidFuncPtr));
                    448:                                        stripeNum++;
                    449:                                }
                    450:                        RF_ASSERT(stripeNum == numStripesBailed);
                    451:                        RF_Free(stripeUnitFuncs, asm_h->numStripes *
                    452:                            sizeof(RF_VoidFuncPtr));
                    453:                        RF_Free(asmh_u, asm_h->numStripes *
                    454:                            sizeof(RF_AccessStripeMapHeader_t **));
                    455:                }
                    456:                return (1);
                    457:        } else {
                    458:                /* Begin dag creation. */
                    459:                stripeNum = 0;
                    460:                stripeUnitNum = 0;
                    461:
                    462:                /* Create an array of dagLists and fill them in. */
                    463:                RF_CallocAndAdd(desc->dagArray, desc->numStripes,
                    464:                    sizeof(RF_DagList_t), (RF_DagList_t *), desc->cleanupList);
                    465:
                    466:                for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
                    467:                        /* Grab dag header for this stripe. */
                    468:                        dag_h = NULL;
                    469:                        desc->dagArray[i].desc = desc;
                    470:
                    471:                        if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) {
                    472:                                /* Use bailout functions for this stripe. */
                    473:                                for (j = 0, physPtr = asm_p->physInfo; physPtr;
                    474:                                    physPtr = physPtr->next, j++) {
                    475:                                        uFunc = stripeUnitFuncs[stripeNum][j];
                    476:                                        if (uFunc == (RF_VoidFuncPtr) NULL) {
                    477:                                                /*
                    478:                                                 * Use bailout functions for
                    479:                                                 * this stripe unit.
                    480:                                                 */
                    481:                                                for (k = 0; k <
                    482:                                                    physPtr->numSector; k++) {
                    483:                                                        /*
                    484:                                                         * Create a dag for
                    485:                                                         * this block.
                    486:                                                         */
                    487:                                                        rf_InitHdrNode(
                    488:                                                            &tempdag_h,
                    489:                                                            raidPtr,
                    490:                                                            rf_useMemChunks);
                    491:                                                        desc->dagArray[i].
                    492:                                                            numDags++;
                    493:                                                        if (dag_h == NULL) {
                    494:                                                                dag_h =
                    495:                                                                    tempdag_h;
                    496:                                                        } else {
                    497:                                                                lastdag_h->next
                    498:                                                                    = tempdag_h;
                    499:                                                        }
                    500:                                                        lastdag_h = tempdag_h;
                    501:
                    502:                                                        bFunc = blockFuncs
                    503:                                                            [stripeUnitNum][k];
                    504:                                                        RF_ASSERT(bFunc);
                    505:                                                        asm_bp = asmh_b
                    506:                                                            [stripeUnitNum][k]
                    507:                                                            ->stripeMap;
                    508:                                                        (*bFunc) (raidPtr,
                    509:                                                            asm_bp, tempdag_h,
                    510:                                                            bp, flags,
                    511:                                                            tempdag_h
                    512:                                                            ->allocList);
                    513:                                                }
                    514:                                                stripeUnitNum++;
                    515:                                        } else {
                    516:                                                /*
                    517:                                                 * Create a dag for this unit.
                    518:                                                 */
                    519:                                                rf_InitHdrNode(&tempdag_h,
                    520:                                                    raidPtr, rf_useMemChunks);
                    521:                                                desc->dagArray[i].numDags++;
                    522:                                                if (dag_h == NULL) {
                    523:                                                        dag_h = tempdag_h;
                    524:                                                } else {
                    525:                                                        lastdag_h->next =
                    526:                                                            tempdag_h;
                    527:                                                }
                    528:                                                lastdag_h = tempdag_h;
                    529:
                    530:                                                asm_up = asmh_u[stripeNum][j]
                    531:                                                    ->stripeMap;
                    532:                                                (*uFunc) (raidPtr, asm_up,
                    533:                                                    tempdag_h, bp, flags,
                    534:                                                    tempdag_h->allocList);
                    535:                                        }
                    536:                                }
                    537:                                RF_ASSERT(j == asm_p->numStripeUnitsAccessed);
                    538:                                /*
                    539:                                 * Merge linked bailout dag to existing dag
                    540:                                 * collection.
                    541:                                 */
                    542:                                stripeNum++;
                    543:                        } else {
                    544:                                /* Create a dag for this parity stripe. */
                    545:                                rf_InitHdrNode(&tempdag_h, raidPtr,
                    546:                                    rf_useMemChunks);
                    547:                                desc->dagArray[i].numDags++;
                    548:                                if (dag_h == NULL) {
                    549:                                        dag_h = tempdag_h;
                    550:                                } else {
                    551:                                        lastdag_h->next = tempdag_h;
                    552:                                }
                    553:                                lastdag_h = tempdag_h;
                    554:
                    555:                                (stripeFuncs[i]) (raidPtr, asm_p, tempdag_h,
                    556:                                    bp, flags, tempdag_h->allocList);
                    557:                        }
                    558:                        desc->dagArray[i].dags = dag_h;
                    559:                }
                    560:                RF_ASSERT(i == desc->numStripes);
                    561:
                    562:                /* Free memory. */
                    563:                if (asm_h->numStripes > MAXNSTRIPES)
                    564:                        RF_Free(stripeFuncs, asm_h->numStripes *
                    565:                            sizeof(RF_VoidFuncPtr));
                    566:                if ((numStripesBailed > 0) || (numStripeUnitsBailed > 0)) {
                    567:                        stripeNum = 0;
                    568:                        stripeUnitNum = 0;
                    569:                        if (dag_h->asmList) {
                    570:                                endASMList = dag_h->asmList;
                    571:                                while (endASMList->next)
                    572:                                        endASMList = endASMList->next;
                    573:                        } else
                    574:                                endASMList = NULL;
                    575:                        /* Walk through io, stripe by stripe. */
                    576:                        for (i = 0, asm_p = asmap; asm_p;
                    577:                            asm_p = asm_p->next, i++)
                    578:                                if (stripeFuncs[i] == NULL) {
                    579:                                        numStripeUnits =
                    580:                                            asm_p->numStripeUnitsAccessed;
                    581:                                        /*
                    582:                                         * Walk through stripe, stripe unit by
                    583:                                         * stripe unit.
                    584:                                         */
                    585:                                        for (j = 0, physPtr = asm_p->physInfo;
                    586:                                            physPtr;
                    587:                                            physPtr = physPtr->next, j++) {
                    588:                                                if (stripeUnitFuncs[stripeNum]
                    589:                                                    [j] == NULL) {
                    590:                                                        numBlocks =
                    591:                                                            physPtr->numSector;
                    592:                                                        /*
                    593:                                                         * Walk through stripe
                    594:                                                         * unit, block by
                    595:                                                         * block.
                    596:                                                         */
                    597:                                                        for (k = 0; k <
                    598:                                                            numBlocks; k++)
                    599:                                                                if (dag_h
                    600:                                                                    ->asmList
                    601:                                                                    == NULL) {
                    602:                                                dag_h->asmList =
                    603:                                                    asmh_b[stripeUnitNum][k];
                    604:                                                endASMList = dag_h->asmList;
                    605:                                                                } else {
                    606:                                                endASMList->next =
                    607:                                                    asmh_b[stripeUnitNum][k];
                    608:                                                endASMList = endASMList->next;
                    609:                                                                }
                    610:                                                        RF_Free(asmh_b
                    611:                                    [stripeUnitNum], numBlocks *
                    612:                                    sizeof(RF_AccessStripeMapHeader_t *));
                    613:                                                        RF_Free(blockFuncs
                    614:                                                    [stripeUnitNum], numBlocks *
                    615:                                                    sizeof(RF_VoidFuncPtr));
                    616:                                                        stripeUnitNum++;
                    617:                                                }
                    618:                                                if (dag_h->asmList == NULL) {
                    619:                                                        dag_h->asmList = asmh_u
                    620:                                                            [stripeNum][j];
                    621:                                                        endASMList = dag_h
                    622:                                                            ->asmList;
                    623:                                                } else {
                    624:                                                        endASMList->next =
                    625:                                                            asmh_u[stripeNum]
                    626:                                                            [j];
                    627:                                                        endASMList = endASMList
                    628:                                                            ->next;
                    629:                                                }
                    630:                                        }
                    631:                                        RF_Free(asmh_u[stripeNum],
                    632:                                            numStripeUnits *
                    633:                                            sizeof(
                    634:                                                RF_AccessStripeMapHeader_t *));
                    635:                                        RF_Free(stripeUnitFuncs[stripeNum],
                    636:                                            numStripeUnits *
                    637:                                            sizeof(RF_VoidFuncPtr));
                    638:                                        stripeNum++;
                    639:                                }
                    640:                        RF_ASSERT(stripeNum == numStripesBailed);
                    641:                        RF_Free(stripeUnitFuncs, asm_h->numStripes *
                    642:                            sizeof(RF_VoidFuncPtr));
                    643:                        RF_Free(asmh_u, asm_h->numStripes *
                    644:                            sizeof(RF_AccessStripeMapHeader_t **));
                    645:                        if (numStripeUnitsBailed > 0) {
                    646:                                RF_ASSERT(stripeUnitNum ==
                    647:                                    numStripeUnitsBailed);
                    648:                                RF_Free(blockFuncs, raidPtr->Layout.numDataCol
                    649:                                    * asm_h->numStripes *
                    650:                                    sizeof(RF_VoidFuncPtr));
                    651:                                RF_Free(asmh_b, raidPtr->Layout.numDataCol *
                    652:                                    asm_h->numStripes *
                    653:                                    sizeof(RF_AccessStripeMapHeader_t **));
                    654:                        }
                    655:                }
                    656:                return (0);
                    657:        }
                    658: }

CVSweb