mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Eliminate raid_delta_gen and convert int/neon32 REC1/REC2 to single-pass fused recovery
This commit is contained in:
parent
0ce89aa35d
commit
ec1daddc8e
13 changed files with 70 additions and 429 deletions
98
raid/raid.c
98
raid/raid.c
|
|
@ -279,104 +279,6 @@ void raid_invert(uint8_t *M, uint8_t *V, int n)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the parity without the missing data blocks
|
||||
* and store it in the buffers of such data blocks.
|
||||
*
|
||||
* This is the parity expressed as Pa,Qa,Ra,Sa,Ta,Ua in the equations.
|
||||
*/
|
||||
void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v)
|
||||
{
|
||||
void *p[RAID_PARITY_MAX];
|
||||
void *pa[RAID_PARITY_MAX];
|
||||
int i, j;
|
||||
int np;
|
||||
void *latest;
|
||||
|
||||
/* zero buffer must be initialized prior to delta recovery */
|
||||
BUG_ON(raid_zero_block == 0);
|
||||
|
||||
/*
|
||||
* Total number of parities we are going to process
|
||||
* they are both the used and the unused ones
|
||||
*/
|
||||
np = ip[nr - 1] + 1;
|
||||
|
||||
/* latest missing data block */
|
||||
latest = v[id[nr - 1]];
|
||||
|
||||
/* setup pointers for delta computation */
|
||||
for (i = 0, j = 0; i < np; ++i) {
|
||||
/* keep a copy of the original parity vector */
|
||||
p[i] = v[nd + i];
|
||||
|
||||
if (ip[j] == i) {
|
||||
/*
|
||||
* Set used parities to point to the missing
|
||||
* data blocks.
|
||||
*
|
||||
* The related data blocks are instead set
|
||||
* to point to the "zero" buffer.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The latest parity to use ends the for loop and
|
||||
* then it cannot happen to process more of them
|
||||
*/
|
||||
BUG_ON(j >= nr);
|
||||
|
||||
/* buffer for missing data blocks */
|
||||
pa[j] = v[id[j]];
|
||||
|
||||
/* set at zero the missing data blocks */
|
||||
v[id[j]] = raid_zero_block;
|
||||
|
||||
/* compute the parity over the missing data blocks */
|
||||
v[nd + i] = pa[j];
|
||||
|
||||
/* check for the next used entry */
|
||||
++j;
|
||||
} else {
|
||||
/*
|
||||
* Unused parities are going to be rewritten with
|
||||
* not significant data, because we don't have
|
||||
* functions able to compute only a subset of
|
||||
* parities.
|
||||
*
|
||||
* To avoid this, we reuse parity buffers,
|
||||
* assuming that all the parity functions write
|
||||
* parities in order.
|
||||
*
|
||||
* We assign the unused parity block to the same
|
||||
* block of the latest used parity that we know it
|
||||
* will be written.
|
||||
*
|
||||
* This means that this block will be written
|
||||
* multiple times and only the latest write will
|
||||
* contain the correct data.
|
||||
*/
|
||||
v[nd + i] = latest;
|
||||
}
|
||||
}
|
||||
|
||||
/* all the parities have to be processed */
|
||||
BUG_ON(j != nr);
|
||||
|
||||
/*
|
||||
* Recompute the parity, note that np may be smaller than the
|
||||
* total number of parities available
|
||||
*/
|
||||
raid_gen(nd, np, size, v, 0);
|
||||
|
||||
/* restore data buffers as before */
|
||||
for (j = 0; j < nr; ++j)
|
||||
v[id[j]] = pa[j];
|
||||
|
||||
/* restore parity buffers as before */
|
||||
for (i = 0; i < np; ++i)
|
||||
v[nd + i] = p[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Recover failure of one data block for PAR1.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue