Subversion Repositories HelenOS

Rev

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