source: mainline/uspace/srv/bd/hr/raid1.c@ a438de5b

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