/* 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_PrintReconSchedule(RF_ReconMap_t *mapPtr, struct timeval *starttime) { static int old_pctg = -1; struct timeval tv, diff; int new_pctg; new_pctg = 100 - (rf_UnitsLeftToReconstruct(mapPtr) * 100 / mapPtr->totalRUs); if (new_pctg != old_pctg) { RF_GETTIME(tv); RF_TIMEVAL_DIFF(starttime, &tv, &diff); printf("%d %d.%06d\n", (int) new_pctg, (int) diff.tv_sec, (int) diff.tv_usec); old_pctg = new_pctg; } }
/* * Invoked via callback after a copyback I/O has completed to * continue on with the next one. */ void rf_ContinueCopyback(RF_CopybackDesc_t *desc) { RF_SectorNum_t testOffs, stripeAddr; RF_Raid_t *raidPtr = desc->raidPtr; RF_RaidAddr_t addr; RF_RowCol_t testRow, testCol; int old_pctg, new_pctg, done; struct timeval t, diff; old_pctg = (-1); while (1) { stripeAddr = desc->stripeAddr; desc->raidPtr->copyback_stripes_done = stripeAddr / desc->sectPerStripe; if (rf_prReconSched) { old_pctg = 100 * desc->stripeAddr / raidPtr->totalSectors; } desc->stripeAddr += desc->sectPerStripe; if (rf_prReconSched) { new_pctg = 100 * desc->stripeAddr / raidPtr->totalSectors; if (new_pctg != old_pctg) { RF_GETTIME(t); RF_TIMEVAL_DIFF(&desc->starttime, &t, &diff); printf("%d %d.%06d\n", new_pctg, (int) diff.tv_sec, (int) diff.tv_usec); } } if (stripeAddr >= raidPtr->totalSectors) { rf_CopybackComplete(desc, 0); return; } /* Walk through the current stripe, su-by-su. */ for (done = 0, addr = stripeAddr; addr < stripeAddr + desc->sectPerStripe; addr += desc->sectPerSU) { /* Map the SU, disallowing remap to spare space. */ (raidPtr->Layout.map->MapSector) (raidPtr, addr, &testRow, &testCol, &testOffs, RF_DONT_REMAP); if (testRow == desc->frow && testCol == desc->fcol) { rf_CopybackOne(desc, RF_COPYBACK_DATA, addr, testRow, testCol, testOffs); done = 1; break; } } if (!done) { /* * We didn't find the failed disk in the data part, * check parity. */ /* * Map the parity for this stripe, disallowing remap * to spare space. */ (raidPtr->Layout.map->MapParity) (raidPtr, stripeAddr, &testRow, &testCol, &testOffs, RF_DONT_REMAP); if (testRow == desc->frow && testCol == desc->fcol) { rf_CopybackOne(desc, RF_COPYBACK_PARITY, stripeAddr, testRow, testCol, testOffs); } } /* Check to see if the last read/write pair failed. */ if (desc->status) { rf_CopybackComplete(desc, 1); return; } /* * We didn't find any units to copy back in this stripe. * Continue with the next one. */ } }