/* Re-initialize an open chapter index for a new chapter. */ void uds_empty_open_chapter_index(struct open_chapter_index *chapter_index,
u64 virtual_chapter_number)
{
uds_reset_delta_index(&chapter_index->delta_index);
chapter_index->virtual_chapter_number = virtual_chapter_number;
}
/* Associate a record name with the record page containing its metadata. */ int uds_put_open_chapter_index_record(struct open_chapter_index *chapter_index, conststruct uds_record_name *name,
u32 page_number)
{ int result; struct delta_index_entry entry;
u32 address;
u32 list_number; const u8 *found_name; bool found; conststruct index_geometry *geometry = chapter_index->geometry;
u64 chapter_number = chapter_index->virtual_chapter_number;
u32 record_pages = geometry->record_pages_per_chapter;
result = VDO_ASSERT(page_number < record_pages, "Page number within chapter (%u) exceeds the maximum value %u",
page_number, record_pages); if (result != VDO_SUCCESS) return UDS_INVALID_ARGUMENT;
found = was_entry_found(&entry, address);
result = VDO_ASSERT(!(found && entry.is_collision), "Chunk appears more than once in chapter %llu",
(unsignedlonglong) chapter_number); if (result != VDO_SUCCESS) return UDS_BAD_STATE;
for (;;) {
result = uds_pack_delta_index_page(delta_index, nonce, memory,
geometry->bytes_per_page,
chapter_number, first_list,
lists_packed); if (result != UDS_SUCCESS) return result;
if ((first_list + *lists_packed) == list_count) { /* All lists are packed. */ break;
} elseif (*lists_packed == 0) { /* *Thenextdeltalistdoesnotfitonapage.Thisdeltalistwillbe *removed.
*/
} elseif (last_page) { /* *Thisisthelastpageandtherearelistsleftunpacked,butallofthe *remaininglistsmustfitonthepage.Findalistthatcontainsentries *andremovetheentirelist.Trythefirstlistthatdoesnotfit.Ifit *isempty,wewillselectthelastlistthatalreadyfitsandhasany *entries.
*/
} else { /* This page is done. */ break;
}
if (removals == 0) {
uds_get_delta_index_stats(delta_index, &stats);
vdo_log_warning("The chapter index for chapter %llu contains %llu entries with %llu collisions",
(unsignedlonglong) chapter_number,
(unsignedlonglong) stats.record_count,
(unsignedlonglong) stats.collision_count);
}
list_number = *lists_packed; do { if (list_number < 0) return UDS_OVERFLOW;
next_list = first_list + list_number--;
result = uds_start_delta_index_search(delta_index, next_list, 0,
&entry); if (result != UDS_SUCCESS) return result;
result = uds_next_delta_index_entry(&entry); if (result != UDS_SUCCESS) return result;
} while (entry.at_end);
do {
result = uds_remove_delta_index_entry(&entry); if (result != UDS_SUCCESS) return result;
removals++;
} while (!entry.at_end);
}
if (removals > 0) {
vdo_log_warning("To avoid chapter index page overflow in chapter %llu, %u entries were removed from the chapter index",
(unsignedlonglong) chapter_number, removals);
}
return UDS_SUCCESS;
}
/* Make a new chapter index page, initializing it with the data from a given index_page buffer. */ int uds_initialize_chapter_index_page(struct delta_index_page *index_page, conststruct index_geometry *geometry,
u8 *page_buffer, u64 volume_nonce)
{ return uds_initialize_delta_index_page(index_page, volume_nonce,
geometry->chapter_mean_delta,
geometry->chapter_payload_bits,
page_buffer, geometry->bytes_per_page);
}
/* Validate a chapter index page read during rebuild. */ int uds_validate_chapter_index_page(conststruct delta_index_page *index_page, conststruct index_geometry *geometry)
{ int result; conststruct delta_index *delta_index = &index_page->delta_index;
u32 first = index_page->lowest_list_number;
u32 last = index_page->highest_list_number;
u32 list_number;
/* We walk every delta list from start to finish. */ for (list_number = first; list_number <= last; list_number++) { struct delta_index_entry entry;
result = uds_start_delta_index_search(delta_index, list_number - first, 0, &entry); if (result != UDS_SUCCESS) return result;
for (;;) {
result = uds_next_delta_index_entry(&entry); if (result != UDS_SUCCESS) { /* *Arandombitstreamishighlylikelytoarriveherewhenwego *pasttheendofthedeltalist.
*/ return result;
}
if (entry.at_end) break;
/* Also make sure that the record page field contains a plausible value. */ if (uds_get_delta_entry_value(&entry) >=
geometry->record_pages_per_chapter) { /* *Donotlogthisasanerror.Ithappensinnormaloperationwhen *wearedoingarebuildbuthaven'twrittentheentirevolume *once.
*/ return UDS_CORRUPT_DATA;
}
}
} return UDS_SUCCESS;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.