This source file includes following definitions.
- RF_Raid1ConfigInfo_t
- rf_ConfigureRAID1
- rf_MapSectorRAID1
- rf_MapParityRAID1
- rf_IdentifyStripeRAID1
- rf_MapSIDToPSIDRAID1
- rf_RAID1DagSelect
- rf_VerifyParityRAID1
- rf_SubmitReconBufferRAID1
    1 
    2 
    3 
    4 
    5 
    6 
    7 
    8 
    9 
   10 
   11 
   12 
   13 
   14 
   15 
   16 
   17 
   18 
   19 
   20 
   21 
   22 
   23 
   24 
   25 
   26 
   27 
   28 
   29 
   30 
   31 
   32 
   33 
   34 
   35 
   36 
   37 #include "rf_raid.h"
   38 #include "rf_raid1.h"
   39 #include "rf_dag.h"
   40 #include "rf_dagffrd.h"
   41 #include "rf_dagffwr.h"
   42 #include "rf_dagdegrd.h"
   43 #include "rf_dagutils.h"
   44 #include "rf_dagfuncs.h"
   45 #include "rf_diskqueue.h"
   46 #include "rf_general.h"
   47 #include "rf_utils.h"
   48 #include "rf_parityscan.h"
   49 #include "rf_mcpair.h"
   50 #include "rf_layout.h"
   51 #include "rf_map.h"
   52 #include "rf_engine.h"
   53 #include "rf_reconbuffer.h"
   54 
   55 typedef struct RF_Raid1ConfigInfo_s {
   56         RF_RowCol_t **stripeIdentifier;
   57 } RF_Raid1ConfigInfo_t;
   58 
   59 
   60 
   61 int
   62 rf_ConfigureRAID1(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
   63     RF_Config_t *cfgPtr)
   64 {
   65         RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;
   66         RF_Raid1ConfigInfo_t *info;
   67         RF_RowCol_t i;
   68 
   69         
   70         RF_MallocAndAdd(info, sizeof(RF_Raid1ConfigInfo_t),
   71             (RF_Raid1ConfigInfo_t *), raidPtr->cleanupList);
   72         if (info == NULL)
   73                 return (ENOMEM);
   74         layoutPtr->layoutSpecificInfo = (void *) info;
   75 
   76         
   77         info->stripeIdentifier = rf_make_2d_array(raidPtr->numCol / 2, 2,
   78             raidPtr->cleanupList);
   79         if (info->stripeIdentifier == NULL)
   80                 return (ENOMEM);
   81         for (i = 0; i < (raidPtr->numCol / 2); i++) {
   82                 info->stripeIdentifier[i][0] = (2 * i);
   83                 info->stripeIdentifier[i][1] = (2 * i) + 1;
   84         }
   85 
   86         RF_ASSERT(raidPtr->numRow == 1);
   87 
   88         
   89 
   90 
   91 
   92 
   93 
   94         raidPtr->totalSectors = layoutPtr->stripeUnitsPerDisk *
   95             (raidPtr->numCol / 2) * layoutPtr->sectorsPerStripeUnit;
   96         layoutPtr->numStripe = layoutPtr->stripeUnitsPerDisk *
   97             (raidPtr->numCol / 2);
   98         layoutPtr->dataSectorsPerStripe = layoutPtr->sectorsPerStripeUnit;
   99         layoutPtr->bytesPerStripeUnit = layoutPtr->sectorsPerStripeUnit <<
  100             raidPtr->logBytesPerSector;
  101         layoutPtr->numDataCol = 1;
  102         layoutPtr->numParityCol = 1;
  103         return (0);
  104 }
  105 
  106 
  107 
  108 
  109 
  110 void
  111 rf_MapSectorRAID1(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
  112     RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap)
  113 {
  114         RF_StripeNum_t SUID = raidSector / raidPtr->Layout.sectorsPerStripeUnit;
  115         RF_RowCol_t mirrorPair = SUID % (raidPtr->numCol / 2);
  116 
  117         *row = 0;
  118         *col = 2 * mirrorPair;
  119         *diskSector = ((SUID / (raidPtr->numCol / 2)) *
  120              raidPtr->Layout.sectorsPerStripeUnit) +
  121             (raidSector % raidPtr->Layout.sectorsPerStripeUnit);
  122 }
  123 
  124 
  125 
  126 
  127 
  128 
  129 
  130 
  131 void
  132 rf_MapParityRAID1(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
  133     RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap)
  134 {
  135         RF_StripeNum_t SUID = raidSector / raidPtr->Layout.sectorsPerStripeUnit;
  136         RF_RowCol_t mirrorPair = SUID % (raidPtr->numCol / 2);
  137 
  138         *row = 0;
  139         *col = (2 * mirrorPair) + 1;
  140 
  141         *diskSector = ((SUID / (raidPtr->numCol / 2)) *
  142              raidPtr->Layout.sectorsPerStripeUnit) +
  143             (raidSector % raidPtr->Layout.sectorsPerStripeUnit);
  144 }
  145 
  146 
  147 
  148 
  149 
  150 
  151 
  152 void
  153 rf_IdentifyStripeRAID1(RF_Raid_t *raidPtr, RF_RaidAddr_t addr,
  154     RF_RowCol_t **diskids, RF_RowCol_t *outRow)
  155 {
  156         RF_StripeNum_t stripeID = rf_RaidAddressToStripeID(&raidPtr->Layout,
  157             addr);
  158         RF_Raid1ConfigInfo_t *info = raidPtr->Layout.layoutSpecificInfo;
  159         RF_ASSERT(stripeID >= 0);
  160         RF_ASSERT(addr >= 0);
  161         *outRow = 0;
  162         *diskids = info->stripeIdentifier[stripeID % (raidPtr->numCol / 2)];
  163         RF_ASSERT(*diskids);
  164 }
  165 
  166 
  167 
  168 
  169 
  170 
  171 
  172 void
  173 rf_MapSIDToPSIDRAID1(RF_RaidLayout_t *layoutPtr, RF_StripeNum_t stripeID,
  174     RF_StripeNum_t *psID, RF_ReconUnitNum_t *which_ru)
  175 {
  176         *which_ru = 0;
  177         *psID = stripeID;
  178 }
  179 
  180 
  181 
  182 
  183 
  184 
  185 
  186 
  187 
  188 
  189 
  190 
  191 void
  192 rf_RAID1DagSelect(RF_Raid_t *raidPtr, RF_IoType_t type,
  193     RF_AccessStripeMap_t *asmap, RF_VoidFuncPtr *createFunc)
  194 {
  195         RF_RowCol_t frow, fcol, or, oc;
  196         RF_PhysDiskAddr_t *failedPDA;
  197         int prior_recon;
  198         RF_RowStatus_t rstat;
  199         RF_SectorNum_t oo;
  200 
  201 
  202         RF_ASSERT(RF_IO_IS_R_OR_W(type));
  203 
  204         if (asmap->numDataFailed + asmap->numParityFailed > 1) {
  205                 RF_ERRORMSG("Multiple disks failed in a single group !"
  206                             "  Aborting I/O operation.\n");
  207                 *createFunc = NULL;
  208                 return;
  209         }
  210         if (asmap->numDataFailed + asmap->numParityFailed) {
  211                 
  212 
  213 
  214 
  215 
  216 
  217 
  218 
  219                 failedPDA = asmap->failedPDAs[0];
  220                 frow = failedPDA->row;
  221                 fcol = failedPDA->col;
  222                 rstat = raidPtr->status[frow];
  223                 prior_recon = (rstat == rf_rs_reconfigured) || (
  224                     (rstat == rf_rs_reconstructing) ?
  225                     rf_CheckRUReconstructed(raidPtr->reconControl[frow]
  226                      ->reconMap, failedPDA->startSector) : 0);
  227                 if (prior_recon) {
  228                         or = frow;
  229                         oc = fcol;
  230                         oo = failedPDA->startSector;
  231                         
  232 
  233 
  234 
  235 
  236                         failedPDA->row = raidPtr->Disks[frow][fcol].spareRow;
  237                         failedPDA->col = raidPtr->Disks[frow][fcol].spareCol;
  238                         
  239 
  240 
  241 
  242 
  243                         if (asmap->parityInfo->next) {
  244                                 if (failedPDA == asmap->parityInfo) {
  245                                         failedPDA->next->row = failedPDA->row;
  246                                         failedPDA->next->col = failedPDA->col;
  247                                 } else {
  248                                         if (failedPDA ==
  249                                             asmap->parityInfo->next) {
  250                                                 asmap->parityInfo->row =
  251                                                     failedPDA->row;
  252                                                 asmap->parityInfo->col =
  253                                                     failedPDA->col;
  254                                         }
  255                                 }
  256                         }
  257                         if (rf_dagDebug || rf_mapDebug) {
  258                                 printf("raid%d: Redirected type '%c' r %d c %d"
  259                                     " o %ld -> r %d c %d o %ld.\n",
  260                                     raidPtr->raidid, type, or, oc, (long) oo,
  261                                     failedPDA->row, failedPDA->col,
  262                                     (long) failedPDA->startSector);
  263                         }
  264                         asmap->numDataFailed = asmap->numParityFailed = 0;
  265                 }
  266         }
  267         if (type == RF_IO_TYPE_READ) {
  268                 if (asmap->numDataFailed == 0)
  269                         *createFunc = (RF_VoidFuncPtr)
  270                             rf_CreateMirrorIdleReadDAG;
  271                 else
  272                         *createFunc = (RF_VoidFuncPtr)
  273                             rf_CreateRaidOneDegradedReadDAG;
  274         } else {
  275                 *createFunc = (RF_VoidFuncPtr) rf_CreateRaidOneWriteDAG;
  276         }
  277 }
  278 
  279 int
  280 rf_VerifyParityRAID1(RF_Raid_t *raidPtr, RF_RaidAddr_t raidAddr,
  281     RF_PhysDiskAddr_t *parityPDA, int correct_it, RF_RaidAccessFlags_t flags)
  282 {
  283         int nbytes, bcount, stripeWidth, ret, i, j, nbad, *bbufs;
  284         RF_DagNode_t *blockNode, *unblockNode, *wrBlock;
  285         RF_DagHeader_t *rd_dag_h, *wr_dag_h;
  286         RF_AccessStripeMapHeader_t *asm_h;
  287         RF_AllocListElem_t *allocList;
  288         RF_AccTraceEntry_t tracerec;
  289         RF_ReconUnitNum_t which_ru;
  290         RF_RaidLayout_t *layoutPtr;
  291         RF_AccessStripeMap_t *aasm;
  292         RF_SectorCount_t nsector;
  293         RF_RaidAddr_t startAddr;
  294         char *buf, *buf1, *buf2;
  295         RF_PhysDiskAddr_t *pda;
  296         RF_StripeNum_t psID;
  297         RF_MCPair_t *mcpair;
  298 
  299         layoutPtr = &raidPtr->Layout;
  300         startAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, raidAddr);
  301         nsector = parityPDA->numSector;
  302         nbytes = rf_RaidAddressToByte(raidPtr, nsector);
  303         psID = rf_RaidAddressToParityStripeID(layoutPtr, raidAddr, &which_ru);
  304 
  305         asm_h = NULL;
  306         rd_dag_h = wr_dag_h = NULL;
  307         mcpair = NULL;
  308 
  309         ret = RF_PARITY_COULD_NOT_VERIFY;
  310 
  311         rf_MakeAllocList(allocList);
  312         if (allocList == NULL)
  313                 return (RF_PARITY_COULD_NOT_VERIFY);
  314         mcpair = rf_AllocMCPair();
  315         if (mcpair == NULL)
  316                 goto done;
  317         RF_ASSERT(layoutPtr->numDataCol == layoutPtr->numParityCol);
  318         stripeWidth = layoutPtr->numDataCol + layoutPtr->numParityCol;
  319         bcount = nbytes * (layoutPtr->numDataCol + layoutPtr->numParityCol);
  320         RF_MallocAndAdd(buf, bcount, (char *), allocList);
  321         if (buf == NULL)
  322                 goto done;
  323         if (rf_verifyParityDebug) {
  324                 printf("raid%d: RAID1 parity verify: buf=%lx bcount=%d"
  325                     " (%lx - %lx).\n", raidPtr->raidid, (long) buf, bcount,
  326                     (long) buf, (long) buf + bcount);
  327         }
  328         
  329 
  330 
  331 
  332 
  333         rd_dag_h = rf_MakeSimpleDAG(raidPtr, stripeWidth, nbytes, buf,
  334             rf_DiskReadFunc, rf_DiskReadUndoFunc, "Rod", allocList, flags,
  335             RF_IO_NORMAL_PRIORITY);
  336         if (rd_dag_h == NULL)
  337                 goto done;
  338         blockNode = rd_dag_h->succedents[0];
  339         unblockNode = blockNode->succedents[0]->succedents[0];
  340 
  341         
  342 
  343 
  344 
  345 
  346         asm_h = rf_MapAccess(raidPtr, startAddr,
  347             layoutPtr->dataSectorsPerStripe, buf, RF_DONT_REMAP);
  348         aasm = asm_h->stripeMap;
  349 
  350         buf1 = buf;
  351         
  352 
  353 
  354         for (pda = aasm->physInfo, i = 0; i < layoutPtr->numDataCol;
  355              i++, pda = pda->next) {
  356                 RF_ASSERT(pda);
  357 
  358                 rf_RangeRestrictPDA(raidPtr, parityPDA, pda, 0, 1);
  359 
  360                 RF_ASSERT(pda->numSector != 0);
  361                 if (rf_TryToRedirectPDA(raidPtr, pda, 0)) {
  362                         
  363                         goto done;
  364                 }
  365                 pda->bufPtr = buf1;
  366                 blockNode->succedents[i]->params[0].p = pda;
  367                 blockNode->succedents[i]->params[1].p = buf1;
  368                 blockNode->succedents[i]->params[2].v = psID;
  369                 blockNode->succedents[i]->params[3].v =
  370                     RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru);
  371                 buf1 += nbytes;
  372         }
  373         RF_ASSERT(pda == NULL);
  374         
  375 
  376 
  377 
  378 
  379         for (pda = aasm->parityInfo; i < layoutPtr->numDataCol +
  380              layoutPtr->numParityCol; i++, pda = pda->next) {
  381                 RF_ASSERT(pda);
  382                 rf_RangeRestrictPDA(raidPtr, parityPDA, pda, 0, 1);
  383                 RF_ASSERT(pda->numSector != 0);
  384                 if (rf_TryToRedirectPDA(raidPtr, pda, 0)) {
  385                         
  386                         goto done;
  387                 }
  388                 pda->bufPtr = buf1;
  389                 blockNode->succedents[i]->params[0].p = pda;
  390                 blockNode->succedents[i]->params[1].p = buf1;
  391                 blockNode->succedents[i]->params[2].v = psID;
  392                 blockNode->succedents[i]->params[3].v =
  393                     RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru);
  394                 buf1 += nbytes;
  395         }
  396         RF_ASSERT(pda == NULL);
  397 
  398         bzero((char *) &tracerec, sizeof(tracerec));
  399         rd_dag_h->tracerec = &tracerec;
  400 
  401         if (rf_verifyParityDebug > 1) {
  402                 printf("raid%d: RAID1 parity verify read dag:\n",
  403                     raidPtr->raidid);
  404                 rf_PrintDAGList(rd_dag_h);
  405         }
  406         RF_LOCK_MUTEX(mcpair->mutex);
  407         mcpair->flag = 0;
  408         rf_DispatchDAG(rd_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc,
  409             (void *) mcpair);
  410         while (mcpair->flag == 0) {
  411                 RF_WAIT_MCPAIR(mcpair);
  412         }
  413         RF_UNLOCK_MUTEX(mcpair->mutex);
  414 
  415         if (rd_dag_h->status != rf_enable) {
  416                 RF_ERRORMSG("Unable to verify raid1 parity:"
  417                             " can't read stripe.\n");
  418                 ret = RF_PARITY_COULD_NOT_VERIFY;
  419                 goto done;
  420         }
  421         
  422 
  423 
  424 
  425         buf1 = buf;
  426         buf2 = buf + (nbytes * layoutPtr->numDataCol);
  427         ret = RF_PARITY_OKAY;
  428         
  429 
  430 
  431 
  432 
  433 
  434         RF_MallocAndAdd(bbufs, layoutPtr->numParityCol * sizeof(int), (int *),
  435             allocList);
  436         nbad = 0;
  437         
  438 
  439 
  440         for (i = 0; i < layoutPtr->numDataCol; i++) {
  441                 if (rf_verifyParityDebug) {
  442                         printf("raid%d: RAID1 parity verify %d bytes: i=%d"
  443                             " buf1=%lx buf2=%lx buf=%lx.\n", raidPtr->raidid,
  444                             nbytes, i, (long) buf1, (long) buf2, (long) buf);
  445                 }
  446                 ret = bcmp(buf1, buf2, nbytes);
  447                 if (ret) {
  448                         if (rf_verifyParityDebug > 1) {
  449                                 for (j = 0; j < nbytes; j++) {
  450                                         if (buf1[j] != buf2[j])
  451                                                 break;
  452                                 }
  453                                 printf("psid=%ld j=%d\n", (long) psID, j);
  454                                 printf("buf1 %02x %02x %02x %02x %02x\n",
  455                                     buf1[0] & 0xff, buf1[1] & 0xff,
  456                                     buf1[2] & 0xff, buf1[3] & 0xff,
  457                                     buf1[4] & 0xff);
  458                                 printf("buf2 %02x %02x %02x %02x %02x\n",
  459                                     buf2[0] & 0xff, buf2[1] & 0xff,
  460                                     buf2[2] & 0xff, buf2[3] & 0xff,
  461                                     buf2[4] & 0xff);
  462                         }
  463                         if (rf_verifyParityDebug) {
  464                                 printf("raid%d: RAID1: found bad parity,"
  465                                     " i=%d.\n", raidPtr->raidid, i);
  466                         }
  467                         
  468 
  469 
  470                         if (bbufs)
  471                                 bbufs[nbad] = i;
  472                         nbad++;
  473                         ret = RF_PARITY_BAD;
  474                 }
  475                 buf1 += nbytes;
  476                 buf2 += nbytes;
  477         }
  478 
  479         if ((ret != RF_PARITY_OKAY) && correct_it) {
  480                 ret = RF_PARITY_COULD_NOT_CORRECT;
  481                 if (rf_verifyParityDebug) {
  482                         printf("raid%d: RAID1 parity verify:"
  483                             " parity not correct.\n", raidPtr->raidid);
  484                 }
  485                 if (bbufs == NULL)
  486                         goto done;
  487                 
  488 
  489 
  490 
  491 
  492 
  493 
  494                 wr_dag_h = rf_MakeSimpleDAG(raidPtr, nbad, nbytes, buf,
  495                     rf_DiskWriteFunc, rf_DiskWriteUndoFunc, "Wnp", allocList,
  496                     flags, RF_IO_NORMAL_PRIORITY);
  497                 if (wr_dag_h == NULL)
  498                         goto done;
  499                 wrBlock = wr_dag_h->succedents[0];
  500                 
  501 
  502 
  503                 for (i = 0; i < nbad; i++) {
  504                         j = i + layoutPtr->numDataCol;
  505                         pda = blockNode->succedents[j]->params[0].p;
  506                         pda->bufPtr = blockNode->succedents[i]->params[1].p;
  507                         wrBlock->succedents[i]->params[0].p = pda;
  508                         wrBlock->succedents[i]->params[1].p = pda->bufPtr;
  509                         wrBlock->succedents[i]->params[2].v = psID;
  510                         wrBlock->succedents[0]->params[3].v =
  511                             RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0,
  512                              which_ru);
  513                 }
  514                 bzero((char *) &tracerec, sizeof(tracerec));
  515                 wr_dag_h->tracerec = &tracerec;
  516                 if (rf_verifyParityDebug > 1) {
  517                         printf("Parity verify write dag:\n");
  518                         rf_PrintDAGList(wr_dag_h);
  519                 }
  520                 RF_LOCK_MUTEX(mcpair->mutex);
  521                 mcpair->flag = 0;
  522                 
  523                 rf_DispatchDAG(wr_dag_h, (void (*) (void *))
  524                     rf_MCPairWakeupFunc, (void *) mcpair);
  525                 while (!mcpair->flag) {
  526                         RF_WAIT_COND(mcpair->cond, mcpair->mutex);
  527                 }
  528                 RF_UNLOCK_MUTEX(mcpair->mutex);
  529                 if (wr_dag_h->status != rf_enable) {
  530                         RF_ERRORMSG("Unable to correct RAID1 parity in"
  531                                     " VerifyParity.\n");
  532                         goto done;
  533                 }
  534                 ret = RF_PARITY_CORRECTED;
  535         }
  536 done:
  537         
  538 
  539 
  540 
  541         if (asm_h)
  542                 rf_FreeAccessStripeMap(asm_h);
  543         if (rd_dag_h)
  544                 rf_FreeDAG(rd_dag_h);
  545         if (wr_dag_h)
  546                 rf_FreeDAG(wr_dag_h);
  547         if (mcpair)
  548                 rf_FreeMCPair(mcpair);
  549         rf_FreeAllocList(allocList);
  550         if (rf_verifyParityDebug) {
  551                 printf("raid%d: RAID1 parity verify, returning %d.\n",
  552                     raidPtr->raidid, ret);
  553         }
  554         return (ret);
  555 }
  556 
  557 int
  558 rf_SubmitReconBufferRAID1(
  559     RF_ReconBuffer_t    *rbuf,          
  560     int                  keep_it,       
  561 
  562 
  563 
  564     int                  use_committed  
  565 
  566 
  567 
  568 )
  569 {
  570         RF_ReconParityStripeStatus_t *pssPtr;
  571         RF_ReconCtrl_t *reconCtrlPtr;
  572         RF_RaidLayout_t *layoutPtr;
  573         int retcode, created;
  574         RF_CallbackDesc_t *cb, *p;
  575         RF_ReconBuffer_t *t;
  576         RF_Raid_t *raidPtr;
  577         caddr_t ta;
  578 
  579         retcode = 0;
  580         created = 0;
  581 
  582         raidPtr = rbuf->raidPtr;
  583         layoutPtr = &raidPtr->Layout;
  584         reconCtrlPtr = raidPtr->reconControl[rbuf->row];
  585 
  586         RF_ASSERT(rbuf);
  587         RF_ASSERT(rbuf->col != reconCtrlPtr->fcol);
  588 
  589         if (rf_reconbufferDebug) {
  590                 printf("raid%d: RAID1 reconbuffer submission r%d c%d psid %ld"
  591                     " ru%d (failed offset %ld).\n", raidPtr->raidid, rbuf->row,
  592                     rbuf->col, (long) rbuf->parityStripeID, rbuf->which_ru,
  593                     (long) rbuf->failedDiskSectorOffset);
  594         }
  595         if (rf_reconDebug) {
  596                 printf("RAID1 reconbuffer submit psid %ld buf %lx\n",
  597                     (long) rbuf->parityStripeID, (long) rbuf->buffer);
  598                 printf("RAID1 psid %ld   %02x %02x %02x %02x %02x\n",
  599                     (long) rbuf->parityStripeID,
  600                     rbuf->buffer[0], rbuf->buffer[1], rbuf->buffer[2],
  601                     rbuf->buffer[3], rbuf->buffer[4]);
  602         }
  603         RF_LOCK_PSS_MUTEX(raidPtr, rbuf->row, rbuf->parityStripeID);
  604 
  605         RF_LOCK_MUTEX(reconCtrlPtr->rb_mutex);
  606 
  607         pssPtr = rf_LookupRUStatus(raidPtr, reconCtrlPtr->pssTable,
  608             rbuf->parityStripeID, rbuf->which_ru, RF_PSS_NONE, &created);
  609         RF_ASSERT(pssPtr);      
  610 
  611 
  612 
  613 
  614         
  615 
  616 
  617 
  618 
  619         t = NULL;
  620         if (keep_it) {
  621                 if (rf_reconbufferDebug) {
  622                         printf("raid%d: RAID1 rbuf submission: keeping rbuf.\n",
  623                             raidPtr->raidid);
  624                 }
  625                 t = rbuf;
  626         } else {
  627                 if (use_committed) {
  628                         if (rf_reconbufferDebug) {
  629                                 printf("raid%d: RAID1 rbuf submission:"
  630                                     " using committed rbuf.\n",
  631                                     raidPtr->raidid);
  632                         }
  633                         t = reconCtrlPtr->committedRbufs;
  634                         RF_ASSERT(t);
  635                         reconCtrlPtr->committedRbufs = t->next;
  636                         t->next = NULL;
  637                 } else
  638                         if (reconCtrlPtr->floatingRbufs) {
  639                                 if (rf_reconbufferDebug) {
  640                                         printf("raid%d: RAID1 rbuf submission:"
  641                                             " using floating rbuf.\n",
  642                                             raidPtr->raidid);
  643                                 }
  644                                 t = reconCtrlPtr->floatingRbufs;
  645                                 reconCtrlPtr->floatingRbufs = t->next;
  646                                 t->next = NULL;
  647                         }
  648         }
  649         if (t == NULL) {
  650                 if (rf_reconbufferDebug) {
  651                         printf("raid%d: RAID1 rbuf submission:"
  652                             " waiting for rbuf.\n", raidPtr->raidid);
  653                 }
  654                 RF_ASSERT((keep_it == 0) && (use_committed == 0));
  655                 raidPtr->procsInBufWait++;
  656                 if ((raidPtr->procsInBufWait == (raidPtr->numCol - 1))
  657                     && (raidPtr->numFullReconBuffers == 0)) {
  658                         
  659                         RF_ERRORMSG("Buffer wait deadlock.\n");
  660                         rf_PrintPSStatusTable(raidPtr, rbuf->row);
  661                         RF_PANIC();
  662                 }
  663                 pssPtr->flags |= RF_PSS_BUFFERWAIT;
  664                 cb = rf_AllocCallbackDesc();
  665                 cb->row = rbuf->row;
  666                 cb->col = rbuf->col;
  667                 cb->callbackArg.v = rbuf->parityStripeID;
  668                 cb->callbackArg2.v = rbuf->which_ru;
  669                 cb->next = NULL;
  670                 if (reconCtrlPtr->bufferWaitList == NULL) {
  671                         
  672                         reconCtrlPtr->bufferWaitList = cb;
  673                 } else {
  674                         
  675                         for (p = reconCtrlPtr->bufferWaitList; p->next;
  676                              p = p->next);
  677                         p->next = cb;
  678                 }
  679                 retcode = 1;
  680                 goto out;
  681         }
  682         if (t != rbuf) {
  683                 t->row = rbuf->row;
  684                 t->col = reconCtrlPtr->fcol;
  685                 t->parityStripeID = rbuf->parityStripeID;
  686                 t->which_ru = rbuf->which_ru;
  687                 t->failedDiskSectorOffset = rbuf->failedDiskSectorOffset;
  688                 t->spRow = rbuf->spRow;
  689                 t->spCol = rbuf->spCol;
  690                 t->spOffset = rbuf->spOffset;
  691                 
  692                 ta = t->buffer;
  693                 t->buffer = rbuf->buffer;
  694                 rbuf->buffer = ta;
  695         }
  696         
  697 
  698 
  699         RF_ASSERT(pssPtr->rbuf == NULL);
  700         pssPtr->rbuf = t;
  701 
  702         t->count = 1;
  703         
  704 
  705 
  706 
  707         rf_CheckForFullRbuf(raidPtr, reconCtrlPtr, pssPtr, 1);
  708 
  709 out:
  710         RF_UNLOCK_PSS_MUTEX(raidPtr, rbuf->row, rbuf->parityStripeID);
  711         RF_UNLOCK_MUTEX(reconCtrlPtr->rb_mutex);
  712         if (rf_reconbufferDebug) {
  713                 printf("raid%d: RAID1 rbuf submission: returning %d.\n",
  714                     raidPtr->raidid, retcode);
  715         }
  716         return (retcode);
  717 }