libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
Loading...
Searching...
No Matches
erasure.c File Reference

Erasure coding setup, parity accumulation, and write-path integration. More...

#include <stdlib.h>
#include <string.h>
#include "aaruformat.h"
#include "aaruformat/context.h"
#include "aaruformat/consts.h"
#include "aaruformat/enums.h"
#include "aaruformat/errors.h"
#include "aaruformat/structs/data.h"
#include "aaruformat/structs/ddt.h"
#include "aaruformat/structs/erasure.h"
#include "aaruformat/structs/index.h"
#include "internal.h"
#include "log.h"
#include "lib/gf256.h"
#include "lib/reed_solomon.h"

Go to the source code of this file.

Data Structures

struct  EcReadStripe
 In-memory representation of one data stripe (parsed from ECMB). More...
struct  EcBlockLookupEntry
 Hash table entry mapping block file offset -> stripe index + position. More...

Macros

#define WRITE_GROUP(desc, desc_len, grp)

Typedefs

typedef struct EcReadStripe EcReadStripe
 In-memory representation of one data stripe (parsed from ECMB).
typedef struct EcBlockLookupEntry EcBlockLookupEntry
 Hash table entry mapping block file offset -> stripe index + position.

Functions

void ec_flush_data_stripe (aaruformat_context *ctx, uint32_t slot)
 Write M parity blocks for a completed data stripe slot and record the stripe descriptor.
int32_t aaruf_set_erasure_coding (void *context, uint8_t algorithm, uint16_t K, uint16_t M)
 Configure erasure coding for a newly created image.
int32_t aaruf_set_erasure_coding_auto (void *context, uint8_t recovery_percent)
 Configure erasure coding from a desired recovery percentage.
void ec_accumulate_data_block (aaruformat_context *ctx, const BlockHeader *block_header, const uint8_t *lzma_props, const uint8_t *payload, uint32_t payload_size, uint64_t file_offset)
 Accumulate parity for a data block that was just written to disk.
static void ec_write_batch_parity (aaruformat_context *ctx, const uint64_t *offsets, const uint32_t *sizes, uint32_t block_count, uint8_t group_type, uint16_t parity_data_type, uint8_t **out_desc, size_t *out_desc_len, StripeGroupDescriptor *out_group)
 Compute and write batch parity for a set of blocks already on disk.
static void ec_collect_blocks_by_type (aaruformat_context *ctx, uint32_t block_type, uint64_t **out_offsets, uint32_t **out_sizes, uint32_t *out_count)
 Collect file offsets and on-disk sizes for index entries matching a block type.
void ec_finalize (aaruformat_context *ctx)
 Flush all partial data stripes and write parity for all groups + ECMB + recovery footer.
int32_t ec_recover_raw_block (aaruformat_context *ctx, uint64_t block_offset, uint8_t **recovered_data, uint32_t *recovered_size, void *stripes_ptr, uint32_t stripe_count, void *lookup_ptr, uint16_t group_K, uint16_t group_M, uint32_t group_shard_size)
 Attempt to recover a raw block at a given file offset using a specified stripe group.
int32_t ec_recover_meta_block (aaruformat_context *ctx, uint64_t block_offset, uint8_t **recovered_data, uint32_t *recovered_size)
 Attempt to recover a metadata/media-tag block at a given file offset.
int32_t ec_recover_ddt_block (aaruformat_context *ctx, uint64_t block_offset, uint8_t **recovered_data, uint32_t *recovered_size)
 Attempt to recover a DDT secondary block at a given file offset.
void ec_free (aaruformat_context *ctx)
 Free all erasure coding state from the context.
void ec_load_ecmb (aaruformat_context *ctx)
 Try to load the ECMB from the recovery footer at EOF.
int32_t ec_recover_data_block (aaruformat_context *ctx, uint64_t block_offset, uint64_t offset, uint8_t *data, uint32_t *length, uint8_t sector_status)
 Attempt to recover a data block that failed decompression or CRC verification.

Variables

static UT_icd ec_stripe_icd = {sizeof(uint8_t), NULL, NULL, NULL}

Detailed Description

Erasure coding setup, parity accumulation, and write-path integration.

Definition in file erasure.c.

Macro Definition Documentation

◆ WRITE_GROUP

#define WRITE_GROUP ( desc,
desc_len,
grp )
Value:
if(desc) { memcpy(wp, &(grp), sizeof(StripeGroupDescriptor)); wp += sizeof(StripeGroupDescriptor); \
memcpy(wp, (desc), (desc_len)); wp += (desc_len); }
Describes one protection group within the ECMB payload.
Definition erasure.h:69

Referenced by ec_finalize().

Typedef Documentation

◆ EcBlockLookupEntry

