Esempio n. 1
0
/* Invoked when the copyback has completed. */
void
rf_CopybackComplete(RF_CopybackDesc_t *desc, int status)
{
	RF_Raid_t *raidPtr = desc->raidPtr;
	struct timeval t, diff;

	if (!status) {
		RF_LOCK_MUTEX(raidPtr->mutex);
		if (raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE) {
			RF_ASSERT(raidPtr->Layout.map->parityConfig == 'D');
			rf_FreeSpareTable(raidPtr);
		} else {
			raidPtr->Disks[desc->spRow][desc->spCol].status =
			    rf_ds_spare;
		}
		RF_UNLOCK_MUTEX(raidPtr->mutex);

		RF_GETTIME(t);
		RF_TIMEVAL_DIFF(&desc->starttime, &t, &diff);
		printf("Copyback time was %d.%06d seconds.\n",
		    (int) diff.tv_sec, (int) diff.tv_usec);
	} else
		printf("COPYBACK: Failure.\n");

	RF_Free(desc->databuf, rf_RaidAddressToByte(raidPtr, desc->sectPerSU));
	rf_FreeMCPair(desc->mcpair);
	RF_Free(desc, sizeof(*desc));

	rf_copyback_in_progress = 0;
	rf_ResumeNewRequests(raidPtr);
}
Esempio n. 2
0
void
rf_free_2d_array(RF_RowCol_t **a, int b, int k)
{
    RF_RowCol_t i;

    for (i = 0; i < b; i++)
        RF_Free(a[i], k * sizeof(RF_RowCol_t));
    RF_Free(a, b * sizeof(RF_RowCol_t));
}
Esempio n. 3
0
void
rf_FreeSpareTable(RF_Raid_t *raidPtr)
{
	long    i;
	RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;
	RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
	RF_SpareTableEntry_t **table = info->SpareTable;

	for (i = 0; i < info->TablesPerSpareRegion; i++) {
		RF_Free(table[i], info->BlocksPerTable * sizeof(RF_SpareTableEntry_t));
	}
	RF_Free(table, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *));
	info->SpareTable = (RF_SpareTableEntry_t **) NULL;
}
Esempio n. 4
0
RF_ReconMap_t *
rf_MakeReconMap(
    RF_Raid_t		*raidPtr,
    RF_SectorCount_t	 ru_sectors,		/*
						 * Size of reconstruction unit
						 * in sectors.
						 */
    RF_SectorCount_t	 disk_sectors,		/* Size of disk in sectors. */
    RF_ReconUnitCount_t	 spareUnitsPerDisk	/*
						 * Zero unless distributed
						 * sparing.
						 */
)
{
	RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;
	RF_ReconUnitCount_t num_rus = layoutPtr->stripeUnitsPerDisk /
	    layoutPtr->SUsPerRU;
	RF_ReconMap_t *p;
	int rc;

	RF_Malloc(p, sizeof(RF_ReconMap_t), (RF_ReconMap_t *));
	p->sectorsPerReconUnit = ru_sectors;
	p->sectorsInDisk = disk_sectors;

	p->totalRUs = num_rus;
	p->spareRUs = spareUnitsPerDisk;
	p->unitsLeft = num_rus - spareUnitsPerDisk;

	RF_Malloc(p->status, num_rus * sizeof(RF_ReconMapListElem_t *),
	    (RF_ReconMapListElem_t **));
	RF_ASSERT(p->status != (RF_ReconMapListElem_t **) NULL);

	(void) bzero((char *) p->status, num_rus *
	    sizeof(RF_ReconMapListElem_t *));

	p->size = sizeof(RF_ReconMap_t) + num_rus *
	    sizeof(RF_ReconMapListElem_t *);
	p->maxSize = p->size;

	rc = rf_mutex_init(&p->mutex);
	if (rc) {
		RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d.\n",
		    __FILE__, __LINE__, rc);
		RF_Free(p->status, num_rus * sizeof(RF_ReconMapListElem_t *));
		RF_Free(p, sizeof(RF_ReconMap_t));
		return (NULL);
	}
	return (p);
}
Esempio n. 5
0
int
rf_ConfigureAccessTrace(RF_ShutdownList_t **listp)
{
	int rc;

	numTracesSoFar = accessTraceBufCount = rf_stopCollectingTraces = 0;
	if (rf_accessTraceBufSize) {
		RF_Malloc(access_tracebuf, rf_accessTraceBufSize *
		    sizeof(RF_AccTraceEntry_t), (RF_AccTraceEntry_t *));
		accessTraceBufCount = 0;
	}
	traceCount = 0;
	numTracesSoFar = 0;
	rc = rf_mutex_init(&rf_tracing_mutex);
	if (rc) {
		RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d.\n",
		    __FILE__, __LINE__, rc);
	}
	rc = rf_ShutdownCreate(listp, rf_ShutdownAccessTrace, NULL);
	if (rc) {
		RF_ERRORMSG3("Unable to add to shutdown list file %s line %d"
		    " rc=%d.\n", __FILE__, __LINE__, rc);
		if (rf_accessTraceBufSize) {
			RF_Free(access_tracebuf, rf_accessTraceBufSize *
			    sizeof(RF_AccTraceEntry_t));
			rf_mutex_destroy(&rf_tracing_mutex);
		}
	}
	return (rc);
}
Esempio n. 6
0
/*
 * Invoked via ioctl to install a spare table in the kernel.
 */
