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

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

hr: remake structures to include extent status

Also rename .devs → .extents in hr_volume_t and when printing status,
display each extent status, and parity disk when array is of type RAID4.

  • Property mode set to 100644
File size: 4.6 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 rc = block_init(vol->extents[i].svc_id);
59 log_msg(LOG_DEFAULT, LVL_DEBUG,
60 "hr_init_devs(): initing (%" PRIun ")", vol->extents[i].svc_id);
61 if (rc != EOK) {
62 log_msg(LOG_DEFAULT, LVL_ERROR,
63 "hr_init_devs(): initing (%" PRIun ") failed, aborting",
64 vol->extents[i].svc_id);
65 break;
66 }
67 }
68
69 return rc;
70}
71
72void hr_fini_devs(hr_volume_t *vol)
73{
74 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_fini_devs()");
75
76 size_t i;
77
78 for (i = 0; i < vol->dev_no; i++)
79 block_fini(vol->extents[i].svc_id);
80}
81
82errno_t hr_register_volume(hr_volume_t *new_volume)
83{
84 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_register_volume()");
85
86 errno_t rc;
87 service_id_t new_id;
88 category_id_t cat_id;
89 char *fullname = NULL;
90
91 if (asprintf(&fullname, "devices/%s", new_volume->devname) < 0)
92 return ENOMEM;
93
94 rc = loc_service_register(hr_srv, fullname, &new_id);
95 if (rc != EOK) {
96 log_msg(LOG_DEFAULT, LVL_ERROR,
97 "unable to register device \"%s\": %s\n",
98 new_volume->devname, str_error(rc));
99 goto error;
100 }
101
102 rc = loc_category_get_id("raid", &cat_id, IPC_FLAG_BLOCKING);
103 if (rc != EOK) {
104 log_msg(LOG_DEFAULT, LVL_ERROR,
105 "failed resolving category \"raid\": %s\n", str_error(rc));
106 goto error;
107 }
108
109 rc = loc_service_add_to_cat(hr_srv, new_id, cat_id);
110 if (rc != EOK) {
111 log_msg(LOG_DEFAULT, LVL_ERROR,
112 "failed adding \"%s\" to category \"raid\": %s\n",
113 new_volume->devname, str_error(rc));
114 goto error;
115 }
116
117 new_volume->svc_id = new_id;
118
119error:
120 free(fullname);
121 return rc;
122}
123
124errno_t hr_check_devs(hr_volume_t *vol)
125{
126 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_check_devs()");
127
128 errno_t rc;
129 size_t i, bsize, last_bsize;
130 uint64_t nblocks, last_nblocks;
131 uint64_t total_blocks = 0;
132
133 for (i = 0; i < vol->dev_no; i++) {
134 rc = block_get_nblocks(vol->extents[i].svc_id, &nblocks);
135 if (rc != EOK)
136 goto error;
137 if (i != 0 && nblocks != last_nblocks) {
138 log_msg(LOG_DEFAULT, LVL_ERROR,
139 "number of blocks differs");
140 rc = EINVAL;
141 goto error;
142 }
143 total_blocks += nblocks;
144 last_nblocks = nblocks;
145 }
146
147 for (i = 0; i < vol->dev_no; i++) {
148 rc = block_get_bsize(vol->extents[i].svc_id, &bsize);
149 if (rc != EOK)
150 goto error;
151 if (i != 0 && bsize != last_bsize) {
152 log_msg(LOG_DEFAULT, LVL_ERROR, "block sizes differ");
153 rc = EINVAL;
154 goto error;
155 }
156 last_bsize = bsize;
157 }
158
159 if (vol->level == hr_l_1) {
160 vol->nblocks = total_blocks / vol->dev_no;
161 } else if (vol->level == hr_l_0 || vol->level == hr_l_4) {
162 vol->nblocks = total_blocks;
163 } else {
164 log_msg(LOG_DEFAULT, LVL_DEBUG, "unkown level, ok when assembling");
165 vol->nblocks = 0;
166 }
167
168 vol->bsize = bsize;
169
170error:
171 return rc;
172}
173
174errno_t hr_check_ba_range(hr_volume_t *vol, size_t cnt, uint64_t ba)
175{
176 if (ba + cnt > vol->data_blkno)
177 return ERANGE;
178 return EOK;
179}
180
181void hr_add_ba_offset(hr_volume_t *vol, uint64_t *ba)
182{
183 *ba = *ba + vol->data_offset;
184}
185
186/** @}
187 */
Note: See TracBrowser for help on using the repository browser.