rf_pqdeg.c revision 1.1
1/* $NetBSD: rf_pqdeg.c,v 1.1 1998/11/13 04:20:32 oster Exp $ */ 2/* 3 * Copyright (c) 1995 Carnegie-Mellon University. 4 * All rights reserved. 5 * 6 * Author: Daniel Stodolsky 7 * 8 * Permission to use, copy, modify and distribute this software and 9 * its documentation is hereby granted, provided that both the copyright 10 * notice and this permission notice appear in all copies of the 11 * software, derivative works or modified versions, and any portions 12 * thereof, and that both notices appear in supporting documentation. 13 * 14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 16 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 * 18 * Carnegie Mellon requests users of this software to return to 19 * 20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 21 * School of Computer Science 22 * Carnegie Mellon University 23 * Pittsburgh PA 15213-3890 24 * 25 * any improvements or extensions that they make and grant Carnegie the 26 * rights to redistribute these changes. 27 */ 28 29/* 30 * Log: rf_pqdeg.c,v 31 * Revision 1.19 1996/11/05 21:10:40 jimz 32 * failed pda generalization 33 * 34 * Revision 1.18 1996/07/31 16:30:01 jimz 35 * asm/asmap fix 36 * 37 * Revision 1.17 1996/07/31 15:35:09 jimz 38 * evenodd changes; bugfixes for double-degraded archs, generalize 39 * some formerly PQ-only functions 40 * 41 * Revision 1.16 1996/07/27 23:36:08 jimz 42 * Solaris port of simulator 43 * 44 * Revision 1.15 1996/07/22 19:52:16 jimz 45 * switched node params to RF_DagParam_t, a union of 46 * a 64-bit int and a void *, for better portability 47 * attempted hpux port, but failed partway through for 48 * lack of a single C compiler capable of compiling all 49 * source files 50 * 51 * Revision 1.14 1996/06/02 17:31:48 jimz 52 * Moved a lot of global stuff into array structure, where it belongs. 53 * Fixed up paritylogging, pss modules in this manner. Some general 54 * code cleanup. Removed lots of dead code, some dead files. 55 * 56 * Revision 1.13 1996/05/31 22:26:54 jimz 57 * fix a lot of mapping problems, memory allocation problems 58 * found some weird lock issues, fixed 'em 59 * more code cleanup 60 * 61 * Revision 1.12 1996/05/27 18:56:37 jimz 62 * more code cleanup 63 * better typing 64 * compiles in all 3 environments 65 * 66 * Revision 1.11 1996/05/24 22:17:04 jimz 67 * continue code + namespace cleanup 68 * typed a bunch of flags 69 * 70 * Revision 1.10 1996/05/24 04:28:55 jimz 71 * release cleanup ckpt 72 * 73 * Revision 1.9 1996/05/18 19:51:34 jimz 74 * major code cleanup- fix syntax, make some types consistent, 75 * add prototypes, clean out dead code, et cetera 76 * 77 * Revision 1.8 1996/05/03 19:41:07 wvcii 78 * added includes for dag library 79 * 80 * Revision 1.7 1995/11/30 16:19:36 wvcii 81 * added copyright info 82 * 83 * Revision 1.6 1995/11/07 16:15:08 wvcii 84 * updated/added prototyping for dag creation 85 * 86 * Revision 1.5 1995/03/01 20:25:48 holland 87 * kernelization changes 88 * 89 * Revision 1.4 1995/02/03 22:31:36 holland 90 * many changes related to kernelization 91 * 92 * Revision 1.3 1995/02/01 15:13:05 holland 93 * moved #include of general.h out of raid.h and into each file 94 * 95 * Revision 1.2 1994/12/05 04:50:26 danner 96 * additional pq support 97 * 98 * Revision 1.1 1994/11/29 20:36:02 danner 99 * Initial revision 100 * 101 */ 102 103#include "rf_archs.h" 104 105#if (RF_INCLUDE_DECL_PQ > 0) || (RF_INCLUDE_RAID6 > 0) 106 107#include "rf_types.h" 108#include "rf_raid.h" 109#include "rf_dag.h" 110#include "rf_dagutils.h" 111#include "rf_dagfuncs.h" 112#include "rf_dagffrd.h" 113#include "rf_dagffwr.h" 114#include "rf_dagdegrd.h" 115#include "rf_dagdegwr.h" 116#include "rf_threadid.h" 117#include "rf_etimer.h" 118#include "rf_pqdeg.h" 119#include "rf_general.h" 120#include "rf_pqdegdags.h" 121#include "rf_pq.h" 122 123/* 124 Degraded mode dag functions for P+Q calculations. 125 126 The following nomenclature is used. 127 128 PQ_<D><P><Q>_Create{Large,Small}<Write|Read>DAG 129 130 where <D><P><Q> are single digits representing the number of failed 131 data units <D> (0,1,2), parity units <P> (0,1), and Q units <Q>, effecting 132 the I/O. The reads have only PQ_<D><P><Q>_CreateReadDAG variants, while 133 the single fault writes have both large and small write versions. (Single fault 134 PQ is equivalent to normal mode raid 5 in many aspects. 135 136 Some versions degenerate into the same case, and are grouped together below. 137*/ 138 139/* Reads, single failure 140 141 we have parity, so we can do a raid 5 142 reconstruct read. 143*/ 144 145RF_CREATE_DAG_FUNC_DECL(rf_PQ_100_CreateReadDAG) 146{ 147 rf_CreateDegradedReadDAG(raidPtr, asmap, dag_h, bp, flags, allocList, &rf_pRecoveryFuncs); 148} 149 150/* Reads double failure */ 151 152/* 153 Q is lost, but not parity 154 so we can a raid 5 reconstruct read. 155*/ 156 157RF_CREATE_DAG_FUNC_DECL(rf_PQ_101_CreateReadDAG) 158{ 159 rf_CreateDegradedReadDAG(raidPtr, asmap, dag_h, bp, flags, allocList, &rf_pRecoveryFuncs); 160} 161 162/* 163 parity is lost, so we need to 164 do a reconstruct read and recompute 165 the data with Q. 166*/ 167 168RF_CREATE_DAG_FUNC_DECL(rf_PQ_110_CreateReadDAG) 169{ 170 RF_PhysDiskAddr_t *temp; 171 /* swap P and Q pointers to fake out the DegradedReadDAG code */ 172 temp = asmap->parityInfo; asmap->parityInfo = asmap->qInfo; asmap->qInfo = temp; 173 rf_CreateDegradedReadDAG(raidPtr, asmap, dag_h, bp, flags, allocList, &rf_qRecoveryFuncs); 174} 175 176/* 177 Two data units are dead in this stripe, so we will need read 178 both P and Q to reconstruct the data. Note that only 179 one data unit we are reading may actually be missing. 180*/ 181RF_CREATE_DAG_FUNC_DECL(rf_CreateDoubleDegradedReadDAG) 182{ 183 rf_PQ_DoubleDegRead(raidPtr, asmap, dag_h, bp, flags, allocList); 184} 185 186RF_CREATE_DAG_FUNC_DECL(rf_PQ_200_CreateReadDAG) 187{ 188 rf_CreateDoubleDegradedReadDAG(raidPtr, asmap, dag_h, bp, flags, allocList); 189} 190 191/* Writes, single failure */ 192 193RF_CREATE_DAG_FUNC_DECL(rf_PQ_100_CreateWriteDAG) 194{ 195 if (asmap->numStripeUnitsAccessed != 1 && 196 asmap->failedPDAs[0]->numSector != raidPtr->Layout.sectorsPerStripeUnit) 197 RF_PANIC(); 198 rf_CommonCreateSimpleDegradedWriteDAG(raidPtr, asmap, dag_h, bp, flags, 199 allocList, 2, (int (*)())rf_Degraded_100_PQFunc, RF_FALSE); 200} 201 202/* Dead P - act like a RAID 5 small write with parity = Q */ 203RF_CREATE_DAG_FUNC_DECL(rf_PQ_010_CreateSmallWriteDAG) 204{ 205 RF_PhysDiskAddr_t *temp; 206 /* swap P and Q pointers to fake out the DegradedReadDAG code */ 207 temp = asmap->parityInfo; asmap->parityInfo = asmap->qInfo; asmap->qInfo = temp; 208 rf_CommonCreateSmallWriteDAG(raidPtr, asmap, dag_h, bp, flags, allocList, &rf_qFuncs, NULL); 209} 210 211/* Dead Q - act like a RAID 5 small write */ 212RF_CREATE_DAG_FUNC_DECL(rf_PQ_001_CreateSmallWriteDAG) 213{ 214 rf_CommonCreateSmallWriteDAG(raidPtr, asmap, dag_h, bp, flags, allocList, &rf_pFuncs, NULL); 215} 216 217/* Dead P - act like a RAID 5 large write but for Q */ 218RF_CREATE_DAG_FUNC_DECL(rf_PQ_010_CreateLargeWriteDAG) 219{ 220 RF_PhysDiskAddr_t *temp; 221 /* swap P and Q pointers to fake out the code */ 222 temp = asmap->parityInfo; asmap->parityInfo = asmap->qInfo; asmap->qInfo = temp; 223 rf_CommonCreateLargeWriteDAG(raidPtr, asmap, dag_h, bp, flags, allocList, 1, rf_RegularQFunc, RF_FALSE); 224} 225 226/* Dead Q - act like a RAID 5 large write */ 227RF_CREATE_DAG_FUNC_DECL(rf_PQ_001_CreateLargeWriteDAG) 228{ 229 rf_CommonCreateLargeWriteDAG(raidPtr, asmap, dag_h, bp, flags, allocList, 1, rf_RegularPFunc, RF_FALSE); 230} 231 232 233/* 234 * writes, double failure 235 */ 236 237/* 238 * Lost P & Q - do a nonredundant write 239 */ 240RF_CREATE_DAG_FUNC_DECL(rf_PQ_011_CreateWriteDAG) 241{ 242 rf_CreateNonRedundantWriteDAG(raidPtr, asmap, dag_h, bp, flags, allocList, 243 RF_IO_TYPE_WRITE); 244} 245 246/* 247 In the two cases below, 248 A nasty case arises when the write a (strict) portion of a failed stripe unit 249 and parts of another su. For now, we do not support this. 250*/ 251 252/* 253 Lost Data and P - do a Q write. 254*/ 255RF_CREATE_DAG_FUNC_DECL(rf_PQ_110_CreateWriteDAG) 256{ 257 RF_PhysDiskAddr_t *temp; 258 259 if (asmap->numStripeUnitsAccessed != 1 && 260 asmap->failedPDAs[0]->numSector != raidPtr->Layout.sectorsPerStripeUnit) 261 { 262 RF_PANIC(); 263 } 264 /* swap P and Q to fake out parity code */ 265 temp = asmap->parityInfo; 266 asmap->parityInfo = asmap->qInfo; 267 asmap->qInfo = temp; 268 rf_CommonCreateSimpleDegradedWriteDAG(raidPtr, asmap, dag_h, bp, flags, 269 allocList,1, (int (*)())rf_PQ_DegradedWriteQFunc, RF_FALSE); 270 /* is the regular Q func the right one to call? */ 271} 272 273/* 274 Lost Data and Q - do degraded mode P write 275*/ 276RF_CREATE_DAG_FUNC_DECL(rf_PQ_101_CreateWriteDAG) 277{ 278 if (asmap->numStripeUnitsAccessed != 1 && 279 asmap->failedPDAs[0]->numSector != raidPtr->Layout.sectorsPerStripeUnit) 280 RF_PANIC(); 281 rf_CommonCreateSimpleDegradedWriteDAG(raidPtr, asmap, dag_h, bp, flags, 282 allocList,1, rf_RecoveryXorFunc, RF_FALSE); 283} 284 285#endif /* (RF_INCLUDE_DECL_PQ > 0) || (RF_INCLUDE_RAID6 > 0) */ 286