typedef struct EcBlockLookupEntry EcBlockLookupEntry

Hash table entry mapping block file offset -> stripe index + position.

◆ EcReadStripe

typedef struct EcReadStripe EcReadStripe

In-memory representation of one data stripe (parsed from ECMB).

Function Documentation

◆ aaruf_set_erasure_coding()

int32_t aaruf_set_erasure_coding ( void * context,
uint8_t algorithm,
uint16_t K,
uint16_t M )

◆ aaruf_set_erasure_coding_auto()

int32_t aaruf_set_erasure_coding_auto ( void * context,
uint8_t recovery_percent )

Configure erasure coding from a desired recovery percentage.

Computes K and M from the requested percentage of data that should be recoverable. Higher recovery percentages produce higher M values (more parity blocks = better burst-corruption tolerance).

Strategy: M = max(2, min(8, round(20 * percent / 100))) K = M * 100 / percent

This keeps K roughly constant (~16–40) while scaling M monotonically with the requested recovery level:

1% → RS(200, 2) M=2, minimum burst tolerance 5% → RS(40, 2) M=2 10% → RS(20, 2) M=2 15% → RS(20, 3) M=3, burst tolerance grows 25% → RS(20, 5) M=5 50% → RS(16, 8) M=8 (capped), strong burst tolerance 100% → RS(8, 8) M=8 (capped), maximum protection

Parameters
contextOpaque context from aaruf_create().
recovery_percentDesired recoverable percentage (1..100).
Returns
AARUF_STATUS_OK on success, error code otherwise.

Definition at line 174 of file erasure.c.

References AARU_CALL, AARU_EXPORT, AARUF_ERROR_INCORRECT_DATA_SIZE, aaruf_set_erasure_coding(), aaruf_set_erasure_coding_auto(), kErasureCodingRsVandermonde, and TRACE.

Referenced by aaruf_set_erasure_coding_auto().

◆ ec_accumulate_data_block()

void ec_accumulate_data_block ( aaruformat_context * ctx,
const BlockHeader * block_header,
const uint8_t * lzma_props,
const uint8_t * payload,
uint32_t payload_size,
uint64_t file_offset )

Accumulate parity for a data block that was just written to disk.

Called from aaruf_close_current_block() after writing BlockHeader + payload to the file but before freeing the compressed data buffer.

Parameters
ctxContext with EC enabled.
block_headerPointer to the BlockHeader that was written.
lzma_propsLZMA properties (may be NULL if not LZMA).
payloadCompressed payload data (or uncompressed if no compression).
payload_sizeSize of the payload data.
file_offsetFile offset where the block was written.

Definition at line 209 of file erasure.c.

References aaruf_crc64_data(), BlockHeader::compression, ec_accumulate_data_block(), aaruformat_context::ec_data_block_offsets, aaruformat_context::ec_data_block_sizes, aaruformat_context::ec_data_parity, aaruformat_context::ec_data_shard_crcs, aaruformat_context::ec_data_shard_size, aaruformat_context::ec_data_stripe_counts, aaruformat_context::ec_enabled, ec_flush_data_stripe(), aaruformat_context::ec_K, aaruformat_context::ec_M, aaruformat_context::ec_rs_ctx, aaruformat_context::ec_total_data_blocks, kCompressionLzma, LZMA_PROPERTIES_LENGTH, rs_encode_incremental(), rs_get_coefficient(), and TRACE.

Referenced by aaruf_close_current_block(), and ec_accumulate_data_block().

◆ ec_collect_blocks_by_type()

void ec_collect_blocks_by_type ( aaruformat_context * ctx,
uint32_t block_type,
uint64_t ** out_offsets,
uint32_t ** out_sizes,
uint32_t * out_count )
static

◆ ec_finalize()

void ec_finalize ( aaruformat_context * ctx)

Flush all partial data stripes and write parity for all groups + ECMB + recovery footer.

Definition at line 585 of file erasure.c.

