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); |