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

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

1.1       nbrk        1: /*     $OpenBSD: rf_pqdeg.c,v 1.5 2002/12/16 07:01:04 tdeval Exp $     */
                      2: /*     $NetBSD: rf_pqdeg.c,v 1.5 2000/01/07 03:41:04 oster Exp $       */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Carnegie-Mellon University.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Author: Daniel Stodolsky
                      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: #include "rf_archs.h"
                     32:
                     33: #if    (RF_INCLUDE_DECL_PQ > 0) || (RF_INCLUDE_RAID6 > 0)
                     34:
                     35: #include "rf_types.h"
                     36: #include "rf_raid.h"
                     37: #include "rf_dag.h"
                     38: #include "rf_dagutils.h"
                     39: #include "rf_dagfuncs.h"
                     40: #include "rf_dagffrd.h"
                     41: #include "rf_dagffwr.h"
                     42: #include "rf_dagdegrd.h"
                     43: #include "rf_dagdegwr.h"
                     44: #include "rf_etimer.h"
                     45: #include "rf_pqdeg.h"
                     46: #include "rf_general.h"
                     47: #include "rf_pqdegdags.h"
                     48: #include "rf_pq.h"
                     49:
                     50: /*
                     51:  * Degraded mode dag functions for P+Q calculations.
                     52:  *
                     53:  * The following nomenclature is used.
                     54:  *
                     55:  *   PQ_<D><P><Q>_Create{Large,Small}<Write|Read>DAG
                     56:  *
                     57:  * where <D><P><Q> are single digits representing the number of failed
                     58:  * data units <D> (0,1,2), parity units <P> (0,1), and Q units <Q>, effecting
                     59:  * the I/O. The reads have only  PQ_<D><P><Q>_CreateReadDAG variants, while
                     60:  * the single fault writes have both large and small write versions.
                     61:  * Single fault PQ is equivalent to normal mode raid 5 in many aspects.
                     62:  *
                     63:  * Some versions degenerate into the same case, and are grouped together below.
                     64:  */
                     65:
                     66:
                     67: /* Reads, single failure. */
                     68:
                     69: /* We have parity, so we can do a raid 5 reconstruct read. */
                     70: RF_CREATE_DAG_FUNC_DECL(rf_PQ_100_CreateReadDAG)
                     71: {
                     72:        rf_CreateDegradedReadDAG(raidPtr, asmap, dag_h, bp, flags, allocList,
                     73:            &rf_pRecoveryFuncs);
                     74: }
                     75:
                     76:
                     77: /* Reads double failure. */
                     78:
                     79: /*
                     80:  * Q is lost, but not parity.
                     81:  * So we can a raid 5 reconstruct read.
                     82:  */
                     83: RF_CREATE_DAG_FUNC_DECL(rf_PQ_101_CreateReadDAG)
                     84: {
                     85:        rf_CreateDegradedReadDAG(raidPtr, asmap, dag_h, bp, flags, allocList,
                     86:            &rf_pRecoveryFuncs);
                     87: }
                     88:
                     89: /*
                     90:  * Parity is lost, so we need to
                     91:  * do a reconstruct read and recompute
                     92:  * the data with Q.
                     93:  */
                     94: RF_CREATE_DAG_FUNC_DECL(rf_PQ_110_CreateReadDAG)
                     95: {
                     96:        RF_PhysDiskAddr_t *temp;
                     97:        /* Swap P and Q pointers to fake out the DegradedReadDAG code. */
                     98:        temp = asmap->parityInfo;
                     99:        asmap->parityInfo = asmap->qInfo;
                    100:        asmap->qInfo = temp;
                    101:        rf_CreateDegradedReadDAG(raidPtr, asmap, dag_h, bp, flags, allocList,
                    102:            &rf_qRecoveryFuncs);
                    103: }
                    104:
                    105: /*
                    106:  * Two data units are dead in this stripe, so we will need read
                    107:  * both P and Q to reconstruct the data. Note that only
                    108:  * one data unit we are reading may actually be missing.
                    109:  */
                    110: RF_CREATE_DAG_FUNC_DECL(rf_CreateDoubleDegradedReadDAG);
                    111: RF_CREATE_DAG_FUNC_DECL(rf_CreateDoubleDegradedReadDAG)
                    112: {
                    113:        rf_PQ_DoubleDegRead(raidPtr, asmap, dag_h, bp, flags, allocList);
                    114: }
                    115:
                    116: RF_CREATE_DAG_FUNC_DECL(rf_PQ_200_CreateReadDAG);
                    117: RF_CREATE_DAG_FUNC_DECL(rf_PQ_200_CreateReadDAG)
                    118: {
                    119:        rf_CreateDoubleDegradedReadDAG(raidPtr, asmap, dag_h, bp, flags,
                    120:            allocList);
                    121: }
                    122:
                    123:
                    124: /* Writes, single failure. */
                    125:
                    126: RF_CREATE_DAG_FUNC_DECL(rf_PQ_100_CreateWriteDAG);
                    127: RF_CREATE_DAG_FUNC_DECL(rf_PQ_100_CreateWriteDAG)
                    128: {
                    129:        if (asmap->numStripeUnitsAccessed != 1 &&
                    130:            asmap->failedPDAs[0]->numSector !=
                    131:            raidPtr->Layout.sectorsPerStripeUnit)
                    132:                RF_PANIC();
                    133:        rf_CommonCreateSimpleDegradedWriteDAG(raidPtr, asmap, dag_h, bp,
                    134:            flags, allocList, 2, (int (*) (RF_DagNode_t *))
                    135:            rf_Degraded_100_PQFunc, RF_FALSE);
                    136: }
                    137:
                    138: /* Dead  P - act like a RAID 5 small write with parity = Q. */
                    139: RF_CREATE_DAG_FUNC_DECL(rf_PQ_010_CreateSmallWriteDAG)
                    140: {
                    141:        RF_PhysDiskAddr_t *temp;
                    142:        /* Swap P and Q pointers to fake out the DegradedReadDAG code. */
                    143:        temp = asmap->parityInfo;
                    144:        asmap->parityInfo = asmap->qInfo;
                    145:        asmap->qInfo = temp;
                    146:        rf_CommonCreateSmallWriteDAG(raidPtr, asmap, dag_h, bp, flags,
                    147:            allocList, &rf_qFuncs, NULL);
                    148: }
                    149:
                    150: /* Dead Q - act like a RAID 5 small write. */
                    151: RF_CREATE_DAG_FUNC_DECL(rf_PQ_001_CreateSmallWriteDAG)
                    152: {
                    153:        rf_CommonCreateSmallWriteDAG(raidPtr, asmap, dag_h, bp, flags,
                    154:            allocList, &rf_pFuncs, NULL);
                    155: }
                    156:
                    157: /* Dead P - act like a RAID 5 large write but for Q. */
                    158: RF_CREATE_DAG_FUNC_DECL(rf_PQ_010_CreateLargeWriteDAG)
                    159: {
                    160:        RF_PhysDiskAddr_t *temp;
                    161:        /* Swap P and Q pointers to fake out the code. */
                    162:        temp = asmap->parityInfo;
                    163:        asmap->parityInfo = asmap->qInfo;
                    164:        asmap->qInfo = temp;
                    165:        rf_CommonCreateLargeWriteDAG(raidPtr, asmap, dag_h, bp, flags,
                    166:            allocList, 1, rf_RegularQFunc, RF_FALSE);
                    167: }
                    168:
                    169: /* Dead Q - act like a RAID 5 large write. */
                    170: RF_CREATE_DAG_FUNC_DECL(rf_PQ_001_CreateLargeWriteDAG)
                    171: {
                    172:        rf_CommonCreateLargeWriteDAG(raidPtr, asmap, dag_h, bp, flags,
                    173:            allocList, 1, rf_RegularPFunc, RF_FALSE);
                    174: }
                    175:
                    176:
                    177: /* Writes, double failure. */
                    178:
                    179: /* Lost P & Q - do a nonredundant write. */
                    180: RF_CREATE_DAG_FUNC_DECL(rf_PQ_011_CreateWriteDAG)
                    181: {
                    182:        rf_CreateNonRedundantWriteDAG(raidPtr, asmap, dag_h, bp, flags,
                    183:            allocList, RF_IO_TYPE_WRITE);
                    184: }
                    185:
                    186:
                    187: /*
                    188:  * In the two cases below, a nasty case arises when it's a write for a
                    189:  * (strict) portion of a failed stripe unit and parts of another su.
                    190:  * For now, we do not support this.
                    191:  */
                    192:
                    193: /* Lost Data and  P - do a Q write. */
                    194: RF_CREATE_DAG_FUNC_DECL(rf_PQ_110_CreateWriteDAG)
                    195: {
                    196:        RF_PhysDiskAddr_t *temp;
                    197:
                    198:        if (asmap->numStripeUnitsAccessed != 1 &&
                    199:            asmap->failedPDAs[0]->numSector !=
                    200:            raidPtr->Layout.sectorsPerStripeUnit) {
                    201:                RF_PANIC();
                    202:        }
                    203:        /* Swap P and Q to fake out parity code. */
                    204:        temp = asmap->parityInfo;
                    205:        asmap->parityInfo = asmap->qInfo;
                    206:        asmap->qInfo = temp;
                    207:        rf_CommonCreateSimpleDegradedWriteDAG(raidPtr, asmap, dag_h, bp, flags,
                    208:            allocList, 1, (int (*) (RF_DagNode_t *))
                    209:            rf_PQ_DegradedWriteQFunc, RF_FALSE);
                    210:        /* Is the regular Q func the right one to call ? */
                    211: }
                    212:
                    213: /* Lost Data and Q - do degraded mode P write. */
                    214: RF_CREATE_DAG_FUNC_DECL(rf_PQ_101_CreateWriteDAG)
                    215: {
                    216:        if (asmap->numStripeUnitsAccessed != 1 &&
                    217:            asmap->failedPDAs[0]->numSector !=
                    218:            raidPtr->Layout.sectorsPerStripeUnit)
                    219:                RF_PANIC();
                    220:        rf_CommonCreateSimpleDegradedWriteDAG(raidPtr, asmap, dag_h, bp, flags,
                    221:            allocList, 1, rf_RecoveryXorFunc, RF_FALSE);
                    222: }
                    223:
                    224: #endif /* (RF_INCLUDE_DECL_PQ > 0) || (RF_INCLUDE_RAID6 > 0) */

CVSweb