int
rf_SetSpareTable(RF_Raid_t *raidPtr, void *data)
{
	RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) raidPtr->Layout.layoutSpecificInfo;
	RF_SpareTableEntry_t **ptrs;
	int     i, retcode;

	/* what we need to copyin is a 2-d array, so first copyin the user
	 * pointers to the rows in the table */
	RF_Malloc(ptrs, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *), (RF_SpareTableEntry_t **));
	retcode = copyin((void *) data, (void *) ptrs, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *));

	if (retcode)
		return (retcode);

	/* now allocate kernel space for the row pointers */
	RF_Malloc(info->SpareTable, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *), (RF_SpareTableEntry_t **));

	/* now allocate kernel space for each row in the table, and copy it in
	 * from user space */
	for (i = 0; i < info->TablesPerSpareRegion; i++) {
		RF_Malloc(info->SpareTable[i], info->BlocksPerTable * sizeof(RF_SpareTableEntry_t), (RF_SpareTableEntry_t *));
		retcode = copyin(ptrs[i], info->SpareTable[i], info->BlocksPerTable * sizeof(RF_SpareTableEntry_t));
		if (retcode) {
			info->SpareTable = NULL;	/* blow off the memory
							 * we've allocated */
			return (retcode);
		}
	}

	/* free up the temporary array we used */
	RF_Free(ptrs, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *));

	return (0);
}
Esempio n. 7
0
/*
 * We use the debug_mem_mutex here because we need to lock it anyway to call
 * free. This is probably a bug somewhere else in the code, but when I call
 * malloc/free outside of any lock, I have endless trouble with malloc
 * appearing to return the same pointer twice. Since we have to lock it
 * anyway, we might as well use it as the lock around the al_free_list.
 * Note that we can't call Free with the debug_mem_mutex locked.
 */
