FreeBSD ZFS
The Zettabyte File System
Data Structures | Defines | Typedefs | Functions | Variables

vdev_raidz.c File Reference

Virtual device vector for RAID-Z. More...

#include <sys/zfs_context.h>
#include <sys/spa.h>
#include <sys/vdev_impl.h>
#include <sys/zio.h>
#include <sys/zio_checksum.h>
#include <sys/fs/zfs.h>
#include <sys/fm/fs/zfs.h>
Include dependency graph for vdev_raidz.c:

Go to the source code of this file.

Data Structures

struct  raidz_col
struct  raidz_map

Defines

#define VDEV_RAIDZ_P   0
#define VDEV_RAIDZ_Q   1
#define VDEV_RAIDZ_R   2
#define VDEV_RAIDZ_MUL_2(x)   (((x) << 1) ^ (((x) & 0x80) ? 0x1d : 0))
#define VDEV_RAIDZ_MUL_4(x)   (VDEV_RAIDZ_MUL_2(VDEV_RAIDZ_MUL_2(x)))
#define VDEV_RAIDZ_64MUL_2(x, mask)
 We provide a mechanism to perform the field multiplication operation on a 64-bit value all at once rather than a byte at a time.
#define VDEV_RAIDZ_64MUL_4(x, mask)

Typedefs

typedef struct raidz_col raidz_col_t
typedef struct raidz_map raidz_map_t

Functions

static void vdev_raidz_generate_parity (raidz_map_t *rm)
 Generate RAID parity in the first virtual columns according to the number of parity columns available.
static uint8_t vdev_raidz_exp2 (uint_t a, int exp)
 Multiply a given number by 2 raised to the given power.
static void vdev_raidz_map_free (raidz_map_t *rm)
static void vdev_raidz_map_free_vsd (zio_t *zio)
static void vdev_raidz_cksum_free (void *arg, size_t ignored)
static void vdev_raidz_cksum_finish (zio_cksum_report_t *zcr, const void *good_data)
static void vdev_raidz_cksum_report (zio_t *zio, zio_cksum_report_t *zcr, void *arg)
 Invoked indirectly by zfs_ereport_start_checksum(), called below when our read operation fails completely.
static raidz_map_tvdev_raidz_map_alloc (zio_t *zio, uint64_t unit_shift, uint64_t dcols, uint64_t nparity)
 Divides the IO evenly across all child vdevs.
static void vdev_raidz_generate_parity_p (raidz_map_t *rm)
static void vdev_raidz_generate_parity_pq (raidz_map_t *rm)
static void vdev_raidz_generate_parity_pqr (raidz_map_t *rm)
static int vdev_raidz_reconstruct_p (raidz_map_t *rm, int *tgts, int ntgts)
static int vdev_raidz_reconstruct_q (raidz_map_t *rm, int *tgts, int ntgts)
static int vdev_raidz_reconstruct_pq (raidz_map_t *rm, int *tgts, int ntgts)
static void vdev_raidz_matrix_init (raidz_map_t *rm, int n, int nmap, int *map, uint8_t **rows)
static void vdev_raidz_matrix_invert (raidz_map_t *rm, int n, int nmissing, int *missing, uint8_t **rows, uint8_t **invrows, const uint8_t *used)
static void vdev_raidz_matrix_reconstruct (raidz_map_t *rm, int n, int nmissing, int *missing, uint8_t **invrows, const uint8_t *used)
static int vdev_raidz_reconstruct_general (raidz_map_t *rm, int *tgts, int ntgts)
static int vdev_raidz_reconstruct (raidz_map_t *rm, int *t, int nt)
static int vdev_raidz_open (vdev_t *vd, uint64_t *asize, uint64_t *max_asize, uint64_t *ashift)
 Called (via vector tables) by vdev_open.
static void vdev_raidz_close (vdev_t *vd)
static uint64_t vdev_raidz_asize (vdev_t *vd, uint64_t psize)
static void vdev_raidz_child_done (zio_t *zio)
 Record the completion of a column's child IO.
static int vdev_raidz_io_start (zio_t *zio)
 Start an IO operation on a RAIDZ VDev.
static void raidz_checksum_error (zio_t *zio, raidz_col_t *rc, void *bad_data)
 Report a checksum error for a child of a RAID-Z device.
