/* 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); }
int rf_FailDisk(RF_Raid_t *raidPtr, int fcol, int initRecon) { /* need to suspend IO's here -- if there are DAGs in flight and we pull the rug out from under ci_vp, Bad Things can happen. */ rf_SuspendNewRequestsAndWait(raidPtr); RF_LOCK_MUTEX(raidPtr->mutex); if (raidPtr->Disks[fcol].status != rf_ds_failed) { /* must be failing something that is valid, or else it's already marked as failed (in which case we don't want to mark it failed again!) */ raidPtr->numFailures++; raidPtr->Disks[fcol].status = rf_ds_failed; raidPtr->status = rf_rs_degraded; } RF_UNLOCK_MUTEX(raidPtr->mutex); rf_update_component_labels(raidPtr, RF_NORMAL_COMPONENT_UPDATE); /* Close the component, so that it's not "locked" if someone else want's to use it! */ rf_close_component(raidPtr, raidPtr->raid_cinfo[fcol].ci_vp, raidPtr->Disks[fcol].auto_configured); RF_LOCK_MUTEX(raidPtr->mutex); raidPtr->raid_cinfo[fcol].ci_vp = NULL; /* Need to mark the component as not being auto_configured (in case it was previously). */ raidPtr->Disks[fcol].auto_configured = 0; RF_UNLOCK_MUTEX(raidPtr->mutex); /* now we can allow IO to continue -- we'll be suspending it again in rf_ReconstructFailedDisk() if we have to.. */ rf_ResumeNewRequests(raidPtr); if (initRecon) rf_ReconstructFailedDisk(raidPtr, fcol); return (0); }