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