[BACK]Return to rf_layout.c CVS log [TXT][DIR] Up to [local] / sys / dev / raidframe

Annotation of sys/dev/raidframe/rf_layout.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: rf_layout.c,v 1.7 2007/04/10 17:47:55 miod Exp $      */
                      2: /*     $NetBSD: rf_layout.c,v 1.6 2000/04/17 19:35:12 oster Exp $      */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Carnegie-Mellon University.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Author: Mark Holland
                      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:  * rf_layout.c -- Driver code dealing with layout and mapping issues.
                     33:  */
                     34:
                     35: #include "rf_types.h"
                     36: #include "rf_archs.h"
                     37: #include "rf_raid.h"
                     38: #include "rf_configure.h"
                     39: #include "rf_dag.h"
                     40: #include "rf_desc.h"
                     41: #include "rf_decluster.h"
                     42: #include "rf_pq.h"
                     43: #include "rf_declusterPQ.h"
                     44: #include "rf_raid0.h"
                     45: #include "rf_raid1.h"
                     46: #include "rf_raid4.h"
                     47: #include "rf_raid5.h"
                     48: #include "rf_states.h"
                     49: #if    RF_INCLUDE_RAID5_RS > 0
                     50: #include "rf_raid5_rotatedspare.h"
                     51: #endif /* RF_INCLUDE_RAID5_RS > 0 */
                     52: #if    RF_INCLUDE_CHAINDECLUSTER > 0
                     53: #include "rf_chaindecluster.h"
                     54: #endif /* RF_INCLUDE_CHAINDECLUSTER > 0 */
                     55: #if    RF_INCLUDE_INTERDECLUSTER > 0
                     56: #include "rf_interdecluster.h"
                     57: #endif /* RF_INCLUDE_INTERDECLUSTER > 0 */
                     58: #if    RF_INCLUDE_PARITYLOGGING > 0
                     59: #include "rf_paritylogging.h"
                     60: #endif /* RF_INCLUDE_PARITYLOGGING > 0 */
                     61: #if    RF_INCLUDE_EVENODD > 0
                     62: #include "rf_evenodd.h"
                     63: #endif /* RF_INCLUDE_EVENODD > 0 */
                     64: #include "rf_general.h"
                     65: #include "rf_driver.h"
                     66: #include "rf_parityscan.h"
                     67: #include "rf_reconbuffer.h"
                     68: #include "rf_reconutil.h"
                     69:
                     70: /*****************************************************************************
                     71:  *
                     72:  * The layout switch defines all the layouts that are supported.
                     73:  * Fields are: layout ID, init routine, shutdown routine, map sector,
                     74:  *             map parity, identify stripe, dag selection, map stripeid
                     75:  *             to parity stripe id (optional), num faults tolerated,
                     76:  *             special flags.
                     77:  *
                     78:  *****************************************************************************/
                     79:
                     80: static RF_AccessState_t DefaultStates[] = {
                     81:        rf_QuiesceState, rf_IncrAccessesCountState, rf_MapState,
                     82:        rf_LockState, rf_CreateDAGState, rf_ExecuteDAGState,
                     83:        rf_ProcessDAGState, rf_DecrAccessesCountState,
                     84:        rf_CleanupState, rf_LastState
                     85: };
                     86:
                     87: #if    (defined(__NetBSD__) || defined(__OpenBSD__)) && !defined(_KERNEL)
                     88: /*
                     89:  * XXX Gross hack to shutup gcc -- It complains that DefaultStates is not
                     90:  * used when compiling this in userland... I hate to burst its bubble, but
                     91:  * DefaultStates is used all over the place here in the initialization of
                     92:  * lots of data structures. GO
                     93:  */
                     94: RF_AccessState_t *NothingAtAll = DefaultStates;
                     95: #endif
                     96:
                     97: #if    (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)
                     98: /* XXX Remove static so GCC doesn't complain about these being unused ! */
                     99: int distSpareYes = 1;
                    100: int distSpareNo = 0;
                    101: #else
                    102: static int distSpareYes = 1;
                    103: static int distSpareNo = 0;
                    104: #endif
                    105:
                    106: #ifdef _KERNEL
                    107: #define        RF_NK2(a,b)
                    108: #else  /* _KERNEL */
                    109: #define        RF_NK2(a,b)     a,b,
                    110: #endif /* !_KERNEL */
                    111:
                    112: #if    RF_UTILITY > 0
                    113: #define        RF_NU(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
                    114: #else  /* RF_UTILITY > 0 */
                    115: #define        RF_NU(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)  a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
                    116: #endif /* RF_UTILITY > 0 */
                    117:
                    118: static RF_LayoutSW_t mapsw[] = {
                    119:        /* Parity declustering. */
                    120:        {'T', "Parity declustering",
                    121:                RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
                    122:                RF_NU(
                    123:                    rf_ConfigureDeclustered,
                    124:                    rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
                    125:                    rf_IdentifyStripeDeclustered,
                    126:                    rf_RaidFiveDagSelect,
                    127:                    rf_MapSIDToPSIDDeclustered,
                    128:                    rf_GetDefaultHeadSepLimitDeclustered,
                    129:                    rf_GetDefaultNumFloatingReconBuffersDeclustered,
                    130:                    NULL, NULL,
                    131:                    rf_SubmitReconBufferBasic,
                    132:                    rf_VerifyParityBasic,
                    133:                    1,
                    134:                    DefaultStates,
                    135:                    0)
                    136:        },
                    137:
                    138:        /* Parity declustering with distributed sparing. */
                    139:        {'D', "Distributed sparing parity declustering",
                    140:                RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareYes)
                    141:                RF_NU(
                    142:                    rf_ConfigureDeclusteredDS,
                    143:                    rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
                    144:                    rf_IdentifyStripeDeclustered,
                    145:                    rf_RaidFiveDagSelect,
                    146:                    rf_MapSIDToPSIDDeclustered,
                    147:                    rf_GetDefaultHeadSepLimitDeclustered,
                    148:                    rf_GetDefaultNumFloatingReconBuffersDeclustered,
                    149:                    rf_GetNumSpareRUsDeclustered, rf_InstallSpareTable,
                    150:                    rf_SubmitReconBufferBasic,
                    151:                    rf_VerifyParityBasic,
                    152:                    1,
                    153:                    DefaultStates,
                    154:                    RF_DISTRIBUTE_SPARE | RF_BD_DECLUSTERED)
                    155:        },
                    156:
                    157: #if    RF_INCLUDE_DECL_PQ > 0
                    158:        /* Declustered P+Q. */
                    159:        {'Q', "Declustered P+Q",
                    160:                RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
                    161:                RF_NU(
                    162:                    rf_ConfigureDeclusteredPQ,
                    163:                    rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ,
                    164:                    rf_MapQDeclusteredPQ,
                    165:                    rf_IdentifyStripeDeclusteredPQ,
                    166:                    rf_PQDagSelect,
                    167:                    rf_MapSIDToPSIDDeclustered,
                    168:                    rf_GetDefaultHeadSepLimitDeclustered,
                    169:                    rf_GetDefaultNumFloatingReconBuffersPQ,
                    170:                    NULL, NULL,
                    171:                    NULL,
                    172:                    rf_VerifyParityBasic,
                    173:                    2,
                    174:                    DefaultStates,
                    175:                    0)
                    176:        },
                    177: #endif /* RF_INCLUDE_DECL_PQ > 0 */
                    178:
                    179: #if    RF_INCLUDE_RAID5_RS > 0
                    180:        /* RAID 5 with rotated sparing. */
                    181:        {'R', "RAID Level 5 rotated sparing",
                    182:                RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
                    183:                RF_NU(
                    184:                    rf_ConfigureRAID5_RS,
                    185:                    rf_MapSectorRAID5_RS, rf_MapParityRAID5_RS, NULL,
                    186:                    rf_IdentifyStripeRAID5_RS,
                    187:                    rf_RaidFiveDagSelect,
                    188:                    rf_MapSIDToPSIDRAID5_RS,
                    189:                    rf_GetDefaultHeadSepLimitRAID5,
                    190:                    rf_GetDefaultNumFloatingReconBuffersRAID5,
                    191:                    rf_GetNumSpareRUsRAID5_RS, NULL,
                    192:                    rf_SubmitReconBufferBasic,
                    193:                    rf_VerifyParityBasic,
                    194:                    1,
                    195:                    DefaultStates,
                    196:                    RF_DISTRIBUTE_SPARE)
                    197:        },
                    198: #endif /* RF_INCLUDE_RAID5_RS > 0 */
                    199:
                    200: #if    RF_INCLUDE_CHAINDECLUSTER > 0
                    201:        /* Chained Declustering. */
                    202:        {'C', "Chained Declustering",
                    203:                RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
                    204:                RF_NU(
                    205:                    rf_ConfigureChainDecluster,
                    206:                    rf_MapSectorChainDecluster, rf_MapParityChainDecluster,
                    207:                    NULL,
                    208:                    rf_IdentifyStripeChainDecluster,
                    209:                    rf_RAIDCDagSelect,
                    210:                    rf_MapSIDToPSIDChainDecluster,
                    211:                    NULL,
                    212:                    NULL,
                    213:                    rf_GetNumSpareRUsChainDecluster, NULL,
                    214:                    rf_SubmitReconBufferBasic,
                    215:                    rf_VerifyParityBasic,
                    216:                    1,
                    217:                    DefaultStates,
                    218:                    0)
                    219:        },
                    220: #endif /* RF_INCLUDE_CHAINDECLUSTER > 0 */
                    221:
                    222: #if    RF_INCLUDE_INTERDECLUSTER > 0
                    223:        /* Interleaved Declustering. */
                    224:        {'I', "Interleaved Declustering",
                    225:                RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
                    226:                RF_NU(
                    227:                    rf_ConfigureInterDecluster,
                    228:                    rf_MapSectorInterDecluster, rf_MapParityInterDecluster,
                    229:                    NULL,
                    230:                    rf_IdentifyStripeInterDecluster,
                    231:                    rf_RAIDIDagSelect,
                    232:                    rf_MapSIDToPSIDInterDecluster,
                    233:                    rf_GetDefaultHeadSepLimitInterDecluster,
                    234:                    rf_GetDefaultNumFloatingReconBuffersInterDecluster,
                    235:                    rf_GetNumSpareRUsInterDecluster, NULL,
                    236:                    rf_SubmitReconBufferBasic,
                    237:                    rf_VerifyParityBasic,
                    238:                    1,
                    239:                    DefaultStates,
                    240:                    RF_DISTRIBUTE_SPARE)
                    241:        },
                    242: #endif /* RF_INCLUDE_INTERDECLUSTER > 0 */
                    243:
                    244: #if    RF_INCLUDE_RAID0 > 0
                    245:        /* RAID level 0. */
                    246:        {'0', "RAID Level 0",
                    247:                RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
                    248:                RF_NU(
                    249:                    rf_ConfigureRAID0,
                    250:                    rf_MapSectorRAID0, rf_MapParityRAID0, NULL,
                    251:                    rf_IdentifyStripeRAID0,
                    252:                    rf_RAID0DagSelect,
                    253:                    rf_MapSIDToPSIDRAID0,
                    254:                    NULL,
                    255:                    NULL,
                    256:                    NULL, NULL,
                    257:                    NULL,
                    258:                    rf_VerifyParityRAID0,
                    259:                    0,
                    260:                    DefaultStates,
                    261:                    0)
                    262:        },
                    263: #endif /* RF_INCLUDE_RAID0 > 0 */
                    264:
                    265: #if    RF_INCLUDE_RAID1 > 0
                    266:        /* RAID level 1. */
                    267:        {'1', "RAID Level 1",
                    268:                RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
                    269:                RF_NU(
                    270:                    rf_ConfigureRAID1,
                    271:                    rf_MapSectorRAID1, rf_MapParityRAID1, NULL,
                    272:                    rf_IdentifyStripeRAID1,
                    273:                    rf_RAID1DagSelect,
                    274:                    rf_MapSIDToPSIDRAID1,
                    275:                    NULL,
                    276:                    NULL,
                    277:                    NULL, NULL,
                    278:                    rf_SubmitReconBufferRAID1,
                    279:                    rf_VerifyParityRAID1,
                    280:                    1,
                    281:                    DefaultStates,
                    282:                    0)
                    283:        },
                    284: #endif /* RF_INCLUDE_RAID1 > 0 */
                    285:
                    286: #if    RF_INCLUDE_RAID4 > 0
                    287:        /* RAID level 4. */
                    288:        {'4', "RAID Level 4",
                    289:                RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
                    290:                RF_NU(
                    291:                    rf_ConfigureRAID4,
                    292:                    rf_MapSectorRAID4, rf_MapParityRAID4, NULL,
                    293:                    rf_IdentifyStripeRAID4,
                    294:                    rf_RaidFiveDagSelect,
                    295:                    rf_MapSIDToPSIDRAID4,
                    296:                    rf_GetDefaultHeadSepLimitRAID4,
                    297:                    rf_GetDefaultNumFloatingReconBuffersRAID4,
                    298:                    NULL, NULL,
                    299:                    rf_SubmitReconBufferBasic,
                    300:                    rf_VerifyParityBasic,
                    301:                    1,
                    302:                    DefaultStates,
                    303:                    0)
                    304:        },
                    305: #endif /* RF_INCLUDE_RAID4 > 0 */
                    306:
                    307: #if    RF_INCLUDE_RAID5 > 0
                    308:        /* RAID level 5. */
                    309:        {'5', "RAID Level 5",
                    310:                RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
                    311:                RF_NU(
                    312:                    rf_ConfigureRAID5,
                    313:                    rf_MapSectorRAID5, rf_MapParityRAID5, NULL,
                    314:                    rf_IdentifyStripeRAID5,
                    315:                    rf_RaidFiveDagSelect,
                    316:                    rf_MapSIDToPSIDRAID5,
                    317:                    rf_GetDefaultHeadSepLimitRAID5,
                    318:                    rf_GetDefaultNumFloatingReconBuffersRAID5,
                    319:                    NULL, NULL,
                    320:                    rf_SubmitReconBufferBasic,
                    321:                    rf_VerifyParityBasic,
                    322:                    1,
                    323:                    DefaultStates,
                    324:                    0)
                    325:        },
                    326: #endif /* RF_INCLUDE_RAID5 > 0 */
                    327:
                    328: #if    RF_INCLUDE_EVENODD > 0
                    329:        /* Evenodd. */
                    330:        {'E', "EvenOdd",
                    331:                RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
                    332:                RF_NU(
                    333:                    rf_ConfigureEvenOdd,
                    334:                    rf_MapSectorRAID5, rf_MapParityEvenOdd, rf_MapEEvenOdd,
                    335:                    rf_IdentifyStripeEvenOdd,
                    336:                    rf_EODagSelect,
                    337:                    rf_MapSIDToPSIDRAID5,
                    338:                    NULL,
                    339:                    NULL,
                    340:                    NULL, NULL,
                    341:                    NULL,       /* No reconstruction, yet. */
                    342:                    rf_VerifyParityEvenOdd,
                    343:                    2,
                    344:                    DefaultStates,
                    345:                    0)
                    346:        },
                    347: #endif /* RF_INCLUDE_EVENODD > 0 */
                    348:
                    349: #if    RF_INCLUDE_EVENODD > 0
                    350:        /* Declustered Evenodd. */
                    351:        {'e', "Declustered EvenOdd",
                    352:                RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
                    353:                RF_NU(
                    354:                    rf_ConfigureDeclusteredPQ,
                    355:                    rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ,
                    356:                    rf_MapQDeclusteredPQ,
                    357:                    rf_IdentifyStripeDeclusteredPQ,
                    358:                    rf_EODagSelect,
                    359:                    rf_MapSIDToPSIDRAID5,
                    360:                    rf_GetDefaultHeadSepLimitDeclustered,
                    361:                    rf_GetDefaultNumFloatingReconBuffersPQ,
                    362:                    NULL, NULL,
                    363:                    NULL,       /* No reconstruction, yet. */
                    364:                    rf_VerifyParityEvenOdd,
                    365:                    2,
                    366:                    DefaultStates,
                    367:                    0)
                    368:        },
                    369: #endif /* RF_INCLUDE_EVENODD > 0 */
                    370:
                    371: #if    RF_INCLUDE_PARITYLOGGING > 0
                    372:        /* Parity logging. */
                    373:        {'L', "Parity logging",
                    374:                RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
                    375:                RF_NU(
                    376:                    rf_ConfigureParityLogging,
                    377:                    rf_MapSectorParityLogging, rf_MapParityParityLogging, NULL,
                    378:                    rf_IdentifyStripeParityLogging,
                    379:                    rf_ParityLoggingDagSelect,
                    380:                    rf_MapSIDToPSIDParityLogging,
                    381:                    rf_GetDefaultHeadSepLimitParityLogging,
                    382:                    rf_GetDefaultNumFloatingReconBuffersParityLogging,
                    383:                    NULL, NULL,
                    384:                    rf_SubmitReconBufferBasic,
                    385:                    NULL,
                    386:                    1,
                    387:                    DefaultStates,
                    388:                    0)
                    389:        },
                    390: #endif /* RF_INCLUDE_PARITYLOGGING > 0 */
                    391:
                    392:        /* End-of-list marker. */
                    393:        {'\0', NULL,
                    394:                RF_NK2(NULL, NULL)
                    395:                RF_NU(
                    396:                    NULL,
                    397:                    NULL, NULL, NULL,
                    398:                    NULL,
                    399:                    NULL,
                    400:                    NULL,
                    401:                    NULL,
                    402:                    NULL,
                    403:                    NULL, NULL,
                    404:                    NULL,
                    405:                    NULL,
                    406:                    0,
                    407:                    NULL,
                    408:                    0)
                    409:        }
                    410: };
                    411:
                    412: RF_LayoutSW_t *
                    413: rf_GetLayout(RF_ParityConfig_t parityConfig)
                    414: {
                    415:        RF_LayoutSW_t *p;
                    416:
                    417:        /* Look up the specific layout. */
                    418:        for (p = &mapsw[0]; p->parityConfig; p++)
                    419:                if (p->parityConfig == parityConfig)
                    420:                        break;
                    421:        if (!p->parityConfig)
                    422:                return (NULL);
                    423:        RF_ASSERT(p->parityConfig == parityConfig);
                    424:        return (p);
                    425: }
                    426:
                    427: #if    RF_UTILITY == 0
                    428: /*****************************************************************************
                    429:  *
                    430:  * ConfigureLayout
                    431:  *
                    432:  * Read the configuration file and set up the RAID layout parameters.
                    433:  * After reading common params, invokes the layout-specific configuration
                    434:  * routine to finish the configuration.
                    435:  *
                    436:  *****************************************************************************/
                    437: int
                    438: rf_ConfigureLayout(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
                    439:     RF_Config_t *cfgPtr)
                    440: {
                    441:        RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
                    442:        RF_ParityConfig_t parityConfig;
                    443:        RF_LayoutSW_t *p;
                    444:        int retval;
                    445:
                    446:        layoutPtr->sectorsPerStripeUnit = cfgPtr->sectPerSU;
                    447:        layoutPtr->SUsPerPU = cfgPtr->SUsPerPU;
                    448:        layoutPtr->SUsPerRU = cfgPtr->SUsPerRU;
                    449:        parityConfig = cfgPtr->parityConfig;
                    450:
                    451:        if (layoutPtr->sectorsPerStripeUnit <= 0) {
                    452:                RF_ERRORMSG2("raid%d: Invalid sectorsPerStripeUnit: %d.\n",
                    453:                    raidPtr->raidid, (int)layoutPtr->sectorsPerStripeUnit);
                    454:                return (EINVAL);
                    455:        }
                    456:
                    457:        layoutPtr->stripeUnitsPerDisk = raidPtr->sectorsPerDisk /
                    458:            layoutPtr->sectorsPerStripeUnit;
                    459:
                    460:        p = rf_GetLayout(parityConfig);
                    461:        if (p == NULL) {
                    462:                RF_ERRORMSG1("Unknown parity configuration '%c'", parityConfig);
                    463:                return (EINVAL);
                    464:        }
                    465:        RF_ASSERT(p->parityConfig == parityConfig);
                    466:        layoutPtr->map = p;
                    467:
                    468:        /* Initialize the specific layout. */
                    469:
                    470:        retval = (p->Configure) (listp, raidPtr, cfgPtr);
                    471:
                    472:        if (retval)
                    473:                return (retval);
                    474:
                    475:        layoutPtr->dataBytesPerStripe = layoutPtr->dataSectorsPerStripe <<
                    476:            raidPtr->logBytesPerSector;
                    477:        raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk *
                    478:            layoutPtr->sectorsPerStripeUnit;
                    479:
                    480:        if (rf_forceNumFloatingReconBufs >= 0) {
                    481:                raidPtr->numFloatingReconBufs = rf_forceNumFloatingReconBufs;
                    482:        } else {
                    483:                raidPtr->numFloatingReconBufs =
                    484:                    rf_GetDefaultNumFloatingReconBuffers(raidPtr);
                    485:        }
                    486:
                    487:        if (rf_forceHeadSepLimit >= 0) {
                    488:                raidPtr->headSepLimit = rf_forceHeadSepLimit;
                    489:        } else {
                    490:                raidPtr->headSepLimit = rf_GetDefaultHeadSepLimit(raidPtr);
                    491:        }
                    492:
                    493: #ifdef RAIDDEBUG
                    494:        if (raidPtr->headSepLimit >= 0) {
                    495:                printf("RAIDFRAME(%s): Using %ld floating recon bufs"
                    496:                    " with head sep limit %ld.\n", layoutPtr->map->configName,
                    497:                    (long) raidPtr->numFloatingReconBufs,
                    498:                    (long) raidPtr->headSepLimit);
                    499:        } else {
                    500:                printf("RAIDFRAME(%s): Using %ld floating recon bufs"
                    501:                    " with no head sep limit.\n", layoutPtr->map->configName,
                    502:                    (long) raidPtr->numFloatingReconBufs);
                    503:        }
                    504: #endif /* RAIDDEBUG */
                    505:
                    506:        return (0);
                    507: }
                    508:
                    509: /*
                    510:  * Typically there is a 1-1 mapping between stripes and parity stripes.
                    511:  * However, the declustering code supports packing multiple stripes into
                    512:  * a single parity stripe, so as to increase the size of the reconstruction
                    513:  * unit without affecting the size of the stripe unit. This routine finds
                    514:  * the parity stripe identifier associated with a stripe ID. There is also
                    515:  * a RaidAddressToParityStripeID macro in layout.h
                    516:  */
                    517: RF_StripeNum_t
                    518: rf_MapStripeIDToParityStripeID(RF_RaidLayout_t *layoutPtr,
                    519:     RF_StripeNum_t stripeID, RF_ReconUnitNum_t *which_ru)
                    520: {
                    521:        RF_StripeNum_t parityStripeID;
                    522:
                    523:        /* Quick exit in the common case of SUsPerPU == 1. */
                    524:        if ((layoutPtr->SUsPerPU == 1) || !layoutPtr->map->MapSIDToPSID) {
                    525:                *which_ru = 0;
                    526:                return (stripeID);
                    527:        } else {
                    528:                (layoutPtr->map->MapSIDToPSID) (layoutPtr, stripeID,
                    529:                    &parityStripeID, which_ru);
                    530:        }
                    531:        return (parityStripeID);
                    532: }
                    533: #endif /* RF_UTILITY == 0 */

CVSweb