Set DDTv2 as 64-bit and remove concept of multiple sizes of DDTs.

This commit is contained in:
2025-10-10 02:39:57 +01:00
parent 421d5ada72
commit 17e1c0f2bd
15 changed files with 107 additions and 150 deletions

View File

@@ -182,10 +182,10 @@ typedef struct aaruformat_context
TapeDdtHashEntry *tape_ddt; ///< Hash table root for tape DDT entries
uint32_t *sector_prefix_ddt; ///< Legacy CD sector prefix DDT (deprecated by *2).
uint32_t *sector_suffix_ddt; ///< Legacy CD sector suffix DDT.
uint32_t *sector_prefix_ddt2; ///< CD sector prefix DDT V2.
uint32_t *sector_suffix_ddt2; ///< CD sector suffix DDT V2.
uint32_t *user_data_ddt2; ///< DDT entries (big variant) primary/secondary current.
uint32_t *cached_secondary_ddt2; ///< Cached secondary table (big entries) or NULL.
uint64_t *sector_prefix_ddt2; ///< CD sector prefix DDT V2.
uint64_t *sector_suffix_ddt2; ///< CD sector suffix DDT V2.
uint64_t *user_data_ddt2; ///< DDT entries (big variant) primary/secondary current.
uint64_t *cached_secondary_ddt2; ///< Cached secondary table (big entries) or NULL.
DdtHeader2 user_data_ddt_header; ///< Active user data DDT v2 header (primary table meta).
uint64_t cached_ddt_offset; ///< File offset of currently cached secondary DDT (0=none).
uint64_t cached_ddt_position; ///< Position index of cached secondary DDT.

View File

