Rev 4555 | Rev 4584 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4555 | Rev 4566 | ||
---|---|---|---|
Line 52... | Line 52... | ||
52 | #include <vfs/canonify.h> |
52 | #include <vfs/canonify.h> |
53 | 53 | ||
54 | /* Forward declarations of static functions. */ |
54 | /* Forward declarations of static functions. */ |
55 | static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t); |
55 | static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t); |
56 | 56 | ||
57 | /** Pending mount structure. */ |
- | |
58 | typedef struct { |
- | |
59 | link_t link; |
- | |
60 | char *fs_name; /**< File system name */ |
- | |
61 | char *mp; /**< Mount point */ |
- | |
62 | char *opts; /**< Mount options. */ |
- | |
63 | ipc_callid_t callid; /**< Call ID waiting for the mount */ |
- | |
64 | ipc_callid_t rid; /**< Request ID */ |
- | |
65 | dev_handle_t dev_handle; /**< Device handle */ |
- | |
66 | } pending_req_t; |
- | |
67 | - | ||
68 | FIBRIL_CONDVAR_INITIALIZE(pending_cv); |
- | |
69 | bool pending_new_fs = false; /**< True if a new file system was mounted. */ |
- | |
70 | LIST_INITIALIZE(pending_req); |
- | |
71 | - | ||
72 | /** |
57 | /** |
73 | * This rwlock prevents the race between a triplet-to-VFS-node resolution and a |
58 | * This rwlock prevents the race between a triplet-to-VFS-node resolution and a |
74 | * concurrent VFS operation which modifies the file system namespace. |
59 | * concurrent VFS operation which modifies the file system namespace. |
75 | */ |
60 | */ |
76 | FIBRIL_RWLOCK_INITIALIZE(namespace_rwlock); |
61 | FIBRIL_RWLOCK_INITIALIZE(namespace_rwlock); |
Line 258... | Line 243... | ||
258 | 243 | ||
259 | ipc_answer_0(rid, rc); |
244 | ipc_answer_0(rid, rc); |
260 | fibril_rwlock_write_unlock(&namespace_rwlock); |
245 | fibril_rwlock_write_unlock(&namespace_rwlock); |
261 | } |
246 | } |
262 | 247 | ||
263 | /** Process pending mount requests */ |
- | |
264 | void vfs_process_pending_mount(void) |
- | |
265 | { |
- | |
266 | link_t *cur; |
- | |
267 | - | ||
268 | while (true) { |
- | |
269 | fibril_mutex_lock(&fs_head_lock); |
- | |
270 | while (!pending_new_fs) |
- | |
271 | fibril_condvar_wait(&pending_cv, &fs_head_lock); |
- | |
272 | rescan: |
- | |
273 | for (cur = pending_req.next; cur != &pending_req; |
- | |
274 | cur = cur->next) { |
- | |
275 | pending_req_t *pr = list_get_instance(cur, |
- | |
276 | pending_req_t, link); |
- | |
277 | fs_handle_t fs_handle = fs_name_to_handle(pr->fs_name, |
- | |
278 | false); |
- | |
279 | if (!fs_handle) |
- | |
280 | continue; |
- | |
281 | - | ||
282 | /* Acknowledge that we know fs_name. */ |
- | |
283 | ipc_answer_0(pr->callid, EOK); |
- | |
284 | - | ||
285 | list_remove(cur); |
- | |
286 | fibril_mutex_unlock(&fs_head_lock); |
- | |
287 | - | ||
288 | /* Do the mount */ |
- | |
289 | vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, |
- | |
290 | pr->mp, pr->opts); |
- | |
291 | - | ||
292 | free(pr->fs_name); |
- | |
293 | free(pr->mp); |
- | |
294 | free(pr->opts); |
- | |
295 | free(pr); |
- | |
296 | - | ||
297 | fibril_mutex_lock(&fs_head_lock); |
- | |
298 | goto rescan; |
- | |
299 | } |
- | |
300 | pending_new_fs = false; |
- | |
301 | fibril_mutex_unlock(&fs_head_lock); |
- | |
302 | } |
- | |
303 | } |
- | |
304 | - | ||
305 | void vfs_mount(ipc_callid_t rid, ipc_call_t *request) |
248 | void vfs_mount(ipc_callid_t rid, ipc_call_t *request) |
306 | { |
249 | { |
307 | /* |
250 | /* |
308 | * We expect the library to do the device-name to device-handle |
251 | * We expect the library to do the device-name to device-handle |
309 | * translation for us, thus the device handle will arrive as ARG1 |
252 | * translation for us, thus the device handle will arrive as ARG1 |
Line 454... | Line 397... | ||
454 | /* |
397 | /* |
455 | * Check if we know a file system with the same name as is in fs_name. |
398 | * Check if we know a file system with the same name as is in fs_name. |
456 | * This will also give us its file system handle. |
399 | * This will also give us its file system handle. |
457 | */ |
400 | */ |
458 | fibril_mutex_lock(&fs_head_lock); |
401 | fibril_mutex_lock(&fs_head_lock); |
- | 402 | fs_handle_t fs_handle; |
|
- | 403 | recheck: |
|
459 | fs_handle_t fs_handle = fs_name_to_handle(fs_name, false); |
404 | fs_handle = fs_name_to_handle(fs_name, false); |
460 | if (!fs_handle) { |
405 | if (!fs_handle) { |
461 | if (flags & IPC_FLAG_BLOCKING) { |
406 | if (flags & IPC_FLAG_BLOCKING) { |
462 | pending_req_t *pr; |
- | |
463 | - | ||
464 | /* Blocking mount, add to pending list */ |
- | |
465 | pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
- | |
466 | if (!pr) { |
- | |
467 | fibril_mutex_unlock(&fs_head_lock); |
407 | fibril_condvar_wait(&fs_head_cv, &fs_head_lock); |
468 | ipc_answer_0(callid, ENOMEM); |
- | |
469 | ipc_answer_0(rid, ENOMEM); |
- | |
470 | free(mp); |
408 | goto recheck; |
471 | free(fs_name); |
- | |
472 | free(opts); |
- | |
473 | return; |
- | |
474 | } |
- | |
475 | - | ||
476 | pr->fs_name = fs_name; |
- | |
477 | pr->mp = mp; |
- | |
478 | pr->opts = opts; |
- | |
479 | pr->callid = callid; |
- | |
480 | pr->rid = rid; |
- | |
481 | pr->dev_handle = dev_handle; |
- | |
482 | link_initialize(&pr->link); |
- | |
483 | list_append(&pr->link, &pending_req); |
- | |
484 | fibril_mutex_unlock(&fs_head_lock); |
- | |
485 | return; |
- | |
486 | } |
409 | } |
487 | 410 | ||
488 | fibril_mutex_unlock(&fs_head_lock); |
411 | fibril_mutex_unlock(&fs_head_lock); |
489 | ipc_answer_0(callid, ENOENT); |
412 | ipc_answer_0(callid, ENOENT); |
490 | ipc_answer_0(rid, ENOENT); |
413 | ipc_answer_0(rid, ENOENT); |