source: mainline/uspace/srv/bd/hr/raid0.c@ fad91b9

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

hr: make bd op functions more compact

A single function now handles all bd ops, just the type of IO reuqest
is specified in bd op caller. Besides this design being more compact,
it can be seen as preparation for workers and parallelization.

  • 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 <abi/ipc/ipc.h>
37#include <bd_srv.h>
38#include <block.h>
39#include <errno.h>
40#include <hr.h>
41#include <io/log.h>
42#include <ipc/hr.h>
43#include <ipc/services.h>
44#include <loc.h>
45#include <task.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <str_error.h>
49
50#include "superblock.h"
51#include "util.h"
52#include "var.h"
53
54extern loc_srv_t *hr_srv;
55
56static errno_t hr_raid0_bd_open(bd_srvs_t *, bd_srv_t *);
57static errno_t hr_raid0_bd_close(bd_srv_t *);
58static errno_t hr_raid0_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *,
59 size_t);
60static errno_t hr_raid0_bd_sync_cache(bd_srv_t *, aoff64_t, size_t);
61static errno_t hr_raid0_bd_write_blocks(bd_srv_t *, aoff64_t, size_t,
62 const void *, size_t);
63static errno_t hr_raid0_bd_get_block_size(bd_srv_t *, size_t *);
64static errno_t hr_raid0_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
65
66static bd_ops_t hr_raid0_bd_ops = {
67 .open = hr_raid0_bd_open,
68 .close = hr_raid0_bd_close,
69 .sync_cache = hr_raid0_bd_sync_cache,
70 .read_blocks = hr_raid0_bd_read_blocks,
71 .write_blocks = hr_raid0_bd_write_blocks,
72 .get_block_size = hr_raid0_bd_get_block_size,
73 .get_num_blocks = hr_raid0_bd_get_num_blocks
74};
75
76static void raid0_geometry(uint64_t x, hr_volume_t *vol, size_t *extent,
77 uint64_t *phys_block)
78{
79 uint64_t N = vol->dev_no; /* extents */
80 uint64_t L = vol->strip_size / vol->bsize; /* size of strip in blocks */
81
82 uint64_t i = (x / L) % N; /* extent */
83 uint64_t j = (x / L) / N; /* stripe */
84 uint64_t k = x % L; /* strip offset */
85
86 *extent = i;
87 *phys_block = j * L + k;
88}
89
90static errno_t hr_raid0_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
91{
92 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_bd_open()");
93 return EOK;
94}
95
96static errno_t hr_raid0_bd_close(bd_srv_t *bd)
97{
98 log_msg(LOG_DEFAULT, LVL_NOTE, "hr_bd_close()");
99 return EOK;
100}
101
102static errno_t hr_raid0_bd_op(hr_bd_op_type_t type, bd_srv_t *bd, aoff64_t ba,
103 size_t cnt, void *data_read, const void *data_write, size_t size)
104{
105 hr_volume_t *vol = bd->srvs->sarg;
106 errno_t rc;
107 uint64_t phys_block;
108 size_t extent, left;
109
110 if (type == HR_BD_READ || type == HR_BD_WRITE)
111 if (size < cnt * vol->bsize)
112 return EINVAL;
113
114 rc = hr_check_ba_range(vol, cnt, ba);
115 if (rc != EOK)
116 return rc;
117
118 fibril_mutex_lock(&vol->lock);
119
120 left = cnt;
121 while (left != 0) {
122 raid0_geometry(ba, vol, &extent, &phys_block);
123 hr_add_ba_offset(vol, &phys_block);
124 switch (type) {
125 case HR_BD_SYNC:
126 rc = block_sync_cache(vol->extents[extent].svc_id,
127 phys_block, 1);
128 break;
129 case HR_BD_READ:
130 rc = block_read_direct(vol->extents[extent].svc_id,
131 phys_block, 1, data_read);
132 data_read = data_read + vol->bsize;
133 break;
134 case HR_BD_WRITE:
135 rc = block_write_direct(vol->extents[extent].svc_id,
136 phys_block, 1, data_write);
137 data_write = data_write + vol->bsize;
138 break;
139 default:
140 rc = EINVAL;
141 }
142
143 if (rc != EOK)
144 goto error;
145
146 left--;
147 ba++;
148 }
149
150error:
151 fibril_mutex_unlock(&vol->lock);
152 return rc;
153}
154
155static errno_t hr_raid0_bd_sync_cache(bd_srv_t *bd, aoff64_t ba, size_t cnt)
156{
157 return hr_raid0_bd_op(HR_BD_SYNC, bd, ba, cnt, NULL, NULL, 0);
158}
159
160static errno_t hr_raid0_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
161 void *buf, size_t size)
162{
163 return hr_raid0_bd_op(HR_BD_READ, bd, ba, cnt, buf, NULL, size);
164}
165
166static errno_t hr_raid0_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
167 const void *data, size_t size)
168{
169 return hr_raid0_bd_op(HR_BD_WRITE, bd, ba, cnt, NULL, data, size);
170}
171
172static errno_t hr_raid0_bd_get_block_size(bd_srv_t *bd, size_t *rsize)
173{
174 hr_volume_t *vol = bd->srvs->sarg;
175
176 *rsize = vol->bsize;
177 return EOK;
178}
179
180static errno_t hr_raid0_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
181{
182 hr_volume_t *vol = bd->srvs->sarg;
183
184 *rnb = vol->data_blkno;
185 return EOK;
186}
187
188errno_t hr_raid0_create(hr_volume_t *new_volume)
189{
190 errno_t rc;
191
192 assert(new_volume->level == HR_LVL_0);
193
194 if (new_volume->dev_no < 2) {
195 log_msg(LOG_DEFAULT, LVL_ERROR,
196 "RAID 0 array needs at least 2 devices");
197 return EINVAL;
198 }
199
200 bd_srvs_init(&new_volume->hr_bds);
201 new_volume->hr_bds.ops = &hr_raid0_bd_ops;
202 new_volume->hr_bds.sarg = new_volume;
203
204 rc = hr_register_volume(new_volume);
205
206 return rc;
207}
208
209errno_t hr_raid0_init(hr_volume_t *vol)
210{
211 errno_t rc;
212 size_t bsize;
213 uint64_t total_blkno;
214
215 assert(vol->level == HR_LVL_0);
216
217 rc = hr_check_devs(vol, &total_blkno, &bsize);
218 if (rc != EOK)
219 return rc;
220
221 vol->nblocks = total_blkno;
222 vol->bsize = bsize;
223 vol->data_offset = HR_DATA_OFF;
224 vol->data_blkno = vol->nblocks - (vol->data_offset * vol->dev_no);
225 vol->strip_size = HR_STRIP_SIZE;
226
227 return EOK;
228}
229
230/** @}
231 */
Note: See TracBrowser for help on using the repository browser.