Home | History | Annotate | Line # | Download | only in raidframe
rf_aselect.c revision 1.23
      1  1.23  oster /*	$NetBSD: rf_aselect.c,v 1.23 2006/03/18 17:34:31 oster 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.23  oster __KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.23 2006/03/18 17:34:31 oster 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.20  oster 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.16  oster static void
     58  1.20  oster 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.17  oster 	(*hdr)->nodes = NULL;
     66   1.3  oster 	(*hdr)->raidPtr = raidPtr;
     67   1.3  oster 	(*hdr)->next = NULL;
     68  1.20  oster 	(*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.12  oster  * create a list of dagLists, one list per parity stripe.
     76  1.12  oster  * 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.21  perry int
    106  1.10  oster 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.12  oster 	RF_DagList_t *dagList, *dagListend;
    117   1.3  oster 	int     i, j, k;
    118  1.13  oster 	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.18  oster 	RF_ASMHeaderListElem_t *asmhle, *tmpasmhle;
    123  1.18  oster 	RF_VoidFunctionPointerListElem_t *vfple, *tmpvfple;
    124  1.18  oster 	RF_FailedStripe_t *failed_stripes_list, *failed_stripes_list_end;
    125  1.18  oster 	RF_FailedStripe_t *tmpfailed_stripe, *failed_stripe = NULL;
    126  1.18  oster 	RF_ASMHeaderListElem_t *failed_stripes_asmh_u_end = NULL;
    127  1.18  oster 	RF_ASMHeaderListElem_t *failed_stripes_asmh_b_end = NULL;
    128  1.18  oster 	RF_VoidFunctionPointerListElem_t *failed_stripes_vfple_end = NULL;
    129  1.18  oster 	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.13  oster 	stripeFuncsList = NULL;
    148  1.13  oster 	stripeFuncsEnd = NULL;
    149   1.3  oster 
    150  1.18  oster 	failed_stripes_list = NULL;
    151  1.18  oster 	failed_stripes_list_end = NULL;
    152  1.18  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.13  oster 		stripeFuncs = rf_AllocFuncList();
    159  1.13  oster 
    160  1.13  oster 		if (stripeFuncsEnd == NULL) {
    161  1.13  oster 			stripeFuncsList = stripeFuncs;
    162  1.13  oster 		} else {
    163  1.13  oster 			stripeFuncsEnd->next = stripeFuncs;
    164  1.13  oster 		}
    165  1.13  oster 		stripeFuncsEnd = stripeFuncs;
    166  1.13  oster 
    167  1.13  oster 		(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.13  oster 		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.21  perry 
    174  1.18  oster 			/* create a failed stripe structure to attempt to deal with the failure */
    175  1.18  oster 			failed_stripe = rf_AllocFailedStripeStruct();
    176  1.18  oster 			if (failed_stripes_list == NULL) {
    177  1.18  oster 				failed_stripes_list = failed_stripe;
    178  1.18  oster 				failed_stripes_list_end = failed_stripe;
    179  1.18  oster 			} else {
    180  1.18  oster 				failed_stripes_list_end->next = failed_stripe;
    181  1.18  oster 				failed_stripes_list_end = failed_stripe;
    182  1.18  oster 			}
    183   1.3  oster 
    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.21  perry 			/* lookup array of stripeUnitFuncs for this stripe */
    189  1.18  oster 			failed_stripes_asmh_u_end = NULL;
    190  1.18  oster 			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.18  oster 				asmhle = rf_AllocASMHeaderListElem();
    199  1.18  oster 				if (failed_stripe->asmh_u == NULL) {
    200  1.18  oster 					failed_stripe->asmh_u = asmhle;      /* we're the head... */
    201  1.18  oster 					failed_stripes_asmh_u_end = asmhle;  /* and the tail      */
    202  1.18  oster 				} else {
    203  1.18  oster 					/* tack us onto the end of the list */
    204  1.18  oster 					failed_stripes_asmh_u_end->next = asmhle;
    205  1.18  oster 					failed_stripes_asmh_u_end = asmhle;
    206  1.18  oster 				}
    207  1.21  perry 
    208  1.21  perry 
    209  1.18  oster 				asmhle->asmh = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP);
    210  1.18  oster 				asm_up = asmhle->asmh->stripeMap;
    211  1.18  oster 
    212  1.18  oster 				vfple = rf_AllocVFPListElem();
    213  1.18  oster 				if (failed_stripe->vfple == NULL) {
    214  1.18  oster 					failed_stripe->vfple = vfple;
    215  1.18  oster 					failed_stripes_vfple_end = vfple;
    216  1.18  oster 				} else {
    217  1.18  oster 					failed_stripes_vfple_end->next = vfple;
    218  1.18  oster 					failed_stripes_vfple_end = vfple;
    219  1.18  oster 				}
    220   1.3  oster 
    221   1.3  oster 				/* get the creation func for this stripe unit */
    222  1.18  oster 				(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.18  oster 
    227  1.18  oster 				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.18  oster 
    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.18  oster 						asmhle = rf_AllocASMHeaderListElem();
    246  1.18  oster 						if (failed_stripe->asmh_b == NULL) {
    247  1.18  oster 							failed_stripe->asmh_b = asmhle;
    248  1.18  oster 							failed_stripes_asmh_b_end = asmhle;
    249  1.18  oster 						} else {
    250  1.18  oster 							failed_stripes_asmh_b_end->next = asmhle;
    251  1.18  oster 							failed_stripes_asmh_b_end = asmhle;
    252  1.18  oster 						}
    253   1.3  oster 
    254  1.18  oster 						asmhle->asmh = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP);
    255  1.18  oster 						asm_bp = asmhle->asmh->stripeMap;
    256  1.21  perry 
    257  1.18  oster 						vfple = rf_AllocVFPListElem();
    258  1.18  oster 						if (failed_stripe->bvfple == NULL) {
    259  1.18  oster 							failed_stripe->bvfple = vfple;
    260  1.18  oster 							failed_stripes_bvfple_end = vfple;
    261  1.18  oster 						} else {
    262  1.18  oster 							failed_stripes_bvfple_end->next = vfple;
    263  1.18  oster 							failed_stripes_bvfple_end = vfple;
    264  1.18  oster 						}
    265  1.18  oster 						(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.18  oster 
    271  1.18  oster 						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.13  oster 			stripeFuncs = stripeFuncsList;
    289  1.18  oster 			failed_stripe = failed_stripes_list;
    290  1.13  oster 			for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    291  1.13  oster 				if (stripeFuncs->fp == NULL) {
    292  1.18  oster 
    293  1.18  oster 					asmhle = failed_stripe->asmh_u;
    294  1.18  oster 					while (asmhle) {
    295  1.18  oster 						tmpasmhle= asmhle;
    296  1.18  oster 						asmhle = tmpasmhle->next;
    297  1.18  oster 						rf_FreeAccessStripeMap(tmpasmhle->asmh);
    298  1.18  oster 						rf_FreeASMHeaderListElem(tmpasmhle);
    299  1.18  oster 					}
    300  1.18  oster 
    301  1.18  oster 					asmhle = failed_stripe->asmh_b;
    302  1.18  oster 					while (asmhle) {
    303  1.18  oster 						tmpasmhle= asmhle;
    304  1.18  oster 						asmhle = tmpasmhle->next;
    305  1.18  oster 						rf_FreeAccessStripeMap(tmpasmhle->asmh);
    306  1.18  oster 						rf_FreeASMHeaderListElem(tmpasmhle);
    307  1.18  oster 					}
    308  1.21  perry 
    309  1.18  oster 					vfple = failed_stripe->vfple;
    310  1.18  oster 					while (vfple) {
    311  1.18  oster 						tmpvfple = vfple;
    312  1.18  oster 						vfple = tmpvfple->next;
    313  1.18  oster 						rf_FreeVFPListElem(tmpvfple);
    314  1.18  oster 					}
    315  1.18  oster 
    316  1.18  oster 					vfple = failed_stripe->bvfple;
    317  1.18  oster 					while (vfple) {
    318  1.18  oster 						tmpvfple = vfple;
    319  1.18  oster 						vfple = tmpvfple->next;
    320  1.18  oster 						rf_FreeVFPListElem(tmpvfple);
    321  1.18  oster 					}
    322  1.18  oster 
    323   1.3  oster 					stripeNum++;
    324  1.18  oster 					/* only move to the next failed stripe slot if the current one was used */
    325  1.18  oster 					tmpfailed_stripe = failed_stripe;
    326  1.18  oster 					failed_stripe = failed_stripe->next;
    327  1.18  oster 					rf_FreeFailedStripeStruct(tmpfailed_stripe);
    328   1.3  oster 				}
    329  1.13  oster 				stripeFuncs = stripeFuncs->next;
    330  1.13  oster 			}
    331   1.3  oster 			RF_ASSERT(stripeNum == numStripesBailed);
    332   1.3  oster 		}
    333  1.13  oster 		while (stripeFuncsList != NULL) {
    334  1.13  oster 			temp = stripeFuncsList;
    335  1.13  oster 			stripeFuncsList = stripeFuncsList->next;
    336  1.13  oster 			rf_FreeFuncList(temp);
    337  1.13  oster 		}
    338  1.11  oster 		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.12  oster 		/* create a list of dagLists and fill them in */
    346  1.12  oster 
    347  1.12  oster 		dagListend = NULL;
    348   1.3  oster 
    349  1.13  oster 		stripeFuncs = stripeFuncsList;
    350  1.18  oster 		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.12  oster 
    355  1.12  oster 			dagList = rf_AllocDAGList();
    356  1.12  oster 
    357  1.12  oster 			/* always tack the new dagList onto the end of the list... */
    358  1.12  oster 			if (dagListend == NULL) {
    359  1.12  oster 				desc->dagList = dagList;
    360  1.12  oster 			} else {
    361  1.12  oster 				dagListend->next = dagList;
    362  1.12  oster 			}
    363  1.12  oster 			dagListend = dagList;
    364  1.12  oster 
    365  1.12  oster 			dagList->desc = desc;
    366   1.3  oster 
    367  1.13  oster 			if (stripeFuncs->fp == NULL) {
    368   1.3  oster 				/* use bailout functions for this stripe */
    369  1.18  oster 				asmhle = failed_stripe->asmh_u;
    370  1.18  oster 				vfple = failed_stripe->vfple;
    371  1.18  oster 				/* the following two may contain asm headers and
    372  1.18  oster 				   block function pointers for multiple asm within
    373  1.18  oster 				   this access.  We initialize tmpasmhle and tmpvfple
    374  1.18  oster 				   here in order to allow for that, and for correct
    375  1.18  oster 				   operation below */
    376  1.18  oster 				tmpasmhle = failed_stripe->asmh_b;
    377  1.18  oster 				tmpvfple = failed_stripe->bvfple;
    378   1.3  oster 				for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) {
    379  1.18  oster 					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.20  oster 							InitHdrNode(&tempdag_h, raidPtr, desc);
    387  1.12  oster 							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.18  oster 							bFunc = tmpvfple->fn; /* blockFuncs[stripeUnitNum][k]; */
    396   1.3  oster 							RF_ASSERT(bFunc);
    397  1.18  oster 							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.18  oster 
    400  1.18  oster 							tmpasmhle = tmpasmhle->next;
    401  1.18  oster 							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.20  oster 						InitHdrNode(&tempdag_h, raidPtr, desc);
    407  1.12  oster 						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.18  oster 						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.18  oster 					asmhle = asmhle->next;
    419  1.18  oster 					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.18  oster 				failed_stripe = failed_stripe->next;
    426   1.3  oster 			} else {
    427   1.3  oster 				/* Create a dag for this parity stripe */
    428  1.20  oster 				InitHdrNode(&tempdag_h, raidPtr, desc);
    429  1.12  oster 				dagList->numDags++;
    430  1.23  oster 				dag_h = tempdag_h;
    431   1.3  oster 				lastdag_h = tempdag_h;
    432   1.3  oster 
    433  1.13  oster 				(stripeFuncs->fp) (raidPtr, asm_p, tempdag_h, bp, flags, tempdag_h->allocList);
    434   1.1  oster 			}
    435  1.12  oster 			dagList->dags = dag_h;
    436  1.13  oster 			stripeFuncs = stripeFuncs->next;
    437   1.3  oster 		}
    438   1.3  oster 		RF_ASSERT(i == desc->numStripes);
    439   1.3  oster 
    440   1.3  oster 		/* free memory */
    441   1.3  oster 		if ((numStripesBailed > 0) || (numStripeUnitsBailed > 0)) {
    442   1.3  oster 			stripeNum = 0;
    443   1.3  oster 			stripeUnitNum = 0;
    444   1.3  oster 			if (dag_h->asmList) {
    445   1.3  oster 				endASMList = dag_h->asmList;
    446   1.3  oster 				while (endASMList->next)
    447   1.3  oster 					endASMList = endASMList->next;
    448   1.3  oster 			} else
    449   1.3  oster 				endASMList = NULL;
    450   1.3  oster 			/* walk through io, stripe by stripe */
    451  1.18  oster 			/* here we build up dag_h->asmList for this dag...
    452  1.18  oster 			   we need all of these asm's to do the IO, and
    453  1.18  oster 			   want them in a convenient place for freeing at a
    454  1.18  oster 			   later time */
    455  1.13  oster 			stripeFuncs = stripeFuncsList;
    456  1.18  oster 			failed_stripe = failed_stripes_list;
    457  1.13  oster 			for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    458  1.13  oster 				if (stripeFuncs->fp == NULL) {
    459   1.3  oster 					numStripeUnits = asm_p->numStripeUnitsAccessed;
    460   1.3  oster 					/* walk through stripe, stripe unit by
    461   1.3  oster 					 * stripe unit */
    462  1.18  oster 					asmhle = failed_stripe->asmh_u;
    463  1.18  oster 					vfple = failed_stripe->vfple;
    464  1.18  oster 					/* this contains all of the asm headers for block funcs,
    465  1.18  oster 					   so we have to initialize this here instead of below.*/
    466  1.18  oster 					tmpasmhle = failed_stripe->asmh_b;
    467   1.3  oster 					for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) {
    468  1.18  oster 						if (vfple->fn == NULL) {
    469   1.3  oster 							numBlocks = physPtr->numSector;
    470   1.3  oster 							/* walk through stripe
    471   1.3  oster 							 * unit, block by
    472   1.3  oster 							 * block */
    473  1.18  oster 							for (k = 0; k < numBlocks; k++) {
    474   1.3  oster 								if (dag_h->asmList == NULL) {
    475  1.18  oster 									dag_h->asmList = tmpasmhle->asmh; /* asmh_b[stripeUnitNum][k];*/
    476   1.3  oster 									endASMList = dag_h->asmList;
    477   1.3  oster 								} else {
    478  1.18  oster 									endASMList->next = tmpasmhle->asmh;
    479   1.3  oster 									endASMList = endASMList->next;
    480   1.3  oster 								}
    481  1.18  oster 								tmpasmhle = tmpasmhle->next;
    482  1.18  oster 							}
    483   1.3  oster 							stripeUnitNum++;
    484   1.3  oster 						}
    485   1.3  oster 						if (dag_h->asmList == NULL) {
    486  1.18  oster 							dag_h->asmList = asmhle->asmh;
    487   1.3  oster 							endASMList = dag_h->asmList;
    488   1.3  oster 						} else {
    489  1.18  oster 							endASMList->next = asmhle->asmh;
    490   1.3  oster 							endASMList = endASMList->next;
    491   1.3  oster 						}
    492  1.18  oster 						asmhle = asmhle->next;
    493  1.18  oster 						vfple = vfple->next;
    494   1.3  oster 					}
    495   1.3  oster 					stripeNum++;
    496  1.18  oster 					failed_stripe = failed_stripe->next;
    497   1.3  oster 				}
    498  1.13  oster 				stripeFuncs = stripeFuncs->next;
    499  1.13  oster 			}
    500   1.3  oster 			RF_ASSERT(stripeNum == numStripesBailed);
    501  1.19  oster 			RF_ASSERT(stripeUnitNum == numStripeUnitsBailed);
    502  1.18  oster 
    503  1.19  oster 			failed_stripe = failed_stripes_list;
    504  1.19  oster 			while (failed_stripe) {
    505  1.18  oster 
    506  1.19  oster 				asmhle = failed_stripe->asmh_u;
    507  1.19  oster 				while (asmhle) {
    508  1.19  oster 					tmpasmhle= asmhle;
    509  1.19  oster 					asmhle = tmpasmhle->next;
    510  1.19  oster 					rf_FreeASMHeaderListElem(tmpasmhle);
    511  1.19  oster 				}
    512  1.18  oster 
    513  1.19  oster 				asmhle = failed_stripe->asmh_b;
    514  1.19  oster 				while (asmhle) {
    515  1.19  oster 					tmpasmhle= asmhle;
    516  1.19  oster 					asmhle = tmpasmhle->next;
    517  1.19  oster 					rf_FreeASMHeaderListElem(tmpasmhle);
    518  1.19  oster 				}
    519  1.19  oster 				vfple = failed_stripe->vfple;
    520  1.19  oster 				while (vfple) {
    521  1.19  oster 					tmpvfple = vfple;
    522  1.19  oster 					vfple = tmpvfple->next;
    523  1.19  oster 					rf_FreeVFPListElem(tmpvfple);
    524  1.19  oster 				}
    525  1.21  perry 
    526  1.19  oster 				vfple = failed_stripe->bvfple;
    527  1.19  oster 				while (vfple) {
    528  1.19  oster 					tmpvfple = vfple;
    529  1.19  oster 					vfple = tmpvfple->next;
    530  1.19  oster 					rf_FreeVFPListElem(tmpvfple);
    531  1.18  oster 				}
    532  1.21  perry 
    533  1.19  oster 				tmpfailed_stripe = failed_stripe;
    534  1.19  oster 				failed_stripe = tmpfailed_stripe->next;
    535  1.19  oster 				rf_FreeFailedStripeStruct(tmpfailed_stripe);
    536   1.1  oster 			}
    537   1.3  oster 		}
    538  1.13  oster 		while (stripeFuncsList != NULL) {
    539  1.13  oster 			temp = stripeFuncsList;
    540  1.13  oster 			stripeFuncsList = stripeFuncsList->next;
    541  1.13  oster 			rf_FreeFuncList(temp);
    542  1.13  oster 		}
    543   1.3  oster 		return (0);
    544   1.1  oster 	}
    545   1.1  oster }
    546