Home | History | Annotate | Line # | Download | only in raidframe
      1  1.31    andvar /*	$NetBSD: rf_aselect.c,v 1.31 2022/03/20 19:26:27 andvar 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.31    andvar __KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.31 2022/03/20 19:26:27 andvar 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.31    andvar  * Create and Initialize 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.30     oster 	*hdr = rf_AllocDAGHeader(raidPtr);
     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.21     perry int
    104  1.10     oster rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
    105   1.1     oster {
    106   1.3     oster 	RF_AccessStripeMapHeader_t *asm_h = desc->asmap;
    107   1.3     oster 	RF_IoType_t type = desc->type;
    108   1.3     oster 	RF_Raid_t *raidPtr = desc->raidPtr;
    109   1.3     oster 	void   *bp = desc->bp;
    110   1.3     oster 
    111   1.3     oster 	RF_AccessStripeMap_t *asmap = asm_h->stripeMap;
    112   1.3     oster 	RF_AccessStripeMap_t *asm_p;
    113   1.3     oster 	RF_DagHeader_t *dag_h = NULL, *tempdag_h, *lastdag_h;
    114  1.12     oster 	RF_DagList_t *dagList, *dagListend;
    115   1.3     oster 	int     i, j, k;
    116  1.13     oster 	RF_FuncList_t *stripeFuncsList, *stripeFuncs, *stripeFuncsEnd, *temp;
    117   1.3     oster 	RF_AccessStripeMap_t *asm_up, *asm_bp;
    118  1.28    martin 	RF_AccessStripeMapHeader_t *endASMList;
    119  1.18     oster 	RF_ASMHeaderListElem_t *asmhle, *tmpasmhle;
    120  1.18     oster 	RF_VoidFunctionPointerListElem_t *vfple, *tmpvfple;
    121  1.18     oster 	RF_FailedStripe_t *failed_stripes_list, *failed_stripes_list_end;
    122  1.18     oster 	RF_FailedStripe_t *tmpfailed_stripe, *failed_stripe = NULL;
    123  1.18     oster 	RF_ASMHeaderListElem_t *failed_stripes_asmh_u_end = NULL;
    124  1.18     oster 	RF_ASMHeaderListElem_t *failed_stripes_asmh_b_end = NULL;
    125  1.18     oster 	RF_VoidFunctionPointerListElem_t *failed_stripes_vfple_end = NULL;
    126  1.18     oster 	RF_VoidFunctionPointerListElem_t *failed_stripes_bvfple_end = NULL;
    127  1.28    martin 	RF_VoidFuncPtr uFunc;
    128  1.28    martin 	RF_VoidFuncPtr bFunc;
    129   1.3     oster 	int     numStripesBailed = 0, cantCreateDAGs = RF_FALSE;
    130   1.3     oster 	int     numStripeUnitsBailed = 0;
    131  1.29  christos 	int     stripeNum, stripeUnitNum, numBlockDags = 0;
    132   1.3     oster 	RF_StripeNum_t numStripeUnits;
    133   1.3     oster 	RF_SectorNum_t numBlocks;
    134   1.3     oster 	RF_RaidAddr_t address;
    135   1.3     oster 	int     length;
    136   1.3     oster 	RF_PhysDiskAddr_t *physPtr;
    137  1.25  christos 	void *buffer;
    138   1.3     oster 
    139   1.3     oster 	lastdag_h = NULL;
    140   1.3     oster 
    141  1.13     oster 	stripeFuncsList = NULL;
    142  1.13     oster 	stripeFuncsEnd = NULL;
    143   1.3     oster 
    144  1.18     oster 	failed_stripes_list = NULL;
    145  1.18     oster 	failed_stripes_list_end = NULL;
    146  1.18     oster 
    147   1.3     oster 	/* walk through the asm list once collecting information */
    148   1.3     oster 	/* attempt to find a single creation function for each stripe */
    149   1.3     oster 	desc->numStripes = 0;
    150   1.3     oster 	for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    151   1.3     oster 		desc->numStripes++;
    152  1.30     oster 		stripeFuncs = rf_AllocFuncList(raidPtr);
    153  1.13     oster 
    154  1.13     oster 		if (stripeFuncsEnd == NULL) {
    155  1.13     oster 			stripeFuncsList = stripeFuncs;
    156  1.13     oster 		} else {
    157  1.13     oster 			stripeFuncsEnd->next = stripeFuncs;
    158  1.13     oster 		}
    159  1.13     oster 		stripeFuncsEnd = stripeFuncs;
    160  1.13     oster 
    161  1.13     oster 		(raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_p, &(stripeFuncs->fp));
    162   1.3     oster 		/* check to see if we found a creation func for this stripe */
    163  1.13     oster 		if (stripeFuncs->fp == NULL) {
    164   1.3     oster 			/* could not find creation function for entire stripe
    165   1.3     oster 			 * so, let's see if we can find one for each stripe
    166   1.3     oster 			 * unit in the stripe */
    167  1.21     perry 
    168  1.18     oster 			/* create a failed stripe structure to attempt to deal with the failure */
    169  1.30     oster 			failed_stripe = rf_AllocFailedStripeStruct(raidPtr);
    170  1.18     oster 			if (failed_stripes_list == NULL) {
    171  1.18     oster 				failed_stripes_list = failed_stripe;
    172  1.18     oster 				failed_stripes_list_end = failed_stripe;
    173  1.18     oster 			} else {
    174  1.18     oster 				failed_stripes_list_end->next = failed_stripe;
    175  1.18     oster 				failed_stripes_list_end = failed_stripe;
    176  1.18     oster 			}
    177   1.3     oster 
    178   1.3     oster 			/* create an array of creation funcs (called
    179   1.3     oster 			 * stripeFuncs) for this stripe */
    180   1.3     oster 			numStripeUnits = asm_p->numStripeUnitsAccessed;
    181   1.3     oster 
    182  1.21     perry 			/* lookup array of stripeUnitFuncs for this stripe */
    183  1.18     oster 			failed_stripes_asmh_u_end = NULL;
    184  1.18     oster 			failed_stripes_vfple_end = NULL;
    185   1.3     oster 			for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) {
    186   1.3     oster 				/* remap for series of single stripe-unit
    187   1.3     oster 				 * accesses */
    188   1.3     oster 				address = physPtr->raidAddress;
    189   1.3     oster 				length = physPtr->numSector;
    190   1.3     oster 				buffer = physPtr->bufPtr;
    191   1.3     oster 
    192  1.30     oster 				asmhle = rf_AllocASMHeaderListElem(raidPtr);
    193  1.18     oster 				if (failed_stripe->asmh_u == NULL) {
    194  1.18     oster 					failed_stripe->asmh_u = asmhle;      /* we're the head... */
    195  1.18     oster 					failed_stripes_asmh_u_end = asmhle;  /* and the tail      */
    196  1.18     oster 				} else {
    197  1.18     oster 					/* tack us onto the end of the list */
    198  1.18     oster 					failed_stripes_asmh_u_end->next = asmhle;
    199  1.18     oster 					failed_stripes_asmh_u_end = asmhle;
    200  1.18     oster 				}
    201  1.21     perry 
    202  1.21     perry 
    203  1.18     oster 				asmhle->asmh = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP);
    204  1.18     oster 				asm_up = asmhle->asmh->stripeMap;
    205  1.18     oster 
    206  1.30     oster 				vfple = rf_AllocVFPListElem(raidPtr);
    207  1.18     oster 				if (failed_stripe->vfple == NULL) {
    208  1.18     oster 					failed_stripe->vfple = vfple;
    209  1.18     oster 					failed_stripes_vfple_end = vfple;
    210  1.18     oster 				} else {
    211  1.18     oster 					failed_stripes_vfple_end->next = vfple;
    212  1.18     oster 					failed_stripes_vfple_end = vfple;
    213  1.18     oster 				}
    214   1.3     oster 
    215   1.3     oster 				/* get the creation func for this stripe unit */
    216  1.18     oster 				(raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_up, &(vfple->fn));
    217   1.3     oster 
    218   1.3     oster 				/* check to see if we found a creation func
    219   1.3     oster 				 * for this stripe unit */
    220  1.18     oster 
    221  1.27    plunky 				if (vfple->fn == NULL) {
    222   1.3     oster 					/* could not find creation function
    223   1.3     oster 					 * for stripe unit so, let's see if we
    224   1.3     oster 					 * can find one for each block in the
    225   1.3     oster 					 * stripe unit */
    226  1.18     oster 
    227   1.3     oster 					numBlocks = physPtr->numSector;
    228   1.3     oster 					numBlockDags += numBlocks;
    229   1.3     oster 
    230   1.3     oster 					/* lookup array of blockFuncs for this
    231   1.3     oster 					 * stripe unit */
    232   1.3     oster 					for (k = 0; k < numBlocks; k++) {
    233   1.3     oster 						/* remap for series of single
    234   1.3     oster 						 * stripe-unit accesses */
    235   1.3     oster 						address = physPtr->raidAddress + k;
    236   1.3     oster 						length = 1;
    237  1.25  christos 						buffer = (char *)physPtr->bufPtr + (k * (1 << raidPtr->logBytesPerSector));
    238   1.3     oster 
    239  1.30     oster 						asmhle = rf_AllocASMHeaderListElem(raidPtr);
    240  1.18     oster 						if (failed_stripe->asmh_b == NULL) {
    241  1.18     oster 							failed_stripe->asmh_b = asmhle;
    242  1.18     oster 							failed_stripes_asmh_b_end = asmhle;
    243  1.18     oster 						} else {
    244  1.18     oster 							failed_stripes_asmh_b_end->next = asmhle;
    245  1.18     oster 							failed_stripes_asmh_b_end = asmhle;
    246  1.18     oster 						}
    247   1.3     oster 
    248  1.18     oster 						asmhle->asmh = rf_MapAccess(raidPtr, address, length, buffer, RF_DONT_REMAP);
    249  1.18     oster 						asm_bp = asmhle->asmh->stripeMap;
    250  1.21     perry 
    251  1.30     oster 						vfple = rf_AllocVFPListElem(raidPtr);
    252  1.18     oster 						if (failed_stripe->bvfple == NULL) {
    253  1.18     oster 							failed_stripe->bvfple = vfple;
    254  1.18     oster 							failed_stripes_bvfple_end = vfple;
    255  1.18     oster 						} else {
    256  1.18     oster 							failed_stripes_bvfple_end->next = vfple;
    257  1.18     oster 							failed_stripes_bvfple_end = vfple;
    258  1.18     oster 						}
    259  1.18     oster 						(raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_bp, &(vfple->fn));
    260   1.3     oster 
    261   1.3     oster 						/* check to see if we found a
    262   1.3     oster 						 * creation func for this
    263   1.3     oster 						 * stripe unit */
    264  1.18     oster 
    265  1.18     oster 						if (vfple->fn == NULL)
    266   1.3     oster 							cantCreateDAGs = RF_TRUE;
    267   1.3     oster 					}
    268   1.3     oster 					numStripeUnitsBailed++;
    269   1.3     oster 				}
    270   1.3     oster 			}
    271   1.3     oster 			RF_ASSERT(j == numStripeUnits);
    272   1.3     oster 			numStripesBailed++;
    273   1.3     oster 		}
    274   1.1     oster 	}
    275   1.3     oster 
    276   1.3     oster 	if (cantCreateDAGs) {
    277   1.3     oster 		/* free memory and punt */
    278   1.3     oster 		if (numStripesBailed > 0) {
    279   1.3     oster 			stripeNum = 0;
    280  1.13     oster 			stripeFuncs = stripeFuncsList;
    281  1.18     oster 			failed_stripe = failed_stripes_list;
    282  1.13     oster 			for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    283  1.13     oster 				if (stripeFuncs->fp == NULL) {
    284  1.18     oster 
    285  1.18     oster 					asmhle = failed_stripe->asmh_u;
    286  1.18     oster 					while (asmhle) {
    287  1.18     oster 						tmpasmhle= asmhle;
    288  1.18     oster 						asmhle = tmpasmhle->next;
    289  1.30     oster 						rf_FreeAccessStripeMap(raidPtr, tmpasmhle->asmh);
    290  1.30     oster 						rf_FreeASMHeaderListElem(raidPtr, tmpasmhle);
    291  1.18     oster 					}
    292  1.18     oster 
    293  1.18     oster 					asmhle = failed_stripe->asmh_b;
    294  1.18     oster 					while (asmhle) {
    295  1.18     oster 						tmpasmhle= asmhle;
    296  1.18     oster 						asmhle = tmpasmhle->next;
    297  1.30     oster 						rf_FreeAccessStripeMap(raidPtr, tmpasmhle->asmh);
    298  1.30     oster 						rf_FreeASMHeaderListElem(raidPtr, tmpasmhle);
    299  1.18     oster 					}
    300  1.21     perry 
    301  1.18     oster 					vfple = failed_stripe->vfple;
    302  1.18     oster 					while (vfple) {
    303  1.18     oster 						tmpvfple = vfple;
    304  1.18     oster 						vfple = tmpvfple->next;
    305  1.30     oster 						rf_FreeVFPListElem(raidPtr, tmpvfple);
    306  1.18     oster 					}
    307  1.18     oster 
    308  1.18     oster 					vfple = failed_stripe->bvfple;
    309  1.18     oster 					while (vfple) {
    310  1.18     oster 						tmpvfple = vfple;
    311  1.18     oster 						vfple = tmpvfple->next;
    312  1.30     oster 						rf_FreeVFPListElem(raidPtr, tmpvfple);
    313  1.18     oster 					}
    314  1.18     oster 
    315   1.3     oster 					stripeNum++;
    316  1.18     oster 					/* only move to the next failed stripe slot if the current one was used */
    317  1.18     oster 					tmpfailed_stripe = failed_stripe;
    318  1.18     oster 					failed_stripe = failed_stripe->next;
    319  1.30     oster 					rf_FreeFailedStripeStruct(raidPtr, tmpfailed_stripe);
    320   1.3     oster 				}
    321  1.13     oster 				stripeFuncs = stripeFuncs->next;
    322  1.13     oster 			}
    323   1.3     oster 			RF_ASSERT(stripeNum == numStripesBailed);
    324   1.3     oster 		}
    325  1.13     oster 		while (stripeFuncsList != NULL) {
    326  1.13     oster 			temp = stripeFuncsList;
    327  1.13     oster 			stripeFuncsList = stripeFuncsList->next;
    328  1.30     oster 			rf_FreeFuncList(raidPtr, temp);
    329  1.13     oster 		}
    330  1.11     oster 		desc->numStripes = 0;
    331   1.3     oster 		return (1);
    332   1.3     oster 	} else {
    333   1.3     oster 		/* begin dag creation */
    334   1.3     oster 		stripeNum = 0;
    335   1.3     oster 		stripeUnitNum = 0;
    336   1.3     oster 
    337  1.12     oster 		/* create a list of dagLists and fill them in */
    338  1.12     oster 
    339  1.12     oster 		dagListend = NULL;
    340   1.3     oster 
    341  1.13     oster 		stripeFuncs = stripeFuncsList;
    342  1.18     oster 		failed_stripe = failed_stripes_list;
    343   1.3     oster 		for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    344   1.3     oster 			/* grab dag header for this stripe */
    345   1.3     oster 			dag_h = NULL;
    346  1.12     oster 
    347  1.30     oster 			dagList = rf_AllocDAGList(raidPtr);
    348  1.12     oster 
    349  1.12     oster 			/* always tack the new dagList onto the end of the list... */
    350  1.12     oster 			if (dagListend == NULL) {
    351  1.12     oster 				desc->dagList = dagList;
    352  1.12     oster 			} else {
    353  1.12     oster 				dagListend->next = dagList;
    354  1.12     oster 			}
    355  1.12     oster 			dagListend = dagList;
    356  1.12     oster 
    357  1.12     oster 			dagList->desc = desc;
    358   1.3     oster 
    359  1.13     oster 			if (stripeFuncs->fp == NULL) {
    360   1.3     oster 				/* use bailout functions for this stripe */
    361  1.18     oster 				asmhle = failed_stripe->asmh_u;
    362  1.18     oster 				vfple = failed_stripe->vfple;
    363  1.18     oster 				/* the following two may contain asm headers and
    364  1.18     oster 				   block function pointers for multiple asm within
    365  1.18     oster 				   this access.  We initialize tmpasmhle and tmpvfple
    366  1.18     oster 				   here in order to allow for that, and for correct
    367  1.18     oster 				   operation below */
    368  1.18     oster 				tmpasmhle = failed_stripe->asmh_b;
    369  1.18     oster 				tmpvfple = failed_stripe->bvfple;
    370   1.3     oster 				for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) {
    371  1.18     oster 					uFunc = vfple->fn; /* stripeUnitFuncs[stripeNum][j]; */
    372  1.27    plunky 					if (uFunc == NULL) {
    373   1.3     oster 						/* use bailout functions for
    374   1.3     oster 						 * this stripe unit */
    375   1.3     oster 						for (k = 0; k < physPtr->numSector; k++) {
    376   1.3     oster 							/* create a dag for
    377   1.3     oster 							 * this block */
    378  1.20     oster 							InitHdrNode(&tempdag_h, raidPtr, desc);
    379  1.12     oster 							dagList->numDags++;
    380   1.3     oster 							if (dag_h == NULL) {
    381   1.3     oster 								dag_h = tempdag_h;
    382   1.3     oster 							} else {
    383   1.3     oster 								lastdag_h->next = tempdag_h;
    384   1.3     oster 							}
    385   1.3     oster 							lastdag_h = tempdag_h;
    386   1.3     oster 
    387  1.18     oster 							bFunc = tmpvfple->fn; /* blockFuncs[stripeUnitNum][k]; */
    388   1.3     oster 							RF_ASSERT(bFunc);
    389  1.18     oster 							asm_bp = tmpasmhle->asmh->stripeMap; /* asmh_b[stripeUnitNum][k]->stripeMap; */
    390   1.3     oster 							(*bFunc) (raidPtr, asm_bp, tempdag_h, bp, flags, tempdag_h->allocList);
    391  1.18     oster 
    392  1.18     oster 							tmpasmhle = tmpasmhle->next;
    393  1.18     oster 							tmpvfple = tmpvfple->next;
    394   1.3     oster 						}
    395   1.3     oster 						stripeUnitNum++;
    396   1.3     oster 					} else {
    397   1.3     oster 						/* create a dag for this unit */
    398  1.20     oster 						InitHdrNode(&tempdag_h, raidPtr, desc);
    399  1.12     oster 						dagList->numDags++;
    400   1.3     oster 						if (dag_h == NULL) {
    401   1.3     oster 							dag_h = tempdag_h;
    402   1.3     oster 						} else {
    403   1.3     oster 							lastdag_h->next = tempdag_h;
    404   1.3     oster 						}
    405   1.3     oster 						lastdag_h = tempdag_h;
    406   1.3     oster 
    407  1.18     oster 						asm_up = asmhle->asmh->stripeMap; /* asmh_u[stripeNum][j]->stripeMap; */
    408   1.3     oster 						(*uFunc) (raidPtr, asm_up, tempdag_h, bp, flags, tempdag_h->allocList);
    409   1.3     oster 					}
    410  1.18     oster 					asmhle = asmhle->next;
    411  1.18     oster 					vfple = vfple->next;
    412   1.3     oster 				}
    413   1.3     oster 				RF_ASSERT(j == asm_p->numStripeUnitsAccessed);
    414   1.3     oster 				/* merge linked bailout dag to existing dag
    415   1.3     oster 				 * collection */
    416   1.3     oster 				stripeNum++;
    417  1.18     oster 				failed_stripe = failed_stripe->next;
    418   1.3     oster 			} else {
    419   1.3     oster 				/* Create a dag for this parity stripe */
    420  1.20     oster 				InitHdrNode(&tempdag_h, raidPtr, desc);
    421  1.12     oster 				dagList->numDags++;
    422  1.23     oster 				dag_h = tempdag_h;
    423   1.3     oster 				lastdag_h = tempdag_h;
    424   1.3     oster 
    425  1.13     oster 				(stripeFuncs->fp) (raidPtr, asm_p, tempdag_h, bp, flags, tempdag_h->allocList);
    426   1.1     oster 			}
    427  1.12     oster 			dagList->dags = dag_h;
    428  1.13     oster 			stripeFuncs = stripeFuncs->next;
    429   1.3     oster 		}
    430   1.3     oster 		RF_ASSERT(i == desc->numStripes);
    431   1.3     oster 
    432   1.3     oster 		/* free memory */
    433   1.3     oster 		if ((numStripesBailed > 0) || (numStripeUnitsBailed > 0)) {
    434   1.3     oster 			stripeNum = 0;
    435   1.3     oster 			stripeUnitNum = 0;
    436   1.3     oster 			/* walk through io, stripe by stripe */
    437  1.18     oster 			/* here we build up dag_h->asmList for this dag...
    438  1.18     oster 			   we need all of these asm's to do the IO, and
    439  1.18     oster 			   want them in a convenient place for freeing at a
    440  1.18     oster 			   later time */
    441  1.13     oster 			stripeFuncs = stripeFuncsList;
    442  1.18     oster 			failed_stripe = failed_stripes_list;
    443  1.24     oster 			dagList = desc->dagList;
    444  1.24     oster 
    445  1.13     oster 			for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
    446  1.24     oster 
    447  1.24     oster 				dag_h = dagList->dags;
    448  1.24     oster 				if (dag_h->asmList) {
    449  1.24     oster 					endASMList = dag_h->asmList;
    450  1.24     oster 					while (endASMList->next)
    451  1.24     oster 						endASMList = endASMList->next;
    452  1.24     oster 				} else
    453  1.24     oster 					endASMList = NULL;
    454  1.24     oster 
    455  1.24     oster 				if (stripeFuncs->fp == NULL) {
    456   1.3     oster 					numStripeUnits = asm_p->numStripeUnitsAccessed;
    457   1.3     oster 					/* walk through stripe, stripe unit by
    458   1.3     oster 					 * stripe unit */
    459  1.18     oster 					asmhle = failed_stripe->asmh_u;
    460  1.18     oster 					vfple = failed_stripe->vfple;
    461  1.18     oster 					/* this contains all of the asm headers for block funcs,
    462  1.18     oster 					   so we have to initialize this here instead of below.*/
    463  1.18     oster 					tmpasmhle = failed_stripe->asmh_b;
    464   1.3     oster 					for (j = 0, physPtr = asm_p->physInfo; physPtr; physPtr = physPtr->next, j++) {
    465  1.18     oster 						if (vfple->fn == NULL) {
    466   1.3     oster 							numBlocks = physPtr->numSector;
    467   1.3     oster 							/* walk through stripe
    468   1.3     oster 							 * unit, block by
    469   1.3     oster 							 * block */
    470  1.18     oster 							for (k = 0; k < numBlocks; k++) {
    471   1.3     oster 								if (dag_h->asmList == NULL) {
    472  1.18     oster 									dag_h->asmList = tmpasmhle->asmh; /* asmh_b[stripeUnitNum][k];*/
    473   1.3     oster 									endASMList = dag_h->asmList;
    474   1.3     oster 								} else {
    475  1.18     oster 									endASMList->next = tmpasmhle->asmh;
    476   1.3     oster 									endASMList = endASMList->next;
    477   1.3     oster 								}
    478  1.18     oster 								tmpasmhle = tmpasmhle->next;
    479  1.18     oster 							}
    480   1.3     oster 							stripeUnitNum++;
    481   1.3     oster 						}
    482   1.3     oster 						if (dag_h->asmList == NULL) {
    483  1.18     oster 							dag_h->asmList = asmhle->asmh;
    484   1.3     oster 							endASMList = dag_h->asmList;
    485   1.3     oster 						} else {
    486  1.18     oster 							endASMList->next = asmhle->asmh;
    487   1.3     oster 							endASMList = endASMList->next;
    488   1.3     oster 						}
    489  1.18     oster 						asmhle = asmhle->next;
    490  1.18     oster 						vfple = vfple->next;
    491   1.3     oster 					}
    492   1.3     oster 					stripeNum++;
    493  1.18     oster 					failed_stripe = failed_stripe->next;
    494   1.3     oster 				}
    495  1.24     oster 				dagList = dagList->next; /* need to move in stride with stripeFuncs */
    496  1.13     oster 				stripeFuncs = stripeFuncs->next;
    497  1.13     oster 			}
    498   1.3     oster 			RF_ASSERT(stripeNum == numStripesBailed);
    499  1.19     oster 			RF_ASSERT(stripeUnitNum == numStripeUnitsBailed);
    500  1.18     oster 
    501  1.19     oster 			failed_stripe = failed_stripes_list;
    502  1.19     oster 			while (failed_stripe) {
    503  1.18     oster 
    504  1.19     oster 				asmhle = failed_stripe->asmh_u;
    505  1.19     oster 				while (asmhle) {
    506  1.19     oster 					tmpasmhle= asmhle;
    507  1.19     oster 					asmhle = tmpasmhle->next;
    508  1.30     oster 					rf_FreeASMHeaderListElem(raidPtr, tmpasmhle);
    509  1.19     oster 				}
    510  1.18     oster 
    511  1.19     oster 				asmhle = failed_stripe->asmh_b;
    512  1.19     oster 				while (asmhle) {
    513  1.19     oster 					tmpasmhle= asmhle;
    514  1.19     oster 					asmhle = tmpasmhle->next;
    515  1.30     oster 					rf_FreeASMHeaderListElem(raidPtr, tmpasmhle);
    516  1.19     oster 				}
    517  1.19     oster 				vfple = failed_stripe->vfple;
    518  1.19     oster 				while (vfple) {
    519  1.19     oster 					tmpvfple = vfple;
    520  1.19     oster 					vfple = tmpvfple->next;
    521  1.30     oster 					rf_FreeVFPListElem(raidPtr, tmpvfple);
    522  1.19     oster 				}
    523  1.21     perry 
    524  1.19     oster 				vfple = failed_stripe->bvfple;
    525  1.19     oster 				while (vfple) {
    526  1.19     oster 					tmpvfple = vfple;
    527  1.19     oster 					vfple = tmpvfple->next;
    528  1.30     oster 					rf_FreeVFPListElem(raidPtr, tmpvfple);
    529  1.18     oster 				}
    530  1.21     perry 
    531  1.19     oster 				tmpfailed_stripe = failed_stripe;
    532  1.19     oster 				failed_stripe = tmpfailed_stripe->next;
    533  1.30     oster 				rf_FreeFailedStripeStruct(raidPtr, tmpfailed_stripe);
    534   1.1     oster 			}
    535   1.3     oster 		}
    536  1.13     oster 		while (stripeFuncsList != NULL) {
    537  1.13     oster 			temp = stripeFuncsList;
    538  1.13     oster 			stripeFuncsList = stripeFuncsList->next;
    539  1.30     oster 			rf_FreeFuncList(raidPtr, temp);
    540  1.13     oster 		}
    541   1.3     oster 		return (0);
    542   1.1     oster 	}
    543   1.1     oster }
    544