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");
239 if(crc64 != ddt_header.
crc64)
241 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
243 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
250 *found_user_data_ddt =
true;
254 buffer = malloc(ddt_header.
length);
258 TRACE(
"Cannot allocate memory for DDT, continuing...");
262 TRACE(
"Reading DDT of length %zu bytes", ddt_header.
length);
265 if(read_bytes != ddt_header.
length)
268 FATAL(
"Could not read deduplication table, continuing...");
274 if(crc64_context == NULL)
276 FATAL(
"Could not initialize CRC64.");
278 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
285 if(crc64 != ddt_header.
crc64)
287 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
289 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
296 *found_user_data_ddt =
true;
300 TRACE(
"Found unknown compression type %d, continuing...", ddt_header.
compression);
301 *found_user_data_ddt =
false;
311 FATAL(
"Compressed DDT payload too small (%" PRIu64
") for LZMA properties.", ddt_header.
cmpLength);
312 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
318 cmp_data = (uint8_t *)malloc(lzma_size);
321 TRACE(
"Cannot allocate memory for DDT, continuing...");
325 buffer = malloc(ddt_header.
length);
328 TRACE(
"Cannot allocate memory for DDT, continuing...");
336 TRACE(
"Could not read LZMA properties, continuing...");
342 read_bytes = fread(cmp_data, 1, lzma_size, ctx->
imageStream);
343 if(read_bytes != lzma_size)
345 TRACE(
"Could not read compressed block, continuing...");
351 read_bytes = ddt_header.
length;
352 TRACE(
"Decompressing block of size %zu bytes", ddt_header.
length);
358 FATAL(
"Got error %d from LZMA, stopping...", error_no);
361 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
365 if(read_bytes != ddt_header.
length)
367 FATAL(
"Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
370 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
379 if(crc64_context == NULL)
381 FATAL(
"Could not initialize CRC64.");
383 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
390 if(crc64 != ddt_header.
crc64)
392 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
394 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
408 buffer = malloc(ddt_header.
length);
412 TRACE(
"Cannot allocate memory for deduplication table.");
418 if(read_bytes != ddt_header.
length)
421 FATAL(
"Could not read deduplication table, continuing...");
427 if(crc64_context == NULL)
429 FATAL(
"Could not initialize CRC64.");
431 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
438 if(crc64 != ddt_header.
crc64)
440 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
442 TRACE(
"Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
455 TRACE(
"Found unknown compression type %d, continuing...", ddt_header.
compression);
459 TRACE(
"Exiting process_ddt_v2() = AARUF_STATUS_OK");
508 uint64_t *block_offset, uint8_t *sector_status)
510 TRACE(
"Entering decode_ddt_entry_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative, *offset,
511 *block_offset, *sector_status);
515 FATAL(
"Invalid context or image stream.");
517 TRACE(
"Exiting decode_ddt_entry_v2() = AARUF_ERROR_NOT_AARUFORMAT");
582 uint64_t *block_offset, uint8_t *sector_status)
584 TRACE(
"Entering decode_ddt_single_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative,
585 *offset, *block_offset, *sector_status);
587 uint64_t ddt_entry = 0;
592 FATAL(
"Invalid context or image stream.");
594 TRACE(
"Exiting decode_ddt_single_level_v2() = AARUF_ERROR_NOT_AARUFORMAT");
601 FATAL(
"DDT table shift is not zero, but we are in single-level DDT decoding.");
602 TRACE(
"Exiting decode_ddt_single_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
619 TRACE(
"Exiting decode_ddt_single_level_v2(%p, %" PRIu64
", %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
620 sector_address, *offset, *block_offset, *sector_status);
624 *sector_status = ddt_entry >> 60;
625 ddt_entry &= 0xFFFFFFFFFFFFFFF;
628 *offset = ddt_entry & offset_mask;
632 TRACE(
"Exiting decode_ddt_single_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
633 sector_address, negative, *offset, *block_offset, *sector_status);
725 uint64_t *block_offset, uint8_t *sector_status)
727 TRACE(
"Entering decode_ddt_multi_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative,
728 *offset, *block_offset, *sector_status);
730 uint64_t ddt_entry = 0;
732 size_t lzma_size = 0;
733 uint8_t *cmp_data = NULL;
734 uint8_t *buffer = NULL;
737 int items_per_ddt_entry = 0;
738 uint64_t ddt_position = 0;
739 uint64_t secondary_ddt_offset = 0;
744 FATAL(
"Invalid context or image stream.");
746 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_NOT_AARUFORMAT");
753 FATAL(
"DDT table shift is zero, but we are in multi-level DDT decoding.");
754 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
765 ddt_position = sector_address / items_per_ddt_entry;
774 int32_t error_no = 0;
775 fseek(ctx->
imageStream, secondary_ddt_offset, SEEK_SET);
781 FATAL(
"Could not read block header at %" PRIu64
"", secondary_ddt_offset);
782 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
788 FATAL(
"Invalid block header at %" PRIu64
"", secondary_ddt_offset);
789 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
799 FATAL(
"Compressed DDT payload too small (%" PRIu64
") for LZMA properties.", ddt_header.
cmpLength);
800 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
806 cmp_data = (uint8_t *)malloc(lzma_size);
809 FATAL(
"Cannot allocate memory for DDT, stopping...");
810 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
814 buffer = malloc(ddt_header.
length);
817 FATAL(
"Cannot allocate memory for DDT, stopping...");
825 FATAL(
"Could not read LZMA properties, stopping...");
828 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
832 read_bytes = fread(cmp_data, 1, lzma_size, ctx->
imageStream);
833 if(read_bytes != lzma_size)
835 FATAL(
"Could not read compressed block, stopping...");
838 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
842 TRACE(
"Decompressing block of size %zu bytes", ddt_header.
length);
843 read_bytes = ddt_header.
length;
849 FATAL(
"Got error %d from LZMA, stopping...", error_no);
852 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
856 if(read_bytes != ddt_header.
length)
858 FATAL(
"Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
861 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
869 if(crc64_context == NULL)
871 FATAL(
"Could not initialize CRC64.");
873 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
880 if(crc64 != ddt_header.
crc64)
882 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
884 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
894 buffer = malloc(ddt_header.
length);
898 FATAL(
"Cannot allocate memory for DDT, stopping...");
899 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
905 if(read_bytes != ddt_header.
length)
908 FATAL(
"Could not read deduplication table, stopping...");
909 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
915 if(crc64_context == NULL)
917 FATAL(
"Could not initialize CRC64.");
919 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
926 if(crc64 != ddt_header.
crc64)
928 FATAL(
"Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
930 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
940 FATAL(
"Found unknown compression type %d, stopping...", ddt_header.
compression);
941 TRACE(
"Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
954 TRACE(
"Exiting decode_ddt_multi_level_v2(%p, %" PRIu64
", %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
955 sector_address, *offset, *block_offset, *sector_status);
959 *sector_status = ddt_entry >> 60;
960 ddt_entry &= 0x0FFFFFFFFFFFFFFF;
963 *offset = ddt_entry & offset_mask;
967 TRACE(
"Exiting decode_ddt_multi_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
968 sector_address, negative, *offset, *block_offset, *sector_status);
989 const uint64_t block_offset,
const uint8_t sector_status, uint64_t *ddt_entry)
991 TRACE(
"Entering set_ddt_entry_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative, offset,
992 block_offset, sector_status);
997 FATAL(
"Invalid context or image stream.");
1002 return set_ddt_multi_level_v2(ctx, sector_address,
false, offset, block_offset, sector_status, ddt_entry);
1024 const uint64_t offset,
const uint64_t block_offset,
const uint8_t sector_status,
1025 uint64_t *ddt_entry)
1027 TRACE(
"Entering set_ddt_single_level_v2(%p, %" PRIu64
", %d, %llu, %llu, %d)", ctx, sector_address, negative,
1028 offset, block_offset, sector_status);
1033 FATAL(
"Invalid context or image stream.");
1034 TRACE(
"Exiting set_ddt_single_level_v2() = false");
1041 FATAL(
"DDT table shift is not zero, but we are in single-level DDT setting.");
1042 TRACE(
"Exiting set_ddt_single_level_v2() = false");
1059 if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
1061 FATAL(
"DDT overflow: media does not fit in big DDT");
1062 TRACE(
"Exiting set_ddt_single_level_v2() = false");
1066 *ddt_entry |= (uint64_t)sector_status << 60;
1069 TRACE(
"Setting big single-level DDT entry %d to %ull", sector_address, (uint64_t)*ddt_entry);
1072 TRACE(
"Exiting set_ddt_single_level_v2() = true");
1093 uint64_t block_offset, uint8_t sector_status, uint64_t *ddt_entry)
1095 TRACE(
"Entering set_ddt_multi_level_v2(%p, %" PRIu64
", %d, %" PRIu64
", %" PRIu64
", %d)", ctx, sector_address,
1096 negative, offset, block_offset, sector_status);
1098 uint64_t items_per_ddt_entry = 0;
1099 uint64_t ddt_position = 0;
1100 uint64_t secondary_ddt_offset = 0;
1101 uint64_t block_index = 0;
1102 uint8_t *buffer = NULL;
1106 size_t written_bytes = 0;
1107 long end_of_file = 0;
1108 bool create_new_table =
false;
1113 FATAL(
"Invalid context or image stream.");
1114 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1121 FATAL(
"DDT table shift is zero, but we are in multi-level DDT setting.");
1122 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1134 ddt_position = sector_address / items_per_ddt_entry;
1151 if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
1153 FATAL(
"DDT overflow: media does not fit in big DDT");
1154 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1158 *ddt_entry |= (uint64_t)sector_status << 60;
1161 TRACE(
"Setting small secondary DDT entry %d to %ull", sector_address % items_per_ddt_entry,
1162 (uint64_t)*ddt_entry);
1165 TRACE(
"Updated cached secondary DDT entry at position %" PRIu64, sector_address % items_per_ddt_entry);
1166 TRACE(
"Exiting set_ddt_multi_level_v2() = true");
1177 TRACE(
"Current secondary DDT in memory belongs to position %" PRIu64
1178 " but requested block needs position %" PRIu64,
1192 end_of_file = end_of_file + alignment_mask & ~alignment_mask;
1204 ddt_header.
blocks = items_per_ddt_entry;
1210 ddt_header.
entries = items_per_ddt_entry;
1214 ddt_header.
length = items_per_ddt_entry *
sizeof(uint64_t);
1218 if(crc64_context == NULL)
1220 FATAL(
"Could not initialize CRC64.");
1221 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1228 ddt_header.
crc64 = crc64;
1230 uint8_t *cmp_buffer = NULL;
1241 cmp_buffer = malloc((
size_t)ddt_header.
length * 2);
1242 if(cmp_buffer == NULL)
1244 TRACE(
"Failed to allocate memory for secondary DDT v2 compression");
1248 size_t dst_size = (size_t)ddt_header.
length * 2 * 2;
1254 ddt_header.
cmpLength = (uint32_t)dst_size;
1277 if(written_bytes != 1)
1279 FATAL(
"Could not write never-written DDT header to file.");
1280 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1289 FATAL(
"Could not write never-written DDT data to file.");
1290 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1300 new_ddt_entry.
offset = end_of_file;
1303 TRACE(
"Added new DDT index entry for never-written table at offset %" PRIu64, end_of_file);
1318 if(written_bytes != 1)
1320 FATAL(
"Could not flush primary DDT table to file after writing never-written secondary table.");
1321 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1327 ctx->
next_block_position = end_of_file + ddt_total_size + alignment_mask & ~alignment_mask;
1344 TRACE(
"Successfully wrote never-written cached secondary DDT to disk");
1348 TRACE(
"Cached DDT is for the correct block range, using it directly");
1355 long current_pos = 0;
1366 end_of_file = end_of_file + alignment_mask & ~alignment_mask;
1378 ddt_header.
blocks = items_per_ddt_entry;
1380 ddt_header.
start = ddt_position * items_per_ddt_entry;
1384 ddt_header.
entries = items_per_ddt_entry;
1388 ddt_header.
length = items_per_ddt_entry *
sizeof(uint64_t);
1392 if(crc64_context == NULL)
1394 FATAL(
"Could not initialize CRC64.");
1395 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1402 ddt_header.
crc64 = crc64;
1404 uint8_t *cmp_buffer = NULL;
1415 cmp_buffer = malloc((
size_t)ddt_header.
length * 2);
1416 if(cmp_buffer == NULL)
1418 TRACE(
"Failed to allocate memory for secondary DDT v2 compression");
1422 size_t dst_size = (size_t)ddt_header.
length * 2 * 2;
1425 lzma_properties, &props_size, 9, ctx->
lzma_dict_size, 4, 0, 2, 273, 8);
1427 ddt_header.
cmpLength = (uint32_t)dst_size;
1452 if(written_bytes != 1)
1454 FATAL(
"Could not write DDT header to file.");
1455 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1462 if(written_bytes != 1)
1464 FATAL(
"Could not write DDT data to file.");
1465 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1472 TRACE(
"Updating index for evicted secondary DDT");
1481 for(
unsigned int i = 0; i < utarray_len(ctx->
index_entries); i++)
1486 TRACE(
"Found old DDT index entry at position %u, removing", i);
1497 new_ddt_entry.
offset = end_of_file;
1500 TRACE(
"Added new DDT index entry at offset %" PRIu64, end_of_file);
1508 ctx->
user_data_ddt2[ddt_position] = new_secondary_table_block_offset;
1518 if(written_bytes != 1)
1520 FATAL(
"Could not flush primary DDT table to file.");
1521 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1527 ctx->
next_block_position = end_of_file + ddt_total_size + alignment_mask & ~alignment_mask;
1546 if(!create_new_table && secondary_ddt_offset != 0)
1549 fseek(ctx->
imageStream, secondary_ddt_offset, SEEK_SET);
1555 FATAL(
"Invalid secondary DDT header at %" PRIu64, secondary_ddt_offset);
1556 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1561 buffer = malloc(ddt_header.
length);
1564 FATAL(
"Cannot allocate memory for secondary DDT.");
1565 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1570 if(read_bytes != ddt_header.
length)
1572 FATAL(
"Could not read secondary DDT data.");
1574 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1580 if(crc64_context == NULL)
1582 FATAL(
"Could not initialize CRC64.");
1584 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1591 if(crc64 != ddt_header.
crc64)
1593 FATAL(
"Secondary DDT CRC mismatch. Expected 0x%16lX but got 0x%16lX.", ddt_header.
crc64, crc64);
1595 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1606 if(create_new_table)
1609 size_t table_size = items_per_ddt_entry *
sizeof(uint64_t);
1611 buffer = calloc(1, table_size);
1614 FATAL(
"Cannot allocate memory for new secondary DDT.");
1615 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1623 TRACE(
"Created new secondary DDT for position %" PRIu64, ddt_position);
1634 if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
1636 FATAL(
"DDT overflow: media does not fit in big DDT");
1637 TRACE(
"Exiting set_ddt_multi_level_v2() = false");
1641 *ddt_entry |= (uint64_t)sector_status << 60;
1644 TRACE(
"Setting big secondary DDT entry %d to %ull", sector_address % items_per_ddt_entry, (uint64_t)*ddt_entry);
1647 TRACE(
"Updated secondary DDT entry at position %" PRIu64, sector_address % items_per_ddt_entry);
1648 TRACE(
"Exiting set_ddt_multi_level_v2() = true");
1769 const uint8_t sector_status, uint64_t *ddt_entry)
1771 TRACE(
"Entering set_ddt_tape(%p, %" PRIu64
", %llu, %llu, %d)", ctx, sector_address, offset, block_offset,
1777 FATAL(
"Invalid context or image stream.");
1778 TRACE(
"Exiting set_ddt_tape() = false");
1785 FATAL(
"Image is not tape, wrong function called.");
1786 TRACE(
"Exiting set_ddt_tape() = false");
1796 if(*ddt_entry > 0xFFFFFFFFFFFFFFF)
1798 FATAL(
"DDT overflow: media does not fit in big DDT");
1799 TRACE(
"Exiting set_ddt_tape() = false");
1803 *ddt_entry |= (uint64_t)sector_status << 60;
1809 if(new_entry == NULL)
1811 FATAL(
"Cannot allocate memory for new tape DDT hash entry.");
1812 TRACE(
"Exiting set_ddt_tape() = false");
1816 TRACE(
"Setting tape DDT entry %d to %u", sector_address, (uint32_t)*ddt_entry);
1818 new_entry->
key = sector_address;
1819 new_entry->
value = *ddt_entry;
1822 HASH_REPLACE(hh, ctx->
tape_ddt, key,
sizeof(uint64_t), new_entry, old_entry);
1823 if(old_entry) free(old_entry);
1825 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.
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.
bool set_ddt_entry_v2(aaruformat_context *ctx, const uint64_t sector_address, 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_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.
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.
@ 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).
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.
TapeDdtHashEntry * tape_ddt
Hash table root for tape DDT entries.
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.
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).