[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     ! 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