/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright 2023 Red Hat */ #ifndef UDS_INDEX_GEOMETRY_H #define UDS_INDEX_GEOMETRY_H #include "indexer.h" /* * The index_geometry records parameters that define the layout of a UDS index volume, and the size and * shape of various index structures. It is created when the index is created, and is referenced by * many index sub-components. */ struct index_geometry { /* Size of a chapter page, in bytes */ size_t bytes_per_page; /* Number of record pages in a chapter */ u32 record_pages_per_chapter; /* Total number of chapters in a volume */ u32 chapters_per_volume; /* Number of sparsely-indexed chapters in a volume */ u32 sparse_chapters_per_volume; /* Number of bits used to determine delta list numbers */ u8 chapter_delta_list_bits; /* Virtual chapter remapped from physical chapter 0 */ u64 remapped_virtual; /* New physical chapter where the remapped chapter can be found */ u64 remapped_physical; /* * The following properties are derived from the ones above, but they are computed and * recorded as fields for convenience. */ /* Total number of pages in a volume, excluding the header */ u32 pages_per_volume; /* Total number of bytes in a volume, including the header */ size_t bytes_per_volume; /* Number of pages in a chapter */ u32 pages_per_chapter; /* Number of index pages in a chapter index */ u32 index_pages_per_chapter; /* Number of records that fit on a page */ u32 records_per_page; /* Number of records that fit in a chapter */ u32 records_per_chapter; /* Number of records that fit in a volume */ u64 records_per_volume; /* Number of delta lists per chapter index */ u32 delta_lists_per_chapter; /* Mean delta for chapter indexes */ u32 chapter_mean_delta; /* Number of bits needed for record page numbers */ u8 chapter_payload_bits; /* Number of bits used to compute addresses for chapter delta lists */ u8 chapter_address_bits; /* Number of densely-indexed chapters in a volume */ u32 dense_chapters_per_volume; }; enum { /* The number of bytes in a record (name + metadata) */ BYTES_PER_RECORD = (UDS_RECORD_NAME_SIZE + UDS_RECORD_DATA_SIZE), /* The default length of a page in a chapter, in bytes */ DEFAULT_BYTES_PER_PAGE = 1024 * BYTES_PER_RECORD, /* The default maximum number of records per page */ DEFAULT_RECORDS_PER_PAGE = DEFAULT_BYTES_PER_PAGE / BYTES_PER_RECORD, /* The default number of record pages in a chapter */ DEFAULT_RECORD_PAGES_PER_CHAPTER = 256, /* The default number of record pages in a chapter for a small index */ SMALL_RECORD_PAGES_PER_CHAPTER = 64, /* The default number of chapters in a volume */ DEFAULT_CHAPTERS_PER_VOLUME = 1024, /* The default number of sparsely-indexed chapters in a volume */ DEFAULT_SPARSE_CHAPTERS_PER_VOLUME = 0, /* The log2 of the default mean delta */ DEFAULT_CHAPTER_MEAN_DELTA_BITS = 16, /* The log2 of the number of delta lists in a large chapter */ DEFAULT_CHAPTER_DELTA_LIST_BITS = 12, /* The log2 of the number of delta lists in a small chapter */ SMALL_CHAPTER_DELTA_LIST_BITS = 10, /* The number of header pages per volume */ HEADER_PAGES_PER_VOLUME = 1, }; int __must_check uds_make_index_geometry(size_t bytes_per_page, u32 record_pages_per_chapter, u32 chapters_per_volume, u32 sparse_chapters_per_volume, u64 remapped_virtual, u64 remapped_physical, struct index_geometry **geometry_ptr); int __must_check uds_copy_index_geometry(struct index_geometry *source, struct index_geometry **geometry_ptr); void uds_free_index_geometry(struct index_geometry *geometry); u32 __must_check uds_map_to_physical_chapter(const struct index_geometry *geometry, u64 virtual_chapter); /* * Check whether this geometry is reduced by a chapter. This will only be true if the volume was * converted from a non-lvm volume to an lvm volume. */ static inline bool __must_check uds_is_reduced_index_geometry(const struct index_geometry *geometry) { return !!(geometry->chapters_per_volume & 1); } static inline bool __must_check uds_is_sparse_index_geometry(const struct index_geometry *geometry) { return geometry->sparse_chapters_per_volume > 0; } bool __must_check uds_has_sparse_chapters(const struct index_geometry *geometry, u64 oldest_virtual_chapter, u64 newest_virtual_chapter); bool __must_check uds_is_chapter_sparse(const struct index_geometry *geometry, u64 oldest_virtual_chapter, u64 newest_virtual_chapter, u64 virtual_chapter_number); u32 __must_check uds_chapters_to_expire(const struct index_geometry *geometry, u64 newest_chapter); #endif /* UDS_INDEX_GEOMETRY_H */