References AARU_RECOVERY_FOOTER_MAGIC, aaruf_crc64_data(), aaruf_fseek(), aaruf_ftell(), ErasureCodingMapHeader::algorithm, AaruRecoveryFooter::backupHeader, DdtHeader2::blockAlignmentShift, IndexEntry::blockType, ErasureCodingMapHeader::cmpCrc64, BlockHeader::cmpLength, ErasureCodingMapHeader::cmpLength, ErasureCodingMapHeader::compression, ErasureCodingMapHeader::crc64, DataBlock, IndexEntry::dataType, DeDuplicationTable, DeDuplicationTable2, DeDuplicationTableSecondary, aaruformat_context::ec_algorithm, ec_collect_blocks_by_type(), aaruformat_context::ec_data_shard_size, aaruformat_context::ec_data_stripe_counts, aaruformat_context::ec_data_stripes, aaruformat_context::ec_enabled, ec_finalize(), ec_flush_data_stripe(), aaruformat_context::ec_K, aaruformat_context::ec_M, ec_write_batch_parity(), AaruRecoveryFooter::ecmbLength, AaruRecoveryFooter::ecmbOffset, IndexHeader3::entries, ErasureCodingMapBlock, AaruRecoveryFooter::footerMagic, StripeGroupDescriptor::groupType, aaruformat_context::header, AaruRecoveryFooter::headerCrc64, ErasureCodingMapHeader::identifier, aaruformat_context::imageStream, aaruformat_context::index_entries, IndexBlock, IndexBlock2, IndexBlock3, AaruHeaderV2::indexOffset, StripeGroupDescriptor::interleaveDepth, StripeGroupDescriptor::K, kCompressionNone, kDataTypeErasureParity, kDataTypeErasureParityDdt, kDataTypeErasureParityDdtPrimary, kDataTypeErasureParityIndex, kDataTypeErasureParityMeta, kDataTypeUserData, kECGroupData, kECGroupDdtPrimary, kECGroupDdtSecondary, kECGroupIndex, kECGroupMetadata, ErasureCodingMapHeader::length, StripeGroupDescriptor::M, IndexEntry::offset, StripeGroupDescriptor::shardSize, StripeGroupDescriptor::stripeCount, ErasureCodingMapHeader::stripeGroupCount, TRACE, aaruformat_context::user_data_ddt_header, and WRITE_GROUP.

Referenced by aaruf_finalize_write(), and ec_finalize().

◆ ec_flush_data_stripe()

◆ ec_free()

◆ ec_load_ecmb()

void ec_load_ecmb ( aaruformat_context * ctx)

Try to load the ECMB from the recovery footer at EOF.

Reads the last 160 bytes, checks for footerMagic, parses ECMB, and populates the ec_read_* fields and block lookup hashmap. Called from aaruf_open().

Definition at line 1046 of file erasure.c.

References AARU_RECOVERY_FOOTER_MAGIC, aaruf_crc64_data(), aaruf_fseek(), aaruf_ftell(), aaruf_lzma_decode_buffer(), aaruf_zstd_decode_buffer(), EcReadStripe::actual_k, ErasureCodingMapHeader::algorithm, EcBlockLookupEntry::block_offset, ErasureCodingMapHeader::cmpLength, ErasureCodingMapHeader::compression, ErasureCodingMapHeader::crc64, EcReadStripe::data_entries, aaruformat_context::ec_algorithm, aaruformat_context::ec_block_lookup, aaruformat_context::ec_data_shard_size, aaruformat_context::ec_ddt_block_lookup, aaruformat_context::ec_ddt_K, aaruformat_context::ec_ddt_M, aaruformat_context::ec_ddt_shard_size, aaruformat_context::ec_ddt_stripe_count, aaruformat_context::ec_ddt_stripes, aaruformat_context::ec_K, ec_load_ecmb(), aaruformat_context::ec_M, aaruformat_context::ec_meta_block_lookup, aaruformat_context::ec_meta_K, aaruformat_context::ec_meta_M, aaruformat_context::ec_meta_shard_size, aaruformat_context::ec_meta_stripe_count, aaruformat_context::ec_meta_stripes, aaruformat_context::ec_read_stripe_count, aaruformat_context::ec_read_stripes, aaruformat_context::ec_recovery_available, aaruformat_context::ec_rs_ctx, AaruRecoveryFooter::ecmbOffset, ErasureCodingMapBlock, AaruRecoveryFooter::footerMagic, StripeGroupDescriptor::groupType, ErasureCodingMapHeader::identifier, aaruformat_context::imageStream, StripeGroupDescriptor::K, kCompressionLzma, kCompressionNone, kCompressionZstd, kECGroupData, kECGroupDdtSecondary, kECGroupMetadata, ErasureCodingMapHeader::length, LZMA_PROPERTIES_LENGTH, StripeGroupDescriptor::M, StripeDataBlockEntry::offset, StripeParityBlockEntry::offset, EcReadStripe::parity_offsets, EcBlockLookupEntry::position, rs_create(), StripeGroupDescriptor::shardSize, EcBlockLookupEntry::stripe_index, StripeGroupDescriptor::stripeCount, ErasureCodingMapHeader::stripeGroupCount, and TRACE.

Referenced by aaruf_open(), and ec_load_ecmb().

◆ ec_recover_data_block()

int32_t ec_recover_data_block ( aaruformat_context * ctx,
uint64_t block_offset,
uint64_t offset,
uint8_t * data,
uint32_t * length,
uint8_t sector_status )

