Annotation of sys/dev/raidframe/rf_aselect.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: rf_aselect.c,v 1.3 2002/12/16 07:01:03 tdeval Exp $ */
2: /* $NetBSD: rf_aselect.c,v 1.3 1999/02/05 00:06:06 oster Exp $ */
3:
4: /*
5: * Copyright (c) 1995 Carnegie-Mellon University.
6: * All rights reserved.
7: *
8: * Author: Mark Holland, William V. Courtright II
9: *
10: * Permission to use, copy, modify and distribute this software and
11: * its documentation is hereby granted, provided that both the copyright
12: * notice and this permission notice appear in all copies of the
13: * software, derivative works or modified versions, and any portions
14: * thereof, and that both notices appear in supporting documentation.
15: *
16: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19: *
20: * Carnegie Mellon requests users of this software to return to
21: *
22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23: * School of Computer Science
24: * Carnegie Mellon University
25: * Pittsburgh PA 15213-3890
26: *
27: * any improvements or extensions that they make and grant Carnegie the
28: * rights to redistribute these changes.
29: */
30:
31: /****************************************************************************
32: *
33: * aselect.c -- algorithm selection code
34: *
35: *****************************************************************************/
36:
37:
38: #include "rf_archs.h"
39: #include "rf_types.h"
40: #include "rf_raid.h"
41: #include "rf_dag.h"
42: #include "rf_dagutils.h"
43: #include "rf_dagfuncs.h"
44: #include "rf_general.h"
45: #include "rf_desc.h"
46: #include "rf_map.h"
47:
48: #if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)
49: /* The function below is not used... so don't define it! */
50: #else
51: void rf_TransferDagMemory(RF_DagHeader_t *, RF_DagHeader_t *);
52: #endif
53:
54: int rf_InitHdrNode(RF_DagHeader_t **, RF_Raid_t *, int);
55: void rf_UpdateNodeHdrPtr(RF_DagHeader_t *, RF_DagNode_t *);
56: int rf_SelectAlgorithm(RF_RaidAccessDesc_t *, RF_RaidAccessFlags_t);
57:
58:
59: /*****************************************************************************
60: *
61: * Create and Initialize a dag header and termination node.
62: *
63: *****************************************************************************/
64: int
65: rf_InitHdrNode(RF_DagHeader_t **hdr, RF_Raid_t *raidPtr, int memChunkEnable)
66: {
67: /* Create and initialize dag hdr. */
68: *hdr = rf_AllocDAGHeader();
69: rf_MakeAllocList((*hdr)->allocList);
70: if ((*hdr)->allocList == NULL) {
71: rf_FreeDAGHeader(*hdr);
72: return (ENOMEM);
73: }
74: (*hdr)->status = rf_enable;
75: (*hdr)->numSuccedents = 0;
76: (*hdr)->raidPtr = raidPtr;
77: (*hdr)->next = NULL;
78: return (0);
79: }
80:
81:
82: /*****************************************************************************
83: *
84: * Transfer allocation list and mem chunks from one dag to another.
85: *
86: *****************************************************************************/
87: #if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)
88: /* The function below is not used... so don't define it! */
89: #else
90: void
91: rf_TransferDagMemory(RF_DagHeader_t *daga, RF_DagHeader_t *dagb)
92: {
93: RF_AccessStripeMapHeader_t *end;
94: RF_AllocListElem_t *p;
95: int i, memChunksXfrd = 0, xtraChunksXfrd = 0;
96:
97: /* Transfer allocList from dagb to daga. */
98: for (p = dagb->allocList; p; p = p->next) {
99: for (i = 0; i < p->numPointers; i++) {
100: rf_AddToAllocList(daga->allocList, p->pointers[i],
101: p->sizes[i]);
102: p->pointers[i] = NULL;
103: p->sizes[i] = 0;
104: }
105: p->numPointers = 0;
106: }
107:
108: /* Transfer chunks from dagb to daga. */
109: while ((memChunksXfrd + xtraChunksXfrd <
110: dagb->chunkIndex + dagb->xtraChunkIndex) &&
111: (daga->chunkIndex < RF_MAXCHUNKS)) {
112: /* Stuff chunks into daga's memChunk array. */
113: if (memChunksXfrd < dagb->chunkIndex) {
114: daga->memChunk[daga->chunkIndex++] =
115: dagb->memChunk[memChunksXfrd];
116: dagb->memChunk[memChunksXfrd++] = NULL;
117: } else {
118: daga->memChunk[daga->xtraChunkIndex++] =
119: dagb->xtraMemChunk[xtraChunksXfrd];
120: dagb->xtraMemChunk[xtraChunksXfrd++] = NULL;
121: }
122: }
123: /* Use escape hatch to hold excess chunks. */
124: while (memChunksXfrd + xtraChunksXfrd <
125: dagb->chunkIndex + dagb->xtraChunkIndex) {
126: if (memChunksXfrd < dagb->chunkIndex) {
127: daga->xtraMemChunk[daga->xtraChunkIndex++] =
128: dagb->memChunk[memChunksXfrd];
129: dagb->memChunk[memChunksXfrd++] = NULL;
130: } else {
131: daga->xtraMemChunk[daga->xtraChunkIndex++] =
132: dagb->xtraMemChunk[xtraChunksXfrd];
133: dagb->xtraMemChunk[xtraChunksXfrd++] = NULL;
134: }
135: }
136: RF_ASSERT((memChunksXfrd == dagb->chunkIndex) &&
137: (xtraChunksXfrd == dagb->xtraChunkIndex));
138: RF_ASSERT(daga->chunkIndex <= RF_MAXCHUNKS);
139: RF_ASSERT(daga->xtraChunkIndex <= daga->xtraChunkCnt);
140: dagb->chunkIndex = 0;
141: dagb->xtraChunkIndex = 0;
142:
143: /* Transfer asmList from dagb to daga. */
144: if (dagb->asmList) {
145: if (daga->asmList) {
146: end = daga->asmList;
147: while (end->next)
148: end = end->next;
149: end->next = dagb->asmList;
150: } else
151: daga->asmList = dagb->asmList;
152: dagb->asmList = NULL;
153: }
154: }
155: #endif /* __NetBSD__ || __OpenBSD__ */
156:
157:
158: /*****************************************************************************
159: *
160: * Ensure that all node->dagHdr fields in a dag are consistent.
161: *
162: * IMPORTANT: This routine recursively searches all succedents of the node.
163: * If a succedent is encountered whose dagHdr ptr does not require adjusting,
164: * that node's succedents WILL NOT BE EXAMINED.
165: *
166: *****************************************************************************/
167: void
168: rf_UpdateNodeHdrPtr(RF_DagHeader_t *hdr, RF_DagNode_t *node)
169: {
170: int i;
171: RF_ASSERT(hdr != NULL && node != NULL);
172: for (i = 0; i < node->numSuccedents; i++)
173: if (node->succedents[i]->dagHdr != hdr)
174: rf_UpdateNodeHdrPtr(hdr, node->succedents[i]);
175: node->dagHdr = hdr;
176: }
177:
178:
179: /*****************************************************************************
180: *
181: * Create a DAG to do a read or write operation.
182: *
183: * Create an array of dagLists, one list per parity stripe.
184: * Return the lists in the array desc->dagArray.
185: *
186: * Normally, each list contains one dag for the entire stripe. In some
187: * tricky cases, we break this into multiple dags, either one per stripe
188: * unit or one per block (sector). When this occurs, these dags are returned
189: * as a linked list (dagList) which is executed sequentially (to preserve
190: * atomic parity updates in the stripe).
191: *
192: * Dags that operate on independent parity goups (stripes) are returned in
193: * independent dagLists (distinct elements in desc->dagArray) and may be
194: * executed concurrently.
195: *
196: * Finally, if the SelectionFunc fails to create a dag for a block, we punt
197: * and return 1.
198: *
199: * The above process is performed in two phases:
200: * 1) create an array(s) of creation functions (eg stripeFuncs)
201: * 2) create dags and concatenate/merge to form the final dag.
202: *
203: * Because dag's are basic blocks (single entry, single exit, unconditional
204: * control flow), we can add the following optimizations (future work):
205: * first-pass optimizer to allow max concurrency (need all data dependencies)
206: * second-pass optimizer to eliminate common subexpressions (need true
207: * data dependencies)
208: * third-pass optimizer to eliminate dead code (need true data dependencies)
209: *****************************************************************************/
210:
211: #define MAXNSTRIPES 50
212:
213: int
214: rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags)
215: {
216: RF_AccessStripeMapHeader_t *asm_h = desc->asmap;
217: RF_IoType_t type = desc->type;
218: RF_Raid_t *raidPtr = desc->raidPtr;
219: void *bp = desc->bp;
220:
221: RF_AccessStripeMap_t *asmap = asm_h->stripeMap;
222: RF_AccessStripeMap_t *asm_p;
223: RF_DagHeader_t *dag_h = NULL, *tempdag_h, *lastdag_h;
224: int i, j, k;
225: RF_VoidFuncPtr *stripeFuncs, normalStripeFuncs[MAXNSTRIPES];
226: RF_AccessStripeMap_t *asm_up, *asm_bp;
227: RF_AccessStripeMapHeader_t ***asmh_u, *endASMList;
228: RF_AccessStripeMapHeader_t ***asmh_b;
229: RF_VoidFuncPtr **stripeUnitFuncs, uFunc;
230: RF_VoidFuncPtr **blockFuncs, bFunc;
231: int numStripesBailed = 0, cantCreateDAGs = RF_FALSE;
232: int numStripeUnitsBailed = 0;
233: int stripeNum, numUnitDags = 0, stripeUnitNum, numBlockDags = 0;
234: RF_StripeNum_t numStripeUnits;
235: RF_SectorNum_t numBlocks;
236: RF_RaidAddr_t address;
237: int length;
238: RF_PhysDiskAddr_t *physPtr;
239: caddr_t buffer;
240:
241: lastdag_h = NULL;
242: asmh_u = asmh_b = NULL;
243: stripeUnitFuncs = NULL;
244: blockFuncs = NULL;
245:
246: /*
247: * Get an array of dag-function creation pointers.
248: * Try to avoid calling malloc.
249: */
250: if (asm_h->numStripes <= MAXNSTRIPES)
251: stripeFuncs = normalStripeFuncs;
252: else
253: RF_Calloc(stripeFuncs, asm_h->numStripes,
254: sizeof(RF_VoidFuncPtr), (RF_VoidFuncPtr *));
255:
256: /*
257: * Walk through the asm list once collecting information.
258: * Attempt to find a single creation function for each stripe.
259: */
260: desc->numStripes = 0;
261: for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
262: desc->numStripes++;
263: (raidPtr->Layout.map->SelectionFunc) (raidPtr, type, asm_p,
264: &stripeFuncs[i]);
265: /* Check to see if we found a creation func for this stripe. */
266: if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) {
267: /*
268: * Could not find creation function for entire stripe.
269: * So, let's see if we can find one for each stripe
270: * unit in the stripe.
271: */
272:
273: if (numStripesBailed == 0) {
274: /*
275: * One stripe map header for each stripe we
276: * bail on.
277: */
278: RF_Malloc(asmh_u,
279: sizeof(RF_AccessStripeMapHeader_t **) *
280: asm_h->numStripes,
281: (RF_AccessStripeMapHeader_t ***));
282: /*
283: * Create an array of ptrs to arrays of
284: * stripeFuncs.
285: */
286: RF_Calloc(stripeUnitFuncs, asm_h->numStripes,
287: sizeof(RF_VoidFuncPtr),
288: (RF_VoidFuncPtr **));
289: }
290: /*
291: * Create an array of creation funcs (called
292: * stripeFuncs) for this stripe.
293: */
294: numStripeUnits = asm_p->numStripeUnitsAccessed;
295: RF_Calloc(stripeUnitFuncs[numStripesBailed],
296: numStripeUnits, sizeof(RF_VoidFuncPtr),
297: (RF_VoidFuncPtr *));
298: RF_Malloc(asmh_u[numStripesBailed], numStripeUnits *
299: sizeof(RF_AccessStripeMapHeader_t *),
300: (RF_AccessStripeMapHeader_t **));
301:
302: /* Lookup array of stripeUnitFuncs for this stripe. */
303: for (j = 0, physPtr = asm_p->physInfo; physPtr;
304: physPtr = physPtr->next, j++) {
305: /*
306: * Remap for series of single stripe-unit
307: * accesses.
308: */
309: address = physPtr->raidAddress;
310: length = physPtr->numSector;
311: buffer = physPtr->bufPtr;
312:
313: asmh_u[numStripesBailed][j] =
314: rf_MapAccess(raidPtr, address, length,
315: buffer, RF_DONT_REMAP);
316: asm_up = asmh_u[numStripesBailed][j]->stripeMap;
317:
318: /*
319: * Get the creation func for this
320: * stripe unit.
321: */
322: (raidPtr->Layout.map->SelectionFunc) (raidPtr,
323: type, asm_up,
324: &(stripeUnitFuncs[numStripesBailed][j]));
325:
326: /*
327: * Check to see if we found a creation func
328: * for this stripe unit.
329: */
330: if (stripeUnitFuncs[numStripesBailed][j] ==
331: (RF_VoidFuncPtr) NULL) {
332: /*
333: * Could not find creation function
334: * for stripe unit. So, let's see if
335: * we can find one for each block in
336: * the stripe unit.
337: */
338: if (numStripeUnitsBailed == 0) {
339: /*
340: * one stripe map header for
341: * each stripe unit we bail on.
342: */
343: RF_Malloc(asmh_b,
344: sizeof(RF_AccessStripeMapHeader_t **) *
345: asm_h->numStripes *
346: raidPtr->Layout.numDataCol,
347: (RF_AccessStripeMapHeader_t ***));
348: /*
349: * Create an array of ptrs to
350: * arrays of blockFuncs.
351: */
352: RF_Calloc(blockFuncs,
353: asm_h->numStripes *
354: raidPtr->Layout.numDataCol,
355: sizeof(RF_VoidFuncPtr),
356: (RF_VoidFuncPtr **));
357: }
358: /*
359: * Create an array of creation funcs
360: * (called blockFuncs) for this stripe
361: * unit.
362: */
363: numBlocks = physPtr->numSector;
364: numBlockDags += numBlocks;
365: RF_Calloc(
366: blockFuncs[numStripeUnitsBailed],
367: numBlocks, sizeof(RF_VoidFuncPtr),
368: (RF_VoidFuncPtr *));
369: RF_Malloc(asmh_b[numStripeUnitsBailed],
370: numBlocks *
371: sizeof(RF_AccessStripeMapHeader_t *),
372: (RF_AccessStripeMapHeader_t **));
373:
374: /*
375: * Lookup array of blockFuncs for this
376: * stripe unit.
377: */
378: for (k = 0; k < numBlocks; k++) {
379: /*
380: * Remap for series of single
381: * stripe-unit accesses.
382: */
383: address = physPtr->raidAddress
384: + k;
385: length = 1;
386: buffer = physPtr->bufPtr +
387: (k * (1 <<
388: raidPtr->logBytesPerSector));
389:
390: asmh_b[numStripeUnitsBailed][k]
391: = rf_MapAccess(raidPtr,
392: address, length, buffer,
393: RF_DONT_REMAP);
394: asm_bp =
395: asmh_b[numStripeUnitsBailed][k]->stripeMap;
396:
397: /*
398: * Get the creation func for
399: * this stripe unit.
400: */
401: (raidPtr->Layout.map->
402: SelectionFunc) (raidPtr,
403: type, asm_bp,
404: &(blockFuncs[numStripeUnitsBailed][k]));
405:
406: /*
407: * Check to see if we found a
408: * creation func for this
409: * stripe unit.
410: */
411: if (blockFuncs
412: [numStripeUnitsBailed][k]
413: == NULL)
414: cantCreateDAGs =
415: RF_TRUE;
416: }
417: numStripeUnitsBailed++;
418: } else {
419: numUnitDags++;
420: }
421: }
422: RF_ASSERT(j == numStripeUnits);
423: numStripesBailed++;
424: }
425: }
426:
427: if (cantCreateDAGs) {
428: /* Free memory and punt. */
429: if (asm_h->numStripes > MAXNSTRIPES)
430: RF_Free(stripeFuncs, asm_h->numStripes *
431: sizeof(RF_VoidFuncPtr));
432: if (numStripesBailed > 0) {
433: stripeNum = 0;
434: for (i = 0, asm_p = asmap; asm_p;
435: asm_p = asm_p->next, i++)
436: if (stripeFuncs[i] == NULL) {
437: numStripeUnits =
438: asm_p->numStripeUnitsAccessed;
439: for (j = 0; j < numStripeUnits; j++)
440: rf_FreeAccessStripeMap(
441: asmh_u[stripeNum][j]);
442: RF_Free(asmh_u[stripeNum],
443: numStripeUnits *
444: sizeof(RF_AccessStripeMapHeader_t *));
445: RF_Free(stripeUnitFuncs[stripeNum],
446: numStripeUnits *
447: sizeof(RF_VoidFuncPtr));
448: stripeNum++;
449: }
450: RF_ASSERT(stripeNum == numStripesBailed);
451: RF_Free(stripeUnitFuncs, asm_h->numStripes *
452: sizeof(RF_VoidFuncPtr));
453: RF_Free(asmh_u, asm_h->numStripes *
454: sizeof(RF_AccessStripeMapHeader_t **));
455: }
456: return (1);
457: } else {
458: /* Begin dag creation. */
459: stripeNum = 0;
460: stripeUnitNum = 0;
461:
462: /* Create an array of dagLists and fill them in. */
463: RF_CallocAndAdd(desc->dagArray, desc->numStripes,
464: sizeof(RF_DagList_t), (RF_DagList_t *), desc->cleanupList);
465:
466: for (i = 0, asm_p = asmap; asm_p; asm_p = asm_p->next, i++) {
467: /* Grab dag header for this stripe. */
468: dag_h = NULL;
469: desc->dagArray[i].desc = desc;
470:
471: if (stripeFuncs[i] == (RF_VoidFuncPtr) NULL) {
472: /* Use bailout functions for this stripe. */
473: for (j = 0, physPtr = asm_p->physInfo; physPtr;
474: physPtr = physPtr->next, j++) {
475: uFunc = stripeUnitFuncs[stripeNum][j];
476: if (uFunc == (RF_VoidFuncPtr) NULL) {
477: /*
478: * Use bailout functions for
479: * this stripe unit.
480: */
481: for (k = 0; k <
482: physPtr->numSector; k++) {
483: /*
484: * Create a dag for
485: * this block.
486: */
487: rf_InitHdrNode(
488: &tempdag_h,
489: raidPtr,
490: rf_useMemChunks);
491: desc->dagArray[i].
492: numDags++;
493: if (dag_h == NULL) {
494: dag_h =
495: tempdag_h;
496: } else {
497: lastdag_h->next
498: = tempdag_h;
499: }
500: lastdag_h = tempdag_h;
501:
502: bFunc = blockFuncs
503: [stripeUnitNum][k];
504: RF_ASSERT(bFunc);
505: asm_bp = asmh_b
506: [stripeUnitNum][k]
507: ->stripeMap;
508: (*bFunc) (raidPtr,
509: asm_bp, tempdag_h,
510: bp, flags,
511: tempdag_h
512: ->allocList);
513: }
514: stripeUnitNum++;
515: } else {
516: /*
517: * Create a dag for this unit.
518: */
519: rf_InitHdrNode(&tempdag_h,
520: raidPtr, rf_useMemChunks);
521: desc->dagArray[i].numDags++;
522: if (dag_h == NULL) {
523: dag_h = tempdag_h;
524: } else {
525: lastdag_h->next =
526: tempdag_h;
527: }
528: lastdag_h = tempdag_h;
529:
530: asm_up = asmh_u[stripeNum][j]
531: ->stripeMap;
532: (*uFunc) (raidPtr, asm_up,
533: tempdag_h, bp, flags,
534: tempdag_h->allocList);
535: }
536: }
537: RF_ASSERT(j == asm_p->numStripeUnitsAccessed);
538: /*
539: * Merge linked bailout dag to existing dag
540: * collection.
541: */
542: stripeNum++;
543: } else {
544: /* Create a dag for this parity stripe. */
545: rf_InitHdrNode(&tempdag_h, raidPtr,
546: rf_useMemChunks);
547: desc->dagArray[i].numDags++;
548: if (dag_h == NULL) {
549: dag_h = tempdag_h;
550: } else {
551: lastdag_h->next = tempdag_h;
552: }
553: lastdag_h = tempdag_h;
554:
555: (stripeFuncs[i]) (raidPtr, asm_p, tempdag_h,
556: bp, flags, tempdag_h->allocList);
557: }
558: desc->dagArray[i].dags = dag_h;
559: }
560: RF_ASSERT(i == desc->numStripes);
561:
562: /* Free memory. */
563: if (asm_h->numStripes > MAXNSTRIPES)
564: RF_Free(stripeFuncs, asm_h->numStripes *
565: sizeof(RF_VoidFuncPtr));
566: if ((numStripesBailed > 0) || (numStripeUnitsBailed > 0)) {
567: stripeNum = 0;
568: stripeUnitNum = 0;
569: if (dag_h->asmList) {
570: endASMList = dag_h->asmList;
571: while (endASMList->next)
572: endASMList = endASMList->next;
573: } else
574: endASMList = NULL;
575: /* Walk through io, stripe by stripe. */
576: for (i = 0, asm_p = asmap; asm_p;
577: asm_p = asm_p->next, i++)
578: if (stripeFuncs[i] == NULL) {
579: numStripeUnits =
580: asm_p->numStripeUnitsAccessed;
581: /*
582: * Walk through stripe, stripe unit by
583: * stripe unit.
584: */
585: for (j = 0, physPtr = asm_p->physInfo;
586: physPtr;
587: physPtr = physPtr->next, j++) {
588: if (stripeUnitFuncs[stripeNum]
589: [j] == NULL) {
590: numBlocks =
591: physPtr->numSector;
592: /*
593: * Walk through stripe
594: * unit, block by
595: * block.
596: */
597: for (k = 0; k <
598: numBlocks; k++)
599: if (dag_h
600: ->asmList
601: == NULL) {
602: dag_h->asmList =
603: asmh_b[stripeUnitNum][k];
604: endASMList = dag_h->asmList;
605: } else {
606: endASMList->next =
607: asmh_b[stripeUnitNum][k];
608: endASMList = endASMList->next;
609: }
610: RF_Free(asmh_b
611: [stripeUnitNum], numBlocks *
612: sizeof(RF_AccessStripeMapHeader_t *));
613: RF_Free(blockFuncs
614: [stripeUnitNum], numBlocks *
615: sizeof(RF_VoidFuncPtr));
616: stripeUnitNum++;
617: }
618: if (dag_h->asmList == NULL) {
619: dag_h->asmList = asmh_u
620: [stripeNum][j];
621: endASMList = dag_h
622: ->asmList;
623: } else {
624: endASMList->next =
625: asmh_u[stripeNum]
626: [j];
627: endASMList = endASMList
628: ->next;
629: }
630: }
631: RF_Free(asmh_u[stripeNum],
632: numStripeUnits *
633: sizeof(
634: RF_AccessStripeMapHeader_t *));
635: RF_Free(stripeUnitFuncs[stripeNum],
636: numStripeUnits *
637: sizeof(RF_VoidFuncPtr));
638: stripeNum++;
639: }
640: RF_ASSERT(stripeNum == numStripesBailed);
641: RF_Free(stripeUnitFuncs, asm_h->numStripes *
642: sizeof(RF_VoidFuncPtr));
643: RF_Free(asmh_u, asm_h->numStripes *
644: sizeof(RF_AccessStripeMapHeader_t **));
645: if (numStripeUnitsBailed > 0) {
646: RF_ASSERT(stripeUnitNum ==
647: numStripeUnitsBailed);
648: RF_Free(blockFuncs, raidPtr->Layout.numDataCol
649: * asm_h->numStripes *
650: sizeof(RF_VoidFuncPtr));
651: RF_Free(asmh_b, raidPtr->Layout.numDataCol *
652: asm_h->numStripes *
653: sizeof(RF_AccessStripeMapHeader_t **));
654: }
655: }
656: return (0);
657: }
658: }
CVSweb