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
RevLine 
[da5c257]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>
[44ea48e]41#include <stdlib.h>
42#include <stdio.h>
[da5c257]43#include <str_error.h>
44
45#include "util.h"
[b0f1366]46#include "var.h"
[da5c257]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++) {
[e47a032]58 if (vol->extents[i].svc_id == 0) {
59 vol->extents[i].status = HR_EXT_MISSING;
60 continue;
61 }
[dbd91da]62 rc = block_init(vol->extents[i].svc_id);
[e47a032]63 vol->extents[i].status = HR_EXT_ONLINE;
[da5c257]64 log_msg(LOG_DEFAULT, LVL_DEBUG,
[e47a032]65 "hr_init_devs(): initing (%" PRIun ")",
66 vol->extents[i].svc_id);
[da5c257]67 if (rc != EOK) {
68 log_msg(LOG_DEFAULT, LVL_ERROR,
69 "hr_init_devs(): initing (%" PRIun ") failed, aborting",
[dbd91da]70 vol->extents[i].svc_id);
[da5c257]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++)
[e47a032]85 if (vol->extents[i].status != HR_EXT_MISSING)
86 block_fini(vol->extents[i].svc_id);
[da5c257]87}
88
89errno_t hr_register_volume(hr_volume_t *new_volume)
90{
[b0f1366]91 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_register_volume()");
92
[da5c257]93 errno_t rc;
94 service_id_t new_id;
95 category_id_t cat_id;
[44ea48e]96 char *fullname = NULL;
[da5c257]97
[44ea48e]98 if (asprintf(&fullname, "devices/%s", new_volume->devname) < 0)
99 return ENOMEM;
100
101 rc = loc_service_register(hr_srv, fullname, &new_id);
[da5c257]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:
[44ea48e]127 free(fullname);
[da5c257]128 return rc;
129}
130
[6b8e89b0]131errno_t hr_check_devs(hr_volume_t *vol, uint64_t *rblkno, size_t *rbsize)
[b0f1366]132{
133 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_check_devs()");
134
135 errno_t rc;
[e47a032]136 size_t i, bsize;
137 uint64_t nblocks;
138 size_t last_bsize = 0;
139 uint64_t last_nblocks = 0;
[b0f1366]140 uint64_t total_blocks = 0;
141
142 for (i = 0; i < vol->dev_no; i++) {
[e47a032]143 if (vol->extents[i].status == HR_EXT_MISSING)
144 continue;
[dbd91da]145 rc = block_get_nblocks(vol->extents[i].svc_id, &nblocks);
[b0f1366]146 if (rc != EOK)
147 goto error;
[e47a032]148 if (last_nblocks != 0 && nblocks != last_nblocks) {
[b0f1366]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++) {
[e47a032]159 if (vol->extents[i].status == HR_EXT_MISSING)
160 continue;
[dbd91da]161 rc = block_get_bsize(vol->extents[i].svc_id, &bsize);
[b0f1366]162 if (rc != EOK)
163 goto error;
[e47a032]164 if (last_bsize != 0 && bsize != last_bsize) {
[b0f1366]165 log_msg(LOG_DEFAULT, LVL_ERROR, "block sizes differ");
166 rc = EINVAL;
167 goto error;
168 }
169 last_bsize = bsize;
170 }
171
[1cfa162]172 if ((bsize % 512) != 0) {
173 log_msg(LOG_DEFAULT, LVL_ERROR,
174 "block size not multiple of 512");
175 return EINVAL;
176 }
177
[6b8e89b0]178 if (rblkno != NULL)
179 *rblkno = total_blocks;
180 if (rbsize != NULL)
181 *rbsize = bsize;
[b0f1366]182error:
183 return rc;
184}
185
[4a2a6b8b]186errno_t hr_check_ba_range(hr_volume_t *vol, size_t cnt, uint64_t ba)
[b0f1366]187{
[4a2a6b8b]188 if (ba + cnt > vol->data_blkno)
[b0f1366]189 return ERANGE;
[4a2a6b8b]190 return EOK;
191}
[b0f1366]192
[4a2a6b8b]193void hr_add_ba_offset(hr_volume_t *vol, uint64_t *ba)
194{
[b0f1366]195 *ba = *ba + vol->data_offset;
196}
197
[e47a032]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
[52af125]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
[da5c257]232/** @}
233 */
Note: See TracBrowser for help on using the repository browser.