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