Subversion Repositories HelenOS

Rev

Rev 4581 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4581 Rev 4718
Line 106... Line 106...
106
            return;
106
            return;
107
        }
107
        }
108
       
108
       
109
        /*
109
        /*
110
         * Now we hold a reference to mp_node.
110
         * Now we hold a reference to mp_node.
111
         * It will be dropped upon the corresponding VFS_UNMOUNT.
111
         * It will be dropped upon the corresponding VFS_IN_UNMOUNT.
112
         * This prevents the mount point from being deleted.
112
         * This prevents the mount point from being deleted.
113
         */
113
         */
114
    } else {
114
    } else {
115
        /* We still don't have the root file system mounted. */
115
        /* We still don't have the root file system mounted. */
116
        if (str_cmp(mp, "/") == 0) {
116
        if (str_cmp(mp, "/") == 0) {
Line 119... Line 119...
119
             * we are almost done.
119
             * we are almost done.
120
             */
120
             */
121
           
121
           
122
            /* Tell the mountee that it is being mounted. */
122
            /* Tell the mountee that it is being mounted. */
123
            phone = vfs_grab_phone(fs_handle);
123
            phone = vfs_grab_phone(fs_handle);
124
            msg = async_send_1(phone, VFS_MOUNTED,
124
            msg = async_send_1(phone, VFS_OUT_MOUNTED,
125
                (ipcarg_t) dev_handle, &answer);
125
                (ipcarg_t) dev_handle, &answer);
126
            /* send the mount options */
126
            /* send the mount options */
127
            rc = ipc_data_write_start(phone, (void *)opts,
127
            rc = ipc_data_write_start(phone, (void *)opts,
128
                str_size(opts));
128
                str_size(opts));
129
            if (rc != EOK) {
129
            if (rc != EOK) {
Line 181... Line 181...
181
   
181
   
182
    int mountee_phone = vfs_grab_phone(fs_handle);
182
    int mountee_phone = vfs_grab_phone(fs_handle);
183
    assert(mountee_phone >= 0);
183
    assert(mountee_phone >= 0);
184
 
184
 
185
    phone = vfs_grab_phone(mp_res.triplet.fs_handle);
185
    phone = vfs_grab_phone(mp_res.triplet.fs_handle);
186
    msg = async_send_4(phone, VFS_MOUNT,
186
    msg = async_send_4(phone, VFS_OUT_MOUNT,
187
        (ipcarg_t) mp_res.triplet.dev_handle,
187
        (ipcarg_t) mp_res.triplet.dev_handle,
188
        (ipcarg_t) mp_res.triplet.index,
188
        (ipcarg_t) mp_res.triplet.index,
189
        (ipcarg_t) fs_handle,
189
        (ipcarg_t) fs_handle,
190
        (ipcarg_t) dev_handle, &answer);
190
        (ipcarg_t) dev_handle, &answer);
191
   
191
   
Line 304... Line 304...
304
        free(mp);
304
        free(mp);
305
        return;
305
        return;
306
    }
306
    }
307
 
307
 
308
    /* Check the offered options size. */
308
    /* Check the offered options size. */
309
    if (size < 0 || size > MAX_MNTOPTS_LEN) {
309
    if (size > MAX_MNTOPTS_LEN) {
310
        ipc_answer_0(callid, EINVAL);
310
        ipc_answer_0(callid, EINVAL);
311
        ipc_answer_0(rid, EINVAL);
311
        ipc_answer_0(rid, EINVAL);
312
        free(mp);
312
        free(mp);
313
        return;
313
        return;
314
    }
314
    }
Line 435... Line 435...
435
        return;
435
        return;
436
    }
436
    }
437
   
437
   
438
    /*
438
    /*
439
     * The POSIX interface is open(path, oflag, mode).
439
     * The POSIX interface is open(path, oflag, mode).
440
     * We can receive oflags and mode along with the VFS_OPEN call; the path
440
     * We can receive oflags and mode along with the VFS_IN_OPEN call;
441
     * will need to arrive in another call.
441
     * the path will need to arrive in another call.
442
     *
442
     *
443
     * We also receive one private, non-POSIX set of flags called lflag
443
     * We also receive one private, non-POSIX set of flags called lflag
444
     * used to pass information to vfs_lookup_internal().
444
     * used to pass information to vfs_lookup_internal().
445
     */
445
     */
446
    int lflag = IPC_GET_ARG1(*request);
446
    int lflag = IPC_GET_ARG1(*request);
447
    int oflag = IPC_GET_ARG2(*request);
447
    int oflag = IPC_GET_ARG2(*request);
448
    int mode = IPC_GET_ARG3(*request);
448
    int mode = IPC_GET_ARG3(*request);
449
    size_t len;
449
    size_t len;
-
 
450
 
-
 
451
    /* Ignore mode for now. */
-
 
452
    (void) mode;
450
   
453
   
451
    /*
454
    /*
452
     * Make sure that we are called with exactly one of L_FILE and
455
     * Make sure that we are called with exactly one of L_FILE and
453
     * L_DIRECTORY. Make sure that the user does not pass L_OPEN.
456
     * L_DIRECTORY. Make sure that the user does not pass L_OPEN.
454
     */
457
     */
Line 553... Line 556...
553
    /*
556
    /*
554
     * The following increase in reference count is for the fact that the
557
     * The following increase in reference count is for the fact that the
555
     * file is being opened and that a file structure is pointing to it.
558
     * file is being opened and that a file structure is pointing to it.
556
     * It is necessary so that the file will not disappear when
559
     * It is necessary so that the file will not disappear when
557
     * vfs_node_put() is called. The reference will be dropped by the
560
     * vfs_node_put() is called. The reference will be dropped by the
558
     * respective VFS_CLOSE.
561
     * respective VFS_IN_CLOSE.
559
     */
562
     */
560
    vfs_node_addref(node);
563
    vfs_node_addref(node);
561
    vfs_node_put(node);
564
    vfs_node_put(node);
562
   
565
   
563
    /* Success! Return the new file descriptor to the client. */
566
    /* Success! Return the new file descriptor to the client. */
Line 630... Line 633...
630
    /*
633
    /*
631
     * The following increase in reference count is for the fact that the
634
     * The following increase in reference count is for the fact that the
632
     * file is being opened and that a file structure is pointing to it.
635
     * file is being opened and that a file structure is pointing to it.
633
     * It is necessary so that the file will not disappear when
636
     * It is necessary so that the file will not disappear when
634
     * vfs_node_put() is called. The reference will be dropped by the
637
     * vfs_node_put() is called. The reference will be dropped by the
635
     * respective VFS_CLOSE.
638
     * respective VFS_IN_CLOSE.
636
     */
639
     */
637
    vfs_node_addref(node);
640
    vfs_node_addref(node);
638
    vfs_node_put(node);
641
    vfs_node_put(node);
639
   
642
   
640
    /* Success! Return the new file descriptor to the client. */
643
    /* Success! Return the new file descriptor to the client. */
641
    ipc_answer_1(rid, EOK, fd);
644
    ipc_answer_1(rid, EOK, fd);
642
}
645
}
643
 
