mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Uses a more general interface for the RAID engine.
This commit is contained in:
parent
684edf2173
commit
e80a5e868f
5 changed files with 108 additions and 56 deletions
4
check.c
4
check.c
|
|
@ -199,7 +199,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
memcpy(buffer[diskmax+ip[i]], buffer_recov[ip[i]], state->block_size);
|
||||
|
||||
/* recover using one less parity, the ip[r-1] one */
|
||||
raid_rec(r-1, id, ip, diskmax, state->block_size, buffer);
|
||||
raid_rec_dataonly(r-1, id, ip, diskmax, state->block_size, buffer);
|
||||
|
||||
/* use the remaining ip[r-1] parity to check the result */
|
||||
if (is_parity_matching(state, diskmax, ip[r-1], buffer, buffer_recov))
|
||||
|
|
@ -239,7 +239,7 @@ static int repair_step(struct snapraid_state* state, int rehash, unsigned pos, u
|
|||
memcpy(buffer[diskmax+ip[i]], buffer_recov[ip[i]], state->block_size);
|
||||
|
||||
/* recover */
|
||||
raid_rec(r, id, ip, diskmax, state->block_size, buffer);
|
||||
raid_rec_dataonly(r, id, ip, diskmax, state->block_size, buffer);
|
||||
|
||||
/* use the hash to check the result */
|
||||
if (is_hash_matching(state, rehash, diskmax, failed, failed_map, failed_count, buffer, buffer_zero))
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ void raid_par2_int64(int nd, size_t size, void **vv)
|
|||
/*
|
||||
* PAR3 (triple parity with Cauchy matrix) 8bit C implementation
|
||||
*
|
||||
* Note that instead of a generic multiplicationt table, likely resulting
|
||||
* Note that instead of a generic multiplication table, likely resulting
|
||||
* in multiple cache misses, a precomputed table could be used.
|
||||
* But this is only a kind of reference function, and we are not really
|
||||
* interested in speed.
|
||||
|
|
@ -210,7 +210,7 @@ void raid_par3_int8(int nd, size_t size, void **vv)
|
|||
/*
|
||||
* PAR4 (quad parity with Cauchy matrix) 8bit C implementation
|
||||
*
|
||||
* Note that instead of a generic multiplicationt table, likely resulting
|
||||
* Note that instead of a generic multiplication table, likely resulting
|
||||
* in multiple cache misses, a precomputed table could be used.
|
||||
* But this is only a kind of reference function, and we are not really
|
||||
* interested in speed.
|
||||
|
|
@ -262,7 +262,7 @@ void raid_par4_int8(int nd, size_t size, void **vv)
|
|||
/*
|
||||
* PAR5 (penta parity with Cauchy matrix) 8bit C implementation
|
||||
*
|
||||
* Note that instead of a generic multiplicationt table, likely resulting
|
||||
* Note that instead of a generic multiplication table, likely resulting
|
||||
* in multiple cache misses, a precomputed table could be used.
|
||||
* But this is only a kind of reference function, and we are not really
|
||||
* interested in speed.
|
||||
|
|
@ -319,7 +319,7 @@ void raid_par5_int8(int nd, size_t size, void **vv)
|
|||
/*
|
||||
* PAR6 (hexa parity with Cauchy matrix) 8bit C implementation
|
||||
*
|
||||
* Note that instead of a generic multiplicationt table, likely resulting
|
||||
* Note that instead of a generic multiplication table, likely resulting
|
||||
* in multiple cache misses, a precomputed table could be used.
|
||||
* But this is only a kind of reference function, and we are not really
|
||||
* interested in speed.
|
||||
|
|
|
|||
70
raid/raid.c
70
raid/raid.c
|
|
@ -212,11 +212,21 @@ void raid_mode(int mode)
|
|||
/**
|
||||
* Buffer filled with 0 used in recovering.
|
||||
*/
|
||||
static void *raid_empty_zero_block;
|
||||
static void *raid_zero_block;
|
||||
|
||||
void raid_zero(void *zero)
|
||||
{
|
||||
raid_empty_zero_block = zero;
|
||||
raid_zero_block = zero;
|
||||
}
|
||||
|
||||
/**
|
||||
* Buffer for raid_rec_dataonly().
|
||||
*/
|
||||
static void *raid_waste_block;
|
||||
|
||||
void raid_waste(void *waste)
|
||||
{
|
||||
raid_waste_block = waste;
|
||||
}
|
||||
|
||||
/* internal forwarder */
|
||||
|
|
@ -298,7 +308,7 @@ void raid_delta_gen(int nr, const int *id, const int *ip, int nd, size_t size, v
|
|||
pa[i] = v[id[i]];
|
||||
|
||||
/* set at zero the missing data blocks */
|
||||
v[id[i]] = raid_empty_zero_block;
|
||||
v[id[i]] = raid_zero_block;
|
||||
|
||||
/* compute the parity over the missing data blocks */
|
||||
v[nd+ip[i]] = pa[i];
|
||||
|
|
@ -414,17 +424,7 @@ void raid_rec2_par2(const int *id, const int *ip, int nd, size_t size, void **vv
|
|||
/* internal forwarder */
|
||||
void (*raid_rec_ptr[RAID_PARITY_MAX])(int nr, const int *id, const int *ip, int nd, size_t size, void **vv);
|
||||
|
||||
void raid_rec(int nr, const int *id, const int *ip, int nd, size_t size, void **v)
|
||||
{
|
||||
BUG_ON(nr > nd);
|
||||
BUG_ON(size % 64 != 0);
|
||||
|
||||
/* if failed data is present */
|
||||
if (nr != 0)
|
||||
raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
|
||||
}
|
||||
|
||||
void raid_recpar(int nrd, const int *id, int nrp, int *ip, int np, int nd, size_t size, void **v)
|
||||
void raid_rec(int nrd, const int *id, int nrp, int *ip, int np, int nd, size_t size, void **v)
|
||||
{
|
||||
BUG_ON(nrd > nd);
|
||||
BUG_ON(nrd + nrp > np);
|
||||
|
|
@ -438,8 +438,10 @@ void raid_recpar(int nrd, const int *id, int nrp, int *ip, int np, int nd, size_
|
|||
/* setup the vector of parities to use */
|
||||
for (i = 0, j = 0, k = 0; i < np; ++i) {
|
||||
if (ip[j] == i) {
|
||||
/* this parity has to be recovered */
|
||||
++j;
|
||||
} else {
|
||||
/* this parity is used for recovering */
|
||||
iu[k] = i;
|
||||
++k;
|
||||
}
|
||||
|
|
@ -454,3 +456,43 @@ void raid_recpar(int nrd, const int *id, int nrp, int *ip, int np, int nd, size_
|
|||
raid_par(ip[nrp - 1] + 1, nd, size, v);
|
||||
}
|
||||
|
||||
void raid_rec_dataonly(int nr, const int *id, const int *ip, int nd, size_t size, void **v)
|
||||
{
|
||||
BUG_ON(nr > nd);
|
||||
BUG_ON(size % 64 != 0);
|
||||
|
||||
/* if failed data is present */
|
||||
if (nr != 0) {
|
||||
/* if there is a waste buffer, use it to save unused parities */
|
||||
if (raid_waste_block != 0) {
|
||||
void * p[RAID_PARITY_MAX];
|
||||
int i, j;
|
||||
int np;
|
||||
|
||||
/* number of parities used */
|
||||
np = ip[nr - 1] + 1;
|
||||
|
||||
/* set unused parities to the waste buffer */
|
||||
for (i = 0, j = 0; i < np; ++i) {
|
||||
p[i] = v[nd+i];
|
||||
|
||||
if (ip[j] == i) {
|
||||
/* this parity is used for recovering */
|
||||
++j;
|
||||
} else {
|
||||
/* this parity is not used */
|
||||
v[nd+i] = raid_waste_block;
|
||||
}
|
||||
}
|
||||
|
||||
raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
|
||||
|
||||
/* restore pointers */
|
||||
for (i = 0; i < np; ++i)
|
||||
v[nd+i] = p[i];
|
||||
} else {
|
||||
raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
78
raid/raid.h
78
raid/raid.h
|
|
@ -67,11 +67,17 @@ void raid_mode(int mode);
|
|||
/**
|
||||
* Sets the zero buffer to use in recovering.
|
||||
*
|
||||
* Before calling raid_rec() and raid_recpar() you must provide a memory
|
||||
* Before calling raid_rec_dataonly() and raid_recpar() you must provide a memory
|
||||
* buffer filled with zero with the same size of the blocks to recover.
|
||||
*/
|
||||
void raid_zero(void *zero);
|
||||
|
||||
/**
|
||||
* Sets an additional buffer used by raid_rec_dataonly() to avoid to overwrite
|
||||
* unused parities.
|
||||
*/
|
||||
void raid_waste(void *zero);
|
||||
|
||||
/**
|
||||
* Computes the parity.
|
||||
*
|
||||
|
|
@ -86,10 +92,42 @@ void raid_zero(void *zero);
|
|||
void raid_par(int np, int nd, size_t size, void **vv);
|
||||
|
||||
/**
|
||||
* Recovers failures of data disks using the specified parities.
|
||||
* Recovers failures of data and parity blocks.
|
||||
*
|
||||
* Only the data blocks are recovered. The parity buffers are destroyed.
|
||||
* If you want also to recompute parities, you can use raid_recpar().
|
||||
* All the data and parity blocks marked as bad in the ::id and ::ip vector
|
||||
* are recovered and recomputed.
|
||||
*
|
||||
* The parities blocks to use for recoverign are automatically selected from
|
||||
* the ones NOT present in the ::ip vector.
|
||||
*
|
||||
* Ensure to have ::nrd + ::nrp <= ::np, otherwise recovering is not possible.
|
||||
*
|
||||
* \param nrd Number of failed data disks to recover.
|
||||
* \param id[] Vector of ::nrd indexes of the data disks to recover.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* \param nrp Number of failed parity disks to recover.
|
||||
* \param ip[] Vector of ::nrp indexes of the parity disks to recover.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* All the parities not specified here are assumed correct, and they are
|
||||
* not recomputed.
|
||||
* \param np Number of parity disks.
|
||||
* \param nd Number of data disks.
|
||||
* \param size Size of the blocks pointed by vv. It must be a multipler of 64.
|
||||
* \param vv Vector of pointers to the blocks for disks and parities.
|
||||
* It has (::nd + ::np) elements. The first elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
* Each blocks has ::size bytes.
|
||||
*/
|
||||
void raid_rec(int nrd, const int *id, int nrp, int *ip, int np, int nd, size_t size, void **vv);
|
||||
|
||||
/**
|
||||
* Recovers failures of data blocks using the specified parities.
|
||||
*
|
||||
* The data blocks marked as bad in the ::id vector are recovered.
|
||||
*
|
||||
* If you have provided an additional buffer with raid_waste(), the
|
||||
* parity blocks are not modified. Without this buffer, the content of
|
||||
* parities blocks not specified in the ::ip vector will be destroyed.
|
||||
*
|
||||
* \param nr Number of failed data disks to recover.
|
||||
* \param id[] Vector of ::nr indexes of the data disks to recover.
|
||||
|
|
@ -103,35 +141,7 @@ void raid_par(int np, int nd, size_t size, void **vv);
|
|||
* blocks for data, following with the parity blocks.
|
||||
* Each blocks has ::size bytes.
|
||||
*/
|
||||
void raid_rec(int nr, const int *id, const int *ip, int nd, size_t size, void **vv);
|
||||
|
||||
/**
|
||||
* Recovers failures of data and parity disks.
|
||||
*
|
||||
* It's similar at raid_rec() but it also recovers parities.
|
||||
*
|
||||
* In case there are more parities available than needed, ones to use are
|
||||
* automatically selected, excluding the ones specified in the ::ip vector.
|
||||
*
|
||||
* Ensure to have ::nrd + ::nrp <= ::np, otherwise recovering is not possible.
|
||||
*
|
||||
* \param nrd Number of failed data disks to recover.
|
||||
* \param id[] Vector of ::nrd indexes of the data disks to recover.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* \param nrp Number of failed parity disks to recover.
|
||||
* \param ip[] Vector of ::nrp indexes of the parity disks to recover.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* Note that as difference than raid_rec() these are the failed parities.
|
||||
* All the parities not specified here are assumed correct, and they are
|
||||
* not recomputed.
|
||||
* \param np Number of parity disks.
|
||||
* \param nd Number of data disks.
|
||||
* \param size Size of the blocks pointed by vv. It must be a multipler of 64.
|
||||
* \param vv Vector of pointers to the blocks for disks and parities.
|
||||
* It has (::nd + ::np) elements. The first elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
* Each blocks has ::size bytes.
|
||||
*/
|
||||
void raid_recpar(int nrd, const int *id, int nrp, int *ip, int np, int nd, size_t size, void **vv);
|
||||
void raid_rec_dataonly(int nr, const int *id, const int *ip, int nd, size_t size, void **vv);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
4
speed.c
4
speed.c
|
|
@ -591,7 +591,7 @@ void speed(void)
|
|||
|
||||
SPEED_START {
|
||||
for(j=0;j<nd;++j) {
|
||||
/* +1 to avoid PAR1 optimized case */
|
||||
/* +1 to avoid PAR2 optimized case */
|
||||
raid_rec2_int8(2, id, ip + 1, nd, block_size, buffer);
|
||||
}
|
||||
} SPEED_STOP
|
||||
|
|
@ -603,7 +603,7 @@ void speed(void)
|
|||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for(j=0;j<nd;++j) {
|
||||
/* +1 to avoid PAR1 optimized case */
|
||||
/* +1 to avoid PAR2 optimized case */
|
||||
raid_rec2_ssse3(2, id, ip + 1, nd, block_size, buffer);
|
||||
}
|
||||
} SPEED_STOP
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue