]>
Commit | Line | Data |
---|---|---|
a4b75251 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause */ |
2 | /* Copyright 2014-2020, Intel Corporation */ | |
3 | ||
4 | /* | |
5 | * pool_hdr.h -- internal definitions for pool header module | |
6 | */ | |
7 | ||
8 | #ifndef PMDK_POOL_HDR_H | |
9 | #define PMDK_POOL_HDR_H 1 | |
10 | ||
11 | #include <stddef.h> | |
12 | #include <stdint.h> | |
13 | #include <unistd.h> | |
14 | #include "uuid.h" | |
15 | #include "shutdown_state.h" | |
16 | #include "util.h" | |
17 | #include "page_size.h" | |
18 | ||
19 | #ifdef __cplusplus | |
20 | extern "C" { | |
21 | #endif | |
22 | ||
23 | /* | |
24 | * Number of bits per type in alignment descriptor | |
25 | */ | |
26 | #define ALIGNMENT_DESC_BITS 4 | |
27 | ||
28 | /* | |
29 | * architecture identification flags | |
30 | * | |
31 | * These flags allow to unambiguously determine the architecture | |
32 | * on which the pool was created. | |
33 | * | |
34 | * The alignment_desc field contains information about alignment | |
35 | * of the following basic types: | |
36 | * - char | |
37 | * - short | |
38 | * - int | |
39 | * - long | |
40 | * - long long | |
41 | * - size_t | |
42 | * - os_off_t | |
43 | * - float | |
44 | * - double | |
45 | * - long double | |
46 | * - void * | |
47 | * | |
48 | * The alignment of each type is computed as an offset of field | |
49 | * of specific type in the following structure: | |
50 | * struct { | |
51 | * char byte; | |
52 | * type field; | |
53 | * }; | |
54 | * | |
55 | * The value is decremented by 1 and masked by 4 bits. | |
56 | * Multiple alignments are stored on consecutive 4 bits of each | |
57 | * type in the order specified above. | |
58 | * | |
59 | * The values used in the machine, and machine_class fields are in | |
60 | * principle independent of operating systems, and object formats. | |
61 | * In practice they happen to match constants used in ELF object headers. | |
62 | */ | |
63 | struct arch_flags { | |
64 | uint64_t alignment_desc; /* alignment descriptor */ | |
65 | uint8_t machine_class; /* address size -- 64 bit or 32 bit */ | |
66 | uint8_t data; /* data encoding -- LE or BE */ | |
67 | uint8_t reserved[4]; | |
68 | uint16_t machine; /* required architecture */ | |
69 | }; | |
70 | ||
71 | #define POOL_HDR_ARCH_LEN sizeof(struct arch_flags) | |
72 | ||
73 | /* possible values of the machine class field in the above struct */ | |
74 | #define PMDK_MACHINE_CLASS_64 2 /* 64 bit pointers, 64 bit size_t */ | |
75 | ||
76 | /* possible values of the machine field in the above struct */ | |
77 | #define PMDK_MACHINE_X86_64 62 | |
78 | #define PMDK_MACHINE_AARCH64 183 | |
79 | #define PMDK_MACHINE_PPC64 21 | |
80 | ||
81 | /* possible values of the data field in the above struct */ | |
82 | #define PMDK_DATA_LE 1 /* 2's complement, little endian */ | |
83 | #define PMDK_DATA_BE 2 /* 2's complement, big endian */ | |
84 | ||
85 | /* | |
86 | * features flags | |
87 | */ | |
88 | typedef struct { | |
89 | uint32_t compat; /* mask: compatible "may" features */ | |
90 | uint32_t incompat; /* mask: "must support" features */ | |
91 | uint32_t ro_compat; /* mask: force RO if unsupported */ | |
92 | } features_t; | |
93 | ||
94 | /* | |
95 | * header used at the beginning of all types of memory pools | |
96 | * | |
97 | * for pools build on persistent memory, the integer types | |
98 | * below are stored in little-endian byte order. | |
99 | */ | |
100 | #define POOL_HDR_SIG_LEN 8 | |
101 | #define POOL_HDR_UNUSED_SIZE 1904 | |
102 | #define POOL_HDR_UNUSED2_SIZE 1976 | |
103 | #define POOL_HDR_ALIGN_PAD (PMEM_PAGESIZE - 4096) | |
104 | struct pool_hdr { | |
105 | char signature[POOL_HDR_SIG_LEN]; | |
106 | uint32_t major; /* format major version number */ | |
107 | features_t features; /* features flags */ | |
108 | uuid_t poolset_uuid; /* pool set UUID */ | |
109 | uuid_t uuid; /* UUID of this file */ | |
110 | uuid_t prev_part_uuid; /* prev part */ | |
111 | uuid_t next_part_uuid; /* next part */ | |
112 | uuid_t prev_repl_uuid; /* prev replica */ | |
113 | uuid_t next_repl_uuid; /* next replica */ | |
114 | uint64_t crtime; /* when created (seconds since epoch) */ | |
115 | struct arch_flags arch_flags; /* architecture identification flags */ | |
116 | unsigned char unused[POOL_HDR_UNUSED_SIZE]; /* must be zero */ | |
117 | /* not checksumed */ | |
118 | unsigned char unused2[POOL_HDR_UNUSED2_SIZE]; /* must be zero */ | |
119 | struct shutdown_state sds; /* shutdown status */ | |
120 | uint64_t checksum; /* checksum of above fields */ | |
121 | ||
122 | #if PMEM_PAGESIZE > 4096 /* prevent zero size array */ | |
123 | unsigned char align_pad[POOL_HDR_ALIGN_PAD]; /* alignment pad */ | |
124 | #endif | |
125 | }; | |
126 | ||
127 | #define POOL_HDR_SIZE (sizeof(struct pool_hdr)) | |
128 | ||
129 | #define POOL_DESC_SIZE PMEM_PAGESIZE | |
130 | ||
131 | void util_convert2le_hdr(struct pool_hdr *hdrp); | |
132 | void util_convert2h_hdr_nocheck(struct pool_hdr *hdrp); | |
133 | ||
134 | void util_get_arch_flags(struct arch_flags *arch_flags); | |
135 | int util_check_arch_flags(const struct arch_flags *arch_flags); | |
136 | ||
137 | features_t util_get_unknown_features(features_t features, features_t known); | |
138 | int util_feature_check(struct pool_hdr *hdrp, features_t features); | |
139 | int util_feature_cmp(features_t features, features_t ref); | |
140 | int util_feature_is_zero(features_t features); | |
141 | int util_feature_is_set(features_t features, features_t flag); | |
142 | void util_feature_enable(features_t *features, features_t new_feature); | |
143 | void util_feature_disable(features_t *features, features_t new_feature); | |
144 | ||
145 | const char *util_feature2str(features_t feature, features_t *found); | |
146 | features_t util_str2feature(const char *str); | |
147 | uint32_t util_str2pmempool_feature(const char *str); | |
148 | uint32_t util_feature2pmempool_feature(features_t feat); | |
149 | ||
150 | /* | |
151 | * set of macros for determining the alignment descriptor | |
152 | */ | |
153 | #define DESC_MASK ((1 << ALIGNMENT_DESC_BITS) - 1) | |
154 | #define alignment_of(t) offsetof(struct { char c; t x; }, x) | |
155 | #define alignment_desc_of(t) (((uint64_t)alignment_of(t) - 1) & DESC_MASK) | |
156 | #define alignment_desc()\ | |
157 | (alignment_desc_of(char) << 0 * ALIGNMENT_DESC_BITS) |\ | |
158 | (alignment_desc_of(short) << 1 * ALIGNMENT_DESC_BITS) |\ | |
159 | (alignment_desc_of(int) << 2 * ALIGNMENT_DESC_BITS) |\ | |
160 | (alignment_desc_of(long) << 3 * ALIGNMENT_DESC_BITS) |\ | |
161 | (alignment_desc_of(long long) << 4 * ALIGNMENT_DESC_BITS) |\ | |
162 | (alignment_desc_of(size_t) << 5 * ALIGNMENT_DESC_BITS) |\ | |
163 | (alignment_desc_of(off_t) << 6 * ALIGNMENT_DESC_BITS) |\ | |
164 | (alignment_desc_of(float) << 7 * ALIGNMENT_DESC_BITS) |\ | |
165 | (alignment_desc_of(double) << 8 * ALIGNMENT_DESC_BITS) |\ | |
166 | (alignment_desc_of(long double) << 9 * ALIGNMENT_DESC_BITS) |\ | |
167 | (alignment_desc_of(void *) << 10 * ALIGNMENT_DESC_BITS) | |
168 | ||
169 | #define POOL_FEAT_ZERO 0x0000U | |
170 | ||
171 | static const features_t features_zero = | |
172 | {POOL_FEAT_ZERO, POOL_FEAT_ZERO, POOL_FEAT_ZERO}; | |
173 | ||
174 | /* | |
175 | * compat features | |
176 | */ | |
177 | #define POOL_FEAT_CHECK_BAD_BLOCKS 0x0001U /* check bad blocks in a pool */ | |
178 | ||
179 | #define POOL_FEAT_COMPAT_ALL \ | |
180 | (POOL_FEAT_CHECK_BAD_BLOCKS) | |
181 | ||
182 | #define FEAT_COMPAT(X) \ | |
183 | {POOL_FEAT_##X, POOL_FEAT_ZERO, POOL_FEAT_ZERO} | |
184 | ||
185 | /* | |
186 | * incompat features | |
187 | */ | |
188 | #define POOL_FEAT_SINGLEHDR 0x0001U /* pool header only in the first part */ | |
189 | #define POOL_FEAT_CKSUM_2K 0x0002U /* only first 2K of hdr checksummed */ | |
190 | #define POOL_FEAT_SDS 0x0004U /* check shutdown state */ | |
191 | ||
192 | #define POOL_FEAT_INCOMPAT_ALL \ | |
193 | (POOL_FEAT_SINGLEHDR | POOL_FEAT_CKSUM_2K | POOL_FEAT_SDS) | |
194 | ||
195 | /* | |
196 | * incompat features effective values (if applicable) | |
197 | */ | |
198 | #ifdef SDS_ENABLED | |
199 | #define POOL_E_FEAT_SDS POOL_FEAT_SDS | |
200 | #else | |
201 | #define POOL_E_FEAT_SDS 0x0000U /* empty */ | |
202 | #endif | |
203 | ||
204 | #define POOL_FEAT_COMPAT_VALID \ | |
205 | (POOL_FEAT_CHECK_BAD_BLOCKS) | |
206 | ||
207 | #define POOL_FEAT_INCOMPAT_VALID \ | |
208 | (POOL_FEAT_SINGLEHDR | POOL_FEAT_CKSUM_2K | POOL_E_FEAT_SDS) | |
209 | ||
210 | #if defined(_WIN32) || NDCTL_ENABLED | |
211 | #define POOL_FEAT_INCOMPAT_DEFAULT \ | |
212 | (POOL_FEAT_CKSUM_2K | POOL_E_FEAT_SDS) | |
213 | #else | |
214 | /* | |
215 | * shutdown state support on Linux requires root access on kernel < 4.20 with | |
216 | * ndctl < 63 so it is disabled by default | |
217 | */ | |
218 | #define POOL_FEAT_INCOMPAT_DEFAULT \ | |
219 | (POOL_FEAT_CKSUM_2K) | |
220 | #endif | |
221 | ||
222 | #if NDCTL_ENABLED | |
223 | #define POOL_FEAT_COMPAT_DEFAULT \ | |
224 | (POOL_FEAT_CHECK_BAD_BLOCKS) | |
225 | #else | |
226 | #define POOL_FEAT_COMPAT_DEFAULT \ | |
227 | (POOL_FEAT_ZERO) | |
228 | #endif | |
229 | ||
230 | #define FEAT_INCOMPAT(X) \ | |
231 | {POOL_FEAT_ZERO, POOL_FEAT_##X, POOL_FEAT_ZERO} | |
232 | ||
233 | #define POOL_FEAT_VALID \ | |
234 | {POOL_FEAT_COMPAT_VALID, POOL_FEAT_INCOMPAT_VALID, POOL_FEAT_ZERO} | |
235 | ||
236 | /* | |
237 | * defines the first not checksummed field - all fields after this will be | |
238 | * ignored during checksum calculations. | |
239 | */ | |
240 | #define POOL_HDR_CSUM_2K_END_OFF offsetof(struct pool_hdr, unused2) | |
241 | #define POOL_HDR_CSUM_4K_END_OFF offsetof(struct pool_hdr, checksum) | |
242 | ||
243 | /* | |
244 | * pick the first not checksummed field. 2K variant is used if | |
245 | * POOL_FEAT_CKSUM_2K incompat feature is set. | |
246 | */ | |
247 | #define POOL_HDR_CSUM_END_OFF(hdrp) \ | |
248 | ((hdrp)->features.incompat & POOL_FEAT_CKSUM_2K) \ | |
249 | ? POOL_HDR_CSUM_2K_END_OFF : POOL_HDR_CSUM_4K_END_OFF | |
250 | ||
251 | /* ignore shutdown state if incompat feature is disabled */ | |
252 | #define IGNORE_SDS(hdrp) \ | |
253 | (((hdrp) != NULL) && (((hdrp)->features.incompat & POOL_FEAT_SDS) == 0)) | |
254 | ||
255 | #ifdef __cplusplus | |
256 | } | |
257 | #endif | |
258 | ||
259 | #endif |