Rev 2958 | Rev 3109 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2958 | Rev 3079 | ||
|---|---|---|---|
| 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); |