/* 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); }
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)); }
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; }
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); }
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); }
/* * 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); }
/* * 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++; } } }
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); }
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); }
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)); }
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; }
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)); }
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)); }
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); }
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; }