98 TRACE(
"Entering process_ddt_v2(%p, %p, %d)", ctx, entry, *found_user_data_ddt);
101 size_t read_bytes = 0;
103 uint8_t *cmp_data = NULL;
105 size_t lzma_size = 0;
109 uint8_t *buffer = NULL;
114 FATAL(
"Invalid context or image stream.");
116 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_NOT_AARUFORMAT");
124 FATAL(
"Could not seek to %" PRIu64
" as indicated by index entry...", entry->
offset);
126 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
131 TRACE(
"Reading DDT block header at position %" PRIu64, entry->
offset);
136 FATAL(
"Could not read block header at %" PRIu64
"", entry->
offset);
138 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
160 FATAL(
"Compressed DDT payload too small (%" PRIu64
") for LZMA properties.", ddt_header.
cmpLength);
161 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
167 cmp_data = (uint8_t *)malloc(lzma_size);
170 TRACE(
"Cannot allocate memory for DDT, continuing...");
174 buffer = malloc(ddt_header.
length);
177 TRACE(
"Cannot allocate memory for DDT, continuing...");
185 TRACE(
"Could not read LZMA properties, continuing...");
191 read_bytes = fread(cmp_data, 1, lzma_size, ctx->
imageStream);
192 if(read_bytes != lzma_size)
194 TRACE(
"Could not read compressed block, continuing...");
200 read_bytes = ddt_header.
length;
201 TRACE(
"Decompressing block of size %zu bytes", ddt_header.
length);
207 FATAL(
"Got error %d from LZMA, stopping...", error_no);
210 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
214 if(read_bytes != ddt_header.
length)
216 FATAL(
"Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
219 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
227 if(crc64_context == NULL)
229 FATAL(
"Could not initialize CRC64.");
232 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
240 if(crc64 != ddt_header.
crc64)
242 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
244 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
251 *found_user_data_ddt =
true;
255 buffer = malloc(ddt_header.
length);
259 TRACE(
"Cannot allocate memory for DDT, continuing...");
263 TRACE(
"Reading DDT of length %zu bytes", ddt_header.
length);
266 if(read_bytes != ddt_header.
length)
269 FATAL(
"Could not read deduplication table, continuing...");
275 if(crc64_context == NULL)
277 FATAL(
"Could not initialize CRC64.");
279 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
287 if(crc64 != ddt_header.
crc64)
289 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
291 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
298 *found_user_data_ddt =
true;
302 TRACE(
"Found unknown compression type %d, continuing...", ddt_header.
compression);
303 *found_user_data_ddt =
false;
313 FATAL(
"Compressed DDT payload too small (%" PRIu64
") for LZMA properties.", ddt_header.
cmpLength);
314 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
320 cmp_data = (uint8_t *)malloc(lzma_size);
323 TRACE(
"Cannot allocate memory for DDT, continuing...");
327 buffer = malloc(ddt_header.
length);
330 TRACE(
"Cannot allocate memory for DDT, continuing...");
338 TRACE(
"Could not read LZMA properties, continuing...");
344 read_bytes = fread(cmp_data, 1, lzma_size, ctx->
imageStream);
345 if(read_bytes != lzma_size)
347 TRACE(
"Could not read compressed block, continuing...");
353 read_bytes = ddt_header.
length;
354 TRACE(
"Decompressing block of size %zu bytes", ddt_header.
length);
360 FATAL(
"Got error %d from LZMA, stopping...", error_no);
363 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
367 if(read_bytes != ddt_header.
length)
369 FATAL(
"Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
372 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
381 if(crc64_context == NULL)
383 FATAL(
"Could not initialize CRC64.");
385 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
393 if(crc64 != ddt_header.
crc64)
395 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
397 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
411 buffer = malloc(ddt_header.
length);
415 TRACE(
"Cannot allocate memory for deduplication table.");
421 if(read_bytes != ddt_header.
length)
424 FATAL(
"Could not read deduplication table, continuing...");
430 if(crc64_context == NULL)
432 FATAL(
"Could not initialize CRC64.");
434 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
442 if(crc64 != ddt_header.
crc64)
444 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
446 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
459 TRACE(
"Found unknown compression type %d, continuing...", ddt_header.
compression);
463 TRACE(
"Exiting process_ddt_v2() = AARUF_STATUS_OK");
512 uint64_t *block_offset, uint8_t *sector_status)
514 TRACE(
"Entering decode_ddt_entry_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative, *offset,
515 *block_offset, *sector_status);
519 FATAL(
"Invalid context or image stream.");
521 TRACE(
"Exiting decode_ddt_entry_v2() = AARUF_ERROR_NOT_AARUFORMAT");
586 uint64_t *block_offset, uint8_t *sector_status)
588 TRACE(
"Entering decode_ddt_single_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative,
589 *offset, *block_offset, *sector_status);
591 uint64_t ddt_entry = 0;
596 FATAL(
"Invalid context or image stream.");
598 TRACE(
"Exiting decode_ddt_single_level_v2() = AARUF_ERROR_NOT_AARUFORMAT");
605 FATAL(
"DDT table shift is not zero, but we are in single-level DDT decoding.");
606 TRACE(
"Exiting decode_ddt_single_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
623 TRACE(
"Exiting decode_ddt_single_level_v2(%p, %" PRIu64
", %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
624 sector_address, *offset, *block_offset, *sector_status);
628 *sector_status = ddt_entry >> 60;
629 ddt_entry &= 0xFFFFFFFFFFFFFFF;
632 *offset = ddt_entry & offset_mask;
636 TRACE(
"Exiting decode_ddt_single_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
637 sector_address, negative, *offset, *block_offset, *sector_status);
729 uint64_t *block_offset, uint8_t *sector_status)
731 TRACE(
"Entering decode_ddt_multi_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative,
732 *offset, *block_offset, *sector_status);
734 uint64_t ddt_entry = 0;
736 size_t lzma_size = 0;
737 uint8_t *cmp_data = NULL;
738 uint8_t *buffer = NULL;
741 int items_per_ddt_entry = 0;
742 uint64_t ddt_position = 0;
743 uint64_t secondary_ddt_offset = 0;
748 FATAL(
"Invalid context or image stream.");
750 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_NOT_AARUFORMAT");
757 FATAL(
"DDT table shift is zero, but we are in multi-level DDT decoding.");
758 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
769 ddt_position = sector_address / items_per_ddt_entry;
778 int32_t error_no = 0;
779 fseek(ctx->
imageStream, secondary_ddt_offset, SEEK_SET);
785 FATAL(
"Could not read block header at %" PRIu64
"", secondary_ddt_offset);
786 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
794 FATAL(
"Invalid block header at %" PRIu64
"", secondary_ddt_offset);
795 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
805 FATAL(
"Compressed DDT payload too small (%" PRIu64
") for LZMA properties.", ddt_header.
cmpLength);
806 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
812 cmp_data = (uint8_t *)malloc(lzma_size);
815 FATAL(
"Cannot allocate memory for DDT, stopping...");
816 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
820 buffer = malloc(ddt_header.
length);
823 FATAL(
"Cannot allocate memory for DDT, stopping...");
831 FATAL(
"Could not read LZMA properties, stopping...");
834 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
838 read_bytes = fread(cmp_data, 1, lzma_size, ctx->
imageStream);
839 if(read_bytes != lzma_size)
841 FATAL(
"Could not read compressed block, stopping...");
844 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
848 TRACE(
"Decompressing block of size %zu bytes", ddt_header.
length);
849 read_bytes = ddt_header.
length;
855 FATAL(
"Got error %d from LZMA, stopping...", error_no);
858 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
862 if(read_bytes != ddt_header.
length)
864 FATAL(
"Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
867 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
875 if(crc64_context == NULL)
877 FATAL(
"Could not initialize CRC64.");
879 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
887 if(crc64 != ddt_header.
crc64)
889 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
891 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
904 buffer = malloc(ddt_header.
length);
908 FATAL(
"Cannot allocate memory for DDT, stopping...");
909 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
915 if(read_bytes != ddt_header.
length)
918 FATAL(
"Could not read deduplication table, stopping...");
919 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
925 if(crc64_context == NULL)
927 FATAL(
"Could not initialize CRC64.");
929 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
937 if(crc64 != ddt_header.
crc64)
939 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
941 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
954 FATAL(
"Found unknown compression type %d, stopping...", ddt_header.
compression);
955 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
968 TRACE(
"Exiting decode_ddt_multi_level_v2(%p, %" PRIu64
", %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
969 sector_address, *offset, *block_offset, *sector_status);
973 *sector_status = ddt_entry >> 60;
974 ddt_entry &= 0x0FFFFFFFFFFFFFFF;
977 *offset = ddt_entry & offset_mask;
981 TRACE(
"Exiting decode_ddt_multi_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
982 sector_address, negative, *offset, *block_offset, *sector_status);
1003 const uint64_t offset,
const uint64_t block_offset,
const uint8_t sector_status,
1004 uint64_t *ddt_entry)
1006 TRACE(
"Entering set_ddt_entry_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative, offset,
1007 block_offset, sector_status);
1012 FATAL(
"Invalid context or image stream.");
1017 return set_ddt_multi_level_v2(ctx, sector_address, negative, offset, block_offset, sector_status, ddt_entry);
1019 return set_ddt_single_level_v2(ctx, sector_address, negative, offset, block_offset, sector_status, ddt_entry);
1039 const uint64_t offset,
const uint64_t block_offset,
const uint8_t sector_status,
1040 uint64_t *ddt_entry)
1042 TRACE(
"Entering set_ddt_single_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative,
1043 offset, block_offset, sector_status);
1048 FATAL(
"Invalid context or image stream.");
1049 TRACE(
"Exiting set_ddt_single_level_v2() = false");
1056 FATAL(
"DDT table shift is not zero, but we are in single-level DDT setting.");
1057 TRACE(
"Exiting set_ddt_single_level_v2() = false");
1074 if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
1076 FATAL(
"DDT overflow: media does not fit in big DDT");
1077 TRACE(
"Exiting set_ddt_single_level_v2() = false");
1083 *ddt_entry &= 0x0FFFFFFFFFFFFFFF;
1084 *ddt_entry |= (uint64_t)sector_status << 60;
1086 TRACE(
"Setting big single-level DDT entry %d to %ull", sector_address, (uint64_t)*ddt_entry);
1090 TRACE(
"Exiting set_ddt_single_level_v2() = true");
1111 uint64_t block_offset, uint8_t sector_status, uint64_t *ddt_entry)
1113 TRACE(
"Entering set_ddt_multi_level_v2(%p, %" PRIu64
", %d, %" PRIu64
", %" PRIu64
", %d)", ctx, sector_address,
1114 negative, offset, block_offset, sector_status);
1116 uint64_t items_per_ddt_entry = 0;
1117 uint64_t ddt_position = 0;
1118 uint64_t secondary_ddt_offset = 0;
1119 uint64_t block_index = 0;
1120 uint8_t *buffer = NULL;
1124 size_t written_bytes = 0;
1125 long end_of_file = 0;
1126 bool create_new_table =
false;
1131 FATAL(
"Invalid context or image stream.");
1132 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1139 FATAL(
"DDT table shift is zero, but we are in multi-level DDT setting.");
1140 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1152 ddt_position = sector_address / items_per_ddt_entry;
1169 if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
1171 FATAL(
"DDT overflow: media does not fit in big DDT");
1172 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1178 *ddt_entry &= 0x0FFFFFFFFFFFFFFF;
1179 *ddt_entry |= (uint64_t)sector_status << 60;
1181 TRACE(
"Setting small secondary DDT entry %d to %ull", sector_address % items_per_ddt_entry,
1182 (uint64_t)*ddt_entry);
1186 TRACE(
"Updated cached secondary DDT entry at position %" PRIu64, sector_address % items_per_ddt_entry);
1187 TRACE(
"Exiting set_ddt_multi_level_v2() = true");
1198 TRACE(
"Current secondary DDT in memory belongs to position %" PRIu64
1199 " but requested block needs position %" PRIu64,
1213 end_of_file = end_of_file + alignment_mask & ~alignment_mask;
1225 ddt_header.
blocks = items_per_ddt_entry;
1231 ddt_header.
entries = items_per_ddt_entry;
1235 ddt_header.
length = items_per_ddt_entry *
sizeof(uint64_t);
1239 if(crc64_context == NULL)
1241 FATAL(
"Could not initialize CRC64.");
1242 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1250 ddt_header.
crc64 = crc64;
1252 uint8_t *cmp_buffer = NULL;
1263 cmp_buffer = malloc((
size_t)ddt_header.
length * 2);
1264 if(cmp_buffer == NULL)
1266 TRACE(
"Failed to allocate memory for secondary DDT v2 compression");
1270 size_t dst_size = (size_t)ddt_header.
length * 2 * 2;
1276 ddt_header.
cmpLength = (uint32_t)dst_size;
1299 if(written_bytes != 1)
1301 FATAL(
"Could not write never-written DDT header to file.");
1302 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1311 FATAL(
"Could not write never-written DDT data to file.");
1312 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1322 new_ddt_entry.
offset = end_of_file;
1326 TRACE(
"Added new DDT index entry for never-written table at offset %" PRIu64, end_of_file);
1342 if(written_bytes != 1)
1344 FATAL(
"Could not flush primary DDT table to file after writing never-written secondary table.");
1345 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1351 ctx->
next_block_position = end_of_file + ddt_total_size + alignment_mask & ~alignment_mask;
1368 TRACE(
"Successfully wrote never-written cached secondary DDT to disk");
1372 TRACE(
"Cached DDT is for the correct block range, using it directly");
1379 long current_pos = 0;
1390 end_of_file = end_of_file + alignment_mask & ~alignment_mask;
1402 ddt_header.
blocks = items_per_ddt_entry;
1404 ddt_header.
start = ddt_position * items_per_ddt_entry;
1408 ddt_header.
entries = items_per_ddt_entry;
1412 ddt_header.
length = items_per_ddt_entry *
sizeof(uint64_t);
1416 if(crc64_context == NULL)
1418 FATAL(
"Could not initialize CRC64.");
1419 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1427 ddt_header.
crc64 = crc64;
1429 uint8_t *cmp_buffer = NULL;
1440 cmp_buffer = malloc((
size_t)ddt_header.
length * 2);
1441 if(cmp_buffer == NULL)
1443 TRACE(
"Failed to allocate memory for secondary DDT v2 compression");
1447 size_t dst_size = (size_t)ddt_header.
length * 2 * 2;
1450 lzma_properties, &props_size, 9, ctx->
lzma_dict_size, 4, 0, 2, 273, 8);
1452 ddt_header.
cmpLength = (uint32_t)dst_size;
1477 if(written_bytes != 1)
1479 FATAL(
"Could not write DDT header to file.");
1480 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1487 if(written_bytes != 1)
1489 FATAL(
"Could not write DDT data to file.");
1490 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1497 TRACE(
"Updating index for evicted secondary DDT");
1506 for(
unsigned int i = 0; i < utarray_len(ctx->
index_entries); i++)
1512 TRACE(
"Found old DDT index entry at position %u, removing", i);
1523 new_ddt_entry.
offset = end_of_file;
1527 TRACE(
"Added new DDT index entry at offset %" PRIu64, end_of_file);
1535 ctx->
user_data_ddt2[ddt_position] = new_secondary_table_block_offset;
1546 if(written_bytes != 1)
1548 FATAL(
"Could not flush primary DDT table to file.");
1549 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1555 ctx->
next_block_position = end_of_file + ddt_total_size + alignment_mask & ~alignment_mask;
1574 if(!create_new_table && secondary_ddt_offset != 0)
1577 fseek(ctx->
imageStream, secondary_ddt_offset, SEEK_SET);
1583 FATAL(
"Invalid secondary DDT header at %" PRIu64, secondary_ddt_offset);
1584 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1589 buffer = malloc(ddt_header.
length);
1592 FATAL(
"Cannot allocate memory for secondary DDT.");
1593 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1598 if(read_bytes != ddt_header.
length)
1600 FATAL(
"Could not read secondary DDT data.");
1602 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1608 if(crc64_context == NULL)
1610 FATAL(
"Could not initialize CRC64.");
1612 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1620 if(crc64 != ddt_header.
crc64)
1622 FATAL(
"Secondary DDT CRC mismatch. Expected 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
1624 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1635 if(create_new_table)
1638 size_t table_size = items_per_ddt_entry *
sizeof(uint64_t);
1640 buffer = calloc(1, table_size);
1643 FATAL(
"Cannot allocate memory for new secondary DDT.");
1644 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1652 TRACE(
"Created new secondary DDT for position %" PRIu64, ddt_position);
1663 if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
1665 FATAL(
"DDT overflow: media does not fit in big DDT");
1666 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1672 *ddt_entry &= 0x0FFFFFFFFFFFFFFF;
1673 *ddt_entry |= (uint64_t)sector_status << 60;
1675 TRACE(
"Setting big secondary DDT entry %d to %ull", sector_address % items_per_ddt_entry, (uint64_t)*ddt_entry);
1679 TRACE(
"Updated secondary DDT entry at position %" PRIu64, sector_address % items_per_ddt_entry);
1680 TRACE(
"Exiting set_ddt_multi_level_v2() = true");
1801 const uint8_t sector_status, uint64_t *ddt_entry)
1803 TRACE(
"Entering set_ddt_tape(%p, %" PRIu64
", %llu, %llu, %d)", ctx, sector_address, offset, block_offset,
1809 FATAL(
"Invalid context or image stream.");
1810 TRACE(
"Exiting set_ddt_tape() = false");
1817 FATAL(
"Image is not tape, wrong function called.");
1818 TRACE(
"Exiting set_ddt_tape() = false");
1828 if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
1830 FATAL(
"DDT overflow: media does not fit in big DDT");
1831 TRACE(
"Exiting set_ddt_tape() = false");
1835 *ddt_entry |= (uint64_t)sector_status << 60;
1841 if(new_entry == NULL)
1843 FATAL(
"Cannot allocate memory for new tape DDT hash entry.");
1844 TRACE(
"Exiting set_ddt_tape() = false");
1848 TRACE(
"Setting tape DDT entry %d to %u", sector_address, (uint32_t)*ddt_entry);
1850 new_entry->
key = sector_address;
1851 new_entry->
value = *ddt_entry;
1854 HASH_REPLACE(hh, ctx->
tape_ddt, key,
sizeof(uint64_t), new_entry, old_entry);
1856 if(old_entry) free(old_entry);
1858 TRACE(
"Exiting set_ddt_tape() = true");
#define LZMA_PROPERTIES_LENGTH
Size in bytes of the fixed LZMA properties header (lc/lp/pb + dictionary size).
int32_t process_ddt_v2(aaruformat_context *ctx, IndexEntry *entry, bool *found_user_data_ddt)
Processes a DDT v2 block from the image stream.
bool set_ddt_tape(aaruformat_context *ctx, uint64_t sector_address, const uint64_t offset, const uint64_t block_offset, const uint8_t sector_status, uint64_t *ddt_entry)
Sets a DDT entry for tape media using a hash-based lookup table.
int32_t decode_ddt_single_level_v2(aaruformat_context *ctx, uint64_t sector_address, bool negative, uint64_t *offset, uint64_t *block_offset, uint8_t *sector_status)
Decodes a single-level DDT v2 entry for a given sector address.
bool set_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bool negative, uint64_t offset, uint64_t block_offset, uint8_t sector_status, uint64_t *ddt_entry)
Sets a multi-level DDT v2 entry for a given sector address.
bool set_ddt_entry_v2(aaruformat_context *ctx, const uint64_t sector_address, const bool negative, const uint64_t offset, const uint64_t block_offset, const uint8_t sector_status, uint64_t *ddt_entry)
Sets a DDT v2 entry for a given sector address.
int32_t decode_ddt_multi_level_v2(aaruformat_context *ctx, uint64_t sector_address, bool negative, uint64_t *offset, uint64_t *block_offset, uint8_t *sector_status)
Decodes a multi-level DDT v2 entry for a given sector address.
bool set_ddt_single_level_v2(aaruformat_context *ctx, uint64_t sector_address, const bool negative, const uint64_t offset, const uint64_t block_offset, const uint8_t sector_status, uint64_t *ddt_entry)
Sets a single-level DDT v2 entry for a given sector address.
int32_t decode_ddt_entry_v2(aaruformat_context *ctx, const uint64_t sector_address, bool negative, uint64_t *offset, uint64_t *block_offset, uint8_t *sector_status)
Decodes a DDT v2 entry for a given sector address.
int32_t aaruf_lzma_encode_buffer(uint8_t *dst_buffer, size_t *dst_size, const uint8_t *src_buffer, size_t src_size, uint8_t *out_props, size_t *out_props_size, int32_t level, uint32_t dict_size, int32_t lc, int32_t lp, int32_t pb, int32_t fb, int32_t num_threads)
Encodes a buffer using LZMA compression.
uint64_t aaruf_crc64_data(const uint8_t *data, uint32_t len)
int32_t aaruf_lzma_decode_buffer(uint8_t *dst_buffer, size_t *dst_size, const uint8_t *src_buffer, size_t *src_size, const uint8_t *props, size_t props_size)
Decodes an LZMA-compressed buffer.
int aaruf_crc64_update(crc64_ctx *ctx, const uint8_t *data, uint32_t len)
Updates the CRC64 context with new data.
void aaruf_crc64_free(crc64_ctx *ctx)
Frees a CRC64 context.
crc64_ctx * aaruf_crc64_init()
Initializes a CRC64 context.
int aaruf_crc64_final(crc64_ctx *ctx, uint64_t *crc)
Computes the final CRC64 value from the context.
@ DeDuplicationTableSecondary
Block containing a secondary deduplication table (v2).
@ DeDuplicationTable2
Block containing a deduplication table v2.
@ DeDuplicationTableSAlpha
Block containing a secondary deduplication table (v2) (mistake).
@ SectorStatusNotDumped
Sector(s) not yet acquired during image dumping.
@ CdSectorPrefix
Compact Disc sector prefix (sync, header).
@ UserData
User (main) data.
@ CdSectorSuffix
Compact Disc sector suffix (EDC, ECC P, ECC Q).
#define AARUF_STATUS_OK
Sector present and read without uncorrectable errors.
#define AARUF_ERROR_NOT_ENOUGH_MEMORY
Memory allocation failure (critical).
#define AARUF_ERROR_CANNOT_READ_BLOCK
Generic block read failure (seek/read error).
#define AARUF_ERROR_INVALID_BLOCK_CRC
CRC64 mismatch indicating corruption.
#define AARUF_ERROR_NOT_AARUFORMAT
Input file/stream failed magic or structural validation.
#define AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK
Decompression routine failed or size mismatch.
int32_t aaruf_close_current_block(aaruformat_context *ctx)
Finalizes and writes the current data block to the AaruFormat image file.
uint64_t ImageSize
Size of the image payload in bytes (excludes headers/metadata).
uint64_t Sectors
Total count of addressable logical sectors/blocks.
Single index entry describing a block's type, (optional) data classification, and file offset.
uint32_t blockType
Block identifier of the referenced block (value from BlockType).
uint64_t offset
Absolute byte offset in the image where the referenced block header begins.
uint16_t dataType
Data classification (value from DataType) or unused for untyped blocks.
uint64_t key
Key: sector address.
uint64_t value
Value: DDT entry.
Master context representing an open or in‑creation Aaru image.
DdtHeader2 user_data_ddt_header
Active user data DDT v2 header (primary table meta).
bool compression_enabled
True if block compression enabled (writing path).
bool dirty_primary_ddt
True if primary DDT table should be written during close.
uint64_t * user_data_ddt2
DDT entries (big variant) primary/secondary current.
uint64_t * sector_suffix_ddt2
CD sector suffix DDT V2.
uint64_t cached_ddt_offset
File offset of currently cached secondary DDT (0=none).
bool is_tape
True if the image is a tape image.
bool in_memory_ddt
True if primary (and possibly secondary) DDT loaded.
bool dirty_index_block
True if index block should be written during close.
TapeDdtHashEntry * tape_ddt
Hash table root for tape DDT entries.
bool dirty_single_level_ddt
True if single-level DDT should be written during close.
int ddt_version
DDT version in use (1=legacy, 2=v2 hierarchical).
uint8_t * writing_buffer
Accumulation buffer for current block data.
uint64_t * sector_prefix_ddt2
CD sector prefix DDT V2.
uint64_t primary_ddt_offset
File offset of the primary DDT v2 table.
uint64_t next_block_position
Absolute file offset where next block will be written.
uint64_t * cached_secondary_ddt2
Cached secondary table (big entries) or NULL.
FILE * imageStream
Underlying FILE* stream (binary mode).
UT_array * index_entries
Flattened index entries (UT_array of IndexEntry).
ImageInfo image_info
Exposed high-level image info summary.
bool dirty_secondary_ddt
True if secondary DDT tables should be written during close.
bool dirty_tape_ddt
True if tape DDT should be written during close.
uint32_t lzma_dict_size
LZMA dictionary size (writing path).
uint64_t cached_ddt_position
Position index of cached secondary DDT.
Minimal ECMA-182 CRC64 incremental state container (running value only).