rf_aselect.c revision 1.8.2.4 1 1.8.2.4 skrll /* $NetBSD: rf_aselect.c,v 1.8.2.4 2005/03/04 16:50:05 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.4 skrll __KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.8.2.4 2005/03/04 16:50:05 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.8.2.4 skrll 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.4 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.4 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.4 skrll
208 1.8.2.4 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.4 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.4 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.4 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.4 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