void
rf_FreeAllocList(RF_AllocListElem_t *l)
{
	int i;
	RF_AllocListElem_t *temp, *p;

	for (p = l; p; p = p->next) {
		RF_ASSERT(p->numPointers >= 0 &&
		    p->numPointers <= RF_POINTERS_PER_ALLOC_LIST_ELEMENT);
		for (i = 0; i < p->numPointers; i++) {
			RF_ASSERT(p->pointers[i]);
			RF_Free(p->pointers[i], p->sizes[i]);
		}
	}
	while (l) {
		temp = l;
		l = l->next;
		if (al_free_list_count > RF_AL_FREELIST_MAX) {
			DO_FREE(temp, sizeof(*temp));
		} else {
			temp->next = al_free_list;
			al_free_list = temp;
			al_free_list_count++;
		}
	}
}
Esempio n. 8
0
RF_CommonLogData_t *
rf_AllocParityLogCommonData(RF_Raid_t *raidPtr)
{
	RF_CommonLogData_t *common = NULL;
	int rc;

	/*
	 * Return a struct for holding common parity log information from the
	 * free list (rf_parityLogDiskQueue.freeCommonList). If the free list
	 * is empty, call RF_Malloc to create a new structure. NON-BLOCKING
	 */

	RF_LOCK_MUTEX(raidPtr->parityLogDiskQueue.mutex);
	if (raidPtr->parityLogDiskQueue.freeCommonList) {
		common = raidPtr->parityLogDiskQueue.freeCommonList;
		raidPtr->parityLogDiskQueue.freeCommonList =
		    raidPtr->parityLogDiskQueue.freeCommonList->next;
		RF_UNLOCK_MUTEX(raidPtr->parityLogDiskQueue.mutex);
	} else {
		RF_UNLOCK_MUTEX(raidPtr->parityLogDiskQueue.mutex);
		RF_Malloc(common, sizeof(RF_CommonLogData_t),
		    (RF_CommonLogData_t *));
		rc = rf_mutex_init(&common->mutex);
		if (rc) {
			RF_ERRORMSG3("Unable to init mutex file %s line %d"
			    " rc=%d\n", __FILE__, __LINE__, rc);
			RF_Free(common, sizeof(RF_CommonLogData_t));
			common = NULL;
		}
	}
	common->next = NULL;
	return (common);
}
Esempio n. 9
0
void
rf_ShutdownAccessTrace(void *ignored)
{
	if (rf_accessTraceBufSize) {
		if (accessTraceBufCount)
			rf_FlushAccessTraceBuf();
		RF_Free(access_tracebuf, rf_accessTraceBufSize *
		    sizeof(RF_AccTraceEntry_t));
	}
	rf_mutex_destroy(&rf_tracing_mutex);
}
Esempio n. 10
0
void
rf_FreeReconMapListElem(RF_ReconMap_t *mapPtr, RF_ReconMapListElem_t *p)
{
	int delta;

	if (mapPtr) {
		delta = 0 - (int) sizeof(RF_ReconMapListElem_t);
		rf_update_size(mapPtr, delta);
	}
	RF_Free(p, sizeof(*p));
}
Esempio n. 11
0
int
rf_get_info50(RF_Raid_t *raidPtr, void *data)
{
	RF_DeviceConfig50_t **ucfgp = data, *d_cfg;
	size_t i, j;
	int error;

	if (!raidPtr->valid)
		return ENODEV;

	RF_Malloc(d_cfg, sizeof(RF_DeviceConfig50_t), (RF_DeviceConfig50_t *));

	if (d_cfg == NULL)
		return ENOMEM;

	d_cfg->rows = 1; /* there is only 1 row now */
	d_cfg->cols = raidPtr->numCol;
	d_cfg->ndevs = raidPtr->numCol;
	if (d_cfg->ndevs >= RF_MAX_DISKS)
		goto nomem;

	d_cfg->nspares = raidPtr->numSpare;
	if (d_cfg->nspares >= RF_MAX_DISKS)
		goto nomem;

	d_cfg->maxqdepth = raidPtr->maxQueueDepth;
	for (j = 0; j < d_cfg->cols; j++)
		rf_disk_to_disk50(&d_cfg->devs[j], &raidPtr->Disks[j]);

	for (j = d_cfg->cols, i = 0; i < d_cfg->nspares; i++, j++)
		rf_disk_to_disk50(&d_cfg->spares[i], &raidPtr->Disks[j]);

	error = copyout(d_cfg, *ucfgp, sizeof(RF_DeviceConfig50_t));
	RF_Free(d_cfg, sizeof(RF_DeviceConfig50_t));

	return error;
nomem:
	RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
	return ENOMEM;
}
Esempio n. 12
0
void
rf_FreeReconMap(RF_ReconMap_t *mapPtr)
{
	RF_ReconMapListElem_t *p, *q;
	RF_ReconUnitCount_t numRUs;
	RF_ReconUnitNum_t i;

	numRUs = mapPtr->sectorsInDisk / mapPtr->sectorsPerReconUnit;
	if (mapPtr->sectorsInDisk % mapPtr->sectorsPerReconUnit)
		numRUs++;

	for (i = 0; i < numRUs; i++) {
		p = mapPtr->status[i];
		while (p != RU_NOTHING && p != RU_ALL) {
			q = p;
			p = p->next;
			RF_Free(q, sizeof(*q));
		}
	}
	rf_mutex_destroy(&mapPtr->mutex);
	RF_Free(mapPtr->status, mapPtr->totalRUs *
	    sizeof(RF_ReconMapListElem_t *));
	RF_Free(mapPtr, sizeof(RF_ReconMap_t));
}
Esempio n. 13
0
void
rf_FreeParityStripeStatusTable(RF_Raid_t *raidPtr,
			       RF_PSStatusHeader_t *pssTable)
{
#if RF_DEBUG_PSS
	int     i;

	if (rf_pssDebug)
		RealPrintPSStatusTable(raidPtr, pssTable);

	for (i = 0; i < raidPtr->pssTableSize; i++) {
		if (pssTable[i].chain) {
			printf("ERROR: pss hash chain not null at recon shutdown\n");
		}
	}
#endif
	RF_Free(pssTable, raidPtr->pssTableSize * sizeof(RF_PSStatusHeader_t));
}
Esempio n. 14
0
void
rf_free_1d_array(RF_RowCol_t *a, int n)
{
    RF_Free(a, n * sizeof(RF_RowCol_t));
}
void
rf_doubleEOdecode(
    RF_Raid_t * raidPtr,
    char **rrdbuf,
    char **dest,
    RF_RowCol_t * fcol,
    char *pbuf,
    char *ebuf)
{
	RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & (raidPtr->Layout);
	int     i, j, k, f1, f2, row;
	int     rrdrow, erow, count = 0;
	int     bytesPerSector = rf_RaidAddressToByte(raidPtr, 1);
	int     numRowInEncMatix = (RF_EO_MATRIX_DIM) - 1;
#if 0
	int     pcol = (RF_EO_MATRIX_DIM) - 1;
#endif
	int     ecol = (RF_EO_MATRIX_DIM) - 2;
	int     bytesPerEU = bytesPerSector / numRowInEncMatix;
	int     numDataCol = layoutPtr->numDataCol;
#if RF_EO_MATRIX_DIM > 17
	int     shortsPerEU = bytesPerEU / sizeof(short);
	short  *rrdbuf_current, *pbuf_current, *ebuf_current;
	short  *dest_smaller, *dest_smaller_current, *dest_larger, *dest_larger_current;
	short *temp;
	short  *P;

	RF_ASSERT(bytesPerEU % sizeof(short) == 0);
	RF_Malloc(P, bytesPerEU, (short *));
	RF_Malloc(temp, bytesPerEU, (short *));
#elif RF_EO_MATRIX_DIM == 17
	int     longsPerEU = bytesPerEU / sizeof(long);
	long   *rrdbuf_current, *pbuf_current, *ebuf_current;
	long   *dest_smaller, *dest_smaller_current, *dest_larger, *dest_larger_current;
	long *temp;
	long   *P;

	RF_ASSERT(bytesPerEU % sizeof(long) == 0);
	RF_Malloc(P, bytesPerEU, (long *));
	RF_Malloc(temp, bytesPerEU, (long *));
#endif
	RF_ASSERT(*((long *) dest[0]) == 0);
	RF_ASSERT(*((long *) dest[1]) == 0);
	memset((char *) P, 0, bytesPerEU);
	memset((char *) temp, 0, bytesPerEU);
	RF_ASSERT(*P == 0);
	/* calculate the 'P' parameter, which, not parity, is the Xor of all
	 * elements in the last two column, ie. 'E' and 'parity' colume, see
	 * the Ref. paper by Blaum, et al 1993  */
	for (i = 0; i < numRowInEncMatix; i++)
		for (k = 0; k < longsPerEU; k++) {
#if RF_EO_MATRIX_DIM > 17
			ebuf_current = ((short *) ebuf) + i * shortsPerEU + k;
			pbuf_current = ((short *) pbuf) + i * shortsPerEU + k;
#elif RF_EO_MATRIX_DIM == 17
			ebuf_current = ((long *) ebuf) + i * longsPerEU + k;
			pbuf_current = ((long *) pbuf) + i * longsPerEU + k;
#endif
			P[k] ^= *ebuf_current;
			P[k] ^= *pbuf_current;
		}
	RF_ASSERT(fcol[0] != fcol[1]);
	if (fcol[0] < fcol[1]) {
#if RF_EO_MATRIX_DIM > 17
		dest_smaller = (short *) (dest[0]);
		dest_larger = (short *) (dest[1]);
#elif RF_EO_MATRIX_DIM == 17
		dest_smaller = (long *) (dest[0]);
		dest_larger = (long *) (dest[1]);
#endif
		f1 = fcol[0];
		f2 = fcol[1];
	} else {
#if RF_EO_MATRIX_DIM > 17
		dest_smaller = (short *) (dest[1]);
		dest_larger = (short *) (dest[0]);
#elif RF_EO_MATRIX_DIM == 17
		dest_smaller = (long *) (dest[1]);
		dest_larger = (long *) (dest[0]);
#endif
		f1 = fcol[1];
		f2 = fcol[0];
	}
	row = (RF_EO_MATRIX_DIM) - 1;
	while ((row = rf_EO_Mod((row + f1 - f2), RF_EO_MATRIX_DIM)) != ((RF_EO_MATRIX_DIM) - 1)) {
#if RF_EO_MATRIX_DIM > 17
		dest_larger_current = dest_larger + row * shortsPerEU;
		dest_smaller_current = dest_smaller + row * shortsPerEU;
#elif RF_EO_MATRIX_DIM == 17
		dest_larger_current = dest_larger + row * longsPerEU;
		dest_smaller_current = dest_smaller + row * longsPerEU;
#endif
		/**    Do the diagonal recovery. Initially, temp[k] = (failed 1),
		       which is the failed data in the colume which has smaller col index. **/
		/* step 1:  ^(SUM of nonfailed in-diagonal A(rrdrow,0..m-3))         */
		for (j = 0; j < numDataCol; j++) {
			if (j == f1 || j == f2)
				continue;
			rrdrow = rf_EO_Mod((row + f2 - j), RF_EO_MATRIX_DIM);
			if (rrdrow != (RF_EO_MATRIX_DIM) - 1) {
#if RF_EO_MATRIX_DIM > 17
				rrdbuf_current = (short *) (rrdbuf[j]) + rrdrow * shortsPerEU;
				for (k = 0; k < shortsPerEU; k++)
					temp[k] ^= *(rrdbuf_current + k);
#elif RF_EO_MATRIX_DIM == 17
				rrdbuf_current = (long *) (rrdbuf[j]) + rrdrow * longsPerEU;
				for (k = 0; k < longsPerEU; k++)
					temp[k] ^= *(rrdbuf_current + k);
#endif
			}
		}
		/* step 2:  ^E(erow,m-2), If erow is at the buttom row, don't
		 * Xor into it  E(erow,m-2) = (principle diagonal) ^ (failed
		 * 1) ^ (failed 2) ^ ( SUM of nonfailed in-diagonal
		 * A(rrdrow,0..m-3) ) After this step, temp[k] = (principle
		 * diagonal) ^ (failed 2)       */

		erow = rf_EO_Mod((row + f2 - ecol), (RF_EO_MATRIX_DIM));
		if (erow != (RF_EO_MATRIX_DIM) - 1) {
#if RF_EO_MATRIX_DIM > 17
			ebuf_current = (short *) ebuf + shortsPerEU * erow;
			for (k = 0; k < shortsPerEU; k++)
				temp[k] ^= *(ebuf_current + k);
#elif RF_EO_MATRIX_DIM == 17
			ebuf_current = (long *) ebuf + longsPerEU * erow;
			for (k = 0; k < longsPerEU; k++)
				temp[k] ^= *(ebuf_current + k);
#endif
		}
		/* step 3: ^P to obtain the failed data (failed 2).  P can be
		 * proved to be actually  (principle diagonal)  After this
		 * step, temp[k] = (failed 2), the failed data to be recovered */
#if RF_EO_MATRIX_DIM > 17
		for (k = 0; k < shortsPerEU; k++)
			temp[k] ^= P[k];
		/* Put the data to the destination buffer                              */
		for (k = 0; k < shortsPerEU; k++)
			dest_larger_current[k] = temp[k];
#elif RF_EO_MATRIX_DIM == 17
		for (k = 0; k < longsPerEU; k++)
			temp[k] ^= P[k];
		/* Put the data to the destination buffer                              */
		for (k = 0; k < longsPerEU; k++)
			dest_larger_current[k] = temp[k];
#endif

		/**          THE FOLLOWING DO THE HORIZONTAL XOR                **/
		/* step 1:  ^(SUM of A(row,0..m-3)), ie. all nonfailed data
		 * columes    */
		for (j = 0; j < numDataCol; j++) {
			if (j == f1 || j == f2)
				continue;
#if RF_EO_MATRIX_DIM > 17
			rrdbuf_current = (short *) (rrdbuf[j]) + row * shortsPerEU;
			for (k = 0; k < shortsPerEU; k++)
				temp[k] ^= *(rrdbuf_current + k);
#elif RF_EO_MATRIX_DIM == 17
			rrdbuf_current = (long *) (rrdbuf[j]) + row * longsPerEU;
			for (k = 0; k < longsPerEU; k++)
				temp[k] ^= *(rrdbuf_current + k);
#endif
		}
		/* step 2: ^A(row,m-1) */
		/* step 3: Put the data to the destination buffer                             	 */
#if RF_EO_MATRIX_DIM > 17
		pbuf_current = (short *) pbuf + shortsPerEU * row;
		for (k = 0; k < shortsPerEU; k++)
			temp[k] ^= *(pbuf_current + k);
		for (k = 0; k < shortsPerEU; k++)
			dest_smaller_current[k] = temp[k];
#elif RF_EO_MATRIX_DIM == 17
		pbuf_current = (long *) pbuf + longsPerEU * row;
		for (k = 0; k < longsPerEU; k++)
			temp[k] ^= *(pbuf_current + k);
		for (k = 0; k < longsPerEU; k++)
			dest_smaller_current[k] = temp[k];
#endif
		count++;
	}
	/* Check if all Encoding Unit in the data buffer have been decoded,
	 * according EvenOdd theory, if "RF_EO_MATRIX_DIM" is a prime number,
	 * this algorithm will covered all buffer 				 */
	RF_ASSERT(count == numRowInEncMatix);
	RF_Free((char *) P, bytesPerEU);
	RF_Free((char *) temp, bytesPerEU);
}
Esempio n. 16
0
int
rf_config50(RF_Raid_t *raidPtr, int unit, void *data, RF_Config_t **k_cfgp)
{
	RF_Config50_t *u50_cfg, *k50_cfg;
	RF_Config_t *k_cfg;
	size_t i, j;
	int error;

	if (raidPtr->valid) {
		/* There is a valid RAID set running on this unit! */
		printf("raid%d: Device already configured!\n", unit);
		return EINVAL;
	}

	/* copy-in the configuration information */
	/* data points to a pointer to the configuration structure */

	u50_cfg = *((RF_Config50_t **) data);
	RF_Malloc(k50_cfg, sizeof(RF_Config50_t), (RF_Config50_t *));
	if (k50_cfg == NULL)
		return ENOMEM;

	error = copyin(u50_cfg, k50_cfg, sizeof(RF_Config50_t));
	if (error) {
		RF_Free(k50_cfg, sizeof(RF_Config50_t));
		return error;
	}
	RF_Malloc(k_cfg, sizeof(RF_Config_t), (RF_Config_t *));
	if (k_cfg == NULL) {
		RF_Free(k50_cfg, sizeof(RF_Config50_t));
		return ENOMEM;
	}

	k_cfg->numRow = k50_cfg->numRow;
	k_cfg->numCol = k50_cfg->numCol;
	k_cfg->numSpare = k50_cfg->numSpare;

	for (i = 0; i < RF_MAXROW; i++)
		for (j = 0; j < RF_MAXCOL; j++)
			k_cfg->devs[i][j] = k50_cfg->devs[i][j];

	memcpy(k_cfg->devnames, k50_cfg->devnames,
	    sizeof(k_cfg->devnames));

	for (i = 0; i < RF_MAXSPARE; i++)
		k_cfg->spare_devs[i] = k50_cfg->spare_devs[i];

	memcpy(k_cfg->spare_names, k50_cfg->spare_names,
	    sizeof(k_cfg->spare_names));

	k_cfg->sectPerSU = k50_cfg->sectPerSU;
	k_cfg->SUsPerPU = k50_cfg->SUsPerPU;
	k_cfg->SUsPerRU = k50_cfg->SUsPerRU;
	k_cfg->parityConfig = k50_cfg->parityConfig;

	memcpy(k_cfg->diskQueueType, k50_cfg->diskQueueType,
	    sizeof(k_cfg->diskQueueType));

	k_cfg->maxOutstandingDiskReqs = k50_cfg->maxOutstandingDiskReqs;

	memcpy(k_cfg->debugVars, k50_cfg->debugVars,
	    sizeof(k_cfg->debugVars));

	k_cfg->layoutSpecificSize = k50_cfg->layoutSpecificSize;
	k_cfg->layoutSpecific = k50_cfg->layoutSpecific;
	k_cfg->force = k50_cfg->force;

	RF_Free(k50_cfg, sizeof(RF_Config50_t));
	*k_cfgp = k_cfg;
	return 0;
}