source: mainline/uspace/lib/c/generic/vol.c@ 58898d1d

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

Merge mainline changes.

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