@@ -220,15 +220,6 @@ typedef enum
AudioMedia = 3 ///< Media that can only store data when modulated to audio.
} XmlMediaType;
/**
* \enum DdtSizeType
* \brief Size type for Deduplication Data Table (DDT) entries.
*/
typedef enum
{
BigDdtSizeType = 1 ///< Large sized DDT entries.
} DdtSizeType;
/**
* \enum SectorStatus
* \brief Acquisition / content status for one or more sectors.

View File

@@ -113,7 +113,6 @@ typedef struct DdtHeader
* - blockAlignmentShift: log2 alignment of stored data blocks (byte granularity of block_offset).
* - dataShift: log2 of the number of addressable sectors per increment of blockIndex bitfield unit.
* - tableShift: log2 of number of logical sectors covered by a single primary-table pointer (multi-level only).
* - sizeType: Selects entry width (small=16b, big=32b) impacting available bits for blockIndex+offset.
*
* Notes & current limitations:
* - User area sector count = blocks - negative - overflow.
@@ -156,7 +155,6 @@ typedef struct DdtHeader2
uint8_t dataShift; ///< 2^dataShift = sectors represented per increment in blockIndex field.
uint8_t tableShift; ///< 2^tableShift = number of logical sectors per primary entry (multi-level only; 0 for
///< single-level or secondary tables).
uint8_t sizeType; ///< Entry size variant (\ref DdtSizeType) controlling width of E.
uint64_t entries; ///< Number of entries contained in (uncompressed) table payload.
uint64_t cmpLength; ///< Compressed payload size in bytes.
uint64_t length; ///< Uncompressed payload size in bytes.

View File

@@ -117,7 +117,6 @@ static int32_t write_cached_secondary_ddt(aaruformat_context *ctx)
ddt_header.blockAlignmentShift = ctx->user_data_ddt_header.blockAlignmentShift;
ddt_header.dataShift = ctx->user_data_ddt_header.dataShift;
ddt_header.tableShift = 0; // Secondary tables are single level
ddt_header.sizeType = ctx->user_data_ddt_header.sizeType;
uint64_t items_per_ddt_entry = 1 << ctx->user_data_ddt_header.tableShift;
ddt_header.blocks = items_per_ddt_entry;
@@ -194,7 +193,7 @@ static int32_t write_cached_secondary_ddt(aaruformat_context *ctx)
const uint64_t new_secondary_table_block_offset =
end_of_file >> ctx->user_data_ddt_header.blockAlignmentShift;
ctx->user_data_ddt2[ctx->cached_ddt_position] = (uint32_t)new_secondary_table_block_offset;
ctx->user_data_ddt2[ctx->cached_ddt_position] = (uint64_t)new_secondary_table_block_offset;
// Update index: remove old entry for cached DDT and add new one
TRACE("Updating index for cached secondary DDT");
@@ -291,7 +290,7 @@ static int32_t write_primary_ddt(aaruformat_context *ctx)
crc64_ctx *crc64_context = aaruf_crc64_init();
if(crc64_context != NULL)
{
size_t primary_table_size = ctx->user_data_ddt_header.entries * sizeof(uint32_t);
size_t primary_table_size = ctx->user_data_ddt_header.entries * sizeof(uint64_t);
aaruf_crc64_update(crc64_context, (uint8_t *)ctx->user_data_ddt2, primary_table_size);
@@ -374,7 +373,7 @@ static int32_t write_single_level_ddt(aaruformat_context *ctx)
TRACE("Writing single-level DDT table to file");
// Calculate CRC64 of the primary DDT table data
const size_t primary_table_size = ctx->user_data_ddt_header.entries * sizeof(uint32_t);
const size_t primary_table_size = ctx->user_data_ddt_header.entries * sizeof(uint64_t);
// Properly populate all header fields
ctx->user_data_ddt_header.identifier = DeDuplicationTable2;
@@ -613,15 +612,14 @@ static int32_t write_tape_ddt(aaruformat_context *ctx)
ctx->user_data_ddt_header.negative = 0;
ctx->user_data_ddt_header.overflow = 0;
ctx->user_data_ddt_header.tableShift = 0; // Single level
ctx->user_data_ddt_header.sizeType = BigDdtSizeType;
ctx->user_data_ddt_header.entries = max_key + 1;
ctx->user_data_ddt_header.blocks = max_key + 1;
ctx->user_data_ddt_header.start = 0;
ctx->user_data_ddt_header.length = ctx->user_data_ddt_header.entries * sizeof(uint32_t);
ctx->user_data_ddt_header.length = ctx->user_data_ddt_header.entries * sizeof(uint64_t);
ctx->user_data_ddt_header.cmpLength = ctx->user_data_ddt_header.length;
// Initialize memory for user data DDT
ctx->user_data_ddt2 = calloc(ctx->user_data_ddt_header.entries, sizeof(uint32_t));
ctx->user_data_ddt2 = calloc(ctx->user_data_ddt_header.entries, sizeof(uint64_t));
if(ctx->user_data_ddt2 == NULL)
{
TRACE("Failed to allocate memory for tape DDT table");
@@ -1233,12 +1231,11 @@ static void write_sector_prefix_ddt(aaruformat_context *ctx)
ddt_header2.blockAlignmentShift = ctx->user_data_ddt_header.blockAlignmentShift;
ddt_header2.dataShift = ctx->user_data_ddt_header.dataShift;
ddt_header2.tableShift = 0; // Single-level DDT
ddt_header2.sizeType = BigDdtSizeType;
ddt_header2.entries =
ctx->image_info.Sectors + ctx->user_data_ddt_header.negative + ctx->user_data_ddt_header.overflow;
ddt_header2.blocks = ctx->user_data_ddt_header.blocks;
ddt_header2.start = 0;
ddt_header2.length = ddt_header2.entries * sizeof(uint32_t);
ddt_header2.length = ddt_header2.entries * sizeof(uint64_t);
// Calculate CRC64
ddt_header2.crc64 = aaruf_crc64_data((uint8_t *)ctx->sector_prefix_ddt2, (uint32_t)ddt_header2.length);
@@ -1379,12 +1376,11 @@ static void write_sector_suffix_ddt(aaruformat_context *ctx)
ddt_header2.blockAlignmentShift = ctx->user_data_ddt_header.blockAlignmentShift;
ddt_header2.dataShift = ctx->user_data_ddt_header.dataShift;
ddt_header2.tableShift = 0; // Single-level DDT
ddt_header2.sizeType = BigDdtSizeType;
ddt_header2.entries =
ctx->image_info.Sectors + ctx->user_data_ddt_header.negative + ctx->user_data_ddt_header.overflow;
ddt_header2.blocks = ctx->user_data_ddt_header.blocks;
ddt_header2.start = 0;
ddt_header2.length = ddt_header2.entries * sizeof(uint32_t);
ddt_header2.length = ddt_header2.entries * sizeof(uint64_t);
// Calculate CRC64
ddt_header2.crc64 = aaruf_crc64_data((uint8_t *)ctx->sector_suffix_ddt2, (uint32_t)ddt_header2.length);

View File

@@ -470,7 +470,6 @@ void *aaruf_create(const char *filepath, const uint32_t media_type, const uint32
ctx->user_data_ddt_header.start = 0;
ctx->user_data_ddt_header.blockAlignmentShift = parsed_options.block_alignment;
ctx->user_data_ddt_header.dataShift = parsed_options.data_shift;
ctx->user_data_ddt_header.sizeType = BigDdtSizeType;
if(parsed_options.table_shift == -1)
{
@@ -501,18 +500,15 @@ void *aaruf_create(const char *filepath, const uint32_t media_type, const uint32
ctx->user_data_ddt_header.entries++;
TRACE("Initializing primary/single DDT");
if(ctx->user_data_ddt_header.sizeType == BigDdtSizeType)
ctx->user_data_ddt2 =
(uint64_t *)calloc(ctx->user_data_ddt_header.entries, sizeof(uint64_t)); // All entries to zero
if(ctx->user_data_ddt2 == NULL)
{
ctx->user_data_ddt2 =
(uint32_t *)calloc(ctx->user_data_ddt_header.entries, sizeof(uint32_t)); // All entries to zero
if(ctx->user_data_ddt2 == NULL)
{
FATAL("Not enough memory to allocate primary DDT (big)");
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
TRACE("Exiting aaruf_create() = NULL");
cleanup_failed_create(ctx);
return NULL;
}
FATAL("Not enough memory to allocate primary DDT (big)");
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
TRACE("Exiting aaruf_create() = NULL");
cleanup_failed_create(ctx);
return NULL;
}
// Set the primary DDT offset (just after the header, block aligned)

View File

@@ -247,7 +247,7 @@ int32_t process_ddt_v2(aaruformat_context *ctx, IndexEntry *entry, bool *found_u
return AARUF_ERROR_INVALID_BLOCK_CRC;
}
ctx->user_data_ddt2 = (uint32_t *)buffer;
ctx->user_data_ddt2 = (uint64_t *)buffer;
ctx->in_memory_ddt = true;
*found_user_data_ddt = true;
@@ -293,7 +293,7 @@ int32_t process_ddt_v2(aaruformat_context *ctx, IndexEntry *entry, bool *found_u
return AARUF_ERROR_INVALID_BLOCK_CRC;
}
ctx->user_data_ddt2 = (uint32_t *)buffer;
ctx->user_data_ddt2 = (uint64_t *)buffer;
ctx->in_memory_ddt = true;
*found_user_data_ddt = true;
@@ -616,14 +616,7 @@ int32_t decode_ddt_single_level_v2(aaruformat_context *ctx, uint64_t sector_addr
else
sector_address += ctx->user_data_ddt_header.negative;
if(ctx->user_data_ddt_header.sizeType == BigDdtSizeType)
ddt_entry = ctx->user_data_ddt2[sector_address];
else
{
FATAL("Unknown DDT size type %d.", ctx->userDataDdtHeader.sizeType);
TRACE("Exiting decode_ddt_single_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
return AARUF_ERROR_CANNOT_READ_BLOCK;
}
ddt_entry = ctx->user_data_ddt2[sector_address];
if(ddt_entry == 0)
{
@@ -635,8 +628,8 @@ int32_t decode_ddt_single_level_v2(aaruformat_context *ctx, uint64_t sector_addr
return AARUF_STATUS_OK;
}
*sector_status = ddt_entry >> 28;
ddt_entry &= 0x0fffffff;
*sector_status = ddt_entry >> 60;
ddt_entry &= 0xFFFFFFFFFFFFFFF;
const uint64_t offset_mask = (uint64_t)((1 << ctx->user_data_ddt_header.dataShift) - 1);
*offset = ddt_entry & offset_mask;
@@ -776,17 +769,9 @@ int32_t decode_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_addre
else
sector_address += ctx->user_data_ddt_header.negative;
items_per_ddt_entry = 1 << ctx->user_data_ddt_header.tableShift;
ddt_position = sector_address / items_per_ddt_entry;
if(ctx->user_data_ddt_header.sizeType == BigDdtSizeType)
secondary_ddt_offset = ctx->user_data_ddt2[ddt_position];
else
{
FATAL("Unknown DDT size type %d.", ctx->userDataDdtHeader.sizeType);
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
return AARUF_ERROR_CANNOT_READ_BLOCK;
}
items_per_ddt_entry = 1 << ctx->user_data_ddt_header.tableShift;
ddt_position = sector_address / items_per_ddt_entry;
secondary_ddt_offset = ctx->user_data_ddt2[ddt_position];
// Position in file of the child DDT table
secondary_ddt_offset *= 1 << ctx->user_data_ddt_header.blockAlignmentShift;
@@ -908,7 +893,7 @@ int32_t decode_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_addre
return AARUF_ERROR_INVALID_BLOCK_CRC;
}
ctx->cached_secondary_ddt2 = (uint32_t *)buffer;
ctx->cached_secondary_ddt2 = (uint64_t *)buffer;
ctx->cached_ddt_offset = secondary_ddt_offset;
@@ -954,7 +939,7 @@ int32_t decode_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_addre
return AARUF_ERROR_INVALID_BLOCK_CRC;
}
ctx->cached_secondary_ddt2 = (uint32_t *)buffer;
ctx->cached_secondary_ddt2 = (uint64_t *)buffer;
ctx->cached_ddt_offset = secondary_ddt_offset;
@@ -979,8 +964,8 @@ int32_t decode_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_addre
return AARUF_STATUS_OK;
}
*sector_status = ddt_entry >> 28;
ddt_entry &= 0x0fffffff;
*sector_status = ddt_entry >> 60;
ddt_entry &= 0x0FFFFFFFFFFFFFFF;
const uint64_t offset_mask = (uint64_t)((1 << ctx->user_data_ddt_header.dataShift) - 1);
*offset = ddt_entry & offset_mask;
@@ -1079,18 +1064,18 @@ bool set_ddt_single_level_v2(aaruformat_context *ctx, uint64_t sector_address, c
block_index << ctx->user_data_ddt_header.dataShift;
// Overflow detection for DDT entry
if(*ddt_entry > 0xFFFFFFF)
if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
{
FATAL("DDT overflow: media does not fit in big DDT");
TRACE("Exiting set_ddt_single_level_v2() = false");
return false;
}
*ddt_entry |= (uint64_t)sector_status << 28;
*ddt_entry |= (uint64_t)sector_status << 60;
}
TRACE("Setting big single-level DDT entry %d to %u", sector_address, (uint32_t)*ddt_entry);
ctx->user_data_ddt2[sector_address] = (uint32_t)*ddt_entry;
TRACE("Setting big single-level DDT entry %d to %ull", sector_address, (uint64_t)*ddt_entry);
ctx->user_data_ddt2[sector_address] = *ddt_entry;
TRACE("Exiting set_ddt_single_level_v2() = true");
return true;
@@ -1153,17 +1138,9 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
sector_address += ctx->user_data_ddt_header.negative;
// Step 1: Calculate the corresponding secondary level table
items_per_ddt_entry = 1 << ctx->user_data_ddt_header.tableShift;
ddt_position = sector_address / items_per_ddt_entry;
if(ctx->user_data_ddt_header.sizeType == BigDdtSizeType)
secondary_ddt_offset = ctx->user_data_ddt2[ddt_position];
else
{
FATAL("Unknown DDT size type %d.", ctx->userDataDdtHeader.sizeType);
TRACE("Exiting set_ddt_multi_level_v2() = false");
return false;
}
items_per_ddt_entry = 1 << ctx->user_data_ddt_header.tableShift;
ddt_position = sector_address / items_per_ddt_entry;
secondary_ddt_offset = ctx->user_data_ddt2[ddt_position];
// Position in file of the child DDT table
secondary_ddt_offset *= 1 << ctx->user_data_ddt_header.blockAlignmentShift;
@@ -1179,18 +1156,19 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
block_index << ctx->user_data_ddt_header.dataShift;
// Overflow detection for DDT entry
if(*ddt_entry > 0xFFFFFFF)
if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
{
FATAL("DDT overflow: media does not fit in big DDT");
TRACE("Exiting set_ddt_multi_level_v2() = false");
return false;
}
*ddt_entry |= (uint64_t)sector_status << 28;
*ddt_entry |= (uint64_t)sector_status << 60;
}
TRACE("Setting small secondary DDT entry %d to %u", sector_address % items_per_ddt_entry, (uint16_t)*ddt_entry);
ctx->cached_secondary_ddt2[sector_address % items_per_ddt_entry] = (uint32_t)*ddt_entry;
TRACE("Setting small secondary DDT entry %d to %ull", sector_address % items_per_ddt_entry,
(uint64_t)*ddt_entry);
ctx->cached_secondary_ddt2[sector_address % items_per_ddt_entry] = *ddt_entry;
TRACE("Updated cached secondary DDT entry at position %" PRIu64, sector_address % items_per_ddt_entry);
TRACE("Exiting set_ddt_multi_level_v2() = true");
@@ -1237,12 +1215,11 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
ddt_header.blockAlignmentShift = ctx->user_data_ddt_header.blockAlignmentShift;
ddt_header.dataShift = ctx->user_data_ddt_header.dataShift;
ddt_header.tableShift = 0; // Secondary tables are single level
ddt_header.sizeType = ctx->user_data_ddt_header.sizeType;
ddt_header.entries = items_per_ddt_entry;
// Calculate data size
ddt_header.length = items_per_ddt_entry * sizeof(uint32_t);
ddt_header.length = items_per_ddt_entry * sizeof(uint64_t);
// Calculate CRC64 of the data
crc64_context = aaruf_crc64_init();
@@ -1336,13 +1313,13 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
// Update the primary level table entry to point to the new location of the secondary table
uint64_t new_secondary_table_block_offset = end_of_file >> ctx->user_data_ddt_header.blockAlignmentShift;
ctx->user_data_ddt2[ctx->cached_ddt_position] = (uint32_t)new_secondary_table_block_offset;
ctx->user_data_ddt2[ctx->cached_ddt_position] = new_secondary_table_block_offset;
// Write the updated primary table back to its original position in the file
long saved_pos = ftell(ctx->imageStream);
fseek(ctx->imageStream, ctx->primary_ddt_offset + sizeof(DdtHeader2), SEEK_SET);
size_t primary_table_size = ctx->user_data_ddt_header.entries * sizeof(uint32_t);
size_t primary_table_size = ctx->user_data_ddt_header.entries * sizeof(uint64_t);
written_bytes = fwrite(ctx->user_data_ddt2, primary_table_size, 1, ctx->imageStream);
@@ -1414,12 +1391,11 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
ddt_header.blockAlignmentShift = ctx->user_data_ddt_header.blockAlignmentShift;
ddt_header.dataShift = ctx->user_data_ddt_header.dataShift;
ddt_header.tableShift = 0; // Secondary tables are single level
ddt_header.sizeType = ctx->user_data_ddt_header.sizeType;
ddt_header.entries = items_per_ddt_entry;
// Calculate data size
ddt_header.length = items_per_ddt_entry * sizeof(uint32_t);
ddt_header.length = items_per_ddt_entry * sizeof(uint64_t);
// Calculate CRC64 of the data
crc64_context = aaruf_crc64_init();
@@ -1539,13 +1515,13 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
// Update the primary table entry to point to the new location of the secondary table
// Use ddtPosition which was calculated from sectorAddress, not cachedDdtOffset
ctx->user_data_ddt2[ddt_position] = (uint32_t)new_secondary_table_block_offset;
ctx->user_data_ddt2[ddt_position] = new_secondary_table_block_offset;
// Write the updated primary table back to its original position in the file
long saved_pos = ftell(ctx->imageStream);
fseek(ctx->imageStream, ctx->primary_ddt_offset + sizeof(DdtHeader2), SEEK_SET);
size_t primary_table_size = ctx->user_data_ddt_header.entries * sizeof(uint32_t);
size_t primary_table_size = ctx->user_data_ddt_header.entries * sizeof(uint64_t);
written_bytes = fwrite(ctx->user_data_ddt2, primary_table_size, 1, ctx->imageStream);
@@ -1632,7 +1608,7 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
// Cache the loaded table
ctx->cached_secondary_ddt2 = (uint32_t *)buffer;
ctx->cached_secondary_ddt2 = (uint64_t *)buffer;
ctx->cached_ddt_offset = secondary_ddt_offset;
}
@@ -1640,7 +1616,7 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
if(create_new_table)
{
// Create a new empty table
size_t table_size = items_per_ddt_entry * sizeof(uint32_t);
size_t table_size = items_per_ddt_entry * sizeof(uint64_t);
buffer = calloc(1, table_size);
if(buffer == NULL)
@@ -1650,7 +1626,7 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
return false;
}
ctx->cached_secondary_ddt2 = (uint32_t *)buffer;
ctx->cached_secondary_ddt2 = (uint64_t *)buffer;
ctx->cached_ddt_offset = 0; // Will be set when written to file
ctx->cached_ddt_position = ddt_position; // Track which primary DDT position this new table belongs to
@@ -1665,18 +1641,18 @@ bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bo
block_index << ctx->user_data_ddt_header.dataShift;
// Overflow detection for DDT entry
if(*ddt_entry > 0xFFFFFFF)
if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
{
FATAL("DDT overflow: media does not fit in big DDT");
TRACE("Exiting set_ddt_multi_level_v2() = false");
return false;
}
*ddt_entry |= (uint64_t)sector_status << 28;
*ddt_entry |= (uint64_t)sector_status << 60;
}
TRACE("Setting big secondary DDT entry %d to %u", sector_address % items_per_ddt_entry, (uint32_t)*ddt_entry);
ctx->cached_secondary_ddt2[sector_address % items_per_ddt_entry] = (uint32_t)*ddt_entry;
TRACE("Setting big secondary DDT entry %d to %ull", sector_address % items_per_ddt_entry, (uint64_t)*ddt_entry);
ctx->cached_secondary_ddt2[sector_address % items_per_ddt_entry] = *ddt_entry;
TRACE("Updated secondary DDT entry at position %" PRIu64, sector_address % items_per_ddt_entry);
TRACE("Exiting set_ddt_multi_level_v2() = true");
@@ -1827,14 +1803,14 @@ bool set_ddt_tape(aaruformat_context *ctx, uint64_t sector_address, const uint64
*ddt_entry = offset & (1ULL << ctx->user_data_ddt_header.dataShift) - 1 |
block_index << ctx->user_data_ddt_header.dataShift;
// Overflow detection for DDT entry
if(*ddt_entry > 0xFFFFFFF)
if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
{
FATAL("DDT overflow: media does not fit in big DDT");
TRACE("Exiting set_ddt_tape() = false");
return false;
}
*ddt_entry |= (uint64_t)sector_status << 28;
*ddt_entry |= (uint64_t)sector_status << 60;
}
// Create DDT hash entry

View File

@@ -1040,9 +1040,9 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, boo
if(ctx->sector_prefix_ddt2 != NULL)
{
const uint32_t prefix_ddt_entry = ctx->sector_prefix_ddt2[corrected_sector_address];
const uint32_t prefix_status = prefix_ddt_entry >> 28;
const uint32_t prefix_index = prefix_ddt_entry & 0x0FFFFFFF;
const uint64_t prefix_ddt_entry = ctx->sector_prefix_ddt2[corrected_sector_address];
const uint32_t prefix_status = prefix_ddt_entry >> 60;
const uint64_t prefix_index = prefix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
if(prefix_status == SectorStatusMode1Correct)
{
@@ -1087,9 +1087,9 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, boo
if(ctx->sector_suffix_ddt2 != NULL)
{
const uint32_t suffix_ddt_entry = ctx->sector_suffix_ddt2[corrected_sector_address];
const uint32_t suffix_status = suffix_ddt_entry >> 28;
const uint32_t suffix_index = suffix_ddt_entry & 0x0FFFFFFF;
const uint64_t suffix_ddt_entry = ctx->sector_suffix_ddt2[corrected_sector_address];
const uint64_t suffix_status = suffix_ddt_entry >> 60;
const uint64_t suffix_index = suffix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
if(suffix_status == SectorStatusMode1Correct)
{
@@ -1133,9 +1133,9 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, boo
case CdMode2Form2:
if(ctx->sector_prefix_ddt2 != NULL)
{
const uint32_t prefix_ddt_entry = ctx->sector_prefix_ddt2[corrected_sector_address];
const uint32_t prefix_status = prefix_ddt_entry >> 28;
const uint32_t prefix_index = prefix_ddt_entry & 0x0FFFFFFF;
const uint64_t prefix_ddt_entry = ctx->sector_prefix_ddt2[corrected_sector_address];
const uint64_t prefix_status = prefix_ddt_entry >> 60;
const uint64_t prefix_index = prefix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
if(prefix_status == SectorStatusMode2Form1Ok || prefix_status == SectorStatusMode2Form2Ok)
{
@@ -1181,9 +1181,9 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, boo
if(ctx->mode2_subheaders != NULL && ctx->sector_suffix_ddt2 != NULL)
{
memcpy(data + 16, ctx->mode2_subheaders + corrected_sector_address * 8, 8);
const uint32_t suffix_ddt_entry = ctx->sector_suffix_ddt2[corrected_sector_address];
const uint32_t suffix_status = suffix_ddt_entry >> 28;
const uint32_t suffix_index = suffix_ddt_entry & 0x0FFFFFFF;
const uint64_t suffix_ddt_entry = ctx->sector_suffix_ddt2[corrected_sector_address];
const uint64_t suffix_status = suffix_ddt_entry >> 60;
const uint64_t suffix_index = suffix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
if(suffix_status == SectorStatusMode2Form1Ok)
{

View File

@@ -689,7 +689,7 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
if(ctx->sector_prefix_ddt2 == NULL)
{
ctx->sector_prefix_ddt2 =
calloc(1, sizeof(uint32_t) * (ctx->user_data_ddt_header.negative + ctx->image_info.Sectors +
calloc(1, sizeof(uint64_t) * (ctx->user_data_ddt_header.negative + ctx->image_info.Sectors +
ctx->user_data_ddt_header.overflow));
if(ctx->sector_prefix_ddt2 == NULL)
@@ -705,7 +705,7 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
if(ctx->sector_suffix_ddt2 == NULL)
{
ctx->sector_suffix_ddt2 =
calloc(1, sizeof(uint32_t) * (ctx->user_data_ddt_header.negative + ctx->image_info.Sectors +
calloc(1, sizeof(uint64_t) * (ctx->user_data_ddt_header.negative + ctx->image_info.Sectors +
ctx->user_data_ddt_header.overflow));
if(ctx->sector_suffix_ddt2 == NULL)
@@ -783,13 +783,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
}
if(prefix_correct)
ctx->sector_prefix_ddt2[corrected_sector_address] = SectorStatusMode1Correct << 28;
ctx->sector_prefix_ddt2[corrected_sector_address] = (uint64_t)SectorStatusMode1Correct << 60;
else
{
// Copy CD prefix from data buffer to prefix buffer
memcpy(ctx->sector_prefix + ctx->sector_prefix_offset, data, 16);
ctx->sector_prefix_ddt2[corrected_sector_address] = (uint32_t)(ctx->sector_prefix_offset / 16);
ctx->sector_prefix_ddt2[corrected_sector_address] |= SectorStatusErrored << 28;
ctx->sector_prefix_ddt2[corrected_sector_address] = (uint64_t)(ctx->sector_prefix_offset / 16);
ctx->sector_prefix_ddt2[corrected_sector_address] |= (uint64_t)SectorStatusErrored << 60;
ctx->sector_prefix_offset += 16;
// Grow prefix buffer if needed
@@ -811,13 +811,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
const bool suffix_correct = aaruf_ecc_cd_is_suffix_correct(context, data);
if(suffix_correct)
ctx->sector_suffix_ddt2[corrected_sector_address] = SectorStatusMode1Correct << 28;
ctx->sector_suffix_ddt2[corrected_sector_address] = SectorStatusMode1Correct << 60;
else
{
// Copy CD suffix from data buffer to suffix buffer
memcpy(ctx->sector_suffix + ctx->sector_suffix_offset, data + 2064, 288);
ctx->sector_suffix_ddt2[corrected_sector_address] = (uint32_t)(ctx->sector_suffix_offset / 288);
ctx->sector_suffix_ddt2[corrected_sector_address] |= SectorStatusErrored << 28;
ctx->sector_suffix_ddt2[corrected_sector_address] = (uint64_t)(ctx->sector_suffix_offset / 288);
ctx->sector_suffix_ddt2[corrected_sector_address] |= SectorStatusErrored << 60;
ctx->sector_suffix_offset += 288;
// Grow suffix buffer if needed
@@ -845,7 +845,7 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
if(ctx->sector_prefix_ddt2 == NULL)
{
ctx->sector_prefix_ddt2 =
calloc(1, sizeof(uint32_t) * (ctx->user_data_ddt_header.negative + ctx->image_info.Sectors +
calloc(1, sizeof(uint64_t) * (ctx->user_data_ddt_header.negative + ctx->image_info.Sectors +
ctx->user_data_ddt_header.overflow));
if(ctx->sector_prefix_ddt2 == NULL)
@@ -861,7 +861,7 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
if(ctx->sector_suffix_ddt2 == NULL)
{
ctx->sector_suffix_ddt2 =
calloc(1, sizeof(uint32_t) * (ctx->user_data_ddt_header.negative + ctx->image_info.Sectors +
calloc(1, sizeof(uint64_t) * (ctx->user_data_ddt_header.negative + ctx->image_info.Sectors +
ctx->user_data_ddt_header.overflow));
if(ctx->sector_suffix_ddt2 == NULL)
@@ -942,13 +942,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
if(prefix_correct)
ctx->sector_prefix_ddt2[corrected_sector_address] =
(form2 ? SectorStatusMode2Form2Ok : SectorStatusMode2Form1Ok) << 28;
(form2 ? SectorStatusMode2Form2Ok : SectorStatusMode2Form1Ok) << 60;
else
{
// Copy CD prefix from data buffer to prefix buffer
memcpy(ctx->sector_prefix + ctx->sector_prefix_offset, data, 16);
ctx->sector_prefix_ddt2[corrected_sector_address] = (uint32_t)(ctx->sector_prefix_offset / 16);
ctx->sector_prefix_ddt2[corrected_sector_address] |= SectorStatusErrored << 28;
ctx->sector_prefix_ddt2[corrected_sector_address] |= (uint64_t)SectorStatusErrored << 60;
ctx->sector_prefix_offset += 16;
// Grow prefix buffer if needed
@@ -990,16 +990,16 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
const bool correct_edc = computed_edc == edc;
if(correct_edc)
ctx->sector_suffix_ddt2[corrected_sector_address] = SectorStatusMode2Form2Ok << 28;
ctx->sector_suffix_ddt2[corrected_sector_address] = SectorStatusMode2Form2Ok << 60;
else if(edc == 0)
ctx->sector_suffix_ddt2[corrected_sector_address] = SectorStatusMode2Form2NoCrc << 28;
ctx->sector_suffix_ddt2[corrected_sector_address] = SectorStatusMode2Form2NoCrc << 60;
else
{
// Copy CD suffix from data buffer to suffix buffer
memcpy(ctx->sector_suffix + ctx->sector_suffix_offset, data + 2348, 4);
ctx->sector_suffix_ddt2[corrected_sector_address] =
(uint32_t)(ctx->sector_suffix_offset / 288);
ctx->sector_suffix_ddt2[corrected_sector_address] |= SectorStatusErrored << 28;
(uint64_t)(ctx->sector_suffix_offset / 288);
ctx->sector_suffix_ddt2[corrected_sector_address] |= SectorStatusErrored << 60;
ctx->sector_suffix_offset += 288;
// Grow suffix buffer if needed
@@ -1034,13 +1034,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
const bool correct_edc = computed_edc == edc;
if(correct_ecc && correct_edc)
ctx->sector_suffix_ddt2[corrected_sector_address] = SectorStatusMode2Form1Ok << 28;
ctx->sector_suffix_ddt2[corrected_sector_address] = SectorStatusMode2Form1Ok << 60;
else
{
// Copy CD suffix from data buffer to suffix buffer
memcpy(ctx->sector_suffix + ctx->sector_suffix_offset, data + 2072, 280);
ctx->sector_suffix_ddt2[corrected_sector_address] = (uint32_t)(ctx->sector_suffix_offset / 288);
ctx->sector_suffix_ddt2[corrected_sector_address] |= SectorStatusErrored << 28;
ctx->sector_suffix_ddt2[corrected_sector_address] = (uint64_t)(ctx->sector_suffix_offset / 288);
ctx->sector_suffix_ddt2[corrected_sector_address] |= SectorStatusErrored << 60;
ctx->sector_suffix_offset += 288;
// Grow suffix buffer if needed

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -121,14 +121,14 @@ TEST_F(OpenImageFixture, open_mf2hd_v2)
// Basic sanity checks on the image info
ASSERT_EQ(image_info.HasPartitions, false) << "Image should not have partitions";
ASSERT_EQ(image_info.HasSessions, false) << "Image should not have sessions";
ASSERT_EQ(image_info.ImageSize, 49786) << "Unexpected image size";
ASSERT_EQ(image_info.ImageSize, 49802) << "Unexpected image size";
ASSERT_EQ(image_info.Sectors, 2880) << "Unexpected number of sectors";
ASSERT_EQ(image_info.SectorSize, 512) << "Unexpected sector size";
ASSERT_STREQ(image_info.Version, "2.0") << "Unexpected image version";
ASSERT_STREQ(image_info.Application, "aaruformattool") << "Unexpected application name";
ASSERT_STREQ(image_info.ApplicationVersion, "1.0") << "Unexpected application version";
ASSERT_EQ(image_info.CreationTime, 134045021233497730ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045021233497730ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.CreationTime, 134045317128230560ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045317128230560ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.MediaType, 199) << "Unexpected media type";
ASSERT_EQ(image_info.MetadataMediaType, 1) << "Unexpected metadata media type";
@@ -237,14 +237,14 @@ TEST_F(OpenImageFixture, open_floptical_v2)
// Basic sanity checks on the image info
ASSERT_EQ(image_info.HasPartitions, false) << "Image should not have partitions";
ASSERT_EQ(image_info.HasSessions, false) << "Image should not have sessions";
ASSERT_EQ(image_info.ImageSize, 115) << "Unexpected image size";
ASSERT_EQ(image_info.ImageSize, 142) << "Unexpected image size";
ASSERT_EQ(image_info.Sectors, 40662) << "Unexpected number of sectors";
ASSERT_EQ(image_info.SectorSize, 512) << "Unexpected sector size";
ASSERT_STREQ(image_info.Version, "2.0") << "Unexpected image version";
ASSERT_STREQ(image_info.Application, "aaruformattool") << "Unexpected application name";
ASSERT_STREQ(image_info.ApplicationVersion, "1.0") << "Unexpected application version";
ASSERT_EQ(image_info.CreationTime, 134045021406383110ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045021406383110ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.CreationTime, 134045315488892290ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045315488892290ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.MediaType, 662) << "Unexpected media type";
ASSERT_EQ(image_info.MetadataMediaType, 1) << "Unexpected metadata media type";
@@ -353,14 +353,14 @@ TEST_F(OpenImageFixture, open_gigamo_v2)
// Basic sanity checks on the image info
ASSERT_EQ(image_info.HasPartitions, false) << "Image should not have partitions";
ASSERT_EQ(image_info.HasSessions, false) << "Image should not have sessions";
ASSERT_EQ(image_info.ImageSize, 445) << "Unexpected image size";
ASSERT_EQ(image_info.ImageSize, 790) << "Unexpected image size";
ASSERT_EQ(image_info.Sectors, 605846) << "Unexpected number of sectors";
ASSERT_EQ(image_info.SectorSize, 2048) << "Unexpected sector size";
ASSERT_STREQ(image_info.Version, "2.0") << "Unexpected image version";
ASSERT_STREQ(image_info.Application, "aaruformattool") << "Unexpected application name";
ASSERT_STREQ(image_info.ApplicationVersion, "1.0") << "Unexpected application version";
ASSERT_EQ(image_info.CreationTime, 134045021623404660ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045021623404660ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.CreationTime, 134045315684449130ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045315684449130ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.MediaType, 653) << "Unexpected media type";
ASSERT_EQ(image_info.MetadataMediaType, 1) << "Unexpected metadata media type";
@@ -469,14 +469,14 @@ TEST_F(OpenImageFixture, open_hifd_v2)
// Basic sanity checks on the image info
ASSERT_EQ(image_info.HasPartitions, false) << "Image should not have partitions";
ASSERT_EQ(image_info.HasSessions, false) << "Image should not have sessions";
ASSERT_EQ(image_info.ImageSize, 811) << "Unexpected image size";
ASSERT_EQ(image_info.ImageSize, 1035) << "Unexpected image size";
ASSERT_EQ(image_info.Sectors, 393380) << "Unexpected number of sectors";
ASSERT_EQ(image_info.SectorSize, 512) << "Unexpected sector size";
ASSERT_STREQ(image_info.Version, "2.0") << "Unexpected image version";
ASSERT_STREQ(image_info.Application, "aaruformattool") << "Unexpected application name";
ASSERT_STREQ(image_info.ApplicationVersion, "1.0") << "Unexpected application version";
ASSERT_EQ(image_info.CreationTime, 134045022447255050ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045022447255050ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.CreationTime, 134045316523097400ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045316523097400ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.MediaType, 663) << "Unexpected media type";
ASSERT_EQ(image_info.MetadataMediaType, 1) << "Unexpected metadata media type";
@@ -585,14 +585,14 @@ TEST_F(OpenImageFixture, open_mo540_v2)
// Basic sanity checks on the image info
ASSERT_EQ(image_info.HasPartitions, false) << "Image should not have partitions";
ASSERT_EQ(image_info.HasSessions, false) << "Image should not have sessions";
ASSERT_EQ(image_info.ImageSize, 682) << "Unexpected image size";
ASSERT_EQ(image_info.ImageSize, 1273) << "Unexpected image size";
ASSERT_EQ(image_info.Sectors, 1041500) << "Unexpected number of sectors";
ASSERT_EQ(image_info.SectorSize, 512) << "Unexpected sector size";
ASSERT_STREQ(image_info.Version, "2.0") << "Unexpected image version";
ASSERT_STREQ(image_info.Application, "aaruformattool") << "Unexpected application name";
ASSERT_STREQ(image_info.ApplicationVersion, "1.0") << "Unexpected application version";
ASSERT_EQ(image_info.CreationTime, 134045023010340070ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045023010340070ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.CreationTime, 134045317276362850ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045317276362850ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.MediaType, 1) << "Unexpected media type";
ASSERT_EQ(image_info.MetadataMediaType, 1) << "Unexpected metadata media type";
@@ -701,14 +701,14 @@ TEST_F(OpenImageFixture, open_mo640_v2)
// Basic sanity checks on the image info
ASSERT_EQ(image_info.HasPartitions, false) << "Image should not have partitions";
ASSERT_EQ(image_info.HasSessions, false) << "Image should not have sessions";
ASSERT_EQ(image_info.ImageSize, 378) << "Unexpected image size";
ASSERT_EQ(image_info.ImageSize, 556) << "Unexpected image size";
ASSERT_EQ(image_info.Sectors, 310352) << "Unexpected number of sectors";
ASSERT_EQ(image_info.SectorSize, 2048) << "Unexpected sector size";
ASSERT_STREQ(image_info.Version, "2.0") << "Unexpected image version";
ASSERT_STREQ(image_info.Application, "aaruformattool") << "Unexpected application name";
ASSERT_STREQ(image_info.ApplicationVersion, "1.0") << "Unexpected application version";
ASSERT_EQ(image_info.CreationTime, 134045024110831840ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045024110831840ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.CreationTime, 134045318614141420ULL) << "Unexpected creation time";
ASSERT_EQ(image_info.LastModificationTime, 134045318614141420ULL) << "Unexpected modification time";
ASSERT_EQ(image_info.MediaType, 646) << "Unexpected media type";
ASSERT_EQ(image_info.MetadataMediaType, 1) << "Unexpected metadata media type";