646
 
644
void vfs_node(ipc_callid_t rid, ipc_call_t *request)
-
 
645
{
-
 
646
    int fd = IPC_GET_ARG1(*request);
-
 
647
   
-
 
648
    /* Lookup the file structure corresponding to the file descriptor. */
-
 
649
    vfs_file_t *file = vfs_file_get(fd);
-
 
650
    if (!file) {
-
 
651
        ipc_answer_0(rid, ENOENT);
-
 
652
        return;
-
 
653
    }
-
 
654
   
-
 
655
    ipc_answer_3(rid, EOK, file->node->fs_handle, file->node->dev_handle,
-
 
656
        file->node->index);
-
 
657
}
-
 
658
 
-
 
659
void vfs_device(ipc_callid_t rid, ipc_call_t *request)
-
 
660
{
-
 
661
    int fd = IPC_GET_ARG1(*request);
-
 
662
   
-
 
663
    /* Lookup the file structure corresponding to the file descriptor. */
-
 
664
    vfs_file_t *file = vfs_file_get(fd);
-
 
665
    if (!file) {
-
 
666
        ipc_answer_0(rid, ENOENT);
-
 
667
        return;
-
 
668
    }
-
 
669
   
-
 
670
    /*
-
 
671
     * Lock the open file structure so that no other thread can manipulate
-
 
672
     * the same open file at a time.
-
 
673
     */
-
 
674
    fibril_mutex_lock(&file->lock);
-
 
675
    int fs_phone = vfs_grab_phone(file->node->fs_handle);
-
 
676
   
-
 
677
    /* Make a VFS_DEVICE request at the destination FS server. */
-
 
678
    aid_t msg;
-
 
679
    ipc_call_t answer;
-
 
680
    msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
-
 
681
        file->node->dev_handle, file->node->index, &answer);
