Home | History | Annotate | Line # | Download | only in raidframe
rf_layout.c revision 1.5
      1 /*	$NetBSD: rf_layout.c,v 1.5 2000/04/16 03:24:26 oster Exp $	*/
      2 /*
      3  * Copyright (c) 1995 Carnegie-Mellon University.
      4  * All rights reserved.
      5  *
      6  * Author: Mark Holland
      7  *
      8  * Permission to use, copy, modify and distribute this software and
      9  * its documentation is hereby granted, provided that both the copyright
     10  * notice and this permission notice appear in all copies of the
     11  * software, derivative works or modified versions, and any portions
     12  * thereof, and that both notices appear in supporting documentation.
     13  *
     14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     16  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     17  *
     18  * Carnegie Mellon requests users of this software to return to
     19  *
     20  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     21  *  School of Computer Science
     22  *  Carnegie Mellon University
     23  *  Pittsburgh PA 15213-3890
     24  *
     25  * any improvements or extensions that they make and grant Carnegie the
     26  * rights to redistribute these changes.
     27  */
     28 
     29 /* rf_layout.c -- driver code dealing with layout and mapping issues
     30  */
     31 
     32 #include <sys/types.h>
     33 #include <machine/param.h>
     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
     74  *    sector, map parity, identify stripe, dag selection, map stripeid
     75  *    to parity stripe id (optional), num faults tolerated, special
     76  *    flags.
     77  *
     78  ***********************************************************************/
     79 
     80 static RF_AccessState_t DefaultStates[] = {rf_QuiesceState,
     81 	rf_IncrAccessesCountState, rf_MapState, rf_LockState, rf_CreateDAGState,
     82 	rf_ExecuteDAGState, rf_ProcessDAGState, rf_DecrAccessesCountState,
     83 rf_CleanupState, rf_LastState};
     84 #if defined(__NetBSD__) && !defined(_KERNEL)
     85 /* XXX Gross hack to shutup gcc -- it complains that DefaultStates is not
     86 used when compiling this in userland..  I hate to burst it's bubble, but
     87 DefaultStates is used all over the place here in the initialization of
     88 lots of data structures.  GO */
     89 RF_AccessState_t *NothingAtAll = DefaultStates;
     90 #endif
     91 
     92 #if defined(__NetBSD__) && defined(_KERNEL)
     93 /* XXX Remove static so GCC doesn't complain about these being unused! */
     94 int     distSpareYes = 1;
     95 int     distSpareNo = 0;
     96 #else
     97 static int distSpareYes = 1;
     98 static int distSpareNo = 0;
     99 #endif
    100 #ifdef _KERNEL
    101 #define RF_NK2(a,b)
    102 #else				/* _KERNEL */
    103 #define RF_NK2(a,b) a,b,
    104 #endif				/* _KERNEL */
    105 
    106 #if RF_UTILITY > 0
    107 #define RF_NU(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
    108 #else				/* RF_UTILITY > 0 */
    109 #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
    110 #endif				/* RF_UTILITY > 0 */
    111 
    112 static RF_LayoutSW_t mapsw[] = {
    113 	/* parity declustering */
    114 	{'T', "Parity declustering",
    115 		RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
    116 		RF_NU(
    117 		    rf_ConfigureDeclustered,
    118 		    rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
    119 		    rf_IdentifyStripeDeclustered,
    120 		    rf_RaidFiveDagSelect,
    121 		    rf_MapSIDToPSIDDeclustered,
    122 		    rf_GetDefaultHeadSepLimitDeclustered,
    123 		    rf_GetDefaultNumFloatingReconBuffersDeclustered,
    124 		    NULL, NULL,
    125 		    rf_SubmitReconBufferBasic,
    126 		    rf_VerifyParityBasic,
    127 		    1,
    128 		    DefaultStates,
    129 		    0)
    130 	},
    131 
    132 	/* parity declustering with distributed sparing */
    133 	{'D', "Distributed sparing parity declustering",
    134 		RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareYes)
    135 		RF_NU(
    136 		    rf_ConfigureDeclusteredDS,
    137 		    rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
    138 		    rf_IdentifyStripeDeclustered,
    139 		    rf_RaidFiveDagSelect,
    140 		    rf_MapSIDToPSIDDeclustered,
    141 		    rf_GetDefaultHeadSepLimitDeclustered,
    142 		    rf_GetDefaultNumFloatingReconBuffersDeclustered,
    143 		    rf_GetNumSpareRUsDeclustered, rf_InstallSpareTable,
    144 		    rf_SubmitReconBufferBasic,
    145 		    rf_VerifyParityBasic,
    146 		    1,
    147 		    DefaultStates,
    148 		    RF_DISTRIBUTE_SPARE | RF_BD_DECLUSTERED)
    149 	},
    150 
    151 #if RF_INCLUDE_DECL_PQ > 0
    152 	/* declustered P+Q */
    153 	{'Q', "Declustered P+Q",
    154 		RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
    155 		RF_NU(
    156 		    rf_ConfigureDeclusteredPQ,
    157 		    rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ, rf_MapQDeclusteredPQ,
    158 		    rf_IdentifyStripeDeclusteredPQ,
    159 		    rf_PQDagSelect,
    160 		    rf_MapSIDToPSIDDeclustered,
    161 		    rf_GetDefaultHeadSepLimitDeclustered,
    162 		    rf_GetDefaultNumFloatingReconBuffersPQ,
    163 		    NULL, NULL,
    164 		    NULL,
    165 		    rf_VerifyParityBasic,
    166 		    2,
    167 		    DefaultStates,
    168 		    0)
    169 	},
    170 #endif				/* RF_INCLUDE_DECL_PQ > 0 */
    171 
    172 #if RF_INCLUDE_RAID5_RS > 0
    173 	/* RAID 5 with rotated sparing */
    174 	{'R', "RAID Level 5 rotated sparing",
    175 		RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    176 		RF_NU(
    177 		    rf_ConfigureRAID5_RS,
    178 		    rf_MapSectorRAID5_RS, rf_MapParityRAID5_RS, NULL,
    179 		    rf_IdentifyStripeRAID5_RS,
    180 		    rf_RaidFiveDagSelect,
    181 		    rf_MapSIDToPSIDRAID5_RS,
    182 		    rf_GetDefaultHeadSepLimitRAID5,
    183 		    rf_GetDefaultNumFloatingReconBuffersRAID5,
    184 		    rf_GetNumSpareRUsRAID5_RS, NULL,
    185 		    rf_SubmitReconBufferBasic,
    186 		    rf_VerifyParityBasic,
    187 		    1,
    188 		    DefaultStates,
    189 		    RF_DISTRIBUTE_SPARE)
    190 	},
    191 #endif				/* RF_INCLUDE_RAID5_RS > 0 */
    192 
    193 #if RF_INCLUDE_CHAINDECLUSTER > 0
    194 	/* Chained Declustering */
    195 	{'C', "Chained Declustering",
    196 		RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    197 		RF_NU(
    198 		    rf_ConfigureChainDecluster,
    199 		    rf_MapSectorChainDecluster, rf_MapParityChainDecluster, NULL,
    200 		    rf_IdentifyStripeChainDecluster,
    201 		    rf_RAIDCDagSelect,
    202 		    rf_MapSIDToPSIDChainDecluster,
    203 		    NULL,
    204 		    NULL,
    205 		    rf_GetNumSpareRUsChainDecluster, NULL,
    206 		    rf_SubmitReconBufferBasic,
    207 		    rf_VerifyParityBasic,
    208 		    1,
    209 		    DefaultStates,
    210 		    0)
    211 	},
    212 #endif				/* RF_INCLUDE_CHAINDECLUSTER > 0 */
    213 
    214 #if RF_INCLUDE_INTERDECLUSTER > 0
    215 	/* Interleaved Declustering */
    216 	{'I', "Interleaved Declustering",
    217 		RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    218 		RF_NU(
    219 		    rf_ConfigureInterDecluster,
    220 		    rf_MapSectorInterDecluster, rf_MapParityInterDecluster, NULL,
    221 		    rf_IdentifyStripeInterDecluster,
    222 		    rf_RAIDIDagSelect,
    223 		    rf_MapSIDToPSIDInterDecluster,
    224 		    rf_GetDefaultHeadSepLimitInterDecluster,
    225 		    rf_GetDefaultNumFloatingReconBuffersInterDecluster,
    226 		    rf_GetNumSpareRUsInterDecluster, NULL,
    227 		    rf_SubmitReconBufferBasic,
    228 		    rf_VerifyParityBasic,
    229 		    1,
    230 		    DefaultStates,
    231 		    RF_DISTRIBUTE_SPARE)
    232 	},
    233 #endif				/* RF_INCLUDE_INTERDECLUSTER > 0 */
    234 
    235 #if RF_INCLUDE_RAID0 > 0
    236 	/* RAID level 0 */
    237 	{'0', "RAID Level 0",
    238 		RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    239 		RF_NU(
    240 		    rf_ConfigureRAID0,
    241 		    rf_MapSectorRAID0, rf_MapParityRAID0, NULL,
    242 		    rf_IdentifyStripeRAID0,
    243 		    rf_RAID0DagSelect,
    244 		    rf_MapSIDToPSIDRAID0,
    245 		    NULL,
    246 		    NULL,
    247 		    NULL, NULL,
    248 		    NULL,
    249 		    rf_VerifyParityRAID0,
    250 		    0,
    251 		    DefaultStates,
    252 		    0)
    253 	},
    254 #endif				/* RF_INCLUDE_RAID0 > 0 */
    255 
    256 #if RF_INCLUDE_RAID1 > 0
    257 	/* RAID level 1 */
    258 	{'1', "RAID Level 1",
    259 		RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    260 		RF_NU(
    261 		    rf_ConfigureRAID1,
    262 		    rf_MapSectorRAID1, rf_MapParityRAID1, NULL,
    263 		    rf_IdentifyStripeRAID1,
    264 		    rf_RAID1DagSelect,
    265 		    rf_MapSIDToPSIDRAID1,
    266 		    NULL,
    267 		    NULL,
    268 		    NULL, NULL,
    269 		    rf_SubmitReconBufferRAID1,
    270 		    rf_VerifyParityRAID1,
    271 		    1,
    272 		    DefaultStates,
    273 		    0)
    274 	},
    275 #endif				/* RF_INCLUDE_RAID1 > 0 */
    276 
    277 #if RF_INCLUDE_RAID4 > 0
    278 	/* RAID level 4 */
    279 	{'4', "RAID Level 4",
    280 		RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    281 		RF_NU(
    282 		    rf_ConfigureRAID4,
    283 		    rf_MapSectorRAID4, rf_MapParityRAID4, NULL,
    284 		    rf_IdentifyStripeRAID4,
    285 		    rf_RaidFiveDagSelect,
    286 		    rf_MapSIDToPSIDRAID4,
    287 		    rf_GetDefaultHeadSepLimitRAID4,
    288 		    rf_GetDefaultNumFloatingReconBuffersRAID4,
    289 		    NULL, NULL,
    290 		    rf_SubmitReconBufferBasic,
    291 		    rf_VerifyParityBasic,
    292 		    1,
    293 		    DefaultStates,
    294 		    0)
    295 	},
    296 #endif				/* RF_INCLUDE_RAID4 > 0 */
    297 
    298 #if RF_INCLUDE_RAID5 > 0
    299 	/* RAID level 5 */
    300 	{'5', "RAID Level 5",
    301 		RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    302 		RF_NU(
    303 		    rf_ConfigureRAID5,
    304 		    rf_MapSectorRAID5, rf_MapParityRAID5, NULL,
    305 		    rf_IdentifyStripeRAID5,
    306 		    rf_RaidFiveDagSelect,
    307 		    rf_MapSIDToPSIDRAID5,
    308 		    rf_GetDefaultHeadSepLimitRAID5,
    309 		    rf_GetDefaultNumFloatingReconBuffersRAID5,
    310 		    NULL, NULL,
    311 		    rf_SubmitReconBufferBasic,
    312 		    rf_VerifyParityBasic,
    313 		    1,
    314 		    DefaultStates,
    315 		    0)
    316 	},
    317 #endif				/* RF_INCLUDE_RAID5 > 0 */
    318 
    319 #if RF_INCLUDE_EVENODD > 0
    320 	/* Evenodd */
    321 	{'E', "EvenOdd",
    322 		RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    323 		RF_NU(
    324 		    rf_ConfigureEvenOdd,
    325 		    rf_MapSectorRAID5, rf_MapParityEvenOdd, rf_MapEEvenOdd,
    326 		    rf_IdentifyStripeEvenOdd,
    327 		    rf_EODagSelect,
    328 		    rf_MapSIDToPSIDRAID5,
    329 		    NULL,
    330 		    NULL,
    331 		    NULL, NULL,
    332 		    NULL,	/* no reconstruction, yet */
    333 		    rf_VerifyParityEvenOdd,
    334 		    2,
    335 		    DefaultStates,
    336 		    0)
    337 	},
    338 #endif				/* RF_INCLUDE_EVENODD > 0 */
    339 
    340 #if RF_INCLUDE_EVENODD > 0
    341 	/* Declustered Evenodd */
    342 	{'e', "Declustered EvenOdd",
    343 		RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
    344 		RF_NU(
    345 		    rf_ConfigureDeclusteredPQ,
    346 		    rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ, rf_MapQDeclusteredPQ,
    347 		    rf_IdentifyStripeDeclusteredPQ,
    348 		    rf_EODagSelect,
    349 		    rf_MapSIDToPSIDRAID5,
    350 		    rf_GetDefaultHeadSepLimitDeclustered,
    351 		    rf_GetDefaultNumFloatingReconBuffersPQ,
    352 		    NULL, NULL,
    353 		    NULL,	/* no reconstruction, yet */
    354 		    rf_VerifyParityEvenOdd,
    355 		    2,
    356 		    DefaultStates,
    357 		    0)
    358 	},
    359 #endif				/* RF_INCLUDE_EVENODD > 0 */
    360 
    361 #if RF_INCLUDE_PARITYLOGGING > 0
    362 	/* parity logging */
    363 	{'L', "Parity logging",
    364 		RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    365 		RF_NU(
    366 		    rf_ConfigureParityLogging,
    367 		    rf_MapSectorParityLogging, rf_MapParityParityLogging, NULL,
    368 		    rf_IdentifyStripeParityLogging,
    369 		    rf_ParityLoggingDagSelect,
    370 		    rf_MapSIDToPSIDParityLogging,
    371 		    rf_GetDefaultHeadSepLimitParityLogging,
    372 		    rf_GetDefaultNumFloatingReconBuffersParityLogging,
    373 		    NULL, NULL,
    374 		    rf_SubmitReconBufferBasic,
    375 		    NULL,
    376 		    1,
    377 		    DefaultStates,
    378 		    0)
    379 	},
    380 #endif				/* RF_INCLUDE_PARITYLOGGING > 0 */
    381 
    382 	/* end-of-list marker */
    383 	{'\0', NULL,
    384 		RF_NK2(NULL, NULL)
    385 		RF_NU(
    386 		    NULL,
    387 		    NULL, NULL, NULL,
    388 		    NULL,
    389 		    NULL,
    390 		    NULL,
    391 		    NULL,
    392 		    NULL,
    393 		    NULL, NULL,
    394 		    NULL,
    395 		    NULL,
    396 		    0,
    397 		    NULL,
    398 		    0)
    399 	}
    400 };
    401 
    402 RF_LayoutSW_t *
    403 rf_GetLayout(RF_ParityConfig_t parityConfig)
    404 {
    405 	RF_LayoutSW_t *p;
    406 
    407 	/* look up the specific layout */
    408 	for (p = &mapsw[0]; p->parityConfig; p++)
    409 		if (p->parityConfig == parityConfig)
    410 			break;
    411 	if (!p->parityConfig)
    412 		return (NULL);
    413 	RF_ASSERT(p->parityConfig == parityConfig);
    414 	return (p);
    415 }
    416 #if RF_UTILITY == 0
    417 /*****************************************************************************************
    418  *
    419  * ConfigureLayout --
    420  *
    421  * read the configuration file and set up the RAID layout parameters.  After reading
    422  * common params, invokes the layout-specific configuration routine to finish
    423  * the configuration.
    424  *
    425  ****************************************************************************************/
    426 int
    427 rf_ConfigureLayout(
    428     RF_ShutdownList_t ** listp,
    429     RF_Raid_t * raidPtr,
    430     RF_Config_t * cfgPtr)
    431 {
    432 	RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
    433 	RF_ParityConfig_t parityConfig;
    434 	RF_LayoutSW_t *p;
    435 	int     retval;
    436 
    437 	layoutPtr->sectorsPerStripeUnit = cfgPtr->sectPerSU;
    438 	layoutPtr->SUsPerPU = cfgPtr->SUsPerPU;
    439 	layoutPtr->SUsPerRU = cfgPtr->SUsPerRU;
    440 	parityConfig = cfgPtr->parityConfig;
    441 
    442 	if (layoutPtr->sectorsPerStripeUnit <= 0) {
    443 		RF_ERRORMSG2("raid%d: Invalid sectorsPerStripeUnit: %d\n",
    444 			     raidPtr->raidid,
    445 			     (int)layoutPtr->sectorsPerStripeUnit );
    446 		return (EINVAL);
    447 	}
    448 
    449 	if ((layoutPtr->sectorsPerStripeUnit *
    450 	     (1 << raidPtr->logBytesPerSector)) > MAXPHYS) {
    451 		RF_ERRORMSG2("raid%d: sectorsPerStripeUnit (%d) would exceed MAXPHYS\n",
    452 			     raidPtr->raidid,
    453 			     (int)layoutPtr->sectorsPerStripeUnit);
    454 		return (EINVAL);
    455 	}
    456 
    457 	layoutPtr->stripeUnitsPerDisk = raidPtr->sectorsPerDisk / layoutPtr->sectorsPerStripeUnit;
    458 
    459 	p = rf_GetLayout(parityConfig);
    460 	if (p == NULL) {
    461 		RF_ERRORMSG1("Unknown parity configuration '%c'", parityConfig);
    462 		return (EINVAL);
    463 	}
    464 	RF_ASSERT(p->parityConfig == parityConfig);
    465 	layoutPtr->map = p;
    466 
    467 	/* initialize the specific layout */
    468 
    469 	retval = (p->Configure) (listp, raidPtr, cfgPtr);
    470 
    471 	if (retval)
    472 		return (retval);
    473 
    474 	layoutPtr->dataBytesPerStripe = layoutPtr->dataSectorsPerStripe << raidPtr->logBytesPerSector;
    475 	raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk * layoutPtr->sectorsPerStripeUnit;
    476 
    477 	if (rf_forceNumFloatingReconBufs >= 0) {
    478 		raidPtr->numFloatingReconBufs = rf_forceNumFloatingReconBufs;
    479 	} else {
    480 		raidPtr->numFloatingReconBufs = rf_GetDefaultNumFloatingReconBuffers(raidPtr);
    481 	}
    482 
    483 	if (rf_forceHeadSepLimit >= 0) {
    484 		raidPtr->headSepLimit = rf_forceHeadSepLimit;
    485 	} else {
    486 		raidPtr->headSepLimit = rf_GetDefaultHeadSepLimit(raidPtr);
    487 	}
    488 
    489 	printf("RAIDFRAME: Configure (%s): total number of sectors is %lu (%lu MB)\n",
    490 	    layoutPtr->map->configName,
    491 	    (unsigned long) raidPtr->totalSectors,
    492 	    (unsigned long) (raidPtr->totalSectors / 1024 * (1 << raidPtr->logBytesPerSector) / 1024));
    493 	if (raidPtr->headSepLimit >= 0) {
    494 		printf("RAIDFRAME(%s): Using %ld floating recon bufs with head sep limit %ld\n",
    495 		    layoutPtr->map->configName, (long) raidPtr->numFloatingReconBufs, (long) raidPtr->headSepLimit);
    496 	} else {
    497 		printf("RAIDFRAME(%s): Using %ld floating recon bufs with no head sep limit\n",
    498 		    layoutPtr->map->configName, (long) raidPtr->numFloatingReconBufs);
    499 	}
    500 
    501 	return (0);
    502 }
    503 /* typically there is a 1-1 mapping between stripes and parity stripes.
    504  * however, the declustering code supports packing multiple stripes into
    505  * a single parity stripe, so as to increase the size of the reconstruction
    506  * unit without affecting the size of the stripe unit.  This routine finds
    507  * the parity stripe identifier associated with a stripe ID.  There is also
    508  * a RaidAddressToParityStripeID macro in layout.h
    509  */
    510 RF_StripeNum_t
    511 rf_MapStripeIDToParityStripeID(layoutPtr, stripeID, which_ru)
    512 	RF_RaidLayout_t *layoutPtr;
    513 	RF_StripeNum_t stripeID;
    514 	RF_ReconUnitNum_t *which_ru;
    515 {
    516 	RF_StripeNum_t parityStripeID;
    517 
    518 	/* quick exit in the common case of SUsPerPU==1 */
    519 	if ((layoutPtr->SUsPerPU == 1) || !layoutPtr->map->MapSIDToPSID) {
    520 		*which_ru = 0;
    521 		return (stripeID);
    522 	} else {
    523 		(layoutPtr->map->MapSIDToPSID) (layoutPtr, stripeID, &parityStripeID, which_ru);
    524 	}
    525 	return (parityStripeID);
    526 }
    527 #endif				/* RF_UTILITY == 0 */
    528