source: mainline/uspace/srv/bd/hr/io.c@ 81b4c795

Last change on this file since 81b4c795 was 81b4c795, checked in by Miroslav Cimerman <mc@…>, 6 weeks ago

hr: rename malloc_waitok() to hr_malloc_waitok()

  • Property mode set to 100644
File size: 7.6 KB
Line 
1/*
2 * Copyright (c) 2025 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 <inttypes.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <str.h>
43#include <str_error.h>
44
45#include "io.h"
46#include "parity_stripe.h"
47#include "util.h"
48#include "var.h"
49
50/** Wrapper for block_write_direct(), never returns ENOMEM */
51errno_t hr_write_direct(service_id_t service_id, uint64_t ba, size_t cnt,
52 const void *data)
53{
54 errno_t rc;
55 while ((rc = block_write_direct(service_id, ba, cnt, data)) == ENOMEM)
56 fibril_usleep(MSEC2USEC(250)); /* sleep 250ms */
57
58 if (rc == EAGAIN)
59 rc = EIO;
60
61 return rc;
62}
63
64/** Wrapper for block_read_direct(), never returns ENOMEM */
65errno_t hr_read_direct(service_id_t service_id, uint64_t ba, size_t cnt,
66 void *data)
67{
68 errno_t rc;
69 while ((rc = block_read_direct(service_id, ba, cnt, data)) == ENOMEM)
70 fibril_usleep(MSEC2USEC(250)); /* sleep 250ms */
71
72 if (rc == EAGAIN)
73 rc = EIO;
74
75 return rc;
76}
77
78/** Wrapper for block_sync_cache(), never returns ENOMEM */
79errno_t hr_sync_cache(service_id_t service_id, uint64_t ba, size_t cnt)
80{
81 errno_t rc;
82 while ((rc = block_sync_cache(service_id, ba, cnt)) == ENOMEM)
83 fibril_usleep(MSEC2USEC(250)); /* sleep 250ms */
84
85 if (rc == EAGAIN)
86 rc = EIO;
87
88 return rc;
89}
90
91errno_t hr_io_worker(void *arg)
92{
93 hr_io_t *io = arg;
94
95 errno_t rc;
96 size_t e = io->extent;
97 hr_extent_t *extents = (hr_extent_t *)&io->vol->extents;
98
99 switch (io->type) {
100 case HR_BD_READ:
101 rc = hr_read_direct(extents[e].svc_id, io->ba, io->cnt,
102 io->data_read);
103 break;
104 case HR_BD_WRITE:
105 rc = hr_write_direct(extents[e].svc_id, io->ba, io->cnt,
106 io->data_write);
107 break;
108 default:
109 assert(0);
110 }
111
112 if (rc != EOK)
113 io->vol->hr_ops.ext_state_cb(io->vol, io->extent, rc);
114
115 return rc;
116}
117
118errno_t hr_io_raid5_basic_reader(void *arg)
119{
120 errno_t rc;
121
122 hr_io_raid5_t *io = arg;
123
124 size_t ext_idx = io->extent;
125 hr_extent_t *extents = (hr_extent_t *)&io->vol->extents;
126
127 rc = hr_read_direct(extents[ext_idx].svc_id, io->ba, io->cnt,
128 io->data_read);
129 if (rc != EOK)
130 io->vol->hr_ops.ext_state_cb(io->vol, io->extent, rc);
131
132 return rc;
133}
134
135errno_t hr_io_raid5_reader(void *arg)
136{
137 errno_t rc;
138
139 hr_io_raid5_t *io = arg;
140 hr_stripe_t *stripe = io->stripe;
141
142 size_t ext_idx = io->extent;
143 hr_extent_t *extents = (hr_extent_t *)&io->vol->extents;
144
145 rc = hr_read_direct(extents[ext_idx].svc_id, io->ba, io->cnt,
146 io->data_read);
147 if (rc != EOK) {
148 hr_stripe_parity_abort(stripe);
149 io->vol->hr_ops.ext_state_cb(io->vol, io->extent, rc);
150 }
151
152 hr_stripe_commit_parity(stripe, io->strip_off, io->data_read,
153 io->cnt * io->vol->bsize);
154
155 return rc;
156}
157
158errno_t hr_io_raid5_basic_writer(void *arg)
159{
160 errno_t rc;
161
162 hr_io_raid5_t *io = arg;
163
164 size_t ext_idx = io->extent;
165 hr_extent_t *extents = (hr_extent_t *)&io->vol->extents;
166
167 rc = hr_write_direct(extents[ext_idx].svc_id, io->ba, io->cnt,
168 io->data_write);
169 if (rc != EOK)
170 io->vol->hr_ops.ext_state_cb(io->vol, io->extent, rc);
171
172 return rc;
173}
174
175errno_t hr_io_raid5_writer(void *arg)
176{
177 errno_t rc;
178
179 hr_io_raid5_t *io = arg;
180 hr_stripe_t *stripe = io->stripe;
181
182 size_t ext_idx = io->extent;
183 hr_extent_t *extents = (hr_extent_t *)&io->vol->extents;
184
185 hr_stripe_commit_parity(stripe, io->strip_off, io->data_write,
186 io->cnt * io->vol->bsize);
187
188 hr_stripe_wait_for_parity_commits(stripe);
189 if (stripe->abort)
190 return EAGAIN;
191
192 rc = hr_write_direct(extents[ext_idx].svc_id, io->ba, io->cnt,
193 io->data_write);
194 if (rc != EOK)
195 io->vol->hr_ops.ext_state_cb(io->vol, io->extent, rc);
196
197 return rc;
198}
199
200errno_t hr_io_raid5_noop_writer(void *arg)
201{
202 hr_io_raid5_t *io = arg;
203 hr_stripe_t *stripe = io->stripe;
204
205 hr_stripe_commit_parity(stripe, io->strip_off, io->data_write,
206 io->cnt * io->vol->bsize);
207
208 return EOK;
209}
210
211errno_t hr_io_raid5_parity_getter(void *arg)
212{
213 hr_io_raid5_t *io = arg;
214 hr_stripe_t *stripe = io->stripe;
215 size_t bsize = stripe->vol->bsize;
216
217 hr_stripe_wait_for_parity_commits(stripe);
218 if (stripe->abort)
219 return EAGAIN;
220
221 memcpy(io->data_read, stripe->parity + io->strip_off, io->cnt * bsize);
222
223 return EOK;
224}
225
226errno_t hr_io_raid5_subtract_writer(void *arg)
227{
228 errno_t rc;
229
230 hr_io_raid5_t *io = arg;
231 hr_stripe_t *stripe = io->stripe;
232
233 size_t ext_idx = io->extent;
234 hr_extent_t *extents = (hr_extent_t *)&io->vol->extents;
235
236 uint8_t *data = hr_malloc_waitok(io->cnt * io->vol->bsize);
237
238 rc = hr_read_direct(extents[ext_idx].svc_id, io->ba, io->cnt, data);
239 if (rc != EOK) {
240 io->vol->hr_ops.ext_state_cb(io->vol, io->extent, rc);
241 hr_stripe_parity_abort(stripe);
242 free(data);
243 return rc;
244 }
245
246 fibril_mutex_lock(&stripe->parity_lock);
247
248 hr_raid5_xor(stripe->parity + io->strip_off, data,
249 io->cnt * io->vol->bsize);
250
251 hr_raid5_xor(stripe->parity + io->strip_off, io->data_write,
252 io->cnt * io->vol->bsize);
253
254 stripe->ps_added++;
255 fibril_condvar_broadcast(&stripe->ps_added_cv);
256 fibril_mutex_unlock(&stripe->parity_lock);
257
258 hr_stripe_wait_for_parity_commits(stripe);
259 if (stripe->abort)
260 return EAGAIN;
261
262 rc = hr_write_direct(extents[ext_idx].svc_id, io->ba, io->cnt,
263 io->data_write);
264 if (rc != EOK)
265 io->vol->hr_ops.ext_state_cb(io->vol, io->extent, rc);
266
267 free(data);
268
269 return rc;
270}
271
272errno_t hr_io_raid5_reconstruct_reader(void *arg)
273{
274 errno_t rc;
275
276 hr_io_raid5_t *io = arg;
277 hr_stripe_t *stripe = io->stripe;
278
279 size_t ext_idx = io->extent;
280 hr_extent_t *extents = (hr_extent_t *)&io->vol->extents;
281
282 uint8_t *data = hr_malloc_waitok(io->cnt * io->vol->bsize);
283
284 rc = hr_write_direct(extents[ext_idx].svc_id, io->ba, io->cnt, data);
285 if (rc != EOK) {
286 hr_stripe_parity_abort(stripe);
287 io->vol->hr_ops.ext_state_cb(io->vol, io->extent, rc);
288 free(data);
289 return rc;
290 }
291
292 hr_stripe_commit_parity(stripe, io->strip_off, data,
293 io->cnt * io->vol->bsize);
294
295 free(data);
296
297 return EOK;
298}
299
300errno_t hr_io_raid5_parity_writer(void *arg)
301{
302 errno_t rc;
303
304 hr_io_raid5_t *io = arg;
305 hr_stripe_t *stripe = io->stripe;
306
307 hr_extent_t *extents = (hr_extent_t *)&io->vol->extents;
308
309 hr_stripe_wait_for_parity_commits(stripe);
310
311 if (stripe->abort)
312 return EAGAIN;
313
314 rc = hr_write_direct(extents[io->extent].svc_id, io->ba, io->cnt,
315 stripe->parity + io->strip_off);
316 if (rc != EOK)
317 io->vol->hr_ops.ext_state_cb(io->vol, stripe->p_extent, rc);
318
319 return rc;
320}
321
322/** @}
323 */
Note: See TracBrowser for help on using the repository browser.