-
 
682
 
-
 
683
    /* Wait for reply from the FS server. */
-
 
684
    ipcarg_t rc;
-
 
685
    async_wait_for(msg, &rc);
-
 
686
 
-
 
687
    vfs_release_phone(fs_phone);
-
 
688
    fibril_mutex_unlock(&file->lock);
-
 
689
   
-
 
690
    ipc_answer_1(rid, EOK, IPC_GET_ARG1(answer));
-
 
691
}
-
 
692
 
-
 
693
void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
647
void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
694
{
648
{
695
    int fd = IPC_GET_ARG1(*request);
649
    int fd = IPC_GET_ARG1(*request);
696
   
650
   
697
    /* Lookup the file structure corresponding to the file descriptor. */
651
    /* Lookup the file structure corresponding to the file descriptor. */
Line 706... Line 660...
706
     * the same open file at a time.
660
     * the same open file at a time.
707
     */
661
     */
708
    fibril_mutex_lock(&file->lock);
662
    fibril_mutex_lock(&file->lock);
709
    int fs_phone = vfs_grab_phone(file->node->fs_handle);
663
    int fs_phone = vfs_grab_phone(file->node->fs_handle);
710
   
664
   
711
    /* Make a VFS_SYMC request at the destination FS server. */
665
    /* Make a VFS_OUT_SYMC request at the destination FS server. */
712
    aid_t msg;
666
    aid_t msg;
713
    ipc_call_t answer;
667
    ipc_call_t answer;
714
    msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
668
    msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->dev_handle,
715
        file->node->dev_handle, file->node->index, &answer);
669
        file->node->index, &answer);
716
 
670
 
717
    /* Wait for reply from the FS server. */
671
    /* Wait for reply from the FS server. */
718
    ipcarg_t rc;
672
    ipcarg_t rc;
719
    async_wait_for(msg, &rc);
673
    async_wait_for(msg, &rc);
720
   
674
   
Line 740... Line 694...
740
     * the same open file at a time.
694
     * the same open file at a time.
741
     */
695
     */
742
    fibril_mutex_lock(&file->lock);
696
    fibril_mutex_lock(&file->lock);
743
    int fs_phone = vfs_grab_phone(file->node->fs_handle);
697
    int fs_phone = vfs_grab_phone(file->node->fs_handle);
744
   
698
   
745
    /* Make a VFS_CLOSE request at the destination FS server. */
699
    /* Make a VFS_OUT_CLOSE request at the destination FS server. */
746
    aid_t msg;
700
    aid_t msg;
747
    ipc_call_t answer;
701
    ipc_call_t answer;
748
    msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
702
    msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle,
749
        file->node->dev_handle, file->node->index, &answer);
703
        file->node->index, &answer);
750
 
704
 
751
    /* Wait for reply from the FS server. */
705
    /* Wait for reply from the FS server. */
752
    ipcarg_t rc;
706
    ipcarg_t rc;
753
    async_wait_for(msg, &rc);
707
    async_wait_for(msg, &rc);
754
 
708
 
Line 830... Line 784...
830
    /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */
784
    /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */
831
    aid_t msg;
785
    aid_t msg;
832
    ipc_call_t answer;
786
    ipc_call_t answer;
833
    if (!read && file->append)
787
    if (!read && file->append)
834
        file->pos = file->node->size;
788
        file->pos = file->node->size;
835
    msg = async_send_3(fs_phone, IPC_GET_METHOD(*request),
789
    msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE,
836
        file->node->dev_handle, file->node->index, file->pos, &answer);