static int raidz_checksum_verify (zio_t *zio)
 We keep track of whether or not there were any injected errors, so that any ereports we generate can note it.
static int raidz_parity_verify (zio_t *zio, raidz_map_t *rm)
 Generate the parity from the data columns.
static int vdev_raidz_worst_error (raidz_map_t *rm)
static int vdev_raidz_combrec (zio_t *zio, int total_errors, int data_errors)
 Iterate over all combinations of bad data and attempt a reconstruction.
static void vdev_raidz_io_done (zio_t *zio)
 Complete an IO operation on a RAIDZ VDev.
static void vdev_raidz_state_change (vdev_t *vd, int faulted, int degraded)

Variables

int vdev_raidz_default_to_general
 Force reconstruction to use the general purpose method.
static const uint8_t vdev_raidz_pow2 [256]
 Powers of 2 in the Galois field defined above.
static const uint8_t vdev_raidz_log2 [256]
 Logs of 2 in the Galois field defined above.
static const zio_vsd_ops_t vdev_raidz_vsd_ops
static uint64_t raidz_corrected [1<< VDEV_RAIDZ_MAXPARITY]
 Keep statistics on all the ways that we used parity to correct data.
vdev_ops_t vdev_raidz_ops

Detailed Description

Virtual device vector for RAID-Z.

Encoding

This vdev supports single, double, and triple parity. For single parity, we use a simple XOR of all the data columns. For double or triple parity, we use a special case of Reed-Solomon coding. This extends the technique described in "The mathematics of RAID-6" by H. Peter Anvin by drawing on the system described in "A Tutorial on Reed-Solomon Coding for Fault-Tolerance in RAID-like Systems" by James S. Plank on which the former is also based. The latter is designed to provide higher performance for writes.

Note that the Plank paper claimed to support arbitrary N+M, but was then amended six years later identifying a critical flaw that invalidates its claims. Nevertheless, the technique can be adapted to work for up to triple parity. For additional parity, the amendment "Note: Correction to the 1997 Tutorial on Reed-Solomon Coding" by James S. Plank and Ying Ding is viable, but the additional complexity means that write performance will suffer.

All of the methods above operate on a Galois field, defined over the integers mod 2^N. In our case we choose N=8 for GF(8) so that all elements can be expressed with a single byte. Briefly, the operations on the field are defined as follows:

  	(A * 2)_7 = A_6
  	(A * 2)_6 = A_5
  	(A * 2)_5 = A_4
  	(A * 2)_4 = A_3 + A_7
  	(A * 2)_3 = A_2 + A_7
  	(A * 2)_2 = A_1 + A_7
  	(A * 2)_1 = A_0
  	(A * 2)_0 = A_7
   

In C, multiplying by 2 is therefore ((a << 1) ^ ((a & 0x80) ? 0x1d : 0)). As an aside, this multiplication is derived from the error correcting primitive polynomial x^8 + x^4 + x^3 + x^2 + 1.

Observe that any number in the field (except for 0) can be expressed as a power of 2 -- a generator for the field. We store a table of the powers of 2 and logs base 2 for quick look ups, and exploit the fact that A * B can be rewritten as 2^(log_2(A) + log_2(B)) (where '+' is normal addition rather than field addition). The inverse of a field element A (A^-1) is therefore A ^ (255 - 1) = A^254.

The up-to-three parity columns, P, Q, R over several data columns, D_0, ... D_n-1, can be expressed by field operations:

  	P = D_0 + D_1 + ... + D_n-2 + D_n-1
  	Q = 2^n-1 * D_0 + 2^n-2 * D_1 + ... + 2^1 * D_n-2 + 2^0 * D_n-1
  	  = ((...((D_0) * 2 + D_1) * 2 + ...) * 2 + D_n-2) * 2 + D_n-1
  	R = 4^n-1 * D_0 + 4^n-2 * D_1 + ... + 4^1 * D_n-2 + 4^0 * D_n-1
  	  = ((...((D_0) * 4 + D_1) * 4 + ...) * 4 + D_n-2) * 4 + D_n-1
   

We chose 1, 2, and 4 as our generators because 1 corresponds to the trival XOR operation, and 2 and 4 can be computed quickly and generate linearly- independent coefficients. (There are no additional coefficients that have this property which is why the uncorrected Plank method breaks down.)

