source: mainline/uspace/lib/c/generic/vol.c@ 8610c2c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8610c2c was 25a179e, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

IPC return values are always errno constants. Adjust types to reflect that.

In principle, IPC server is not allowed to return non-errno values via
the "main" return value, because kernel interprets it (e.g. EHANGUP).
It's still possible to return arbitrary additional return values alongside EOK,
which are not interpreted in normal communication.

  • Property mode set to 100644
File size: 7.1 KB
Line 
1/*
2 * Copyright (c) 2015 Jiri Svoboda
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 libc
30 * @{
31 */
32/** @file Volume service API
33 */
34
35#include <abi/ipc/interfaces.h>
36#include <errno.h>
37#include <ipc/services.h>
38#include <ipc/vol.h>
39#include <loc.h>
40#include <stdlib.h>
41#include <str.h>
42#include <vol.h>
43
44/** Create Volume service session.
45 *
46 * @param rvol Place to store pointer to volume service session.
47 * @return EOK on success, ENOMEM if out of memory, EIO if service
48 * cannot be contacted.
49 */
50int vol_create(vol_t **rvol)
51{
52 vol_t *vol;
53 service_id_t vol_svcid;
54 int rc;
55
56 vol = calloc(1, sizeof(vol_t));
57 if (vol == NULL) {
58 rc = ENOMEM;
59 goto error;
60 }
61
62 rc = loc_service_get_id(SERVICE_NAME_VOLSRV, &vol_svcid, 0);
63 if (rc != EOK) {
64 rc = ENOENT;
65 goto error;
66 }
67
68 vol->sess = loc_service_connect(vol_svcid, INTERFACE_VOL, 0);
69 if (vol->sess == NULL) {
70 rc = EIO;
71 goto error;
72 }
73
74 *rvol = vol;
75 return EOK;
76error:
77 free(vol);
78 return rc;
79}
80
81/** Destroy volume service session.
82 *
83 * @param vol Volume service session
84 */
85void vol_destroy(vol_t *vol)
86{
87 if (vol == NULL)
88 return;
89
90 async_hangup(vol->sess);
91 free(vol);
92}
93
94/** Get list of IDs into a buffer of fixed size.
95 *
96 * @param vol Volume service
97 * @param method IPC method
98 * @param arg1 First argument
99 * @param id_buf Buffer to store IDs
100 * @param buf_size Buffer size
101 * @param act_size Place to store actual size of complete data.
102 *
103 * @return EOK on success or negative error code.
104 */
105static int vol_get_ids_once(vol_t *vol, sysarg_t method, sysarg_t arg1,
106 sysarg_t *id_buf, size_t buf_size, size_t *act_size)
107{
108 async_exch_t *exch = async_exchange_begin(vol->sess);
109
110 ipc_call_t answer;
111 aid_t req = async_send_1(exch, method, arg1, &answer);
112 int rc = async_data_read_start(exch, id_buf, buf_size);
113
114 async_exchange_end(exch);
115
116 if (rc != EOK) {
117 async_forget(req);
118 return rc;
119 }
120
121 int retval;
122 async_wait_for(req, &retval);
123
124 if (retval != EOK) {
125 return retval;
126 }
127
128 *act_size = IPC_GET_ARG1(answer);
129 return EOK;
130}
131
132/** Get list of IDs.
133 *
134 * Returns an allocated array of service IDs.
135 *
136 * @param vol Volume service
137 * @param method IPC method
138 * @param arg1 IPC argument 1
139 * @param data Place to store pointer to array of IDs
140 * @param count Place to store number of IDs
141 * @return EOK on success or negative error code
142 */
143static int vol_get_ids_internal(vol_t *vol, sysarg_t method, sysarg_t arg1,
144 sysarg_t **data, size_t *count)
145{
146 *data = NULL;
147 *count = 0;
148
149 size_t act_size = 0;
150 int rc = vol_get_ids_once(vol, method, arg1, NULL, 0, &act_size);
151 if (rc != EOK)
152 return rc;
153
154 size_t alloc_size = act_size;
155 service_id_t *ids = malloc(alloc_size);
156 if (ids == NULL)
157 return ENOMEM;
158
159 while (true) {
160 rc = vol_get_ids_once(vol, method, arg1, ids, alloc_size,
161 &act_size);
162 if (rc != EOK)
163 return rc;
164
165 if (act_size <= alloc_size)
166 break;
167
168 alloc_size = act_size;
169 ids = realloc(ids, alloc_size);
170 if (ids == NULL)
171 return ENOMEM;
172 }
173
174 *count = act_size / sizeof(service_id_t);
175 *data = ids;
176 return EOK;
177}
178
179/** Get list of partitions as array of service IDs.
180 *
181 * @param vol Volume service
182 * @param data Place to store pointer to array
183 * @param count Place to store length of array (number of entries)
184 *
185 * @return EOK on success or negative error code
186 */
187int vol_get_parts(vol_t *vol, service_id_t **data, size_t *count)
188{
189 return vol_get_ids_internal(vol, VOL_GET_PARTS, 0, data, count);
190}
191
192/** Add partition.
193 *
194 * After a partition is created (e.g. as a result of deleting a label
195 * the dummy partition is created), it can take some (unknown) time
196 * until it is discovered.
197 */
198int vol_part_add(vol_t *vol, service_id_t sid)
199{
200 async_exch_t *exch;
201 int retval;
202
203 exch = async_exchange_begin(vol->sess);
204 retval = async_req_1_0(exch, VOL_PART_ADD, sid);
205 async_exchange_end(exch);
206
207 if (retval != EOK)
208 return retval;
209
210 return EOK;
211}
212
213/** Get partition information. */
214int vol_part_info(vol_t *vol, service_id_t sid, vol_part_info_t *vinfo)
215{
216 async_exch_t *exch;
217 int retval;
218 ipc_call_t answer;
219
220 exch = async_exchange_begin(vol->sess);
221 aid_t req = async_send_1(exch, VOL_PART_INFO, sid, &answer);
222 int rc = async_data_read_start(exch, vinfo, sizeof(vol_part_info_t));
223 async_exchange_end(exch);
224
225 if (rc != EOK) {
226 async_forget(req);
227 return EIO;
228 }
229
230 async_wait_for(req, &retval);
231 if (retval != EOK)
232 return EIO;
233
234 return EOK;
235}
236
237/** Erase partition (to the extent where we will consider it not containing
238 * a file system. */
239int vol_part_empty(vol_t *vol, service_id_t sid)
240{
241 async_exch_t *exch;
242 int retval;
243
244 exch = async_exchange_begin(vol->sess);
245 retval = async_req_1_0(exch, VOL_PART_EMPTY, sid);
246 async_exchange_end(exch);
247
248 if (retval != EOK)
249 return retval;
250
251 return EOK;
252}
253
254/** Get volume label support. */
255int vol_part_get_lsupp(vol_t *vol, vol_fstype_t fstype,
256 vol_label_supp_t *vlsupp)
257{
258 async_exch_t *exch;
259 int retval;
260 ipc_call_t answer;
261
262 exch = async_exchange_begin(vol->sess);
263 aid_t req = async_send_1(exch, VOL_PART_LSUPP, fstype, &answer);
264 int rc = async_data_read_start(exch, vlsupp, sizeof(vol_label_supp_t));
265 async_exchange_end(exch);
266
267 if (rc != EOK) {
268 async_forget(req);
269 return EIO;
270 }
271
272 async_wait_for(req, &retval);
273 if (retval != EOK)
274 return EIO;
275
276 return EOK;
277}
278
279/** Create file system. */
280int vol_part_mkfs(vol_t *vol, service_id_t sid, vol_fstype_t fstype,
281 const char *label)
282{
283 async_exch_t *exch;
284 ipc_call_t answer;
285 int retval;
286
287 exch = async_exchange_begin(vol->sess);
288 aid_t req = async_send_2(exch, VOL_PART_MKFS, sid, fstype, &answer);
289 retval = async_data_write_start(exch, label, str_size(label));
290 async_exchange_end(exch);
291
292 if (retval != EOK) {
293 async_forget(req);
294 return retval;
295 }
296
297 async_wait_for(req, &retval);
298
299 if (retval != EOK)
300 return retval;
301
302 return EOK;
303}
304
305/** @}
306 */
Note: See TracBrowser for help on using the repository browser.