790
        file->node->dev_handle, file->node->index, file->pos, &answer);
837
   
791
   
838
    /*
792
    /*
839
     * Forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
793
     * Forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
840
     * destination FS server. The call will be routed as if sent by
794
     * destination FS server. The call will be routed as if sent by
Line 944... Line 898...
944
{
898
{
945
    ipcarg_t rc;
899
    ipcarg_t rc;
946
    int fs_phone;
900
    int fs_phone;
947
   
901
   
948
    fs_phone = vfs_grab_phone(fs_handle);
902
    fs_phone = vfs_grab_phone(fs_handle);
949
    rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)dev_handle,
903
    rc = async_req_3_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t)dev_handle,
950
        (ipcarg_t)index, (ipcarg_t)size);
904
        (ipcarg_t)index, (ipcarg_t)size);
951
    vfs_release_phone(fs_phone);
905
    vfs_release_phone(fs_phone);
952
    return (int)rc;
906
    return (int)rc;
953
}
907
}
954
 
908
 
Line 974... Line 928...
974
 
928
 
975
    fibril_mutex_unlock(&file->lock);
929
    fibril_mutex_unlock(&file->lock);
976
    ipc_answer_0(rid, (ipcarg_t)rc);
930
    ipc_answer_0(rid, (ipcarg_t)rc);
977
}
931
}
978
 
932
 
-
 
933
void vfs_fstat(ipc_callid_t rid, ipc_call_t *request)
-
 
934
{
-
 
935
    int fd = IPC_GET_ARG1(*request);
-
 
936
    size_t size = IPC_GET_ARG2(*request);
-
 
937
    ipcarg_t rc;
-
 
938
 
-
 
939
    vfs_file_t *file = vfs_file_get(fd);
-
 
940
    if (!file) {
-
 
941
        ipc_answer_0(rid, ENOENT);
-
 
942
        return;
-
 
943
    }
-
 
944
 
-
 
945
    ipc_callid_t callid;
-
 
946
    if (!ipc_data_read_receive(&callid, NULL)) {
-
 
947
        ipc_answer_0(callid, EINVAL);
-
 
948
        ipc_answer_0(rid, EINVAL);
-
 
949
        return;
-
 
950
    }
-
 
951
 
-
 
952
    fibril_mutex_lock(&file->lock);
-
 
953
 
-
 
954
    int fs_phone = vfs_grab_phone(file->node->fs_handle);
-
 
955
   
-
 
956
    aid_t msg;
-
 
957
    msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->dev_handle,
-
 
958
        file->node->index, true, NULL);
-
 
959
    ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
-
 
960
    async_wait_for(msg, &rc);
-
 
961
    vfs_release_phone(fs_phone);
-
 
962
 
-
 
963
    fibril_mutex_unlock(&file->lock);
-
 
964
    ipc_answer_0(rid, rc);
-
 
965
}
-
 
966
 
-
 
967
void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
-
 
968
{
-
 
969
    size_t len;
-
 
970
    ipc_callid_t callid;
-
 
971
 
-
 
972
    if (!ipc_data_write_receive(&callid, &len)) {
-
 
973
        ipc_answer_0(callid, EINVAL);
-
 
974
        ipc_answer_0(rid, EINVAL);
-
 
975
        return;
-
 
976
    }
-
 
977
    char *path = malloc(len + 1);
-
 
978
    if (!path) {
-
 
979
        ipc_answer_0(callid, ENOMEM);
-
 
980
        ipc_answer_0(rid, ENOMEM);
-
 
981
        return;
-
 
982
    }
-
 
983
    int rc;
-
 
984
    if ((rc = ipc_data_write_finalize(callid, path, len))) {
-
 
985
        ipc_answer_0(rid, rc);
-
 
986
        free(path);
-
 
987
        return;
-
 
988
    }
-
 
989
    path[len] = '\0';
-
 
990
 
-
 
991
    if (!ipc_data_read_receive(&callid, NULL)) {
-
 
992
        free(path);
-
 
993
        ipc_answer_0(callid, EINVAL);
-
 
994
        ipc_answer_0(rid, EINVAL);
-
 
995
        return;
-
 
996
    }
-
 
997
 
-
 
998
    vfs_lookup_res_t lr;
-
 
999
    fibril_rwlock_read_lock(&namespace_rwlock);
-
 
1000
    rc = vfs_lookup_internal(path, L_NONE, &lr, NULL);
-
 
1001
    free(path);
-
 
1002
    if (rc != EOK) {
-
 
1003
        fibril_rwlock_read_unlock(&namespace_rwlock);
-
 
1004
        ipc_answer_0(callid, rc);
-
 
1005
        ipc_answer_0(rid, rc);
-
 
1006
        return;
-
 
1007
    }
-
 
1008
    vfs_node_t *node = vfs_node_get(&lr);
-
 
1009
    if (!node) {
-
 
1010
        fibril_rwlock_read_unlock(&namespace_rwlock);
-
 
1011
        ipc_answer_0(callid, ENOMEM);
-
 
1012
        ipc_answer_0(rid, ENOMEM);
-
 
1013
        return;
-
 
1014
    }
-
 
1015
 
-
 
1016
    fibril_rwlock_read_unlock(&namespace_rwlock);
-
 
1017
 
-
 
1018
    int fs_phone = vfs_grab_phone(node->fs_handle);
-
 
1019
    aid_t msg;
-
 
1020
    msg = async_send_3(fs_phone, VFS_OUT_STAT, node->dev_handle,
-
 
1021
        node->index, false, NULL);
-
 
1022
    ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
-
 
1023
   
-
 
1024
    ipcarg_t rv;
-
 
1025
    async_wait_for(msg, &rv);
-
 
1026
    vfs_release_phone(fs_phone);
-
 
1027
 
-
 
1028
    ipc_answer_0(rid, rv);
-
 
1029
 
-
 
1030
    vfs_node_put(node);
-
 
1031
}
-
 
1032
 
979
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
1033
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
980
{
1034
{
981
    int mode = IPC_GET_ARG1(*request);
1035
    int mode = IPC_GET_ARG1(*request);
982
 
1036
 
983
    size_t len;
1037
    size_t len;
Line 999... Line 1053...
999
        ipc_answer_0(rid, rc);
1053
        ipc_answer_0(rid, rc);
1000
        free(path);
1054
        free(path);
1001
        return;
1055
        return;
1002
    }
1056
    }
1003
    path[len] = '\0';
1057
    path[len] = '\0';
-
 
1058
 
-
 
1059
    /* Ignore mode for now. */
