source: mainline/uspace/srv/bd/hr/util.c@ bd51105

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

hr: add hr_sync_all_extents()

  • Property mode set to 100644
File size: 5.9 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 <errno.h>
38#include <hr.h>
39#include <io/log.h>
40#include <loc.h>
41#include <stdlib.h>
42#include <stdio.h>
43#include <str_error.h>
44
45#include "util.h"
46#include "var.h"
47
48extern loc_srv_t *hr_srv;
49
50errno_t hr_init_devs(hr_volume_t *vol)
51{
52 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_init_devs()");
53
54 errno_t rc;
55 size_t i;
56
57 for (i = 0; i < vol->dev_no; i++) {
58 if (vol->extents[i].svc_id == 0) {
59 vol->extents[i].status = HR_EXT_MISSING;
60 continue;
61 }
62 rc = block_init(vol->extents[i].svc_id);
63 vol->extents[i].status = HR_EXT_ONLINE;
64 log_msg(LOG_DEFAULT, LVL_DEBUG,
65 "hr_init_devs(): initing (%" PRIun ")",
66 vol->extents[i].svc_id);
67 if (rc != EOK) {
68 log_msg(LOG_DEFAULT, LVL_ERROR,
69 "hr_init_devs(): initing (%" PRIun ") failed, aborting",
70 vol->extents[i].svc_id);
71 break;
72 }
73 }
74
75 return rc;
76}
77
78void hr_fini_devs(hr_volume_t *vol)
79{
80 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_fini_devs()");
81
82 size_t i;
83
84 for (i = 0; i < vol->dev_no; i++)
85 if (vol->extents[i].status != HR_EXT_MISSING)
86 block_fini(vol->extents[i].svc_id);
87}
88
89errno_t hr_register_volume(hr_volume_t *new_volume)
90{
91 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_register_volume()");
92
93 errno_t rc;
94 service_id_t new_id;
95 category_id_t cat_id;
96 char *fullname = NULL;
97
98 if (asprintf(&fullname, "devices/%s", new_volume->devname) < 0)
99 return ENOMEM;
100
101 rc = loc_service_register(hr_srv, fullname, &new_id);
102 if (rc != EOK) {
103 log_msg(LOG_DEFAULT, LVL_ERROR,
104 "unable to register device \"%s\": %s\n",
105 new_volume->devname, str_error(rc));
106 goto error;
107 }
108
109 rc = loc_category_get_id("raid", &cat_id, IPC_FLAG_BLOCKING);
110 if (rc != EOK) {
111 log_msg(LOG_DEFAULT, LVL_ERROR,
112 "failed resolving category \"raid\": %s\n", str_error(rc));
113 goto error;
114 }
115
116 rc = loc_service_add_to_cat(hr_srv, new_id, cat_id);
117 if (rc != EOK) {
118 log_msg(LOG_DEFAULT, LVL_ERROR,
119 "failed adding \"%s\" to category \"raid\": %s\n",
120 new_volume->devname, str_error(rc));
121 goto error;
122 }
123
124 new_volume->svc_id = new_id;
125
126error:
127 free(fullname);
128 return rc;
129}
130
131errno_t hr_check_devs(hr_volume_t *vol, uint64_t *rblkno, size_t *rbsize)
132{
133 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_check_devs()");
134
135 errno_t rc;
136 size_t i, bsize;
137 uint64_t nblocks;
138 size_t last_bsize = 0;
139 uint64_t last_nblocks = 0;
140 uint64_t total_blocks = 0;
141
142 for (i = 0; i < vol->dev_no; i++) {
143 if (vol->extents[i].status == HR_EXT_MISSING)
144 continue;
145 rc = block_get_nblocks(vol->extents[i].svc_id, &nblocks);
146 if (rc != EOK)
147 goto error;
148 if (last_nblocks != 0 && nblocks != last_nblocks) {
149 log_msg(LOG_DEFAULT, LVL_ERROR,
150 "number of blocks differs");
151 rc = EINVAL;
152 goto error;
153 }
154 total_blocks += nblocks;
155 last_nblocks = nblocks;
156 }
157
158 for (i = 0; i < vol->dev_no; i++) {
159 if (vol->extents[i].status == HR_EXT_MISSING)
160 continue;
161 rc = block_get_bsize(vol->extents[i].svc_id, &bsize);
162 if (rc != EOK)
163 goto error;
164 if (last_bsize != 0 && bsize != last_bsize) {
165 log_msg(LOG_DEFAULT, LVL_ERROR, "block sizes differ");
166 rc = EINVAL;
167 goto error;
168 }
169 last_bsize = bsize;
170 }
171
172 if ((bsize % 512) != 0) {
173 log_msg(LOG_DEFAULT, LVL_ERROR,
174 "block size not multiple of 512");
175 return EINVAL;
176 }
177
178 if (rblkno != NULL)
179 *rblkno = total_blocks;
180 if (rbsize != NULL)
181 *rbsize = bsize;
182error:
183 return rc;
184}
185
186errno_t hr_check_ba_range(hr_volume_t *vol, size_t cnt, uint64_t ba)
187{
188 if (ba + cnt > vol->data_blkno)
189 return ERANGE;
190 return EOK;
191}
192
193void hr_add_ba_offset(hr_volume_t *vol, uint64_t *ba)
194{
195 *ba = *ba + vol->data_offset;
196}
197
198void hr_update_ext_status(hr_volume_t *vol, uint64_t extent, hr_ext_status_t s)
199{
200 log_msg(LOG_DEFAULT, LVL_WARN,
201 "vol %s, changing extent: %lu, to status: %s",
202 vol->devname, extent, hr_get_ext_status_msg(s));
203 vol->extents[extent].status = s;
204}
205
206/*
207 * Do a whole sync (ba = 0, cnt = 0) across all extents,
208 * and update extent status. *For now*, the caller has to
209 * update volume status after the syncs.
210 *
211 * TODO: add update_vol_status fcn ptr for each raid
212 */
213void hr_sync_all_extents(hr_volume_t *vol)
214{
215 errno_t rc;
216
217 fibril_mutex_lock(&vol->lock);
218 for (size_t i = 0; i < vol->dev_no; i++) {
219 if (vol->extents[i].status != HR_EXT_ONLINE)
220 continue;
221 rc = block_sync_cache(vol->extents[i].svc_id, 0, 0);
222 if (rc != EOK && rc != ENOTSUP) {
223 if (rc == ENOENT)
224 hr_update_ext_status(vol, i, HR_EXT_MISSING);
225 else if (rc != EOK)
226 hr_update_ext_status(vol, i, HR_EXT_FAILED);
227 }
228 }
229 fibril_mutex_unlock(&vol->lock);
230}
231
232/** @}
233 */
Note: See TracBrowser for help on using the repository browser.