Distributed Spare (dRAID) Feature

This patch adds a new top-level vdev type called dRAID, which stands
for Distributed parity RAID.  This pool configuration allows all dRAID
vdevs to participate when rebuilding to a distributed hot spare device.
This can substantially reduce the total time required to restore full
parity to pool with a failed device.

A dRAID pool can be created using the new top-level `draid` type.
Like `raidz`, the desired redundancy is specified after the type:
`draid[1,2,3]`.  No additional information is required to create the
pool and reasonable default values will be chosen based on the number
of child vdevs in the dRAID vdev.

    zpool create <pool> draid[1,2,3] <vdevs...>

Unlike raidz, additional optional dRAID configuration values can be
provided as part of the draid type as colon separated values. This
allows administrators to fully specify a layout for either performance
or capacity reasons.  The supported options include:

    zpool create <pool> \
        draid[<parity>][:<data>d][:<children>c][:<spares>s] \
        <vdevs...>

    - draid[parity]       - Parity level (default 1)
    - draid[:<data>d]     - Data devices per group (default 8)
    - draid[:<children>c] - Expected number of child vdevs
    - draid[:<spares>s]   - Distributed hot spares (default 0)

Abbreviated example `zpool status` output for a 68 disk dRAID pool
with two distributed spares using special allocation classes.

```
  pool: tank
 state: ONLINE
config:

    NAME                  STATE     READ WRITE CKSUM
    slag7                 ONLINE       0     0     0
      draid2:8d:68c:2s-0  ONLINE       0     0     0
        L0                ONLINE       0     0     0
        L1                ONLINE       0     0     0
        ...
        U25               ONLINE       0     0     0
        U26               ONLINE       0     0     0
        spare-53          ONLINE       0     0     0
          U27             ONLINE       0     0     0
          draid2-0-0      ONLINE       0     0     0
        U28               ONLINE       0     0     0
        U29               ONLINE       0     0     0
        ...
        U42               ONLINE       0     0     0
        U43               ONLINE       0     0     0
    special
      mirror-1            ONLINE       0     0     0
        L5                ONLINE       0     0     0
        U5                ONLINE       0     0     0
      mirror-2            ONLINE       0     0     0
        L6                ONLINE       0     0     0
        U6                ONLINE       0     0     0
    spares
      draid2-0-0          INUSE     currently in use
      draid2-0-1          AVAIL
```

When adding test coverage for the new dRAID vdev type the following
options were added to the ztest command.  These options are leverages
by zloop.sh to test a wide range of dRAID configurations.

    -K draid|raidz|random - kind of RAID to test
    -D <value>            - dRAID data drives per group
    -S <value>            - dRAID distributed hot spares
    -R <value>            - RAID parity (raidz or dRAID)

The zpool_create, zpool_import, redundancy, replacement and fault
test groups have all been updated provide test coverage for the
dRAID feature.

