author | Lin Ling <Lin.Ling@Sun.COM> |
Mon, 03 May 2010 14:54:08 -0700 | |
changeset 12296 | 7cf402a7f374 |
parent 11958 | 575ffe1e978d |
child 13570 | 3411fd5f1589 |
permissions | -rw-r--r-- |
789 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
1544 | 5 |
* Common Development and Distribution License (the "License"). |
6 |
* You may not use this file except in compliance with the License. |
|
789 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
2082 | 21 |
|
789 | 22 |
/* |
12296
7cf402a7f374
6675946 'zpool status' should show the progress of resilvering for individual disk.
Lin Ling <Lin.Ling@Sun.COM>
parents:
11958
diff
changeset
|
23 |
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
789 | 24 |
*/ |
25 |
||
26 |
#include <sys/zfs_context.h> |
|
27 |
#include <sys/spa.h> |
|
28 |
#include <sys/vdev_impl.h> |
|
29 |
#include <sys/zio.h> |
|
30 |
#include <sys/zio_checksum.h> |
|
31 |
#include <sys/fs/zfs.h> |
|
1544 | 32 |
#include <sys/fm/fs/zfs.h> |
789 | 33 |
|
34 |
/* |
|
35 |
* Virtual device vector for RAID-Z. |
|
2082 | 36 |
* |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
37 |
* This vdev supports single, double, and triple parity. For single parity, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
38 |
* we use a simple XOR of all the data columns. For double or triple parity, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
39 |
* we use a special case of Reed-Solomon coding. This extends the |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
40 |
* technique described in "The mathematics of RAID-6" by H. Peter Anvin by |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
41 |
* drawing on the system described in "A Tutorial on Reed-Solomon Coding for |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
42 |
* Fault-Tolerance in RAID-like Systems" by James S. Plank on which the |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
43 |
* former is also based. The latter is designed to provide higher performance |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
44 |
* for writes. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
45 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
46 |
* Note that the Plank paper claimed to support arbitrary N+M, but was then |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
47 |
* amended six years later identifying a critical flaw that invalidates its |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
48 |
* claims. Nevertheless, the technique can be adapted to work for up to |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
49 |
* triple parity. For additional parity, the amendment "Note: Correction to |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
50 |
* the 1997 Tutorial on Reed-Solomon Coding" by James S. Plank and Ying Ding |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
51 |
* is viable, but the additional complexity means that write performance will |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
52 |
* suffer. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
53 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
54 |
* All of the methods above operate on a Galois field, defined over the |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
55 |
* integers mod 2^N. In our case we choose N=8 for GF(8) so that all elements |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
56 |
* can be expressed with a single byte. Briefly, the operations on the |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
57 |
* field are defined as follows: |
2082 | 58 |
* |
59 |
* o addition (+) is represented by a bitwise XOR |
|
60 |
* o subtraction (-) is therefore identical to addition: A + B = A - B |
|
61 |
* o multiplication of A by 2 is defined by the following bitwise expression: |
|
62 |
* (A * 2)_7 = A_6 |
|
63 |
* (A * 2)_6 = A_5 |
|
64 |
* (A * 2)_5 = A_4 |
|
65 |
* (A * 2)_4 = A_3 + A_7 |
|
66 |
* (A * 2)_3 = A_2 + A_7 |
|
67 |
* (A * 2)_2 = A_1 + A_7 |
|
68 |
* (A * 2)_1 = A_0 |
|
69 |
* (A * 2)_0 = A_7 |
|
70 |
* |
|
71 |
* In C, multiplying by 2 is therefore ((a << 1) ^ ((a & 0x80) ? 0x1d : 0)). |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
72 |
* As an aside, this multiplication is derived from the error correcting |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
73 |
* primitive polynomial x^8 + x^4 + x^3 + x^2 + 1. |
2082 | 74 |
* |
75 |
* Observe that any number in the field (except for 0) can be expressed as a |
|
76 |
* power of 2 -- a generator for the field. We store a table of the powers of |
|
77 |
* 2 and logs base 2 for quick look ups, and exploit the fact that A * B can |
|
78 |
* be rewritten as 2^(log_2(A) + log_2(B)) (where '+' is normal addition rather |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
79 |
* than field addition). The inverse of a field element A (A^-1) is therefore |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
80 |
* A ^ (255 - 1) = A^254. |
2082 | 81 |
* |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
82 |
* The up-to-three parity columns, P, Q, R over several data columns, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
83 |
* D_0, ... D_n-1, can be expressed by field operations: |
2082 | 84 |
* |
85 |
* P = D_0 + D_1 + ... + D_n-2 + D_n-1 |
|
86 |
* Q = 2^n-1 * D_0 + 2^n-2 * D_1 + ... + 2^1 * D_n-2 + 2^0 * D_n-1 |
|
87 |
* = ((...((D_0) * 2 + D_1) * 2 + ...) * 2 + D_n-2) * 2 + D_n-1 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
88 |
* R = 4^n-1 * D_0 + 4^n-2 * D_1 + ... + 4^1 * D_n-2 + 4^0 * D_n-1 |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
89 |
* = ((...((D_0) * 4 + D_1) * 4 + ...) * 4 + D_n-2) * 4 + D_n-1 |
2082 | 90 |
* |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
91 |
* We chose 1, 2, and 4 as our generators because 1 corresponds to the trival |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
92 |
* XOR operation, and 2 and 4 can be computed quickly and generate linearly- |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
93 |
* independent coefficients. (There are no additional coefficients that have |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
94 |
* this property which is why the uncorrected Plank method breaks down.) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
95 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
96 |
* See the reconstruction code below for how P, Q and R can used individually |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
97 |
* or in concert to recover missing data columns. |
789 | 98 |
*/ |
99 |
||
100 |
typedef struct raidz_col { |
|
2082 | 101 |
uint64_t rc_devidx; /* child device index for I/O */ |
102 |
uint64_t rc_offset; /* device offset */ |
|
103 |
uint64_t rc_size; /* I/O size */ |
|
104 |
void *rc_data; /* I/O data */ |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
105 |
void *rc_gdata; /* used to store the "good" version */ |
2082 | 106 |
int rc_error; /* I/O error for this device */ |
107 |
uint8_t rc_tried; /* Did we attempt this I/O column? */ |
|
108 |
uint8_t rc_skipped; /* Did we skip this I/O column? */ |
|
789 | 109 |
} raidz_col_t; |
110 |
||
111 |
typedef struct raidz_map { |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
112 |
uint64_t rm_cols; /* Regular column count */ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
113 |
uint64_t rm_scols; /* Count including skipped columns */ |
2082 | 114 |
uint64_t rm_bigcols; /* Number of oversized columns */ |
115 |
uint64_t rm_asize; /* Actual total I/O size */ |
|
116 |
uint64_t rm_missingdata; /* Count of missing data devices */ |
|
117 |
uint64_t rm_missingparity; /* Count of missing parity devices */ |
|
118 |
uint64_t rm_firstdatacol; /* First data column/parity count */ |
|
10450
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
119 |
uint64_t rm_nskip; /* Skipped sectors for padding */ |
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
120 |
uint64_t rm_skipstart; /* Column index of padding start */ |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
121 |
void *rm_datacopy; /* rm_asize-buffer of copied data */ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
122 |
uintptr_t rm_reports; /* # of referencing checksum reports */ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
123 |
uint8_t rm_freed; /* map no longer has referencing ZIO */ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
124 |
uint8_t rm_ecksuminjected; /* checksum error was injected */ |
2082 | 125 |
raidz_col_t rm_col[1]; /* Flexible array of I/O columns */ |
789 | 126 |
} raidz_map_t; |
127 |
||
2082 | 128 |
#define VDEV_RAIDZ_P 0 |
129 |
#define VDEV_RAIDZ_Q 1 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
130 |
#define VDEV_RAIDZ_R 2 |
2082 | 131 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
132 |
#define VDEV_RAIDZ_MUL_2(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1d : 0)) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
133 |
#define VDEV_RAIDZ_MUL_4(x) (VDEV_RAIDZ_MUL_2(VDEV_RAIDZ_MUL_2(x))) |
2082 | 134 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
135 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
136 |
* We provide a mechanism to perform the field multiplication operation on a |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
137 |
* 64-bit value all at once rather than a byte at a time. This works by |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
138 |
* creating a mask from the top bit in each byte and using that to |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
139 |
* conditionally apply the XOR of 0x1d. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
140 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
141 |
#define VDEV_RAIDZ_64MUL_2(x, mask) \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
142 |
{ \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
143 |
(mask) = (x) & 0x8080808080808080ULL; \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
144 |
(mask) = ((mask) << 1) - ((mask) >> 7); \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
145 |
(x) = (((x) << 1) & 0xfefefefefefefefeULL) ^ \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
146 |
((mask) & 0x1d1d1d1d1d1d1d1d); \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
147 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
148 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
149 |
#define VDEV_RAIDZ_64MUL_4(x, mask) \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
150 |
{ \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
151 |
VDEV_RAIDZ_64MUL_2((x), mask); \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
152 |
VDEV_RAIDZ_64MUL_2((x), mask); \ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
153 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
154 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
155 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
156 |
* Force reconstruction to use the general purpose method. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
157 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
158 |
int vdev_raidz_default_to_general; |
2082 | 159 |
|
160 |
/* |
|
161 |
* These two tables represent powers and logs of 2 in the Galois field defined |
|
162 |
* above. These values were computed by repeatedly multiplying by 2 as above. |
|
163 |
*/ |
|
164 |
static const uint8_t vdev_raidz_pow2[256] = { |
|
165 |
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, |
|
166 |
0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, |
|
167 |
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, |
|
168 |
0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, |
|
169 |
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, |
|
170 |
0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, |
|
171 |
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, |
|
172 |
0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, |
|
173 |
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, |
|
174 |
0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, |
|
175 |
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, |
|
176 |
0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, |
|
177 |
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, |
|
178 |
0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, |
|
179 |
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, |
|
180 |
0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, |
|
181 |
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, |
|
182 |
0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54, |
|
183 |
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, |
|
184 |
0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, |
|
185 |
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, |
|
186 |
0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, |
|
187 |
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, |
|
188 |
0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, |
|
189 |
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, |
|
190 |
0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, |
|
191 |
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, |
|
192 |
0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09, |
|
193 |
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, |
|
194 |
0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16, |
|
195 |
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, |
|
196 |
0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01 |
|
197 |
}; |
|
198 |
static const uint8_t vdev_raidz_log2[256] = { |
|
199 |
0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, |
|
200 |
0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b, |
|
201 |
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, |
|
202 |
0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71, |
|
203 |
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, |
|
204 |
0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45, |
|
205 |
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, |
|
206 |
0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6, |
|
207 |
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, |
|
208 |
0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88, |
|
209 |
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, |
|
210 |
0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40, |
|
211 |
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, |
|
212 |
0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d, |
|
213 |
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, |
|
214 |
0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57, |
|
215 |
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, |
|
216 |
0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18, |
|
217 |
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, |
|
218 |
0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e, |
|
219 |
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, |
|
220 |
0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61, |
|
221 |
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, |
|
222 |
0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2, |
|
223 |
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, |
|
224 |
0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6, |
|
225 |
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, |
|
226 |
0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a, |
|
227 |
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, |
|
228 |
0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7, |
|
229 |
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, |
|
230 |
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf, |
|
231 |
}; |
|
232 |
||
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
233 |
static void vdev_raidz_generate_parity(raidz_map_t *rm); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
234 |
|
2082 | 235 |
/* |
236 |
* Multiply a given number by 2 raised to the given power. |
|
237 |
*/ |
|
238 |
static uint8_t |
|
239 |
vdev_raidz_exp2(uint_t a, int exp) |
|
240 |
{ |
|
241 |
if (a == 0) |
|
242 |
return (0); |
|
243 |
||
244 |
ASSERT(exp >= 0); |
|
245 |
ASSERT(vdev_raidz_log2[a] > 0 || a == 1); |
|
246 |
||
247 |
exp += vdev_raidz_log2[a]; |
|
248 |
if (exp > 255) |
|
249 |
exp -= 255; |
|
250 |
||
251 |
return (vdev_raidz_pow2[exp]); |
|
252 |
} |
|
253 |
||
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
254 |
static void |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
255 |
vdev_raidz_map_free(raidz_map_t *rm) |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
256 |
{ |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
257 |
int c; |
10653
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
258 |
size_t size; |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
259 |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
260 |
for (c = 0; c < rm->rm_firstdatacol; c++) { |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
261 |
zio_buf_free(rm->rm_col[c].rc_data, rm->rm_col[c].rc_size); |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
262 |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
263 |
if (rm->rm_col[c].rc_gdata != NULL) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
264 |
zio_buf_free(rm->rm_col[c].rc_gdata, |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
265 |
rm->rm_col[c].rc_size); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
266 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
267 |
|
10653
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
268 |
size = 0; |
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
269 |
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) |
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
270 |
size += rm->rm_col[c].rc_size; |
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
271 |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
272 |
if (rm->rm_datacopy != NULL) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
273 |
zio_buf_free(rm->rm_datacopy, size); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
274 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
275 |
kmem_free(rm, offsetof(raidz_map_t, rm_col[rm->rm_scols])); |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
276 |
} |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
277 |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
278 |
static void |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
279 |
vdev_raidz_map_free_vsd(zio_t *zio) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
280 |
{ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
281 |
raidz_map_t *rm = zio->io_vsd; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
282 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
283 |
ASSERT3U(rm->rm_freed, ==, 0); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
284 |
rm->rm_freed = 1; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
285 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
286 |
if (rm->rm_reports == 0) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
287 |
vdev_raidz_map_free(rm); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
288 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
289 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
290 |
/*ARGSUSED*/ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
291 |
static void |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
292 |
vdev_raidz_cksum_free(void *arg, size_t ignored) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
293 |
{ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
294 |
raidz_map_t *rm = arg; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
295 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
296 |
ASSERT3U(rm->rm_reports, >, 0); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
297 |
|
10653
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
298 |
if (--rm->rm_reports == 0 && rm->rm_freed != 0) |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
299 |
vdev_raidz_map_free(rm); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
300 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
301 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
302 |
static void |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
303 |
vdev_raidz_cksum_finish(zio_cksum_report_t *zcr, const void *good_data) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
304 |
{ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
305 |
raidz_map_t *rm = zcr->zcr_cbdata; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
306 |
size_t c = zcr->zcr_cbinfo; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
307 |
size_t x; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
308 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
309 |
const char *good = NULL; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
310 |
const char *bad = rm->rm_col[c].rc_data; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
311 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
312 |
if (good_data == NULL) { |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
313 |
zfs_ereport_finish_checksum(zcr, NULL, NULL, B_FALSE); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
314 |
return; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
315 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
316 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
317 |
if (c < rm->rm_firstdatacol) { |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
318 |
/* |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
319 |
* The first time through, calculate the parity blocks for |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
320 |
* the good data (this relies on the fact that the good |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
321 |
* data never changes for a given logical ZIO) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
322 |
*/ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
323 |
if (rm->rm_col[0].rc_gdata == NULL) { |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
324 |
char *bad_parity[VDEV_RAIDZ_MAXPARITY]; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
325 |
char *buf; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
326 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
327 |
/* |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
328 |
* Set up the rm_col[]s to generate the parity for |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
329 |
* good_data, first saving the parity bufs and |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
330 |
* replacing them with buffers to hold the result. |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
331 |
*/ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
332 |
for (x = 0; x < rm->rm_firstdatacol; x++) { |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
333 |
bad_parity[x] = rm->rm_col[x].rc_data; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
334 |
rm->rm_col[x].rc_data = rm->rm_col[x].rc_gdata = |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
335 |
zio_buf_alloc(rm->rm_col[x].rc_size); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
336 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
337 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
338 |
/* fill in the data columns from good_data */ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
339 |
buf = (char *)good_data; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
340 |
for (; x < rm->rm_cols; x++) { |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
341 |
rm->rm_col[x].rc_data = buf; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
342 |
buf += rm->rm_col[x].rc_size; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
343 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
344 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
345 |
/* |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
346 |
* Construct the parity from the good data. |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
347 |
*/ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
348 |
vdev_raidz_generate_parity(rm); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
349 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
350 |
/* restore everything back to its original state */ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
351 |
for (x = 0; x < rm->rm_firstdatacol; x++) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
352 |
rm->rm_col[x].rc_data = bad_parity[x]; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
353 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
354 |
buf = rm->rm_datacopy; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
355 |
for (x = rm->rm_firstdatacol; x < rm->rm_cols; x++) { |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
356 |
rm->rm_col[x].rc_data = buf; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
357 |
buf += rm->rm_col[x].rc_size; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
358 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
359 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
360 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
361 |
ASSERT3P(rm->rm_col[c].rc_gdata, !=, NULL); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
362 |
good = rm->rm_col[c].rc_gdata; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
363 |
} else { |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
364 |
/* adjust good_data to point at the start of our column */ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
365 |
good = good_data; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
366 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
367 |
for (x = rm->rm_firstdatacol; x < c; x++) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
368 |
good += rm->rm_col[x].rc_size; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
369 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
370 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
371 |
/* we drop the ereport if it ends up that the data was good */ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
372 |
zfs_ereport_finish_checksum(zcr, good, bad, B_TRUE); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
373 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
374 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
375 |
/* |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
376 |
* Invoked indirectly by zfs_ereport_start_checksum(), called |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
377 |
* below when our read operation fails completely. The main point |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
378 |
* is to keep a copy of everything we read from disk, so that at |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
379 |
* vdev_raidz_cksum_finish() time we can compare it with the good data. |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
380 |
*/ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
381 |
static void |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
382 |
vdev_raidz_cksum_report(zio_t *zio, zio_cksum_report_t *zcr, void *arg) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
383 |
{ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
384 |
size_t c = (size_t)(uintptr_t)arg; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
385 |
caddr_t buf; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
386 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
387 |
raidz_map_t *rm = zio->io_vsd; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
388 |
size_t size; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
389 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
390 |
/* set up the report and bump the refcount */ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
391 |
zcr->zcr_cbdata = rm; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
392 |
zcr->zcr_cbinfo = c; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
393 |
zcr->zcr_finish = vdev_raidz_cksum_finish; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
394 |
zcr->zcr_free = vdev_raidz_cksum_free; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
395 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
396 |
rm->rm_reports++; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
397 |
ASSERT3U(rm->rm_reports, >, 0); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
398 |
|
10653
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
399 |
if (rm->rm_datacopy != NULL) |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
400 |
return; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
401 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
402 |
/* |
10653
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
403 |
* It's the first time we're called for this raidz_map_t, so we need |
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
404 |
* to copy the data aside; there's no guarantee that our zio's buffer |
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
405 |
* won't be re-used for something else. |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
406 |
* |
10653
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
407 |
* Our parity data is already in separate buffers, so there's no need |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
408 |
* to copy them. |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
409 |
*/ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
410 |
|
10653
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
411 |
size = 0; |
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
412 |
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) |
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
413 |
size += rm->rm_col[c].rc_size; |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
414 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
415 |
buf = rm->rm_datacopy = zio_buf_alloc(size); |
10653
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
416 |
|
e0ceed15cf0a
6885320 assertion failed: rm->rm_freed != 0 (0x0 != 0x0), file: ../../common/fs/zfs/vdev_raidz.c, line: 298
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10614
diff
changeset
|
417 |
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
418 |
raidz_col_t *col = &rm->rm_col[c]; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
419 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
420 |
bcopy(col->rc_data, buf, col->rc_size); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
421 |
col->rc_data = buf; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
422 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
423 |
buf += col->rc_size; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
424 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
425 |
ASSERT3P(buf - (caddr_t)rm->rm_datacopy, ==, size); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
426 |
} |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
427 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
428 |
static const zio_vsd_ops_t vdev_raidz_vsd_ops = { |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
429 |
vdev_raidz_map_free_vsd, |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
430 |
vdev_raidz_cksum_report |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
431 |
}; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
432 |
|
789 | 433 |
static raidz_map_t * |
2082 | 434 |
vdev_raidz_map_alloc(zio_t *zio, uint64_t unit_shift, uint64_t dcols, |
435 |
uint64_t nparity) |
|
789 | 436 |
{ |
437 |
raidz_map_t *rm; |
|
438 |
uint64_t b = zio->io_offset >> unit_shift; |
|
439 |
uint64_t s = zio->io_size >> unit_shift; |
|
440 |
uint64_t f = b % dcols; |
|
441 |
uint64_t o = (b / dcols) << unit_shift; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
442 |
uint64_t q, r, c, bc, col, acols, scols, coff, devidx, asize, tot; |
789 | 443 |
|
2082 | 444 |
q = s / (dcols - nparity); |
445 |
r = s - q * (dcols - nparity); |
|
446 |
bc = (r == 0 ? 0 : r + nparity); |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
447 |
tot = s + nparity * (q + (r == 0 ? 0 : 1)); |
789 | 448 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
449 |
if (q == 0) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
450 |
acols = bc; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
451 |
scols = MIN(dcols, roundup(bc, nparity + 1)); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
452 |
} else { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
453 |
acols = dcols; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
454 |
scols = dcols; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
455 |
} |
789 | 456 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
457 |
ASSERT3U(acols, <=, scols); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
458 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
459 |
rm = kmem_alloc(offsetof(raidz_map_t, rm_col[scols]), KM_SLEEP); |
789 | 460 |
|
461 |
rm->rm_cols = acols; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
462 |
rm->rm_scols = scols; |
789 | 463 |
rm->rm_bigcols = bc; |
10450
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
464 |
rm->rm_skipstart = bc; |
2082 | 465 |
rm->rm_missingdata = 0; |
466 |
rm->rm_missingparity = 0; |
|
467 |
rm->rm_firstdatacol = nparity; |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
468 |
rm->rm_datacopy = NULL; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
469 |
rm->rm_reports = 0; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
470 |
rm->rm_freed = 0; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
471 |
rm->rm_ecksuminjected = 0; |
789 | 472 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
473 |
asize = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
474 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
475 |
for (c = 0; c < scols; c++) { |
789 | 476 |
col = f + c; |
477 |
coff = o; |
|
478 |
if (col >= dcols) { |
|
479 |
col -= dcols; |
|
480 |
coff += 1ULL << unit_shift; |
|
481 |
} |
|
2082 | 482 |
rm->rm_col[c].rc_devidx = col; |
789 | 483 |
rm->rm_col[c].rc_offset = coff; |
484 |
rm->rm_col[c].rc_data = NULL; |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
485 |
rm->rm_col[c].rc_gdata = NULL; |
789 | 486 |
rm->rm_col[c].rc_error = 0; |
487 |
rm->rm_col[c].rc_tried = 0; |
|
488 |
rm->rm_col[c].rc_skipped = 0; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
489 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
490 |
if (c >= acols) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
491 |
rm->rm_col[c].rc_size = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
492 |
else if (c < bc) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
493 |
rm->rm_col[c].rc_size = (q + 1) << unit_shift; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
494 |
else |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
495 |
rm->rm_col[c].rc_size = q << unit_shift; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
496 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
497 |
asize += rm->rm_col[c].rc_size; |
789 | 498 |
} |
499 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
500 |
ASSERT3U(asize, ==, tot << unit_shift); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
501 |
rm->rm_asize = roundup(asize, (nparity + 1) << unit_shift); |
10450
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
502 |
rm->rm_nskip = roundup(tot, nparity + 1) - tot; |
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
503 |
ASSERT3U(rm->rm_asize - asize, ==, rm->rm_nskip << unit_shift); |
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
504 |
ASSERT3U(rm->rm_nskip, <=, nparity); |
789 | 505 |
|
506 |
for (c = 0; c < rm->rm_firstdatacol; c++) |
|
507 |
rm->rm_col[c].rc_data = zio_buf_alloc(rm->rm_col[c].rc_size); |
|
508 |
||
509 |
rm->rm_col[c].rc_data = zio->io_data; |
|
510 |
||
511 |
for (c = c + 1; c < acols; c++) |
|
512 |
rm->rm_col[c].rc_data = (char *)rm->rm_col[c - 1].rc_data + |
|
513 |
rm->rm_col[c - 1].rc_size; |
|
514 |
||
1133
335d069294d1
6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents:
789
diff
changeset
|
515 |
/* |
2082 | 516 |
* If all data stored spans all columns, there's a danger that parity |
517 |
* will always be on the same device and, since parity isn't read |
|
518 |
* during normal operation, that that device's I/O bandwidth won't be |
|
519 |
* used effectively. We therefore switch the parity every 1MB. |
|
520 |
* |
|
521 |
* ... at least that was, ostensibly, the theory. As a practical |
|
522 |
* matter unless we juggle the parity between all devices evenly, we |
|
523 |
* won't see any benefit. Further, occasional writes that aren't a |
|
524 |
* multiple of the LCM of the number of children and the minimum |
|
525 |
* stripe width are sufficient to avoid pessimal behavior. |
|
526 |
* Unfortunately, this decision created an implicit on-disk format |
|
3456 | 527 |
* requirement that we need to support for all eternity, but only |
528 |
* for single-parity RAID-Z. |
|
10450
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
529 |
* |
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
530 |
* If we intend to skip a sector in the zeroth column for padding |
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
531 |
* we must make sure to note this swap. We will never intend to |
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
532 |
* skip the first column since at least one data and one parity |
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
533 |
* column must appear in each row. |
1133
335d069294d1
6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents:
789
diff
changeset
|
534 |
*/ |
335d069294d1
6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents:
789
diff
changeset
|
535 |
ASSERT(rm->rm_cols >= 2); |
335d069294d1
6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents:
789
diff
changeset
|
536 |
ASSERT(rm->rm_col[0].rc_size == rm->rm_col[1].rc_size); |
789 | 537 |
|
2082 | 538 |
if (rm->rm_firstdatacol == 1 && (zio->io_offset & (1ULL << 20))) { |
539 |
devidx = rm->rm_col[0].rc_devidx; |
|
1133
335d069294d1
6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents:
789
diff
changeset
|
540 |
o = rm->rm_col[0].rc_offset; |
2082 | 541 |
rm->rm_col[0].rc_devidx = rm->rm_col[1].rc_devidx; |
1133
335d069294d1
6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents:
789
diff
changeset
|
542 |
rm->rm_col[0].rc_offset = rm->rm_col[1].rc_offset; |
2082 | 543 |
rm->rm_col[1].rc_devidx = devidx; |
1133
335d069294d1
6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents:
789
diff
changeset
|
544 |
rm->rm_col[1].rc_offset = o; |
10450
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
545 |
|
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
546 |
if (rm->rm_skipstart == 0) |
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
547 |
rm->rm_skipstart = 1; |
789 | 548 |
} |
549 |
||
550 |
zio->io_vsd = rm; |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
551 |
zio->io_vsd_ops = &vdev_raidz_vsd_ops; |
789 | 552 |
return (rm); |
553 |
} |
|
554 |
||
555 |
static void |
|
2082 | 556 |
vdev_raidz_generate_parity_p(raidz_map_t *rm) |
557 |
{ |
|
558 |
uint64_t *p, *src, pcount, ccount, i; |
|
559 |
int c; |
|
560 |
||
561 |
pcount = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]); |
|
562 |
||
563 |
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { |
|
564 |
src = rm->rm_col[c].rc_data; |
|
565 |
p = rm->rm_col[VDEV_RAIDZ_P].rc_data; |
|
566 |
ccount = rm->rm_col[c].rc_size / sizeof (src[0]); |
|
567 |
||
568 |
if (c == rm->rm_firstdatacol) { |
|
569 |
ASSERT(ccount == pcount); |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
570 |
for (i = 0; i < ccount; i++, src++, p++) { |
2082 | 571 |
*p = *src; |
572 |
} |
|
573 |
} else { |
|
574 |
ASSERT(ccount <= pcount); |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
575 |
for (i = 0; i < ccount; i++, src++, p++) { |
2082 | 576 |
*p ^= *src; |
577 |
} |
|
578 |
} |
|
579 |
} |
|
580 |
} |
|
581 |
||
582 |
static void |
|
583 |
vdev_raidz_generate_parity_pq(raidz_map_t *rm) |
|
789 | 584 |
{ |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
585 |
uint64_t *p, *q, *src, pcnt, ccnt, mask, i; |
2082 | 586 |
int c; |
587 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
588 |
pcnt = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]); |
2082 | 589 |
ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size == |
590 |
rm->rm_col[VDEV_RAIDZ_Q].rc_size); |
|
591 |
||
592 |
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { |
|
593 |
src = rm->rm_col[c].rc_data; |
|
594 |
p = rm->rm_col[VDEV_RAIDZ_P].rc_data; |
|
595 |
q = rm->rm_col[VDEV_RAIDZ_Q].rc_data; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
596 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
597 |
ccnt = rm->rm_col[c].rc_size / sizeof (src[0]); |
2082 | 598 |
|
599 |
if (c == rm->rm_firstdatacol) { |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
600 |
ASSERT(ccnt == pcnt || ccnt == 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
601 |
for (i = 0; i < ccnt; i++, src++, p++, q++) { |
2082 | 602 |
*p = *src; |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
603 |
*q = *src; |
2082 | 604 |
} |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
605 |
for (; i < pcnt; i++, src++, p++, q++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
606 |
*p = 0; |
2082 | 607 |
*q = 0; |
608 |
} |
|
609 |
} else { |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
610 |
ASSERT(ccnt <= pcnt); |
789 | 611 |
|
2082 | 612 |
/* |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
613 |
* Apply the algorithm described above by multiplying |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
614 |
* the previous result and adding in the new value. |
2082 | 615 |
*/ |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
616 |
for (i = 0; i < ccnt; i++, src++, p++, q++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
617 |
*p ^= *src; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
618 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
619 |
VDEV_RAIDZ_64MUL_2(*q, mask); |
2082 | 620 |
*q ^= *src; |
621 |
} |
|
622 |
||
623 |
/* |
|
624 |
* Treat short columns as though they are full of 0s. |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
625 |
* Note that there's therefore nothing needed for P. |
2082 | 626 |
*/ |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
627 |
for (; i < pcnt; i++, q++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
628 |
VDEV_RAIDZ_64MUL_2(*q, mask); |
2082 | 629 |
} |
630 |
} |
|
631 |
} |
|
632 |
} |
|
633 |
||
634 |
static void |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
635 |
vdev_raidz_generate_parity_pqr(raidz_map_t *rm) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
636 |
{ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
637 |
uint64_t *p, *q, *r, *src, pcnt, ccnt, mask, i; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
638 |
int c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
639 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
640 |
pcnt = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
641 |
ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size == |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
642 |
rm->rm_col[VDEV_RAIDZ_Q].rc_size); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
643 |
ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size == |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
644 |
rm->rm_col[VDEV_RAIDZ_R].rc_size); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
645 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
646 |
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
647 |
src = rm->rm_col[c].rc_data; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
648 |
p = rm->rm_col[VDEV_RAIDZ_P].rc_data; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
649 |
q = rm->rm_col[VDEV_RAIDZ_Q].rc_data; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
650 |
r = rm->rm_col[VDEV_RAIDZ_R].rc_data; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
651 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
652 |
ccnt = rm->rm_col[c].rc_size / sizeof (src[0]); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
653 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
654 |
if (c == rm->rm_firstdatacol) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
655 |
ASSERT(ccnt == pcnt || ccnt == 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
656 |
for (i = 0; i < ccnt; i++, src++, p++, q++, r++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
657 |
*p = *src; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
658 |
*q = *src; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
659 |
*r = *src; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
660 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
661 |
for (; i < pcnt; i++, src++, p++, q++, r++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
662 |
*p = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
663 |
*q = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
664 |
*r = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
665 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
666 |
} else { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
667 |
ASSERT(ccnt <= pcnt); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
668 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
669 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
670 |
* Apply the algorithm described above by multiplying |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
671 |
* the previous result and adding in the new value. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
672 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
673 |
for (i = 0; i < ccnt; i++, src++, p++, q++, r++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
674 |
*p ^= *src; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
675 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
676 |
VDEV_RAIDZ_64MUL_2(*q, mask); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
677 |
*q ^= *src; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
678 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
679 |
VDEV_RAIDZ_64MUL_4(*r, mask); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
680 |
*r ^= *src; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
681 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
682 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
683 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
684 |
* Treat short columns as though they are full of 0s. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
685 |
* Note that there's therefore nothing needed for P. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
686 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
687 |
for (; i < pcnt; i++, q++, r++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
688 |
VDEV_RAIDZ_64MUL_2(*q, mask); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
689 |
VDEV_RAIDZ_64MUL_4(*r, mask); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
690 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
691 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
692 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
693 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
694 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
695 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
696 |
* Generate RAID parity in the first virtual columns according to the number of |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
697 |
* parity columns available. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
698 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
699 |
static void |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
700 |
vdev_raidz_generate_parity(raidz_map_t *rm) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
701 |
{ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
702 |
switch (rm->rm_firstdatacol) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
703 |
case 1: |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
704 |
vdev_raidz_generate_parity_p(rm); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
705 |
break; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
706 |
case 2: |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
707 |
vdev_raidz_generate_parity_pq(rm); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
708 |
break; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
709 |
case 3: |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
710 |
vdev_raidz_generate_parity_pqr(rm); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
711 |
break; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
712 |
default: |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
713 |
cmn_err(CE_PANIC, "invalid RAID-Z configuration"); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
714 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
715 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
716 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
717 |
static int |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
718 |
vdev_raidz_reconstruct_p(raidz_map_t *rm, int *tgts, int ntgts) |
2082 | 719 |
{ |
720 |
uint64_t *dst, *src, xcount, ccount, count, i; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
721 |
int x = tgts[0]; |
2082 | 722 |
int c; |
723 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
724 |
ASSERT(ntgts == 1); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
725 |
ASSERT(x >= rm->rm_firstdatacol); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
726 |
ASSERT(x < rm->rm_cols); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
727 |
|
2082 | 728 |
xcount = rm->rm_col[x].rc_size / sizeof (src[0]); |
729 |
ASSERT(xcount <= rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0])); |
|
730 |
ASSERT(xcount > 0); |
|
731 |
||
732 |
src = rm->rm_col[VDEV_RAIDZ_P].rc_data; |
|
733 |
dst = rm->rm_col[x].rc_data; |
|
734 |
for (i = 0; i < xcount; i++, dst++, src++) { |
|
735 |
*dst = *src; |
|
736 |
} |
|
737 |
||
738 |
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { |
|
789 | 739 |
src = rm->rm_col[c].rc_data; |
740 |
dst = rm->rm_col[x].rc_data; |
|
2082 | 741 |
|
742 |
if (c == x) |
|
743 |
continue; |
|
744 |
||
745 |
ccount = rm->rm_col[c].rc_size / sizeof (src[0]); |
|
746 |
count = MIN(ccount, xcount); |
|
747 |
||
748 |
for (i = 0; i < count; i++, dst++, src++) { |
|
749 |
*dst ^= *src; |
|
789 | 750 |
} |
751 |
} |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
752 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
753 |
return (1 << VDEV_RAIDZ_P); |
789 | 754 |
} |
755 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
756 |
static int |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
757 |
vdev_raidz_reconstruct_q(raidz_map_t *rm, int *tgts, int ntgts) |
2082 | 758 |
{ |
759 |
uint64_t *dst, *src, xcount, ccount, count, mask, i; |
|
760 |
uint8_t *b; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
761 |
int x = tgts[0]; |
2082 | 762 |
int c, j, exp; |
763 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
764 |
ASSERT(ntgts == 1); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
765 |
|
2082 | 766 |
xcount = rm->rm_col[x].rc_size / sizeof (src[0]); |
767 |
ASSERT(xcount <= rm->rm_col[VDEV_RAIDZ_Q].rc_size / sizeof (src[0])); |
|
768 |
||
769 |
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { |
|
770 |
src = rm->rm_col[c].rc_data; |
|
771 |
dst = rm->rm_col[x].rc_data; |
|
772 |
||
773 |
if (c == x) |
|
774 |
ccount = 0; |
|
775 |
else |
|
776 |
ccount = rm->rm_col[c].rc_size / sizeof (src[0]); |
|
777 |
||
778 |
count = MIN(ccount, xcount); |
|
779 |
||
780 |
if (c == rm->rm_firstdatacol) { |
|
781 |
for (i = 0; i < count; i++, dst++, src++) { |
|
782 |
*dst = *src; |
|
783 |
} |
|
784 |
for (; i < xcount; i++, dst++) { |
|
785 |
*dst = 0; |
|
786 |
} |
|
787 |
||
788 |
} else { |
|
789 |
for (i = 0; i < count; i++, dst++, src++) { |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
790 |
VDEV_RAIDZ_64MUL_2(*dst, mask); |
2082 | 791 |
*dst ^= *src; |
792 |
} |
|
793 |
||
794 |
for (; i < xcount; i++, dst++) { |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
795 |
VDEV_RAIDZ_64MUL_2(*dst, mask); |
2082 | 796 |
} |
797 |
} |
|
798 |
} |
|
799 |
||
800 |
src = rm->rm_col[VDEV_RAIDZ_Q].rc_data; |
|
801 |
dst = rm->rm_col[x].rc_data; |
|
802 |
exp = 255 - (rm->rm_cols - 1 - x); |
|
803 |
||
804 |
for (i = 0; i < xcount; i++, dst++, src++) { |
|
805 |
*dst ^= *src; |
|
806 |
for (j = 0, b = (uint8_t *)dst; j < 8; j++, b++) { |
|
807 |
*b = vdev_raidz_exp2(*b, exp); |
|
808 |
} |
|
809 |
} |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
810 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
811 |
return (1 << VDEV_RAIDZ_Q); |
2082 | 812 |
} |
813 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
814 |
static int |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
815 |
vdev_raidz_reconstruct_pq(raidz_map_t *rm, int *tgts, int ntgts) |
2082 | 816 |
{ |
817 |
uint8_t *p, *q, *pxy, *qxy, *xd, *yd, tmp, a, b, aexp, bexp; |
|
818 |
void *pdata, *qdata; |
|
819 |
uint64_t xsize, ysize, i; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
820 |
int x = tgts[0]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
821 |
int y = tgts[1]; |
2082 | 822 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
823 |
ASSERT(ntgts == 2); |
2082 | 824 |
ASSERT(x < y); |
825 |
ASSERT(x >= rm->rm_firstdatacol); |
|
826 |
ASSERT(y < rm->rm_cols); |
|
827 |
||
828 |
ASSERT(rm->rm_col[x].rc_size >= rm->rm_col[y].rc_size); |
|
829 |
||
830 |
/* |
|
831 |
* Move the parity data aside -- we're going to compute parity as |
|
832 |
* though columns x and y were full of zeros -- Pxy and Qxy. We want to |
|
833 |
* reuse the parity generation mechanism without trashing the actual |
|
834 |
* parity so we make those columns appear to be full of zeros by |
|
835 |
* setting their lengths to zero. |
|
836 |
*/ |
|
837 |
pdata = rm->rm_col[VDEV_RAIDZ_P].rc_data; |
|
838 |
qdata = rm->rm_col[VDEV_RAIDZ_Q].rc_data; |
|
839 |
xsize = rm->rm_col[x].rc_size; |
|
840 |
ysize = rm->rm_col[y].rc_size; |
|
841 |
||
842 |
rm->rm_col[VDEV_RAIDZ_P].rc_data = |
|
843 |
zio_buf_alloc(rm->rm_col[VDEV_RAIDZ_P].rc_size); |
|
844 |
rm->rm_col[VDEV_RAIDZ_Q].rc_data = |
|
845 |
zio_buf_alloc(rm->rm_col[VDEV_RAIDZ_Q].rc_size); |
|
846 |
rm->rm_col[x].rc_size = 0; |
|
847 |
rm->rm_col[y].rc_size = 0; |
|
848 |
||
849 |
vdev_raidz_generate_parity_pq(rm); |
|
850 |
||
851 |
rm->rm_col[x].rc_size = xsize; |
|
852 |
rm->rm_col[y].rc_size = ysize; |
|
853 |
||
854 |
p = pdata; |
|
855 |
q = qdata; |
|
856 |
pxy = rm->rm_col[VDEV_RAIDZ_P].rc_data; |
|
857 |
qxy = rm->rm_col[VDEV_RAIDZ_Q].rc_data; |
|
858 |
xd = rm->rm_col[x].rc_data; |
|
859 |
yd = rm->rm_col[y].rc_data; |
|
860 |
||
861 |
/* |
|
862 |
* We now have: |
|
863 |
* Pxy = P + D_x + D_y |
|
864 |
* Qxy = Q + 2^(ndevs - 1 - x) * D_x + 2^(ndevs - 1 - y) * D_y |
|
865 |
* |
|
866 |
* We can then solve for D_x: |
|
867 |
* D_x = A * (P + Pxy) + B * (Q + Qxy) |
|
868 |
* where |
|
869 |
* A = 2^(x - y) * (2^(x - y) + 1)^-1 |
|
870 |
* B = 2^(ndevs - 1 - x) * (2^(x - y) + 1)^-1 |
|
871 |
* |
|
872 |
* With D_x in hand, we can easily solve for D_y: |
|
873 |
* D_y = P + Pxy + D_x |
|
874 |
*/ |
|
875 |
||
876 |
a = vdev_raidz_pow2[255 + x - y]; |
|
877 |
b = vdev_raidz_pow2[255 - (rm->rm_cols - 1 - x)]; |
|
878 |
tmp = 255 - vdev_raidz_log2[a ^ 1]; |
|
879 |
||
880 |
aexp = vdev_raidz_log2[vdev_raidz_exp2(a, tmp)]; |
|
881 |
bexp = vdev_raidz_log2[vdev_raidz_exp2(b, tmp)]; |
|
882 |
||
883 |
for (i = 0; i < xsize; i++, p++, q++, pxy++, qxy++, xd++, yd++) { |
|
884 |
*xd = vdev_raidz_exp2(*p ^ *pxy, aexp) ^ |
|
885 |
vdev_raidz_exp2(*q ^ *qxy, bexp); |
|
886 |
||
887 |
if (i < ysize) |
|
888 |
*yd = *p ^ *pxy ^ *xd; |
|
889 |
} |
|
890 |
||
891 |
zio_buf_free(rm->rm_col[VDEV_RAIDZ_P].rc_data, |
|
892 |
rm->rm_col[VDEV_RAIDZ_P].rc_size); |
|
893 |
zio_buf_free(rm->rm_col[VDEV_RAIDZ_Q].rc_data, |
|
894 |
rm->rm_col[VDEV_RAIDZ_Q].rc_size); |
|
895 |
||
896 |
/* |
|
897 |
* Restore the saved parity data. |
|
898 |
*/ |
|
899 |
rm->rm_col[VDEV_RAIDZ_P].rc_data = pdata; |
|
900 |
rm->rm_col[VDEV_RAIDZ_Q].rc_data = qdata; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
901 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
902 |
return ((1 << VDEV_RAIDZ_P) | (1 << VDEV_RAIDZ_Q)); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
903 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
904 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
905 |
/* BEGIN CSTYLED */ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
906 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
907 |
* In the general case of reconstruction, we must solve the system of linear |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
908 |
* equations defined by the coeffecients used to generate parity as well as |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
909 |
* the contents of the data and parity disks. This can be expressed with |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
910 |
* vectors for the original data (D) and the actual data (d) and parity (p) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
911 |
* and a matrix composed of the identity matrix (I) and a dispersal matrix (V): |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
912 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
913 |
* __ __ __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
914 |
* | | __ __ | p_0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
915 |
* | V | | D_0 | | p_m-1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
916 |
* | | x | : | = | d_0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
917 |
* | I | | D_n-1 | | : | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
918 |
* | | ~~ ~~ | d_n-1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
919 |
* ~~ ~~ ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
920 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
921 |
* I is simply a square identity matrix of size n, and V is a vandermonde |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
922 |
* matrix defined by the coeffecients we chose for the various parity columns |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
923 |
* (1, 2, 4). Note that these values were chosen both for simplicity, speedy |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
924 |
* computation as well as linear separability. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
925 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
926 |
* __ __ __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
927 |
* | 1 .. 1 1 1 | | p_0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
928 |
* | 2^n-1 .. 4 2 1 | __ __ | : | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
929 |
* | 4^n-1 .. 16 4 1 | | D_0 | | p_m-1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
930 |
* | 1 .. 0 0 0 | | D_1 | | d_0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
931 |
* | 0 .. 0 0 0 | x | D_2 | = | d_1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
932 |
* | : : : : | | : | | d_2 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
933 |
* | 0 .. 1 0 0 | | D_n-1 | | : | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
934 |
* | 0 .. 0 1 0 | ~~ ~~ | : | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
935 |
* | 0 .. 0 0 1 | | d_n-1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
936 |
* ~~ ~~ ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
937 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
938 |
* Note that I, V, d, and p are known. To compute D, we must invert the |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
939 |
* matrix and use the known data and parity values to reconstruct the unknown |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
940 |
* data values. We begin by removing the rows in V|I and d|p that correspond |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
941 |
* to failed or missing columns; we then make V|I square (n x n) and d|p |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
942 |
* sized n by removing rows corresponding to unused parity from the bottom up |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
943 |
* to generate (V|I)' and (d|p)'. We can then generate the inverse of (V|I)' |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
944 |
* using Gauss-Jordan elimination. In the example below we use m=3 parity |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
945 |
* columns, n=8 data columns, with errors in d_1, d_2, and p_1: |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
946 |
* __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
947 |
* | 1 1 1 1 1 1 1 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
948 |
* | 128 64 32 16 8 4 2 1 | <-----+-+-- missing disks |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
949 |
* | 19 205 116 29 64 16 4 1 | / / |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
950 |
* | 1 0 0 0 0 0 0 0 | / / |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
951 |
* | 0 1 0 0 0 0 0 0 | <--' / |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
952 |
* (V|I) = | 0 0 1 0 0 0 0 0 | <---' |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
953 |
* | 0 0 0 1 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
954 |
* | 0 0 0 0 1 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
955 |
* | 0 0 0 0 0 1 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
956 |
* | 0 0 0 0 0 0 1 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
957 |
* | 0 0 0 0 0 0 0 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
958 |
* ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
959 |
* __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
960 |
* | 1 1 1 1 1 1 1 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
961 |
* | 128 64 32 16 8 4 2 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
962 |
* | 19 205 116 29 64 16 4 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
963 |
* | 1 0 0 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
964 |
* | 0 1 0 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
965 |
* (V|I)' = | 0 0 1 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
966 |
* | 0 0 0 1 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
967 |
* | 0 0 0 0 1 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
968 |
* | 0 0 0 0 0 1 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
969 |
* | 0 0 0 0 0 0 1 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
970 |
* | 0 0 0 0 0 0 0 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
971 |
* ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
972 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
973 |
* Here we employ Gauss-Jordan elimination to find the inverse of (V|I)'. We |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
974 |
* have carefully chosen the seed values 1, 2, and 4 to ensure that this |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
975 |
* matrix is not singular. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
976 |
* __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
977 |
* | 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
978 |
* | 19 205 116 29 64 16 4 1 0 1 0 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
979 |
* | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
980 |
* | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
981 |
* | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
982 |
* | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
983 |
* | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
984 |
* | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
985 |
* ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
986 |
* __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
987 |
* | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
988 |
* | 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
989 |
* | 19 205 116 29 64 16 4 1 0 1 0 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
990 |
* | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
991 |
* | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
992 |
* | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
993 |
* | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
994 |
* | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
995 |
* ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
996 |
* __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
997 |
* | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
998 |
* | 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
999 |
* | 0 205 116 0 0 0 0 0 0 1 19 29 64 16 4 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1000 |
* | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1001 |
* | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1002 |
* | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1003 |
* | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1004 |
* | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1005 |
* ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1006 |
* __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1007 |
* | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1008 |
* | 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1009 |
* | 0 0 185 0 0 0 0 0 205 1 222 208 141 221 201 204 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1010 |
* | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1011 |
* | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1012 |
* | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1013 |
* | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1014 |
* | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1015 |
* ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1016 |
* __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1017 |
* | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1018 |
* | 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1019 |
* | 0 0 1 0 0 0 0 0 166 100 4 40 158 168 216 209 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1020 |
* | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1021 |
* | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1022 |
* | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1023 |
* | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1024 |
* | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1025 |
* ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1026 |
* __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1027 |
* | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1028 |
* | 0 1 0 0 0 0 0 0 167 100 5 41 159 169 217 208 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1029 |
* | 0 0 1 0 0 0 0 0 166 100 4 40 158 168 216 209 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1030 |
* | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1031 |
* | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1032 |
* | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1033 |
* | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1034 |
* | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1035 |
* ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1036 |
* __ __ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1037 |
* | 0 0 1 0 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1038 |
* | 167 100 5 41 159 169 217 208 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1039 |
* | 166 100 4 40 158 168 216 209 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1040 |
* (V|I)'^-1 = | 0 0 0 1 0 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1041 |
* | 0 0 0 0 1 0 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1042 |
* | 0 0 0 0 0 1 0 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1043 |
* | 0 0 0 0 0 0 1 0 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1044 |
* | 0 0 0 0 0 0 0 1 | |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1045 |
* ~~ ~~ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1046 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1047 |
* We can then simply compute D = (V|I)'^-1 x (d|p)' to discover the values |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1048 |
* of the missing data. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1049 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1050 |
* As is apparent from the example above, the only non-trivial rows in the |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1051 |
* inverse matrix correspond to the data disks that we're trying to |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1052 |
* reconstruct. Indeed, those are the only rows we need as the others would |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1053 |
* only be useful for reconstructing data known or assumed to be valid. For |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1054 |
* that reason, we only build the coefficients in the rows that correspond to |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1055 |
* targeted columns. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1056 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1057 |
/* END CSTYLED */ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1058 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1059 |
static void |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1060 |
vdev_raidz_matrix_init(raidz_map_t *rm, int n, int nmap, int *map, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1061 |
uint8_t **rows) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1062 |
{ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1063 |
int i, j; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1064 |
int pow; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1065 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1066 |
ASSERT(n == rm->rm_cols - rm->rm_firstdatacol); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1067 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1068 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1069 |
* Fill in the missing rows of interest. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1070 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1071 |
for (i = 0; i < nmap; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1072 |
ASSERT3S(0, <=, map[i]); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1073 |
ASSERT3S(map[i], <=, 2); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1074 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1075 |
pow = map[i] * n; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1076 |
if (pow > 255) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1077 |
pow -= 255; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1078 |
ASSERT(pow <= 255); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1079 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1080 |
for (j = 0; j < n; j++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1081 |
pow -= map[i]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1082 |
if (pow < 0) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1083 |
pow += 255; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1084 |
rows[i][j] = vdev_raidz_pow2[pow]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1085 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1086 |
} |
2082 | 1087 |
} |
1088 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1089 |
static void |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1090 |
vdev_raidz_matrix_invert(raidz_map_t *rm, int n, int nmissing, int *missing, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1091 |
uint8_t **rows, uint8_t **invrows, const uint8_t *used) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1092 |
{ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1093 |
int i, j, ii, jj; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1094 |
uint8_t log; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1095 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1096 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1097 |
* Assert that the first nmissing entries from the array of used |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1098 |
* columns correspond to parity columns and that subsequent entries |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1099 |
* correspond to data columns. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1100 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1101 |
for (i = 0; i < nmissing; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1102 |
ASSERT3S(used[i], <, rm->rm_firstdatacol); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1103 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1104 |
for (; i < n; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1105 |
ASSERT3S(used[i], >=, rm->rm_firstdatacol); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1106 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1107 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1108 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1109 |
* First initialize the storage where we'll compute the inverse rows. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1110 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1111 |
for (i = 0; i < nmissing; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1112 |
for (j = 0; j < n; j++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1113 |
invrows[i][j] = (i == j) ? 1 : 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1114 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1115 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1116 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1117 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1118 |
* Subtract all trivial rows from the rows of consequence. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1119 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1120 |
for (i = 0; i < nmissing; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1121 |
for (j = nmissing; j < n; j++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1122 |
ASSERT3U(used[j], >=, rm->rm_firstdatacol); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1123 |
jj = used[j] - rm->rm_firstdatacol; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1124 |
ASSERT3S(jj, <, n); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1125 |
invrows[i][j] = rows[i][jj]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1126 |
rows[i][jj] = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1127 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1128 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1129 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1130 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1131 |
* For each of the rows of interest, we must normalize it and subtract |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1132 |
* a multiple of it from the other rows. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1133 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1134 |
for (i = 0; i < nmissing; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1135 |
for (j = 0; j < missing[i]; j++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1136 |
ASSERT3U(rows[i][j], ==, 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1137 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1138 |
ASSERT3U(rows[i][missing[i]], !=, 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1139 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1140 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1141 |
* Compute the inverse of the first element and multiply each |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1142 |
* element in the row by that value. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1143 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1144 |
log = 255 - vdev_raidz_log2[rows[i][missing[i]]]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1145 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1146 |
for (j = 0; j < n; j++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1147 |
rows[i][j] = vdev_raidz_exp2(rows[i][j], log); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1148 |
invrows[i][j] = vdev_raidz_exp2(invrows[i][j], log); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1149 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1150 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1151 |
for (ii = 0; ii < nmissing; ii++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1152 |
if (i == ii) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1153 |
continue; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1154 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1155 |
ASSERT3U(rows[ii][missing[i]], !=, 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1156 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1157 |
log = vdev_raidz_log2[rows[ii][missing[i]]]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1158 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1159 |
for (j = 0; j < n; j++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1160 |
rows[ii][j] ^= |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1161 |
vdev_raidz_exp2(rows[i][j], log); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1162 |
invrows[ii][j] ^= |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1163 |
vdev_raidz_exp2(invrows[i][j], log); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1164 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1165 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1166 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1167 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1168 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1169 |
* Verify that the data that is left in the rows are properly part of |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1170 |
* an identity matrix. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1171 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1172 |
for (i = 0; i < nmissing; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1173 |
for (j = 0; j < n; j++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1174 |
if (j == missing[i]) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1175 |
ASSERT3U(rows[i][j], ==, 1); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1176 |
} else { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1177 |
ASSERT3U(rows[i][j], ==, 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1178 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1179 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1180 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1181 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1182 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1183 |
static void |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1184 |
vdev_raidz_matrix_reconstruct(raidz_map_t *rm, int n, int nmissing, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1185 |
int *missing, uint8_t **invrows, const uint8_t *used) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1186 |
{ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1187 |
int i, j, x, cc, c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1188 |
uint8_t *src; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1189 |
uint64_t ccount; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1190 |
uint8_t *dst[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1191 |
uint64_t dcount[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1192 |
uint8_t log, val; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1193 |
int ll; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1194 |
uint8_t *invlog[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1195 |
uint8_t *p, *pp; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1196 |
size_t psize; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1197 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1198 |
psize = sizeof (invlog[0][0]) * n * nmissing; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1199 |
p = kmem_alloc(psize, KM_SLEEP); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1200 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1201 |
for (pp = p, i = 0; i < nmissing; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1202 |
invlog[i] = pp; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1203 |
pp += n; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1204 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1205 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1206 |
for (i = 0; i < nmissing; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1207 |
for (j = 0; j < n; j++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1208 |
ASSERT3U(invrows[i][j], !=, 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1209 |
invlog[i][j] = vdev_raidz_log2[invrows[i][j]]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1210 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1211 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1212 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1213 |
for (i = 0; i < n; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1214 |
c = used[i]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1215 |
ASSERT3U(c, <, rm->rm_cols); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1216 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1217 |
src = rm->rm_col[c].rc_data; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1218 |
ccount = rm->rm_col[c].rc_size; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1219 |
for (j = 0; j < nmissing; j++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1220 |
cc = missing[j] + rm->rm_firstdatacol; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1221 |
ASSERT3U(cc, >=, rm->rm_firstdatacol); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1222 |
ASSERT3U(cc, <, rm->rm_cols); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1223 |
ASSERT3U(cc, !=, c); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1224 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1225 |
dst[j] = rm->rm_col[cc].rc_data; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1226 |
dcount[j] = rm->rm_col[cc].rc_size; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1227 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1228 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1229 |
ASSERT(ccount >= rm->rm_col[missing[0]].rc_size || i > 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1230 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1231 |
for (x = 0; x < ccount; x++, src++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1232 |
if (*src != 0) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1233 |
log = vdev_raidz_log2[*src]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1234 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1235 |
for (cc = 0; cc < nmissing; cc++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1236 |
if (x >= dcount[cc]) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1237 |
continue; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1238 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1239 |
if (*src == 0) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1240 |
val = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1241 |
} else { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1242 |
if ((ll = log + invlog[cc][i]) >= 255) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1243 |
ll -= 255; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1244 |
val = vdev_raidz_pow2[ll]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1245 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1246 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1247 |
if (i == 0) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1248 |
dst[cc][x] = val; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1249 |
else |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1250 |
dst[cc][x] ^= val; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1251 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1252 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1253 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1254 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1255 |
kmem_free(p, psize); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1256 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1257 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1258 |
static int |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1259 |
vdev_raidz_reconstruct_general(raidz_map_t *rm, int *tgts, int ntgts) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1260 |
{ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1261 |
int n, i, c, t, tt; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1262 |
int nmissing_rows; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1263 |
int missing_rows[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1264 |
int parity_map[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1265 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1266 |
uint8_t *p, *pp; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1267 |
size_t psize; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1268 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1269 |
uint8_t *rows[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1270 |
uint8_t *invrows[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1271 |
uint8_t *used; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1272 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1273 |
int code = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1274 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1275 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1276 |
n = rm->rm_cols - rm->rm_firstdatacol; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1277 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1278 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1279 |
* Figure out which data columns are missing. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1280 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1281 |
nmissing_rows = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1282 |
for (t = 0; t < ntgts; t++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1283 |
if (tgts[t] >= rm->rm_firstdatacol) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1284 |
missing_rows[nmissing_rows++] = |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1285 |
tgts[t] - rm->rm_firstdatacol; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1286 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1287 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1288 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1289 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1290 |
* Figure out which parity columns to use to help generate the missing |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1291 |
* data columns. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1292 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1293 |
for (tt = 0, c = 0, i = 0; i < nmissing_rows; c++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1294 |
ASSERT(tt < ntgts); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1295 |
ASSERT(c < rm->rm_firstdatacol); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1296 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1297 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1298 |
* Skip any targeted parity columns. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1299 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1300 |
if (c == tgts[tt]) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1301 |
tt++; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1302 |
continue; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1303 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1304 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1305 |
code |= 1 << c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1306 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1307 |
parity_map[i] = c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1308 |
i++; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1309 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1310 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1311 |
ASSERT(code != 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1312 |
ASSERT3U(code, <, 1 << VDEV_RAIDZ_MAXPARITY); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1313 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1314 |
psize = (sizeof (rows[0][0]) + sizeof (invrows[0][0])) * |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1315 |
nmissing_rows * n + sizeof (used[0]) * n; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1316 |
p = kmem_alloc(psize, KM_SLEEP); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1317 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1318 |
for (pp = p, i = 0; i < nmissing_rows; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1319 |
rows[i] = pp; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1320 |
pp += n; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1321 |
invrows[i] = pp; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1322 |
pp += n; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1323 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1324 |
used = pp; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1325 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1326 |
for (i = 0; i < nmissing_rows; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1327 |
used[i] = parity_map[i]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1328 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1329 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1330 |
for (tt = 0, c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1331 |
if (tt < nmissing_rows && |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1332 |
c == missing_rows[tt] + rm->rm_firstdatacol) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1333 |
tt++; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1334 |
continue; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1335 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1336 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1337 |
ASSERT3S(i, <, n); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1338 |
used[i] = c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1339 |
i++; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1340 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1341 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1342 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1343 |
* Initialize the interesting rows of the matrix. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1344 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1345 |
vdev_raidz_matrix_init(rm, n, nmissing_rows, parity_map, rows); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1346 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1347 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1348 |
* Invert the matrix. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1349 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1350 |
vdev_raidz_matrix_invert(rm, n, nmissing_rows, missing_rows, rows, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1351 |
invrows, used); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1352 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1353 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1354 |
* Reconstruct the missing data using the generated matrix. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1355 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1356 |
vdev_raidz_matrix_reconstruct(rm, n, nmissing_rows, missing_rows, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1357 |
invrows, used); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1358 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1359 |
kmem_free(p, psize); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1360 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1361 |
return (code); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1362 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1363 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1364 |
static int |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1365 |
vdev_raidz_reconstruct(raidz_map_t *rm, int *t, int nt) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1366 |
{ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1367 |
int tgts[VDEV_RAIDZ_MAXPARITY], *dt; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1368 |
int ntgts; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1369 |
int i, c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1370 |
int code; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1371 |
int nbadparity, nbaddata; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1372 |
int parity_valid[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1373 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1374 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1375 |
* The tgts list must already be sorted. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1376 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1377 |
for (i = 1; i < nt; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1378 |
ASSERT(t[i] > t[i - 1]); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1379 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1380 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1381 |
nbadparity = rm->rm_firstdatacol; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1382 |
nbaddata = rm->rm_cols - nbadparity; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1383 |
ntgts = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1384 |
for (i = 0, c = 0; c < rm->rm_cols; c++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1385 |
if (c < rm->rm_firstdatacol) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1386 |
parity_valid[c] = B_FALSE; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1387 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1388 |
if (i < nt && c == t[i]) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1389 |
tgts[ntgts++] = c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1390 |
i++; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1391 |
} else if (rm->rm_col[c].rc_error != 0) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1392 |
tgts[ntgts++] = c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1393 |
} else if (c >= rm->rm_firstdatacol) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1394 |
nbaddata--; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1395 |
} else { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1396 |
parity_valid[c] = B_TRUE; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1397 |
nbadparity--; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1398 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1399 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1400 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1401 |
ASSERT(ntgts >= nt); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1402 |
ASSERT(nbaddata >= 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1403 |
ASSERT(nbaddata + nbadparity == ntgts); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1404 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1405 |
dt = &tgts[nbadparity]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1406 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1407 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1408 |
* See if we can use any of our optimized reconstruction routines. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1409 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1410 |
if (!vdev_raidz_default_to_general) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1411 |
switch (nbaddata) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1412 |
case 1: |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1413 |
if (parity_valid[VDEV_RAIDZ_P]) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1414 |
return (vdev_raidz_reconstruct_p(rm, dt, 1)); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1415 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1416 |
ASSERT(rm->rm_firstdatacol > 1); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1417 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1418 |
if (parity_valid[VDEV_RAIDZ_Q]) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1419 |
return (vdev_raidz_reconstruct_q(rm, dt, 1)); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1420 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1421 |
ASSERT(rm->rm_firstdatacol > 2); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1422 |
break; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1423 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1424 |
case 2: |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1425 |
ASSERT(rm->rm_firstdatacol > 1); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1426 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1427 |
if (parity_valid[VDEV_RAIDZ_P] && |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1428 |
parity_valid[VDEV_RAIDZ_Q]) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1429 |
return (vdev_raidz_reconstruct_pq(rm, dt, 2)); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1430 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1431 |
ASSERT(rm->rm_firstdatacol > 2); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1432 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1433 |
break; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1434 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1435 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1436 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1437 |
code = vdev_raidz_reconstruct_general(rm, tgts, ntgts); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1438 |
ASSERT(code < (1 << VDEV_RAIDZ_MAXPARITY)); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1439 |
ASSERT(code > 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1440 |
return (code); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1441 |
} |
2082 | 1442 |
|
789 | 1443 |
static int |
1444 |
vdev_raidz_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift) |
|
1445 |
{ |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1446 |
vdev_t *cvd; |
2082 | 1447 |
uint64_t nparity = vd->vdev_nparity; |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1448 |
int c; |
789 | 1449 |
int lasterror = 0; |
1450 |
int numerrors = 0; |
|
1451 |
||
2082 | 1452 |
ASSERT(nparity > 0); |
1453 |
||
1454 |
if (nparity > VDEV_RAIDZ_MAXPARITY || |
|
1455 |
vd->vdev_children < nparity + 1) { |
|
789 | 1456 |
vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; |
1457 |
return (EINVAL); |
|
1458 |
} |
|
1459 |
||
9846
6527c7b4a92e
6566744 vdev_open() should be done in parallel
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
9434
diff
changeset
|
1460 |
vdev_open_children(vd); |
789 | 1461 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1462 |
for (c = 0; c < vd->vdev_children; c++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1463 |
cvd = vd->vdev_child[c]; |
9846
6527c7b4a92e
6566744 vdev_open() should be done in parallel
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
9434
diff
changeset
|
1464 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1465 |
if (cvd->vdev_open_error != 0) { |
9846
6527c7b4a92e
6566744 vdev_open() should be done in parallel
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
9434
diff
changeset
|
1466 |
lasterror = cvd->vdev_open_error; |
789 | 1467 |
numerrors++; |
1468 |
continue; |
|
1469 |
} |
|
1470 |
||
1471 |
*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1; |
|
1732 | 1472 |
*ashift = MAX(*ashift, cvd->vdev_ashift); |
789 | 1473 |
} |
1474 |
||
1475 |
*asize *= vd->vdev_children; |
|
1476 |
||
2082 | 1477 |
if (numerrors > nparity) { |
789 | 1478 |
vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS; |
1479 |
return (lasterror); |
|
1480 |
} |
|
1481 |
||
1482 |
return (0); |
|
1483 |
} |
|
1484 |
||
1485 |
static void |
|
1486 |
vdev_raidz_close(vdev_t *vd) |
|
1487 |
{ |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1488 |
int c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1489 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1490 |
for (c = 0; c < vd->vdev_children; c++) |
789 | 1491 |
vdev_close(vd->vdev_child[c]); |
1492 |
} |
|
1493 |
||
1494 |
static uint64_t |
|
1495 |
vdev_raidz_asize(vdev_t *vd, uint64_t psize) |
|
1496 |
{ |
|
1497 |
uint64_t asize; |
|
1732 | 1498 |
uint64_t ashift = vd->vdev_top->vdev_ashift; |
789 | 1499 |
uint64_t cols = vd->vdev_children; |
2082 | 1500 |
uint64_t nparity = vd->vdev_nparity; |
789 | 1501 |
|
1732 | 1502 |
asize = ((psize - 1) >> ashift) + 1; |
2082 | 1503 |
asize += nparity * ((asize + cols - nparity - 1) / (cols - nparity)); |
1504 |
asize = roundup(asize, nparity + 1) << ashift; |
|
789 | 1505 |
|
1506 |
return (asize); |
|
1507 |
} |
|
1508 |
||
1509 |
static void |
|
1510 |
vdev_raidz_child_done(zio_t *zio) |
|
1511 |
{ |
|
1512 |
raidz_col_t *rc = zio->io_private; |
|
1513 |
||
1514 |
rc->rc_error = zio->io_error; |
|
1515 |
rc->rc_tried = 1; |
|
1516 |
rc->rc_skipped = 0; |
|
1517 |
} |
|
1518 |
||
5530 | 1519 |
static int |
789 | 1520 |
vdev_raidz_io_start(zio_t *zio) |
1521 |
{ |
|
1522 |
vdev_t *vd = zio->io_vd; |
|
1732 | 1523 |
vdev_t *tvd = vd->vdev_top; |
789 | 1524 |
vdev_t *cvd; |
1525 |
raidz_map_t *rm; |
|
1526 |
raidz_col_t *rc; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1527 |
int c, i; |
789 | 1528 |
|
2082 | 1529 |
rm = vdev_raidz_map_alloc(zio, tvd->vdev_ashift, vd->vdev_children, |
1530 |
vd->vdev_nparity); |
|
789 | 1531 |
|
1775
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1732
diff
changeset
|
1532 |
ASSERT3U(rm->rm_asize, ==, vdev_psize_to_asize(vd, zio->io_size)); |
789 | 1533 |
|
1534 |
if (zio->io_type == ZIO_TYPE_WRITE) { |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1535 |
vdev_raidz_generate_parity(rm); |
789 | 1536 |
|
1537 |
for (c = 0; c < rm->rm_cols; c++) { |
|
1538 |
rc = &rm->rm_col[c]; |
|
2082 | 1539 |
cvd = vd->vdev_child[rc->rc_devidx]; |
789 | 1540 |
zio_nowait(zio_vdev_child_io(zio, NULL, cvd, |
1541 |
rc->rc_offset, rc->rc_data, rc->rc_size, |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1542 |
zio->io_type, zio->io_priority, 0, |
789 | 1543 |
vdev_raidz_child_done, rc)); |
1544 |
} |
|
5530 | 1545 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1546 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1547 |
* Generate optional I/Os for any skipped sectors to improve |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1548 |
* aggregation contiguity. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1549 |
*/ |
10450
c383b4d6980f
6869090 filebench on thumper with ZFS (snv_120) raidz causes checksum errors from all drives
Adam Leventhal <adam.leventhal@sun.com>
parents:
10105
diff
changeset
|
1550 |
for (c = rm->rm_skipstart, i = 0; i < rm->rm_nskip; c++, i++) { |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1551 |
ASSERT(c <= rm->rm_scols); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1552 |
if (c == rm->rm_scols) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1553 |
c = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1554 |
rc = &rm->rm_col[c]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1555 |
cvd = vd->vdev_child[rc->rc_devidx]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1556 |
zio_nowait(zio_vdev_child_io(zio, NULL, cvd, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1557 |
rc->rc_offset + rc->rc_size, NULL, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1558 |
1 << tvd->vdev_ashift, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1559 |
zio->io_type, zio->io_priority, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1560 |
ZIO_FLAG_NODATA | ZIO_FLAG_OPTIONAL, NULL, NULL)); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1561 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1562 |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1563 |
return (ZIO_PIPELINE_CONTINUE); |
789 | 1564 |
} |
1565 |
||
1566 |
ASSERT(zio->io_type == ZIO_TYPE_READ); |
|
1567 |
||
2082 | 1568 |
/* |
1569 |
* Iterate over the columns in reverse order so that we hit the parity |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1570 |
* last -- any errors along the way will force us to read the parity. |
2082 | 1571 |
*/ |
789 | 1572 |
for (c = rm->rm_cols - 1; c >= 0; c--) { |
1573 |
rc = &rm->rm_col[c]; |
|
2082 | 1574 |
cvd = vd->vdev_child[rc->rc_devidx]; |
5329 | 1575 |
if (!vdev_readable(cvd)) { |
2082 | 1576 |
if (c >= rm->rm_firstdatacol) |
1577 |
rm->rm_missingdata++; |
|
1578 |
else |
|
1579 |
rm->rm_missingparity++; |
|
789 | 1580 |
rc->rc_error = ENXIO; |
1581 |
rc->rc_tried = 1; /* don't even try */ |
|
1582 |
rc->rc_skipped = 1; |
|
1583 |
continue; |
|
1584 |
} |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
10653
diff
changeset
|
1585 |
if (vdev_dtl_contains(cvd, DTL_MISSING, zio->io_txg, 1)) { |
2082 | 1586 |
if (c >= rm->rm_firstdatacol) |
1587 |
rm->rm_missingdata++; |
|
1588 |
else |
|
1589 |
rm->rm_missingparity++; |
|
789 | 1590 |
rc->rc_error = ESTALE; |
1591 |
rc->rc_skipped = 1; |
|
1592 |
continue; |
|
1593 |
} |
|
2082 | 1594 |
if (c >= rm->rm_firstdatacol || rm->rm_missingdata > 0 || |
9434
3bebded7c76a
6794570 incomplete resilvering after disk replacement
Mark J Musante <Mark.Musante@Sun.COM>
parents:
8241
diff
changeset
|
1595 |
(zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER))) { |
789 | 1596 |
zio_nowait(zio_vdev_child_io(zio, NULL, cvd, |
1597 |
rc->rc_offset, rc->rc_data, rc->rc_size, |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1598 |
zio->io_type, zio->io_priority, 0, |
789 | 1599 |
vdev_raidz_child_done, rc)); |
1600 |
} |
|
1601 |
} |
|
1602 |
||
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1603 |
return (ZIO_PIPELINE_CONTINUE); |
789 | 1604 |
} |
1605 |
||
12296
7cf402a7f374
6675946 'zpool status' should show the progress of resilvering for individual disk.
Lin Ling <Lin.Ling@Sun.COM>
parents:
11958
diff
changeset
|
1606 |
|
1544 | 1607 |
/* |
1608 |
* Report a checksum error for a child of a RAID-Z device. |
|
1609 |
*/ |
|
1610 |
static void |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1611 |
raidz_checksum_error(zio_t *zio, raidz_col_t *rc, void *bad_data) |
1544 | 1612 |
{ |
2082 | 1613 |
vdev_t *vd = zio->io_vd->vdev_child[rc->rc_devidx]; |
1544 | 1614 |
|
1615 |
if (!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1616 |
zio_bad_cksum_t zbc; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1617 |
raidz_map_t *rm = zio->io_vsd; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1618 |
|
1544 | 1619 |
mutex_enter(&vd->vdev_stat_lock); |
1620 |
vd->vdev_stat.vs_checksum_errors++; |
|
1621 |
mutex_exit(&vd->vdev_stat_lock); |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1622 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1623 |
zbc.zbc_has_cksum = 0; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1624 |
zbc.zbc_injected = rm->rm_ecksuminjected; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1625 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1626 |
zfs_ereport_post_checksum(zio->io_spa, vd, zio, |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1627 |
rc->rc_offset, rc->rc_size, rc->rc_data, bad_data, |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1628 |
&zbc); |
1544 | 1629 |
} |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1630 |
} |
1544 | 1631 |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1632 |
/* |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1633 |
* We keep track of whether or not there were any injected errors, so that |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1634 |
* any ereports we generate can note it. |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1635 |
*/ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1636 |
static int |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1637 |
raidz_checksum_verify(zio_t *zio) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1638 |
{ |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1639 |
zio_bad_cksum_t zbc; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1640 |
raidz_map_t *rm = zio->io_vsd; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1641 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1642 |
int ret = zio_checksum_error(zio, &zbc); |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1643 |
if (ret != 0 && zbc.zbc_injected != 0) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1644 |
rm->rm_ecksuminjected = 1; |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1645 |
|
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1646 |
return (ret); |
1544 | 1647 |
} |
1648 |
||
2082 | 1649 |
/* |
1650 |
* Generate the parity from the data columns. If we tried and were able to |
|
1651 |
* read the parity without error, verify that the generated parity matches the |
|
1652 |
* data we read. If it doesn't, we fire off a checksum error. Return the |
|
1653 |
* number such failures. |
|
1654 |
*/ |
|
1655 |
static int |
|
1656 |
raidz_parity_verify(zio_t *zio, raidz_map_t *rm) |
|
1657 |
{ |
|
1658 |
void *orig[VDEV_RAIDZ_MAXPARITY]; |
|
1659 |
int c, ret = 0; |
|
1660 |
raidz_col_t *rc; |
|
1661 |
||
1662 |
for (c = 0; c < rm->rm_firstdatacol; c++) { |
|
1663 |
rc = &rm->rm_col[c]; |
|
1664 |
if (!rc->rc_tried || rc->rc_error != 0) |
|
1665 |
continue; |
|
1666 |
orig[c] = zio_buf_alloc(rc->rc_size); |
|
1667 |
bcopy(rc->rc_data, orig[c], rc->rc_size); |
|
1668 |
} |
|
1669 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1670 |
vdev_raidz_generate_parity(rm); |
2082 | 1671 |
|
1672 |
for (c = 0; c < rm->rm_firstdatacol; c++) { |
|
1673 |
rc = &rm->rm_col[c]; |
|
1674 |
if (!rc->rc_tried || rc->rc_error != 0) |
|
1675 |
continue; |
|
1676 |
if (bcmp(orig[c], rc->rc_data, rc->rc_size) != 0) { |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1677 |
raidz_checksum_error(zio, rc, orig[c]); |
2082 | 1678 |
rc->rc_error = ECKSUM; |
1679 |
ret++; |
|
1680 |
} |
|
1681 |
zio_buf_free(orig[c], rc->rc_size); |
|
1682 |
} |
|
1683 |
||
1684 |
return (ret); |
|
1685 |
} |
|
1686 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1687 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1688 |
* Keep statistics on all the ways that we used parity to correct data. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1689 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1690 |
static uint64_t raidz_corrected[1 << VDEV_RAIDZ_MAXPARITY]; |
1544 | 1691 |
|
5530 | 1692 |
static int |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1693 |
vdev_raidz_worst_error(raidz_map_t *rm) |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1694 |
{ |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1695 |
int error = 0; |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1696 |
|
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1697 |
for (int c = 0; c < rm->rm_cols; c++) |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1698 |
error = zio_worst_error(error, rm->rm_col[c].rc_error); |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1699 |
|
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1700 |
return (error); |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1701 |
} |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1702 |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1703 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1704 |
* Iterate over all combinations of bad data and attempt a reconstruction. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1705 |
* Note that the algorithm below is non-optimal because it doesn't take into |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1706 |
* account how reconstruction is actually performed. For example, with |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1707 |
* triple-parity RAID-Z the reconstruction procedure is the same if column 4 |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1708 |
* is targeted as invalid as if columns 1 and 4 are targeted since in both |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1709 |
* cases we'd only use parity information in column 0. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1710 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1711 |
static int |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1712 |
vdev_raidz_combrec(zio_t *zio, int total_errors, int data_errors) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1713 |
{ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1714 |
raidz_map_t *rm = zio->io_vsd; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1715 |
raidz_col_t *rc; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1716 |
void *orig[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1717 |
int tstore[VDEV_RAIDZ_MAXPARITY + 2]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1718 |
int *tgts = &tstore[1]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1719 |
int current, next, i, c, n; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1720 |
int code, ret = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1721 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1722 |
ASSERT(total_errors < rm->rm_firstdatacol); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1723 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1724 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1725 |
* This simplifies one edge condition. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1726 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1727 |
tgts[-1] = -1; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1728 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1729 |
for (n = 1; n <= rm->rm_firstdatacol - total_errors; n++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1730 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1731 |
* Initialize the targets array by finding the first n columns |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1732 |
* that contain no error. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1733 |
* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1734 |
* If there were no data errors, we need to ensure that we're |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1735 |
* always explicitly attempting to reconstruct at least one |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1736 |
* data column. To do this, we simply push the highest target |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1737 |
* up into the data columns. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1738 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1739 |
for (c = 0, i = 0; i < n; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1740 |
if (i == n - 1 && data_errors == 0 && |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1741 |
c < rm->rm_firstdatacol) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1742 |
c = rm->rm_firstdatacol; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1743 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1744 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1745 |
while (rm->rm_col[c].rc_error != 0) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1746 |
c++; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1747 |
ASSERT3S(c, <, rm->rm_cols); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1748 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1749 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1750 |
tgts[i] = c++; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1751 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1752 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1753 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1754 |
* Setting tgts[n] simplifies the other edge condition. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1755 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1756 |
tgts[n] = rm->rm_cols; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1757 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1758 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1759 |
* These buffers were allocated in previous iterations. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1760 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1761 |
for (i = 0; i < n - 1; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1762 |
ASSERT(orig[i] != NULL); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1763 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1764 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1765 |
orig[n - 1] = zio_buf_alloc(rm->rm_col[0].rc_size); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1766 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1767 |
current = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1768 |
next = tgts[current]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1769 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1770 |
while (current != n) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1771 |
tgts[current] = next; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1772 |
current = 0; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1773 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1774 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1775 |
* Save off the original data that we're going to |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1776 |
* attempt to reconstruct. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1777 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1778 |
for (i = 0; i < n; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1779 |
ASSERT(orig[i] != NULL); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1780 |
c = tgts[i]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1781 |
ASSERT3S(c, >=, 0); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1782 |
ASSERT3S(c, <, rm->rm_cols); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1783 |
rc = &rm->rm_col[c]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1784 |
bcopy(rc->rc_data, orig[i], rc->rc_size); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1785 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1786 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1787 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1788 |
* Attempt a reconstruction and exit the outer loop on |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1789 |
* success. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1790 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1791 |
code = vdev_raidz_reconstruct(rm, tgts, n); |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1792 |
if (raidz_checksum_verify(zio) == 0) { |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1793 |
atomic_inc_64(&raidz_corrected[code]); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1794 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1795 |
for (i = 0; i < n; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1796 |
c = tgts[i]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1797 |
rc = &rm->rm_col[c]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1798 |
ASSERT(rc->rc_error == 0); |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1799 |
if (rc->rc_tried) |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1800 |
raidz_checksum_error(zio, rc, |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1801 |
orig[i]); |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1802 |
rc->rc_error = ECKSUM; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1803 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1804 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1805 |
ret = code; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1806 |
goto done; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1807 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1808 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1809 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1810 |
* Restore the original data. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1811 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1812 |
for (i = 0; i < n; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1813 |
c = tgts[i]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1814 |
rc = &rm->rm_col[c]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1815 |
bcopy(orig[i], rc->rc_data, rc->rc_size); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1816 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1817 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1818 |
do { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1819 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1820 |
* Find the next valid column after the current |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1821 |
* position.. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1822 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1823 |
for (next = tgts[current] + 1; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1824 |
next < rm->rm_cols && |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1825 |
rm->rm_col[next].rc_error != 0; next++) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1826 |
continue; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1827 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1828 |
ASSERT(next <= tgts[current + 1]); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1829 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1830 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1831 |
* If that spot is available, we're done here. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1832 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1833 |
if (next != tgts[current + 1]) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1834 |
break; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1835 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1836 |
/* |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1837 |
* Otherwise, find the next valid column after |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1838 |
* the previous position. |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1839 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1840 |
for (c = tgts[current - 1] + 1; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1841 |
rm->rm_col[c].rc_error != 0; c++) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1842 |
continue; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1843 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1844 |
tgts[current] = c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1845 |
current++; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1846 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1847 |
} while (current != n); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1848 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1849 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1850 |
n--; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1851 |
done: |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1852 |
for (i = 0; i < n; i++) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1853 |
zio_buf_free(orig[i], rm->rm_col[0].rc_size); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1854 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1855 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1856 |
return (ret); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1857 |
} |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1858 |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1859 |
static void |
789 | 1860 |
vdev_raidz_io_done(zio_t *zio) |
1861 |
{ |
|
1862 |
vdev_t *vd = zio->io_vd; |
|
1863 |
vdev_t *cvd; |
|
1864 |
raidz_map_t *rm = zio->io_vsd; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1865 |
raidz_col_t *rc; |
789 | 1866 |
int unexpected_errors = 0; |
2082 | 1867 |
int parity_errors = 0; |
3456 | 1868 |
int parity_untried = 0; |
2082 | 1869 |
int data_errors = 0; |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1870 |
int total_errors = 0; |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1871 |
int n, c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1872 |
int tgts[VDEV_RAIDZ_MAXPARITY]; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1873 |
int code; |
789 | 1874 |
|
1775
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1732
diff
changeset
|
1875 |
ASSERT(zio->io_bp != NULL); /* XXX need to add code to enforce this */ |
789 | 1876 |
|
2082 | 1877 |
ASSERT(rm->rm_missingparity <= rm->rm_firstdatacol); |
1878 |
ASSERT(rm->rm_missingdata <= rm->rm_cols - rm->rm_firstdatacol); |
|
1879 |
||
789 | 1880 |
for (c = 0; c < rm->rm_cols; c++) { |
1881 |
rc = &rm->rm_col[c]; |
|
1882 |
||
1883 |
if (rc->rc_error) { |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1884 |
ASSERT(rc->rc_error != ECKSUM); /* child has no bp */ |
2082 | 1885 |
|
1886 |
if (c < rm->rm_firstdatacol) |
|
1887 |
parity_errors++; |
|
1888 |
else |
|
1889 |
data_errors++; |
|
1890 |
||
789 | 1891 |
if (!rc->rc_skipped) |
1892 |
unexpected_errors++; |
|
2082 | 1893 |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1894 |
total_errors++; |
3456 | 1895 |
} else if (c < rm->rm_firstdatacol && !rc->rc_tried) { |
1896 |
parity_untried++; |
|
789 | 1897 |
} |
1898 |
} |
|
1899 |
||
1900 |
if (zio->io_type == ZIO_TYPE_WRITE) { |
|
1901 |
/* |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1902 |
* XXX -- for now, treat partial writes as a success. |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1903 |
* (If we couldn't write enough columns to reconstruct |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1904 |
* the data, the I/O failed. Otherwise, good enough.) |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1905 |
* |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1906 |
* Now that we support write reallocation, it would be better |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1907 |
* to treat partial failure as real failure unless there are |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1908 |
* no non-degraded top-level vdevs left, and not update DTLs |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1909 |
* if we intend to reallocate. |
789 | 1910 |
*/ |
1911 |
/* XXPOLICY */ |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1912 |
if (total_errors > rm->rm_firstdatacol) |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1913 |
zio->io_error = vdev_raidz_worst_error(rm); |
789 | 1914 |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1915 |
return; |
789 | 1916 |
} |
1917 |
||
1918 |
ASSERT(zio->io_type == ZIO_TYPE_READ); |
|
2082 | 1919 |
/* |
1920 |
* There are three potential phases for a read: |
|
1921 |
* 1. produce valid data from the columns read |
|
1922 |
* 2. read all disks and try again |
|
1923 |
* 3. perform combinatorial reconstruction |
|
1924 |
* |
|
1925 |
* Each phase is progressively both more expensive and less likely to |
|
1926 |
* occur. If we encounter more errors than we can repair or all phases |
|
1927 |
* fail, we have no choice but to return an error. |
|
1928 |
*/ |
|
789 | 1929 |
|
1930 |
/* |
|
2082 | 1931 |
* If the number of errors we saw was correctable -- less than or equal |
3456 | 1932 |
* to the number of parity disks read -- attempt to produce data that |
1933 |
* has a valid checksum. Naturally, this case applies in the absence of |
|
1934 |
* any errors. |
|
789 | 1935 |
*/ |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
1936 |
if (total_errors <= rm->rm_firstdatacol - parity_untried) { |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1937 |
if (data_errors == 0) { |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1938 |
if (raidz_checksum_verify(zio) == 0) { |
4034 | 1939 |
/* |
1940 |
* If we read parity information (unnecessarily |
|
1941 |
* as it happens since no reconstruction was |
|
1942 |
* needed) regenerate and verify the parity. |
|
1943 |
* We also regenerate parity when resilvering |
|
1944 |
* so we can write it out to the failed device |
|
1945 |
* later. |
|
1946 |
*/ |
|
3456 | 1947 |
if (parity_errors + parity_untried < |
4034 | 1948 |
rm->rm_firstdatacol || |
1949 |
(zio->io_flags & ZIO_FLAG_RESILVER)) { |
|
3456 | 1950 |
n = raidz_parity_verify(zio, rm); |
1951 |
unexpected_errors += n; |
|
1952 |
ASSERT(parity_errors + n <= |
|
1953 |
rm->rm_firstdatacol); |
|
1954 |
} |
|
2082 | 1955 |
goto done; |
1956 |
} |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1957 |
} else { |
3456 | 1958 |
/* |
1959 |
* We either attempt to read all the parity columns or |
|
1960 |
* none of them. If we didn't try to read parity, we |
|
1961 |
* wouldn't be here in the correctable case. There must |
|
1962 |
* also have been fewer parity errors than parity |
|
1963 |
* columns or, again, we wouldn't be in this code path. |
|
1964 |
*/ |
|
1965 |
ASSERT(parity_untried == 0); |
|
2082 | 1966 |
ASSERT(parity_errors < rm->rm_firstdatacol); |
1967 |
||
1968 |
/* |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1969 |
* Identify the data columns that reported an error. |
2082 | 1970 |
*/ |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1971 |
n = 0; |
2082 | 1972 |
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { |
1973 |
rc = &rm->rm_col[c]; |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1974 |
if (rc->rc_error != 0) { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1975 |
ASSERT(n < VDEV_RAIDZ_MAXPARITY); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1976 |
tgts[n++] = c; |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1977 |
} |
2082 | 1978 |
} |
1979 |
||
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1980 |
ASSERT(rm->rm_firstdatacol >= n); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1981 |
|
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1982 |
code = vdev_raidz_reconstruct(rm, tgts, n); |
2082 | 1983 |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
1984 |
if (raidz_checksum_verify(zio) == 0) { |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1985 |
atomic_inc_64(&raidz_corrected[code]); |
789 | 1986 |
|
2082 | 1987 |
/* |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1988 |
* If we read more parity disks than were used |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1989 |
* for reconstruction, confirm that the other |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1990 |
* parity disks produced correct data. This |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1991 |
* routine is suboptimal in that it regenerates |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1992 |
* the parity that we already used in addition |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1993 |
* to the parity that we're attempting to |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1994 |
* verify, but this should be a relatively |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1995 |
* uncommon case, and can be optimized if it |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1996 |
* becomes a problem. Note that we regenerate |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1997 |
* parity when resilvering so we can write it |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
1998 |
* out to failed devices later. |
2082 | 1999 |
*/ |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2000 |
if (parity_errors < rm->rm_firstdatacol - n || |
4034 | 2001 |
(zio->io_flags & ZIO_FLAG_RESILVER)) { |
2082 | 2002 |
n = raidz_parity_verify(zio, rm); |
2003 |
unexpected_errors += n; |
|
2004 |
ASSERT(parity_errors + n <= |
|
2005 |
rm->rm_firstdatacol); |
|
2006 |
} |
|
2007 |
||
2008 |
goto done; |
|
2009 |
} |
|
789 | 2010 |
} |
2011 |
} |
|
2012 |
||
2013 |
/* |
|
2082 | 2014 |
* This isn't a typical situation -- either we got a read error or |
2015 |
* a child silently returned bad data. Read every block so we can |
|
2016 |
* try again with as much data and parity as we can track down. If |
|
2017 |
* we've already been through once before, all children will be marked |
|
2018 |
* as tried so we'll proceed to combinatorial reconstruction. |
|
789 | 2019 |
*/ |
2020 |
unexpected_errors = 1; |
|
2082 | 2021 |
rm->rm_missingdata = 0; |
2022 |
rm->rm_missingparity = 0; |
|
789 | 2023 |
|
2082 | 2024 |
for (c = 0; c < rm->rm_cols; c++) { |
2025 |
if (rm->rm_col[c].rc_tried) |
|
2026 |
continue; |
|
789 | 2027 |
|
2028 |
zio_vdev_io_redone(zio); |
|
2082 | 2029 |
do { |
789 | 2030 |
rc = &rm->rm_col[c]; |
2031 |
if (rc->rc_tried) |
|
2032 |
continue; |
|
2033 |
zio_nowait(zio_vdev_child_io(zio, NULL, |
|
2082 | 2034 |
vd->vdev_child[rc->rc_devidx], |
789 | 2035 |
rc->rc_offset, rc->rc_data, rc->rc_size, |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
2036 |
zio->io_type, zio->io_priority, 0, |
789 | 2037 |
vdev_raidz_child_done, rc)); |
2082 | 2038 |
} while (++c < rm->rm_cols); |
5530 | 2039 |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
2040 |
return; |
789 | 2041 |
} |
2042 |
||
2043 |
/* |
|
2082 | 2044 |
* At this point we've attempted to reconstruct the data given the |
2045 |
* errors we detected, and we've attempted to read all columns. There |
|
2046 |
* must, therefore, be one or more additional problems -- silent errors |
|
2047 |
* resulting in invalid data rather than explicit I/O errors resulting |
|
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2048 |
* in absent data. We check if there is enough additional data to |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2049 |
* possibly reconstruct the data and then perform combinatorial |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2050 |
* reconstruction over all possible combinations. If that fails, |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2051 |
* we're cooked. |
789 | 2052 |
*/ |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2053 |
if (total_errors > rm->rm_firstdatacol) { |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
2054 |
zio->io_error = vdev_raidz_worst_error(rm); |
2082 | 2055 |
|
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2056 |
} else if (total_errors < rm->rm_firstdatacol && |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2057 |
(code = vdev_raidz_combrec(zio, total_errors, data_errors)) != 0) { |
2082 | 2058 |
/* |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2059 |
* If we didn't use all the available parity for the |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2060 |
* combinatorial reconstruction, verify that the remaining |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2061 |
* parity is correct. |
2082 | 2062 |
*/ |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2063 |
if (code != (1 << rm->rm_firstdatacol) - 1) |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2064 |
(void) raidz_parity_verify(zio, rm); |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2065 |
} else { |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2066 |
/* |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2067 |
* We're here because either: |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2068 |
* |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2069 |
* total_errors == rm_first_datacol, or |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2070 |
* vdev_raidz_combrec() failed |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2071 |
* |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2072 |
* In either case, there is enough bad data to prevent |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2073 |
* reconstruction. |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2074 |
* |
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2075 |
* Start checksum ereports for all children which haven't |
11670
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2076 |
* failed, and the IO wasn't speculative. |
10105
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2077 |
*/ |
17811c723fb4
6854612 triple-parity RAID-Z
Adam Leventhal <adam.leventhal@sun.com>
parents:
9846
diff
changeset
|
2078 |
zio->io_error = ECKSUM; |
2082 | 2079 |
|
11670
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2080 |
if (!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2081 |
for (c = 0; c < rm->rm_cols; c++) { |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2082 |
rc = &rm->rm_col[c]; |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2083 |
if (rc->rc_error == 0) { |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2084 |
zio_bad_cksum_t zbc; |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2085 |
zbc.zbc_has_cksum = 0; |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2086 |
zbc.zbc_injected = |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2087 |
rm->rm_ecksuminjected; |
10614
4f397871da47
PSARC 2009/497 zfs checksum ereport payload additions
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents:
10450
diff
changeset
|
2088 |
|
11670
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2089 |
zfs_ereport_start_checksum( |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2090 |
zio->io_spa, |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2091 |
vd->vdev_child[rc->rc_devidx], |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2092 |
zio, rc->rc_offset, rc->rc_size, |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2093 |
(void *)(uintptr_t)c, &zbc); |
1d964fb5d948
6595532 ZIL is too talkative
Neil Perrin <Neil.Perrin@Sun.COM>
parents:
10922
diff
changeset
|
2094 |
} |
2082 | 2095 |
} |
1544 | 2096 |
} |
2097 |
} |
|
789 | 2098 |
|
2099 |
done: |
|
2100 |
zio_checksum_verified(zio); |
|
2101 |
||
8241
5a60f16123ba
6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
7754
diff
changeset
|
2102 |
if (zio->io_error == 0 && spa_writeable(zio->io_spa) && |
789 | 2103 |
(unexpected_errors || (zio->io_flags & ZIO_FLAG_RESILVER))) { |
2104 |
/* |
|
2105 |
* Use the good data we have in hand to repair damaged children. |
|
2106 |
*/ |
|
2107 |
for (c = 0; c < rm->rm_cols; c++) { |
|
2108 |
rc = &rm->rm_col[c]; |
|
2082 | 2109 |
cvd = vd->vdev_child[rc->rc_devidx]; |
789 | 2110 |
|
1732 | 2111 |
if (rc->rc_error == 0) |
2112 |
continue; |
|
2113 |
||
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
5530
diff
changeset
|
2114 |
zio_nowait(zio_vdev_child_io(zio, NULL, cvd, |
1732 | 2115 |
rc->rc_offset, rc->rc_data, rc->rc_size, |
2116 |
ZIO_TYPE_WRITE, zio->io_priority, |
|
8241
5a60f16123ba
6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
7754
diff
changeset
|
2117 |
ZIO_FLAG_IO_REPAIR | (unexpected_errors ? |
5a60f16123ba
6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
7754
diff
changeset
|
2118 |
ZIO_FLAG_SELF_HEAL : 0), NULL, NULL)); |
1732 | 2119 |
} |
789 | 2120 |
} |
2121 |
} |
|
2122 |
||
2123 |
static void |
|
2124 |
vdev_raidz_state_change(vdev_t *vd, int faulted, int degraded) |
|
2125 |
{ |
|
2082 | 2126 |
if (faulted > vd->vdev_nparity) |
1544 | 2127 |
vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN, |
2128 |
VDEV_AUX_NO_REPLICAS); |
|
789 | 2129 |
else if (degraded + faulted != 0) |
1544 | 2130 |
vdev_set_state(vd, B_FALSE, VDEV_STATE_DEGRADED, VDEV_AUX_NONE); |
789 | 2131 |
else |
1544 | 2132 |
vdev_set_state(vd, B_FALSE, VDEV_STATE_HEALTHY, VDEV_AUX_NONE); |
789 | 2133 |
} |
2134 |
||
2135 |
vdev_ops_t vdev_raidz_ops = { |
|
2136 |
vdev_raidz_open, |
|
2137 |
vdev_raidz_close, |
|
2138 |
vdev_raidz_asize, |
|
2139 |
vdev_raidz_io_start, |
|
2140 |
vdev_raidz_io_done, |
|
2141 |
vdev_raidz_state_change, |
|
11958
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
11670
diff
changeset
|
2142 |
NULL, |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
11670
diff
changeset
|
2143 |
NULL, |
789 | 2144 |
VDEV_TYPE_RAIDZ, /* name of this vdev type */ |
2145 |
B_FALSE /* not a leaf vdev */ |
|
2146 |
}; |