[BACK]Return to rf_reconutil.c CVS log [TXT][DIR] Up to [local] / sys / dev / raidframe

Annotation of sys/dev/raidframe/rf_reconutil.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: rf_reconutil.c,v 1.3 2002/12/16 07:01:05 tdeval Exp $ */
                      2: /*     $NetBSD: rf_reconutil.c,v 1.3 1999/02/05 00:06:17 oster Exp $   */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Carnegie-Mellon University.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Author: Mark Holland
                      9:  *
                     10:  * Permission to use, copy, modify and distribute this software and
                     11:  * its documentation is hereby granted, provided that both the copyright
                     12:  * notice and this permission notice appear in all copies of the
                     13:  * software, derivative works or modified versions, and any portions
                     14:  * thereof, and that both notices appear in supporting documentation.
                     15:  *
                     16:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     17:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
                     18:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     19:  *
                     20:  * Carnegie Mellon requests users of this software to return to
                     21:  *
                     22:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     23:  *  School of Computer Science
                     24:  *  Carnegie Mellon University
                     25:  *  Pittsburgh PA 15213-3890
                     26:  *
                     27:  * any improvements or extensions that they make and grant Carnegie the
                     28:  * rights to redistribute these changes.
                     29:  */
                     30:
                     31: /**********************************************
                     32:  * rf_reconutil.c -- Reconstruction utilities.
                     33:  **********************************************/
                     34:
                     35: #include "rf_types.h"
                     36: #include "rf_raid.h"
                     37: #include "rf_desc.h"
                     38: #include "rf_reconutil.h"
                     39: #include "rf_reconbuffer.h"
                     40: #include "rf_general.h"
                     41: #include "rf_decluster.h"
                     42: #include "rf_raid5_rotatedspare.h"
                     43: #include "rf_interdecluster.h"
                     44: #include "rf_chaindecluster.h"
                     45:
                     46:
                     47: /*********************************************************************
                     48:  * Allocates/frees the reconstruction control information structures.
                     49:  *********************************************************************/
                     50: RF_ReconCtrl_t *
                     51: rf_MakeReconControl(
                     52:     RF_RaidReconDesc_t *reconDesc,
                     53:     RF_RowCol_t                 frow,  /* Failed row and column. */
                     54:     RF_RowCol_t                 fcol,
                     55:     RF_RowCol_t                 srow,  /* Identifies which spare we're using. */
                     56:     RF_RowCol_t                 scol
                     57: )
                     58: {
                     59:        RF_Raid_t *raidPtr = reconDesc->raidPtr;
                     60:        RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;
                     61:        RF_ReconUnitCount_t RUsPerPU = layoutPtr->SUsPerPU /
                     62:            layoutPtr->SUsPerRU;
                     63:        RF_ReconUnitCount_t numSpareRUs;
                     64:        RF_ReconCtrl_t *reconCtrlPtr;
                     65:        RF_ReconBuffer_t *rbuf;
                     66:        RF_LayoutSW_t *lp;
                     67:        int retcode, rc;
                     68:        RF_RowCol_t i;
                     69:
                     70:        lp = raidPtr->Layout.map;
                     71:
                     72:        /*
                     73:         * Make and zero the global reconstruction structure and the per-disk
                     74:         * structure.
                     75:         */
                     76:        RF_Calloc(reconCtrlPtr, 1, sizeof(RF_ReconCtrl_t), (RF_ReconCtrl_t *));
                     77:        /* This zeros it. */
                     78:        RF_Calloc(reconCtrlPtr->perDiskInfo, raidPtr->numCol,
                     79:            sizeof(RF_PerDiskReconCtrl_t), (RF_PerDiskReconCtrl_t *));
                     80:        reconCtrlPtr->reconDesc = reconDesc;
                     81:        reconCtrlPtr->fcol = fcol;
                     82:        reconCtrlPtr->spareRow = srow;
                     83:        reconCtrlPtr->spareCol = scol;
                     84:        reconCtrlPtr->lastPSID = layoutPtr->numStripe / layoutPtr->SUsPerPU;
                     85:        reconCtrlPtr->percentComplete = 0;
                     86:
                     87:        /* Initialize each per-disk recon information structure. */
                     88:        for (i = 0; i < raidPtr->numCol; i++) {
                     89:                reconCtrlPtr->perDiskInfo[i].reconCtrl = reconCtrlPtr;
                     90:                reconCtrlPtr->perDiskInfo[i].row = frow;
                     91:                reconCtrlPtr->perDiskInfo[i].col = i;
                     92:                /* Make it appear as if we just finished an RU. */
                     93:                reconCtrlPtr->perDiskInfo[i].curPSID = -1;
                     94:                reconCtrlPtr->perDiskInfo[i].ru_count = RUsPerPU - 1;
                     95:        }
                     96:
                     97:        /*
                     98:         * Get the number of spare units per disk and the sparemap in case
                     99:         * spare is distributed.
                    100:         */
                    101:
                    102:        if (lp->GetNumSpareRUs) {
                    103:                numSpareRUs = lp->GetNumSpareRUs(raidPtr);
                    104:        } else {
                    105:                numSpareRUs = 0;
                    106:        }
                    107:
                    108:        /*
                    109:         * Not all distributed sparing archs need dynamic mappings.
                    110:         */
                    111:        if (lp->InstallSpareTable) {
                    112:                retcode = rf_InstallSpareTable(raidPtr, frow, fcol);
                    113:                if (retcode) {
                    114:                        RF_PANIC();     /* XXX Fix this. */
                    115:                }
                    116:        }
                    117:        /* Make the reconstruction map. */
                    118:        reconCtrlPtr->reconMap = rf_MakeReconMap(raidPtr,
                    119:            (int) (layoutPtr->SUsPerRU * layoutPtr->sectorsPerStripeUnit),
                    120:            raidPtr->sectorsPerDisk, numSpareRUs);
                    121:
                    122:        /* Make the per-disk reconstruction buffers. */
                    123:        for (i = 0; i < raidPtr->numCol; i++) {
                    124:                reconCtrlPtr->perDiskInfo[i].rbuf = (i == fcol) ? NULL :
                    125:                    rf_MakeReconBuffer(raidPtr, frow, i,
                    126:                     RF_RBUF_TYPE_EXCLUSIVE);
                    127:        }
                    128:
                    129:        /* Initialize the event queue. */
                    130:        rc = rf_mutex_init(&reconCtrlPtr->eq_mutex);
                    131:        if (rc) {
                    132:                /* XXX Deallocate, cleanup. */
                    133:                RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d.\n",
                    134:                    __FILE__, __LINE__, rc);
                    135:                return (NULL);
                    136:        }
                    137:        rc = rf_cond_init(&reconCtrlPtr->eq_cond);
                    138:        if (rc) {
                    139:                /* XXX Deallocate, cleanup. */
                    140:                RF_ERRORMSG3("Unable to init cond file %s line %d rc=%d.\n",
                    141:                    __FILE__, __LINE__, rc);
                    142:                return (NULL);
                    143:        }
                    144:        reconCtrlPtr->eventQueue = NULL;
                    145:        reconCtrlPtr->eq_count = 0;
                    146:
                    147:        /* Make the floating recon buffers and append them to the free list. */
                    148:        rc = rf_mutex_init(&reconCtrlPtr->rb_mutex);
                    149:        if (rc) {
                    150:                /* XXX Deallocate, cleanup. */
                    151:                RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d.\n",
                    152:                    __FILE__, __LINE__, rc);
                    153:                return (NULL);
                    154:        }
                    155:        reconCtrlPtr->fullBufferList = NULL;
                    156:        reconCtrlPtr->priorityList = NULL;
                    157:        reconCtrlPtr->floatingRbufs = NULL;
                    158:        reconCtrlPtr->committedRbufs = NULL;
                    159:        for (i = 0; i < raidPtr->numFloatingReconBufs; i++) {
                    160:                rbuf = rf_MakeReconBuffer(raidPtr, frow, fcol,
                    161:                    RF_RBUF_TYPE_FLOATING);
                    162:                rbuf->next = reconCtrlPtr->floatingRbufs;
                    163:                reconCtrlPtr->floatingRbufs = rbuf;
                    164:        }
                    165:
                    166:        /* Create the parity stripe status table. */
                    167:        reconCtrlPtr->pssTable = rf_MakeParityStripeStatusTable(raidPtr);
                    168:
                    169:        /* Set the initial min head sep counter val. */
                    170:        reconCtrlPtr->minHeadSepCounter = 0;
                    171:
                    172:        return (reconCtrlPtr);
                    173: }
                    174:
                    175: void
                    176: rf_FreeReconControl(RF_Raid_t *raidPtr, RF_RowCol_t row)
                    177: {
                    178:        RF_ReconCtrl_t *reconCtrlPtr = raidPtr->reconControl[row];
                    179:        RF_ReconBuffer_t *t;
                    180:        RF_ReconUnitNum_t i;
                    181:
                    182:        RF_ASSERT(reconCtrlPtr);
                    183:        for (i = 0; i < raidPtr->numCol; i++)
                    184:                if (reconCtrlPtr->perDiskInfo[i].rbuf)
                    185:                        rf_FreeReconBuffer(reconCtrlPtr->perDiskInfo[i].rbuf);
                    186:        for (i = 0; i < raidPtr->numFloatingReconBufs; i++) {
                    187:                t = reconCtrlPtr->floatingRbufs;
                    188:                RF_ASSERT(t);
                    189:                reconCtrlPtr->floatingRbufs = t->next;
                    190:                rf_FreeReconBuffer(t);
                    191:        }
                    192:        rf_mutex_destroy(&reconCtrlPtr->rb_mutex);
                    193:        rf_mutex_destroy(&reconCtrlPtr->eq_mutex);
                    194:        rf_cond_destroy(&reconCtrlPtr->eq_cond);
                    195:        rf_FreeReconMap(reconCtrlPtr->reconMap);
                    196:        rf_FreeParityStripeStatusTable(raidPtr, reconCtrlPtr->pssTable);
                    197:        RF_Free(reconCtrlPtr->perDiskInfo, raidPtr->numCol *
                    198:            sizeof(RF_PerDiskReconCtrl_t));
                    199:        RF_Free(reconCtrlPtr, sizeof(*reconCtrlPtr));
                    200: }
                    201:
                    202:
                    203: /*****************************************************************************
                    204:  * Computes the default head separation limit.
                    205:  *****************************************************************************/
                    206: RF_HeadSepLimit_t
                    207: rf_GetDefaultHeadSepLimit(RF_Raid_t *raidPtr)
                    208: {
                    209:        RF_HeadSepLimit_t hsl;
                    210:        RF_LayoutSW_t *lp;
                    211:
                    212:        lp = raidPtr->Layout.map;
                    213:        if (lp->GetDefaultHeadSepLimit == NULL)
                    214:                return (-1);
                    215:        hsl = lp->GetDefaultHeadSepLimit(raidPtr);
                    216:        return (hsl);
                    217: }
                    218:
                    219:
                    220: /*****************************************************************************
                    221:  * Computes the default number of floating recon buffers.
                    222:  *****************************************************************************/
                    223: int
                    224: rf_GetDefaultNumFloatingReconBuffers(RF_Raid_t *raidPtr)
                    225: {
                    226:        RF_LayoutSW_t *lp;
                    227:        int nrb;
                    228:
                    229:        lp = raidPtr->Layout.map;
                    230:        if (lp->GetDefaultNumFloatingReconBuffers == NULL)
                    231:                return (3 * raidPtr->numCol);
                    232:        nrb = lp->GetDefaultNumFloatingReconBuffers(raidPtr);
                    233:        return (nrb);
                    234: }
                    235:
                    236:
                    237: /*****************************************************************************
                    238:  * Creates and initializes a reconstruction buffer.
                    239:  *****************************************************************************/
                    240: RF_ReconBuffer_t *
                    241: rf_MakeReconBuffer(RF_Raid_t *raidPtr, RF_RowCol_t row, RF_RowCol_t col,
                    242:     RF_RbufType_t type)
                    243: {
                    244:        RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;
                    245:        RF_ReconBuffer_t *t;
                    246:        u_int recon_buffer_size = rf_RaidAddressToByte(raidPtr,
                    247:            layoutPtr->SUsPerRU * layoutPtr->sectorsPerStripeUnit);
                    248:
                    249:        RF_Malloc(t, sizeof(RF_ReconBuffer_t), (RF_ReconBuffer_t *));
                    250:        RF_Malloc(t->buffer, recon_buffer_size, (caddr_t));
                    251:        RF_Malloc(t->arrived, raidPtr->numCol * sizeof(char), (char *));
                    252:        t->raidPtr = raidPtr;
                    253:        t->row = row;
                    254:        t->col = col;
                    255:        t->priority = RF_IO_RECON_PRIORITY;
                    256:        t->type = type;
                    257:        t->pssPtr = NULL;
                    258:        t->next = NULL;
                    259:        return (t);
                    260: }
                    261:
                    262:
                    263: /*****************************************************************************
                    264:  * Frees a reconstruction buffer.
                    265:  *****************************************************************************/
                    266: void
                    267: rf_FreeReconBuffer(RF_ReconBuffer_t *rbuf)
                    268: {
                    269:        RF_Raid_t *raidPtr = rbuf->raidPtr;
                    270:        u_int recon_buffer_size = rf_RaidAddressToByte(raidPtr,
                    271:            raidPtr->Layout.SUsPerRU * raidPtr->Layout.sectorsPerStripeUnit);
                    272:
                    273:        RF_Free(rbuf->arrived, raidPtr->numCol * sizeof(char));
                    274:        RF_Free(rbuf->buffer, recon_buffer_size);
                    275:        RF_Free(rbuf, sizeof(*rbuf));
                    276: }
                    277:
                    278:
                    279: /*****************************************************************************
                    280:  * Debug only:  Sanity check the number of floating recon bufs in use.
                    281:  *****************************************************************************/
                    282: void
                    283: rf_CheckFloatingRbufCount(RF_Raid_t *raidPtr, int dolock)
                    284: {
                    285:        RF_ReconParityStripeStatus_t *p;
                    286:        RF_PSStatusHeader_t *pssTable;
                    287:        RF_ReconBuffer_t *rbuf;
                    288:        int i, j, sum = 0;
                    289:        RF_RowCol_t frow = 0;
                    290:
                    291:        for (i = 0; i < raidPtr->numRow; i++)
                    292:                if (raidPtr->reconControl[i]) {
                    293:                        frow = i;
                    294:                        break;
                    295:                }
                    296:        RF_ASSERT(frow >= 0);
                    297:
                    298:        if (dolock)
                    299:                RF_LOCK_MUTEX(raidPtr->reconControl[frow]->rb_mutex);
                    300:        pssTable = raidPtr->reconControl[frow]->pssTable;
                    301:
                    302:        for (i = 0; i < raidPtr->pssTableSize; i++) {
                    303:                RF_LOCK_MUTEX(pssTable[i].mutex);
                    304:                for (p = pssTable[i].chain; p; p = p->next) {
                    305:                        rbuf = (RF_ReconBuffer_t *) p->rbuf;
                    306:                        if (rbuf && rbuf->type == RF_RBUF_TYPE_FLOATING)
                    307:                                sum++;
                    308:
                    309:                        rbuf = (RF_ReconBuffer_t *) p->writeRbuf;
                    310:                        if (rbuf && rbuf->type == RF_RBUF_TYPE_FLOATING)
                    311:                                sum++;
                    312:
                    313:                        for (j = 0; j < p->xorBufCount; j++) {
                    314:                                rbuf = (RF_ReconBuffer_t *) p->rbufsForXor[j];
                    315:                                RF_ASSERT(rbuf);
                    316:                                if (rbuf->type == RF_RBUF_TYPE_FLOATING)
                    317:                                        sum++;
                    318:                        }
                    319:                }
                    320:                RF_UNLOCK_MUTEX(pssTable[i].mutex);
                    321:        }
                    322:
                    323:        for (rbuf = raidPtr->reconControl[frow]->floatingRbufs; rbuf;
                    324:             rbuf = rbuf->next) {
                    325:                if (rbuf->type == RF_RBUF_TYPE_FLOATING)
                    326:                        sum++;
                    327:        }
                    328:        for (rbuf = raidPtr->reconControl[frow]->committedRbufs; rbuf;
                    329:             rbuf = rbuf->next) {
                    330:                if (rbuf->type == RF_RBUF_TYPE_FLOATING)
                    331:                        sum++;
                    332:        }
                    333:        for (rbuf = raidPtr->reconControl[frow]->fullBufferList; rbuf;
                    334:             rbuf = rbuf->next) {
                    335:                if (rbuf->type == RF_RBUF_TYPE_FLOATING)
                    336:                        sum++;
                    337:        }
                    338:        for (rbuf = raidPtr->reconControl[frow]->priorityList; rbuf;
                    339:             rbuf = rbuf->next) {
                    340:                if (rbuf->type == RF_RBUF_TYPE_FLOATING)
                    341:                        sum++;
                    342:        }
                    343:
                    344:        RF_ASSERT(sum == raidPtr->numFloatingReconBufs);
                    345:
                    346:        if (dolock)
                    347:                RF_UNLOCK_MUTEX(raidPtr->reconControl[frow]->rb_mutex);
                    348: }

CVSweb