]> git.proxmox.com Git - ceph.git/blob - ceph/src/pmdk/src/libpmemobj/heap_layout.h
import ceph 16.2.7
[ceph.git] / ceph / src / pmdk / src / libpmemobj / heap_layout.h
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright 2015-2020, Intel Corporation */
3
4 /*
5 * heap_layout.h -- internal definitions for heap layout
6 */
7
8 #ifndef LIBPMEMOBJ_HEAP_LAYOUT_H
9 #define LIBPMEMOBJ_HEAP_LAYOUT_H 1
10
11 #include <stddef.h>
12 #include <stdint.h>
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 #define HEAP_MAJOR 1
19 #define HEAP_MINOR 0
20
21 #define MAX_CHUNK (UINT16_MAX - 7) /* has to be multiple of 8 */
22 #define CHUNK_BASE_ALIGNMENT 1024
23 #define CHUNKSIZE ((size_t)1024 * 256) /* 256 kilobytes */
24 #define MAX_MEMORY_BLOCK_SIZE (MAX_CHUNK * CHUNKSIZE)
25 #define HEAP_SIGNATURE_LEN 16
26 #define HEAP_SIGNATURE "MEMORY_HEAP_HDR\0"
27 #define ZONE_HEADER_MAGIC 0xC3F0A2D2
28 #define ZONE_MIN_SIZE (sizeof(struct zone) + sizeof(struct chunk))
29 #define ZONE_MAX_SIZE (sizeof(struct zone) + sizeof(struct chunk) * MAX_CHUNK)
30 #define HEAP_MIN_SIZE (sizeof(struct heap_layout) + ZONE_MIN_SIZE)
31
32 /* Base bitmap values, relevant for both normal and flexible bitmaps */
33 #define RUN_BITS_PER_VALUE 64U
34 #define RUN_BASE_METADATA_VALUES\
35 ((unsigned)(sizeof(struct chunk_run_header) / sizeof(uint64_t)))
36 #define RUN_BASE_METADATA_SIZE (sizeof(struct chunk_run_header))
37
38 #define RUN_CONTENT_SIZE (CHUNKSIZE - RUN_BASE_METADATA_SIZE)
39
40 /*
41 * Calculates the size in bytes of a single run instance, including bitmap
42 */
43 #define RUN_CONTENT_SIZE_BYTES(size_idx)\
44 (RUN_CONTENT_SIZE + (((size_idx) - 1) * CHUNKSIZE))
45
46 /* Default bitmap values, specific for old, non-flexible, bitmaps */
47 #define RUN_DEFAULT_METADATA_VALUES 40 /* in 8 byte words, 320 bytes total */
48 #define RUN_DEFAULT_BITMAP_VALUES \
49 (RUN_DEFAULT_METADATA_VALUES - RUN_BASE_METADATA_VALUES)
50 #define RUN_DEFAULT_BITMAP_SIZE (sizeof(uint64_t) * RUN_DEFAULT_BITMAP_VALUES)
51 #define RUN_DEFAULT_BITMAP_NBITS\
52 (RUN_BITS_PER_VALUE * RUN_DEFAULT_BITMAP_VALUES)
53 #define RUN_DEFAULT_SIZE \
54 (CHUNKSIZE - RUN_BASE_METADATA_SIZE - RUN_DEFAULT_BITMAP_SIZE)
55
56 /*
57 * Calculates the size in bytes of a single run instance, without bitmap,
58 * but only for the default fixed-bitmap algorithm
59 */
60 #define RUN_DEFAULT_SIZE_BYTES(size_idx)\
61 (RUN_DEFAULT_SIZE + (((size_idx) - 1) * CHUNKSIZE))
62
63 #define CHUNK_MASK ((CHUNKSIZE) - 1)
64 #define CHUNK_ALIGN_UP(value) ((((value) + CHUNK_MASK) & ~CHUNK_MASK))
65
66 enum chunk_flags {
67 CHUNK_FLAG_COMPACT_HEADER = 0x0001,
68 CHUNK_FLAG_HEADER_NONE = 0x0002,
69 CHUNK_FLAG_ALIGNED = 0x0004,
70 CHUNK_FLAG_FLEX_BITMAP = 0x0008,
71 };
72
73 #define CHUNK_FLAGS_ALL_VALID (\
74 CHUNK_FLAG_COMPACT_HEADER |\
75 CHUNK_FLAG_HEADER_NONE |\
76 CHUNK_FLAG_ALIGNED |\
77 CHUNK_FLAG_FLEX_BITMAP\
78 )
79
80 enum chunk_type {
81 CHUNK_TYPE_UNKNOWN,
82 CHUNK_TYPE_FOOTER, /* not actual chunk type */
83 CHUNK_TYPE_FREE,
84 CHUNK_TYPE_USED,
85 CHUNK_TYPE_RUN,
86 CHUNK_TYPE_RUN_DATA,
87
88 MAX_CHUNK_TYPE
89 };
90
91 struct chunk {
92 uint8_t data[CHUNKSIZE];
93 };
94
95 struct chunk_run_header {
96 uint64_t block_size;
97 uint64_t alignment; /* valid only /w CHUNK_FLAG_ALIGNED */
98 };
99
100 struct chunk_run {
101 struct chunk_run_header hdr;
102 uint8_t content[RUN_CONTENT_SIZE]; /* bitmap + data */
103 };
104
105 struct chunk_header {
106 uint16_t type;
107 uint16_t flags;
108 uint32_t size_idx;
109 };
110
111 struct zone_header {
112 uint32_t magic;
113 uint32_t size_idx;
114 uint8_t reserved[56];
115 };
116
117 struct zone {
118 struct zone_header header;
119 struct chunk_header chunk_headers[MAX_CHUNK];
120 struct chunk chunks[];
121 };
122
123 struct heap_header {
124 char signature[HEAP_SIGNATURE_LEN];
125 uint64_t major;
126 uint64_t minor;
127 uint64_t unused; /* might be garbage */
128 uint64_t chunksize;
129 uint64_t chunks_per_zone;
130 uint8_t reserved[960];
131 uint64_t checksum;
132 };
133
134 struct heap_layout {
135 struct heap_header header;
136 struct zone zone0; /* first element of zones array */
137 };
138
139 #define ALLOC_HDR_SIZE_SHIFT (48ULL)
140 #define ALLOC_HDR_FLAGS_MASK (((1ULL) << ALLOC_HDR_SIZE_SHIFT) - 1)
141
142 struct allocation_header_legacy {
143 uint8_t unused[8];
144 uint64_t size;
145 uint8_t unused2[32];
146 uint64_t root_size;
147 uint64_t type_num;
148 };
149
150 #define ALLOC_HDR_COMPACT_SIZE sizeof(struct allocation_header_compact)
151
152 struct allocation_header_compact {
153 uint64_t size;
154 uint64_t extra;
155 };
156
157 enum header_type {
158 HEADER_LEGACY,
159 HEADER_COMPACT,
160 HEADER_NONE,
161
162 MAX_HEADER_TYPES
163 };
164
165 static const size_t header_type_to_size[MAX_HEADER_TYPES] = {
166 sizeof(struct allocation_header_legacy),
167 sizeof(struct allocation_header_compact),
168 0
169 };
170
171 static const enum chunk_flags header_type_to_flag[MAX_HEADER_TYPES] = {
172 (enum chunk_flags)0,
173 CHUNK_FLAG_COMPACT_HEADER,
174 CHUNK_FLAG_HEADER_NONE
175 };
176
177 static inline struct zone *
178 ZID_TO_ZONE(struct heap_layout *layout, size_t zone_id)
179 {
180 return (struct zone *)
181 ((uintptr_t)&layout->zone0 + ZONE_MAX_SIZE * zone_id);
182 }
183
184 static inline struct chunk_header *
185 GET_CHUNK_HDR(struct heap_layout *layout, size_t zone_id, unsigned chunk_id)
186 {
187 return &ZID_TO_ZONE(layout, zone_id)->chunk_headers[chunk_id];
188 }
189
190 static inline struct chunk *
191 GET_CHUNK(struct heap_layout *layout, size_t zone_id, unsigned chunk_id)
192 {
193 return &ZID_TO_ZONE(layout, zone_id)->chunks[chunk_id];
194 }
195
196 static inline struct chunk_run *
197 GET_CHUNK_RUN(struct heap_layout *layout, size_t zone_id, unsigned chunk_id)
198 {
199 return (struct chunk_run *)GET_CHUNK(layout, zone_id, chunk_id);
200 }
201
202 #ifdef __cplusplus
203 }
204 #endif
205
206 #endif