⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rf_dagdegrd.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 3 页
字号:
	}    }  /* figure out number of nonaccessed pda */  napdas = PDAPerDisk * (numDataCol - asmap->numStripeUnitsAccessed - (ftwo==NULL ? 1 : 0));  *nPQNodep = PDAPerDisk;  /* sweep over the over accessed pda's, figuring out the number of     additional pda's to generate. Of course, skip the failed ones */  count = 0;  for ( pda_p=asmap->physInfo; pda_p; pda_p= pda_p->next)    {      if ((pda_p == fone) || (pda_p == ftwo))	continue;      suoff = rf_StripeUnitOffset(layoutPtr,pda_p->startSector);      suend = suoff + pda_p->numSector;      switch (state)	{	case 1: /* one failed PDA to overlap */	  /* if a PDA doesn't contain the failed unit, it can	     only miss the start or end, not both */	  if ((suoff > fone_start) || (suend <fone_end))	    count++;	  break;	case 2: /* whole stripe */	  if (suoff) /* leak at begining */	    count++;	  if (suend < numDataCol) /* leak at end */	    count++;	  break;	case 3: /* two disjoint units */	  if ((suoff > fone_start) || (suend <fone_end))	    count++;	  if ((suoff > ftwo_start) || (suend <ftwo_end))	    count++;	  break;	default:	  RF_PANIC();	}    }  napdas += count;  *nNodep = napdas;  if (napdas == 0) return; /* short circuit */  /* allocate up our list of pda's */       RF_CallocAndAdd(pda_p, napdas, sizeof(RF_PhysDiskAddr_t), (RF_PhysDiskAddr_t *), allocList);  *pdap = pda_p;      /* linkem together */  for (i=0; i < (napdas-1); i++)    pda_p[i].next = pda_p+(i+1);  /* march through the one's up to the first accessed disk */  firstDataCol = rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),asmap->physInfo->raidAddress) % numDataCol;  sosAddr      = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, asmap->raidAddress);  for (i=0; i < firstDataCol; i++)    {      if ((pda_p - (*pdap)) == napdas) 	continue;      pda_p->type = RF_PDA_TYPE_DATA;      pda_p->raidAddress = sosAddr + (i * secPerSU);      (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);      /* skip over dead disks */      if (RF_DEAD_DISK(raidPtr->Disks[pda_p->row][pda_p->col].status)) 	continue;      switch (state)	{	case 1: /* fone */	  pda_p->numSector = fone->numSector;	  pda_p->raidAddress += fone_start;	  pda_p->startSector += fone_start;	  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);	  break;	case 2: /* full stripe */	  pda_p->numSector = secPerSU;	  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,secPerSU), (char *), allocList);	  break;	case 3: /* two slabs */	  pda_p->numSector = fone->numSector;	  pda_p->raidAddress += fone_start;	  pda_p->startSector += fone_start;	  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);	  pda_p++;          pda_p->type = RF_PDA_TYPE_DATA;          pda_p->raidAddress = sosAddr + (i * secPerSU);          (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);	  pda_p->numSector = ftwo->numSector;	  pda_p->raidAddress += ftwo_start;	  pda_p->startSector += ftwo_start;	  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);	  break;	default:	  RF_PANIC();	}      pda_p++;    }  /* march through the touched stripe units */  for (phys_p = asmap->physInfo; phys_p; phys_p = phys_p->next, i++)    {      if ((phys_p == asmap->failedPDA) || (phys_p == asmap->failedPDAtwo))	continue;      suoff = rf_StripeUnitOffset(layoutPtr,phys_p->startSector);      suend = suoff + phys_p->numSector;      switch(state)	{	case 1: /* single buffer */	  if (suoff > fone_start)	    { 	      RF_ASSERT( suend >= fone_end );	      /* The data read starts after the mapped access,		 snip off the begining */	      pda_p->numSector = suoff - fone_start;	      pda_p->raidAddress = sosAddr + (i*secPerSU) + fone_start;	      (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);	      RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);	      pda_p++;	    }	  if (suend < fone_end)	    {	      RF_ASSERT ( suoff <= fone_start);	      /* The data read stops before the end of the failed access, extend */	      pda_p->numSector = fone_end - suend;	      pda_p->raidAddress = sosAddr + (i*secPerSU) + suend; /* off by one? */	      (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);	      RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);	      pda_p++;	    }	  break;	case 2: /* whole stripe unit */	  RF_ASSERT( (suoff == 0) || (suend == secPerSU));	  if (suend < secPerSU)	    { /* short read, snip from end on */	      pda_p->numSector = secPerSU - suend;	      pda_p->raidAddress = sosAddr + (i*secPerSU) + suend; /* off by one? */	      (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);	      RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);	      pda_p++;	    }	  else	    if (suoff > 0)	      { /* short at front */		pda_p->numSector = suoff;		pda_p->raidAddress = sosAddr + (i*secPerSU);		(raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);		RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);		pda_p++;	      }	  break;	case 3: /* two nonoverlapping failures */	  if ((suoff > fone_start) || (suend <fone_end))	    {	      if (suoff > fone_start)		{ 		  RF_ASSERT( suend >= fone_end );		  /* The data read starts after the mapped access,		     snip off the begining */		  pda_p->numSector = suoff - fone_start;		  pda_p->raidAddress = sosAddr + (i*secPerSU) + fone_start;		  (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);		  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);		  pda_p++;		}	      if (suend < fone_end)		{		  RF_ASSERT ( suoff <= fone_start);		  /* The data read stops before the end of the failed access, extend */		  pda_p->numSector = fone_end - suend;		  pda_p->raidAddress = sosAddr + (i*secPerSU) + suend; /* off by one? */		  (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);		  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);		  pda_p++;		}	    }	  if ((suoff > ftwo_start) || (suend <ftwo_end))	    {	      if (suoff > ftwo_start)		{ 		  RF_ASSERT( suend >= ftwo_end );		  /* The data read starts after the mapped access,		     snip off the begining */		  pda_p->numSector = suoff - ftwo_start;		  pda_p->raidAddress = sosAddr + (i*secPerSU) + ftwo_start;		  (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);		  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);		  pda_p++;		}	      if (suend < ftwo_end)		{		  RF_ASSERT ( suoff <= ftwo_start);		  /* The data read stops before the end of the failed access, extend */		  pda_p->numSector = ftwo_end - suend;		  pda_p->raidAddress = sosAddr + (i*secPerSU) + suend; /* off by one? */		  (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);		  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);		  pda_p++;		}	    }	  break;	default:	  RF_PANIC();        }    }  /* after the last accessed disk */  for (; i < numDataCol; i++ )    {      if ((pda_p - (*pdap)) == napdas) 	continue;      pda_p->type = RF_PDA_TYPE_DATA;      pda_p->raidAddress = sosAddr + (i * secPerSU);      (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);      /* skip over dead disks */      if (RF_DEAD_DISK(raidPtr->Disks[pda_p->row][pda_p->col].status)) 	continue;      switch (state)	{	case 1: /* fone */	  pda_p->numSector = fone->numSector;	  pda_p->raidAddress += fone_start;	  pda_p->startSector += fone_start;	  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);	  break;	case 2: /* full stripe */	  pda_p->numSector = secPerSU;	  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,secPerSU), (char *), allocList);	  break;	case 3: /* two slabs */	  pda_p->numSector = fone->numSector;	  pda_p->raidAddress += fone_start;	  pda_p->startSector += fone_start;	  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);	  pda_p++;          pda_p->type = RF_PDA_TYPE_DATA;          pda_p->raidAddress = sosAddr + (i * secPerSU);          (raidPtr->Layout.map->MapSector)(raidPtr,pda_p->raidAddress, &(pda_p->row), &(pda_p->col), &(pda_p->startSector), 0);	  pda_p->numSector = ftwo->numSector;	  pda_p->raidAddress += ftwo_start;	  pda_p->startSector += ftwo_start;	  RF_MallocAndAdd(pda_p->bufPtr, rf_RaidAddressToByte(raidPtr,pda_p->numSector), (char *), allocList);	  break;	default:	  RF_PANIC();	}      pda_p++;    }  RF_ASSERT  (pda_p - *pdap == napdas);  return;}#define INIT_DISK_NODE(node,name) \rf_InitNode(node, rf_wait, RF_FALSE, rf_DiskReadFunc, rf_DiskReadUndoFunc, rf_GenericWakeupFunc, 2,1,4,0, dag_h, name, allocList); \(node)->succedents[0] = unblockNode; \(node)->succedents[1] = recoveryNode; \(node)->antecedents[0] = blockNode; \(node)->antType[0] = rf_control#define DISK_NODE_PARAMS(_node_,_p_) \  (_node_).params[0].p = _p_ ; \  (_node_).params[1].p = (_p_)->bufPtr; \  (_node_).params[2].v = parityStripeID; \  (_node_).params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru)void rf_DoubleDegRead(  RF_Raid_t              *raidPtr,  RF_AccessStripeMap_t   *asmap,  RF_DagHeader_t         *dag_h,  void                   *bp,  RF_RaidAccessFlags_t    flags,  RF_AllocListElem_t     *allocList,  char                   *redundantReadNodeName,  char                   *recoveryNodeName,  int                   (*recovFunc)()){  RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);  RF_DagNode_t *nodes, *rudNodes, *rrdNodes, *recoveryNode, *blockNode, *unblockNode, *rpNodes, *rqNodes, *termNode;  RF_PhysDiskAddr_t *pda, *pqPDAs;  RF_PhysDiskAddr_t *npdas;  int nNodes, nRrdNodes, nRudNodes, i;  RF_ReconUnitNum_t which_ru;  int nReadNodes, nPQNodes;  RF_PhysDiskAddr_t *failedPDA = asmap->failedPDA;        RF_PhysDiskAddr_t *failedPDAtwo = asmap->failedPDAtwo;      RF_StripeNum_t parityStripeID = rf_RaidAddressToParityStripeID(layoutPtr, asmap->raidAddress, &which_ru);  if (rf_dagDebug) printf("[Creating Double Degraded Read DAG]\n");  rf_DD_GenerateFailedAccessASMs(raidPtr, asmap, &npdas, &nRrdNodes, &pqPDAs, &nPQNodes,allocList);  nRudNodes = asmap->numStripeUnitsAccessed - (asmap->numDataFailed);  nReadNodes = nRrdNodes + nRudNodes + 2*nPQNodes;  nNodes = 4 /* block, unblock, recovery, term */ + nReadNodes;  RF_CallocAndAdd(nodes, nNodes, sizeof(RF_DagNode_t), (RF_DagNode_t *), allocList);  i = 0;  blockNode    = &nodes[i]; i += 1;  unblockNode  = &nodes[i]; i += 1;  recoveryNode = &nodes[i]; i += 1;  termNode     = &nodes[i]; i += 1;  rudNodes     = &nodes[i]; i += nRudNodes;  rrdNodes     = &nodes[i]; i += nRrdNodes;  rpNodes      = &nodes[i]; i += nPQNodes;  rqNodes      = &nodes[i]; i += nPQNodes;  RF_ASSERT(i == nNodes);  dag_h->numSuccedents = 1;  dag_h->succedents[0] = blockNode;  dag_h->creator = "DoubleDegRead";  dag_h->numCommits = 0;  dag_h->numCommitNodes = 1; /*unblock */  rf_InitNode(termNode, rf_wait, RF_FALSE, rf_TerminateFunc, rf_TerminateUndoFunc, NULL, 0, 2, 0, 0, dag_h, "Trm", allocList);  termNode->antecedents[0]  = unblockNode;  termNode->antType[0] = rf_control;  termNode->antecedents[1]  = recoveryNode;  termNode->antType[1] = rf_control;  /* init the block and unblock nodes */  /* The block node has all nodes except itself, unblock and recovery as successors. Similarly for      predecessors of the unblock. */  rf_InitNode(blockNode, rf_wait, RF_FALSE, rf_NullNodeFunc, rf_NullNodeUndoFunc, NULL, nReadNodes, 0, 0, 0, dag_h, "Nil", allocList);  rf_InitNode(unblockNode, rf_wait, RF_TRUE, rf_NullNodeFunc, rf_NullNodeUndoFunc, NULL, 1, nReadNodes, 0, 0, dag_h, "Nil", allocList);    for (i=0; i < nReadNodes; i++)    {      blockNode->succedents[i] = rudNodes+i;      unblockNode->antecedents[i] = rudNodes+i;      unblockNode->antType[i] = rf_control;    }  unblockNode->succedents[0] = termNode;  /* The recovery node has all the reads as predecessors, and the term node as successors. It gets a pda as a param     from each of the read nodes plus the raidPtr.     For each failed unit is has a result pda. */  rf_InitNode(recoveryNode, rf_wait, RF_FALSE, recovFunc, rf_NullNodeUndoFunc, NULL, 	   1, /* succesors */	   nReadNodes, /* preds */ 	   nReadNodes+2, /* params */	   asmap->numDataFailed, /* results */	   dag_h, recoveryNodeName, allocList);    recoveryNode->succedents[0] = termNode;  for (i=0; i < nReadNodes; i++) {    recoveryNode->antecedents[i] = rudNodes+i;    recoveryNode->antType[i] = rf_trueData;  }    /* build the read nodes, then come back and fill in recovery params and results */  pda = asmap->physInfo;  for (i=0; i < nRudNodes; pda = pda->next)    {      if ((pda == failedPDA) || (pda == failedPDAtwo))	continue;      INIT_DISK_NODE(rudNodes+i,"Rud");      RF_ASSERT(pda);      DISK_NODE_PARAMS(rudNodes[i],pda);      i++;    }  pda = npdas;  for (i=0; i < nRrdNodes; i++, pda = pda->next)    {      INIT_DISK_NODE(rrdNodes+i,"Rrd");      RF_ASSERT(pda);      DISK_NODE_PARAMS(rrdNodes[i],pda);    }    /* redundancy pdas */  pda = pqPDAs;  INIT_DISK_NODE(rpNodes,"Rp");  RF_ASSERT(pda);  DISK_NODE_PARAMS(rpNodes[0],pda);  pda++;  INIT_DISK_NODE(rqNodes,redundantReadNodeName );  RF_ASSERT(pda);  DISK_NODE_PARAMS(rqNodes[0],pda);  if (nPQNodes==2)    {      pda++;      INIT_DISK_NODE(rpNodes+1,"Rp");      RF_ASSERT(pda);      DISK_NODE_PARAMS(rpNodes[1],pda);      pda++;      INIT_DISK_NODE( rqNodes+1,redundantReadNodeName );      RF_ASSERT(pda);      DISK_NODE_PARAMS(rqNodes[1],pda);    }  /* fill in recovery node params */  for (i=0; i < nReadNodes; i++)    recoveryNode->params[i] = rudNodes[i].params[0]; /* pda */  recoveryNode->params[i++].p = (void *) raidPtr;  recoveryNode->params[i++].p = (void *) asmap;  recoveryNode->results[0] = failedPDA;  if (asmap->numDataFailed ==2 )    recoveryNode->results[1] = failedPDAtwo;  /* zero fill the target data buffers? */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -