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