See the reconstruction code below for how P, Q and R can used individually or in concert to recover missing data columns.

Reconstruction

In the general case of reconstruction, we must solve the system of linear equations defined by the coeffecients used to generate parity as well as the contents of the data and parity disks. This can be expressed with vectors for the original data (D) and the actual data (d) and parity (p) and a matrix composed of the identity matrix (I) and a dispersal matrix (V):

              __   __                     __     __
              |     |         __     __   |  p_0  |
              |  V  |         |  D_0  |   | p_m-1 |
              |     |    x    |   :   | = |  d_0  |
              |  I  |         | D_n-1 |   |   :   |
              |     |         ~~     ~~   | d_n-1 |
              ~~   ~~                     ~~     ~~
   

I is simply a square identity matrix of size n, and V is a vandermonde matrix defined by the coeffecients we chose for the various parity columns (1, 2, 4). Note that these values were chosen both for simplicity, speedy computation as well as linear separability.

        __               __               __     __
        |   1   ..  1 1 1 |               |  p_0  |
        | 2^n-1 ..  4 2 1 |   __     __   |   :   |
        | 4^n-1 .. 16 4 1 |   |  D_0  |   | p_m-1 |
        |   1   ..  0 0 0 |   |  D_1  |   |  d_0  |
        |   0   ..  0 0 0 | x |  D_2  | = |  d_1  |
        |   :       : : : |   |   :   |   |  d_2  |
        |   0   ..  1 0 0 |   | D_n-1 |   |   :   |
        |   0   ..  0 1 0 |   ~~     ~~   |   :   |
        |   0   ..  0 0 1 |               | d_n-1 |
        ~~               ~~               ~~     ~~
   

Note that I, V, d, and p are known. To compute D, we must invert the matrix and use the known data and parity values to reconstruct the unknown data values. We begin by removing the rows in V|I and d|p that correspond to failed or missing columns; we then make V|I square (n x n) and d|p sized n by removing rows corresponding to unused parity from the bottom up to generate (V|I)' and (d|p)'. We can then generate the inverse of (V|I)' using Gauss-Jordan elimination. In the example below we use m=3 parity columns, n=8 data columns, with errors in d_1, d_2, and p_1:

             __                               __
             |  1   1   1   1   1   1   1   1  |
             | 128  64  32  16  8   4   2   1  | <-----+-+-- missing disks
             |  19 205 116  29  64  16  4   1  |      / /
             |  1   0   0   0   0   0   0   0  |     / /
             |  0   1   0   0   0   0   0   0  | <--' /
    (V|I)  = |  0   0   1   0   0   0   0   0  | <---'
             |  0   0   0   1   0   0   0   0  |
             |  0   0   0   0   1   0   0   0  |
             |  0   0   0   0   0   1   0   0  |
             |  0   0   0   0   0   0   1   0  |
             |  0   0   0   0   0   0   0   1  |
             ~~                               ~~
             __                               __
             |  1   1   1   1   1   1   1   1  |
             | 128  64  32  16  8   4   2   1  |
             |  19 205 116  29  64  16  4   1  |
             |  1   0   0   0   0   0   0   0  |
             |  0   1   0   0   0   0   0   0  |
    (V|I)' = |  0   0   1   0   0   0   0   0  |
             |  0   0   0   1   0   0   0   0  |
             |  0   0   0   0   1   0   0   0  |
             |  0   0   0   0   0   1   0   0  |
             |  0   0   0   0   0   0   1   0  |
             |  0   0   0   0   0   0   0   1  |
             ~~                               ~~
   

