source: mainline/uspace/srv/bd/hr/superblock.c@ 9c1cf34c

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

hr: add strip size to metadata and hr_volume_t

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2024 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 <block.h>
37#include <byteorder.h>
38#include <errno.h>
39#include <io/log.h>
40#include <loc.h>
41#include <mem.h>
42#include <uuid.h>
43#include <stdlib.h>
44#include <stdio.h>
45#include <str.h>
46#include <types/uuid.h>
47
48#include "superblock.h"
49#include "util.h"
50#include "var.h"
51
52static errno_t read_metadata(service_id_t, hr_metadata_t *);
53
54errno_t hr_write_meta_to_vol(hr_volume_t *vol)
55{
56 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_write_meta_to_vol()");
57
58 errno_t rc;
59 size_t i, data_offset;
60 uint64_t data_blkno;
61 hr_metadata_t *metadata;
62 uuid_t uuid;
63
64 metadata = calloc(1, HR_META_SIZE * vol->bsize);
65 if (metadata == NULL)
66 return ENOMEM;
67
68 if (vol->nblocks <= HR_META_OFF + HR_META_SIZE) {
69 log_msg(LOG_DEFAULT, LVL_ERROR,
70 "not enough blocks");
71 rc = EINVAL;
72 goto error;
73 }
74
75 data_offset = HR_META_OFF + HR_META_SIZE;
76 if (vol->level == hr_l_1) {
77 data_blkno = vol->nblocks - data_offset;
78 } else if (vol->level == hr_l_0) {
79 data_blkno = vol->nblocks - (data_offset * vol->dev_no);
80 } else {
81 log_msg(LOG_DEFAULT, LVL_ERROR,
82 "level %d not implemented yet", vol->level);
83 return EINVAL;
84 }
85
86 metadata->magic = host2uint64_t_le(HR_MAGIC);
87 metadata->extent_no = host2uint32_t_le(vol->dev_no);
88 metadata->level = host2uint32_t_le(vol->level);
89 metadata->nblocks = host2uint64_t_le(vol->nblocks);
90 metadata->data_blkno = host2uint64_t_le(data_blkno);
91 metadata->data_offset = host2uint32_t_le(data_offset);
92 metadata->strip_size = host2uint32_t_le(vol->strip_size);
93 for (i = 0; i < vol->dev_no; i++) {
94 metadata->index = host2uint32_t_le(i);
95
96 rc = uuid_generate(&uuid);
97 if (rc != EOK)
98 goto error;
99 uuid_encode(&uuid, metadata->uuid);
100
101 str_cpy(metadata->devname, 32, vol->devname);
102
103 rc = block_write_direct(vol->devs[i], HR_META_OFF, HR_META_SIZE,
104 metadata);
105 if (rc != EOK)
106 goto error;
107 }
108
109 /* fill in new members */
110 vol->data_offset = data_offset;
111 vol->data_blkno = data_blkno;
112
113error:
114 free(metadata);
115 return rc;
116}
117
118errno_t hr_get_vol_from_meta(hr_config_t *cfg, hr_volume_t *new_volume)
119{
120 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_get_vol_from_meta()");
121
122 errno_t rc;
123 hr_metadata_t *metadata;
124
125 metadata = calloc(1, HR_META_SIZE * new_volume->bsize);
126 if (metadata == NULL)
127 return ENOMEM;
128
129 /* for now assume metadata are in sync across extents */
130 rc = read_metadata(cfg->devs[0], metadata);
131 if (rc != EOK)
132 goto end;
133
134 /* TODO: sort new_volume->devs according to metadata extent index */
135
136 if (uint64_t_le2host(metadata->magic) != HR_MAGIC) {
137 printf("invalid magic\n");
138 rc = EINVAL;
139 goto end;
140 }
141
142 new_volume->level = uint32_t_le2host(metadata->level);
143 new_volume->dev_no = uint32_t_le2host(metadata->extent_no);
144 new_volume->nblocks = uint64_t_le2host(metadata->nblocks);
145 new_volume->data_blkno = uint64_t_le2host(metadata->data_blkno);
146 new_volume->data_offset = uint32_t_le2host(metadata->data_offset);
147 new_volume->strip_size = uint32_t_le2host(metadata->strip_size);
148
149 if (str_cmp(metadata->devname, new_volume->devname) != 0) {
150 log_msg(LOG_DEFAULT, LVL_NOTE,
151 "devname on metadata (%s) and config (%s) differ, using config",
152 metadata->devname, new_volume->devname);
153 }
154end:
155 free(metadata);
156 return EOK;
157}
158
159static errno_t read_metadata(service_id_t dev, hr_metadata_t *metadata)
160{
161 errno_t rc;
162 size_t bsize;
163 uint64_t nblocks;
164
165 rc = block_get_bsize(dev, &bsize);
166 if (rc != EOK)
167 return rc;
168
169 rc = block_get_nblocks(dev, &nblocks);
170 if (rc != EOK)
171 return rc;
172
173 if (nblocks < (HR_META_SIZE + HR_META_OFF) * bsize)
174 return EINVAL;
175
176 rc = block_read_direct(dev, HR_META_OFF, HR_META_SIZE, metadata);
177 if (rc != EOK)
178 return rc;
179
180 return EOK;
181}
182
183/** @}
184 */
Note: See TracBrowser for help on using the repository browser.