2011-03-01 22:19:30 +01:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
< html lang = "en" >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
< title > LCOV - lcov.info - raid/raid.c< / title >
< link rel = "stylesheet" type = "text/css" href = "../gcov.css" >
< / head >
< body >
< table width = "100%" border = 0 cellspacing = 0 cellpadding = 0 >
< tr > < td class = "title" > LCOV - code coverage report< / td > < / tr >
< tr > < td class = "ruler" > < img src = "../glass.png" width = 3 height = 3 alt = "" > < / td > < / tr >
< tr >
< td width = "100%" >
< table cellpadding = 1 border = 0 width = "100%" >
< tr >
< td width = "10%" class = "headerItem" > Current view:< / td >
2017-12-11 23:00:27 +01:00
< td width = "35%" class = "headerValue" > < a href = "../index.html" > top level< / a > - < a href = "index.html" > raid< / a > - raid.c< span style = "font-size: 80%;" > (source / < a href = "raid.c.func-sort-c.html" > functions< / a > )< / span > < / td >
2011-03-01 22:19:30 +01:00
< td width = "5%" > < / td >
< td width = "15%" > < / td >
< td width = "10%" class = "headerCovTableHead" > Hit< / td >
< td width = "10%" class = "headerCovTableHead" > Total< / td >
< td width = "15%" class = "headerCovTableHead" > Coverage< / td >
< / tr >
< tr >
< td class = "headerItem" > Test:< / td >
< td class = "headerValue" > lcov.info< / td >
< td > < / td >
< td class = "headerItem" > Lines:< / td >
< td class = "headerCovTableEntry" > 123< / td >
< td class = "headerCovTableEntry" > 123< / td >
< td class = "headerCovTableEntryHi" > 100.0 %< / td >
< / tr >
< tr >
< td class = "headerItem" > Date:< / td >
2026-03-15 18:52:43 +01:00
< td class = "headerValue" > 2026-03-15 15:58:19< / td >
2011-03-01 22:19:30 +01:00
< td > < / td >
< td class = "headerItem" > Functions:< / td >
< td class = "headerCovTableEntry" > 9< / td >
< td class = "headerCovTableEntry" > 9< / td >
< td class = "headerCovTableEntryHi" > 100.0 %< / td >
< / tr >
< tr > < td > < img src = "../glass.png" width = 3 height = 3 alt = "" > < / td > < / tr >
< / table >
< / td >
< / tr >
< tr > < td class = "ruler" > < img src = "../glass.png" width = 3 height = 3 alt = "" > < / td > < / tr >
< / table >
< table cellpadding = 0 cellspacing = 0 border = 0 >
< tr >
< td > < br > < / td >
< / tr >
< tr >
< td >
< pre class = "sourceHeading" > Line data Source code< / pre >
< pre class = "source" >
< a name = "1" > < span class = "lineNum" > 1 < / span > : /*< / a >
2025-10-28 12:01:21 +01:00
< a name = "2" > < span class = "lineNum" > 2 < / span > : * Copyright (C) 2013 Andrea Mazzoleni< / a >
< a name = "3" > < span class = "lineNum" > 3 < / span > : *< / a >
< a name = "4" > < span class = "lineNum" > 4 < / span > : * This program is free software: you can redistribute it and/or modify< / a >
< a name = "5" > < span class = "lineNum" > 5 < / span > : * it under the terms of the GNU General Public License as published by< / a >
< a name = "6" > < span class = "lineNum" > 6 < / span > : * the Free Software Foundation, either version 2 of the License, or< / a >
< a name = "7" > < span class = "lineNum" > 7 < / span > : * (at your option) any later version.< / a >
< a name = "8" > < span class = "lineNum" > 8 < / span > : *< / a >
< a name = "9" > < span class = "lineNum" > 9 < / span > : * This program is distributed in the hope that it will be useful,< / a >
< a name = "10" > < span class = "lineNum" > 10 < / span > : * but WITHOUT ANY WARRANTY; without even the implied warranty of< / a >
< a name = "11" > < span class = "lineNum" > 11 < / span > : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the< / a >
< a name = "12" > < span class = "lineNum" > 12 < / span > : * GNU General Public License for more details.< / a >
< a name = "13" > < span class = "lineNum" > 13 < / span > : */< / a >
< a name = "14" > < span class = "lineNum" > 14 < / span > : < / a >
< a name = "15" > < span class = "lineNum" > 15 < / span > : #include " internal.h" < / a >
< a name = "16" > < span class = "lineNum" > 16 < / span > : #include " gf.h" < / a >
< a name = "17" > < span class = "lineNum" > 17 < / span > : < / a >
< a name = "18" > < span class = "lineNum" > 18 < / span > : /*< / a >
< a name = "19" > < span class = "lineNum" > 19 < / span > : * Cauchy Matrix Construction for MDS RAID with Arbitrary Parity Levels in GF(2^8)< / a >
< a name = "20" > < span class = "lineNum" > 20 < / span > : *< / a >
< a name = "21" > < span class = "lineNum" > 21 < / span > : * This is a RAID implementation operating in the Galois Field GF(2^8) with< / a >
< a name = "22" > < span class = "lineNum" > 22 < / span > : * the primitive polynomial x^8 + x^4 + x^3 + x^2 + 1 (285 decimal), supporting< / a >
< a name = "23" > < span class = "lineNum" > 23 < / span > : * up to six parity levels.< / a >
< a name = "24" > < span class = "lineNum" > 24 < / span > : *< / a >
< a name = "25" > < span class = "lineNum" > 25 < / span > : * For RAID5 and RAID6, it follows the method described in H. Peter Anvin's< / a >
< a name = "26" > < span class = "lineNum" > 26 < / span > : * paper " The mathematics of RAID-6" [1]. Please refer to this paper for a< / a >
< a name = "27" > < span class = "lineNum" > 27 < / span > : * complete explanation.< / a >
< a name = "28" > < span class = "lineNum" > 28 < / span > : *< / a >
< a name = "29" > < span class = "lineNum" > 29 < / span > : * Triple parity was first evaluated using an extension of the same approach,< / a >
< a name = "30" > < span class = "lineNum" > 30 < / span > : * with additional parity coefficients set as powers of 2^-1, defined as:< / a >
< a name = "31" > < span class = "lineNum" > 31 < / span > : *< / a >
< a name = "32" > < span class = "lineNum" > 32 < / span > : * P = sum(Di)< / a >
< a name = "33" > < span class = "lineNum" > 33 < / span > : * Q = sum(2^i * Di)< / a >
< a name = "34" > < span class = "lineNum" > 34 < / span > : * R = sum(2^-i * Di) for 0 < = i < N< / a >
< a name = "35" > < span class = "lineNum" > 35 < / span > : *< / a >
< a name = "36" > < span class = "lineNum" > 36 < / span > : * This approach works efficiently for triple parity because multiplications< / a >
< a name = "37" > < span class = "lineNum" > 37 < / span > : * and divisions by 2 in GF(2^8) are very fast. It is similar to ZFS RAIDZ3,< / a >
< a name = "38" > < span class = "lineNum" > 38 < / span > : * which uses powers of 4 instead of 2^-1.< / a >
< a name = "39" > < span class = "lineNum" > 39 < / span > : *< / a >
< a name = "40" > < span class = "lineNum" > 40 < / span > : * Unfortunately, this method does not extend beyond triple parity because< / a >
< a name = "41" > < span class = "lineNum" > 41 < / span > : * no choice of power coefficients guarantees solvable equations for all< / a >
< a name = "42" > < span class = "lineNum" > 42 < / span > : * combinations of missing disks. This is expected: a Vandermonde matrix,< / a >
< a name = "43" > < span class = "lineNum" > 43 < / span > : * used in this method, does not ensure that all submatrices are nonsingular< / a >
< a name = "44" > < span class = "lineNum" > 44 < / span > : * [2, Chap. 11, Problem 7], which is required for an MDS (Maximum Distance< / a >
< a name = "45" > < span class = "lineNum" > 45 < / span > : * Separable) code [2, Chap. 11, Theorem 8].< / a >
< a name = "46" > < span class = "lineNum" > 46 < / span > : *< / a >
< a name = "47" > < span class = "lineNum" > 47 < / span > : * To overcome this limitation, a Cauchy matrix [3][4] is used for parity< / a >
< a name = "48" > < span class = "lineNum" > 48 < / span > : * computation. A Cauchy matrix ensures that all square submatrices are< / a >
< a name = "49" > < span class = "lineNum" > 49 < / span > : * nonsingular, so the linear system is always solvable for any combination< / a >
< a name = "50" > < span class = "lineNum" > 50 < / span > : * of missing disks. This guarantees an MDS code.< / a >
< a name = "51" > < span class = "lineNum" > 51 < / span > : *< / a >
< a name = "52" > < span class = "lineNum" > 52 < / span > : * How the matrix is obtained:< / a >
< a name = "53" > < span class = "lineNum" > 53 < / span > : *< / a >
< a name = "54" > < span class = "lineNum" > 54 < / span > : * The matrix is constructed to match Linux RAID coefficients for the< / a >
< a name = "55" > < span class = "lineNum" > 55 < / span > : * first two rows, while ensuring that all square submatrices are nonsingular.< / a >
< a name = "56" > < span class = "lineNum" > 56 < / span > : *< / a >
< a name = "57" > < span class = "lineNum" > 57 < / span > : * 1. Start by forming a Cauchy matrix with elements defined as 1/(x_i + y_j),< / a >
< a name = "58" > < span class = "lineNum" > 58 < / span > : * where all x_i and y_j are distinct elements (the textbook definition< / a >
< a name = "59" > < span class = "lineNum" > 59 < / span > : * of a Cauchy matrix).< / a >
< a name = "60" > < span class = "lineNum" > 60 < / span > : *< / a >
< a name = "61" > < span class = "lineNum" > 61 < / span > : * 2. For the first row (j=0), set x_i = 2^-i and y_0 = 0, resulting in:< / a >
< a name = "62" > < span class = "lineNum" > 62 < / span > : *< / a >
< a name = "63" > < span class = "lineNum" > 63 < / span > : * row j=0 -> 1/(x_i + y_0) = 1/(2^-i + 0) = 2^i< / a >
< a name = "64" > < span class = "lineNum" > 64 < / span > : *< / a >
< a name = "65" > < span class = "lineNum" > 65 < / span > : * which reproduces the RAID-6 coefficients.< / a >
< a name = "66" > < span class = "lineNum" > 66 < / span > : *< / a >
< a name = "67" > < span class = "lineNum" > 67 < / span > : * 3. For subsequent rows (j> 0), set y_j = 2^j, yielding:< / a >
< a name = "68" > < span class = "lineNum" > 68 < / span > : *< / a >
< a name = "69" > < span class = "lineNum" > 69 < / span > : * rows j> 0 -> 1/(x_i + y_j) = 1/(2^-i + 2^j)< / a >
< a name = "70" > < span class = "lineNum" > 70 < / span > : *< / a >
< a name = "71" > < span class = "lineNum" > 71 < / span > : * ensuring x_i != y_j for any i > = 0, j > = 1, and i + j < 255.< / a >
< a name = "72" > < span class = "lineNum" > 72 < / span > : *< / a >
< a name = "73" > < span class = "lineNum" > 73 < / span > : * 4. Place a row filled with 1 at the top of the matrix, transforming it< / a >
< a name = "74" > < span class = "lineNum" > 74 < / span > : * into an Extended Cauchy Matrix. This preserves the nonsingularity< / a >
< a name = "75" > < span class = "lineNum" > 75 < / span > : * of all square submatrices.< / a >
< a name = "76" > < span class = "lineNum" > 76 < / span > : *< / a >
< a name = "77" > < span class = "lineNum" > 77 < / span > : * This first row reproduces the RAID-5 coefficients.< / a >
< a name = "78" > < span class = "lineNum" > 78 < / span > : *< / a >
< a name = "79" > < span class = "lineNum" > 79 < / span > : * 5. Adjust each row with a factor so that the first column contains all 1s.< / a >
< a name = "80" > < span class = "lineNum" > 80 < / span > : * This transformation also preserves the nonsingularity property,< / a >
< a name = "81" > < span class = "lineNum" > 81 < / span > : * maintaining the MDS code property.< / a >
< a name = "82" > < span class = "lineNum" > 82 < / span > : *< / a >
< a name = "83" > < span class = "lineNum" > 83 < / span > : * Concrete example in GF(256) for k=6, m=4:< / a >
< a name = "84" > < span class = "lineNum" > 84 < / span > : *< / a >
< a name = "85" > < span class = "lineNum" > 85 < / span > : * First, create a 3x6 Cauchy matrix using x_i = 2^-i and y_0 = 0, y_j = 2^j for j> 0:< / a >
< a name = "86" > < span class = "lineNum" > 86 < / span > : *< / a >
< a name = "87" > < span class = "lineNum" > 87 < / span > : * x = { 1, 142, 71, 173, 216, 108 }< / a >
< a name = "88" > < span class = "lineNum" > 88 < / span > : * y = { 0, 2, 4 }< / a >
< a name = "89" > < span class = "lineNum" > 89 < / span > : *< / a >
< a name = "90" > < span class = "lineNum" > 90 < / span > : * The Cauchy matrix is:< / a >
< a name = "91" > < span class = "lineNum" > 91 < / span > : *< / a >
< a name = "92" > < span class = "lineNum" > 92 < / span > : * 1 2 4 8 16 32< / a >
< a name = "93" > < span class = "lineNum" > 93 < / span > : * 244 83 78 183 118 47< / a >
< a name = "94" > < span class = "lineNum" > 94 < / span > : * 167 39 213 59 153 82< / a >
< a name = "95" > < span class = "lineNum" > 95 < / span > : *< / a >
< a name = "96" > < span class = "lineNum" > 96 < / span > : * Divide row 2 by 244 and row 3 by 167. Then extend it with a row of ones< / a >
< a name = "97" > < span class = "lineNum" > 97 < / span > : * on top, and it remains MDS. This forms the code for m=4, with RAID-6 as< / a >
< a name = "98" > < span class = "lineNum" > 98 < / span > : * a subset:< / a >
< a name = "99" > < span class = "lineNum" > 99 < / span > : *< / a >
< a name = "100" > < span class = "lineNum" > 100 < / span > : * 1 1 1 1 1 1 < / a >
< a name = "101" > < span class = "lineNum" > 101 < / span > : * 1 2 4 8 16 32< / a >
< a name = "102" > < span class = "lineNum" > 102 < / span > : * 1 245 210 196 154 113< / a >
< a name = "103" > < span class = "lineNum" > 103 < / span > : * 1 187 166 215 199 7< / a >
< a name = "104" > < span class = "lineNum" > 104 < / span > : *< / a >
< a name = "105" > < span class = "lineNum" > 105 < / span > : * Extending the same computation to k=251 and m=6 gives:< / a >
< a name = "106" > < span class = "lineNum" > 106 < / span > : *< / a >
< a name = "107" > < span class = "lineNum" > 107 < / span > : * This results in the matrix A[row, col] defined as:< / a >
< a name = "108" > < span class = "lineNum" > 108 < / span > : *< / a >
< a name = "109" > < span class = "lineNum" > 109 < / span > : * 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01...< / a >
< a name = "110" > < span class = "lineNum" > 110 < / span > : * 01 02 04 08 10 20 40 80 1d 3a 74 e8 cd 87 13 26 4c 98 2d 5a b4 75...< / a >
< a name = "111" > < span class = "lineNum" > 111 < / span > : * 01 f5 d2 c4 9a 71 f1 7f fc 87 c1 c6 19 2f 40 55 3d ba 53 04 9c 61...< / a >
< a name = "112" > < span class = "lineNum" > 112 < / span > : * 01 bb a6 d7 c7 07 ce 82 4a 2f a5 9b b6 60 f1 ad e7 f4 06 d2 df 2e...< / a >
< a name = "113" > < span class = "lineNum" > 113 < / span > : * 01 97 7f 9c 7c 18 bd a2 58 1a da 74 70 a3 e5 47 29 07 f5 80 23 e9...< / a >
< a name = "114" > < span class = "lineNum" > 114 < / span > : * 01 2b 3f cf 73 2c d6 ed cb 74 15 78 8a c1 17 c9 89 68 21 ab 76 3b...< / a >
< a name = "115" > < span class = "lineNum" > 115 < / span > : *< / a >
< a name = "116" > < span class = "lineNum" > 116 < / span > : * This matrix supports six levels of parity, one for each row, for up to 251< / a >
< a name = "117" > < span class = "lineNum" > 117 < / span > : * data disks, one for each column. All the 377,342,351,231 square submatrices< / a >
< a name = "118" > < span class = "lineNum" > 118 < / span > : * are nonsingular, verified also by brute-force testing.< / a >
< a name = "119" > < span class = "lineNum" > 119 < / span > : *< / a >
< a name = "120" > < span class = "lineNum" > 120 < / span > : * This matrix can be extended to support any number of parities by simply< / a >
< a name = "121" > < span class = "lineNum" > 121 < / span > : * adding additional rows and removing one column for each new row to maintain< / a >
< a name = "122" > < span class = "lineNum" > 122 < / span > : * the condition i + j < 255.< / a >
< a name = "123" > < span class = "lineNum" > 123 < / span > : * (See mktables.c for more details on how the matrix is generated.)< / a >
< a name = "124" > < span class = "lineNum" > 124 < / span > : *< / a >
< a name = "125" > < span class = "lineNum" > 125 < / span > : * The downside is that generic multiplications are required to compute the< / a >
< a name = "126" > < span class = "lineNum" > 126 < / span > : * parity, not only fast multiplications by 2^n or 2^-n, which negatively< / a >
< a name = "127" > < span class = "lineNum" > 127 < / span > : * affect performance. However, optimized parallel multiplications using SSSE3< / a >
< a name = "128" > < span class = "lineNum" > 128 < / span > : * or AVX2 instructions [1][5] make this approach competitive with the triple< / a >
< a name = "129" > < span class = "lineNum" > 129 < / span > : * parity computation using power coefficients.< / a >
< a name = "130" > < span class = "lineNum" > 130 < / span > : *< / a >
< a name = "131" > < span class = "lineNum" > 131 < / span > : * Another advantage of the Cauchy matrix is that the first two rows can< / a >
< a name = "132" > < span class = "lineNum" > 132 < / span > : * replicate the RAID5 and RAID6 approach, resulting in a compatible extension.< / a >
< a name = "133" > < span class = "lineNum" > 133 < / span > : * SSSE3 or AVX2 instructions are only needed for triple parity or beyond.< / a >
< a name = "134" > < span class = "lineNum" > 134 < / span > : *< / a >
< a name = "135" > < span class = "lineNum" > 135 < / span > : * Parity computation is as follows:< / a >
< a name = "136" > < span class = "lineNum" > 136 < / span > : *< / a >
< a name = "137" > < span class = "lineNum" > 137 < / span > : * P = sum(Di)< / a >
< a name = "138" > < span class = "lineNum" > 138 < / span > : * Q = sum(2^i * Di)< / a >
< a name = "139" > < span class = "lineNum" > 139 < / span > : * R = sum(A[2,i] * Di)< / a >
< a name = "140" > < span class = "lineNum" > 140 < / span > : * S = sum(A[3,i] * Di)< / a >
< a name = "141" > < span class = "lineNum" > 141 < / span > : * T = sum(A[4,i] * Di)< / a >
< a name = "142" > < span class = "lineNum" > 142 < / span > : * U = sum(A[5,i] * Di) for 0 < = i < N< / a >
< a name = "143" > < span class = "lineNum" > 143 < / span > : *< / a >
< a name = "144" > < span class = "lineNum" > 144 < / span > : * Recovery from six disk failures at indices x, y, z, h, v, w (0 < = x < y < z < h < v < w < N)< / a >
< a name = "145" > < span class = "lineNum" > 145 < / span > : * involves computing parity of the remaining N-6 disks:< / a >
< a name = "146" > < span class = "lineNum" > 146 < / span > : *< / a >
< a name = "147" > < span class = "lineNum" > 147 < / span > : * Pa = sum(Di)< / a >
< a name = "148" > < span class = "lineNum" > 148 < / span > : * Qa = sum(2^i * Di)< / a >
< a name = "149" > < span class = "lineNum" > 149 < / span > : * Ra = sum(A[2,i] * Di)< / a >
< a name = "150" > < span class = "lineNum" > 150 < / span > : * Sa = sum(A[3,i] * Di)< / a >
< a name = "151" > < span class = "lineNum" > 151 < / span > : * Ta = sum(A[4,i] * Di)< / a >
< a name = "152" > < span class = "lineNum" > 152 < / span > : * Ua = sum(A[5,i] * Di) for i != x,y,z,h,v,w< / a >
< a name = "153" > < span class = "lineNum" > 153 < / span > : *< / a >
< a name = "154" > < span class = "lineNum" > 154 < / span > : * Defining:< / a >
< a name = "155" > < span class = "lineNum" > 155 < / span > : *< / a >
< a name = "156" > < span class = "lineNum" > 156 < / span > : * Pd = Pa + P< / a >
< a name = "157" > < span class = "lineNum" > 157 < / span > : * Qd = Qa + Q< / a >
< a name = "158" > < span class = "lineNum" > 158 < / span > : * Rd = Ra + R< / a >
< a name = "159" > < span class = "lineNum" > 159 < / span > : * Sd = Sa + S< / a >
< a name = "160" > < span class = "lineNum" > 160 < / span > : * Td = Ta + T< / a >
< a name = "161" > < span class = "lineNum" > 161 < / span > : * Ud = Ua + U< / a >
< a name = "162" > < span class = "lineNum" > 162 < / span > : *< / a >
< a name = "163" > < span class = "lineNum" > 163 < / span > : * yields:< / a >
< a name = "164" > < span class = "lineNum" > 164 < / span > : *< / a >
< a name = "165" > < span class = "lineNum" > 165 < / span > : * Pd = Dx + Dy + Dz + Dh + Dv + Dw< / a >
< a name = "166" > < span class = "lineNum" > 166 < / span > : * Qd = 2^x * Dx + 2^y * Dy + 2^z * Dz + 2^h * Dh + 2^v * Dv + 2^w * Dw< / a >
< a name = "167" > < span class = "lineNum" > 167 < / span > : * Rd = A[2,x] * Dx + A[2,y] * Dy + A[2,z] * Dz + A[2,h] * Dh + A[2,v] * Dv + A[2,w] * Dw< / a >
< a name = "168" > < span class = "lineNum" > 168 < / span > : * Sd = A[3,x] * Dx + A[3,y] * Dy + A[3,z] * Dz + A[3,h] * Dh + A[3,v] * Dv + A[3,w] * Dw< / a >
< a name = "169" > < span class = "lineNum" > 169 < / span > : * Td = A[4,x] * Dx + A[4,y] * Dy + A[4,z] * Dz + A[4,h] * Dh + A[4,v] * Dv + A[4,w] * Dw< / a >
< a name = "170" > < span class = "lineNum" > 170 < / span > : * Ud = A[5,x] * Dx + A[5,y] * Dy + A[5,z] * Dz + A[5,h] * Dh + A[5,v] * Dv + A[5,w] * Dw< / a >
< a name = "171" > < span class = "lineNum" > 171 < / span > : *< / a >
< a name = "172" > < span class = "lineNum" > 172 < / span > : * This linear system is always solvable since the coefficient matrix is< / a >
< a name = "173" > < span class = "lineNum" > 173 < / span > : * nonsingular due to the properties of A[].< / a >
< a name = "174" > < span class = "lineNum" > 174 < / span > : *< / a >
< a name = "175" > < span class = "lineNum" > 175 < / span > : * Example performance on a Intel Core i7-10700 CPU @ 2.90GHz, stripe 256 KiB, 8 data disks:< / a >
< a name = "176" > < span class = "lineNum" > 176 < / span > : *< / a >
< a name = "177" > < span class = "lineNum" > 177 < / span > : * int8 int32 int64 sse2 sse2e ssse3 ssse3e avx2 avx2e< / a >
< a name = "178" > < span class = "lineNum" > 178 < / span > : * gen1 24995 46562 62683 77069< / a >
< a name = "179" > < span class = "lineNum" > 179 < / span > : * gen2 8243 15879 25788 27292 44907< / a >
< a name = "180" > < span class = "lineNum" > 180 < / span > : * genz 5509 10588 14485 13920 25175< / a >
< a name = "181" > < span class = "lineNum" > 181 < / span > : * gen3 1190 13201 14307 27268< / a >
< a name = "182" > < span class = "lineNum" > 182 < / span > : * gen4 914 10061 11006 21328< / a >
< a name = "183" > < span class = "lineNum" > 183 < / span > : * gen5 746 7970 8828 17040< / a >
< a name = "184" > < span class = "lineNum" > 184 < / span > : * gen6 630 6627 7516 14584< / a >
< a name = "185" > < span class = "lineNum" > 185 < / span > : *< / a >
< a name = "186" > < span class = "lineNum" > 186 < / span > : * Values are in MiB/s of data processed by a single thread.< / a >
< a name = "187" > < span class = "lineNum" > 187 < / span > : * Results can be reproduced using " raid/test/speedtest.c" .< / a >
< a name = "188" > < span class = "lineNum" > 188 < / span > : *< / a >
< a name = "189" > < span class = "lineNum" > 189 < / span > : * Triple parity with power coefficients " 1, 2, 2^-1" is slightly faster than< / a >
< a name = "190" > < span class = "lineNum" > 190 < / span > : * the Cauchy matrix computation if SSSE3 or AVX2 are available:< / a >
< a name = "191" > < span class = "lineNum" > 191 < / span > : *< / a >
< a name = "192" > < span class = "lineNum" > 192 < / span > : * int8 int32 int64 sse2 ssse3 avx2< / a >
< a name = "193" > < span class = "lineNum" > 193 < / span > : * genz 2337 2874 10920 18944< / a >
< a name = "194" > < span class = "lineNum" > 194 < / span > : *< / a >
< a name = "195" > < span class = "lineNum" > 195 < / span > : * In conclusion, the use of power coefficients, specifically powers< / a >
< a name = "196" > < span class = "lineNum" > 196 < / span > : * of 1, 2, and 2^-1, is the best option to implement triple parity on CPUs< / a >
< a name = "197" > < span class = "lineNum" > 197 < / span > : * without SSSE3 and AVX2.< / a >
< a name = "198" > < span class = "lineNum" > 198 < / span > : * On modern CPUs with SSSE3 or AVX2, the Cauchy matrix is the best< / a >
< a name = "199" > < span class = "lineNum" > 199 < / span > : * option because it provides a fast and general approach that works for any< / a >
< a name = "200" > < span class = "lineNum" > 200 < / span > : * number of parities.< / a >
< a name = "201" > < span class = "lineNum" > 201 < / span > : *< / a >
< a name = "202" > < span class = "lineNum" > 202 < / span > : * References:< / a >
< a name = "203" > < span class = "lineNum" > 203 < / span > : * [1] Anvin, " The mathematics of RAID-6" , 2004< / a >
< a name = "204" > < span class = "lineNum" > 204 < / span > : * [2] MacWilliams, Sloane, " The Theory of Error-Correcting Codes" , 1977< / a >
< a name = "205" > < span class = "lineNum" > 205 < / span > : * [3] Blomer, " An XOR-Based Erasure-Resilient Coding Scheme" , 1995< / a >
< a name = "206" > < span class = "lineNum" > 206 < / span > : * [4] Roth, " Introduction to Coding Theory" , 2006< / a >
< a name = "207" > < span class = "lineNum" > 207 < / span > : * [5] Plank, " Screaming Fast Galois Field Arithmetic Using Intel SIMD Instructions" , 2013< / a >
< a name = "208" > < span class = "lineNum" > 208 < / span > : */< / a >
< a name = "209" > < span class = "lineNum" > 209 < / span > : < / a >
< a name = "210" > < span class = "lineNum" > 210 < / span > : /**< / a >
< a name = "211" > < span class = "lineNum" > 211 < / span > : * Generator matrix currently used.< / a >
< a name = "212" > < span class = "lineNum" > 212 < / span > : */< / a >
< a name = "213" > < span class = "lineNum" > 213 < / span > : const uint8_t (*raid_gfgen)[256];< / a >
< a name = "214" > < span class = "lineNum" > 214 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "215" > < span class = "lineNum" > 215 < / span > < span class = "lineCov" > 593 : void raid_mode(int mode)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "216" > < span class = "lineNum" > 216 < / span > : {< / a >
2026-03-15 18:52:43 +01:00
< a name = "217" > < span class = "lineNum" > 217 < / span > < span class = "lineCov" > 593 : if (mode == RAID_MODE_VANDERMONDE) {< / span > < / a >
2026-02-28 16:47:55 +01:00
< a name = "218" > < span class = "lineNum" > 218 < / span > < span class = "lineCov" > 5 : raid_gen_ptr[2] = raid_genz_ptr;< / span > < / a >
< a name = "219" > < span class = "lineNum" > 219 < / span > < span class = "lineCov" > 5 : raid_gfgen = gfvandermonde;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "220" > < span class = "lineNum" > 220 < / span > : } else {< / a >
2026-03-15 18:52:43 +01:00
< a name = "221" > < span class = "lineNum" > 221 < / span > < span class = "lineCov" > 588 : raid_gen_ptr[2] = raid_gen3_ptr;< / span > < / a >
< a name = "222" > < span class = "lineNum" > 222 < / span > < span class = "lineCov" > 588 : raid_gfgen = gfcauchy;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "223" > < span class = "lineNum" > 223 < / span > : }< / a >
2026-03-15 18:52:43 +01:00
< a name = "224" > < span class = "lineNum" > 224 < / span > < span class = "lineCov" > 593 : }< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "225" > < span class = "lineNum" > 225 < / span > : < / a >
< a name = "226" > < span class = "lineNum" > 226 < / span > : /**< / a >
< a name = "227" > < span class = "lineNum" > 227 < / span > : * Buffer filled with 0 used in recovering.< / a >
< a name = "228" > < span class = "lineNum" > 228 < / span > : */< / a >
< a name = "229" > < span class = "lineNum" > 229 < / span > : static void *raid_zero_block;< / a >
< a name = "230" > < span class = "lineNum" > 230 < / span > : < / a >
2026-02-28 16:47:55 +01:00
< a name = "231" > < span class = "lineNum" > 231 < / span > < span class = "lineCov" > 221 : void raid_zero(void *zero)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "232" > < span class = "lineNum" > 232 < / span > : {< / a >
2026-02-28 16:47:55 +01:00
< a name = "233" > < span class = "lineNum" > 233 < / span > < span class = "lineCov" > 221 : raid_zero_block = zero;< / span > < / a >
< a name = "234" > < span class = "lineNum" > 234 < / span > < span class = "lineCov" > 221 : }< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "235" > < span class = "lineNum" > 235 < / span > : < / a >
< a name = "236" > < span class = "lineNum" > 236 < / span > : /*< / a >
< a name = "237" > < span class = "lineNum" > 237 < / span > : * Forwarders for parity computation.< / a >
< a name = "238" > < span class = "lineNum" > 238 < / span > : *< / a >
< a name = "239" > < span class = "lineNum" > 239 < / span > : * These functions compute the parity blocks from the provided data.< / a >
< a name = "240" > < span class = "lineNum" > 240 < / span > : *< / a >
< a name = "241" > < span class = "lineNum" > 241 < / span > : * The number of parities to compute is implicit in the position in the< / a >
< a name = "242" > < span class = "lineNum" > 242 < / span > : * forwarder vector. Position at index #i, computes (#i+1) parities.< / a >
< a name = "243" > < span class = "lineNum" > 243 < / span > : *< / a >
< a name = "244" > < span class = "lineNum" > 244 < / span > : * All these functions give the guarantee that parities are written< / a >
< a name = "245" > < span class = "lineNum" > 245 < / span > : * in order. First parity P, then parity Q, and so on.< / a >
< a name = "246" > < span class = "lineNum" > 246 < / span > : * This allows to specify the same memory buffer for multiple parities< / a >
< a name = "247" > < span class = "lineNum" > 247 < / span > : * knowing that you'll get the latest written one.< / a >
< a name = "248" > < span class = "lineNum" > 248 < / span > : * This characteristic is used by the raid_delta_gen() function to< / a >
< a name = "249" > < span class = "lineNum" > 249 < / span > : * avoid to damage unused parities in recovering.< / a >
< a name = "250" > < span class = "lineNum" > 250 < / span > : *< / a >
< a name = "251" > < span class = "lineNum" > 251 < / span > : * @nd Number of data blocks< / a >
< a name = "252" > < span class = "lineNum" > 252 < / span > : * @size Size of the blocks pointed by @v. It must be a multiplier of 64.< / a >
< a name = "253" > < span class = "lineNum" > 253 < / span > : * @v Vector of pointers to the blocks of data and parity.< / a >
< a name = "254" > < span class = "lineNum" > 254 < / span > : * It has (@nd + #parities) elements. The starting elements are the blocks< / a >
< a name = "255" > < span class = "lineNum" > 255 < / span > : * for data, following with the parity blocks.< / a >
< a name = "256" > < span class = "lineNum" > 256 < / span > : * Each block has @size bytes.< / a >
< a name = "257" > < span class = "lineNum" > 257 < / span > : */< / a >
< a name = "258" > < span class = "lineNum" > 258 < / span > : void (*raid_gen_ptr[RAID_PARITY_MAX])(int nd, size_t size, void **vv);< / a >
< a name = "259" > < span class = "lineNum" > 259 < / span > : void (*raid_gen3_ptr)(int nd, size_t size, void **vv);< / a >
< a name = "260" > < span class = "lineNum" > 260 < / span > : void (*raid_genz_ptr)(int nd, size_t size, void **vv);< / a >
< a name = "261" > < span class = "lineNum" > 261 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "262" > < span class = "lineNum" > 262 < / span > < span class = "lineCov" > 1286322 : void raid_gen(int nd, int np, size_t size, void **v)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "263" > < span class = "lineNum" > 263 < / span > : {< / a >
< a name = "264" > < span class = "lineNum" > 264 < / span > : /* enforce limit on size */< / a >
2026-03-15 18:52:43 +01:00
< a name = "265" > < span class = "lineNum" > 265 < / span > < span class = "lineCov" > 1286322 : BUG_ON(size % 64 != 0);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "266" > < span class = "lineNum" > 266 < / span > : < / a >
< a name = "267" > < span class = "lineNum" > 267 < / span > : /* enforce limit on number of failures */< / a >
2026-03-15 18:52:43 +01:00
< a name = "268" > < span class = "lineNum" > 268 < / span > < span class = "lineCov" > 1286322 : BUG_ON(np < 1);< / span > < / a >
< a name = "269" > < span class = "lineNum" > 269 < / span > < span class = "lineCov" > 1286322 : BUG_ON(np > RAID_PARITY_MAX);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "270" > < span class = "lineNum" > 270 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "271" > < span class = "lineNum" > 271 < / span > < span class = "lineCov" > 1286322 : raid_gen_ptr[np - 1](nd, size, v);< / span > < / a >
< a name = "272" > < span class = "lineNum" > 272 < / span > < span class = "lineCov" > 1286322 : }< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "273" > < span class = "lineNum" > 273 < / span > : < / a >
< a name = "274" > < span class = "lineNum" > 274 < / span > : /**< / a >
< a name = "275" > < span class = "lineNum" > 275 < / span > : * Inverts the square matrix M of size nxn into V.< / a >
< a name = "276" > < span class = "lineNum" > 276 < / span > : *< / a >
< a name = "277" > < span class = "lineNum" > 277 < / span > : * This is not a general matrix inversion because we assume the matrix M< / a >
< a name = "278" > < span class = "lineNum" > 278 < / span > : * to have all the square submatrix not singular.< / a >
< a name = "279" > < span class = "lineNum" > 279 < / span > : * We use Gauss elimination to invert.< / a >
< a name = "280" > < span class = "lineNum" > 280 < / span > : *< / a >
< a name = "281" > < span class = "lineNum" > 281 < / span > : * @M Matrix to invert with @n rows and @n columns.< / a >
< a name = "282" > < span class = "lineNum" > 282 < / span > : * @V Destination matrix where the result is put.< / a >
< a name = "283" > < span class = "lineNum" > 283 < / span > : * @n Number of rows and columns of the matrix.< / a >
< a name = "284" > < span class = "lineNum" > 284 < / span > : */< / a >
2026-03-15 18:52:43 +01:00
< a name = "285" > < span class = "lineNum" > 285 < / span > < span class = "lineCov" > 185482 : void raid_invert(uint8_t *M, uint8_t *V, int n)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "286" > < span class = "lineNum" > 286 < / span > : {< / a >
< a name = "287" > < span class = "lineNum" > 287 < / span > : int i, j, k;< / a >
< a name = "288" > < span class = "lineNum" > 288 < / span > : < / a >
< a name = "289" > < span class = "lineNum" > 289 < / span > : /* set the identity matrix in V */< / a >
2026-03-15 18:52:43 +01:00
< a name = "290" > < span class = "lineNum" > 290 < / span > < span class = "lineCov" > 849421 : for (i = 0; i < n; ++i)< / span > < / a >
< a name = "291" > < span class = "lineNum" > 291 < / span > < span class = "lineCov" > 3373654 : for (j = 0; j < n; ++j)< / span > < / a >
< a name = "292" > < span class = "lineNum" > 292 < / span > < span class = "lineCov" > 2709715 : V[i * n + j] = i == j;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "293" > < span class = "lineNum" > 293 < / span > : < / a >
< a name = "294" > < span class = "lineNum" > 294 < / span > : /* for each element in the diagonal */< / a >
2026-03-15 18:52:43 +01:00
< a name = "295" > < span class = "lineNum" > 295 < / span > < span class = "lineCov" > 849421 : for (k = 0; k < n; ++k) {< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "296" > < span class = "lineNum" > 296 < / span > : uint8_t f;< / a >
< a name = "297" > < span class = "lineNum" > 297 < / span > : < / a >
< a name = "298" > < span class = "lineNum" > 298 < / span > : /* the diagonal element cannot be 0 because */< / a >
< a name = "299" > < span class = "lineNum" > 299 < / span > : /* we are inverting matrices with all the square */< / a >
< a name = "300" > < span class = "lineNum" > 300 < / span > : /* submatrices not singular */< / a >
2026-03-15 18:52:43 +01:00
< a name = "301" > < span class = "lineNum" > 301 < / span > < span class = "lineCov" > 663939 : BUG_ON(M[k * n + k] == 0);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "302" > < span class = "lineNum" > 302 < / span > : < / a >
< a name = "303" > < span class = "lineNum" > 303 < / span > : /* make the diagonal element to be 1 */< / a >
2026-03-15 18:52:43 +01:00
< a name = "304" > < span class = "lineNum" > 304 < / span > < span class = "lineCov" > 663939 : f = inv(M[k * n + k]);< / span > < / a >
< a name = "305" > < span class = "lineNum" > 305 < / span > < span class = "lineCov" > 3373654 : for (j = 0; j < n; ++j) {< / span > < / a >
< a name = "306" > < span class = "lineNum" > 306 < / span > < span class = "lineCov" > 2709715 : M[k * n + j] = mul(f, M[k * n + j]);< / span > < / a >
< a name = "307" > < span class = "lineNum" > 307 < / span > < span class = "lineCov" > 5419430 : V[k * n + j] = mul(f, V[k * n + j]);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "308" > < span class = "lineNum" > 308 < / span > : }< / a >
< a name = "309" > < span class = "lineNum" > 309 < / span > : < / a >
< a name = "310" > < span class = "lineNum" > 310 < / span > : /* make all the elements over and under the diagonal */< / a >
< a name = "311" > < span class = "lineNum" > 311 < / span > : /* to be zero */< / a >
2026-03-15 18:52:43 +01:00
< a name = "312" > < span class = "lineNum" > 312 < / span > < span class = "lineCov" > 3373654 : for (i = 0; i < n; ++i) {< / span > < / a >
< a name = "313" > < span class = "lineNum" > 313 < / span > < span class = "lineCov" > 2709715 : if (i == k)< / span > < / a >
< a name = "314" > < span class = "lineNum" > 314 < / span > < span class = "lineCov" > 663939 : continue;< / span > < / a >
< a name = "315" > < span class = "lineNum" > 315 < / span > < span class = "lineCov" > 2045776 : f = M[i * n + k];< / span > < / a >
< a name = "316" > < span class = "lineNum" > 316 < / span > < span class = "lineCov" > 11569884 : for (j = 0; j < n; ++j) {< / span > < / a >
< a name = "317" > < span class = "lineNum" > 317 < / span > < span class = "lineCov" > 9524108 : M[i * n + j] ^= mul(f, M[k * n + j]);< / span > < / a >
< a name = "318" > < span class = "lineNum" > 318 < / span > < span class = "lineCov" > 19048216 : V[i * n + j] ^= mul(f, V[k * n + j]);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "319" > < span class = "lineNum" > 319 < / span > : }< / a >
< a name = "320" > < span class = "lineNum" > 320 < / span > : }< / a >
< a name = "321" > < span class = "lineNum" > 321 < / span > : }< / a >
2026-03-15 18:52:43 +01:00
< a name = "322" > < span class = "lineNum" > 322 < / span > < span class = "lineCov" > 185482 : }< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "323" > < span class = "lineNum" > 323 < / span > : < / a >
< a name = "324" > < span class = "lineNum" > 324 < / span > : /**< / a >
< a name = "325" > < span class = "lineNum" > 325 < / span > : * Computes the parity without the missing data blocks< / a >
< a name = "326" > < span class = "lineNum" > 326 < / span > : * and store it in the buffers of such data blocks.< / a >
< a name = "327" > < span class = "lineNum" > 327 < / span > : *< / a >
< a name = "328" > < span class = "lineNum" > 328 < / span > : * This is the parity expressed as Pa,Qa,Ra,Sa,Ta,Ua in the equations.< / a >
< a name = "329" > < span class = "lineNum" > 329 < / span > : */< / a >
2026-03-15 18:52:43 +01:00
< a name = "330" > < span class = "lineNum" > 330 < / span > < span class = "lineCov" > 184637 : void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "331" > < span class = "lineNum" > 331 < / span > : {< / a >
< a name = "332" > < span class = "lineNum" > 332 < / span > : void *p[RAID_PARITY_MAX];< / a >
< a name = "333" > < span class = "lineNum" > 333 < / span > : void *pa[RAID_PARITY_MAX];< / a >
< a name = "334" > < span class = "lineNum" > 334 < / span > : int i, j;< / a >
< a name = "335" > < span class = "lineNum" > 335 < / span > : int np;< / a >
< a name = "336" > < span class = "lineNum" > 336 < / span > : void *latest;< / a >
< a name = "337" > < span class = "lineNum" > 337 < / span > : < / a >
< a name = "338" > < span class = "lineNum" > 338 < / span > : /* total number of parities we are going to process */< / a >
< a name = "339" > < span class = "lineNum" > 339 < / span > : /* they are both the used and the unused ones */< / a >
2026-03-15 18:52:43 +01:00
< a name = "340" > < span class = "lineNum" > 340 < / span > < span class = "lineCov" > 184637 : np = ip[nr - 1] + 1;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "341" > < span class = "lineNum" > 341 < / span > : < / a >
< a name = "342" > < span class = "lineNum" > 342 < / span > : /* latest missing data block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "343" > < span class = "lineNum" > 343 < / span > < span class = "lineCov" > 184637 : latest = v[id[nr - 1]];< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "344" > < span class = "lineNum" > 344 < / span > : < / a >
< a name = "345" > < span class = "lineNum" > 345 < / span > : /* setup pointers for delta computation */< / a >
2026-03-15 18:52:43 +01:00
< a name = "346" > < span class = "lineNum" > 346 < / span > < span class = "lineCov" > 925349 : for (i = 0, j = 0; i < np; ++i) {< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "347" > < span class = "lineNum" > 347 < / span > : /* keep a copy of the original parity vector */< / a >
2026-03-15 18:52:43 +01:00
< a name = "348" > < span class = "lineNum" > 348 < / span > < span class = "lineCov" > 740712 : p[i] = v[nd + i];< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "349" > < span class = "lineNum" > 349 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "350" > < span class = "lineNum" > 350 < / span > < span class = "lineCov" > 740712 : if (ip[j] == i) {< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "351" > < span class = "lineNum" > 351 < / span > : /*< / a >
< a name = "352" > < span class = "lineNum" > 352 < / span > : * Set used parities to point to the missing< / a >
< a name = "353" > < span class = "lineNum" > 353 < / span > : * data blocks.< / a >
< a name = "354" > < span class = "lineNum" > 354 < / span > : *< / a >
< a name = "355" > < span class = "lineNum" > 355 < / span > : * The related data blocks are instead set< / a >
< a name = "356" > < span class = "lineNum" > 356 < / span > : * to point to the " zero" buffer.< / a >
< a name = "357" > < span class = "lineNum" > 357 < / span > : */< / a >
< a name = "358" > < span class = "lineNum" > 358 < / span > : < / a >
< a name = "359" > < span class = "lineNum" > 359 < / span > : /* the latest parity to use ends the for loop and */< / a >
< a name = "360" > < span class = "lineNum" > 360 < / span > : /* then it cannot happen to process more of them */< / a >
2026-03-15 18:52:43 +01:00
< a name = "361" > < span class = "lineNum" > 361 < / span > < span class = "lineCov" > 644420 : BUG_ON(j > = nr);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "362" > < span class = "lineNum" > 362 < / span > : < / a >
< a name = "363" > < span class = "lineNum" > 363 < / span > : /* buffer for missing data blocks */< / a >
2026-03-15 18:52:43 +01:00
< a name = "364" > < span class = "lineNum" > 364 < / span > < span class = "lineCov" > 644420 : pa[j] = v[id[j]];< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "365" > < span class = "lineNum" > 365 < / span > : < / a >
< a name = "366" > < span class = "lineNum" > 366 < / span > : /* set at zero the missing data blocks */< / a >
2026-03-15 18:52:43 +01:00
< a name = "367" > < span class = "lineNum" > 367 < / span > < span class = "lineCov" > 644420 : v[id[j]] = raid_zero_block;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "368" > < span class = "lineNum" > 368 < / span > : < / a >
< a name = "369" > < span class = "lineNum" > 369 < / span > : /* compute the parity over the missing data blocks */< / a >
2026-03-15 18:52:43 +01:00
< a name = "370" > < span class = "lineNum" > 370 < / span > < span class = "lineCov" > 644420 : v[nd + i] = pa[j];< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "371" > < span class = "lineNum" > 371 < / span > : < / a >
< a name = "372" > < span class = "lineNum" > 372 < / span > : /* check for the next used entry */< / a >
2026-03-15 18:52:43 +01:00
< a name = "373" > < span class = "lineNum" > 373 < / span > < span class = "lineCov" > 644420 : ++j;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "374" > < span class = "lineNum" > 374 < / span > : } else {< / a >
< a name = "375" > < span class = "lineNum" > 375 < / span > : /*< / a >
< a name = "376" > < span class = "lineNum" > 376 < / span > : * Unused parities are going to be rewritten with< / a >
< a name = "377" > < span class = "lineNum" > 377 < / span > : * not significative data, because we don't have< / a >
< a name = "378" > < span class = "lineNum" > 378 < / span > : * functions able to compute only a subset of< / a >
< a name = "379" > < span class = "lineNum" > 379 < / span > : * parities.< / a >
< a name = "380" > < span class = "lineNum" > 380 < / span > : *< / a >
< a name = "381" > < span class = "lineNum" > 381 < / span > : * To avoid this, we reuse parity buffers,< / a >
< a name = "382" > < span class = "lineNum" > 382 < / span > : * assuming that all the parity functions write< / a >
< a name = "383" > < span class = "lineNum" > 383 < / span > : * parities in order.< / a >
< a name = "384" > < span class = "lineNum" > 384 < / span > : *< / a >
< a name = "385" > < span class = "lineNum" > 385 < / span > : * We assign the unused parity block to the same< / a >
< a name = "386" > < span class = "lineNum" > 386 < / span > : * block of the latest used parity that we know it< / a >
< a name = "387" > < span class = "lineNum" > 387 < / span > : * will be written.< / a >
< a name = "388" > < span class = "lineNum" > 388 < / span > : *< / a >
< a name = "389" > < span class = "lineNum" > 389 < / span > : * This means that this block will be written< / a >
< a name = "390" > < span class = "lineNum" > 390 < / span > : * multiple times and only the latest write will< / a >
< a name = "391" > < span class = "lineNum" > 391 < / span > : * contain the correct data.< / a >
< a name = "392" > < span class = "lineNum" > 392 < / span > : */< / a >
2026-03-15 18:52:43 +01:00
< a name = "393" > < span class = "lineNum" > 393 < / span > < span class = "lineCov" > 96292 : v[nd + i] = latest;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "394" > < span class = "lineNum" > 394 < / span > : }< / a >
< a name = "395" > < span class = "lineNum" > 395 < / span > : }< / a >
< a name = "396" > < span class = "lineNum" > 396 < / span > : < / a >
< a name = "397" > < span class = "lineNum" > 397 < / span > : /* all the parities have to be processed */< / a >
2026-03-15 18:52:43 +01:00
< a name = "398" > < span class = "lineNum" > 398 < / span > < span class = "lineCov" > 184637 : BUG_ON(j != nr);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "399" > < span class = "lineNum" > 399 < / span > : < / a >
< a name = "400" > < span class = "lineNum" > 400 < / span > : /* recompute the parity, note that np may be smaller than the */< / a >
< a name = "401" > < span class = "lineNum" > 401 < / span > : /* total number of parities available */< / a >
2026-03-15 18:52:43 +01:00
< a name = "402" > < span class = "lineNum" > 402 < / span > < span class = "lineCov" > 184637 : raid_gen(nd, np, size, v);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "403" > < span class = "lineNum" > 403 < / span > : < / a >
< a name = "404" > < span class = "lineNum" > 404 < / span > : /* restore data buffers as before */< / a >
2026-03-15 18:52:43 +01:00
< a name = "405" > < span class = "lineNum" > 405 < / span > < span class = "lineCov" > 829057 : for (j = 0; j < nr; ++j)< / span > < / a >
< a name = "406" > < span class = "lineNum" > 406 < / span > < span class = "lineCov" > 644420 : v[id[j]] = pa[j];< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "407" > < span class = "lineNum" > 407 < / span > : < / a >
< a name = "408" > < span class = "lineNum" > 408 < / span > : /* restore parity buffers as before */< / a >
2026-03-15 18:52:43 +01:00
< a name = "409" > < span class = "lineNum" > 409 < / span > < span class = "lineCov" > 925349 : for (i = 0; i < np; ++i)< / span > < / a >
< a name = "410" > < span class = "lineNum" > 410 < / span > < span class = "lineCov" > 740712 : v[nd + i] = p[i];< / span > < / a >
< a name = "411" > < span class = "lineNum" > 411 < / span > < span class = "lineCov" > 184637 : }< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "412" > < span class = "lineNum" > 412 < / span > : < / a >
< a name = "413" > < span class = "lineNum" > 413 < / span > : /**< / a >
< a name = "414" > < span class = "lineNum" > 414 < / span > : * Recover failure of one data block for PAR1.< / a >
< a name = "415" > < span class = "lineNum" > 415 < / span > : *< / a >
< a name = "416" > < span class = "lineNum" > 416 < / span > : * Starting from the equation:< / a >
< a name = "417" > < span class = "lineNum" > 417 < / span > : *< / a >
< a name = "418" > < span class = "lineNum" > 418 < / span > : * Pd = Dx< / a >
< a name = "419" > < span class = "lineNum" > 419 < / span > : *< / a >
< a name = "420" > < span class = "lineNum" > 420 < / span > : * and solving we get:< / a >
< a name = "421" > < span class = "lineNum" > 421 < / span > : *< / a >
< a name = "422" > < span class = "lineNum" > 422 < / span > : * Dx = Pd< / a >
< a name = "423" > < span class = "lineNum" > 423 < / span > : */< / a >
2026-03-15 18:52:43 +01:00
< a name = "424" > < span class = "lineNum" > 424 < / span > < span class = "lineCov" > 96535 : void raid_rec1of1(int *id, int nd, size_t size, void **v)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "425" > < span class = "lineNum" > 425 < / span > : {< / a >
< a name = "426" > < span class = "lineNum" > 426 < / span > : void *p;< / a >
< a name = "427" > < span class = "lineNum" > 427 < / span > : void *pa;< / a >
< a name = "428" > < span class = "lineNum" > 428 < / span > : < / a >
< a name = "429" > < span class = "lineNum" > 429 < / span > : /* for PAR1 we can directly compute the missing block */< / a >
< a name = "430" > < span class = "lineNum" > 430 < / span > : /* and we don't need to use the zero buffer */< / a >
2026-03-15 18:52:43 +01:00
< a name = "431" > < span class = "lineNum" > 431 < / span > < span class = "lineCov" > 96535 : p = v[nd];< / span > < / a >
< a name = "432" > < span class = "lineNum" > 432 < / span > < span class = "lineCov" > 96535 : pa = v[id[0]];< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "433" > < span class = "lineNum" > 433 < / span > : < / a >
< a name = "434" > < span class = "lineNum" > 434 < / span > : /* use the parity as missing data block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "435" > < span class = "lineNum" > 435 < / span > < span class = "lineCov" > 96535 : v[id[0]] = p;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "436" > < span class = "lineNum" > 436 < / span > : < / a >
< a name = "437" > < span class = "lineNum" > 437 < / span > : /* compute the parity over the missing data block */< / a >
2026-03-15 18:52:43 +01:00
< a name = "438" > < span class = "lineNum" > 438 < / span > < span class = "lineCov" > 96535 : v[nd] = pa;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "439" > < span class = "lineNum" > 439 < / span > : < / a >
< a name = "440" > < span class = "lineNum" > 440 < / span > : /* compute */< / a >
2026-03-15 18:52:43 +01:00
< a name = "441" > < span class = "lineNum" > 441 < / span > < span class = "lineCov" > 96535 : raid_gen(nd, 1, size, v);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "442" > < span class = "lineNum" > 442 < / span > : < / a >
< a name = "443" > < span class = "lineNum" > 443 < / span > : /* restore as before */< / a >
2026-03-15 18:52:43 +01:00
< a name = "444" > < span class = "lineNum" > 444 < / span > < span class = "lineCov" > 96535 : v[id[0]] = pa;< / span > < / a >
< a name = "445" > < span class = "lineNum" > 445 < / span > < span class = "lineCov" > 96535 : v[nd] = p;< / span > < / a >
< a name = "446" > < span class = "lineNum" > 446 < / span > < span class = "lineCov" > 96535 : }< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "447" > < span class = "lineNum" > 447 < / span > : < / a >
< a name = "448" > < span class = "lineNum" > 448 < / span > : /**< / a >
< a name = "449" > < span class = "lineNum" > 449 < / span > : * Recover failure of two data blocks for PAR2.< / a >
< a name = "450" > < span class = "lineNum" > 450 < / span > : *< / a >
< a name = "451" > < span class = "lineNum" > 451 < / span > : * Starting from the equations:< / a >
< a name = "452" > < span class = "lineNum" > 452 < / span > : *< / a >
< a name = "453" > < span class = "lineNum" > 453 < / span > : * Pd = Dx + Dy< / a >
< a name = "454" > < span class = "lineNum" > 454 < / span > : * Qd = 2^id[0] * Dx + 2^id[1] * Dy< / a >
< a name = "455" > < span class = "lineNum" > 455 < / span > : *< / a >
< a name = "456" > < span class = "lineNum" > 456 < / span > : * and solving we get:< / a >
< a name = "457" > < span class = "lineNum" > 457 < / span > : *< / a >
< a name = "458" > < span class = "lineNum" > 458 < / span > : * 1 2^(-id[0])< / a >
< a name = "459" > < span class = "lineNum" > 459 < / span > : * Dy = ------------------- * Pd + ------------------- * Qd< / a >
< a name = "460" > < span class = "lineNum" > 460 < / span > : * 2^(id[1]-id[0]) + 1 2^(id[1]-id[0]) + 1< / a >
< a name = "461" > < span class = "lineNum" > 461 < / span > : *< / a >
< a name = "462" > < span class = "lineNum" > 462 < / span > : * Dx = Dy + Pd< / a >
< a name = "463" > < span class = "lineNum" > 463 < / span > : *< / a >
< a name = "464" > < span class = "lineNum" > 464 < / span > : * with conditions:< / a >
< a name = "465" > < span class = "lineNum" > 465 < / span > : *< / a >
< a name = "466" > < span class = "lineNum" > 466 < / span > : * 2^id[0] != 0< / a >
< a name = "467" > < span class = "lineNum" > 467 < / span > : * 2^(id[1]-id[0]) + 1 != 0< / a >
< a name = "468" > < span class = "lineNum" > 468 < / span > : *< / a >
< a name = "469" > < span class = "lineNum" > 469 < / span > : * That are always satisfied for any 0< =id[0]< id[1]< 255.< / a >
< a name = "470" > < span class = "lineNum" > 470 < / span > : */< / a >
< a name = "471" > < span class = "lineNum" > 471 < / span > < span class = "lineCov" > 132 : void raid_rec2of2_int8(int *id, int *ip, int nd, size_t size, void **vv)< / span > < / a >
< a name = "472" > < span class = "lineNum" > 472 < / span > : {< / a >
< a name = "473" > < span class = "lineNum" > 473 < / span > < span class = "lineCov" > 132 : uint8_t **v = (uint8_t **)vv;< / span > < / a >
< a name = "474" > < span class = "lineNum" > 474 < / span > : size_t i;< / a >
< a name = "475" > < span class = "lineNum" > 475 < / span > : uint8_t *p;< / a >
< a name = "476" > < span class = "lineNum" > 476 < / span > : uint8_t *pa;< / a >
< a name = "477" > < span class = "lineNum" > 477 < / span > : uint8_t *q;< / a >
< a name = "478" > < span class = "lineNum" > 478 < / span > : uint8_t *qa;< / a >
< a name = "479" > < span class = "lineNum" > 479 < / span > : const uint8_t *T[2];< / a >
< a name = "480" > < span class = "lineNum" > 480 < / span > : < / a >
< a name = "481" > < span class = "lineNum" > 481 < / span > : /* get multiplication tables */< / a >
< a name = "482" > < span class = "lineNum" > 482 < / span > < span class = "lineCov" > 396 : T[0] = table(inv(pow2(id[1] - id[0]) ^ 1));< / span > < / a >
< a name = "483" > < span class = "lineNum" > 483 < / span > < span class = "lineCov" > 528 : T[1] = table(inv(pow2(id[0]) ^ pow2(id[1])));< / span > < / a >
< a name = "484" > < span class = "lineNum" > 484 < / span > : < / a >
< a name = "485" > < span class = "lineNum" > 485 < / span > : /* compute delta parity */< / a >
< a name = "486" > < span class = "lineNum" > 486 < / span > < span class = "lineCov" > 132 : raid_delta_gen(2, id, ip, nd, size, vv);< / span > < / a >
< a name = "487" > < span class = "lineNum" > 487 < / span > : < / a >
< a name = "488" > < span class = "lineNum" > 488 < / span > < span class = "lineCov" > 132 : p = v[nd];< / span > < / a >
< a name = "489" > < span class = "lineNum" > 489 < / span > < span class = "lineCov" > 132 : q = v[nd + 1];< / span > < / a >
< a name = "490" > < span class = "lineNum" > 490 < / span > < span class = "lineCov" > 132 : pa = v[id[0]];< / span > < / a >
< a name = "491" > < span class = "lineNum" > 491 < / span > < span class = "lineCov" > 132 : qa = v[id[1]];< / span > < / a >
< a name = "492" > < span class = "lineNum" > 492 < / span > : < / a >
< a name = "493" > < span class = "lineNum" > 493 < / span > < span class = "lineCov" > 33924 : for (i = 0; i < size; ++i) {< / span > < / a >
< a name = "494" > < span class = "lineNum" > 494 < / span > : /* delta */< / a >
< a name = "495" > < span class = "lineNum" > 495 < / span > < span class = "lineCov" > 33792 : uint8_t Pd = p[i] ^ pa[i];< / span > < / a >
< a name = "496" > < span class = "lineNum" > 496 < / span > < span class = "lineCov" > 33792 : uint8_t Qd = q[i] ^ qa[i];< / span > < / a >
< a name = "497" > < span class = "lineNum" > 497 < / span > : < / a >
< a name = "498" > < span class = "lineNum" > 498 < / span > : /* reconstruct */< / a >
< a name = "499" > < span class = "lineNum" > 499 < / span > < span class = "lineCov" > 33792 : uint8_t Dy = T[0][Pd] ^ T[1][Qd];< / span > < / a >
< a name = "500" > < span class = "lineNum" > 500 < / span > < span class = "lineCov" > 33792 : uint8_t Dx = Pd ^ Dy;< / span > < / a >
< a name = "501" > < span class = "lineNum" > 501 < / span > : < / a >
< a name = "502" > < span class = "lineNum" > 502 < / span > : /* set */< / a >
< a name = "503" > < span class = "lineNum" > 503 < / span > < span class = "lineCov" > 33792 : pa[i] = Dx;< / span > < / a >
< a name = "504" > < span class = "lineNum" > 504 < / span > < span class = "lineCov" > 33792 : qa[i] = Dy;< / span > < / a >
< a name = "505" > < span class = "lineNum" > 505 < / span > : }< / a >
< a name = "506" > < span class = "lineNum" > 506 < / span > < span class = "lineCov" > 132 : }< / span > < / a >
< a name = "507" > < span class = "lineNum" > 507 < / span > : < / a >
< a name = "508" > < span class = "lineNum" > 508 < / span > : /*< / a >
< a name = "509" > < span class = "lineNum" > 509 < / span > : * Forwarders for data recovery.< / a >
< a name = "510" > < span class = "lineNum" > 510 < / span > : *< / a >
< a name = "511" > < span class = "lineNum" > 511 < / span > : * These functions recover data blocks using the specified parity< / a >
< a name = "512" > < span class = "lineNum" > 512 < / span > : * to recompute the missing data.< / a >
< a name = "513" > < span class = "lineNum" > 513 < / span > : *< / a >
< a name = "514" > < span class = "lineNum" > 514 < / span > : * Note that the format of vectors @id/@ip is different than raid_rec().< / a >
< a name = "515" > < span class = "lineNum" > 515 < / span > : * For example, in the vector @ip the first parity is represented with the< / a >
< a name = "516" > < span class = "lineNum" > 516 < / span > : * value 0 and not @nd.< / a >
< a name = "517" > < span class = "lineNum" > 517 < / span > : *< / a >
< a name = "518" > < span class = "lineNum" > 518 < / span > : * @nr Number of failed data blocks to recover.< / a >
< a name = "519" > < span class = "lineNum" > 519 < / span > : * @id[] Vector of @nr indexes of the data blocks to recover.< / a >
< a name = "520" > < span class = "lineNum" > 520 < / span > : * The indexes start from 0. They must be in order.< / a >
< a name = "521" > < span class = "lineNum" > 521 < / span > : * @ip[] Vector of @nr indexes of the parity blocks to use in the recovering.< / a >
< a name = "522" > < span class = "lineNum" > 522 < / span > : * The indexes start from 0. They must be in order.< / a >
< a name = "523" > < span class = "lineNum" > 523 < / span > : * @nd Number of data blocks.< / a >
< a name = "524" > < span class = "lineNum" > 524 < / span > : * @np Number of parity blocks.< / a >
< a name = "525" > < span class = "lineNum" > 525 < / span > : * @size Size of the blocks pointed by @v. It must be a multiplier of 64.< / a >
< a name = "526" > < span class = "lineNum" > 526 < / span > : * @v Vector of pointers to the blocks of data and parity.< / a >
< a name = "527" > < span class = "lineNum" > 527 < / span > : * It has (@nd + @np) elements. The starting elements are the blocks< / a >
< a name = "528" > < span class = "lineNum" > 528 < / span > : * for data, following with the parity blocks.< / a >
< a name = "529" > < span class = "lineNum" > 529 < / span > : * Each block has @size bytes.< / a >
< a name = "530" > < span class = "lineNum" > 530 < / span > : */< / a >
< a name = "531" > < span class = "lineNum" > 531 < / span > : void (*raid_rec_ptr[RAID_PARITY_MAX])(< / a >
< a name = "532" > < span class = "lineNum" > 532 < / span > : int nr, int *id, int *ip, int nd, size_t size, void **vv);< / a >
< a name = "533" > < span class = "lineNum" > 533 < / span > : < / a >
2026-02-28 10:26:32 +01:00
< a name = "534" > < span class = "lineNum" > 534 < / span > < span class = "lineCov" > 870 : void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "535" > < span class = "lineNum" > 535 < / span > : {< / a >
< a name = "536" > < span class = "lineNum" > 536 < / span > : int nrd; /* number of data blocks to recover */< / a >
< a name = "537" > < span class = "lineNum" > 537 < / span > : int nrp; /* number of parity blocks to recover */< / a >
< a name = "538" > < span class = "lineNum" > 538 < / span > : < / a >
< a name = "539" > < span class = "lineNum" > 539 < / span > : /* enforce limit on size */< / a >
2026-02-28 10:26:32 +01:00
< a name = "540" > < span class = "lineNum" > 540 < / span > < span class = "lineCov" > 870 : BUG_ON(size % 64 != 0);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "541" > < span class = "lineNum" > 541 < / span > : < / a >
< a name = "542" > < span class = "lineNum" > 542 < / span > : /* enforce limit on number of failures */< / a >
2026-02-28 10:26:32 +01:00
< a name = "543" > < span class = "lineNum" > 543 < / span > < span class = "lineCov" > 870 : BUG_ON(nr > np);< / span > < / a >
< a name = "544" > < span class = "lineNum" > 544 < / span > < span class = "lineCov" > 870 : BUG_ON(np > RAID_PARITY_MAX);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "545" > < span class = "lineNum" > 545 < / span > : < / a >
< a name = "546" > < span class = "lineNum" > 546 < / span > : /* enforce order in index vector */< / a >
2026-02-28 10:26:32 +01:00
< a name = "547" > < span class = "lineNum" > 547 < / span > < span class = "lineCov" > 870 : BUG_ON(nr > = 2 & & ir[0] > = ir[1]);< / span > < / a >
< a name = "548" > < span class = "lineNum" > 548 < / span > < span class = "lineCov" > 870 : BUG_ON(nr > = 3 & & ir[1] > = ir[2]);< / span > < / a >
< a name = "549" > < span class = "lineNum" > 549 < / span > < span class = "lineCov" > 870 : BUG_ON(nr > = 4 & & ir[2] > = ir[3]);< / span > < / a >
< a name = "550" > < span class = "lineNum" > 550 < / span > < span class = "lineCov" > 870 : BUG_ON(nr > = 5 & & ir[3] > = ir[4]);< / span > < / a >
< a name = "551" > < span class = "lineNum" > 551 < / span > < span class = "lineCov" > 870 : BUG_ON(nr > = 6 & & ir[4] > = ir[5]);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "552" > < span class = "lineNum" > 552 < / span > : < / a >
< a name = "553" > < span class = "lineNum" > 553 < / span > : /* enforce limit on index vector */< / a >
2026-02-28 10:26:32 +01:00
< a name = "554" > < span class = "lineNum" > 554 < / span > < span class = "lineCov" > 870 : BUG_ON(nr > 0 & & ir[nr-1] > = nd + np);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "555" > < span class = "lineNum" > 555 < / span > : < / a >
< a name = "556" > < span class = "lineNum" > 556 < / span > : /* count the number of data blocks to recover */< / a >
2026-02-28 10:26:32 +01:00
< a name = "557" > < span class = "lineNum" > 557 < / span > < span class = "lineCov" > 870 : nrd = 0;< / span > < / a >
< a name = "558" > < span class = "lineNum" > 558 < / span > < span class = "lineCov" > 2613 : while (nrd < nr & & ir[nrd] < nd)< / span > < / a >
< a name = "559" > < span class = "lineNum" > 559 < / span > < span class = "lineCov" > 1743 : ++nrd;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "560" > < span class = "lineNum" > 560 < / span > : < / a >
< a name = "561" > < span class = "lineNum" > 561 < / span > : /* all the remaining are parity */< / a >
2026-02-28 10:26:32 +01:00
< a name = "562" > < span class = "lineNum" > 562 < / span > < span class = "lineCov" > 870 : nrp = nr - nrd;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "563" > < span class = "lineNum" > 563 < / span > : < / a >
< a name = "564" > < span class = "lineNum" > 564 < / span > : /* enforce limit on number of failures */< / a >
2026-02-28 10:26:32 +01:00
< a name = "565" > < span class = "lineNum" > 565 < / span > < span class = "lineCov" > 870 : BUG_ON(nrd > nd);< / span > < / a >
< a name = "566" > < span class = "lineNum" > 566 < / span > < span class = "lineCov" > 870 : BUG_ON(nrp > np);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "567" > < span class = "lineNum" > 567 < / span > : < / a >
< a name = "568" > < span class = "lineNum" > 568 < / span > : /* if failed data is present */< / a >
2026-02-28 10:26:32 +01:00
< a name = "569" > < span class = "lineNum" > 569 < / span > < span class = "lineCov" > 870 : if (nrd != 0) {< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "570" > < span class = "lineNum" > 570 < / span > : int ip[RAID_PARITY_MAX];< / a >
< a name = "571" > < span class = "lineNum" > 571 < / span > : int i, j, k;< / a >
< a name = "572" > < span class = "lineNum" > 572 < / span > : < / a >
< a name = "573" > < span class = "lineNum" > 573 < / span > : /* setup the vector of parities to use */< / a >
2026-02-28 10:26:32 +01:00
< a name = "574" > < span class = "lineNum" > 574 < / span > < span class = "lineCov" > 6041 : for (i = 0, j = 0, k = 0; i < np; ++i) {< / span > < / a >
< a name = "575" > < span class = "lineNum" > 575 < / span > < span class = "lineCov" > 5173 : if (j < nrp & & ir[nrd + j] == nd + i) {< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "576" > < span class = "lineNum" > 576 < / span > : /* this parity has to be recovered */< / a >
< a name = "577" > < span class = "lineNum" > 577 < / span > < span class = "lineCov" > 22 : ++j;< / span > < / a >
< a name = "578" > < span class = "lineNum" > 578 < / span > : } else {< / a >
< a name = "579" > < span class = "lineNum" > 579 < / span > : /* this parity is used for recovering */< / a >
2026-02-28 10:26:32 +01:00
< a name = "580" > < span class = "lineNum" > 580 < / span > < span class = "lineCov" > 5151 : ip[k] = i;< / span > < / a >
< a name = "581" > < span class = "lineNum" > 581 < / span > < span class = "lineCov" > 5151 : ++k;< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "582" > < span class = "lineNum" > 582 < / span > : }< / a >
< a name = "583" > < span class = "lineNum" > 583 < / span > : }< / a >
< a name = "584" > < span class = "lineNum" > 584 < / span > : < / a >
< a name = "585" > < span class = "lineNum" > 585 < / span > : /* recover the nrd data blocks specified in ir[], */< / a >
< a name = "586" > < span class = "lineNum" > 586 < / span > : /* using the first nrd parity in ip[] for recovering */< / a >
2026-02-28 10:26:32 +01:00
< a name = "587" > < span class = "lineNum" > 587 < / span > < span class = "lineCov" > 868 : raid_rec_ptr[nrd - 1](nrd, ir, ip, nd, size, v);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "588" > < span class = "lineNum" > 588 < / span > : }< / a >
< a name = "589" > < span class = "lineNum" > 589 < / span > : < / a >
< a name = "590" > < span class = "lineNum" > 590 < / span > : /* recompute all the parities up to the last bad one */< / a >
2026-02-28 10:26:32 +01:00
< a name = "591" > < span class = "lineNum" > 591 < / span > < span class = "lineCov" > 870 : if (nrp != 0)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "592" > < span class = "lineNum" > 592 < / span > < span class = "lineCov" > 12 : raid_gen(nd, ir[nr - 1] - nd + 1, size, v);< / span > < / a >
2026-02-28 10:26:32 +01:00
< a name = "593" > < span class = "lineNum" > 593 < / span > < span class = "lineCov" > 870 : }< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "594" > < span class = "lineNum" > 594 < / span > : < / a >
2026-03-15 18:52:43 +01:00
< a name = "595" > < span class = "lineNum" > 595 < / span > < span class = "lineCov" > 222871 : void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "596" > < span class = "lineNum" > 596 < / span > : {< / a >
< a name = "597" > < span class = "lineNum" > 597 < / span > : /* enforce limit on size */< / a >
2026-03-15 18:52:43 +01:00
< a name = "598" > < span class = "lineNum" > 598 < / span > < span class = "lineCov" > 222871 : BUG_ON(size % 64 != 0);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "599" > < span class = "lineNum" > 599 < / span > : < / a >
< a name = "600" > < span class = "lineNum" > 600 < / span > : /* enforce limit on number of failures */< / a >
2026-03-15 18:52:43 +01:00
< a name = "601" > < span class = "lineNum" > 601 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > nd);< / span > < / a >
< a name = "602" > < span class = "lineNum" > 602 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > RAID_PARITY_MAX);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "603" > < span class = "lineNum" > 603 < / span > : < / a >
< a name = "604" > < span class = "lineNum" > 604 < / span > : /* enforce order in index vector for data */< / a >
2026-03-15 18:52:43 +01:00
< a name = "605" > < span class = "lineNum" > 605 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 2 & & id[0] > = id[1]);< / span > < / a >
< a name = "606" > < span class = "lineNum" > 606 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 3 & & id[1] > = id[2]);< / span > < / a >
< a name = "607" > < span class = "lineNum" > 607 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 4 & & id[2] > = id[3]);< / span > < / a >
< a name = "608" > < span class = "lineNum" > 608 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 5 & & id[3] > = id[4]);< / span > < / a >
< a name = "609" > < span class = "lineNum" > 609 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 6 & & id[4] > = id[5]);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "610" > < span class = "lineNum" > 610 < / span > : < / a >
< a name = "611" > < span class = "lineNum" > 611 < / span > : /* enforce limit on index vector for data */< / a >
2026-03-15 18:52:43 +01:00
< a name = "612" > < span class = "lineNum" > 612 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > 0 & & id[nr-1] > = nd);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "613" > < span class = "lineNum" > 613 < / span > : < / a >
< a name = "614" > < span class = "lineNum" > 614 < / span > : /* enforce order in index vector for parity */< / a >
2026-03-15 18:52:43 +01:00
< a name = "615" > < span class = "lineNum" > 615 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 2 & & ip[0] > = ip[1]);< / span > < / a >
< a name = "616" > < span class = "lineNum" > 616 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 3 & & ip[1] > = ip[2]);< / span > < / a >
< a name = "617" > < span class = "lineNum" > 617 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 4 & & ip[2] > = ip[3]);< / span > < / a >
< a name = "618" > < span class = "lineNum" > 618 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 5 & & ip[3] > = ip[4]);< / span > < / a >
< a name = "619" > < span class = "lineNum" > 619 < / span > < span class = "lineCov" > 222871 : BUG_ON(nr > = 6 & & ip[4] > = ip[5]);< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "620" > < span class = "lineNum" > 620 < / span > : < / a >
< a name = "621" > < span class = "lineNum" > 621 < / span > : /* if failed data is present */< / a >
2026-03-15 18:52:43 +01:00
< a name = "622" > < span class = "lineNum" > 622 < / span > < span class = "lineCov" > 222871 : if (nr != 0)< / span > < / a >
< a name = "623" > < span class = "lineNum" > 623 < / span > < span class = "lineCov" > 222869 : raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);< / span > < / a >
< a name = "624" > < span class = "lineNum" > 624 < / span > < span class = "lineCov" > 222871 : }< / span > < / a >
2025-10-28 12:01:21 +01:00
< a name = "625" > < span class = "lineNum" > 625 < / span > : < / a >
2011-03-01 22:19:30 +01:00
< / pre >
< / td >
< / tr >
< / table >
< br >
< table width = "100%" border = 0 cellspacing = 0 cellpadding = 0 >
< tr > < td class = "ruler" > < img src = "../glass.png" width = 3 height = 3 alt = "" > < / td > < / tr >
2025-10-28 12:01:21 +01:00
< tr > < td class = "versionInfo" > Generated by: < a href = "https://github.com/linux-test-project/lcov" target = "_parent" > LCOV version 1.0< / a > < / td > < / tr >
2011-03-01 22:19:30 +01:00
< / table >
< br >
< / body >
< / html >