diff options
Diffstat (limited to 'sys/dev/raidframe/rf_aselect.c')
-rw-r--r-- | sys/dev/raidframe/rf_aselect.c | 865 |
1 files changed, 371 insertions, 494 deletions
diff --git a/sys/dev/raidframe/rf_aselect.c b/sys/dev/raidframe/rf_aselect.c index f6a1918b7a5..b50be26171b 100644 --- a/sys/dev/raidframe/rf_aselect.c +++ b/sys/dev/raidframe/rf_aselect.c @@ -1,5 +1,5 @@ -/* $OpenBSD: rf_aselect.c,v 1.1 1999/01/11 14:28:59 niklas Exp $ */ -/* $NetBSD: rf_aselect.c,v 1.1 1998/11/13 04:20:26 oster Exp $ */ +/* $OpenBSD: rf_aselect.c,v 1.2 1999/02/16 00:02:23 niklas Exp $ */ +/* $NetBSD: rf_aselect.c,v 1.3 1999/02/05 00:06:06 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -30,110 +30,9 @@ /***************************************************************************** * * aselect.c -- algorithm selection code - * - *****************************************************************************/ -/* - * : - * Log: rf_aselect.c,v - * Revision 1.35 1996/07/28 20:31:39 jimz - * i386netbsd port - * true/false fixup - * - * Revision 1.34 1996/07/27 18:39:39 jimz - * cleanup sweep - * - * Revision 1.33 1996/07/22 19:52:16 jimz - * switched node params to RF_DagParam_t, a union of - * a 64-bit int and a void *, for better portability - * attempted hpux port, but failed partway through for - * lack of a single C compiler capable of compiling all - * source files - * - * Revision 1.32 1996/06/12 03:29:40 jimz - * Note: things that call InitHdrNode should check - * for successful return. - * - * Revision 1.31 1996/06/07 21:33:04 jimz - * begin using consistent types for sector numbers, - * stripe numbers, row+col numbers, recon unit numbers - * - * Revision 1.30 1996/06/05 18:06:02 jimz - * Major code cleanup. The Great Renaming is now done. - * Better modularity. Better typing. Fixed a bunch of - * synchronization bugs. Made a lot of global stuff - * per-desc or per-array. Removed dead code. - * - * Revision 1.29 1996/05/31 22:26:54 jimz - * fix a lot of mapping problems, memory allocation problems - * found some weird lock issues, fixed 'em - * more code cleanup - * - * Revision 1.28 1996/05/30 11:29:41 jimz - * Numerous bug fixes. Stripe lock release code disagreed with the taking code - * about when stripes should be locked (I made it consistent: no parity, no lock) - * There was a lot of extra serialization of I/Os which I've removed- a lot of - * it was to calculate values for the cache code, which is no longer with us. - * More types, function, macro cleanup. Added code to properly quiesce the array - * on shutdown. Made a lot of stuff array-specific which was (bogusly) general - * before. Fixed memory allocation, freeing bugs. - * - * Revision 1.27 1996/05/27 18:56:37 jimz - * more code cleanup - * better typing - * compiles in all 3 environments - * - * Revision 1.26 1996/05/24 22:17:04 jimz - * continue code + namespace cleanup - * typed a bunch of flags - * - * Revision 1.25 1996/05/24 04:28:55 jimz - * release cleanup ckpt - * - * Revision 1.24 1996/05/23 21:46:35 jimz - * checkpoint in code cleanup (release prep) - * lots of types, function names have been fixed - * - * Revision 1.23 1996/05/23 00:33:23 jimz - * code cleanup: move all debug decls to rf_options.c, all extern - * debug decls to rf_options.h, all debug vars preceded by rf_ - * - * Revision 1.22 1996/05/18 19:51:34 jimz - * major code cleanup- fix syntax, make some types consistent, - * add prototypes, clean out dead code, et cetera * - * Revision 1.21 1996/05/08 21:01:24 jimz - * fixed up enum type names that were conflicting with other - * enums and function names (ie, "panic") - * future naming trends will be towards RF_ and rf_ for - * everything raidframe-related - * - * Revision 1.20 1996/05/03 19:45:35 wvcii - * removed includes of old deg creation files - * updated SelectAlgorithm comments - * - * Revision 1.19 1995/12/12 18:10:06 jimz - * MIN -> RF_MIN, MAX -> RF_MAX, ASSERT -> RF_ASSERT - * fix 80-column brain damage in comments - * - * Revision 1.18 1995/11/30 16:27:48 wvcii - * added copyright info - * - * Revision 1.17 1995/11/19 16:25:55 wvcii - * SelectAlgorithm now creates an array, returned in desc->dagArray - * return value is now int (1 = FAIL) - * - * Revision 1.16 1995/11/17 15:09:58 wvcii - * fixed bug in SelectAlgorithm in which multiple graphs per stripe are required - * - * Revision 1.15 1995/11/07 17:12:42 wvcii - * changed SelectAlgorithm as follows: - * - * dag creation funcs now create term nodes - * dag selection funcs no longer return numHdrSucc, numTermAnt - * there is now one dag hdr for each dag in a request, implying - * that SelectAlgorithm now returns a linked list of dag hdrs - * - */ + *****************************************************************************/ + #include "rf_archs.h" #include "rf_types.h" @@ -153,7 +52,7 @@ static void TransferDagMemory(RF_DagHeader_t *, RF_DagHeader_t *); static int InitHdrNode(RF_DagHeader_t **, RF_Raid_t *, int); static void UpdateNodeHdrPtr(RF_DagHeader_t *, RF_DagNode_t *); -int rf_SelectAlgorithm(RF_RaidAccessDesc_t *, RF_RaidAccessFlags_t ); +int rf_SelectAlgorithm(RF_RaidAccessDesc_t *, RF_RaidAccessFlags_t); /****************************************************************************** @@ -161,25 +60,25 @@ int rf_SelectAlgorithm(RF_RaidAccessDesc_t *, RF_RaidAccessFlags_t ); * Create and Initialiaze a dag header and termination node * *****************************************************************************/ -static int InitHdrNode(hdr, raidPtr, memChunkEnable) - RF_DagHeader_t **hdr; - RF_Raid_t *raidPtr; - int memChunkEnable; +static int +InitHdrNode(hdr, raidPtr, memChunkEnable) + RF_DagHeader_t **hdr; + RF_Raid_t *raidPtr; + int memChunkEnable; { - /* create and initialize dag hdr */ - *hdr = rf_AllocDAGHeader(); - rf_MakeAllocList((*hdr)->allocList); - if ((*hdr)->allocList == NULL) { - rf_FreeDAGHeader(*hdr); - return(ENOMEM); - } - (*hdr)->status = rf_enable; - (*hdr)->numSuccedents = 0; - (*hdr)->raidPtr = raidPtr; - (*hdr)->next = NULL; - return(0); + /* create and initialize dag hdr */ + *hdr = rf_AllocDAGHeader(); + rf_MakeAllocList((*hdr)->allocList); + if ((*hdr)->allocList == NULL) { + rf_FreeDAGHeader(*hdr); + return (ENOMEM); + } + (*hdr)->status = rf_enable; + (*hdr)->numSuccedents = 0; + (*hdr)->raidPtr = raidPtr; + (*hdr)->next = NULL; + return (0); } - /****************************************************************************** * * Transfer allocation list and mem chunks from one dag to another @@ -188,76 +87,65 @@ static int InitHdrNode(hdr, raidPtr, memChunkEnable) #if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL) /* the function below is not used... so don't define it! */ #else -static void TransferDagMemory(daga, dagb) - RF_DagHeader_t *daga; - RF_DagHeader_t *dagb; +static void +TransferDagMemory(daga, dagb) + RF_DagHeader_t *daga; + RF_DagHeader_t *dagb; { - RF_AccessStripeMapHeader_t *end; - RF_AllocListElem_t *p; - int i, memChunksXfrd = 0, xtraChunksXfrd = 0; - - /* transfer allocList from dagb to daga */ - for (p = dagb->allocList; p ; p = p->next) - { - for (i = 0; i < p->numPointers; i++) - { - rf_AddToAllocList(daga->allocList, p->pointers[i], p->sizes[i]); - p->pointers[i] = NULL; - p->sizes[i] = 0; + RF_AccessStripeMapHeader_t *end; + RF_AllocListElem_t *p; + int i, memChunksXfrd = 0, xtraChunksXfrd = 0; + + /* transfer allocList from dagb to daga */ + for (p = dagb->allocList; p; p = p->next) { + for (i = 0; i < p->numPointers; i++) { + rf_AddToAllocList(daga->allocList, p->pointers[i], p->sizes[i]); + p->pointers[i] = NULL; + p->sizes[i] = 0; + } + p->numPointers = 0; } - p->numPointers = 0; - } - - /* transfer chunks from dagb to daga */ - while ((memChunksXfrd + xtraChunksXfrd < dagb->chunkIndex + dagb->xtraChunkIndex) && (daga->chunkIndex < RF_MAXCHUNKS)) - { - /* stuff chunks into daga's memChunk array */ - if (memChunksXfrd < dagb->chunkIndex) - { - daga->memChunk[daga->chunkIndex++] = dagb->memChunk[memChunksXfrd]; - dagb->memChunk[memChunksXfrd++] = NULL; + + /* transfer chunks from dagb to daga */ + while ((memChunksXfrd + xtraChunksXfrd < dagb->chunkIndex + dagb->xtraChunkIndex) && (daga->chunkIndex < RF_MAXCHUNKS)) { + /* stuff chunks into daga's memChunk array */ + if (memChunksXfrd < dagb->chunkIndex) { + daga->memChunk[daga->chunkIndex++] = dagb->memChunk[memChunksXfrd]; + dagb->memChunk[memChunksXfrd++] = NULL; + } else { + daga->memChunk[daga->xtraChunkIndex++] = dagb->xtraMemChunk[xtraChunksXfrd]; + dagb->xtraMemChunk[xtraChunksXfrd++] = NULL; + } } - else - { - daga->memChunk[daga->xtraChunkIndex++] = dagb->xtraMemChunk[xtraChunksXfrd]; - dagb->xtraMemChunk[xtraChunksXfrd++] = NULL; + /* use escape hatch to hold excess chunks */ + while (memChunksXfrd + xtraChunksXfrd < dagb->chunkIndex + dagb->xtraChunkIndex) { + if (memChunksXfrd < dagb->chunkIndex) { + daga->xtraMemChunk[daga->xtraChunkIndex++] = dagb->memChunk[memChunksXfrd]; + dagb->memChunk[memChunksXfrd++] = NULL; + } else { + daga->xtraMemChunk[daga->xtraChunkIndex++] = dagb->xtraMemChunk[xtraChunksXfrd]; + dagb->xtraMemChunk[xtraChunksXfrd++] = NULL; + } } - } - /* use escape hatch to hold excess chunks */ - while (memChunksXfrd + xtraChunksXfrd < dagb->chunkIndex + dagb->xtraChunkIndex) { - if (memChunksXfrd < dagb->chunkIndex) - { - daga->xtraMemChunk[daga->xtraChunkIndex++] = dagb->memChunk[memChunksXfrd]; - dagb->memChunk[memChunksXfrd++] = NULL; - } - else - { - daga->xtraMemChunk[daga->xtraChunkIndex++] = dagb->xtraMemChunk[xtraChunksXfrd]; - dagb->xtraMemChunk[xtraChunksXfrd++] = NULL; - } - } - RF_ASSERT((memChunksXfrd == dagb->chunkIndex) && (xtraChunksXfrd == dagb->xtraChunkIndex)); - RF_ASSERT(daga->chunkIndex <= RF_MAXCHUNKS); - RF_ASSERT(daga->xtraChunkIndex <= daga->xtraChunkCnt); - dagb->chunkIndex = 0; - dagb->xtraChunkIndex = 0; - - /* transfer asmList from dagb to daga */ - if (dagb->asmList) - { - if (daga->asmList) - { - end = daga->asmList; - while (end->next) - end = end->next; - end->next = dagb->asmList; + RF_ASSERT((memChunksXfrd == dagb->chunkIndex) && (xtraChunksXfrd == dagb->xtraChunkIndex)); + RF_ASSERT(daga->chunkIndex <= RF_MAXCHUNKS); + RF_ASSERT(daga->xtraChunkIndex <= daga->xtraChunkCnt); + dagb->chunkIndex = 0; + dagb->xtraChunkIndex = 0; + + /* transfer asmList from dagb to daga */ + if (dagb->asmList) { + if (daga->asmList) { + end = daga->asmList; + while (end->next) + end = end->next; + end->next = dagb->asmList; + } else + daga->asmList = dagb->asmList; + dagb->asmList = NULL; } - else - daga->asmList = dagb->asmList; - dagb->asmList = NULL; - } } -#endif /* __NetBSD__ || __OpenBSD__ */ +#endif /* __NetBSD__ || __OpenBSD__ */ /***************************************************************************************** * @@ -268,18 +156,18 @@ static void TransferDagMemory(daga, dagb) * succedents WILL NOT BE EXAMINED. * ****************************************************************************************/ -static void UpdateNodeHdrPtr(hdr, node) - RF_DagHeader_t *hdr; - RF_DagNode_t *node; +static void +UpdateNodeHdrPtr(hdr, node) + RF_DagHeader_t *hdr; + RF_DagNode_t *node; { - int i; - RF_ASSERT(hdr != NULL && node != NULL); - for (i = 0; i < node->numSuccedents; i++) - if (node->succedents[i]->dagHdr != hdr) - UpdateNodeHdrPtr(hdr, node->succedents[i]); - node->dagHdr = hdr; + int i; + RF_ASSERT(hdr != NULL && node != NULL); + for (i = 0; i < node->numSuccedents; i++) + if (node->succedents[i]->dagHdr != hdr) + UpdateNodeHdrPtr(hdr, node->succedents[i]); + node->dagHdr = hdr; } - /****************************************************************************** * * Create a DAG to do a read or write operation. @@ -292,7 +180,7 @@ static void UpdateNodeHdrPtr(hdr, node) * unit or one per block (sector). When this occurs, these dags are returned * as a linked list (dagList) which is executed sequentially (to preserve * atomic parity updates in the stripe). - * + * * dags which operate on independent parity goups (stripes) are returned in * independent dagLists (distinct elements in desc->dagArray) and may be * executed concurrently. @@ -314,305 +202,294 @@ static void UpdateNodeHdrPtr(hdr, node) #define MAXNSTRIPES 50 -int rf_SelectAlgorithm(desc, flags) - RF_RaidAccessDesc_t *desc; - RF_RaidAccessFlags_t flags; +int +rf_SelectAlgorithm(desc, flags) + RF_RaidAccessDesc_t *desc; + RF_RaidAccessFlags_t flags; { - RF_AccessStripeMapHeader_t *asm_h = desc->asmap; - RF_IoType_t type = desc->type; - RF_Raid_t *raidPtr = desc->raidPtr; - void *bp = desc->bp; - - RF_AccessStripeMap_t *asmap = asm_h->stripeMap; - RF_AccessStripeMap_t *asm_p; - RF_DagHeader_t *dag_h = NULL, *tempdag_h, *lastdag_h; - int i, j, k; - RF_VoidFuncPtr *stripeFuncs, normalStripeFuncs[MAXNSTRIPES]; - RF_AccessStripeMap_t *asm_up, *asm_bp; - RF_AccessStripeMapHeader_t ***asmh_u, *endASMList; - RF_AccessStripeMapHeader_t ***asmh_b; - RF_VoidFuncPtr **stripeUnitFuncs, uFunc; - RF_VoidFuncPtr **blockFuncs, bFunc; - int numStripesBailed = 0, cantCreateDAGs = RF_FALSE; - int numStripeUnitsBailed = 0; - int stripeNum, numUnitDags = 0, stripeUnitNum, numBlockDags = 0; - RF_StripeNum_t numStripeUnits; - RF_SectorNum_t numBlocks; - RF_RaidAddr_t address; - int length; - RF_PhysDiskAddr_t *physPtr; - caddr_t buffer; - - lastdag_h = NULL; - asmh_u = asmh_b = NULL; - stripeUnitFuncs = NULL; - blockFuncs = NULL; - - /* get an array of dag-function creation pointers, try to avoid calling malloc */ - if (asm_h->numStripes <= MAXNSTRIPES) stripeFuncs = normalStripeFuncs; - else RF_Calloc(stripeFuncs, asm_h->numStripes, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr *)); - - /* walk through the asm list once collecting information */ - /* attempt to find a single creation function for each stripe */ - desc->numStripes = 0; - for (i=0,asm_p = asmap; asm_p; asm_p=asm_p->next,i++) { - desc->numStripes++; - (raidPtr->Layout.map->SelectionFunc)(raidPtr, type, asm_p, &stripeFuncs[i]); - /* check to see if we found a creation func for this stripe */ - if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) - { - /* could not find creation function for entire stripe - so, let's see if we can find one for each stripe unit in the stripe */ - - if (numStripesBailed == 0) - { - /* one stripe map header for each stripe we bail on */ - RF_Malloc(asmh_u, sizeof(RF_AccessStripeMapHeader_t **) * asm_h->numStripes, (RF_AccessStripeMapHeader_t ***)); - /* create an array of ptrs to arrays of stripeFuncs */ - RF_Calloc(stripeUnitFuncs, asm_h->numStripes, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr **)); - } - - /* create an array of creation funcs (called stripeFuncs) for this stripe */ - numStripeUnits = asm_p->numStripeUnitsAccessed; - RF_Calloc(stripeUnitFuncs[numStripesBailed], numStripeUnits, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr *)); - RF_Malloc(asmh_u[numStripesBailed], numStripeUnits * sizeof(RF_AccessStripeMapHeader_t *), (RF_AccessStripeMapHeader_t **)); - - /* lookup array of stripeUnitFuncs for this stripe */ - for (j=0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) - { - /* remap for series of single stripe-unit accesses */ - address = physPtr->raidAddress; - length = physPtr->numSector; - buffer = physPtr->bufPtr; - - asmh_u[numStripesBailed][j] = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP); - asm_up = asmh_u[numStripesBailed][j]->stripeMap; - - /* get the creation func for this stripe unit */ - (raidPtr->Layout.map-> SelectionFunc)(raidPtr, type, asm_up, &(stripeUnitFuncs[numStripesBailed][j])); - - /* check to see if we found a creation func for this stripe unit */ - if (stripeUnitFuncs[numStripesBailed][j] == (RF_VoidFuncPtr) NULL) - { - /* could not find creation function for stripe unit so, - let's see if we can find one for each block in the stripe unit */ - if (numStripeUnitsBailed == 0) - { - /* one stripe map header for each stripe unit we bail on */ - RF_Malloc(asmh_b, sizeof(RF_AccessStripeMapHeader_t **) * asm_h->numStripes * raidPtr->Layout.numDataCol, (RF_AccessStripeMapHeader_t ***)); - /* create an array of ptrs to arrays of blockFuncs */ - RF_Calloc(blockFuncs, asm_h->numStripes * raidPtr->Layout.numDataCol, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr **)); - } - - /* create an array of creation funcs (called blockFuncs) for this stripe unit */ - numBlocks = physPtr->numSector; - numBlockDags += numBlocks; - RF_Calloc(blockFuncs[numStripeUnitsBailed], numBlocks, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr *)); - RF_Malloc(asmh_b[numStripeUnitsBailed], numBlocks * sizeof(RF_AccessStripeMapHeader_t *), (RF_AccessStripeMapHeader_t **)); - - /* lookup array of blockFuncs for this stripe unit */ - for (k=0; k < numBlocks; k++) - { - /* remap for series of single stripe-unit accesses */ - address = physPtr->raidAddress + k; - length = 1; - buffer = physPtr->bufPtr + (k * (1<<raidPtr->logBytesPerSector)); - - asmh_b[numStripeUnitsBailed][k] = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP); - asm_bp = asmh_b[numStripeUnitsBailed][k]->stripeMap; - - /* get the creation func for this stripe unit */ - (raidPtr->Layout.map-> SelectionFunc)(raidPtr, type, asm_bp, &(blockFuncs[numStripeUnitsBailed][k])); - - /* check to see if we found a creation func for this stripe unit */ - if (blockFuncs[numStripeUnitsBailed][k] == NULL) - cantCreateDAGs = RF_TRUE; - } - numStripeUnitsBailed++; - } - else - { - numUnitDags++; - } - } - RF_ASSERT(j == numStripeUnits); - numStripesBailed++; - } - } - - if (cantCreateDAGs) - { - /* free memory and punt */ - if (asm_h->numStripes > MAXNSTRIPES) - RF_Free(stripeFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); - if (numStripesBailed > 0) - { - stripeNum = 0; - for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) - if (stripeFuncs[i] == NULL) - { - numStripeUnits = asm_p->numStripeUnitsAccessed; - for (j = 0; j < numStripeUnits; j++) - rf_FreeAccessStripeMap(asmh_u[stripeNum][j]); - RF_Free(asmh_u[stripeNum], numStripeUnits * sizeof(RF_AccessStripeMapHeader_t *)); - RF_Free(stripeUnitFuncs[stripeNum], numStripeUnits * sizeof(RF_VoidFuncPtr)); - stripeNum++; - } - RF_ASSERT(stripeNum == numStripesBailed); - RF_Free(stripeUnitFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); - RF_Free(asmh_u, asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); - } - return(1); - } - else - { - /* begin dag creation */ - stripeNum = 0; - stripeUnitNum = 0; - - /* create an array of dagLists and fill them in */ - RF_CallocAndAdd(desc->dagArray, desc->numStripes, sizeof(RF_DagList_t), (RF_DagList_t *), desc->cleanupList); - - for (i=0, asm_p = asmap; asm_p; asm_p=asm_p->next,i++) { - /* grab dag header for this stripe */ - dag_h = NULL; - desc->dagArray[i].desc = desc; - - if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) - { - /* use bailout functions for this stripe */ - for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr=physPtr->next, j++) - { - uFunc = stripeUnitFuncs[stripeNum][j]; - if (uFunc == (RF_VoidFuncPtr) NULL) - { - /* use bailout functions for this stripe unit */ - for (k = 0; k < physPtr->numSector; k++) - { - /* create a dag for this block */ - InitHdrNode(&tempdag_h, raidPtr, rf_useMemChunks); - desc->dagArray[i].numDags++; - if (dag_h == NULL) { - dag_h = tempdag_h; + RF_AccessStripeMapHeader_t *asm_h = desc->asmap; + RF_IoType_t type = desc->type; + RF_Raid_t *raidPtr = desc->raidPtr; + void *bp = desc->bp; + + RF_AccessStripeMap_t *asmap = asm_h->stripeMap; + RF_AccessStripeMap_t *asm_p; + RF_DagHeader_t *dag_h = NULL, *tempdag_h, *lastdag_h; + int i, j, k; + RF_VoidFuncPtr *stripeFuncs, normalStripeFuncs[MAXNSTRIPES]; + RF_AccessStripeMap_t *asm_up, *asm_bp; + RF_AccessStripeMapHeader_t ***asmh_u, *endASMList; + RF_AccessStripeMapHeader_t ***asmh_b; + RF_VoidFuncPtr **stripeUnitFuncs, uFunc; + RF_VoidFuncPtr **blockFuncs, bFunc; + int numStripesBailed = 0, cantCreateDAGs = RF_FALSE; + int numStripeUnitsBailed = 0; + int stripeNum, numUnitDags = 0, stripeUnitNum, numBlockDags = 0; + RF_StripeNum_t numStripeUnits; + RF_SectorNum_t numBlocks; + RF_RaidAddr_t address; + int length; + RF_PhysDiskAddr_t *physPtr; + caddr_t buffer; + + lastdag_h = NULL; + asmh_u = asmh_b = NULL; + stripeUnitFuncs = NULL; + blockFuncs = NULL; + + /* get an array of dag-function creation pointers, try to avoid + * calling malloc */ + if (asm_h->numStripes <= MAXNSTRIPES) + stripeFuncs = normalStripeFuncs; + else + RF_Calloc(stripeFuncs, asm_h->numStripes, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr *)); + + /* walk through the asm list once collecting information */ + /* attempt to find a single creation function for each stripe */ + desc->numStripes = 0; + for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) { + desc->numStripes++; + (raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_p, &stripeFuncs[i]); + /* check to see if we found a creation func for this stripe */ + if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) { + /* could not find creation function for entire stripe + * so, let's see if we can find one for each stripe + * unit in the stripe */ + + if (numStripesBailed == 0) { + /* one stripe map header for each stripe we + * bail on */ + RF_Malloc(asmh_u, sizeof(RF_AccessStripeMapHeader_t **) * asm_h->numStripes, (RF_AccessStripeMapHeader_t ***)); + /* create an array of ptrs to arrays of + * stripeFuncs */ + RF_Calloc(stripeUnitFuncs, asm_h->numStripes, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr **)); } - else { - lastdag_h->next = tempdag_h; + /* create an array of creation funcs (called + * stripeFuncs) for this stripe */ + numStripeUnits = asm_p->numStripeUnitsAccessed; + RF_Calloc(stripeUnitFuncs[numStripesBailed], numStripeUnits, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr *)); + RF_Malloc(asmh_u[numStripesBailed], numStripeUnits * sizeof(RF_AccessStripeMapHeader_t *), (RF_AccessStripeMapHeader_t **)); + + /* lookup array of stripeUnitFuncs for this stripe */ + for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) { + /* remap for series of single stripe-unit + * accesses */ + address = physPtr->raidAddress; + length = physPtr->numSector; + buffer = physPtr->bufPtr; + + asmh_u[numStripesBailed][j] = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP); + asm_up = asmh_u[numStripesBailed][j]->stripeMap; + + /* get the creation func for this stripe unit */ + (raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_up, &(stripeUnitFuncs[numStripesBailed][j])); + + /* check to see if we found a creation func + * for this stripe unit */ + if (stripeUnitFuncs[numStripesBailed][j] == (RF_VoidFuncPtr) NULL) { + /* could not find creation function + * for stripe unit so, let's see if we + * can find one for each block in the + * stripe unit */ + if (numStripeUnitsBailed == 0) { + /* one stripe map header for + * each stripe unit we bail on */ + RF_Malloc(asmh_b, sizeof(RF_AccessStripeMapHeader_t **) * asm_h->numStripes * raidPtr->Layout.numDataCol, (RF_AccessStripeMapHeader_t ***)); + /* create an array of ptrs to + * arrays of blockFuncs */ + RF_Calloc(blockFuncs, asm_h->numStripes * raidPtr->Layout.numDataCol, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr **)); + } + /* create an array of creation funcs + * (called blockFuncs) for this stripe + * unit */ + numBlocks = physPtr->numSector; + numBlockDags += numBlocks; + RF_Calloc(blockFuncs[numStripeUnitsBailed], numBlocks, sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr *)); + RF_Malloc(asmh_b[numStripeUnitsBailed], numBlocks * sizeof(RF_AccessStripeMapHeader_t *), (RF_AccessStripeMapHeader_t **)); + + /* lookup array of blockFuncs for this + * stripe unit */ + for (k = 0; k < numBlocks; k++) { + /* remap for series of single + * stripe-unit accesses */ + address = physPtr->raidAddress + k; + length = 1; + buffer = physPtr->bufPtr + (k * (1 << raidPtr->logBytesPerSector)); + + asmh_b[numStripeUnitsBailed][k] = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP); + asm_bp = asmh_b[numStripeUnitsBailed][k]->stripeMap; + + /* get the creation func for + * this stripe unit */ + (raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_bp, &(blockFuncs[numStripeUnitsBailed][k])); + + /* check to see if we found a + * creation func for this + * stripe unit */ + if (blockFuncs[numStripeUnitsBailed][k] == NULL) + cantCreateDAGs = RF_TRUE; + } + numStripeUnitsBailed++; + } else { + numUnitDags++; + } } - lastdag_h = tempdag_h; - - bFunc = blockFuncs[stripeUnitNum][k]; - RF_ASSERT(bFunc); - asm_bp = asmh_b[stripeUnitNum][k]->stripeMap; - (*bFunc)(raidPtr, asm_bp, tempdag_h, bp, flags, tempdag_h->allocList); - } - stripeUnitNum++; - } - else - { - /* create a dag for this unit */ - InitHdrNode(&tempdag_h, raidPtr, rf_useMemChunks); - desc->dagArray[i].numDags++; - if (dag_h == NULL) { - dag_h = tempdag_h; - } - else { - lastdag_h->next = tempdag_h; - } - lastdag_h = tempdag_h; - - asm_up = asmh_u[stripeNum][j]->stripeMap; - (*uFunc)(raidPtr, asm_up, tempdag_h, bp, flags, tempdag_h->allocList); - } - } - RF_ASSERT(j == asm_p->numStripeUnitsAccessed); - /* merge linked bailout dag to existing dag collection */ - stripeNum++; - } - else { - /* Create a dag for this parity stripe */ - InitHdrNode(&tempdag_h, raidPtr, rf_useMemChunks); - desc->dagArray[i].numDags++; - if (dag_h == NULL) { - dag_h = tempdag_h; - } - else { - lastdag_h->next = tempdag_h; - } - lastdag_h = tempdag_h; - - (stripeFuncs[i])(raidPtr, asm_p, tempdag_h, bp, flags, tempdag_h->allocList); + RF_ASSERT(j == numStripeUnits); + numStripesBailed++; + } } - desc->dagArray[i].dags = dag_h; - } - RF_ASSERT(i == desc->numStripes); - - /* free memory */ - if (asm_h->numStripes > MAXNSTRIPES) - RF_Free(stripeFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); - if ((numStripesBailed > 0) || (numStripeUnitsBailed > 0)) - { - stripeNum = 0; - stripeUnitNum = 0; - if (dag_h->asmList) - { - endASMList = dag_h->asmList; - while (endASMList->next) - endASMList = endASMList->next; - } - else - endASMList = NULL; - /* walk through io, stripe by stripe */ - for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) - if (stripeFuncs[i] == NULL) - { - numStripeUnits = asm_p->numStripeUnitsAccessed; - /* walk through stripe, stripe unit by stripe unit */ - for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) - { - if (stripeUnitFuncs[stripeNum][j] == NULL) - { - numBlocks = physPtr->numSector; - /* walk through stripe unit, block by block */ - for (k = 0; k < numBlocks; k++) - if (dag_h->asmList == NULL) - { - dag_h->asmList = asmh_b[stripeUnitNum][k]; - endASMList = dag_h->asmList; - } - else - { - endASMList->next = asmh_b[stripeUnitNum][k]; - endASMList = endASMList->next; - } - RF_Free(asmh_b[stripeUnitNum], numBlocks * sizeof(RF_AccessStripeMapHeader_t *)); - RF_Free(blockFuncs[stripeUnitNum], numBlocks * sizeof(RF_VoidFuncPtr)); - stripeUnitNum++; - } - if (dag_h->asmList == NULL) - { - dag_h->asmList = asmh_u[stripeNum][j]; - endASMList = dag_h->asmList; - } - else - { - endASMList->next = asmh_u[stripeNum][j]; - endASMList = endASMList->next; - } - } - RF_Free(asmh_u[stripeNum], numStripeUnits * sizeof(RF_AccessStripeMapHeader_t *)); - RF_Free(stripeUnitFuncs[stripeNum], numStripeUnits * sizeof(RF_VoidFuncPtr)); - stripeNum++; - } - RF_ASSERT(stripeNum == numStripesBailed); - RF_Free(stripeUnitFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); - RF_Free(asmh_u, asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); - if (numStripeUnitsBailed > 0) - { - RF_ASSERT(stripeUnitNum == numStripeUnitsBailed); - RF_Free(blockFuncs, raidPtr->Layout.numDataCol * asm_h->numStripes * sizeof(RF_VoidFuncPtr)); - RF_Free(asmh_b, raidPtr->Layout.numDataCol * asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); - } + + if (cantCreateDAGs) { + /* free memory and punt */ + if (asm_h->numStripes > MAXNSTRIPES) + RF_Free(stripeFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); + if (numStripesBailed > 0) { + stripeNum = 0; + for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) + if (stripeFuncs[i] == NULL) { + numStripeUnits = asm_p->numStripeUnitsAccessed; + for (j = 0; j < numStripeUnits; j++) + rf_FreeAccessStripeMap(asmh_u[stripeNum][j]); + RF_Free(asmh_u[stripeNum], numStripeUnits * sizeof(RF_AccessStripeMapHeader_t *)); + RF_Free(stripeUnitFuncs[stripeNum], numStripeUnits * sizeof(RF_VoidFuncPtr)); + stripeNum++; + } + RF_ASSERT(stripeNum == numStripesBailed); + RF_Free(stripeUnitFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); + RF_Free(asmh_u, asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); + } + return (1); + } else { + /* begin dag creation */ + stripeNum = 0; + stripeUnitNum = 0; + + /* create an array of dagLists and fill them in */ + RF_CallocAndAdd(desc->dagArray, desc->numStripes, sizeof(RF_DagList_t), (RF_DagList_t *), desc->cleanupList); + + for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) { + /* grab dag header for this stripe */ + dag_h = NULL; + desc->dagArray[i].desc = desc; + + if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) { + /* use bailout functions for this stripe */ + for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) { + uFunc = stripeUnitFuncs[stripeNum][j]; + if (uFunc == (RF_VoidFuncPtr) NULL) { + /* use bailout functions for + * this stripe unit */ + for (k = 0; k < physPtr->numSector; k++) { + /* create a dag for + * this block */ + InitHdrNode(&tempdag_h, raidPtr, rf_useMemChunks); + desc->dagArray[i].numDags++; + if (dag_h == NULL) { + dag_h = tempdag_h; + } else { + lastdag_h->next = tempdag_h; + } + lastdag_h = tempdag_h; + + bFunc = blockFuncs[stripeUnitNum][k]; + RF_ASSERT(bFunc); + asm_bp = asmh_b[stripeUnitNum][k]->stripeMap; + (*bFunc) (raidPtr, asm_bp, tempdag_h, bp, flags, tempdag_h->allocList); + } + stripeUnitNum++; + } else { + /* create a dag for this unit */ + InitHdrNode(&tempdag_h, raidPtr, rf_useMemChunks); + desc->dagArray[i].numDags++; + if (dag_h == NULL) { + dag_h = tempdag_h; + } else { + lastdag_h->next = tempdag_h; + } + lastdag_h = tempdag_h; + + asm_up = asmh_u[stripeNum][j]->stripeMap; + (*uFunc) (raidPtr, asm_up, tempdag_h, bp, flags, tempdag_h->allocList); + } + } + RF_ASSERT(j == asm_p->numStripeUnitsAccessed); + /* merge linked bailout dag to existing dag + * collection */ + stripeNum++; + } else { + /* Create a dag for this parity stripe */ + InitHdrNode(&tempdag_h, raidPtr, rf_useMemChunks); + desc->dagArray[i].numDags++; + if (dag_h == NULL) { + dag_h = tempdag_h; + } else { + lastdag_h->next = tempdag_h; + } + lastdag_h = tempdag_h; + + (stripeFuncs[i]) (raidPtr, asm_p, tempdag_h, bp, flags, tempdag_h->allocList); + } + desc->dagArray[i].dags = dag_h; + } + RF_ASSERT(i == desc->numStripes); + + /* free memory */ + if (asm_h->numStripes > MAXNSTRIPES) + RF_Free(stripeFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); + if ((numStripesBailed > 0) || (numStripeUnitsBailed > 0)) { + stripeNum = 0; + stripeUnitNum = 0; + if (dag_h->asmList) { + endASMList = dag_h->asmList; + while (endASMList->next) + endASMList = endASMList->next; + } else + endASMList = NULL; + /* walk through io, stripe by stripe */ + for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) + if (stripeFuncs[i] == NULL) { + numStripeUnits = asm_p->numStripeUnitsAccessed; + /* walk through stripe, stripe unit by + * stripe unit */ + for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) { + if (stripeUnitFuncs[stripeNum][j] == NULL) { + numBlocks = physPtr->numSector; + /* walk through stripe + * unit, block by + * block */ + for (k = 0; k < numBlocks; k++) + if (dag_h->asmList == NULL) { + dag_h->asmList = asmh_b[stripeUnitNum][k]; + endASMList = dag_h->asmList; + } else { + endASMList->next = asmh_b[stripeUnitNum][k]; + endASMList = endASMList->next; + } + RF_Free(asmh_b[stripeUnitNum], numBlocks * sizeof(RF_AccessStripeMapHeader_t *)); + RF_Free(blockFuncs[stripeUnitNum], numBlocks * sizeof(RF_VoidFuncPtr)); + stripeUnitNum++; + } + if (dag_h->asmList == NULL) { + dag_h->asmList = asmh_u[stripeNum][j]; + endASMList = dag_h->asmList; + } else { + endASMList->next = asmh_u[stripeNum][j]; + endASMList = endASMList->next; + } + } + RF_Free(asmh_u[stripeNum], numStripeUnits * sizeof(RF_AccessStripeMapHeader_t *)); + RF_Free(stripeUnitFuncs[stripeNum], numStripeUnits * sizeof(RF_VoidFuncPtr)); + stripeNum++; + } + RF_ASSERT(stripeNum == numStripesBailed); + RF_Free(stripeUnitFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); + RF_Free(asmh_u, asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); + if (numStripeUnitsBailed > 0) { + RF_ASSERT(stripeUnitNum == numStripeUnitsBailed); + RF_Free(blockFuncs, raidPtr->Layout.numDataCol * asm_h->numStripes * sizeof(RF_VoidFuncPtr)); + RF_Free(asmh_b, raidPtr->Layout.numDataCol * asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); + } + } + return (0); } - return(0); - } } |