Rev 3009 | Rev 3153 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3009 | Rev 3150 | ||
---|---|---|---|
Line 442... | Line 442... | ||
442 | * Additional synchronization needs to be added once the table of |
442 | * Additional synchronization needs to be added once the table of |
443 | * open files supports parallel access! |
443 | * open files supports parallel access! |
444 | */ |
444 | */ |
445 | 445 | ||
446 | int fd = IPC_GET_ARG1(*request); |
446 | int fd = IPC_GET_ARG1(*request); |
447 | 447 | ||
448 | /* Lookup the file structure corresponding to the file descriptor. */ |
448 | /* Lookup the file structure corresponding to the file descriptor. */ |
449 | vfs_file_t *file = vfs_file_get(fd); |
449 | vfs_file_t *file = vfs_file_get(fd); |
450 | if (!file) { |
450 | if (!file) { |
451 | ipc_answer_0(rid, ENOENT); |
451 | ipc_answer_0(rid, ENOENT); |
452 | return; |
452 | return; |
453 | } |
453 | } |
454 | 454 | ||
455 | /* |
455 | /* |
456 | * Now we need to receive a call with client's |
456 | * Now we need to receive a call with client's |
457 | * IPC_M_DATA_READ/IPC_M_DATA_WRITE request. |
457 | * IPC_M_DATA_READ/IPC_M_DATA_WRITE request. |
458 | */ |
458 | */ |
459 | ipc_callid_t callid; |
459 | ipc_callid_t callid; |
Line 465... | Line 465... | ||
465 | if (!res) { |
465 | if (!res) { |
466 | ipc_answer_0(callid, EINVAL); |
466 | ipc_answer_0(callid, EINVAL); |
467 | ipc_answer_0(rid, EINVAL); |
467 | ipc_answer_0(rid, EINVAL); |
468 | return; |
468 | return; |
469 | } |
469 | } |
470 | 470 | ||
471 | /* |
471 | /* |
472 | * Lock the open file structure so that no other thread can manipulate |
472 | * Lock the open file structure so that no other thread can manipulate |
473 | * the same open file at a time. |
473 | * the same open file at a time. |
474 | */ |
474 | */ |
475 | futex_down(&file->lock); |
475 | futex_down(&file->lock); |
476 | 476 | ||
477 | /* |
477 | /* |
478 | * Lock the file's node so that no other client can read/write to it at |
478 | * Lock the file's node so that no other client can read/write to it at |
479 | * the same time. |
479 | * the same time. |
480 | */ |
480 | */ |
481 | if (read) |
481 | if (read) |
482 | rwlock_read_lock(&file->node->contents_rwlock); |
482 | rwlock_read_lock(&file->node->contents_rwlock); |
483 | else |
483 | else |
484 | rwlock_write_lock(&file->node->contents_rwlock); |
484 | rwlock_write_lock(&file->node->contents_rwlock); |
485 | 485 | ||
486 | int fs_phone = vfs_grab_phone(file->node->fs_handle); |
486 | int fs_phone = vfs_grab_phone(file->node->fs_handle); |
487 | 487 | ||
488 | /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */ |
488 | /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */ |
489 | aid_t msg; |
489 | aid_t msg; |
490 | ipc_call_t answer; |
490 | ipc_call_t answer; |
Line 498... | Line 498... | ||
498 | * destination FS server. The call will be routed as if sent by |
498 | * destination FS server. The call will be routed as if sent by |
499 | * ourselves. Note that call arguments are immutable in this case so we |
499 | * ourselves. Note that call arguments are immutable in this case so we |
500 | * don't have to bother. |
500 | * don't have to bother. |
501 | */ |
501 | */ |
502 | ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); |
502 | ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); |
503 | 503 | ||
504 | vfs_release_phone(fs_phone); |
504 | vfs_release_phone(fs_phone); |
505 | 505 | ||
506 | /* Wait for reply from the FS server. */ |
506 | /* Wait for reply from the FS server. */ |
507 | ipcarg_t rc; |
507 | ipcarg_t rc; |
508 | async_wait_for(msg, &rc); |
508 | async_wait_for(msg, &rc); |
509 | size_t bytes = IPC_GET_ARG1(answer); |
509 | size_t bytes = IPC_GET_ARG1(answer); |
510 | 510 | ||
511 | /* Unlock the VFS node. */ |
511 | /* Unlock the VFS node. */ |
512 | if (read) |
512 | if (read) |
513 | rwlock_read_unlock(&file->node->contents_rwlock); |
513 | rwlock_read_unlock(&file->node->contents_rwlock); |
514 | else { |
514 | else { |
515 | /* Update the cached version of node's size. */ |
515 | /* Update the cached version of node's size. */ |
516 | if (rc == EOK) |
516 | if (rc == EOK) |
517 | file->node->size = IPC_GET_ARG2(answer); |
517 | file->node->size = IPC_GET_ARG2(answer); |
518 | rwlock_write_unlock(&file->node->contents_rwlock); |
518 | rwlock_write_unlock(&file->node->contents_rwlock); |
519 | } |
519 | } |
520 | 520 | ||
521 | /* Update the position pointer and unlock the open file. */ |
521 | /* Update the position pointer and unlock the open file. */ |
522 | if (rc == EOK) |
522 | if (rc == EOK) |
523 | file->pos += bytes; |
523 | file->pos += bytes; |
524 | futex_up(&file->lock); |
524 | futex_up(&file->lock); |
525 | 525 | ||
526 | /* |
526 | /* |
527 | * FS server's reply is the final result of the whole operation we |
527 | * FS server's reply is the final result of the whole operation we |
528 | * return to the client. |
528 | * return to the client. |
529 | */ |
529 | */ |
530 | ipc_answer_1(rid, rc, bytes); |
530 | ipc_answer_1(rid, rc, bytes); |