Recover damaged block headers.

This commit is contained in:
2026-04-11 21:32:25 +01:00
parent 640ec68146
commit 501405a6ee
2 changed files with 23 additions and 3 deletions

View File

@@ -607,6 +607,16 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se
return AARUF_ERROR_CANNOT_READ_HEADER;
}
/* Sanity check: if the cached/read block header looks corrupt, skip directly to EC recovery.
* A corrupt header will have garbage sectorSize, compression, or identifier fields. */
if(block_header->identifier != DataBlock ||
block_header->sectorSize == 0 || block_header->sectorSize > 65536)
{
TRACE("Block header at offset %" PRIu64 " appears corrupt (id=0x%08X sectorSize=%u)",
block_offset, block_header->identifier, block_header->sectorSize);
goto ec_try_recovery;
}
if(data == NULL || *length < block_header->sectorSize)
{
TRACE("Buffer too small for sector, required %u bytes", block_header->sectorSize);

View File

@@ -284,9 +284,19 @@ TEST_F(ErasureCodingTest, RecoverCorruptedDataBlock)
*/
TEST_F(ErasureCodingTest, RecoverCorruptedBlockHeader)
{
/* NOTE: Corrupted BlockHeader recovery requires cache invalidation
* which is not yet implemented. Skipping for now. */
GTEST_SKIP() << "BlockHeader corruption recovery requires cache invalidation (TODO)";
uint64_t golden_crc = 0;
ASSERT_TRUE(create_ec_image("data/mf2hd.aif", "ec_test_output.aif", 4, 2, &golden_crc));
ASSERT_TRUE(copy_file("ec_test_output.aif", "ec_test_corrupt.aif"));
/* Corrupt the first block's header at offset 512 (after alignment).
* Corrupt 32 bytes = entire BlockHeader, making identifier/compression/sectorSize garbage. */
corrupt_file("ec_test_corrupt.aif", 512, 32);
bool success = false;
uint64_t read_crc = compute_image_crc("ec_test_corrupt.aif", &success);
ASSERT_TRUE(success) << "EC recovery failed on corrupted BlockHeader";
EXPECT_EQ(read_crc, golden_crc);
}
/**