Here we employ Gauss-Jordan elimination to find the inverse of (V|I)'. We have carefully chosen the seed values 1, 2, and 4 to ensure that this matrix is not singular.

   __                                                                 __
   |  1   1   1   1   1   1   1   1     1   0   0   0   0   0   0   0  |
   |  19 205 116  29  64  16  4   1     0   1   0   0   0   0   0   0  |
   |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
   |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
   |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
   |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
   |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
   |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
   ~~                                                                 ~~
   __                                                                 __
   |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
   |  1   1   1   1   1   1   1   1     1   0   0   0   0   0   0   0  |
   |  19 205 116  29  64  16  4   1     0   1   0   0   0   0   0   0  |
   |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
   |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
   |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
   |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
   |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
   ~~                                                                 ~~
   __                                                                 __
   |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
   |  0   1   1   0   0   0   0   0     1   0   1   1   1   1   1   1  |
   |  0  205 116  0   0   0   0   0     0   1   19  29  64  16  4   1  |
   |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
   |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
   |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
   |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
   |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
   ~~                                                                 ~~
   __                                                                 __
   |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
   |  0   1   1   0   0   0   0   0     1   0   1   1   1   1   1   1  |
   |  0   0  185  0   0   0   0   0    205  1  222 208 141 221 201 204 |
   |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
   |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
   |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
   |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
   |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
   ~~                                                                 ~~
   __                                                                 __
   |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
   |  0   1   1   0   0   0   0   0     1   0   1   1   1   1   1   1  |
   |  0   0   1   0   0   0   0   0    166 100  4   40 158 168 216 209 |
   |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
   |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
   |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
   |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
   |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
   ~~                                                                 ~~
   __                                                                 __
   |  1   0   0   0   0   0   0   0     0   0   1   0   0   0   0   0  |
   |  0   1   0   0   0   0   0   0    167 100  5   41 159 169 217 208 |
   |  0   0   1   0   0   0   0   0    166 100  4   40 158 168 216 209 |
   |  0   0   0   1   0   0   0   0     0   0   0   1   0   0   0   0  |
   |  0   0   0   0   1   0   0   0     0   0   0   0   1   0   0   0  |
   |  0   0   0   0   0   1   0   0     0   0   0   0   0   1   0   0  |
   |  0   0   0   0   0   0   1   0     0   0   0   0   0   0   1   0  |
   |  0   0   0   0   0   0   0   1     0   0   0   0   0   0   0   1  |
   ~~                                                                 ~~
                     __                               __
                     |  0   0   1   0   0   0   0   0  |
                     | 167 100  5   41 159 169 217 208 |
                     | 166 100  4   40 158 168 216 209 |
         (V|I)'^-1 = |  0   0   0   1   0   0   0   0  |
                     |  0   0   0   0   1   0   0   0  |
                     |  0   0   0   0   0   1   0   0  |
                     |  0   0   0   0   0   0   1   0  |
                     |  0   0   0   0   0   0   0   1  |
                     ~~                               ~~
   

We can then simply compute D = (V|I)'^-1 x (d|p)' to discover the values of the missing data.

As is apparent from the example above, the only non-trivial rows in the inverse matrix correspond to the data disks that we're trying to reconstruct. Indeed, those are the only rows we need as the others would only be useful for reconstructing data known or assumed to be valid. For that reason, we only build the coefficients in the rows that correspond to targeted columns.

Definition in file vdev_raidz.c.


Define Documentation

#define VDEV_RAIDZ_64MUL_2 (   x,
  mask 
)
Value:
{ \
        (mask) = (x) & 0x8080808080808080ULL; \
        (mask) = ((mask) << 1) - ((mask) >> 7); \
        (x) = (((x) << 1) & 0xfefefefefefefefeULL) ^ \
            ((mask) & 0x1d1d1d1d1d1d1d1d); \
}

We provide a mechanism to perform the field multiplication operation on a 64-bit value all at once rather than a byte at a time.

This works by creating a mask from the top bit in each byte and using that to conditionally apply the XOR of 0x1d.

Definition at line 149 of file vdev_raidz.c.

#define VDEV_RAIDZ_64MUL_4 (   x,
  mask 
)
Value:
{ \
        VDEV_RAIDZ_64MUL_2((x), mask); \
        VDEV_RAIDZ_64MUL_2((x), mask); \
}

Definition at line 157 of file vdev_raidz.c.

#define VDEV_RAIDZ_MUL_2 (   x)    (((x) << 1) ^ (((x) & 0x80) ? 0x1d : 0))

Definition at line 140 of file vdev_raidz.c.

#define VDEV_RAIDZ_MUL_4 (   x)    (VDEV_RAIDZ_MUL_2(VDEV_RAIDZ_MUL_2(x)))

Definition at line 141 of file vdev_raidz.c.

#define VDEV_RAIDZ_P   0

Definition at line 136 of file vdev_raidz.c.

#define VDEV_RAIDZ_Q   1

Definition at line 137 of file vdev_raidz.c.

#define VDEV_RAIDZ_R   2

Definition at line 138 of file vdev_raidz.c.


