Annotation of sys/dev/raidframe/rf_pqdeg.c, Revision 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