Rev 4302 | Rev 4366 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4302 | Rev 4305 | ||
|---|---|---|---|
| Line 58... | Line 58... | ||
| 58 | /** Pending mount structure. */ |
58 | /** Pending mount structure. */ |
| 59 | typedef struct { |
59 | typedef struct { |
| 60 | link_t link; |
60 | link_t link; |
| 61 | char *fs_name; /**< File system name */ |
61 | char *fs_name; /**< File system name */ |
| 62 | char *mp; /**< Mount point */ |
62 | char *mp; /**< Mount point */ |
| - | 63 | char *opts; /**< Mount options. */ |
|
| 63 | ipc_callid_t callid; /**< Call ID waiting for the mount */ |
64 | ipc_callid_t callid; /**< Call ID waiting for the mount */ |
| 64 | ipc_callid_t rid; /**< Request ID */ |
65 | ipc_callid_t rid; /**< Request ID */ |
| 65 | dev_handle_t dev_handle; /**< Device handle */ |
66 | dev_handle_t dev_handle; /**< Device handle */ |
| 66 | } pending_req_t; |
67 | } pending_req_t; |
| 67 | 68 | ||
| Line 78... | Line 79... | ||
| 78 | .fs_handle = 0, |
79 | .fs_handle = 0, |
| 79 | .dev_handle = 0 |
80 | .dev_handle = 0 |
| 80 | }; |
81 | }; |
| 81 | 82 | ||
| 82 | static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle, |
83 | static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle, |
| 83 | fs_handle_t fs_handle, char *mp) |
84 | fs_handle_t fs_handle, char *mp, char *opts) |
| 84 | { |
85 | { |
| 85 | /* Resolve the path to the mountpoint. */ |
- | |
| 86 | vfs_lookup_res_t mp_res; |
86 | vfs_lookup_res_t mp_res; |
| 87 | vfs_node_t *mp_node = NULL; |
87 | vfs_node_t *mp_node = NULL; |
| 88 | int rc; |
88 | ipcarg_t rc; |
| 89 | int phone; |
89 | int phone; |
| - | 90 | aid_t msg; |
|
| - | 91 | ipc_call_t answer; |
|
| - | 92 | ||
| - | 93 | /* Resolve the path to the mountpoint. */ |
|
| 90 | futex_down(&rootfs_futex); |
94 | futex_down(&rootfs_futex); |
| 91 | if (rootfs.fs_handle) { |
95 | if (rootfs.fs_handle) { |
| 92 | /* We already have the root FS. */ |
96 | /* We already have the root FS. */ |
| 93 | rwlock_write_lock(&namespace_rwlock); |
97 | rwlock_write_lock(&namespace_rwlock); |
| 94 | if (str_cmp(mp, "/") == 0) { |
98 | if (str_cmp(mp, "/") == 0) { |
| Line 125... | Line 129... | ||
| 125 | } else { |
129 | } else { |
| 126 | /* We still don't have the root file system mounted. */ |
130 | /* We still don't have the root file system mounted. */ |
| 127 | if (str_cmp(mp, "/") == 0) { |
131 | if (str_cmp(mp, "/") == 0) { |
| 128 | vfs_lookup_res_t mr_res; |
132 | vfs_lookup_res_t mr_res; |
| 129 | vfs_node_t *mr_node; |
133 | vfs_node_t *mr_node; |
| 130 | ipcarg_t rindex; |
134 | fs_index_t rindex; |
| 131 | ipcarg_t rsize; |
135 | size_t rsize; |
| 132 | ipcarg_t rlnkcnt; |
136 | unsigned rlnkcnt; |
| 133 | 137 | ||
| 134 | /* |
138 | /* |
| 135 | * For this simple, but important case, |
139 | * For this simple, but important case, |
| 136 | * we are almost done. |
140 | * we are almost done. |
| 137 | */ |
141 | */ |
| 138 | 142 | ||
| 139 | /* Tell the mountee that it is being mounted. */ |
143 | /* Tell the mountee that it is being mounted. */ |
| 140 | phone = vfs_grab_phone(fs_handle); |
144 | phone = vfs_grab_phone(fs_handle); |
| 141 | rc = async_req_1_3(phone, VFS_MOUNTED, |
145 | msg = async_send_1(phone, VFS_MOUNTED, |
| 142 | (ipcarg_t) dev_handle, &rindex, &rsize, &rlnkcnt); |
146 | (ipcarg_t) dev_handle, &answer); |
| - | 147 | /* send the mount options */ |
|
| - | 148 | rc = ipc_data_write_start(phone, (void *)opts, |
|
| - | 149 | str_size(opts)); |
|
| - | 150 | if (rc != EOK) { |
|
| - | 151 | async_wait_for(msg, NULL); |
|
| - | 152 | vfs_release_phone(phone); |
|
| - | 153 | futex_up(&rootfs_futex); |
|
| - | 154 | ipc_answer_0(rid, rc); |
|
| - | 155 | return; |
|
| - | 156 | } |
|
| - | 157 | async_wait_for(msg, &rc); |
|
| 143 | vfs_release_phone(phone); |
158 | vfs_release_phone(phone); |
| 144 | 159 | ||
| 145 | if (rc != EOK) { |
160 | if (rc != EOK) { |
| 146 | futex_up(&rootfs_futex); |
161 | futex_up(&rootfs_futex); |
| 147 | ipc_answer_0(rid, rc); |
162 | ipc_answer_0(rid, rc); |
| 148 | return; |
163 | return; |
| 149 | } |
164 | } |
| - | 165 | ||
| - | 166 | rindex = (fs_index_t) IPC_GET_ARG1(answer); |
|
| - | 167 | rsize = (size_t) IPC_GET_ARG2(answer); |
|
| - | 168 | rlnkcnt = (unsigned) IPC_GET_ARG3(answer); |
|
| 150 | 169 | ||
| 151 | mr_res.triplet.fs_handle = fs_handle; |
170 | mr_res.triplet.fs_handle = fs_handle; |
| 152 | mr_res.triplet.dev_handle = dev_handle; |
171 | mr_res.triplet.dev_handle = dev_handle; |
| 153 | mr_res.triplet.index = (fs_index_t) rindex; |
172 | mr_res.triplet.index = rindex; |
| 154 | mr_res.size = (size_t) rsize; |
173 | mr_res.size = rsize; |
| 155 | mr_res.lnkcnt = (unsigned) rlnkcnt; |
174 | mr_res.lnkcnt = rlnkcnt; |
| 156 | mr_res.type = VFS_NODE_DIRECTORY; |
175 | mr_res.type = VFS_NODE_DIRECTORY; |
| 157 | 176 | ||
| 158 | rootfs.fs_handle = fs_handle; |
177 | rootfs.fs_handle = fs_handle; |
| 159 | rootfs.dev_handle = dev_handle; |
178 | rootfs.dev_handle = dev_handle; |
| 160 | futex_up(&rootfs_futex); |
179 | futex_up(&rootfs_futex); |
| Line 181... | Line 200... | ||
| 181 | * At this point, we have all necessary pieces: file system and device |
200 | * At this point, we have all necessary pieces: file system and device |
| 182 | * handles, and we know the mount point VFS node. |
201 | * handles, and we know the mount point VFS node. |
| 183 | */ |
202 | */ |
| 184 | 203 | ||
| 185 | phone = vfs_grab_phone(mp_res.triplet.fs_handle); |
204 | phone = vfs_grab_phone(mp_res.triplet.fs_handle); |
| 186 | rc = async_req_4_0(phone, VFS_MOUNT, |
205 | msg = async_send_4(phone, VFS_MOUNT, |
| 187 | (ipcarg_t) mp_res.triplet.dev_handle, |
206 | (ipcarg_t) mp_res.triplet.dev_handle, |
| 188 | (ipcarg_t) mp_res.triplet.index, |
207 | (ipcarg_t) mp_res.triplet.index, |
| 189 | (ipcarg_t) fs_handle, |
208 | (ipcarg_t) fs_handle, |
| 190 | (ipcarg_t) dev_handle); |
209 | (ipcarg_t) dev_handle, &answer); |
| - | 210 | /* send the mount options */ |
|
| - | 211 | rc = ipc_data_write_start(phone, (void *)opts, str_size(opts)); |
|
| - | 212 | if (rc != EOK) { |
|
| - | 213 | async_wait_for(msg, NULL); |
|
| - | 214 | vfs_release_phone(phone); |
|
| - | 215 | /* Mount failed, drop reference to mp_node. */ |
|
| - | 216 | if (mp_node) |
|
| - | 217 | vfs_node_put(mp_node); |
|
| - | 218 | ipc_answer_0(rid, rc); |
|
| - | 219 | return; |
|
| - | 220 | } |
|
| - | 221 | async_wait_for(msg, &rc); |
|
| 191 | vfs_release_phone(phone); |
222 | vfs_release_phone(phone); |
| 192 | 223 | ||
| 193 | if (rc != EOK) { |
224 | if (rc != EOK) { |
| 194 | /* Mount failed, drop reference to mp_node. */ |
225 | /* Mount failed, drop reference to mp_node. */ |
| 195 | if (mp_node) |
226 | if (mp_node) |
| Line 214... | Line 245... | ||
| 214 | 245 | ||
| 215 | /* Acknowledge that we know fs_name. */ |
246 | /* Acknowledge that we know fs_name. */ |
| 216 | ipc_answer_0(pr->callid, EOK); |
247 | ipc_answer_0(pr->callid, EOK); |
| 217 | 248 | ||
| 218 | /* Do the mount */ |
249 | /* Do the mount */ |
| 219 | vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp); |
250 | vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp, |
| - | 251 | pr->opts); |
|
| 220 | 252 | ||
| 221 | free(pr->fs_name); |
253 | free(pr->fs_name); |
| 222 | free(pr->mp); |
254 | free(pr->mp); |
| - | 255 | free(pr->opts); |
|
| 223 | list_remove(cur); |
256 | list_remove(cur); |
| 224 | free(pr); |
257 | free(pr); |
| 225 | goto loop; |
258 | goto loop; |
| 226 | } |
259 | } |
| 227 | } |
260 | } |
| Line 276... | Line 309... | ||
| 276 | free(mp); |
309 | free(mp); |
| 277 | return; |
310 | return; |
| 278 | } |
311 | } |
| 279 | mp[size] = '\0'; |
312 | mp[size] = '\0'; |
| 280 | 313 | ||
| - | 314 | /* Now we expect to receive the mount options. */ |
|
| - | 315 | if (!ipc_data_write_receive(&callid, &size)) { |
|
| - | 316 | ipc_answer_0(callid, EINVAL); |
|
| - | 317 | ipc_answer_0(rid, EINVAL); |
|
| - | 318 | free(mp); |
|
| - | 319 | return; |
|
| - | 320 | } |
|
| - | 321 | ||
| - | 322 | /* Check the offered options size. */ |
|
| - | 323 | if (size < 0 || size > MAX_MNTOPTS_LEN) { |
|
| - | 324 | ipc_answer_0(callid, EINVAL); |
|
| - | 325 | ipc_answer_0(rid, EINVAL); |
|
| - | 326 | free(mp); |
|
| - | 327 | return; |
|
| - | 328 | } |
|
| - | 329 | ||
| - | 330 | /* Allocate buffer for the mount options. */ |
|
| - | 331 | char *opts = (char *) malloc(size + 1); |
|
| - | 332 | if (!opts) { |
|
| - | 333 | ipc_answer_0(callid, ENOMEM); |
|
| - | 334 | ipc_answer_0(rid, ENOMEM); |
|
| - | 335 | free(mp); |
|
| - | 336 | return; |
|
| - | 337 | } |
|
| - | 338 | ||
| - | 339 | /* Deliver the mount options. */ |
|
| - | 340 | retval = ipc_data_write_finalize(callid, opts, size); |
|
| - | 341 | if (retval != EOK) { |
|
| - | 342 | ipc_answer_0(rid, retval); |
|
| - | 343 | free(mp); |
|
| - | 344 | free(opts); |
|
| - | 345 | return; |
|
| - | 346 | } |
|
| - | 347 | opts[size] = '\0'; |
|
| - | 348 | ||
| 281 | /* |
349 | /* |
| 282 | * Now, we expect the client to send us data with the name of the file |
350 | * Now, we expect the client to send us data with the name of the file |
| 283 | * system. |
351 | * system. |
| 284 | */ |
352 | */ |
| 285 | if (!ipc_data_write_receive(&callid, &size)) { |
353 | if (!ipc_data_write_receive(&callid, &size)) { |
| 286 | ipc_answer_0(callid, EINVAL); |
354 | ipc_answer_0(callid, EINVAL); |
| 287 | ipc_answer_0(rid, EINVAL); |
355 | ipc_answer_0(rid, EINVAL); |
| 288 | free(mp); |
356 | free(mp); |
| - | 357 | free(opts); |
|
| 289 | return; |
358 | return; |
| 290 | } |
359 | } |
| 291 | 360 | ||
| 292 | /* |
361 | /* |
| 293 | * Don't receive more than is necessary for storing a full file system |
362 | * Don't receive more than is necessary for storing a full file system |
| Line 295... | Line 364... | ||
| 295 | */ |
364 | */ |
| 296 | if ((size < 1) || (size > FS_NAME_MAXLEN)) { |
365 | if ((size < 1) || (size > FS_NAME_MAXLEN)) { |
| 297 | ipc_answer_0(callid, EINVAL); |
366 | ipc_answer_0(callid, EINVAL); |
| 298 | ipc_answer_0(rid, EINVAL); |
367 | ipc_answer_0(rid, EINVAL); |
| 299 | free(mp); |
368 | free(mp); |
| - | 369 | free(opts); |
|
| 300 | return; |
370 | return; |
| 301 | } |
371 | } |
| 302 | 372 | ||
| 303 | /* |
373 | /* |
| 304 | * Allocate buffer for file system name. |
374 | * Allocate buffer for file system name. |
| Line 306... | Line 376... | ||
| 306 | char *fs_name = (char *) malloc(size + 1); |
376 | char *fs_name = (char *) malloc(size + 1); |
| 307 | if (fs_name == NULL) { |
377 | if (fs_name == NULL) { |
| 308 | ipc_answer_0(callid, ENOMEM); |
378 | ipc_answer_0(callid, ENOMEM); |
| 309 | ipc_answer_0(rid, ENOMEM); |
379 | ipc_answer_0(rid, ENOMEM); |
| 310 | free(mp); |
380 | free(mp); |
| - | 381 | free(opts); |
|
| 311 | return; |
382 | return; |
| 312 | } |
383 | } |
| 313 | 384 | ||
| 314 | /* Deliver the file system name. */ |
385 | /* Deliver the file system name. */ |
| 315 | retval = ipc_data_write_finalize(callid, fs_name, size); |
386 | retval = ipc_data_write_finalize(callid, fs_name, size); |
| 316 | if (retval != EOK) { |
387 | if (retval != EOK) { |
| 317 | ipc_answer_0(rid, retval); |
388 | ipc_answer_0(rid, retval); |
| 318 | free(mp); |
389 | free(mp); |
| - | 390 | free(opts); |
|
| 319 | free(fs_name); |
391 | free(fs_name); |
| 320 | return; |
392 | return; |
| 321 | } |
393 | } |
| 322 | fs_name[size] = '\0'; |
394 | fs_name[size] = '\0'; |
| 323 | 395 | ||
| Line 329... | Line 401... | ||
| 329 | callid = async_get_call(&data); |
401 | callid = async_get_call(&data); |
| 330 | if (IPC_GET_METHOD(data) != IPC_M_PING) { |
402 | if (IPC_GET_METHOD(data) != IPC_M_PING) { |
| 331 | ipc_answer_0(callid, ENOTSUP); |
403 | ipc_answer_0(callid, ENOTSUP); |
| 332 | ipc_answer_0(rid, ENOTSUP); |
404 | ipc_answer_0(rid, ENOTSUP); |
| 333 | free(mp); |
405 | free(mp); |
| - | 406 | free(opts); |
|
| 334 | free(fs_name); |
407 | free(fs_name); |
| 335 | return; |
408 | return; |
| 336 | } |
409 | } |
| 337 | 410 | ||
| 338 | /* |
411 | /* |
| Line 349... | Line 422... | ||
| 349 | if (!pr) { |
422 | if (!pr) { |
| 350 | ipc_answer_0(callid, ENOMEM); |
423 | ipc_answer_0(callid, ENOMEM); |
| 351 | ipc_answer_0(rid, ENOMEM); |
424 | ipc_answer_0(rid, ENOMEM); |
| 352 | free(mp); |
425 | free(mp); |
| 353 | free(fs_name); |
426 | free(fs_name); |
| - | 427 | free(opts); |
|
| 354 | return; |
428 | return; |
| 355 | } |
429 | } |
| 356 | 430 | ||
| 357 | pr->fs_name = fs_name; |
431 | pr->fs_name = fs_name; |
| 358 | pr->mp = mp; |
432 | pr->mp = mp; |
| - | 433 | pr->opts = opts; |
|
| 359 | pr->callid = callid; |
434 | pr->callid = callid; |
| 360 | pr->rid = rid; |
435 | pr->rid = rid; |
| 361 | pr->dev_handle = dev_handle; |
436 | pr->dev_handle = dev_handle; |
| 362 | link_initialize(&pr->link); |
437 | link_initialize(&pr->link); |
| 363 | list_append(&pr->link, &pending_req); |
438 | list_append(&pr->link, &pending_req); |
| Line 366... | Line 441... | ||
| 366 | 441 | ||
| 367 | ipc_answer_0(callid, ENOENT); |
442 | ipc_answer_0(callid, ENOENT); |
| 368 | ipc_answer_0(rid, ENOENT); |
443 | ipc_answer_0(rid, ENOENT); |
| 369 | free(mp); |
444 | free(mp); |
| 370 | free(fs_name); |
445 | free(fs_name); |
| - | 446 | free(opts); |
|
| 371 | return; |
447 | return; |
| 372 | } |
448 | } |
| 373 | 449 | ||
| 374 | /* Acknowledge that we know fs_name. */ |
450 | /* Acknowledge that we know fs_name. */ |
| 375 | ipc_answer_0(callid, EOK); |
451 | ipc_answer_0(callid, EOK); |
| 376 | 452 | ||
| 377 | /* Do the mount */ |
453 | /* Do the mount */ |
| 378 | vfs_mount_internal(rid, dev_handle, fs_handle, mp); |
454 | vfs_mount_internal(rid, dev_handle, fs_handle, mp, opts); |
| 379 | free(mp); |
455 | free(mp); |
| 380 | free(fs_name); |
456 | free(fs_name); |
| - | 457 | free(opts); |
|
| 381 | } |
458 | } |
| 382 | 459 | ||
| 383 | void vfs_open(ipc_callid_t rid, ipc_call_t *request) |
460 | void vfs_open(ipc_callid_t rid, ipc_call_t *request) |
| 384 | { |
461 | { |
| 385 | if (!vfs_files_init()) { |
462 | if (!vfs_files_init()) { |