Typedef Documentation

typedef struct raidz_col raidz_col_t
typedef struct raidz_map raidz_map_t

Function Documentation

static void raidz_checksum_error ( zio_t zio,
raidz_col_t rc,
void *  bad_data 
) [static]

Report a checksum error for a child of a RAID-Z device.

Definition at line 1678 of file vdev_raidz.c.

static int raidz_checksum_verify ( zio_t zio) [static]

We keep track of whether or not there were any injected errors, so that any ereports we generate can note it.

Definition at line 1704 of file vdev_raidz.c.

static int raidz_parity_verify ( zio_t zio,
raidz_map_t rm 
) [static]

Generate the parity from the data columns.

If we tried and were able to read the parity without error, verify that the generated parity matches the data we read. If it doesn't, we fire off a checksum error. Return the number such failures.

Definition at line 1723 of file vdev_raidz.c.

static uint64_t vdev_raidz_asize ( vdev_t vd,
uint64_t  psize 
) [static]

Definition at line 1531 of file vdev_raidz.c.

static void vdev_raidz_child_done ( zio_t zio) [static]

Record the completion of a column's child IO.

Definition at line 1549 of file vdev_raidz.c.

static void vdev_raidz_cksum_finish ( zio_cksum_report_t zcr,
const void *  good_data 
) [static]

Definition at line 311 of file vdev_raidz.c.

static void vdev_raidz_cksum_free ( void *  arg,
size_t  ignored 
) [static]

Definition at line 300 of file vdev_raidz.c.

static void vdev_raidz_cksum_report ( zio_t zio,
zio_cksum_report_t zcr,
void *  arg 
) [static]

Invoked indirectly by zfs_ereport_start_checksum(), called below when our read operation fails completely.

The main point is to keep a copy of everything we read from disk, so that at vdev_raidz_cksum_finish() time we can compare it with the good data.

Definition at line 390 of file vdev_raidz.c.

static void vdev_raidz_close ( vdev_t vd) [static]

Definition at line 1522 of file vdev_raidz.c.

static int vdev_raidz_combrec ( zio_t zio,
int  total_errors,
int  data_errors 
) [static]

Iterate over all combinations of bad data and attempt a reconstruction.

Note that the algorithm below is non-optimal because it doesn't take into account how reconstruction is actually performed. For example, with triple-parity RAID-Z the reconstruction procedure is the same if column 4 is targeted as invalid as if columns 1 and 4 are targeted since in both cases we'd only use parity information in column 0.

Definition at line 1779 of file vdev_raidz.c.

static uint8_t vdev_raidz_exp2 ( uint_t  a,
int  exp 
) [static]

Multiply a given number by 2 raised to the given power.

Definition at line 245 of file vdev_raidz.c.

static void vdev_raidz_generate_parity ( raidz_map_t rm) [static]

Generate RAID parity in the first virtual columns according to the number of parity columns available.

Definition at line 720 of file vdev_raidz.c.

static void vdev_raidz_generate_parity_p ( raidz_map_t rm) [static]

Definition at line 576 of file vdev_raidz.c.

static void vdev_raidz_generate_parity_pq ( raidz_map_t rm) [static]

Definition at line 603 of file vdev_raidz.c.

static void vdev_raidz_generate_parity_pqr ( raidz_map_t rm) [static]

Definition at line 655 of file vdev_raidz.c.

static void vdev_raidz_io_done ( zio_t zio) [static]

Complete an IO operation on a RAIDZ VDev.

Outline:

  • For write ops:
    1. Check for errors on the child IOs.
    2. Return, setting an error code if too few child VDevs were written to reconstruct the data later.
  • For read ops:
    1. Check for errors on the child IOs.
    2. If data errors occurred:
      1. Try to reassemble the data from the parity available.
      2. If we haven't yet read the parity drives, read them now.
      3. If all parity drives have been read but the data still doesn't reassemble with a correct checksum, then try combinatorial reconstruction.
      4. If that doesn't work, return an error.
    3. If there were unexpected errors or this is a resilver operation, rewrite the vdevs that had errors.

