1896 {
1897 ULONG sectors_per_stripe = (
ULONG)(
c->chunk_item->stripe_length >>
Vcb->sector_shift), off;
1898 uint16_t stripe, parity1 = (bit_start +
num +
c->chunk_item->num_stripes - 2) %
c->chunk_item->num_stripes;
1899 uint16_t parity2 = (parity1 + 1) %
c->chunk_item->num_stripes;
1901
1902 stripe = (parity1 + 2) %
c->chunk_item->num_stripes;
1903 off = (
ULONG)(bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2);
1904 stripeoff =
num * sectors_per_stripe;
1905
1906 if (
c->devices[parity1]->devobj)
1908
1909 if (
c->devices[parity2]->devobj)
1911
1912 while (
stripe != parity1) {
1914
1915 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
1919 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (off <<
Vcb->sector_shift);
1920
1924
1925 if (missing_devices == 2)
1927 }
1928
1929 off +=
Vcb->superblock.node_size >>
Vcb->sector_shift;
1930 stripeoff +=
Vcb->superblock.node_size >>
Vcb->sector_shift;
1931 i += (
Vcb->superblock.node_size >>
Vcb->sector_shift) - 1;
1932
1933 continue;
1936
1938
1940 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (off <<
Vcb->sector_shift);
1941
1944
1945 if (missing_devices == 2)
1947 }
1948 }
1949 }
1950
1951 off++;
1952 stripeoff++;
1953 }
1954
1955 if (
c->devices[parity1]->devobj)
1957
1959 stripeoff =
num * sectors_per_stripe;
1960 }
1961
1963
1964 if (missing_devices == 0 || (missing_devices == 1 && !
c->devices[parity2]->devobj)) {
1965
1966
1967 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
1969
1970 o =
i <<
Vcb->sector_shift;
1971 for (
j = 0;
j <
Vcb->superblock.sector_size;
j++) {
1972 if (
context->parity_scratch[o] != 0) {
1974 break;
1975 }
1976 o++;
1977 }
1978 }
1979 }
1980
1982
1983 if (missing_devices == 0 || (missing_devices == 1 && !
c->devices[parity1]->devobj)) {
1984
1985
1986 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
1987
1988 while (
stripe != parity2) {
1991
1993 }
1994
1995 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
1997 &
context->parity_scratch2[
i <<
Vcb->sector_shift],
Vcb->superblock.sector_size) !=
Vcb->superblock.sector_size)
1999 }
2000 }
2001
2002 if (missing_devices == 2)
2003 return;
2004
2005
2006
2007 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
2009 uint64_t bad_stripe1 = 0, bad_stripe2 = 0;
2010 ULONG bad_off1 = 0, bad_off2 = 0;
2012
2013 stripe = (parity1 + 2) %
c->chunk_item->num_stripes;
2014 off = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2)) +
i;
2015
2016 while (
stripe != parity1) {
2019
2023 bad_off1 = off;
2026 bad_off2 = off;
2027 }
2029 }
2030 }
2031
2032 off += sectors_per_stripe;
2034 }
2035
2037 continue;
2038
2040 continue;
2041
2044
2046 do_xor(&
context->stripes[parity1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2048 Vcb->superblock.sector_size);
2049
2050 bad_off1 = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2)) +
i;
2051 addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off1 <<
Vcb->sector_shift);
2052
2053 context->stripes[parity1].rewrite =
true;
2054
2057 }
2058
2061 &
context->parity_scratch2[
i <<
Vcb->sector_shift],
2062 Vcb->superblock.sector_size);
2063
2064 bad_off1 = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2)) +
i;
2065 addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off1 <<
Vcb->sector_shift);
2066
2067 context->stripes[parity2].rewrite =
true;
2068
2071 }
2074 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off1 <<
Vcb->sector_shift);
2076
2078
2080 if (!scratch) {
2081 ERR(
"out of memory\n");
2082 return;
2083 }
2084
2086
2088 &
context->stripes[bad_stripe1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
len);
2089
2090 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
2091
2092 if (
c->devices[parity2]->devobj) {
2093 uint16_t stripe_num, bad_stripe_num = 0;
2094
2095 stripe_num =
c->chunk_item->num_stripes - 3;
2096 while (
stripe != parity2) {
2098
2099 if (
stripe != bad_stripe1)
2101 else
2102 bad_stripe_num = stripe_num;
2103
2105 stripe_num--;
2106 }
2107
2108 do_xor(scratch, &
context->stripes[parity2].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
len);
2109
2110 if (bad_stripe_num != 0)
2112 }
2113
2118
2119 if (
c->devices[parity1]->devobj) {
2122 }
2123
2124 if (
c->devices[parity2]->devobj) {
2127 }
2128
2133 scratch,
Vcb->superblock.node_size);
2134
2135 if (
c->devices[parity1]->devobj) {
2136
2137
2138 stripe = (parity1 + 2) %
c->chunk_item->num_stripes;
2139
2142 Vcb->superblock.node_size);
2143
2145
2147 do_xor(&
context->stripes[parity1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2149 Vcb->superblock.node_size);
2150
2152 }
2153
2154 context->stripes[parity1].rewrite =
true;
2155
2158 }
2159 } else {
2161 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.node_size);
2162
2164
2165 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
2166
2167 if (
c->devices[parity2]->devobj) {
2170 Vcb->superblock.node_size);
2171
2173
2174 while (
stripe != parity2) {
2176
2177 do_xor(&
context->stripes[parity2].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2179 Vcb->superblock.node_size);
2180
2182 }
2183
2184 context->stripes[parity2].rewrite =
true;
2185
2188 }
2189 }
2190 }
2191
2192 context->stripes[bad_stripe1].rewrite =
true;
2193
2195
2196 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
true,
true,
false);
2197 } else
2198 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
true,
false,
false);
2199 } else {
2202
2203 if (
c->devices[parity1]->devobj)
2205
2206 if (
c->devices[parity2]->devobj)
2208
2213 scratch,
Vcb->superblock.sector_size);
2214
2216
2217
2218 stripe = (parity1 + 2) %
c->chunk_item->num_stripes;
2219
2222 Vcb->superblock.sector_size);
2223
2225
2227 do_xor(&
context->stripes[parity1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2229 Vcb->superblock.sector_size);
2230
2232 }
2233
2234 context->stripes[parity1].rewrite =
true;
2235
2238 }
2239 } else {
2241 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.sector_size);
2242
2244
2245 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
2246
2249 Vcb->superblock.sector_size);
2250
2252
2253 while (
stripe != parity2) {
2255
2256 do_xor(&
context->stripes[parity2].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2258 Vcb->superblock.sector_size);
2259
2261 }
2262
2263 context->stripes[parity2].rewrite =
true;
2264
2267 }
2268 }
2269
2270 context->stripes[bad_stripe1].rewrite =
true;
2271
2272 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
false,
true,
false);
2273 } else
2274 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
false,
false,
false);
2275 }
2276
2278 }
else if (
num_errors == 2 && missing_devices == 0) {
2284
2285 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
2286
2287
2288
2289
2290 k =
c->chunk_item->num_stripes - 3;
2294
2295 if (
stripe == bad_stripe1)
2297 else
2299 } else {
2304 }
2305
2307
2309 do {
2311
2317 }
else if (
stripe == bad_stripe1)
2319 else if (
stripe == bad_stripe2)
2321
2324 }
while (
stripe != parity2);
2325
2328
2329 denom =
gdiv(1, gyx ^ 1);
2330 a =
gmul(gyx, denom);
2331 b =
gmul(gx, denom);
2332
2333 p = &
context->stripes[parity1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)];
2334 q = &
context->stripes[parity2].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)];
2335 pxy = &
context->parity_scratch2[
i <<
Vcb->sector_shift];
2336 qxy = &
context->parity_scratch[
i <<
Vcb->sector_shift];
2337
2338 for (
j = 0;
j <
len;
j++) {
2340
2343 pxy++;
2344 qxy++;
2345 }
2346
2349
2350 addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off1 <<
Vcb->sector_shift);
2351
2354
2357 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.node_size);
2358
2359 context->stripes[bad_stripe1].rewrite =
true;
2360
2362
2363 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
true,
true,
false);
2364 } else
2365 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
true,
false,
false);
2366 } else {
2369 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.sector_size);
2370
2371 context->stripes[bad_stripe1].rewrite =
true;
2372
2373 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
false,
true,
false);
2374 } else
2375 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
false,
false,
false);
2376 }
2377
2378 addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off2 <<
Vcb->sector_shift);
2379
2382
2385 &
context->parity_scratch2[
i <<
Vcb->sector_shift],
Vcb->superblock.node_size);
2386
2387 context->stripes[bad_stripe2].rewrite =
true;
2388
2390
2391 log_error(
Vcb,
addr,
c->devices[bad_stripe2]->devitem.dev_id,
true,
true,
false);
2392 } else
2393 log_error(
Vcb,
addr,
c->devices[bad_stripe2]->devitem.dev_id,
true,
false,
false);
2394 } else {
2397 &
context->parity_scratch2[
i <<
Vcb->sector_shift],
Vcb->superblock.sector_size);
2398
2399 context->stripes[bad_stripe2].rewrite =
true;
2400
2401 log_error(
Vcb,
addr,
c->devices[bad_stripe2]->devitem.dev_id,
false,
true,
false);
2402 } else
2403 log_error(
Vcb,
addr,
c->devices[bad_stripe2]->devitem.dev_id,
false,
false,
false);
2404 }
2405 } else {
2406 stripe = (parity2 + 1) %
c->chunk_item->num_stripes;
2407 off = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2)) +
i;
2408
2409 while (
stripe != parity1) {
2412 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (off <<
Vcb->sector_shift);
2413
2415 }
2416 }
2417
2418 off += sectors_per_stripe;
2420 }
2421 }
2422 }
2423}
uint8_t gdiv(uint8_t a, uint8_t b)
uint8_t gmul(uint8_t a, uint8_t b)
void galois_double(uint8_t *data, uint32_t len)
void galois_divpower(uint8_t *data, uint8_t div, uint32_t readlen)
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
GLint GLint GLint GLint GLint x
GLint GLint GLint GLint GLint GLint y
GLdouble GLdouble GLdouble GLdouble q
GLboolean GLboolean GLboolean GLboolean a