mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Clarify RAID buffer access, aliasing, and zero-size behavior
This commit is contained in:
parent
bfe5ee7643
commit
5d9b1aee00
3 changed files with 45 additions and 20 deletions
38
raid/README
38
raid/README
|
|
@ -37,29 +37,33 @@ library startup before normal RAID operations.
|
|||
Computes 'np' parity blocks from 'nd' data blocks. Vector 'v' contains
|
||||
'nd + np' block pointers (data blocks v[0..nd-1], parity blocks
|
||||
v[nd..nd+np-1]). Each block must be aligned to a 64-byte boundary.
|
||||
Data blocks are read-only; parity blocks are written. 'streaming' must be
|
||||
either 0 or 1. If it is 1, non-temporal streaming stores are used where
|
||||
supported to avoid polluting the CPU cache when parity is written directly
|
||||
to disk. If it is 0, normal cached stores are used.
|
||||
Data entries are used only for reading and may reference read-only memory.
|
||||
Parity entries are outputs and must reference writable memory.
|
||||
'streaming' must be either 0 or 1. If it is 1, non-temporal streaming stores
|
||||
are used where supported to avoid polluting the CPU cache when parity is
|
||||
written directly to disk. If it is 0, normal cached stores are used.
|
||||
|
||||
void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)
|
||||
Recovers 'nr' failed blocks (data or parity) listed in sorted index array
|
||||
'ir'. Indexes start at 0 (data 0..nd-1, parity nd..nd+np-1). Each block
|
||||
pointed to by 'v' must be aligned to a 64-byte boundary. Pointers in 'v'
|
||||
for good blocks are read; pointers for bad blocks are target destinations.
|
||||
Requires nr <= np.
|
||||
Requires nr <= np. If nr is 0, 'ir' may be null; 'v' must be non-null but
|
||||
no block pointers are accessed.
|
||||
|
||||
void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
|
||||
Recovers 'nr' failed data blocks listed in sorted array 'id', using
|
||||
parities listed in sorted array 'ip'. Each block pointed to by 'v' must
|
||||
be aligned to a 64-byte boundary. Parity blocks in 'v' are unmodified.
|
||||
Requires nr <= nd and nr <= RAID_PARITY_MAX.
|
||||
Requires nr <= nd and nr <= RAID_PARITY_MAX. If nr is 0, 'id' and 'ip'
|
||||
may be null; 'v' must be non-null but no block pointers are accessed.
|
||||
|
||||
int raid_check(int nr, int *ir, int nd, int np, size_t size, void **v)
|
||||
Validates whether candidate failed block set 'ir' matches available parity
|
||||
redundancy. Each block pointed to by 'v' must be aligned to a 64-byte
|
||||
boundary. Returns 0 if candidate set matches, or -1 if invalid. Requires
|
||||
nr < np. Does not modify data or parity blocks.
|
||||
nr < np. If nr is 0, 'ir' may be null. Does not modify data or parity
|
||||
blocks. Returns -1 if size is 0.
|
||||
|
||||
int raid_scan(int *ir, int nd, int np, size_t size, void **v)
|
||||
Searches for up to 'np - 1' failed blocks using available redundancy.
|
||||
|
|
@ -69,6 +73,7 @@ library startup before normal RAID operations.
|
|||
checking uniqueness. Each block pointed to by 'v' must be aligned to a
|
||||
64-byte boundary. Fills 'ir' with the matching block indexes and returns
|
||||
their number (0 if no error), or -1 if no compatible combination is found.
|
||||
Returns -1 if size is 0.
|
||||
|
||||
int raid_selftest(void)
|
||||
Runs startup verification tests for parity generation, recovery, and
|
||||
|
|
@ -88,18 +93,23 @@ Memory, Alignment and Aliasing Requirements
|
|||
v[nd ... nd+np-1] -> Parity blocks (PAR1, PAR2, ..., PAR6)
|
||||
|
||||
- Block Size: Parameter 'size' MUST be a multiple of 64 bytes
|
||||
(size % 64 == 0).
|
||||
(size % 64 == 0). A zero size makes generation and recovery empty
|
||||
operations; validation and scanning return -1 because no redundancy data
|
||||
is available.
|
||||
|
||||
- Memory Alignment: All data and parity blocks pointed to by 'v[]'
|
||||
MUST be aligned to a 64-byte boundary. This requirement applies to each
|
||||
individual block buffer, not to the pointer array 'v' itself.
|
||||
|
||||
- Buffer Aliasing: Entries in 'v[]' MAY point to the same block buffer.
|
||||
Blocks are processed from lower to higher offsets. For each processed
|
||||
byte or vector chunk, all required inputs are read before outputs are
|
||||
written. Parity outputs are written in increasing parity order.
|
||||
Consequently, when multiple parity outputs point to the same block,
|
||||
later parity outputs overwrite earlier ones.
|
||||
- Buffer Aliasing: In raid_gen(), entries in 'v[]' MAY point to the same
|
||||
block buffer. Blocks are processed from lower to higher offsets. For each
|
||||
processed byte or vector chunk, all required inputs are read before outputs
|
||||
are written. Parity outputs are written in increasing parity order. When
|
||||
multiple parity outputs point to the same block, later parity outputs
|
||||
overwrite earlier ones.
|
||||
|
||||
In raid_rec() and raid_data(), each block being recovered MUST have a
|
||||
distinct destination buffer that does not alias any other block in 'v[]'.
|
||||
|
||||
This guarantee applies to block aliasing (identical block pointers);
|
||||
arbitrary partial overlap between distinct block ranges is not supported.
|
||||
|
|
|
|||
25
raid/raid.h
25
raid/raid.h
|
|
@ -195,11 +195,14 @@ int raid_selftest(void);
|
|||
* @np Number of parity blocks to compute. It must be between 1 and
|
||||
* RAID_PARITY_MAX. RAID_MODE_VANDERMONDE_RAID supports at most 3.
|
||||
* @size Size of the blocks pointed to by @v. It must be a multiple of 64.
|
||||
* It may be 0, in which case no block data is read or written.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @np) elements. The starting elements are the blocks for
|
||||
* data, following with the parity blocks.
|
||||
* Data entries are used as inputs and parity entries as outputs.
|
||||
* Data entries are used only for reading and may reference read-only memory.
|
||||
* Parity entries are outputs and must reference writable memory.
|
||||
* Entries may point to the same block buffer.
|
||||
* Each block has @size bytes and must be aligned to a 64-byte boundary.
|
||||
* @streaming Store policy hint: 1 for streaming / non-temporal stores
|
||||
* (bypassing cache) where supported, or 0 for normal cached / temporal stores.
|
||||
* No other values are valid.
|
||||
|
|
@ -239,13 +242,16 @@ void raid_gen(int nd, int np, size_t size, void **v, int streaming);
|
|||
* All indexes must be nonnegative and smaller than @nd + @np.
|
||||
* The first parity is represented with value @nd, the second with value
|
||||
* @nd + 1, just like positions in the @v vector.
|
||||
* It may be 0 if @nr is 0.
|
||||
* @nd Number of data blocks. It must be between 1 and RAID_DATA_MAX.
|
||||
* @np Number of parity blocks. It must be between 1 and RAID_PARITY_MAX.
|
||||
* RAID_MODE_VANDERMONDE_RAID supports at most 3.
|
||||
* @size Size of the blocks pointed by @v. It must be a multiple of 64.
|
||||
* It may be 0, in which case no block data is read or written.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @np) elements. The starting elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
* If @nr is greater than 0, it has (@nd + @np) elements. The starting
|
||||
* elements are the blocks for data, followed by the parity blocks.
|
||||
* If @nr is 0, @v must be nonzero but no block pointers are accessed.
|
||||
* Each block being recovered must have a distinct destination buffer
|
||||
* that does not alias any other block in this vector.
|
||||
* Each block has @size bytes and must be aligned to a 64-byte boundary.
|
||||
|
|
@ -263,15 +269,19 @@ void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v);
|
|||
* @id[] Vector of @nr indexes of the data blocks to recover.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* All indexes must be nonnegative and smaller than @nd.
|
||||
* It may be 0 if @nr is 0.
|
||||
* @ip[] Vector of @nr indexes of the parity blocks to use for recovery.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* All indexes must be nonnegative and smaller than RAID_PARITY_MAX.
|
||||
* In RAID_MODE_VANDERMONDE_RAID they must be smaller than 3.
|
||||
* It may be 0 if @nr is 0.
|
||||
* @nd Number of data blocks. It must be between 1 and RAID_DATA_MAX.
|
||||
* @size Size of the blocks pointed to by @v. It must be a multiple of 64.
|
||||
* It may be 0, in which case no block data is read or written.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @ip[@nr - 1] + 1) elements. The starting elements are the
|
||||
* blocks for data, following with the parity blocks.
|
||||
* If @nr is greater than 0, it has (@nd + @ip[@nr - 1] + 1) elements.
|
||||
* The starting elements are the blocks for data, followed by the parity
|
||||
* blocks. If @nr is 0, @v must be nonzero but no block pointers are accessed.
|
||||
* Each data block being recovered must have a distinct destination buffer
|
||||
* that does not alias any other block in this vector.
|
||||
* Each block has @size bytes and must be aligned to a 64-byte boundary.
|
||||
|
|
@ -297,10 +307,13 @@ void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v);
|
|||
* All indexes must be nonnegative and smaller than @nd + @np.
|
||||
* The first parity is represented with value @nd, the second with value
|
||||
* @nd + 1, just like positions in the @v vector.
|
||||
* It may be 0 if @nr is 0.
|
||||
* @nd Number of data blocks. It must be between 1 and RAID_DATA_MAX.
|
||||
* @np Number of parity blocks. It must be between 1 and RAID_PARITY_MAX.
|
||||
* RAID_MODE_VANDERMONDE_RAID supports at most 3.
|
||||
* @size Size of the blocks pointed by @v. It must be a multiple of 64.
|
||||
* If it is 0, the function returns -1 because no redundancy data is
|
||||
* available for validation.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @np) elements. The starting elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
|
|
@ -350,6 +363,8 @@ int raid_check(int nr, int *ir, int nd, int np, size_t size, void **v);
|
|||
* @np Number of parity blocks. It must be between 0 and RAID_PARITY_MAX.
|
||||
* RAID_MODE_VANDERMONDE_RAID supports at most 3.
|
||||
* @size Size of the blocks pointed by @v. It must be a multiple of 64.
|
||||
* If it is 0, the function returns -1 because no redundancy data is
|
||||
* available for validation.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @np) elements. The starting elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
|
|
|
|||
|
|
@ -2134,7 +2134,7 @@ void speed(void)
|
|||
|
||||
printf("Speed test using %u data buffers of %u bytes, for a total of %u KiB.\n", nd, size, nd * size / 1024);
|
||||
printf("Memory blocks have a displacement of %u bytes to improve cache performance.\n", raid_optimal_displacement(nv));
|
||||
printf("The reported values are the aggregate bandwidth of all data blocks in MiB/s,\n");
|
||||
printf("The reported values are the aggregate bandwidth of all data blocks in MB/s,\n");
|
||||
printf("not counting parity blocks.\n");
|
||||
printf("\n");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue