source: mainline/uspace/srv/bd/hr/superblock.c@ 6f41c21f

Last change on this file since 6f41c21f was e77c3ed, checked in by Miroslav Cimerman <mc@…>, 7 months ago

hr: superblock.c,h: const quals for args

  • Property mode set to 100644
File size: 8.5 KB
RevLine 
[b0f1366]1/*
[a57dde4]2 * Copyright (c) 2025 Miroslav Cimerman
[b0f1366]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 <block.h>
37#include <byteorder.h>
38#include <errno.h>
[ca7fa5b]39#include <inttypes.h>
[b0f1366]40#include <io/log.h>
41#include <loc.h>
42#include <mem.h>
43#include <uuid.h>
44#include <stdlib.h>
45#include <stdio.h>
46#include <str.h>
47#include <types/uuid.h>
48
49#include "superblock.h"
50#include "util.h"
51#include "var.h"
52
[0277ec2]53errno_t hr_metadata_init(hr_volume_t *vol, hr_metadata_t *md)
[b0f1366]54{
[a57dde4]55 HR_DEBUG("%s()", __func__);
[b0f1366]56
[0277ec2]57 str_cpy(md->magic, HR_MAGIC_SIZE, HR_MAGIC_STR);
[b0f1366]58
[0277ec2]59 md->version = HR_METADATA_VERSION;
60 vol->metadata_version = md->version;
[b0f1366]61
[0277ec2]62 md->counter = 0;
[b0f1366]63
[0277ec2]64 uuid_t uuid;
[8b51009]65 /* rndgen */
66 fibril_usleep(1000);
[0277ec2]67 errno_t rc = uuid_generate(&uuid);
[8b51009]68 if (rc != EOK)
[0277ec2]69 return rc;
[8b51009]70
71 /* XXX: for now we just copy byte by byte as "encoding" */
[0277ec2]72 memcpy(md->uuid, &uuid, HR_UUID_LEN);
[8b51009]73 /* uuid_encode(&uuid, metadata->uuid); */
74
[0277ec2]75 md->nblocks = vol->nblocks;
76 md->data_blkno = vol->data_blkno;
77 md->truncated_blkno = vol->truncated_blkno;
78 md->data_offset = vol->data_offset;
79 md->extent_no = vol->extent_no;
80 md->level = vol->level;
81 md->layout = vol->layout;
82 md->strip_size = vol->strip_size;
83 md->bsize = vol->bsize;
84 memcpy(md->devname, vol->devname, HR_DEVNAME_LEN);
[b0f1366]85
[0277ec2]86 return EOK;
[b0f1366]87}
88
[52be5fa]89/*
[800d188]90 * XXX: finish this fcn documentation
91 *
92 * Returns ENOMEM else EOK
[52be5fa]93 */
[800d188]94errno_t hr_metadata_save(hr_volume_t *vol, bool with_state_callback)
[06f2762]95{
[a57dde4]96 HR_DEBUG("%s()", __func__);
[06f2762]97
[0277ec2]98 errno_t rc = EOK;
[06f2762]99
[0277ec2]100 void *md_block = calloc(1, vol->bsize);
101 if (md_block == NULL)
[06f2762]102 return ENOMEM;
103
[800d188]104 fibril_rwlock_read_lock(&vol->extents_lock);
105
106 fibril_mutex_lock(&vol->md_lock);
107
[0277ec2]108 for (size_t i = 0; i < vol->extent_no; i++) {
109 hr_extent_t *ext = &vol->extents[i];
[06f2762]110
[800d188]111 fibril_rwlock_read_lock(&vol->states_lock);
112
[0277ec2]113 /* TODO: special case for REBUILD */
114 if (ext->status != HR_EXT_ONLINE)
115 continue;
[06f2762]116
[800d188]117 fibril_rwlock_read_unlock(&vol->states_lock);
118
[0277ec2]119 vol->in_mem_md->index = i;
120 hr_encode_metadata_to_block(vol->in_mem_md, md_block);
121 rc = hr_write_metadata_block(ext->svc_id, md_block);
[800d188]122 if (with_state_callback && rc != EOK)
123 vol->state_callback(vol, i, rc);
[0277ec2]124 }
[06f2762]125
[800d188]126 fibril_mutex_unlock(&vol->md_lock);
127
128 fibril_rwlock_read_unlock(&vol->extents_lock);
129
130 if (with_state_callback)
131 vol->hr_ops.status_event(vol);
132
[0277ec2]133 free(md_block);
[800d188]134 return EOK;
[06f2762]135}
136
[e77c3ed]137bool hr_valid_md_magic(const hr_metadata_t *md)
[06f2762]138{
[a57dde4]139 HR_DEBUG("%s()", __func__);
[06f2762]140
[8b51009]141 if (str_lcmp(md->magic, HR_MAGIC_STR, HR_MAGIC_SIZE) != 0)
142 return false;
143
144 return true;
[b422718]145}
146
[0277ec2]147errno_t hr_write_metadata_block(service_id_t dev, const void *block)
[b0f1366]148{
[a57dde4]149 HR_DEBUG("%s()", __func__);
[b0f1366]150
151 errno_t rc;
[0277ec2]152 uint64_t blkno;
153 size_t bsize;
[b0f1366]154
[0277ec2]155 rc = block_get_bsize(dev, &bsize);
[b0f1366]156 if (rc != EOK)
157 return rc;
158
[0277ec2]159 if (bsize < sizeof(hr_metadata_t))
[b0f1366]160 return EINVAL;
161
[0277ec2]162 rc = block_get_nblocks(dev, &blkno);
[b0f1366]163 if (rc != EOK)
164 return rc;
165
[0277ec2]166 if (blkno < HR_META_SIZE)
167 return EINVAL;
168
169 rc = block_write_direct(dev, blkno - 1, HR_META_SIZE, block);
170
171 return rc;
[b0f1366]172}
173
[8b51009]174errno_t hr_get_metadata_block(service_id_t dev, void **rblock)
175{
176 HR_DEBUG("%s()", __func__);
[0277ec2]177
[8b51009]178 errno_t rc;
179 uint64_t blkno;
180 size_t bsize;
181 void *block;
182
183 rc = block_get_bsize(dev, &bsize);
184 if (rc != EOK)
185 return rc;
186
187 if (bsize < sizeof(hr_metadata_t))
188 return EINVAL;
189
190 rc = block_get_nblocks(dev, &blkno);
191 if (rc != EOK)
192 return rc;
193
[a5ec426]194 if (blkno < HR_META_SIZE)
[8b51009]195 return EINVAL;
196
197 block = malloc(bsize);
198 if (block == NULL)
199 return ENOMEM;
200
[a5ec426]201 rc = block_read_direct(dev, blkno - 1, HR_META_SIZE, block);
[0277ec2]202 /*
203 * XXX: here maybe call vol status event or the state callback...
204 *
205 * but need to pass vol pointer
206 */
[8b51009]207 if (rc != EOK) {
208 free(block);
209 return rc;
210 }
211
212 if (rblock == NULL) {
213 free(block);
214 return EINVAL;
215 }
216
217 *rblock = block;
218 return EOK;
219}
220
[e77c3ed]221void hr_encode_metadata_to_block(const hr_metadata_t *metadata, void *block)
[8b51009]222{
[0277ec2]223 HR_DEBUG("%s()", __func__);
224
225 /*
226 * Use scratch metadata for easier encoding without the need
227 * for manualy specifying offsets.
228 */
229 hr_metadata_t scratch_md;
230
231 memcpy(scratch_md.magic, metadata->magic, HR_MAGIC_SIZE);
232 memcpy(scratch_md.uuid, metadata->uuid, HR_UUID_LEN);
233 /* uuid_decode((uint8_t *)scratch_md.uuid, (uuid_t *)metadata->uuid); */
234
235 scratch_md.nblocks = host2uint64_t_le(metadata->nblocks);
236 scratch_md.data_blkno = host2uint64_t_le(metadata->data_blkno);
237 scratch_md.truncated_blkno = host2uint64_t_le(
238 metadata->truncated_blkno);
239 scratch_md.data_offset = host2uint64_t_le(metadata->data_offset);
240 scratch_md.counter = host2uint64_t_le(metadata->counter);
241 scratch_md.version = host2uint32_t_le(metadata->version);
242 scratch_md.extent_no = host2uint32_t_le(metadata->extent_no);
243 scratch_md.index = host2uint32_t_le(metadata->index);
244 scratch_md.level = host2uint32_t_le(metadata->level);
245 scratch_md.layout = host2uint32_t_le(metadata->layout);
246 scratch_md.strip_size = host2uint32_t_le(metadata->strip_size);
247 scratch_md.bsize = host2uint32_t_le(metadata->bsize);
248 memcpy(scratch_md.devname, metadata->devname, HR_DEVNAME_LEN);
249
250 memcpy(block, &scratch_md, sizeof(hr_metadata_t));
251}
252
253void hr_decode_metadata_from_block(const void *block, hr_metadata_t *metadata)
254{
255 HR_DEBUG("%s()", __func__);
256
[8b51009]257 /*
258 * Use scratch metadata for easier decoding without the need
259 * for manualy specifying offsets.
260 */
261 hr_metadata_t scratch_md;
262 memcpy(&scratch_md, block, sizeof(hr_metadata_t));
263
264 memcpy(metadata->magic, scratch_md.magic, HR_MAGIC_SIZE);
265 memcpy(metadata->uuid, scratch_md.uuid, HR_UUID_LEN);
[1a28518]266 /* uuid_decode((uint8_t *)scratch_md.uuid, (uuid_t *)metadata->uuid); */
267
[8b51009]268 metadata->nblocks = uint64_t_le2host(scratch_md.nblocks);
269 metadata->data_blkno = uint64_t_le2host(scratch_md.data_blkno);
270 metadata->truncated_blkno = uint64_t_le2host(
271 scratch_md.truncated_blkno);
272 metadata->data_offset = uint64_t_le2host(scratch_md.data_offset);
273 metadata->counter = uint64_t_le2host(scratch_md.counter);
274 metadata->version = uint32_t_le2host(scratch_md.version);
275 metadata->extent_no = uint32_t_le2host(scratch_md.extent_no);
276 metadata->index = uint32_t_le2host(scratch_md.index);
277 metadata->level = uint32_t_le2host(scratch_md.level);
278 metadata->layout = uint32_t_le2host(scratch_md.layout);
279 metadata->strip_size = uint32_t_le2host(scratch_md.strip_size);
[1a28518]280 metadata->bsize = uint32_t_le2host(scratch_md.bsize);
[8b51009]281 memcpy(metadata->devname, scratch_md.devname, HR_DEVNAME_LEN);
282}
283
[e77c3ed]284void hr_metadata_dump(const hr_metadata_t *metadata)
[8b51009]285{
[0277ec2]286 HR_DEBUG("%s()", __func__);
287
[8b51009]288 printf("\tmagic: %s\n", metadata->magic);
289 printf("\tUUID: ");
290 for (size_t i = 0; i < HR_UUID_LEN; ++i) {
291 printf("%.2X", metadata->uuid[i]);
292 if (i + 1 < HR_UUID_LEN)
293 printf(" ");
294 }
295 printf("\n");
[ca7fa5b]296 printf("\tnblocks: %" PRIu64 "\n", metadata->nblocks);
297 printf("\tdata_blkno: %" PRIu64 "\n", metadata->data_blkno);
298 printf("\ttruncated_blkno: %" PRIu64 "\n", metadata->truncated_blkno);
299 printf("\tdata_offset: %" PRIu64 "\n", metadata->data_offset);
300 printf("\tcounter: %" PRIu64 "\n", metadata->counter);
301 printf("\tversion: %" PRIu32 "\n", metadata->version);
302 printf("\textent_no: %" PRIu32 "\n", metadata->extent_no);
303 printf("\tindex: %" PRIu32 "\n", metadata->index);
304 printf("\tlevel: %" PRIu32 "\n", metadata->level);
305 printf("\tlayout: %" PRIu32 "\n", metadata->layout);
306 printf("\tstrip_size: %" PRIu32 "\n", metadata->strip_size);
307 printf("\tbsize: %" PRIu32 "\n", metadata->bsize);
[8b51009]308 printf("\tdevname: %s\n", metadata->devname);
309}
310
[b0f1366]311/** @}
312 */
Note: See TracBrowser for help on using the repository browser.