Todo:
For now, treat partial writes as a success. (If we couldn't write enough columns to reconstruct the data, the I/O failed. Otherwise, good enough.) Now that we support write reallocation, it would be better to treat partial failure as real failure unless there are no non-degraded top-level vdevs left, and not update DTLs if we intend to reallocate.

Definition at line 1947 of file vdev_raidz.c.

static int vdev_raidz_io_start ( zio_t zio) [static]

Start an IO operation on a RAIDZ VDev.

Outline:

  • For Write operations:
    1. Generate the parity data
    2. Send async write operations to each column (data and parity)'s VDev
    3. If the column skips any sectors for padding, generate dummy write operations for those areas to improve aggregation continuity.
  • For read operations:
    1. Send an async read operation to each data column's VDev to read the range of data required for zio.
    2. If this is a scrub or resilver operation, or if any of the data vdevs have had errors, then send async read operations to the parity columns' VDevs as well.

Definition at line 1575 of file vdev_raidz.c.

static raidz_map_t* vdev_raidz_map_alloc ( zio_t zio,
uint64_t  unit_shift,
uint64_t  dcols,
uint64_t  nparity 
) [static]

Divides the IO evenly across all child vdevs.

Parameters:
[in]dcolsUsually, the number of children in the target vdev

Definition at line 447 of file vdev_raidz.c.

static void vdev_raidz_map_free ( raidz_map_t rm) [static]

Definition at line 261 of file vdev_raidz.c.

static void vdev_raidz_map_free_vsd ( zio_t zio) [static]

Definition at line 287 of file vdev_raidz.c.

static void vdev_raidz_matrix_init ( raidz_map_t rm,
int  n,
int  nmap,
int *  map,
uint8_t **  rows 
) [static]

Definition at line 1090 of file vdev_raidz.c.

static void vdev_raidz_matrix_invert ( raidz_map_t rm,
int  n,
int  nmissing,
int *  missing,
uint8_t **  rows,
uint8_t **  invrows,
const uint8_t *  used 
) [static]

Definition at line 1120 of file vdev_raidz.c.

static void vdev_raidz_matrix_reconstruct ( raidz_map_t rm,
int  n,
int  nmissing,
int *  missing,
uint8_t **  invrows,
const uint8_t *  used 
) [static]

Definition at line 1214 of file vdev_raidz.c.

static int vdev_raidz_open ( vdev_t vd,
uint64_t *  asize,
uint64_t *  max_asize,
uint64_t *  ashift 
) [static]

Called (via vector tables) by vdev_open.

Definition at line 1477 of file vdev_raidz.c.

static int vdev_raidz_reconstruct ( raidz_map_t rm,
int *  t,
int  nt 
) [static]

Definition at line 1395 of file vdev_raidz.c.

static int vdev_raidz_reconstruct_general ( raidz_map_t rm,
int *  tgts,
int  ntgts 
) [static]

Definition at line 1289 of file vdev_raidz.c.

static int vdev_raidz_reconstruct_p ( raidz_map_t rm,
int *  tgts,
int  ntgts 
) [static]

Definition at line 738 of file vdev_raidz.c.

static int vdev_raidz_reconstruct_pq ( raidz_map_t rm,
int *  tgts,
int  ntgts 
) [static]

Definition at line 835 of file vdev_raidz.c.

static int vdev_raidz_reconstruct_q ( raidz_map_t rm,
int *  tgts,
int  ntgts 
) [static]

Definition at line 777 of file vdev_raidz.c.

static void vdev_raidz_state_change ( vdev_t vd,
int  faulted,
int  degraded 
) [static]

Definition at line 2213 of file vdev_raidz.c.

static int vdev_raidz_worst_error ( raidz_map_t rm) [static]

Definition at line 1760 of file vdev_raidz.c.


Variable Documentation

uint64_t raidz_corrected[1<< VDEV_RAIDZ_MAXPARITY] [static]

Keep statistics on all the ways that we used parity to correct data.

Definition at line 1757 of file vdev_raidz.c.

Force reconstruction to use the general purpose method.

Definition at line 166 of file vdev_raidz.c.

const uint8_t vdev_raidz_log2[256] [static]

Logs of 2 in the Galois field defined above.

Definition at line 204 of file vdev_raidz.c.

Initial value:

Definition at line 2224 of file vdev_raidz.c.

const uint8_t vdev_raidz_pow2[256] [static]

Powers of 2 in the Galois field defined above.

Definition at line 169 of file vdev_raidz.c.

Initial value:

Definition at line 436 of file vdev_raidz.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines