source: mainline/uspace/srv/vfs/vfs_ipc.c@ 582a0b8

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

Mount should be able to print the list of available file system types.

  • Property mode set to 100644
File size: 8.5 KB
Line 
1/*
2 * Copyright (c) 2008 Jakub Jermar
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#include <vfs/vfs.h>
30#include "vfs.h"
31
32#include <errno.h>
33#include <stdlib.h>
34#include <str.h>
35#include <vfs/canonify.h>
36
37static void vfs_in_clone(ipc_callid_t rid, ipc_call_t *request)
38{
39 int oldfd = IPC_GET_ARG1(*request);
40 int newfd = IPC_GET_ARG2(*request);
41 bool desc = IPC_GET_ARG3(*request);
42
43 int ret = vfs_op_clone(oldfd, newfd, desc);
44 async_answer_0(rid, ret);
45}
46
47static void vfs_in_fstypes(ipc_callid_t rid, ipc_call_t *request)
48{
49 ipc_callid_t callid;
50 size_t len;
51 vfs_fstypes_t fstypes;
52 int rc;
53
54 rc = vfs_get_fstypes(&fstypes);
55 if (rc != EOK) {
56 async_answer_0(rid, ENOMEM);
57 return;
58 }
59
60 /* Send size of the data */
61 async_answer_1(rid, EOK, fstypes.size);
62
63 /* Now we should get a read request */
64 if (!async_data_read_receive(&callid, &len))
65 goto out;
66
67 if (len > fstypes.size)
68 len = fstypes.size;
69 (void) async_data_read_finalize(callid, fstypes.buf, len);
70
71out:
72 vfs_fstypes_free(&fstypes);
73}
74
75static void vfs_in_mount(ipc_callid_t rid, ipc_call_t *request)
76{
77 int mpfd = IPC_GET_ARG1(*request);
78
79 /*
80 * We expect the library to do the device-name to device-handle
81 * translation for us, thus the device handle will arrive as ARG1
82 * in the request.
83 */
84 service_id_t service_id = (service_id_t) IPC_GET_ARG2(*request);
85
86 unsigned int flags = (unsigned int) IPC_GET_ARG3(*request);
87 unsigned int instance = IPC_GET_ARG4(*request);
88
89 char *opts = NULL;
90 char *fs_name = NULL;
91
92 /* Now we expect to receive the mount options. */
93 int rc = async_data_write_accept((void **) &opts, true, 0,
94 MAX_MNTOPTS_LEN, 0, NULL);
95 if (rc != EOK) {
96 async_answer_0(rid, rc);
97 return;
98 }
99
100 /* Now, we expect the client to send us data with the name of the file
101 * system.
102 */
103 rc = async_data_write_accept((void **) &fs_name, true, 0,
104 FS_NAME_MAXLEN, 0, NULL);
105 if (rc != EOK) {
106 free(opts);
107 async_answer_0(rid, rc);
108 return;
109 }
110
111 int outfd = 0;
112 rc = vfs_op_mount(mpfd, service_id, flags, instance, opts, fs_name,
113 &outfd);
114 async_answer_1(rid, rc, outfd);
115
116 free(opts);
117 free(fs_name);
118}
119
120static void vfs_in_open(ipc_callid_t rid, ipc_call_t *request)
121{
122 int fd = IPC_GET_ARG1(*request);
123 int mode = IPC_GET_ARG2(*request);
124
125 int rc = vfs_op_open(fd, mode);
126 async_answer_0(rid, rc);
127}
128
129static void vfs_in_put(ipc_callid_t rid, ipc_call_t *request)
130{
131 int fd = IPC_GET_ARG1(*request);
132 int rc = vfs_op_put(fd);
133 async_answer_0(rid, rc);
134}
135
136static void vfs_in_read(ipc_callid_t rid, ipc_call_t *request)
137{
138 int fd = IPC_GET_ARG1(*request);
139 aoff64_t pos = MERGE_LOUP32(IPC_GET_ARG2(*request),
140 IPC_GET_ARG3(*request));
141
142 size_t bytes = 0;
143 int rc = vfs_op_read(fd, pos, &bytes);
144 async_answer_1(rid, rc, bytes);
145}
146
147static void vfs_in_rename(ipc_callid_t rid, ipc_call_t *request)
148{
149 /* The common base directory. */
150 int basefd;
151 char *old = NULL;
152 char *new = NULL;
153 int rc;
154
155 basefd = IPC_GET_ARG1(*request);
156
157 /* Retrieve the old path. */
158 rc = async_data_write_accept((void **) &old, true, 0, 0, 0, NULL);
159 if (rc != EOK)
160 goto out;
161
162 /* Retrieve the new path. */
163 rc = async_data_write_accept((void **) &new, true, 0, 0, 0, NULL);
164 if (rc != EOK)
165 goto out;
166
167 size_t olen;
168 size_t nlen;
169 char *oldc = canonify(old, &olen);
170 char *newc = canonify(new, &nlen);
171
172 if ((!oldc) || (!newc)) {
173 rc = EINVAL;
174 goto out;
175 }
176
177 assert(oldc[olen] == '\0');
178 assert(newc[nlen] == '\0');
179
180 rc = vfs_op_rename(basefd, oldc, newc);
181
182out:
183 async_answer_0(rid, rc);
184
185 if (old)
186 free(old);
187 if (new)
188 free(new);
189}
190
191static void vfs_in_resize(ipc_callid_t rid, ipc_call_t *request)
192{
193 int fd = IPC_GET_ARG1(*request);
194 int64_t size = MERGE_LOUP32(IPC_GET_ARG2(*request), IPC_GET_ARG3(*request));
195 int rc = vfs_op_resize(fd, size);
196 async_answer_0(rid, rc);
197}
198
199static void vfs_in_stat(ipc_callid_t rid, ipc_call_t *request)
200{
201 int fd = IPC_GET_ARG1(*request);
202 int rc = vfs_op_stat(fd);
203 async_answer_0(rid, rc);
204}
205
206static void vfs_in_statfs(ipc_callid_t rid, ipc_call_t *request)
207{
208 int fd = (int) IPC_GET_ARG1(*request);
209
210 int rc = vfs_op_statfs(fd);
211 async_answer_0(rid, rc);
212}
213
214static void vfs_in_sync(ipc_callid_t rid, ipc_call_t *request)
215{
216 int fd = IPC_GET_ARG1(*request);
217 int rc = vfs_op_sync(fd);
218 async_answer_0(rid, rc);
219}
220
221static void vfs_in_unlink(ipc_callid_t rid, ipc_call_t *request)
222{
223 int parentfd = IPC_GET_ARG1(*request);
224 int expectfd = IPC_GET_ARG2(*request);
225
226 char *path;
227 int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
228 if (rc == EOK)
229 rc = vfs_op_unlink(parentfd, expectfd, path);
230
231 async_answer_0(rid, rc);
232}
233
234static void vfs_in_unmount(ipc_callid_t rid, ipc_call_t *request)
235{
236 int mpfd = IPC_GET_ARG1(*request);
237 int rc = vfs_op_unmount(mpfd);
238 async_answer_0(rid, rc);
239}
240
241static void vfs_in_wait_handle(ipc_callid_t rid, ipc_call_t *request)
242{
243 bool high_fd = IPC_GET_ARG1(*request);
244 int fd = vfs_op_wait_handle(high_fd);
245 async_answer_1(rid, EOK, fd);
246}
247
248static void vfs_in_walk(ipc_callid_t rid, ipc_call_t *request)
249{
250 /*
251 * Parent is our relative root for file lookup.
252 * For defined flags, see <ipc/vfs.h>.
253 */
254 int parentfd = IPC_GET_ARG1(*request);
255 int flags = IPC_GET_ARG2(*request);
256
257 int fd = 0;
258 char *path;
259 int rc = async_data_write_accept((void **)&path, true, 0, 0, 0, NULL);
260 if (rc == EOK) {
261 rc = vfs_op_walk(parentfd, flags, path, &fd);
262 free(path);
263 }
264 async_answer_1(rid, rc, fd);
265}
266
267static void vfs_in_write(ipc_callid_t rid, ipc_call_t *request)
268{
269 int fd = IPC_GET_ARG1(*request);
270 aoff64_t pos = MERGE_LOUP32(IPC_GET_ARG2(*request),
271 IPC_GET_ARG3(*request));
272
273 size_t bytes = 0;
274 int rc = vfs_op_write(fd, pos, &bytes);
275 async_answer_1(rid, rc, bytes);
276}
277
278void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
279{
280 bool cont = true;
281
282 /*
283 * The connection was opened via the IPC_CONNECT_ME_TO call.
284 * This call needs to be answered.
285 */
286 async_answer_0(iid, EOK);
287
288 while (cont) {
289 ipc_call_t call;
290 ipc_callid_t callid = async_get_call(&call);
291
292 if (!IPC_GET_IMETHOD(call))
293 break;
294
295 switch (IPC_GET_IMETHOD(call)) {
296 case VFS_IN_CLONE:
297 vfs_in_clone(callid, &call);
298 break;
299 case VFS_IN_FSTYPES:
300 vfs_in_fstypes(callid, &call);
301 break;
302 case VFS_IN_MOUNT:
303 vfs_in_mount(callid, &call);
304 break;
305 case VFS_IN_OPEN:
306 vfs_in_open(callid, &call);
307 break;
308 case VFS_IN_PUT:
309 vfs_in_put(callid, &call);
310 break;
311 case VFS_IN_READ:
312 vfs_in_read(callid, &call);
313 break;
314 case VFS_IN_REGISTER:
315 vfs_register(callid, &call);
316 cont = false;
317 break;
318 case VFS_IN_RENAME:
319 vfs_in_rename(callid, &call);
320 break;
321 case VFS_IN_RESIZE:
322 vfs_in_resize(callid, &call);
323 break;
324 case VFS_IN_STAT:
325 vfs_in_stat(callid, &call);
326 break;
327 case VFS_IN_STATFS:
328 vfs_in_statfs(callid, &call);
329 break;
330 case VFS_IN_SYNC:
331 vfs_in_sync(callid, &call);
332 break;
333 case VFS_IN_UNLINK:
334 vfs_in_unlink(callid, &call);
335 break;
336 case VFS_IN_UNMOUNT:
337 vfs_in_unmount(callid, &call);
338 break;
339 case VFS_IN_WAIT_HANDLE:
340 vfs_in_wait_handle(callid, &call);
341 break;
342 case VFS_IN_WALK:
343 vfs_in_walk(callid, &call);
344 break;
345 case VFS_IN_WRITE:
346 vfs_in_write(callid, &call);
347 break;
348 default:
349 async_answer_0(callid, ENOTSUP);
350 break;
351 }
352 }
353
354 /*
355 * Open files for this client will be cleaned up when its last
356 * connection fibril terminates.
357 */
358}
Note: See TracBrowser for help on using the repository browser.