Attempt to recover a data block that failed decompression or CRC verification.

Looks up the block's stripe via the ECMB, reads surviving stripe members + parity, RS-decodes the erased shard, and decompresses the recovered block.

Parameters
ctxContext with ec_recovery_available == true.
block_offsetFile offset of the corrupted block.
offsetSector offset within the block.
dataOutput buffer for the recovered sector.
lengthOutput: bytes written to data.
sector_statusSector status from DDT.
Returns
AARUF_STATUS_OK on success, negative error code on failure.

Definition at line 1303 of file erasure.c.

References aaruf_crc64_data(), AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK, AARUF_ERROR_NOT_ENOUGH_MEMORY, aaruf_flac_decode_redbook_buffer(), aaruf_fseek(), aaruf_lzma_decode_buffer(), AARUF_STATUS_OK, aaruf_zstd_decode_buffer(), EcReadStripe::actual_k, add_to_cache_uint64(), aaruformat_context::block_cache, aaruformat_context::block_header_cache, BlockHeader::cmpLength, BlockHeader::compression, BlockHeader::crc64, EcReadStripe::data_entries, aaruformat_context::ec_block_lookup, aaruformat_context::ec_data_shard_size, aaruformat_context::ec_K, aaruformat_context::ec_M, aaruformat_context::ec_read_stripes, ec_recover_data_block(), aaruformat_context::ec_recovery_available, aaruformat_context::ec_recovery_in_progress, aaruformat_context::ec_rs_ctx, aaruformat_context::imageStream, kCompressionFlac, kCompressionLzma, kCompressionNone, kCompressionZstd, BlockHeader::length, LZMA_PROPERTIES_LENGTH, StripeDataBlockEntry::offset, StripeDataBlockEntry::onDiskSize, EcReadStripe::parity_offsets, EcBlockLookupEntry::position, rs_decode(), BlockHeader::sectorSize, StripeDataBlockEntry::shardCrc64, and EcBlockLookupEntry::stripe_index.

Referenced by aaruf_read_sector(), and ec_recover_data_block().

◆ ec_recover_ddt_block()

int32_t ec_recover_ddt_block ( aaruformat_context * ctx,
uint64_t block_offset,
uint8_t ** recovered_data,
uint32_t * recovered_size )

◆ ec_recover_meta_block()

int32_t ec_recover_meta_block ( aaruformat_context * ctx,
uint64_t block_offset,
uint8_t ** recovered_data,
uint32_t * recovered_size )

◆ ec_recover_raw_block()

int32_t ec_recover_raw_block ( aaruformat_context * ctx,
uint64_t block_offset,
uint8_t ** recovered_data,
uint32_t * recovered_size,
void * stripes,
uint32_t stripe_count,
void * lookup,
uint16_t group_K,
uint16_t group_M,
uint32_t group_shard_size )

Attempt to recover a raw block at a given file offset using a specified stripe group.

Reads surviving stripe members + parity, RS-decodes the erased shard, returns the recovered raw on-disk bytes.

Parameters
ctxContext.
block_offsetFile offset of the corrupted block.
recovered_dataOutput: malloc'd buffer with recovered bytes (caller frees). NULL on failure.
recovered_sizeOutput: size of recovered data.
stripesEcReadStripe array for the group.
stripe_countNumber of stripes.
lookupBlock lookup hashmap for the group.
group_KK for this group.
group_MM for this group.
group_shard_sizeShard size for this group.
Returns
0 on success, negative on failure.

Definition at line 827 of file erasure.c.

References aaruf_crc64_data(), AARUF_ERROR_CANNOT_READ_BLOCK, AARUF_ERROR_NOT_ENOUGH_MEMORY, aaruf_fseek(), AARUF_STATUS_OK, EcReadStripe::actual_k, EcReadStripe::data_entries, ec_recover_raw_block(), aaruformat_context::ec_recovery_available, aaruformat_context::ec_recovery_in_progress, aaruformat_context::imageStream, BlockHeader::length, StripeDataBlockEntry::offset, StripeDataBlockEntry::onDiskSize, EcReadStripe::parity_offsets, EcBlockLookupEntry::position, rs_create(), rs_decode(), rs_free(), StripeDataBlockEntry::shardCrc64, and EcBlockLookupEntry::stripe_index.

Referenced by ec_recover_ddt_block(), ec_recover_meta_block(), and ec_recover_raw_block().

◆ ec_write_batch_parity()

Variable Documentation

◆ ec_stripe_icd

UT_icd ec_stripe_icd = {sizeof(uint8_t), NULL, NULL, NULL}
static

Definition at line 65 of file erasure.c.

Referenced by aaruf_set_erasure_coding().