예제 #1
0
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;
	}
}
예제 #2
0
/*
 * 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;
	}
}