Home | History | Annotate | Line # | Download | only in raidframe
rf_aselect.c revision 1.8.2.2
      1  1.8.2.1  skrll /*	$NetBSD: rf_aselect.c,v 1.8.2.2 2004/09/18 14:50:53 skrll Exp $	*/
      2      1.1  oster /*
      3      1.1  oster  * Copyright (c) 1995 Carnegie-Mellon University.
      4      1.1  oster  * All rights reserved.
      5      1.1  oster  *
      6      1.1  oster  * Author: Mark Holland, William V. Courtright II
      7      1.1  oster  *
      8      1.1  oster  * Permission to use, copy, modify and distribute this software and
      9      1.1  oster  * its documentation is hereby granted, provided that both the copyright
     10      1.1  oster  * notice and this permission notice appear in all copies of the
     11      1.1  oster  * software, derivative works or modified versions, and any portions
     12      1.1  oster  * thereof, and that both notices appear in supporting documentation.
     13      1.1  oster  *
     14      1.1  oster  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     15      1.1  oster  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     16      1.1  oster  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     17      1.1  oster  *
     18      1.1  oster  * Carnegie Mellon requests users of this software to return to
     19      1.1  oster  *
     20      1.1  oster  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     21      1.1  oster  *  School of Computer Science
     22      1.1  oster  *  Carnegie Mellon University
     23      1.1  oster  *  Pittsburgh PA 15213-3890
     24      1.1  oster  *
     25      1.1  oster  * any improvements or extensions that they make and grant Carnegie the
     26      1.1  oster  * rights to redistribute these changes.
     27      1.1  oster  */
     28      1.1  oster 
     29      1.1  oster /*****************************************************************************
     30      1.1  oster  *
     31      1.1  oster  * aselect.c -- algorithm selection code
     32      1.3  oster  *
     33      1.1  oster  *****************************************************************************/
     34      1.5  lukem 
     35      1.5  lukem #include <sys/cdefs.h>
     36  1.8.2.1  skrll __KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.8.2.2 2004/09/18 14:50:53 skrll Exp $");
     37      1.2  oster 
     38      1.4  oster #include <dev/raidframe/raidframevar.h>
     39      1.1  oster 
     40      1.1  oster #include "rf_archs.h"
     41      1.1  oster #include "rf_raid.h"
     42      1.1  oster #include "rf_dag.h"
     43      1.1  oster #include "rf_dagutils.h"
     44      1.1  oster #include "rf_dagfuncs.h"
     45      1.1  oster #include "rf_general.h"
     46      1.1  oster #include "rf_desc.h"
     47      1.1  oster #include "rf_map.h"
     48      1.1  oster 
     49  1.8.2.1  skrll static void InitHdrNode(RF_DagHeader_t **, RF_Raid_t *, RF_RaidAccessDesc_t *);
     50      1.3  oster int     rf_SelectAlgorithm(RF_RaidAccessDesc_t *, RF_RaidAccessFlags_t);
     51      1.1  oster 
     52      1.1  oster /******************************************************************************
     53      1.1  oster  *
     54      1.1  oster  * Create and Initialiaze a dag header and termination node
     55      1.1  oster  *
     56      1.1  oster  *****************************************************************************/
     57  1.8.2.1  skrll static void
     58  1.8.2.1  skrll InitHdrNode(RF_DagHeader_t **hdr, RF_Raid_t *raidPtr, RF_RaidAccessDesc_t *desc)
     59      1.1  oster {
     60      1.3  oster 	/* create and initialize dag hdr */
     61      1.3  oster 	*hdr = rf_AllocDAGHeader();
     62      1.3  oster 	rf_MakeAllocList((*hdr)->allocList);
     63      1.3  oster 	(*hdr)->status = rf_enable;
     64      1.3  oster 	(*hdr)->numSuccedents = 0;
     65  1.8.2.1  skrll 	(*hdr)->nodes = NULL;
     66      1.3  oster 	(*hdr)->raidPtr = raidPtr;
     67      1.3  oster 	(*hdr)->next = NULL;
     68  1.8.2.1  skrll 	(*hdr)->desc = desc;
     69      1.1  oster }
     70      1.1  oster 
     71      1.1  oster /******************************************************************************
     72      1.1  oster  *
     73      1.1  oster  * Create a DAG to do a read or write operation.
     74      1.1  oster  *
     75  1.8.2.1  skrll  * create a list of dagLists, one list per parity stripe.
     76  1.8.2.1  skrll  * return the lists in the desc->dagList (which is a list of lists).
     77      1.1  oster  *
     78      1.1  oster  * Normally, each list contains one dag for the entire stripe.  In some
     79      1.1  oster  * tricky cases, we break this into multiple dags, either one per stripe
     80      1.1  oster  * unit or one per block (sector).  When this occurs, these dags are returned
     81      1.1  oster  * as a linked list (dagList) which is executed sequentially (to preserve
     82      1.1  oster  * atomic parity updates in the stripe).
     83      1.3  oster  *
     84      1.1  oster  * dags which operate on independent parity goups (stripes) are returned in
     85      1.1  oster  * independent dagLists (distinct elements in desc->dagArray) and may be
     86      1.1  oster  * executed concurrently.
     87      1.1  oster  *
     88      1.1  oster  * Finally, if the SelectionFunc fails to create a dag for a block, we punt
     89      1.1  oster  * and return 1.
     90      1.1  oster  *
     91      1.1  oster  * The above process is performed in two phases:
     92      1.1  oster  *   1) create an array(s) of creation functions (eg stripeFuncs)
     93      1.1  oster  *   2) create dags and concatenate/merge to form the final dag.
     94      1.1  oster  *
     95      1.1  oster  * Because dag's are basic blocks (single entry, single exit, unconditional
     96      1.1  oster  * control flow, we can add the following optimizations (future work):
     97      1.1  oster  *   first-pass optimizer to allow max concurrency (need all data dependencies)
     98      1.1  oster  *   second-pass optimizer to eliminate common subexpressions (need true
     99      1.1  oster  *                         data dependencies)
    100      1.1  oster  *   third-pass optimizer to eliminate dead code (need true data dependencies)
    101      1.1  oster  *****************************************************************************/
    102      1.1  oster 
    103      1.1  oster #define MAXNSTRIPES 50
    104      1.1  oster 
    105      1.3  oster int
    106  1.8.2.1  skrll rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
    107      1.1  oster {
    108      1.3  oster 	RF_AccessStripeMapHeader_t *asm_h = desc->asmap;
    109      1.3  oster 	RF_IoType_t type = desc->type;
    110      1.3  oster 	RF_Raid_t *raidPtr = desc->raidPtr;
    111      1.3  oster 	void   *bp = desc->bp;
    112      1.3  oster 
    113      1.3  oster 	RF_AccessStripeMap_t *asmap = asm_h->stripeMap;
    114      1.3  oster 	RF_AccessStripeMap_t *asm_p;
    115      1.3  oster 	RF_DagHeader_t *dag_h = NULL, *tempdag_h, *lastdag_h;
    116  1.8.2.1  skrll 	RF_DagList_t *dagList, *dagListend;
    117      1.3  oster 	int     i, j, k;
    118  1.8.2.1  skrll 	RF_FuncList_t *stripeFuncsList, *stripeFuncs, *stripeFuncsEnd, *temp;
    119      1.3  oster 	RF_AccessStripeMap_t *asm_up, *asm_bp;
    120      1.3  oster 	RF_AccessStripeMapHeader_t ***asmh_u, *endASMList;
    121      1.3  oster 	RF_AccessStripeMapHeader_t ***asmh_b;
    122  1.8.2.1  skrll 	RF_ASMHeaderListElem_t *asmhle, *tmpasmhle;
    123  1.8.2.1  skrll 	RF_VoidFunctionPointerListElem_t *vfple, *tmpvfple;
    124  1.8.2.1  skrll 	RF_FailedStripe_t *failed_stripes_list, *failed_stripes_list_end;
    125  1.8.2.1  skrll 	RF_FailedStripe_t *tmpfailed_stripe, *failed_stripe = NULL;
    126  1.8.2.1  skrll 	RF_ASMHeaderListElem_t *failed_stripes_asmh_u_end = NULL;
    127  1.8.2.1  skrll 	RF_ASMHeaderListElem_t *failed_stripes_asmh_b_end = NULL;
    128  1.8.2.1  skrll 	RF_VoidFunctionPointerListElem_t *failed_stripes_vfple_end = NULL;
    129  1.8.2.1  skrll 	RF_VoidFunctionPointerListElem_t *failed_stripes_bvfple_end = NULL;
    130      1.3  oster 	RF_VoidFuncPtr **stripeUnitFuncs, uFunc;
    131      1.3  oster 	RF_VoidFuncPtr **blockFuncs, bFunc;
    132      1.3  oster 	int     numStripesBailed = 0, cantCreateDAGs = RF_FALSE;
    133      1.3  oster 	int     numStripeUnitsBailed = 0;
    134      1.3  oster 	int     stripeNum, numUnitDags = 0, stripeUnitNum, numBlockDags = 0;
    135      1.3  oster 	RF_StripeNum_t numStripeUnits;
    136      1.3  oster 	RF_SectorNum_t numBlocks;
    137      1.3  oster 	RF_RaidAddr_t address;
    138      1.3  oster 	int     length;
    139      1.3  oster 	RF_PhysDiskAddr_t *physPtr;
    140      1.3  oster 	caddr_t buffer;
    141      1.3  oster 
    142      1.3  oster 	lastdag_h = NULL;
    143      1.3  oster 	asmh_u = asmh_b = NULL;
    144      1.3  oster 	stripeUnitFuncs = NULL;
    145      1.3  oster 	blockFuncs = NULL;
    146      1.3  oster 
    147  1.8.2.1  skrll 	stripeFuncsList = NULL;
    148  1.8.2.1  skrll 	stripeFuncsEnd = NULL;
    149  1.8.2.1  skrll 
    150  1.8.2.1  skrll 	failed_stripes_list = NULL;
    151  1.8.2.1  skrll 	failed_stripes_list_end = NULL;
    152      1.3  oster 
    153      1.3  oster 	/* walk through the asm list once collecting information */
    154      1.3  oster 	/* attempt to find a single creation function for each stripe */
    155      1.3  oster 	desc->numStripes = 0;
    156      1.3  oster 	for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    157      1.3  oster 		desc->numStripes++;
    158  1.8.2.1  skrll 		stripeFuncs = rf_AllocFuncList();
    159  1.8.2.1  skrll 
    160  1.8.2.1  skrll 		if (stripeFuncsEnd == NULL) {
    161  1.8.2.1  skrll 			stripeFuncsList = stripeFuncs;
    162  1.8.2.1  skrll 		} else {
    163  1.8.2.1  skrll 			stripeFuncsEnd->next = stripeFuncs;
    164  1.8.2.1  skrll 		}
    165  1.8.2.1  skrll 		stripeFuncsEnd = stripeFuncs;
    166  1.8.2.1  skrll 
    167  1.8.2.1  skrll 		(raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_p, &(stripeFuncs->fp));
    168      1.3  oster 		/* check to see if we found a creation func for this stripe */
    169  1.8.2.1  skrll 		if (stripeFuncs->fp == NULL) {
    170      1.3  oster 			/* could not find creation function for entire stripe
    171      1.3  oster 			 * so, let's see if we can find one for each stripe
    172      1.3  oster 			 * unit in the stripe */
    173  1.8.2.1  skrll 
    174  1.8.2.1  skrll 			/* create a failed stripe structure to attempt to deal with the failure */
    175  1.8.2.1  skrll 			failed_stripe = rf_AllocFailedStripeStruct();
    176  1.8.2.1  skrll 			if (failed_stripes_list == NULL) {
    177  1.8.2.1  skrll 				failed_stripes_list = failed_stripe;
    178  1.8.2.1  skrll 				failed_stripes_list_end = failed_stripe;
    179  1.8.2.1  skrll 			} else {
    180  1.8.2.1  skrll 				failed_stripes_list_end->next = failed_stripe;
    181  1.8.2.1  skrll 				failed_stripes_list_end = failed_stripe;
    182      1.3  oster 			}
    183  1.8.2.1  skrll 
    184      1.3  oster 			/* create an array of creation funcs (called
    185      1.3  oster 			 * stripeFuncs) for this stripe */
    186      1.3  oster 			numStripeUnits = asm_p->numStripeUnitsAccessed;
    187      1.3  oster 
    188  1.8.2.1  skrll 			/* lookup array of stripeUnitFuncs for this stripe */
    189  1.8.2.1  skrll 			failed_stripes_asmh_u_end = NULL;
    190  1.8.2.1  skrll 			failed_stripes_vfple_end = NULL;
    191      1.3  oster 			for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) {
    192      1.3  oster 				/* remap for series of single stripe-unit
    193      1.3  oster 				 * accesses */
    194      1.3  oster 				address = physPtr->raidAddress;
    195      1.3  oster 				length = physPtr->numSector;
    196      1.3  oster 				buffer = physPtr->bufPtr;
    197      1.3  oster 
    198  1.8.2.1  skrll 				asmhle = rf_AllocASMHeaderListElem();
    199  1.8.2.1  skrll 				if (failed_stripe->asmh_u == NULL) {
    200  1.8.2.1  skrll 					failed_stripe->asmh_u = asmhle;      /* we're the head... */
    201  1.8.2.1  skrll 					failed_stripes_asmh_u_end = asmhle;  /* and the tail      */
    202  1.8.2.1  skrll 				} else {
    203  1.8.2.1  skrll 					/* tack us onto the end of the list */
    204  1.8.2.1  skrll 					failed_stripes_asmh_u_end->next = asmhle;
    205  1.8.2.1  skrll 					failed_stripes_asmh_u_end = asmhle;
    206  1.8.2.1  skrll 				}
    207  1.8.2.1  skrll 
    208  1.8.2.1  skrll 
    209  1.8.2.1  skrll 				asmhle->asmh = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP);
    210  1.8.2.1  skrll 				asm_up = asmhle->asmh->stripeMap;
    211  1.8.2.1  skrll 
    212  1.8.2.1  skrll 				vfple = rf_AllocVFPListElem();
    213  1.8.2.1  skrll 				if (failed_stripe->vfple == NULL) {
    214  1.8.2.1  skrll 					failed_stripe->vfple = vfple;
    215  1.8.2.1  skrll 					failed_stripes_vfple_end = vfple;
    216  1.8.2.1  skrll 				} else {
    217  1.8.2.1  skrll 					failed_stripes_vfple_end->next = vfple;
    218  1.8.2.1  skrll 					failed_stripes_vfple_end = vfple;
    219  1.8.2.1  skrll 				}
    220      1.3  oster 
    221      1.3  oster 				/* get the creation func for this stripe unit */
    222  1.8.2.1  skrll 				(raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_up, &(vfple->fn));
    223      1.3  oster 
    224      1.3  oster 				/* check to see if we found a creation func
    225      1.3  oster 				 * for this stripe unit */
    226  1.8.2.1  skrll 
    227  1.8.2.1  skrll 				if (vfple->fn == (RF_VoidFuncPtr) NULL) {
    228      1.3  oster 					/* could not find creation function
    229      1.3  oster 					 * for stripe unit so, let's see if we
    230      1.3  oster 					 * can find one for each block in the
    231      1.3  oster 					 * stripe unit */
    232  1.8.2.1  skrll 
    233      1.3  oster 					numBlocks = physPtr->numSector;
    234      1.3  oster 					numBlockDags += numBlocks;
    235      1.3  oster 
    236      1.3  oster 					/* lookup array of blockFuncs for this
    237      1.3  oster 					 * stripe unit */
    238      1.3  oster 					for (k = 0; k < numBlocks; k++) {
    239      1.3  oster 						/* remap for series of single
    240      1.3  oster 						 * stripe-unit accesses */
    241      1.3  oster 						address = physPtr->raidAddress + k;
    242      1.3  oster 						length = 1;
    243      1.3  oster 						buffer = physPtr->bufPtr + (k * (1 << raidPtr->logBytesPerSector));
    244      1.3  oster 
    245  1.8.2.1  skrll 						asmhle = rf_AllocASMHeaderListElem();
    246  1.8.2.1  skrll 						if (failed_stripe->asmh_b == NULL) {
    247  1.8.2.1  skrll 							failed_stripe->asmh_b = asmhle;
    248  1.8.2.1  skrll 							failed_stripes_asmh_b_end = asmhle;
    249  1.8.2.1  skrll 						} else {
    250  1.8.2.1  skrll 							failed_stripes_asmh_b_end->next = asmhle;
    251  1.8.2.1  skrll 							failed_stripes_asmh_b_end = asmhle;
    252  1.8.2.1  skrll 						}
    253      1.3  oster 
    254  1.8.2.1  skrll 						asmhle->asmh = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP);
    255  1.8.2.1  skrll 						asm_bp = asmhle->asmh->stripeMap;
    256  1.8.2.1  skrll 
    257  1.8.2.1  skrll 						vfple = rf_AllocVFPListElem();
    258  1.8.2.1  skrll 						if (failed_stripe->bvfple == NULL) {
    259  1.8.2.1  skrll 							failed_stripe->bvfple = vfple;
    260  1.8.2.1  skrll 							failed_stripes_bvfple_end = vfple;
    261  1.8.2.1  skrll 						} else {
    262  1.8.2.1  skrll 							failed_stripes_bvfple_end->next = vfple;
    263  1.8.2.1  skrll 							failed_stripes_bvfple_end = vfple;
    264  1.8.2.1  skrll 						}
    265  1.8.2.1  skrll 						(raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_bp, &(vfple->fn));
    266      1.3  oster 
    267      1.3  oster 						/* check to see if we found a
    268      1.3  oster 						 * creation func for this
    269      1.3  oster 						 * stripe unit */
    270  1.8.2.1  skrll 
    271  1.8.2.1  skrll 						if (vfple->fn == NULL)
    272      1.3  oster 							cantCreateDAGs = RF_TRUE;
    273      1.3  oster 					}
    274      1.3  oster 					numStripeUnitsBailed++;
    275      1.3  oster 				} else {
    276      1.3  oster 					numUnitDags++;
    277      1.3  oster 				}
    278      1.3  oster 			}
    279      1.3  oster 			RF_ASSERT(j == numStripeUnits);
    280      1.3  oster 			numStripesBailed++;
    281      1.3  oster 		}
    282      1.1  oster 	}
    283      1.3  oster 
    284      1.3  oster 	if (cantCreateDAGs) {
    285      1.3  oster 		/* free memory and punt */
    286      1.3  oster 		if (numStripesBailed > 0) {
    287      1.3  oster 			stripeNum = 0;
    288  1.8.2.1  skrll 			stripeFuncs = stripeFuncsList;
    289  1.8.2.1  skrll 			failed_stripe = failed_stripes_list;
    290  1.8.2.1  skrll 			for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    291  1.8.2.1  skrll 				if (stripeFuncs->fp == NULL) {
    292  1.8.2.1  skrll 
    293  1.8.2.1  skrll 					asmhle = failed_stripe->asmh_u;
    294  1.8.2.1  skrll 					while (asmhle) {
    295  1.8.2.1  skrll 						tmpasmhle= asmhle;
    296  1.8.2.1  skrll 						asmhle = tmpasmhle->next;
    297  1.8.2.1  skrll 						rf_FreeAccessStripeMap(tmpasmhle->asmh);
    298  1.8.2.1  skrll 						rf_FreeASMHeaderListElem(tmpasmhle);
    299  1.8.2.1  skrll 					}
    300  1.8.2.1  skrll 
    301  1.8.2.1  skrll 					asmhle = failed_stripe->asmh_b;
    302  1.8.2.1  skrll 					while (asmhle) {
    303  1.8.2.1  skrll 						tmpasmhle= asmhle;
    304  1.8.2.1  skrll 						asmhle = tmpasmhle->next;
    305  1.8.2.1  skrll 						rf_FreeAccessStripeMap(tmpasmhle->asmh);
    306  1.8.2.1  skrll 						rf_FreeASMHeaderListElem(tmpasmhle);
    307  1.8.2.1  skrll 					}
    308  1.8.2.1  skrll 
    309  1.8.2.1  skrll 					vfple = failed_stripe->vfple;
    310  1.8.2.1  skrll 					while (vfple) {
    311  1.8.2.1  skrll 						tmpvfple = vfple;
    312  1.8.2.1  skrll 						vfple = tmpvfple->next;
    313  1.8.2.1  skrll 						rf_FreeVFPListElem(tmpvfple);
    314  1.8.2.1  skrll 					}
    315  1.8.2.1  skrll 
    316  1.8.2.1  skrll 					vfple = failed_stripe->bvfple;
    317  1.8.2.1  skrll 					while (vfple) {
    318  1.8.2.1  skrll 						tmpvfple = vfple;
    319  1.8.2.1  skrll 						vfple = tmpvfple->next;
    320  1.8.2.1  skrll 						rf_FreeVFPListElem(tmpvfple);
    321  1.8.2.1  skrll 					}
    322  1.8.2.1  skrll 
    323      1.3  oster 					stripeNum++;
    324  1.8.2.1  skrll 					/* only move to the next failed stripe slot if the current one was used */
    325  1.8.2.1  skrll 					tmpfailed_stripe = failed_stripe;
    326  1.8.2.1  skrll 					failed_stripe = failed_stripe->next;
    327  1.8.2.1  skrll 					rf_FreeFailedStripeStruct(tmpfailed_stripe);
    328      1.3  oster 				}
    329  1.8.2.1  skrll 				stripeFuncs = stripeFuncs->next;
    330  1.8.2.1  skrll 			}
    331      1.3  oster 			RF_ASSERT(stripeNum == numStripesBailed);
    332      1.3  oster 		}
    333  1.8.2.1  skrll 		while (stripeFuncsList != NULL) {
    334  1.8.2.1  skrll 			temp = stripeFuncsList;
    335  1.8.2.1  skrll 			stripeFuncsList = stripeFuncsList->next;
    336  1.8.2.1  skrll 			rf_FreeFuncList(temp);
    337  1.8.2.1  skrll 		}
    338  1.8.2.1  skrll 		desc->numStripes = 0;
    339      1.3  oster 		return (1);
    340      1.3  oster 	} else {
    341      1.3  oster 		/* begin dag creation */
    342      1.3  oster 		stripeNum = 0;
    343      1.3  oster 		stripeUnitNum = 0;
    344      1.3  oster 
    345  1.8.2.1  skrll 		/* create a list of dagLists and fill them in */
    346  1.8.2.1  skrll 
    347  1.8.2.1  skrll 		dagListend = NULL;
    348      1.3  oster 
    349  1.8.2.1  skrll 		stripeFuncs = stripeFuncsList;
    350  1.8.2.1  skrll 		failed_stripe = failed_stripes_list;
    351      1.3  oster 		for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    352      1.3  oster 			/* grab dag header for this stripe */
    353      1.3  oster 			dag_h = NULL;
    354      1.3  oster 
    355  1.8.2.1  skrll 			dagList = rf_AllocDAGList();
    356  1.8.2.1  skrll 
    357  1.8.2.1  skrll 			/* always tack the new dagList onto the end of the list... */
    358  1.8.2.1  skrll 			if (dagListend == NULL) {
    359  1.8.2.1  skrll 				desc->dagList = dagList;
    360  1.8.2.1  skrll 			} else {
    361  1.8.2.1  skrll 				dagListend->next = dagList;
    362  1.8.2.1  skrll 			}
    363  1.8.2.1  skrll 			dagListend = dagList;
    364  1.8.2.1  skrll 
    365  1.8.2.1  skrll 			dagList->desc = desc;
    366  1.8.2.1  skrll 
    367  1.8.2.1  skrll 			if (stripeFuncs->fp == NULL) {
    368      1.3  oster 				/* use bailout functions for this stripe */
    369  1.8.2.1  skrll 				asmhle = failed_stripe->asmh_u;
    370  1.8.2.1  skrll 				vfple = failed_stripe->vfple;
    371  1.8.2.1  skrll 				/* the following two may contain asm headers and
    372  1.8.2.1  skrll 				   block function pointers for multiple asm within
    373  1.8.2.1  skrll 				   this access.  We initialize tmpasmhle and tmpvfple
    374  1.8.2.1  skrll 				   here in order to allow for that, and for correct
    375  1.8.2.1  skrll 				   operation below */
    376  1.8.2.1  skrll 				tmpasmhle = failed_stripe->asmh_b;
    377  1.8.2.1  skrll 				tmpvfple = failed_stripe->bvfple;
    378      1.3  oster 				for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) {
    379  1.8.2.1  skrll 					uFunc = vfple->fn; /* stripeUnitFuncs[stripeNum][j]; */
    380      1.3  oster 					if (uFunc == (RF_VoidFuncPtr) NULL) {
    381      1.3  oster 						/* use bailout functions for
    382      1.3  oster 						 * this stripe unit */
    383      1.3  oster 						for (k = 0; k < physPtr->numSector; k++) {
    384      1.3  oster 							/* create a dag for
    385      1.3  oster 							 * this block */
    386  1.8.2.1  skrll 							InitHdrNode(&tempdag_h, raidPtr, desc);
    387  1.8.2.1  skrll 							dagList->numDags++;
    388      1.3  oster 							if (dag_h == NULL) {
    389      1.3  oster 								dag_h = tempdag_h;
    390      1.3  oster 							} else {
    391      1.3  oster 								lastdag_h->next = tempdag_h;
    392      1.3  oster 							}
    393      1.3  oster 							lastdag_h = tempdag_h;
    394      1.3  oster 
    395  1.8.2.1  skrll 							bFunc = tmpvfple->fn; /* blockFuncs[stripeUnitNum][k]; */
    396      1.3  oster 							RF_ASSERT(bFunc);
    397  1.8.2.1  skrll 							asm_bp = tmpasmhle->asmh->stripeMap; /* asmh_b[stripeUnitNum][k]->stripeMap; */
    398      1.3  oster 							(*bFunc) (raidPtr, asm_bp, tempdag_h, bp, flags, tempdag_h->allocList);
    399  1.8.2.1  skrll 
    400  1.8.2.1  skrll 							tmpasmhle = tmpasmhle->next;
    401  1.8.2.1  skrll 							tmpvfple = tmpvfple->next;
    402      1.3  oster 						}
    403      1.3  oster 						stripeUnitNum++;
    404      1.3  oster 					} else {
    405      1.3  oster 						/* create a dag for this unit */
    406  1.8.2.1  skrll 						InitHdrNode(&tempdag_h, raidPtr, desc);
    407  1.8.2.1  skrll 						dagList->numDags++;
    408      1.3  oster 						if (dag_h == NULL) {
    409      1.3  oster 							dag_h = tempdag_h;
    410      1.3  oster 						} else {
    411      1.3  oster 							lastdag_h->next = tempdag_h;
    412      1.3  oster 						}
    413      1.3  oster 						lastdag_h = tempdag_h;
    414      1.3  oster 
    415  1.8.2.1  skrll 						asm_up = asmhle->asmh->stripeMap; /* asmh_u[stripeNum][j]->stripeMap; */
    416      1.3  oster 						(*uFunc) (raidPtr, asm_up, tempdag_h, bp, flags, tempdag_h->allocList);
    417      1.3  oster 					}
    418  1.8.2.1  skrll 					asmhle = asmhle->next;
    419  1.8.2.1  skrll 					vfple = vfple->next;
    420      1.3  oster 				}
    421      1.3  oster 				RF_ASSERT(j == asm_p->numStripeUnitsAccessed);
    422      1.3  oster 				/* merge linked bailout dag to existing dag
    423      1.3  oster 				 * collection */
    424      1.3  oster 				stripeNum++;
    425  1.8.2.1  skrll 				failed_stripe = failed_stripe->next;
    426      1.3  oster 			} else {
    427      1.3  oster 				/* Create a dag for this parity stripe */
    428  1.8.2.1  skrll 				InitHdrNode(&tempdag_h, raidPtr, desc);
    429  1.8.2.1  skrll 				dagList->numDags++;
    430      1.3  oster 				if (dag_h == NULL) {
    431      1.3  oster 					dag_h = tempdag_h;
    432      1.3  oster 				} else {
    433      1.3  oster 					lastdag_h->next = tempdag_h;
    434      1.3  oster 				}
    435      1.3  oster 				lastdag_h = tempdag_h;
    436      1.3  oster 
    437  1.8.2.1  skrll 				(stripeFuncs->fp) (raidPtr, asm_p, tempdag_h, bp, flags, tempdag_h->allocList);
    438      1.1  oster 			}
    439  1.8.2.1  skrll 			dagList->dags = dag_h;
    440  1.8.2.1  skrll 			stripeFuncs = stripeFuncs->next;
    441      1.3  oster 		}
    442      1.3  oster 		RF_ASSERT(i == desc->numStripes);
    443      1.3  oster 
    444      1.3  oster 		/* free memory */
    445      1.3  oster 		if ((numStripesBailed > 0) || (numStripeUnitsBailed > 0)) {
    446      1.3  oster 			stripeNum = 0;
    447      1.3  oster 			stripeUnitNum = 0;
    448      1.3  oster 			if (dag_h->asmList) {
    449      1.3  oster 				endASMList = dag_h->asmList;
    450      1.3  oster 				while (endASMList->next)
    451      1.3  oster 					endASMList = endASMList->next;
    452      1.3  oster 			} else
    453      1.3  oster 				endASMList = NULL;
    454      1.3  oster 			/* walk through io, stripe by stripe */
    455  1.8.2.1  skrll 			/* here we build up dag_h->asmList for this dag...
    456  1.8.2.1  skrll 			   we need all of these asm's to do the IO, and
    457  1.8.2.1  skrll 			   want them in a convenient place for freeing at a
    458  1.8.2.1  skrll 			   later time */
    459  1.8.2.1  skrll 			stripeFuncs = stripeFuncsList;
    460  1.8.2.1  skrll 			failed_stripe = failed_stripes_list;
    461  1.8.2.1  skrll 			for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    462  1.8.2.1  skrll 				if (stripeFuncs->fp == NULL) {
    463      1.3  oster 					numStripeUnits = asm_p->numStripeUnitsAccessed;
    464      1.3  oster 					/* walk through stripe, stripe unit by
    465      1.3  oster 					 * stripe unit */
    466  1.8.2.1  skrll 					asmhle = failed_stripe->asmh_u;
    467  1.8.2.1  skrll 					vfple = failed_stripe->vfple;
    468  1.8.2.1  skrll 					/* this contains all of the asm headers for block funcs,
    469  1.8.2.1  skrll 					   so we have to initialize this here instead of below.*/
    470  1.8.2.1  skrll 					tmpasmhle = failed_stripe->asmh_b;
    471      1.3  oster 					for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) {
    472  1.8.2.1  skrll 						if (vfple->fn == NULL) {
    473      1.3  oster 							numBlocks = physPtr->numSector;
    474      1.3  oster 							/* walk through stripe
    475      1.3  oster 							 * unit, block by
    476      1.3  oster 							 * block */
    477  1.8.2.1  skrll 							for (k = 0; k < numBlocks; k++) {
    478      1.3  oster 								if (dag_h->asmList == NULL) {
    479  1.8.2.1  skrll 									dag_h->asmList = tmpasmhle->asmh; /* asmh_b[stripeUnitNum][k];*/
    480      1.3  oster 									endASMList = dag_h->asmList;
    481      1.3  oster 								} else {
    482  1.8.2.1  skrll 									endASMList->next = tmpasmhle->asmh;
    483      1.3  oster 									endASMList = endASMList->next;
    484      1.3  oster 								}
    485  1.8.2.1  skrll 								tmpasmhle = tmpasmhle->next;
    486  1.8.2.1  skrll 							}
    487      1.3  oster 							stripeUnitNum++;
    488      1.3  oster 						}
    489      1.3  oster 						if (dag_h->asmList == NULL) {
    490  1.8.2.1  skrll 							dag_h->asmList = asmhle->asmh;
    491      1.3  oster 							endASMList = dag_h->asmList;
    492      1.3  oster 						} else {
    493  1.8.2.1  skrll 							endASMList->next = asmhle->asmh;
    494      1.3  oster 							endASMList = endASMList->next;
    495      1.3  oster 						}
    496  1.8.2.1  skrll 						asmhle = asmhle->next;
    497  1.8.2.1  skrll 						vfple = vfple->next;
    498      1.3  oster 					}
    499      1.3  oster 					stripeNum++;
    500  1.8.2.1  skrll 					failed_stripe = failed_stripe->next;
    501      1.3  oster 				}
    502  1.8.2.1  skrll 				stripeFuncs = stripeFuncs->next;
    503  1.8.2.1  skrll 			}
    504      1.3  oster 			RF_ASSERT(stripeNum == numStripesBailed);
    505  1.8.2.1  skrll 			RF_ASSERT(stripeUnitNum == numStripeUnitsBailed);
    506  1.8.2.1  skrll 
    507  1.8.2.1  skrll 			failed_stripe = failed_stripes_list;
    508  1.8.2.1  skrll 			while (failed_stripe) {
    509  1.8.2.1  skrll 
    510  1.8.2.1  skrll 				asmhle = failed_stripe->asmh_u;
    511  1.8.2.1  skrll 				while (asmhle) {
    512  1.8.2.1  skrll 					tmpasmhle= asmhle;
    513  1.8.2.1  skrll 					asmhle = tmpasmhle->next;
    514  1.8.2.1  skrll 					rf_FreeASMHeaderListElem(tmpasmhle);
    515  1.8.2.1  skrll 				}
    516  1.8.2.1  skrll 
    517  1.8.2.1  skrll 				asmhle = failed_stripe->asmh_b;
    518  1.8.2.1  skrll 				while (asmhle) {
    519  1.8.2.1  skrll 					tmpasmhle= asmhle;
    520  1.8.2.1  skrll 					asmhle = tmpasmhle->next;
    521  1.8.2.1  skrll 					rf_FreeASMHeaderListElem(tmpasmhle);
    522  1.8.2.1  skrll 				}
    523  1.8.2.1  skrll 				vfple = failed_stripe->vfple;
    524  1.8.2.1  skrll 				while (vfple) {
    525  1.8.2.1  skrll 					tmpvfple = vfple;
    526  1.8.2.1  skrll 					vfple = tmpvfple->next;
    527  1.8.2.1  skrll 					rf_FreeVFPListElem(tmpvfple);
    528  1.8.2.1  skrll 				}
    529  1.8.2.1  skrll 
    530  1.8.2.1  skrll 				vfple = failed_stripe->bvfple;
    531  1.8.2.1  skrll 				while (vfple) {
    532  1.8.2.1  skrll 					tmpvfple = vfple;
    533  1.8.2.1  skrll 					vfple = tmpvfple->next;
    534  1.8.2.1  skrll 					rf_FreeVFPListElem(tmpvfple);
    535  1.8.2.1  skrll 				}
    536  1.8.2.1  skrll 
    537  1.8.2.1  skrll 				tmpfailed_stripe = failed_stripe;
    538  1.8.2.1  skrll 				failed_stripe = tmpfailed_stripe->next;
    539  1.8.2.1  skrll 				rf_FreeFailedStripeStruct(tmpfailed_stripe);
    540      1.1  oster 			}
    541      1.3  oster 		}
    542  1.8.2.1  skrll 		while (stripeFuncsList != NULL) {
    543  1.8.2.1  skrll 			temp = stripeFuncsList;
    544  1.8.2.1  skrll 			stripeFuncsList = stripeFuncsList->next;
    545  1.8.2.1  skrll 			rf_FreeFuncList(temp);
    546  1.8.2.1  skrll 		}
    547      1.3  oster 		return (0);
    548      1.1  oster 	}
    549      1.1  oster }
    550