source: mainline/uspace/srv/bd/hr/metadata/foreign/geom/stripe.c@ fb06476f

Last change on this file since fb06476f was fb06476f, checked in by Miroslav Cimerman <mc@…>, 4 months ago

hr: use enum for RAID layouts

  • Property mode set to 100644
File size: 8.6 KB
Line 
1/*
2 * Copyright (c) 2025 Miroslav Cimerman
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup hr
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <adt/list.h>
37#include <block.h>
38#include <byteorder.h>
39#include <errno.h>
40#include <inttypes.h>
41#include <io/log.h>
42#include <loc.h>
43#include <mem.h>
44#include <uuid.h>
45#include <stdlib.h>
46#include <stdio.h>
47#include <str.h>
48#include <types/uuid.h>
49
50#include "../../../util.h"
51#include "../../../var.h"
52
53#include "g_stripe.h"
54
55static void *meta_stripe_alloc_struct(void);
56static errno_t meta_stripe_init_vol2meta(const hr_volume_t *, void *);
57static errno_t meta_stripe_init_meta2vol(const list_t *,
58 hr_volume_t *);
59static void meta_stripe_encode(void *, void *);
60static errno_t meta_stripe_decode(const void *, void *);
61static errno_t meta_stripe_get_block(service_id_t, void **);
62static errno_t meta_stripe_write_block(service_id_t, const void *);
63static bool meta_stripe_has_valid_magic(const void *);
64static bool meta_stripe_compare_uuids(const void *, const void *);
65static void meta_stripe_inc_counter(void *);
66static errno_t meta_stripe_save(hr_volume_t *, bool);
67static const char *meta_stripe_get_devname(const void *);
68static hr_level_t meta_stripe_get_level(const void *);
69static uint64_t meta_stripe_get_data_offset(void);
70static size_t meta_stripe_get_size(void);
71static uint8_t meta_stripe_get_flags(void);
72static hr_metadata_type_t meta_stripe_get_type(void);
73static void meta_stripe_dump(const void *);
74
75hr_superblock_ops_t metadata_stripe_ops = {
76 .alloc_struct = meta_stripe_alloc_struct,
77 .init_vol2meta = meta_stripe_init_vol2meta,
78 .init_meta2vol = meta_stripe_init_meta2vol,
79 .encode = meta_stripe_encode,
80 .decode = meta_stripe_decode,
81 .get_block = meta_stripe_get_block,
82 .write_block = meta_stripe_write_block,
83 .has_valid_magic = meta_stripe_has_valid_magic,
84 .compare_uuids = meta_stripe_compare_uuids,
85 .inc_counter = meta_stripe_inc_counter,
86 .save = meta_stripe_save,
87 .get_devname = meta_stripe_get_devname,
88 .get_level = meta_stripe_get_level,
89 .get_data_offset = meta_stripe_get_data_offset,
90 .get_size = meta_stripe_get_size,
91 .get_flags = meta_stripe_get_flags,
92 .get_type = meta_stripe_get_type,
93 .dump = meta_stripe_dump
94};
95
96static void *meta_stripe_alloc_struct(void)
97{
98 return calloc(1, sizeof(struct g_stripe_metadata));
99}
100
101static errno_t meta_stripe_init_vol2meta(const hr_volume_t *vol, void *md_v)
102{
103 (void)vol;
104 (void)md_v;
105 return ENOTSUP;
106}
107
108static errno_t meta_stripe_init_meta2vol(const list_t *list, hr_volume_t *vol)
109{
110 HR_DEBUG("%s()", __func__);
111
112 errno_t rc = EOK;
113
114 /* get bsize */
115 size_t bsize;
116 struct dev_list_member *memb = list_get_instance(list_first(list),
117 struct dev_list_member, link);
118 rc = block_get_bsize(memb->svc_id, &bsize);
119 if (rc != EOK)
120 goto error;
121
122 vol->bsize = bsize;
123
124 uint64_t smallest_provider_size = ~0ULL;
125 struct g_stripe_metadata *main_meta = NULL;
126
127 list_foreach(*list, link, struct dev_list_member, iter) {
128 struct g_stripe_metadata *iter_meta = iter->md;
129
130 meta_stripe_dump(iter_meta);
131
132 if (iter_meta->md_provsize < smallest_provider_size) {
133 smallest_provider_size = iter_meta->md_provsize;
134 main_meta = iter_meta;
135 }
136 }
137
138 assert(main_meta != NULL);
139
140 vol->truncated_blkno =
141 main_meta->md_provsize / bsize;
142
143 vol->extent_no = main_meta->md_all;
144
145 vol->data_blkno = (vol->truncated_blkno - 1) * vol->extent_no;
146
147 vol->data_offset = 0;
148
149 if (main_meta->md_all > HR_MAX_EXTENTS) {
150 HR_DEBUG("Assembled volume has %u extents (max = %u)",
151 (unsigned)main_meta->md_all, HR_MAX_EXTENTS);
152 rc = EINVAL;
153 goto error;
154 }
155
156 vol->strip_size = main_meta->md_stripesize;
157
158 vol->layout = HR_RLQ_NONE;
159
160 memcpy(vol->in_mem_md, main_meta, sizeof(struct g_stripe_metadata));
161
162 list_foreach(*list, link, struct dev_list_member, iter) {
163 struct g_stripe_metadata *iter_meta = iter->md;
164 uint16_t index = iter_meta->md_no;
165
166 vol->extents[index].svc_id = iter->svc_id;
167 iter->fini = false;
168
169 vol->extents[index].status = HR_EXT_ONLINE;
170 }
171
172 for (size_t i = 0; i < vol->extent_no; i++) {
173 if (vol->extents[i].status == HR_EXT_NONE)
174 vol->extents[i].status = HR_EXT_MISSING;
175 }
176
177error:
178 return rc;
179}
180
181static void meta_stripe_encode(void *md_v, void *block)
182{
183 HR_DEBUG("%s()", __func__);
184
185 stripe_metadata_encode(md_v, block);
186}
187
188static errno_t meta_stripe_decode(const void *block, void *md_v)
189{
190 HR_DEBUG("%s()", __func__);
191
192 stripe_metadata_decode(block, md_v);
193
194 return EOK;
195}
196
197static errno_t meta_stripe_get_block(service_id_t dev, void **rblock)
198{
199 HR_DEBUG("%s()", __func__);
200
201 errno_t rc;
202 uint64_t blkno;
203 size_t bsize;
204 void *block;
205
206 if (rblock == NULL)
207 return EINVAL;
208
209 rc = block_get_bsize(dev, &bsize);
210 if (rc != EOK)
211 return rc;
212
213 if (bsize < sizeof(struct g_stripe_metadata))
214 return EINVAL;
215
216 rc = block_get_nblocks(dev, &blkno);
217 if (rc != EOK)
218 return rc;
219
220 if (blkno < 1)
221 return EINVAL;
222
223 block = malloc(bsize);
224 if (block == NULL)
225 return ENOMEM;
226
227 rc = block_read_direct(dev, blkno - 1, 1, block);
228 /*
229 * XXX: here maybe call vol status event or the state callback...
230 *
231 * but need to pass vol pointer
232 */
233 if (rc != EOK) {
234 free(block);
235 return rc;
236 }
237
238 *rblock = block;
239 return EOK;
240}
241
242static errno_t meta_stripe_write_block(service_id_t dev, const void *block)
243{
244 HR_DEBUG("%s()", __func__);
245
246 errno_t rc;
247 uint64_t blkno;
248 size_t bsize;
249
250 rc = block_get_bsize(dev, &bsize);
251 if (rc != EOK)
252 return rc;
253
254 if (bsize < sizeof(struct g_stripe_metadata))
255 return EINVAL;
256
257 rc = block_get_nblocks(dev, &blkno);
258 if (rc != EOK)
259 return rc;
260
261 if (blkno < 1)
262 return EINVAL;
263
264 rc = block_write_direct(dev, blkno - 1, 1, block);
265
266 return rc;
267}
268
269static bool meta_stripe_has_valid_magic(const void *md_v)
270{
271 HR_DEBUG("%s()", __func__);
272
273 const struct g_stripe_metadata *md = md_v;
274
275 if (str_lcmp(md->md_magic, G_STRIPE_MAGIC, 16) != 0)
276 return false;
277
278 return true;
279}
280
281static bool meta_stripe_compare_uuids(const void *md1_v, const void *md2_v)
282{
283 const struct g_stripe_metadata *md1 = md1_v;
284 const struct g_stripe_metadata *md2 = md2_v;
285 if (md1->md_id == md2->md_id)
286 return true;
287
288 return false;
289}
290
291static void meta_stripe_inc_counter(void *md_v)
292{
293 (void)md_v;
294}
295
296static errno_t meta_stripe_save(hr_volume_t *vol, bool with_state_callback)
297{
298 HR_DEBUG("%s()", __func__);
299
300 return EOK;
301}
302
303static const char *meta_stripe_get_devname(const void *md_v)
304{
305 const struct g_stripe_metadata *md = md_v;
306
307 return md->md_name;
308}
309
310static hr_level_t meta_stripe_get_level(const void *md_v)
311{
312 (void)md_v;
313
314 return HR_LVL_0;
315}
316
317static uint64_t meta_stripe_get_data_offset(void)
318{
319 return 0;
320}
321
322static size_t meta_stripe_get_size(void)
323{
324 return 1;
325}
326
327static uint8_t meta_stripe_get_flags(void)
328{
329 uint8_t flags = 0;
330
331 return flags;
332}
333
334static hr_metadata_type_t meta_stripe_get_type(void)
335{
336 return HR_METADATA_GEOM_STRIPE;
337}
338
339static void meta_stripe_dump(const void *md_v)
340{
341 HR_DEBUG("%s()", __func__);
342
343 const struct g_stripe_metadata *md = md_v;
344
345 printf(" magic: %s\n", md->md_magic);
346 printf(" version: %u\n", (u_int)md->md_version);
347 printf(" name: %s\n", md->md_name);
348 printf(" id: %u\n", (u_int)md->md_id);
349 printf(" no: %u\n", (u_int)md->md_no);
350 printf(" all: %u\n", (u_int)md->md_all);
351 printf("stripesize: %u\n", (u_int)md->md_stripesize);
352 printf(" mediasize: %jd\n", (intmax_t)md->md_provsize);
353}
354
355/** @}
356 */
Note: See TracBrowser for help on using the repository browser.