int rf_State_ProcessDAG(RF_RaidAccessDesc_t *desc) { RF_AccessStripeMapHeader_t *asmh = desc->asmap; RF_Raid_t *raidPtr = desc->raidPtr; RF_DagHeader_t *dag_h; int i, j, done = RF_TRUE; RF_DagList_t *dagList, *temp; /* check to see if this is the last dag */ dagList = desc->dagList; for (i = 0; i < desc->numStripes; i++) { if (dagList->numDags != dagList->numDagsDone) done = RF_FALSE; dagList = dagList->next; } if (done) { if (desc->status) { /* a dag failed, retry */ /* free all dags */ dagList = desc->dagList; for (i = 0; i < desc->numStripes; i++) { rf_FreeDAG(dagList->dags); temp = dagList; dagList = dagList->next; rf_FreeDAGList(temp); } desc->dagList = NULL; rf_MarkFailuresInASMList(raidPtr, asmh); /* note the retry so that we'll bail in rf_State_CreateDAG() once we've retired the IO RF_RETRY_THRESHOLD times */ desc->numRetries++; /* back up to rf_State_CreateDAG */ desc->state = desc->state - 2; return RF_FALSE; } else { /* move on to rf_State_Cleanup */ desc->state++; } return RF_FALSE; } else { /* more dags to execute */ /* see if any are ready to be fired. if so, fire them */ /* don't fire the initial dag in a list, it's fired in * rf_State_ExecuteDAG */ dagList = desc->dagList; for (i = 0; i < desc->numStripes; i++) { if ((dagList->numDagsDone < dagList->numDags) && (dagList->numDagsDone == dagList->numDagsFired) && (dagList->numDagsFired > 0)) { #if RF_ACC_TRACE > 0 RF_ETIMER_START(dagList->tracerec.timer); #endif /* fire next dag in this stripe */ /* first, skip to next dag awaiting execution */ dag_h = dagList->dags; for (j = 0; j < dagList->numDagsDone; j++) dag_h = dag_h->next; dagList->numDagsFired++; rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess, dagList); } dagList = dagList->next; } return RF_TRUE; } }
/* * rf_State_ProcessDAG is entered when a dag completes. * First, check that all DAGs in the access have completed. * If not, fire as many DAGs as possible. */ int rf_State_ProcessDAG(RF_RaidAccessDesc_t *desc) { RF_AccessStripeMapHeader_t *asmh = desc->asmap; RF_Raid_t *raidPtr = desc->raidPtr; RF_DagHeader_t *dag_h; int i, j, done = RF_TRUE; RF_DagList_t *dagArray = desc->dagArray; RF_Etimer_t timer; /* Check to see if this is the last dag. */ for (i = 0; i < desc->numStripes; i++) if (dagArray[i].numDags != dagArray[i].numDagsDone) done = RF_FALSE; if (done) { if (desc->status) { /* A dag failed, retry. */ RF_ETIMER_START(timer); /* Free all dags. */ for (i = 0; i < desc->numStripes; i++) { rf_FreeDAG(desc->dagArray[i].dags); } rf_MarkFailuresInASMList(raidPtr, asmh); /* Back up to rf_State_CreateDAG. */ desc->state = desc->state - 2; return RF_FALSE; } else { /* Move on to rf_State_Cleanup. */ desc->state++; } return RF_FALSE; } else { /* More dags to execute. */ /* See if any are ready to be fired. If so, fire them. */ /* * Don't fire the initial dag in a list, it's fired in * rf_State_ExecuteDAG. */ for (i = 0; i < desc->numStripes; i++) { if ((dagArray[i].numDagsDone < dagArray[i].numDags) && (dagArray[i].numDagsDone == dagArray[i].numDagsFired) && (dagArray[i].numDagsFired > 0)) { RF_ETIMER_START(dagArray[i].tracerec.timer); /* Fire next dag in this stripe. */ /* * First, skip to next dag awaiting execution. */ dag_h = dagArray[i].dags; for (j = 0; j < dagArray[i].numDagsDone; j++) dag_h = dag_h->next; dagArray[i].numDagsFired++; /* * XXX And again we pass a different function * pointer... GO */ rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess, &dagArray[i]); } } return RF_TRUE; } }