[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     ! 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