-
 
1060
    (void) mode;
1004
   
1061
   
1005
    fibril_rwlock_write_lock(&namespace_rwlock);
1062
    fibril_rwlock_write_lock(&namespace_rwlock);
1006
    int lflag = L_DIRECTORY | L_CREATE | L_EXCLUSIVE;
1063
    int lflag = L_DIRECTORY | L_CREATE | L_EXCLUSIVE;
1007
    rc = vfs_lookup_internal(path, lflag, NULL, NULL);
1064
    rc = vfs_lookup_internal(path, lflag, NULL, NULL);
1008
    fibril_rwlock_write_unlock(&namespace_rwlock);
1065
    fibril_rwlock_write_unlock(&namespace_rwlock);
Line 1048... Line 1105...
1048
    }
1105
    }
1049
 
1106
 
1050
    /*
1107
    /*
1051
     * The name has already been unlinked by vfs_lookup_internal().
1108
     * The name has already been unlinked by vfs_lookup_internal().
1052
     * We have to get and put the VFS node to ensure that it is
1109
     * We have to get and put the VFS node to ensure that it is
1053
     * VFS_DESTROY'ed after the last reference to it is dropped.
1110
     * VFS_OUT_DESTROY'ed after the last reference to it is dropped.
1054
     */
1111
     */
1055
    vfs_node_t *node = vfs_node_get(&lr);
1112
    vfs_node_t *node = vfs_node_get(&lr);
1056
    fibril_mutex_lock(&nodes_mutex);
1113
    fibril_mutex_lock(&nodes_mutex);
1057
    node->lnkcnt--;
1114
    node->lnkcnt--;
1058
    fibril_mutex_unlock(&nodes_mutex);
1115
    fibril_mutex_unlock(&nodes_mutex);