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

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

hr: add hr_count_extents(volume, state)

Counts volume extents in some state.

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