Co-authored-by: Isaac Huang <he.huang@intel.com>
Co-authored-by: Mark Maybee <mmaybee@cray.com>
Co-authored-by: Don Brady <don.brady@delphix.com>
Co-authored-by: Matthew Ahrens <mahrens@delphix.com>
Co-authored-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Mark Maybee <mmaybee@cray.com>
Reviewed-by: Matt Ahrens <matt@delphix.com>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #10102
This commit is contained in:
Brian Behlendorf
2020-11-13 13:51:51 -08:00
committed by GitHub
parent a724db0374
commit b2255edcc0
153 changed files with 10203 additions and 1882 deletions
+169 -144
View File
@@ -26,6 +26,7 @@
#define _VDEV_RAIDZ_MATH_IMPL_H
#include <sys/types.h>
#include <sys/vdev_raidz_impl.h>
#define raidz_inline inline __attribute__((always_inline))
#ifndef noinline
@@ -36,33 +37,33 @@
* Functions calculate multiplication constants for data reconstruction.
* Coefficients depend on RAIDZ geometry, indexes of failed child vdevs, and
* used parity columns for reconstruction.
* @rm RAIDZ map
* @rr RAIDZ row
* @tgtidx array of missing data indexes
* @coeff output array of coefficients. Array must be provided by
* user and must hold minimum MUL_CNT values.
*/
static noinline void
raidz_rec_q_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
raidz_rec_q_coeff(const raidz_row_t *rr, const int *tgtidx, unsigned *coeff)
{
const unsigned ncols = raidz_ncols(rm);
const unsigned ncols = rr->rr_cols;
const unsigned x = tgtidx[TARGET_X];
coeff[MUL_Q_X] = gf_exp2(255 - (ncols - x - 1));
}
static noinline void
raidz_rec_r_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
raidz_rec_r_coeff(const raidz_row_t *rr, const int *tgtidx, unsigned *coeff)
{
const unsigned ncols = raidz_ncols(rm);
const unsigned ncols = rr->rr_cols;
const unsigned x = tgtidx[TARGET_X];
coeff[MUL_R_X] = gf_exp4(255 - (ncols - x - 1));
}
static noinline void
raidz_rec_pq_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
raidz_rec_pq_coeff(const raidz_row_t *rr, const int *tgtidx, unsigned *coeff)
{
const unsigned ncols = raidz_ncols(rm);
const unsigned ncols = rr->rr_cols;
const unsigned x = tgtidx[TARGET_X];
const unsigned y = tgtidx[TARGET_Y];
gf_t a, b, e;
@@ -76,9 +77,9 @@ raidz_rec_pq_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
}
static noinline void
raidz_rec_pr_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
raidz_rec_pr_coeff(const raidz_row_t *rr, const int *tgtidx, unsigned *coeff)
{
const unsigned ncols = raidz_ncols(rm);
const unsigned ncols = rr->rr_cols;
const unsigned x = tgtidx[TARGET_X];
const unsigned y = tgtidx[TARGET_Y];
@@ -93,9 +94,9 @@ raidz_rec_pr_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
}
static noinline void
raidz_rec_qr_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
raidz_rec_qr_coeff(const raidz_row_t *rr, const int *tgtidx, unsigned *coeff)
{
const unsigned ncols = raidz_ncols(rm);
const unsigned ncols = rr->rr_cols;
const unsigned x = tgtidx[TARGET_X];
const unsigned y = tgtidx[TARGET_Y];
@@ -114,9 +115,9 @@ raidz_rec_qr_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
}
static noinline void
raidz_rec_pqr_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
raidz_rec_pqr_coeff(const raidz_row_t *rr, const int *tgtidx, unsigned *coeff)
{
const unsigned ncols = raidz_ncols(rm);
const unsigned ncols = rr->rr_cols;
const unsigned x = tgtidx[TARGET_X];
const unsigned y = tgtidx[TARGET_Y];
const unsigned z = tgtidx[TARGET_Z];
@@ -347,26 +348,26 @@ raidz_mul_abd_cb(void *dc, size_t size, void *private)
/*
* Generate P parity (RAIDZ1)
*
* @rm RAIDZ map
* @rr RAIDZ row
*/
static raidz_inline void
raidz_generate_p_impl(raidz_map_t * const rm)
raidz_generate_p_impl(raidz_row_t * const rr)
{
size_t c;
const size_t ncols = raidz_ncols(rm);
const size_t psize = rm->rm_col[CODE_P].rc_size;
abd_t *pabd = rm->rm_col[CODE_P].rc_abd;
const size_t ncols = rr->rr_cols;
const size_t psize = rr->rr_col[CODE_P].rc_size;
abd_t *pabd = rr->rr_col[CODE_P].rc_abd;
size_t size;
abd_t *dabd;
raidz_math_begin();
/* start with first data column */
raidz_copy(pabd, rm->rm_col[1].rc_abd, psize);
raidz_copy(pabd, rr->rr_col[1].rc_abd, psize);
for (c = 2; c < ncols; c++) {
dabd = rm->rm_col[c].rc_abd;
size = rm->rm_col[c].rc_size;
dabd = rr->rr_col[c].rc_abd;
size = rr->rr_col[c].rc_size;
/* add data column */
raidz_add(pabd, dabd, size);
@@ -414,29 +415,29 @@ raidz_gen_pq_add(void **c, const void *dc, const size_t csize,
/*
* Generate PQ parity (RAIDZ2)
*
* @rm RAIDZ map
* @rr RAIDZ row
*/
static raidz_inline void
raidz_generate_pq_impl(raidz_map_t * const rm)
raidz_generate_pq_impl(raidz_row_t * const rr)
{
size_t c;
const size_t ncols = raidz_ncols(rm);
const size_t csize = rm->rm_col[CODE_P].rc_size;
const size_t ncols = rr->rr_cols;
const size_t csize = rr->rr_col[CODE_P].rc_size;
size_t dsize;
abd_t *dabd;
abd_t *cabds[] = {
rm->rm_col[CODE_P].rc_abd,
rm->rm_col[CODE_Q].rc_abd
rr->rr_col[CODE_P].rc_abd,
rr->rr_col[CODE_Q].rc_abd
};
raidz_math_begin();
raidz_copy(cabds[CODE_P], rm->rm_col[2].rc_abd, csize);
raidz_copy(cabds[CODE_Q], rm->rm_col[2].rc_abd, csize);
raidz_copy(cabds[CODE_P], rr->rr_col[2].rc_abd, csize);
raidz_copy(cabds[CODE_Q], rr->rr_col[2].rc_abd, csize);
for (c = 3; c < ncols; c++) {
dabd = rm->rm_col[c].rc_abd;
dsize = rm->rm_col[c].rc_size;
dabd = rr->rr_col[c].rc_abd;
dsize = rr->rr_col[c].rc_size;
abd_raidz_gen_iterate(cabds, dabd, csize, dsize, 2,
raidz_gen_pq_add);
@@ -487,31 +488,31 @@ raidz_gen_pqr_add(void **c, const void *dc, const size_t csize,
/*
* Generate PQR parity (RAIDZ2)
*
* @rm RAIDZ map
* @rr RAIDZ row
*/
static raidz_inline void
raidz_generate_pqr_impl(raidz_map_t * const rm)
raidz_generate_pqr_impl(raidz_row_t * const rr)
{
size_t c;
const size_t ncols = raidz_ncols(rm);
const size_t csize = rm->rm_col[CODE_P].rc_size;
const size_t ncols = rr->rr_cols;
const size_t csize = rr->rr_col[CODE_P].rc_size;
size_t dsize;
abd_t *dabd;
abd_t *cabds[] = {
rm->rm_col[CODE_P].rc_abd,
rm->rm_col[CODE_Q].rc_abd,
rm->rm_col[CODE_R].rc_abd
rr->rr_col[CODE_P].rc_abd,
rr->rr_col[CODE_Q].rc_abd,
rr->rr_col[CODE_R].rc_abd
};
raidz_math_begin();
raidz_copy(cabds[CODE_P], rm->rm_col[3].rc_abd, csize);
raidz_copy(cabds[CODE_Q], rm->rm_col[3].rc_abd, csize);
raidz_copy(cabds[CODE_R], rm->rm_col[3].rc_abd, csize);
raidz_copy(cabds[CODE_P], rr->rr_col[3].rc_abd, csize);
raidz_copy(cabds[CODE_Q], rr->rr_col[3].rc_abd, csize);
raidz_copy(cabds[CODE_R], rr->rr_col[3].rc_abd, csize);
for (c = 4; c < ncols; c++) {
dabd = rm->rm_col[c].rc_abd;
dsize = rm->rm_col[c].rc_size;
dabd = rr->rr_col[c].rc_abd;
dsize = rr->rr_col[c].rc_size;
abd_raidz_gen_iterate(cabds, dabd, csize, dsize, 3,
raidz_gen_pqr_add);
@@ -579,33 +580,36 @@ raidz_generate_pqr_impl(raidz_map_t * const rm)
* @syn_method raidz_add_abd()
* @rec_method not applicable
*
* @rm RAIDZ map
* @rr RAIDZ row
* @tgtidx array of missing data indexes
*/
static raidz_inline int
raidz_reconstruct_p_impl(raidz_map_t *rm, const int *tgtidx)
raidz_reconstruct_p_impl(raidz_row_t *rr, const int *tgtidx)
{
size_t c;
const size_t firstdc = raidz_parity(rm);
const size_t ncols = raidz_ncols(rm);
const size_t firstdc = rr->rr_firstdatacol;
const size_t ncols = rr->rr_cols;
const size_t x = tgtidx[TARGET_X];
const size_t xsize = rm->rm_col[x].rc_size;
abd_t *xabd = rm->rm_col[x].rc_abd;
const size_t xsize = rr->rr_col[x].rc_size;
abd_t *xabd = rr->rr_col[x].rc_abd;
size_t size;
abd_t *dabd;
if (xabd == NULL)
return (1 << CODE_P);
raidz_math_begin();
/* copy P into target */
raidz_copy(xabd, rm->rm_col[CODE_P].rc_abd, xsize);
raidz_copy(xabd, rr->rr_col[CODE_P].rc_abd, xsize);
/* generate p_syndrome */
for (c = firstdc; c < ncols; c++) {
if (c == x)
continue;
dabd = rm->rm_col[c].rc_abd;
size = MIN(rm->rm_col[c].rc_size, xsize);
dabd = rr->rr_col[c].rc_abd;
size = MIN(rr->rr_col[c].rc_size, xsize);
raidz_add(xabd, dabd, size);
}
@@ -653,30 +657,33 @@ raidz_syn_q_abd(void **xc, const void *dc, const size_t xsize,
* @syn_method raidz_add_abd()
* @rec_method raidz_mul_abd_cb()
*
* @rm RAIDZ map
* @rr RAIDZ row
* @tgtidx array of missing data indexes
*/
static raidz_inline int
raidz_reconstruct_q_impl(raidz_map_t *rm, const int *tgtidx)
raidz_reconstruct_q_impl(raidz_row_t *rr, const int *tgtidx)
{
size_t c;
size_t dsize;
abd_t *dabd;
const size_t firstdc = raidz_parity(rm);
const size_t ncols = raidz_ncols(rm);
const size_t firstdc = rr->rr_firstdatacol;
const size_t ncols = rr->rr_cols;
const size_t x = tgtidx[TARGET_X];
abd_t *xabd = rm->rm_col[x].rc_abd;
const size_t xsize = rm->rm_col[x].rc_size;
abd_t *xabd = rr->rr_col[x].rc_abd;
const size_t xsize = rr->rr_col[x].rc_size;
abd_t *tabds[] = { xabd };
if (xabd == NULL)
return (1 << CODE_Q);
unsigned coeff[MUL_CNT];
raidz_rec_q_coeff(rm, tgtidx, coeff);
raidz_rec_q_coeff(rr, tgtidx, coeff);
raidz_math_begin();
/* Start with first data column if present */
if (firstdc != x) {
raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(xabd, rr->rr_col[firstdc].rc_abd, xsize);
} else {
raidz_zero(xabd, xsize);
}
@@ -687,8 +694,8 @@ raidz_reconstruct_q_impl(raidz_map_t *rm, const int *tgtidx)
dabd = NULL;
dsize = 0;
} else {
dabd = rm->rm_col[c].rc_abd;
dsize = rm->rm_col[c].rc_size;
dabd = rr->rr_col[c].rc_abd;
dsize = rr->rr_col[c].rc_size;
}
abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 1,
@@ -696,7 +703,7 @@ raidz_reconstruct_q_impl(raidz_map_t *rm, const int *tgtidx)
}
/* add Q to the syndrome */
raidz_add(xabd, rm->rm_col[CODE_Q].rc_abd, xsize);
raidz_add(xabd, rr->rr_col[CODE_Q].rc_abd, xsize);
/* transform the syndrome */
abd_iterate_func(xabd, 0, xsize, raidz_mul_abd_cb, (void*) coeff);
@@ -744,30 +751,33 @@ raidz_syn_r_abd(void **xc, const void *dc, const size_t tsize,
* @syn_method raidz_add_abd()
* @rec_method raidz_mul_abd_cb()
*
* @rm RAIDZ map
* @rr RAIDZ rr
* @tgtidx array of missing data indexes
*/
static raidz_inline int
raidz_reconstruct_r_impl(raidz_map_t *rm, const int *tgtidx)
raidz_reconstruct_r_impl(raidz_row_t *rr, const int *tgtidx)
{
size_t c;
size_t dsize;
abd_t *dabd;
const size_t firstdc = raidz_parity(rm);
const size_t ncols = raidz_ncols(rm);
const size_t firstdc = rr->rr_firstdatacol;
const size_t ncols = rr->rr_cols;
const size_t x = tgtidx[TARGET_X];
const size_t xsize = rm->rm_col[x].rc_size;
abd_t *xabd = rm->rm_col[x].rc_abd;
const size_t xsize = rr->rr_col[x].rc_size;
abd_t *xabd = rr->rr_col[x].rc_abd;
abd_t *tabds[] = { xabd };
if (xabd == NULL)
return (1 << CODE_R);
unsigned coeff[MUL_CNT];
raidz_rec_r_coeff(rm, tgtidx, coeff);
raidz_rec_r_coeff(rr, tgtidx, coeff);
raidz_math_begin();
/* Start with first data column if present */
if (firstdc != x) {
raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(xabd, rr->rr_col[firstdc].rc_abd, xsize);
} else {
raidz_zero(xabd, xsize);
}
@@ -779,8 +789,8 @@ raidz_reconstruct_r_impl(raidz_map_t *rm, const int *tgtidx)
dabd = NULL;
dsize = 0;
} else {
dabd = rm->rm_col[c].rc_abd;
dsize = rm->rm_col[c].rc_size;
dabd = rr->rr_col[c].rc_abd;
dsize = rr->rr_col[c].rc_size;
}
abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 1,
@@ -788,7 +798,7 @@ raidz_reconstruct_r_impl(raidz_map_t *rm, const int *tgtidx)
}
/* add R to the syndrome */
raidz_add(xabd, rm->rm_col[CODE_R].rc_abd, xsize);
raidz_add(xabd, rr->rr_col[CODE_R].rc_abd, xsize);
/* transform the syndrome */
abd_iterate_func(xabd, 0, xsize, raidz_mul_abd_cb, (void *)coeff);
@@ -881,31 +891,34 @@ raidz_rec_pq_abd(void **tc, const size_t tsize, void **c,
* @syn_method raidz_syn_pq_abd()
* @rec_method raidz_rec_pq_abd()
*
* @rm RAIDZ map
* @rr RAIDZ row
* @tgtidx array of missing data indexes
*/
static raidz_inline int
raidz_reconstruct_pq_impl(raidz_map_t *rm, const int *tgtidx)
raidz_reconstruct_pq_impl(raidz_row_t *rr, const int *tgtidx)
{
size_t c;
size_t dsize;
abd_t *dabd;
const size_t firstdc = raidz_parity(rm);
const size_t ncols = raidz_ncols(rm);
const size_t firstdc = rr->rr_firstdatacol;
const size_t ncols = rr->rr_cols;
const size_t x = tgtidx[TARGET_X];
const size_t y = tgtidx[TARGET_Y];
const size_t xsize = rm->rm_col[x].rc_size;
const size_t ysize = rm->rm_col[y].rc_size;
abd_t *xabd = rm->rm_col[x].rc_abd;
abd_t *yabd = rm->rm_col[y].rc_abd;
const size_t xsize = rr->rr_col[x].rc_size;
const size_t ysize = rr->rr_col[y].rc_size;
abd_t *xabd = rr->rr_col[x].rc_abd;
abd_t *yabd = rr->rr_col[y].rc_abd;
abd_t *tabds[2] = { xabd, yabd };
abd_t *cabds[] = {
rm->rm_col[CODE_P].rc_abd,
rm->rm_col[CODE_Q].rc_abd
rr->rr_col[CODE_P].rc_abd,
rr->rr_col[CODE_Q].rc_abd
};
if (xabd == NULL)
return ((1 << CODE_P) | (1 << CODE_Q));
unsigned coeff[MUL_CNT];
raidz_rec_pq_coeff(rm, tgtidx, coeff);
raidz_rec_pq_coeff(rr, tgtidx, coeff);
/*
* Check if some of targets is shorter then others
@@ -921,8 +934,8 @@ raidz_reconstruct_pq_impl(raidz_map_t *rm, const int *tgtidx)
/* Start with first data column if present */
if (firstdc != x) {
raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(yabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(xabd, rr->rr_col[firstdc].rc_abd, xsize);
raidz_copy(yabd, rr->rr_col[firstdc].rc_abd, xsize);
} else {
raidz_zero(xabd, xsize);
raidz_zero(yabd, xsize);
@@ -934,8 +947,8 @@ raidz_reconstruct_pq_impl(raidz_map_t *rm, const int *tgtidx)
dabd = NULL;
dsize = 0;
} else {
dabd = rm->rm_col[c].rc_abd;
dsize = rm->rm_col[c].rc_size;
dabd = rr->rr_col[c].rc_abd;
dsize = rr->rr_col[c].rc_size;
}
abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 2,
@@ -946,7 +959,7 @@ raidz_reconstruct_pq_impl(raidz_map_t *rm, const int *tgtidx)
/* Copy shorter targets back to the original abd buffer */
if (ysize < xsize)
raidz_copy(rm->rm_col[y].rc_abd, yabd, ysize);
raidz_copy(rr->rr_col[y].rc_abd, yabd, ysize);
raidz_math_end();
@@ -1038,30 +1051,34 @@ raidz_rec_pr_abd(void **t, const size_t tsize, void **c,
* @syn_method raidz_syn_pr_abd()
* @rec_method raidz_rec_pr_abd()
*
* @rm RAIDZ map
* @rr RAIDZ row
* @tgtidx array of missing data indexes
*/
static raidz_inline int
raidz_reconstruct_pr_impl(raidz_map_t *rm, const int *tgtidx)
raidz_reconstruct_pr_impl(raidz_row_t *rr, const int *tgtidx)
{
size_t c;
size_t dsize;
abd_t *dabd;
const size_t firstdc = raidz_parity(rm);
const size_t ncols = raidz_ncols(rm);
const size_t firstdc = rr->rr_firstdatacol;
const size_t ncols = rr->rr_cols;
const size_t x = tgtidx[0];
const size_t y = tgtidx[1];
const size_t xsize = rm->rm_col[x].rc_size;
const size_t ysize = rm->rm_col[y].rc_size;
abd_t *xabd = rm->rm_col[x].rc_abd;
abd_t *yabd = rm->rm_col[y].rc_abd;
const size_t xsize = rr->rr_col[x].rc_size;
const size_t ysize = rr->rr_col[y].rc_size;
abd_t *xabd = rr->rr_col[x].rc_abd;
abd_t *yabd = rr->rr_col[y].rc_abd;
abd_t *tabds[2] = { xabd, yabd };
abd_t *cabds[] = {
rm->rm_col[CODE_P].rc_abd,
rm->rm_col[CODE_R].rc_abd
rr->rr_col[CODE_P].rc_abd,
rr->rr_col[CODE_R].rc_abd
};
if (xabd == NULL)
return ((1 << CODE_P) | (1 << CODE_R));
unsigned coeff[MUL_CNT];
raidz_rec_pr_coeff(rm, tgtidx, coeff);
raidz_rec_pr_coeff(rr, tgtidx, coeff);
/*
* Check if some of targets are shorter then others.
@@ -1077,8 +1094,8 @@ raidz_reconstruct_pr_impl(raidz_map_t *rm, const int *tgtidx)
/* Start with first data column if present */
if (firstdc != x) {
raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(yabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(xabd, rr->rr_col[firstdc].rc_abd, xsize);
raidz_copy(yabd, rr->rr_col[firstdc].rc_abd, xsize);
} else {
raidz_zero(xabd, xsize);
raidz_zero(yabd, xsize);
@@ -1090,8 +1107,8 @@ raidz_reconstruct_pr_impl(raidz_map_t *rm, const int *tgtidx)
dabd = NULL;
dsize = 0;
} else {
dabd = rm->rm_col[c].rc_abd;
dsize = rm->rm_col[c].rc_size;
dabd = rr->rr_col[c].rc_abd;
dsize = rr->rr_col[c].rc_size;
}
abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 2,
@@ -1104,14 +1121,14 @@ raidz_reconstruct_pr_impl(raidz_map_t *rm, const int *tgtidx)
* Copy shorter targets back to the original abd buffer
*/
if (ysize < xsize)
raidz_copy(rm->rm_col[y].rc_abd, yabd, ysize);
raidz_copy(rr->rr_col[y].rc_abd, yabd, ysize);
raidz_math_end();
if (ysize < xsize)
abd_free(yabd);
return ((1 << CODE_P) | (1 << CODE_Q));
return ((1 << CODE_P) | (1 << CODE_R));
}
@@ -1201,30 +1218,34 @@ raidz_rec_qr_abd(void **t, const size_t tsize, void **c,
* @syn_method raidz_syn_qr_abd()
* @rec_method raidz_rec_qr_abd()
*
* @rm RAIDZ map
* @rr RAIDZ row
* @tgtidx array of missing data indexes
*/
static raidz_inline int
raidz_reconstruct_qr_impl(raidz_map_t *rm, const int *tgtidx)
raidz_reconstruct_qr_impl(raidz_row_t *rr, const int *tgtidx)
{
size_t c;
size_t dsize;
abd_t *dabd;
const size_t firstdc = raidz_parity(rm);
const size_t ncols = raidz_ncols(rm);
const size_t firstdc = rr->rr_firstdatacol;
const size_t ncols = rr->rr_cols;
const size_t x = tgtidx[TARGET_X];
const size_t y = tgtidx[TARGET_Y];
const size_t xsize = rm->rm_col[x].rc_size;
const size_t ysize = rm->rm_col[y].rc_size;
abd_t *xabd = rm->rm_col[x].rc_abd;
abd_t *yabd = rm->rm_col[y].rc_abd;
const size_t xsize = rr->rr_col[x].rc_size;
const size_t ysize = rr->rr_col[y].rc_size;
abd_t *xabd = rr->rr_col[x].rc_abd;
abd_t *yabd = rr->rr_col[y].rc_abd;
abd_t *tabds[2] = { xabd, yabd };
abd_t *cabds[] = {
rm->rm_col[CODE_Q].rc_abd,
rm->rm_col[CODE_R].rc_abd
rr->rr_col[CODE_Q].rc_abd,
rr->rr_col[CODE_R].rc_abd
};
if (xabd == NULL)
return ((1 << CODE_Q) | (1 << CODE_R));
unsigned coeff[MUL_CNT];
raidz_rec_qr_coeff(rm, tgtidx, coeff);
raidz_rec_qr_coeff(rr, tgtidx, coeff);
/*
* Check if some of targets is shorter then others
@@ -1240,8 +1261,8 @@ raidz_reconstruct_qr_impl(raidz_map_t *rm, const int *tgtidx)
/* Start with first data column if present */
if (firstdc != x) {
raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(yabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(xabd, rr->rr_col[firstdc].rc_abd, xsize);
raidz_copy(yabd, rr->rr_col[firstdc].rc_abd, xsize);
} else {
raidz_zero(xabd, xsize);
raidz_zero(yabd, xsize);
@@ -1253,8 +1274,8 @@ raidz_reconstruct_qr_impl(raidz_map_t *rm, const int *tgtidx)
dabd = NULL;
dsize = 0;
} else {
dabd = rm->rm_col[c].rc_abd;
dsize = rm->rm_col[c].rc_size;
dabd = rr->rr_col[c].rc_abd;
dsize = rr->rr_col[c].rc_size;
}
abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 2,
@@ -1267,7 +1288,7 @@ raidz_reconstruct_qr_impl(raidz_map_t *rm, const int *tgtidx)
* Copy shorter targets back to the original abd buffer
*/
if (ysize < xsize)
raidz_copy(rm->rm_col[y].rc_abd, yabd, ysize);
raidz_copy(rr->rr_col[y].rc_abd, yabd, ysize);
raidz_math_end();
@@ -1384,34 +1405,38 @@ raidz_rec_pqr_abd(void **t, const size_t tsize, void **c,
* @syn_method raidz_syn_pqr_abd()
* @rec_method raidz_rec_pqr_abd()
*
* @rm RAIDZ map
* @rr RAIDZ row
* @tgtidx array of missing data indexes
*/
static raidz_inline int
raidz_reconstruct_pqr_impl(raidz_map_t *rm, const int *tgtidx)
raidz_reconstruct_pqr_impl(raidz_row_t *rr, const int *tgtidx)
{
size_t c;
size_t dsize;
abd_t *dabd;
const size_t firstdc = raidz_parity(rm);
const size_t ncols = raidz_ncols(rm);
const size_t firstdc = rr->rr_firstdatacol;
const size_t ncols = rr->rr_cols;
const size_t x = tgtidx[TARGET_X];
const size_t y = tgtidx[TARGET_Y];
const size_t z = tgtidx[TARGET_Z];
const size_t xsize = rm->rm_col[x].rc_size;
const size_t ysize = rm->rm_col[y].rc_size;
const size_t zsize = rm->rm_col[z].rc_size;
abd_t *xabd = rm->rm_col[x].rc_abd;
abd_t *yabd = rm->rm_col[y].rc_abd;
abd_t *zabd = rm->rm_col[z].rc_abd;
const size_t xsize = rr->rr_col[x].rc_size;
const size_t ysize = rr->rr_col[y].rc_size;
const size_t zsize = rr->rr_col[z].rc_size;
abd_t *xabd = rr->rr_col[x].rc_abd;
abd_t *yabd = rr->rr_col[y].rc_abd;
abd_t *zabd = rr->rr_col[z].rc_abd;
abd_t *tabds[] = { xabd, yabd, zabd };
abd_t *cabds[] = {
rm->rm_col[CODE_P].rc_abd,
rm->rm_col[CODE_Q].rc_abd,
rm->rm_col[CODE_R].rc_abd
rr->rr_col[CODE_P].rc_abd,
rr->rr_col[CODE_Q].rc_abd,
rr->rr_col[CODE_R].rc_abd
};
if (xabd == NULL)
return ((1 << CODE_P) | (1 << CODE_Q) | (1 << CODE_R));
unsigned coeff[MUL_CNT];
raidz_rec_pqr_coeff(rm, tgtidx, coeff);
raidz_rec_pqr_coeff(rr, tgtidx, coeff);
/*
* Check if some of targets is shorter then others
@@ -1431,9 +1456,9 @@ raidz_reconstruct_pqr_impl(raidz_map_t *rm, const int *tgtidx)
/* Start with first data column if present */
if (firstdc != x) {
raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(yabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(zabd, rm->rm_col[firstdc].rc_abd, xsize);
raidz_copy(xabd, rr->rr_col[firstdc].rc_abd, xsize);
raidz_copy(yabd, rr->rr_col[firstdc].rc_abd, xsize);
raidz_copy(zabd, rr->rr_col[firstdc].rc_abd, xsize);
} else {
raidz_zero(xabd, xsize);
raidz_zero(yabd, xsize);
@@ -1446,8 +1471,8 @@ raidz_reconstruct_pqr_impl(raidz_map_t *rm, const int *tgtidx)
dabd = NULL;
dsize = 0;
} else {
dabd = rm->rm_col[c].rc_abd;
dsize = rm->rm_col[c].rc_size;
dabd = rr->rr_col[c].rc_abd;
dsize = rr->rr_col[c].rc_size;
}
abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 3,
@@ -1460,9 +1485,9 @@ raidz_reconstruct_pqr_impl(raidz_map_t *rm, const int *tgtidx)
* Copy shorter targets back to the original abd buffer
*/
if (ysize < xsize)
raidz_copy(rm->rm_col[y].rc_abd, yabd, ysize);
raidz_copy(rr->rr_col[y].rc_abd, yabd, ysize);
if (zsize < xsize)
raidz_copy(rm->rm_col[z].rc_abd, zabd, zsize);
raidz_copy(rr->rr_col[z].rc_abd, zabd, zsize);
raidz_math_end();