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

📄 rf_dagfuncs.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 3 页
字号:
	rf_ParityLogAppend(logData, RF_FALSE, NULL, RF_FALSE);      else	{	  RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->plog_us += RF_ETIMER_VAL_US(timer);	  (node->wakeFunc)(node, ENOMEM);	}    }    return(0);}/***************************************************************************************** * the execution function associated with a parity log overwrite node ****************************************************************************************/int rf_ParityLogOverwriteFunc(node)  RF_DagNode_t  *node;{  RF_PhysDiskAddr_t  *pda = (RF_PhysDiskAddr_t *) node->params[0].p;  caddr_t buf = (caddr_t) node->params[1].p;  RF_ParityLogData_t *logData;  RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;  RF_Etimer_t timer;  if (node->dagHdr->status == rf_enable)    {      RF_ETIMER_START(timer);      logData = rf_CreateParityLogData(RF_OVERWRITE, pda, buf, (RF_Raid_t *) (node->dagHdr->raidPtr),				    node->wakeFunc, (void *) node, node->dagHdr->tracerec, timer);      if (logData)	rf_ParityLogAppend(logData, RF_FALSE, NULL, RF_FALSE);      else	{	  RF_ETIMER_STOP(timer); RF_ETIMER_EVAL(timer); tracerec->plog_us += RF_ETIMER_VAL_US(timer);	  (node->wakeFunc)(node, ENOMEM);	}    }    return(0);}#else /* RF_INCLUDE_PARITYLOGGING > 0 */int rf_ParityLogUpdateFunc(node)  RF_DagNode_t  *node;{  return(0);}int rf_ParityLogOverwriteFunc(node)  RF_DagNode_t  *node;{  return(0);}#endif /* RF_INCLUDE_PARITYLOGGING > 0 */int rf_ParityLogUpdateUndoFunc(node)  RF_DagNode_t  *node;{  return(0);}int rf_ParityLogOverwriteUndoFunc(node)  RF_DagNode_t  *node;{  return(0);}/***************************************************************************************** * the execution function associated with a NOP node ****************************************************************************************/int rf_NullNodeFunc(node)  RF_DagNode_t  *node;{  node->status = rf_good;  return(rf_FinishNode(node, RF_THREAD_CONTEXT));}int rf_NullNodeUndoFunc(node)  RF_DagNode_t  *node;{  node->status = rf_undone;  return(rf_FinishNode(node, RF_THREAD_CONTEXT));}/***************************************************************************************** * the execution function associated with a disk-read node ****************************************************************************************/int rf_DiskReadFuncForThreads(node)  RF_DagNode_t  *node;{  RF_DiskQueueData_t *req;  RF_PhysDiskAddr_t  *pda       = (RF_PhysDiskAddr_t *)node->params[0].p;  caddr_t        buf            = (caddr_t)node->params[1].p;  RF_StripeNum_t parityStripeID = (RF_StripeNum_t)node->params[2].v;  unsigned       priority       = RF_EXTRACT_PRIORITY(node->params[3].v);  unsigned       lock           = RF_EXTRACT_LOCK_FLAG(node->params[3].v);  unsigned       unlock         = RF_EXTRACT_UNLOCK_FLAG(node->params[3].v);  unsigned       which_ru       = RF_EXTRACT_RU(node->params[3].v);  RF_DiskQueueDataFlags_t flags = 0;  RF_IoType_t    iotype = (node->dagHdr->status == rf_enable) ? RF_IO_TYPE_READ : RF_IO_TYPE_NOP;  RF_DiskQueue_t **dqs = ((RF_Raid_t *) (node->dagHdr->raidPtr))->Queues;  void *b_proc = NULL;  caddr_t        undoBuf;#ifdef KERNEL  if (node->dagHdr->bp) b_proc = (void *) ((struct buf *) node->dagHdr->bp)->b_proc;#endif /* KERNEL */  RF_ASSERT( !(lock && unlock) );  flags |= (lock)   ? RF_LOCK_DISK_QUEUE   : 0;  flags |= (unlock) ? RF_UNLOCK_DISK_QUEUE : 0;#if RF_BACKWARD > 0  /* allocate and zero the undo buffer.   * this is equivalent to copying the original buffer's contents to the undo buffer   * prior to performing the disk read.   * XXX hardcoded 512 bytes per sector!   */  if (node->dagHdr->allocList == NULL)    rf_MakeAllocList(node->dagHdr->allocList);  RF_CallocAndAdd(undoBuf, 1, 512 * pda->numSector, (caddr_t), node->dagHdr->allocList);#endif /* RF_BACKWARD > 0 */  req = rf_CreateDiskQueueData(iotype, 			    pda->startSector, pda->numSector, buf, parityStripeID, which_ru, 			    node->wakeFunc, (void *) node, NULL, node->dagHdr->tracerec,			    (void *)(node->dagHdr->raidPtr), flags, b_proc);  if (!req) {    (node->wakeFunc)(node, ENOMEM);  } else {    node->dagFuncData = (void *) req;    rf_DiskIOEnqueue( &(dqs[pda->row][pda->col]), req, priority );  }  return(0);}/***************************************************************************************** * the execution function associated with a disk-write node ****************************************************************************************/int rf_DiskWriteFuncForThreads(node)  RF_DagNode_t  *node;{  RF_DiskQueueData_t *req;  RF_PhysDiskAddr_t  *pda       = (RF_PhysDiskAddr_t *)node->params[0].p;  caddr_t        buf            = (caddr_t)node->params[1].p;  RF_StripeNum_t parityStripeID = (RF_StripeNum_t)node->params[2].v;  unsigned       priority       = RF_EXTRACT_PRIORITY(node->params[3].v);  unsigned       lock           = RF_EXTRACT_LOCK_FLAG(node->params[3].v);  unsigned       unlock         = RF_EXTRACT_UNLOCK_FLAG(node->params[3].v);  unsigned       which_ru       = RF_EXTRACT_RU(node->params[3].v);  RF_DiskQueueDataFlags_t flags = 0;  RF_IoType_t    iotype = (node->dagHdr->status == rf_enable) ? RF_IO_TYPE_WRITE : RF_IO_TYPE_NOP;  RF_DiskQueue_t **dqs = ((RF_Raid_t *) (node->dagHdr->raidPtr))->Queues;  void *b_proc = NULL;  caddr_t undoBuf;#ifdef KERNEL  if (node->dagHdr->bp) b_proc = (void *) ((struct buf *) node->dagHdr->bp)->b_proc;#endif /* KERNEL */#if RF_BACKWARD > 0  /* This area is used only for backward error recovery experiments   * First, schedule allocate a buffer and schedule a pre-read of the disk   * After the pre-read, proceed with the normal disk write   */  if (node->status == rf_bwd2) {    /* just finished undo logging, now perform real function */    node->status = rf_fired;    RF_ASSERT( !(lock && unlock) );    flags |= (lock)   ? RF_LOCK_DISK_QUEUE   : 0;    flags |= (unlock) ? RF_UNLOCK_DISK_QUEUE : 0;    req = rf_CreateDiskQueueData(iotype, 			      pda->startSector, pda->numSector, buf, parityStripeID, which_ru,			      node->wakeFunc, (void *) node, NULL, node->dagHdr->tracerec,			      (void *) (node->dagHdr->raidPtr), flags, b_proc);        if (!req) {      (node->wakeFunc)(node, ENOMEM);    } else {      node->dagFuncData = (void *) req;      rf_DiskIOEnqueue( &(dqs[pda->row][pda->col]), req, priority );    }  }  else {    /* node status should be rf_fired */    /* schedule a disk pre-read */    node->status = rf_bwd1;    RF_ASSERT( !(lock && unlock) );    flags |= (lock)   ? RF_LOCK_DISK_QUEUE   : 0;    flags |= (unlock) ? RF_UNLOCK_DISK_QUEUE : 0;    if (node->dagHdr->allocList == NULL)      rf_MakeAllocList(node->dagHdr->allocList);    RF_CallocAndAdd(undoBuf, 1, 512 * pda->numSector, (caddr_t), node->dagHdr->allocList);    req = rf_CreateDiskQueueData(RF_IO_TYPE_READ, 			      pda->startSector, pda->numSector, undoBuf, parityStripeID, which_ru,			      node->wakeFunc, (void *) node, NULL, node->dagHdr->tracerec,			      (void *) (node->dagHdr->raidPtr), flags, b_proc);        if (!req) {      (node->wakeFunc)(node, ENOMEM);    } else {      node->dagFuncData = (void *) req;      rf_DiskIOEnqueue( &(dqs[pda->row][pda->col]), req, priority );    }  }  return(0);#endif /* RF_BACKWARD > 0 */  /* normal processing (rollaway or forward recovery) begins here */  RF_ASSERT( !(lock && unlock) );  flags |= (lock)   ? RF_LOCK_DISK_QUEUE   : 0;  flags |= (unlock) ? RF_UNLOCK_DISK_QUEUE : 0;  req = rf_CreateDiskQueueData(iotype, 			    pda->startSector, pda->numSector, buf, parityStripeID, which_ru,			    node->wakeFunc, (void *) node, NULL, node->dagHdr->tracerec,			    (void *) (node->dagHdr->raidPtr), flags, b_proc);  if (!req) {    (node->wakeFunc)(node, ENOMEM);  } else {    node->dagFuncData = (void *) req;    rf_DiskIOEnqueue( &(dqs[pda->row][pda->col]), req, priority );  }  return(0);}/***************************************************************************************** * the undo function for disk nodes * Note:  this is not a proper undo of a write node, only locks are released. *        old data is not restored to disk! ****************************************************************************************/int rf_DiskUndoFunc(node)  RF_DagNode_t  *node;{  RF_DiskQueueData_t *req;  RF_PhysDiskAddr_t  *pda = (RF_PhysDiskAddr_t *)node->params[0].p;  RF_DiskQueue_t **dqs = ((RF_Raid_t *) (node->dagHdr->raidPtr))->Queues;  req = rf_CreateDiskQueueData(RF_IO_TYPE_NOP,			    0L, 0, NULL, 0L, 0,			    node->wakeFunc, (void *) node, NULL, node->dagHdr->tracerec,			    (void *) (node->dagHdr->raidPtr), RF_UNLOCK_DISK_QUEUE, NULL);  if (!req)    (node->wakeFunc)(node, ENOMEM);  else {    node->dagFuncData = (void *) req;    rf_DiskIOEnqueue( &(dqs[pda->row][pda->col]), req, RF_IO_NORMAL_PRIORITY );  }  return(0);}/***************************************************************************************** * the execution function associated with an "unlock disk queue" node ****************************************************************************************/int rf_DiskUnlockFuncForThreads(node)  RF_DagNode_t  *node;{  RF_DiskQueueData_t *req;  RF_PhysDiskAddr_t *pda = (RF_PhysDiskAddr_t *)node->params[0].p;  RF_DiskQueue_t **dqs = ((RF_Raid_t *) (node->dagHdr->raidPtr))->Queues;  req = rf_CreateDiskQueueData(RF_IO_TYPE_NOP,			    0L, 0, NULL, 0L, 0,			    node->wakeFunc, (void *) node, NULL, node->dagHdr->tracerec,			    (void *) (node->dagHdr->raidPtr), RF_UNLOCK_DISK_QUEUE, NULL);  if (!req)    (node->wakeFunc)(node, ENOMEM);  else {    node->dagFuncData = (void *) req;    rf_DiskIOEnqueue( &(dqs[pda->row][pda->col]), req, RF_IO_NORMAL_PRIORITY );  }  return(0);}/***************************************************************************************** * Callback routine for DiskRead and DiskWrite nodes.  When the disk op completes, * the routine is called to set the node status and inform the execution engine that * the node has fired. ****************************************************************************************/int rf_GenericWakeupFunc(node, status)  RF_DagNode_t  *node;  int            status;{  switch (node->status) {  case rf_bwd1 :    node->status = rf_bwd2;    if (node->dagFuncData)      rf_FreeDiskQueueData((RF_DiskQueueData_t *) node->dagFuncData);    return(rf_DiskWriteFuncForThreads(node));    break;  case rf_fired :    if (status) node->status = rf_bad;    else node->status = rf_good;    break;  case rf_recover :    /* probably should never reach this case */    if (status) node->status = rf_panic;    else node->status = rf_undone;    break;  default :    RF_PANIC();    break;  }  if (node->dagFuncData)    rf_FreeDiskQueueData((RF_DiskQueueData_t *) node->dagFuncData);  return(rf_FinishNode(node, RF_INTR_CONTEXT));}/***************************************************************************************** * there are three distinct types of xor nodes * A "regular xor" is used in the fault-free case where the access spans a complete * stripe unit.  It assumes that the result buffer is one full stripe unit in size, * and uses the stripe-unit-offset values that it computes from the PDAs to determine * where within the stripe unit to XOR each argument buffer. * * A "simple xor" is used in the fault-free case where the access touches only a portion * of one (or two, in some cases) stripe unit(s).  It assumes that all the argument * buffers are of the same size and have the same stripe unit offset. * * A "recovery xor" is used in the degraded-mode case.  It's similar to the regular * xor function except that it takes the failed PDA as an additional parameter, and * uses it to determine what portions of the argument buffers need to be xor'd into * the result buffer, and where in the result buffer they should go. ****************************************************************************************//* xor the params together and store the result in the result field. * assume the result field points to a buffer that is the size of one SU, * and use the pda params to determine where within the buffer to XOR * the input buffers. */int rf_RegularXorFunc(node)  RF_DagNode_t  *node;{  RF_Raid_t *raidPtr = (RF_Raid_t *)node->params[node->numParams-1].p;  RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;

⌨️ 快捷键说明

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