Rev 4520 | Rev 4551 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4520 | Rev 4539 | ||
---|---|---|---|
Line 64... | Line 64... | ||
64 | ipc_callid_t callid; /**< Call ID waiting for the mount */ |
64 | ipc_callid_t callid; /**< Call ID waiting for the mount */ |
65 | ipc_callid_t rid; /**< Request ID */ |
65 | ipc_callid_t rid; /**< Request ID */ |
66 | dev_handle_t dev_handle; /**< Device handle */ |
66 | dev_handle_t dev_handle; /**< Device handle */ |
67 | } pending_req_t; |
67 | } pending_req_t; |
68 | 68 | ||
69 | FIBRIL_MUTEX_INITIALIZE(pending_lock); |
69 | FIBRIL_CONDVAR_INITIALIZE(pending_cv); |
- | 70 | bool pending_new_fs = false; /**< True if a new file system was mounted. */ |
|
70 | LIST_INITIALIZE(pending_req); |
71 | LIST_INITIALIZE(pending_req); |
71 | 72 | ||
72 | /** |
73 | /** |
73 | * This rwlock prevents the race between a triplet-to-VFS-node resolution and a |
74 | * This rwlock prevents the race between a triplet-to-VFS-node resolution and a |
74 | * concurrent VFS operation which modifies the file system namespace. |
75 | * concurrent VFS operation which modifies the file system namespace. |
Line 261... | Line 262... | ||
261 | /** Process pending mount requests */ |
262 | /** Process pending mount requests */ |
262 | void vfs_process_pending_mount(void) |
263 | void vfs_process_pending_mount(void) |
263 | { |
264 | { |
264 | link_t *cur; |
265 | link_t *cur; |
265 | 266 | ||
266 | loop: |
267 | while (true) { |
267 | fibril_mutex_lock(&pending_lock); |
268 | fibril_mutex_lock(&fs_head_lock); |
- | 269 | while (!pending_new_fs) |
|
- | 270 | fibril_condvar_wait(&pending_cv, &fs_head_lock); |
|
- | 271 | rescan: |
|
268 | for (cur = pending_req.next; cur != &pending_req; cur = cur->next) { |
272 | for (cur = pending_req.next; cur != &pending_req; |
- | 273 | cur = cur->next) { |
|
269 | pending_req_t *pr = list_get_instance(cur, pending_req_t, link); |
274 | pending_req_t *pr = list_get_instance(cur, |
270 | - | ||
- | 275 | pending_req_t, link); |
|
271 | fs_handle_t fs_handle = fs_name_to_handle(pr->fs_name, true); |
276 | fs_handle_t fs_handle = fs_name_to_handle(pr->fs_name, |
- | 277 | false); |
|
272 | if (!fs_handle) |
278 | if (!fs_handle) |
273 | continue; |
279 | continue; |
274 | 280 | ||
275 | /* Acknowledge that we know fs_name. */ |
281 | /* Acknowledge that we know fs_name. */ |
276 | ipc_answer_0(pr->callid, EOK); |
282 | ipc_answer_0(pr->callid, EOK); |
277 | 283 | ||
- | 284 | list_remove(cur); |
|
- | 285 | fibril_mutex_unlock(&fs_head_lock); |
|
- | 286 | ||
278 | /* Do the mount */ |
287 | /* Do the mount */ |
279 | vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp, |
288 | vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, |
- | 289 | pr->mp, pr->opts); |
|
- | 290 | ||
- | 291 | free(pr->fs_name); |
|
- | 292 | free(pr->mp); |
|
280 | pr->opts); |
293 | free(pr->opts); |
- | 294 | free(pr); |
|
281 | 295 | ||
282 | free(pr->fs_name); |
296 | fibril_mutex_lock(&fs_head_lock); |
283 | free(pr->mp); |
297 | goto rescan; |
284 | free(pr->opts); |
298 | } |
285 | list_remove(cur); |
299 | pending_new_fs = false; |
286 | free(pr); |
- | |
287 | fibril_mutex_unlock(&pending_lock); |
300 | fibril_mutex_unlock(&fs_head_lock); |
288 | fibril_yield(); |
- | |
289 | goto loop; |
- | |
290 | } |
301 | } |
291 | fibril_mutex_unlock(&pending_lock); |
- | |
292 | } |
302 | } |
293 | 303 | ||
294 | void vfs_mount(ipc_callid_t rid, ipc_call_t *request) |
304 | void vfs_mount(ipc_callid_t rid, ipc_call_t *request) |
295 | { |
305 | { |
296 | /* |
306 | /* |
Line 442... | Line 452... | ||
442 | 452 | ||
443 | /* |
453 | /* |
444 | * Check if we know a file system with the same name as is in fs_name. |
454 | * Check if we know a file system with the same name as is in fs_name. |
445 | * This will also give us its file system handle. |
455 | * This will also give us its file system handle. |
446 | */ |
456 | */ |
- | 457 | fibril_mutex_lock(&fs_head_lock); |
|
447 | fs_handle_t fs_handle = fs_name_to_handle(fs_name, true); |
458 | fs_handle_t fs_handle = fs_name_to_handle(fs_name, false); |
448 | if (!fs_handle) { |
459 | if (!fs_handle) { |
449 | if (flags & IPC_FLAG_BLOCKING) { |
460 | if (flags & IPC_FLAG_BLOCKING) { |
450 | pending_req_t *pr; |
461 | pending_req_t *pr; |
451 | 462 | ||
452 | /* Blocking mount, add to pending list */ |
463 | /* Blocking mount, add to pending list */ |
453 | pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
464 | pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
454 | if (!pr) { |
465 | if (!pr) { |
- | 466 | fibril_mutex_unlock(&fs_head_lock); |
|
455 | ipc_answer_0(callid, ENOMEM); |
467 | ipc_answer_0(callid, ENOMEM); |
456 | ipc_answer_0(rid, ENOMEM); |
468 | ipc_answer_0(rid, ENOMEM); |
457 | free(mp); |
469 | free(mp); |
458 | free(fs_name); |
470 | free(fs_name); |
459 | free(opts); |
471 | free(opts); |
Line 465... | Line 477... | ||
465 | pr->opts = opts; |
477 | pr->opts = opts; |
466 | pr->callid = callid; |
478 | pr->callid = callid; |
467 | pr->rid = rid; |
479 | pr->rid = rid; |
468 | pr->dev_handle = dev_handle; |
480 | pr->dev_handle = dev_handle; |
469 | link_initialize(&pr->link); |
481 | link_initialize(&pr->link); |
470 | fibril_mutex_lock(&pending_lock); |
- | |
471 | list_append(&pr->link, &pending_req); |
482 | list_append(&pr->link, &pending_req); |
472 | fibril_mutex_unlock(&pending_lock); |
483 | fibril_mutex_unlock(&fs_head_lock); |
473 | return; |
484 | return; |
474 | } |
485 | } |
475 | 486 | ||
- | 487 | fibril_mutex_unlock(&fs_head_lock); |
|
476 | ipc_answer_0(callid, ENOENT); |
488 | ipc_answer_0(callid, ENOENT); |
477 | ipc_answer_0(rid, ENOENT); |
489 | ipc_answer_0(rid, ENOENT); |
478 | free(mp); |
490 | free(mp); |
479 | free(fs_name); |
491 | free(fs_name); |
480 | free(opts); |
492 | free(opts); |
481 | return; |
493 | return; |
482 | } |
494 | } |
- | 495 | fibril_mutex_unlock(&fs_head_lock); |
|
483 | 496 | ||
484 | /* Acknowledge that we know fs_name. */ |
497 | /* Acknowledge that we know fs_name. */ |
485 | ipc_answer_0(callid, EOK); |
498 | ipc_answer_0(callid, EOK); |
486 | 499 | ||
487 | /* Do the mount */ |
500 | /* Do the mount */ |