]> git.proxmox.com Git - ceph.git/blame - ceph/src/pmdk/src/common/pool_hdr.h
import ceph 16.2.7
[ceph.git] / ceph / src / pmdk / src / common / pool_hdr.h
CommitLineData
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
20extern "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 */
63struct 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 */
88typedef 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)
104struct 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
131void util_convert2le_hdr(struct pool_hdr *hdrp);
132void util_convert2h_hdr_nocheck(struct pool_hdr *hdrp);
133
134void util_get_arch_flags(struct arch_flags *arch_flags);
135int util_check_arch_flags(const struct arch_flags *arch_flags);
136
137features_t util_get_unknown_features(features_t features, features_t known);
138int util_feature_check(struct pool_hdr *hdrp, features_t features);
139int util_feature_cmp(features_t features, features_t ref);
140int util_feature_is_zero(features_t features);
141int util_feature_is_set(features_t features, features_t flag);
142void util_feature_enable(features_t *features, features_t new_feature);
143void util_feature_disable(features_t *features, features_t new_feature);
144
145const char *util_feature2str(features_t feature, features_t *found);
146features_t util_str2feature(const char *str);
147uint32_t util_str2pmempool_feature(const char *str);
148uint32_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
171static 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