summaryrefslogtreecommitdiff
path: root/drivers/md/dm-vdo/indexer/geometry.h
blob: a2ecdb238cf2dfd4fcbd1321527db716ab04d951 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* 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 */