source: mainline/uspace/lib/c/generic/vol.c@ a8b0c5d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a8b0c5d was 7c3fb9b, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix block comment formatting (ccheck).

  • 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 */
50errno_t vol_create(vol_t **rvol)
51{
52 vol_t *vol;
53 service_id_t vol_svcid;
54 errno_t 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 an error code.
104 */
105static errno_t 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 errno_t 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 errno_t 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 an error code
142 */
143static errno_t 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 errno_t 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 an error code
186 */
187errno_t 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 */
198errno_t vol_part_add(vol_t *vol, service_id_t sid)
199{
200 async_exch_t *exch;
201 errno_t 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. */
214errno_t vol_part_info(vol_t *vol, service_id_t sid, vol_part_info_t *vinfo)
215{
216 async_exch_t *exch;
217 errno_t 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 errno_t 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.
239 */
240errno_t vol_part_empty(vol_t *vol, service_id_t sid)
241{
242 async_exch_t *exch;
243 errno_t retval;
244
245 exch = async_exchange_begin(vol->sess);
246 retval = async_req_1_0(exch, VOL_PART_EMPTY, sid);
247 async_exchange_end(exch);
248
249 if (retval != EOK)
250 return retval;
251
252 return EOK;
253}
254
255/** Get volume label support. */
256errno_t vol_part_get_lsupp(vol_t *vol, vol_fstype_t fstype,
257 vol_label_supp_t *vlsupp)
258{
259 async_exch_t *exch;
260 errno_t retval;
261 ipc_call_t answer;
262
263 exch = async_exchange_begin(vol->sess);
264 aid_t req = async_send_1(exch, VOL_PART_LSUPP, fstype, &answer);
265 errno_t rc = async_data_read_start(exch, vlsupp, sizeof(vol_label_supp_t));
266 async_exchange_end(exch);
267
268 if (rc != EOK) {
269 async_forget(req);
270 return EIO;
271 }
272
273 async_wait_for(req, &retval);
274 if (retval != EOK)
275 return EIO;
276
277 return EOK;
278}
279
280/** Create file system. */
281errno_t vol_part_mkfs(vol_t *vol, service_id_t sid, vol_fstype_t fstype,
282 const char *label)
283{
284 async_exch_t *exch;
285 ipc_call_t answer;
286 errno_t retval;
287
288 exch = async_exchange_begin(vol->sess);
289 aid_t req = async_send_2(exch, VOL_PART_MKFS, sid, fstype, &answer);
290 retval = async_data_write_start(exch, label, str_size(label));
291 async_exchange_end(exch);
292
293 if (retval != EOK) {
294 async_forget(req);
295 return retval;
296 }
297
298 async_wait_for(req, &retval);
299
300 if (retval != EOK)
301 return retval;
302
303 return EOK;
304}
305
306/** @}
307 */
Note: See TracBrowser for help on using the repository browser.