Changeset 5126f80 in mainline
- Timestamp:
- 2017-03-08T11:42:17Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0d35511
- Parents:
- a737667e
- git-author:
- Jiri Zarevucky <zarevucky.jiri@…> (2017-03-08 11:42:17)
- git-committer:
- Jakub Jermar <jakub@…> (2017-03-08 11:42:17)
- Location:
- uspace
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/mount/mount.c
ra737667e r5126f80 151 151 mopts = t_argv[4]; 152 152 153 rc = vfs_mount(t_argv[1], t_argv[2], dev, mopts, 0, instance);153 rc = mount(t_argv[1], t_argv[2], dev, mopts, 0, instance); 154 154 if (rc != EOK) { 155 155 printf("Unable to mount %s filesystem to %s on %s (rc=%s)\n", -
uspace/app/bdsh/cmds/modules/unmount/unmount.c
ra737667e r5126f80 66 66 } 67 67 68 rc = vfs_unmount(argv[1]);68 rc = unmount(argv[1]); 69 69 if (rc != EOK) { 70 70 printf("Unable to unmount %s (rc=%d)\n", argv[1], rc); -
uspace/app/init/init.c
ra737667e r5126f80 127 127 opts = "restore"; 128 128 129 int rc = vfs_mount(fstype, ROOT_MOUNT_POINT, ROOT_DEVICE, opts,129 int rc = mount(fstype, ROOT_MOUNT_POINT, ROOT_DEVICE, opts, 130 130 IPC_FLAG_BLOCKING, 0); 131 131 return mount_report("Root filesystem", ROOT_MOUNT_POINT, fstype, … … 144 144 static bool mount_locfs(void) 145 145 { 146 int rc = vfs_mount(LOCFS_FS_TYPE, LOCFS_MOUNT_POINT, "", "",146 int rc = mount(LOCFS_FS_TYPE, LOCFS_MOUNT_POINT, "", "", 147 147 IPC_FLAG_BLOCKING, 0); 148 148 return mount_report("Location service filesystem", LOCFS_MOUNT_POINT, … … 300 300 static bool mount_tmpfs(void) 301 301 { 302 int rc = vfs_mount(TMPFS_FS_TYPE, TMPFS_MOUNT_POINT, "", "", 0, 0);302 int rc = mount(TMPFS_FS_TYPE, TMPFS_MOUNT_POINT, "", "", 0, 0); 303 303 return mount_report("Temporary filesystem", TMPFS_MOUNT_POINT, 304 304 TMPFS_FS_TYPE, NULL, rc); -
uspace/app/sysinst/sysinst.c
ra737667e r5126f80 180 180 181 181 printf("sysinst_fs_mount(): mount filesystem\n"); 182 rc = vfs_mount(FS_TYPE, MOUNT_POINT, dev, "", 0, 0);182 rc = mount(FS_TYPE, MOUNT_POINT, dev, "", 0, 0); 183 183 if (rc != EOK) 184 184 return rc; … … 219 219 220 220 printf("sysinst_copy_boot_files(): mount CD filesystem\n"); 221 rc = vfs_mount(CD_FS_TYPE, CD_MOUNT_POINT, CD_DEV, "", 0, 0);221 rc = mount(CD_FS_TYPE, CD_MOUNT_POINT, CD_DEV, "", 0, 0); 222 222 if (rc != EOK) 223 223 return rc; … … 229 229 230 230 printf("sysinst_copy_boot_files(): unmount %s\n", MOUNT_POINT); 231 rc = vfs_unmount(MOUNT_POINT);231 rc = unmount(MOUNT_POINT); 232 232 if (rc != EOK) 233 233 return rc; -
uspace/app/trace/trace.c
ra737667e r5126f80 512 512 goto error; 513 513 514 /* Send program pathname*/514 /* Send program. */ 515 515 rc = loader_set_program_path(ldr, path); 516 516 if (rc != EOK) … … 523 523 524 524 /* Send default files */ 525 int fd_root; 525 526 int fd_stdin; 526 527 int fd_stdout; 527 528 int fd_stderr; 529 530 fd_root = vfs_root(); 531 if (fd_root >= 0) { 532 rc = loader_add_inbox(ldr, "root", fd_root); 533 close(fd_root); 534 if (rc != EOK) 535 goto error; 536 } 528 537 529 538 if ((stdin != NULL) && (vfs_fhandle(stdin, &fd_stdin) == EOK)) { -
uspace/lib/c/generic/elf/elf_mod.c
ra737667e r5126f80 115 115 elf_finfo_t *info) 116 116 { 117 int file = vfs_lookup(path );117 int file = vfs_lookup(path, 0); 118 118 int rc = elf_load_file(file, so_bias, flags, info); 119 119 close(file); -
uspace/lib/c/generic/libc.c
ra737667e r5126f80 48 48 #include <task.h> 49 49 #include <loader/pcb.h> 50 #include <vfs/vfs.h> 51 #include <vfs/inbox.h> 50 52 #include "private/libc.h" 51 53 #include "private/async.h" … … 113 115 __inbox_init(__pcb->inbox, __pcb->inbox_entries); 114 116 __stdio_init(); 117 vfs_root_set(inbox_get("root")); 115 118 (void) chdir(__pcb->cwd); 116 119 } -
uspace/lib/c/generic/loader.c
ra737667e r5126f80 198 198 } 199 199 200 int fd = vfs_lookup(path );200 int fd = vfs_lookup(path, 0); 201 201 if (fd < 0) { 202 202 return fd; -
uspace/lib/c/generic/task.c
ra737667e r5126f80 48 48 #include "private/ns.h" 49 49 #include <vfs/vfs.h> 50 #include <unistd.h> 50 51 51 52 task_id_t task_get_id(void) … … 177 178 178 179 /* Send files */ 180 int root = vfs_root(); 181 if (root >= 0) { 182 rc = loader_add_inbox(ldr, "root", root); 183 close(root); 184 if (rc != EOK) 185 goto error; 186 } 187 179 188 if (fd_stdin >= 0) { 180 189 rc = loader_add_inbox(ldr, "stdin", fd_stdin); -
uspace/lib/c/generic/vfs/vfs.c
ra737667e r5126f80 65 65 static size_t cwd_size = 0; 66 66 67 static FIBRIL_MUTEX_INITIALIZE(root_mutex); 68 static int root_fd = -1; 69 70 int vfs_root(void) 71 { 72 fibril_mutex_lock(&root_mutex); 73 int r; 74 if (root_fd < 0) { 75 r = ENOENT; 76 } else { 77 r = vfs_clone(root_fd, true); 78 } 79 fibril_mutex_unlock(&root_mutex); 80 return r; 81 } 82 83 void vfs_root_set(int nroot) 84 { 85 fibril_mutex_lock(&root_mutex); 86 if (root_fd >= 0) { 87 close(root_fd); 88 } 89 root_fd = vfs_clone(nroot, true); 90 fibril_mutex_unlock(&root_mutex); 91 } 92 67 93 /** Start an async exchange on the VFS session. 68 94 * … … 116 142 } 117 143 118 int vfs_lookup(const char *path )144 int vfs_lookup(const char *path, int flags) 119 145 { 120 146 size_t size; … … 123 149 return ENOMEM; 124 150 } 125 int rc = _vfs_walk(-1, p, 0); 151 int root = vfs_root(); 152 if (root == -1) { 153 free(p); 154 return ENOENT; 155 } 156 int rc = _vfs_walk(root, p, flags); 157 close(root); 126 158 free(p); 127 159 return rc; … … 187 219 } 188 220 189 int vfs_mount(const char *fs_name, const char *mp, const char *fqsn, 221 int vfs_mount(int mp, const char *fs_name, service_id_t serv, const char *opts, 222 unsigned int flags, unsigned int instance, int *mountedfd) 223 { 224 sysarg_t rc, rc1; 225 226 if (!mountedfd) { 227 flags |= VFS_MOUNT_NO_REF; 228 } 229 if (mp < 0) { 230 flags |= VFS_MOUNT_CONNECT_ONLY; 231 } 232 233 ipc_call_t answer; 234 async_exch_t *exch = vfs_exchange_begin(); 235 aid_t req = async_send_4(exch, VFS_IN_MOUNT, mp, serv, flags, instance, &answer); 236 237 rc1 = async_data_write_start(exch, (void *) opts, str_size(opts)); 238 239 if (rc1 == EOK) { 240 rc1 = async_data_write_start(exch, (void *) fs_name, str_size(fs_name)); 241 } 242 243 vfs_exchange_end(exch); 244 245 async_wait_for(req, &rc); 246 247 if (mountedfd) { 248 *mountedfd = (int) IPC_GET_ARG1(answer); 249 } 250 251 if (rc != EOK) { 252 return rc; 253 } 254 return rc1; 255 } 256 257 int vfs_unmount(int mp) 258 { 259 async_exch_t *exch = vfs_exchange_begin(); 260 int rc = async_req_1_0(exch, VFS_IN_UNMOUNT, mp); 261 vfs_exchange_end(exch); 262 return rc; 263 } 264 265 int mount(const char *fs_name, const char *mp, const char *fqsn, 190 266 const char *opts, unsigned int flags, unsigned int instance) 191 267 { … … 205 281 } 206 282 283 if (flags & IPC_FLAG_BLOCKING) { 284 flags = VFS_MOUNT_BLOCKING; 285 } else { 286 flags = 0; 287 } 288 207 289 service_id_t service_id; 208 290 int res = loc_service_get_id(fqsn, &service_id, flags); … … 223 305 } 224 306 225 async_exch_t *exch = vfs_exchange_begin(); 226 227 sysarg_t rc_orig; 228 aid_t req = async_send_3(exch, VFS_IN_MOUNT, service_id, flags, 229 instance, NULL); 230 sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size); 231 if (rc != EOK) { 232 vfs_exchange_end(exch); 233 free(mpa); 234 async_wait_for(req, &rc_orig); 307 fibril_mutex_lock(&root_mutex); 308 309 int rc; 310 311 if (str_cmp(mpa, "/") == 0) { 312 /* Mounting root. */ 235 313 236 if (null_id != -1) 237 loc_null_destroy(null_id); 314 if (root_fd >= 0) { 315 fibril_mutex_unlock(&root_mutex); 316 if (null_id != -1) { 317 loc_null_destroy(null_id); 318 } 319 return EBUSY; 320 } 238 321 239 if (rc_orig == EOK) 240 return (int) rc; 241 else 242 return (int) rc_orig; 243 } 244 245 rc = async_data_write_start(exch, (void *) opts, str_size(opts)); 246 if (rc != EOK) { 247 vfs_exchange_end(exch); 248 free(mpa); 249 async_wait_for(req, &rc_orig); 322 int root; 323 rc = vfs_mount(-1, fs_name, service_id, opts, flags, instance, &root); 324 if (rc == EOK) { 325 root_fd = root; 326 } 327 } else { 328 if (root_fd < 0) { 329 fibril_mutex_unlock(&root_mutex); 330 if (null_id != -1) { 331 loc_null_destroy(null_id); 332 } 333 return EINVAL; 334 } 250 335 251 if (null_id != -1) 252 loc_null_destroy(null_id); 253 254 if (rc_orig == EOK) 255 return (int) rc; 256 else 257 return (int) rc_orig; 258 } 259 260 rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name)); 261 if (rc != EOK) { 262 vfs_exchange_end(exch); 263 free(mpa); 264 async_wait_for(req, &rc_orig); 265 266 if (null_id != -1) 267 loc_null_destroy(null_id); 268 269 if (rc_orig == EOK) 270 return (int) rc; 271 else 272 return (int) rc_orig; 273 } 274 275 vfs_exchange_end(exch); 276 free(mpa); 277 async_wait_for(req, &rc); 336 int mpfd = _vfs_walk(root_fd, mpa, WALK_DIRECTORY); 337 if (mpfd >= 0) { 338 rc = vfs_mount(mpfd, fs_name, service_id, opts, flags, instance, NULL); 339 close(mpfd); 340 } else { 341 rc = mpfd; 342 } 343 } 344 345 fibril_mutex_unlock(&root_mutex); 278 346 279 347 if ((rc != EOK) && (null_id != -1)) … … 283 351 } 284 352 285 int vfs_unmount(const char *mp) 286 { 287 sysarg_t rc; 288 sysarg_t rc_orig; 289 aid_t req; 290 size_t mpa_size; 291 char *mpa; 292 293 mpa = vfs_absolutize(mp, &mpa_size); 294 if (mpa == NULL) 295 return ENOMEM; 296 297 async_exch_t *exch = vfs_exchange_begin(); 298 299 req = async_send_0(exch, VFS_IN_UNMOUNT, NULL); 300 rc = async_data_write_start(exch, (void *) mpa, mpa_size); 301 if (rc != EOK) { 302 vfs_exchange_end(exch); 303 free(mpa); 304 async_wait_for(req, &rc_orig); 305 if (rc_orig == EOK) 306 return (int) rc; 307 else 308 return (int) rc_orig; 309 } 310 311 312 vfs_exchange_end(exch); 313 free(mpa); 314 async_wait_for(req, &rc); 315 316 return (int) rc; 353 int unmount(const char *mpp) 354 { 355 int mp = vfs_lookup(mpp, WALK_MOUNT_POINT | WALK_DIRECTORY); 356 if (mp < 0) { 357 return mp; 358 } 359 360 int rc = vfs_unmount(mp); 361 close(mp); 362 return rc; 317 363 } 318 364 … … 348 394 assert((((oflag & O_RDONLY) != 0) + ((oflag & O_WRONLY) != 0) + ((oflag & O_RDWR) != 0)) == 1); 349 395 350 size_t abs_size; 351 char *abs = vfs_absolutize(path, &abs_size); 352 if (!abs) { 353 return ENOMEM; 354 } 355 356 int ret = _vfs_walk(-1, abs, walk_flags(oflag) | WALK_REGULAR); 396 int ret = vfs_lookup(path, walk_flags(oflag) | WALK_REGULAR); 357 397 if (ret < 0) { 358 398 return ret; … … 680 720 int stat(const char *path, struct stat *stat) 681 721 { 682 size_t pa_size; 683 char *pa = vfs_absolutize(path, &pa_size); 684 if (!pa) { 685 return ENOMEM; 686 } 687 688 int fd = _vfs_walk(-1, pa, 0); 722 int fd = vfs_lookup(path, 0); 689 723 if (fd < 0) { 690 724 return fd; … … 710 744 } 711 745 712 size_t abs_size; 713 char *abs = vfs_absolutize(dirname, &abs_size); 714 if (abs == NULL) { 715 free(dirp); 716 errno = ENOMEM; 717 return NULL; 718 } 719 720 int ret = _vfs_walk(-1, abs, WALK_DIRECTORY); 721 free(abs); 722 723 if (ret < EOK) { 746 int ret = vfs_lookup(dirname, WALK_DIRECTORY); 747 if (ret < 0) { 724 748 free(dirp); 725 749 errno = ret; … … 793 817 int mkdir(const char *path, mode_t mode) 794 818 { 819 int ret = vfs_lookup(path, WALK_MUST_CREATE | WALK_DIRECTORY); 820 if (ret < 0) { 821 return ret; 822 } 823 824 close(ret); 825 return EOK; 826 } 827 828 static int _vfs_unlink2(int parent, const char *path, int expect, int wflag) 829 { 830 sysarg_t rc; 831 aid_t req; 832 833 async_exch_t *exch = vfs_exchange_begin(); 834 835 req = async_send_3(exch, VFS_IN_UNLINK2, parent, expect, wflag, NULL); 836 rc = async_data_write_start(exch, path, str_size(path)); 837 838 vfs_exchange_end(exch); 839 840 sysarg_t rc_orig; 841 async_wait_for(req, &rc_orig); 842 843 if (rc_orig != EOK) { 844 return (int) rc_orig; 845 } 846 return rc; 847 } 848 849 /** Unlink file or directory. 850 * 851 * @param path Path 852 * @return EOk on success, error code on error 853 */ 854 int unlink(const char *path) 855 { 795 856 size_t pa_size; 796 857 char *pa = vfs_absolutize(path, &pa_size); … … 799 860 } 800 861 801 int ret = _vfs_walk(-1, pa, WALK_MUST_CREATE | WALK_DIRECTORY); 802 if (ret < 0) { 803 return ret; 804 } 805 806 close(ret); 807 return EOK; 808 } 809 810 static int _vfs_unlink2(int parent, const char *path, int expect, int wflag) 811 { 812 sysarg_t rc; 813 aid_t req; 814 815 async_exch_t *exch = vfs_exchange_begin(); 816 817 req = async_send_3(exch, VFS_IN_UNLINK2, parent, expect, wflag, NULL); 818 rc = async_data_write_start(exch, path, str_size(path)); 819 820 vfs_exchange_end(exch); 821 822 sysarg_t rc_orig; 823 async_wait_for(req, &rc_orig); 824 825 if (rc_orig != EOK) { 826 return (int) rc_orig; 827 } 862 int root = vfs_root(); 863 if (root < 0) { 864 free(pa); 865 return ENOENT; 866 } 867 868 int rc = _vfs_unlink2(root, pa, -1, 0); 869 870 free(pa); 871 close(root); 828 872 return rc; 829 873 } 830 874 831 /** Unlink file ordirectory.875 /** Remove empty directory. 832 876 * 833 877 * @param path Path 834 * @return EOk on success, error code on error835 */ 836 int unlink(const char *path)878 * @return 0 on success. On error returns -1 and sets errno. 879 */ 880 int rmdir(const char *path) 837 881 { 838 882 size_t pa_size; … … 842 886 } 843 887 844 return _vfs_unlink2(-1, pa, -1, 0); 845 } 846 847 /** Remove empty directory. 848 * 849 * @param path Path 850 * @return 0 on success. On error returns -1 and sets errno. 851 */ 852 int rmdir(const char *path) 853 { 854 size_t pa_size; 855 char *pa = vfs_absolutize(path, &pa_size); 856 if (!pa) { 857 return ENOMEM; 858 } 859 860 return _vfs_unlink2(-1, pa, -1, WALK_DIRECTORY); 888 int root = vfs_root(); 889 if (root < 0) { 890 free(pa); 891 return ENOENT; 892 } 893 894 int rc = _vfs_unlink2(root, pa, -1, WALK_DIRECTORY); 895 896 free(pa); 897 close(root); 898 return rc; 861 899 } 862 900 … … 890 928 891 929 async_exch_t *exch = vfs_exchange_begin(); 892 893 req = async_send_1(exch, VFS_IN_RENAME, -1, NULL); 930 int root = vfs_root(); 931 if (root < 0) { 932 free(olda); 933 free(newa); 934 return ENOENT; 935 } 936 937 req = async_send_1(exch, VFS_IN_RENAME, root, NULL); 894 938 rc = async_data_write_start(exch, olda, olda_size); 895 939 if (rc != EOK) { … … 897 941 free(olda); 898 942 free(newa); 943 close(root); 899 944 async_wait_for(req, &rc_orig); 900 945 if (rc_orig != EOK) … … 911 956 free(olda); 912 957 free(newa); 958 close(root); 913 959 async_wait_for(req, &rc_orig); 914 960 if (rc_orig != EOK) … … 923 969 free(olda); 924 970 free(newa); 971 close(root); 925 972 async_wait_for(req, &rc); 926 973 … … 955 1002 return ENOMEM; 956 1003 957 int fd = _vfs_walk(-1,abs, WALK_DIRECTORY);1004 int fd = vfs_lookup(abs, WALK_DIRECTORY); 958 1005 if (fd < 0) { 959 1006 free(abs); … … 964 1011 fibril_mutex_lock(&cwd_mutex); 965 1012 966 if (cwd_fd >= 0) 1013 if (cwd_fd >= 0) { 967 1014 close(cwd_fd); 968 969 if (cwd_path) 1015 } 1016 1017 if (cwd_path) { 970 1018 free(cwd_path); 1019 } 971 1020 972 1021 cwd_fd = fd; … … 1124 1173 int statfs(const char *path, struct statfs *st) 1125 1174 { 1126 size_t pa_size; 1127 char *pa = vfs_absolutize(path, &pa_size); 1128 if (!pa) { 1129 errno = ENOMEM; 1130 return -1; 1131 } 1132 1133 int fd = _vfs_walk(-1, pa, 0); 1175 int fd = vfs_lookup(path, 0); 1134 1176 if (fd < 0) { 1135 free(pa);1136 1177 errno = fd; 1137 1178 return -1; 1138 1179 } 1139 1140 free(pa);1141 1180 1142 1181 sysarg_t rc, ret; -
uspace/lib/c/include/ipc/vfs.h
ra737667e r5126f80 183 183 WALK_REGULAR = (1 << 3), 184 184 WALK_DIRECTORY = (1 << 4), 185 WALK_MOUNT_POINT = (1 << 5), 185 186 186 187 WALK_ALL_FLAGS = WALK_MAY_CREATE | WALK_MUST_CREATE | WALK_REGULAR | WALK_DIRECTORY, 188 }; 189 190 enum { 191 VFS_MOUNT_BLOCKING = 1, 192 VFS_MOUNT_CONNECT_ONLY = 2, 193 VFS_MOUNT_NO_REF = 4, 187 194 }; 188 195 -
uspace/lib/c/include/vfs/vfs.h
ra737667e r5126f80 52 52 extern char *vfs_absolutize(const char *, size_t *); 53 53 54 extern int vfs_mount(const char *, const char *, const char *, const char *,54 extern int mount(const char *, const char *, const char *, const char *, 55 55 unsigned int, unsigned int); 56 extern int vfs_unmount(const char *);56 extern int unmount(const char *); 57 57 58 58 extern int vfs_fhandle(FILE *, int *); … … 65 65 extern int _vfs_walk(int, const char *, int); 66 66 extern int _vfs_open(int, int); 67 extern int vfs_lookup(const char * );67 extern int vfs_lookup(const char *, int); 68 68 69 69 extern int vfs_pass_handle(async_exch_t *, int, async_exch_t *); … … 71 71 72 72 extern int vfs_clone(int, bool); 73 extern int vfs_root(void); 74 extern void vfs_root_set(int); 75 76 int vfs_mount(int, const char *, service_id_t, const char *, unsigned, unsigned, int *); 77 int vfs_unmount(int); 73 78 74 79 #endif -
uspace/srv/vfs/vfs_file.c
ra737667e r5126f80 178 178 * endpoint FS and drop our reference to the underlying VFS node. 179 179 */ 180 if (file->open_read || file->open_write) { 181 rc = vfs_file_close_remote(file); 182 } 183 vfs_node_delref(file->node); 180 181 if (file->node != NULL) { 182 if (file->open_read || file->open_write) { 183 rc = vfs_file_close_remote(file); 184 } 185 vfs_node_delref(file->node); 186 } 184 187 free(file); 185 188 } … … 312 315 } 313 316 317 static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file) 318 { 319 fibril_mutex_unlock(&file->_lock); 320 321 fibril_mutex_lock(&vfs_data->lock); 322 vfs_file_delref(vfs_data, file); 323 fibril_mutex_unlock(&vfs_data->lock); 324 } 325 314 326 static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd) 315 327 { … … 323 335 vfs_file_addref(vfs_data, file); 324 336 fibril_mutex_unlock(&vfs_data->lock); 337 325 338 fibril_mutex_lock(&file->_lock); 339 if (file->node == NULL) { 340 _vfs_file_put(vfs_data, file); 341 return NULL; 342 } 343 assert(file != NULL); 344 assert(file->node != NULL); 326 345 return file; 327 346 } … … 341 360 { 342 361 return _vfs_file_get(VFS_DATA, fd); 343 }344 345 static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)346 {347 fibril_mutex_unlock(&file->_lock);348 349 fibril_mutex_lock(&vfs_data->lock);350 vfs_file_delref(vfs_data, file);351 fibril_mutex_unlock(&vfs_data->lock);352 362 } 353 363 -
uspace/srv/vfs/vfs_lookup.c
ra737667e r5126f80 330 330 if (result != NULL) { 331 331 /* The found file may be a mount point. Try to cross it. */ 332 if (!(lflag & L_MP)) {332 if (!(lflag & (L_MP|L_DISABLE_MOUNTS))) { 333 333 base = vfs_node_peek(&res); 334 334 if (base != NULL && base->mount != NULL) { -
uspace/srv/vfs/vfs_ops.c
ra737667e r5126f80 68 68 FIBRIL_RWLOCK_INITIALIZE(namespace_rwlock); 69 69 70 vfs_node_t *root = NULL;71 72 70 static int vfs_connect_internal(service_id_t service_id, unsigned flags, unsigned instance, 73 71 char *options, char *fsname, vfs_node_t **root) 74 72 { 75 73 fs_handle_t fs_handle = 0; … … 79 77 fs_handle = fs_name_to_handle(instance, fsname, false); 80 78 81 if (fs_handle != 0 || !(flags & IPC_FLAG_BLOCKING)) {79 if (fs_handle != 0 || !(flags & VFS_MOUNT_BLOCKING)) { 82 80 break; 83 81 } … … 123 121 } 124 122 125 static int vfs_mount_internal(service_id_t service_id, unsigned flags, unsigned instance,126 char *opts, char *fs_name, char *mp)127 {128 /* Resolve the path to the mountpoint. */129 130 if (root == NULL) {131 /* We still don't have the root file system mounted. */132 if (str_cmp(mp, "/") != 0) {133 /*134 * We can't resolve this without the root filesystem135 * being mounted first.136 */137 return ENOENT;138 }139 140 return vfs_connect_internal(service_id, flags, instance, opts, fs_name, &root);141 }142 143 /* We already have the root FS. */144 if (str_cmp(mp, "/") == 0) {145 /* Trying to mount root FS over root FS */146 return EBUSY;147 }148 149 vfs_lookup_res_t mp_res;150 int rc = vfs_lookup_internal(root, mp, L_DIRECTORY, &mp_res);151 if (rc != EOK) {152 /* The lookup failed. */153 return rc;154 }155 156 vfs_node_t *mp_node;157 mp_node = vfs_node_get(&mp_res);158 if (!mp_node) {159 return ENOMEM;160 }161 162 if (mp_node->mount != NULL) {163 return EBUSY;164 }165 166 if (mp_node->type != VFS_NODE_DIRECTORY) {167 printf("%s node not a directory, type=%d\n", mp, mp_node->type);168 return ENOTDIR;169 }170 171 if (vfs_node_has_children(mp_node)) {172 return ENOTEMPTY;173 }174 175 vfs_node_t *mountee;176 177 rc = vfs_connect_internal(service_id, flags, instance, opts, fs_name, &mountee);178 if (rc != EOK) {179 vfs_node_put(mp_node);180 return ENOMEM;181 }182 183 mp_node->mount = mountee;184 /* The two references to nodes are held by the mount so that they cannot be freed.185 * They are removed in detach_internal().186 */187 return EOK;188 }189 190 123 void vfs_mount_srv(ipc_callid_t rid, ipc_call_t *request) 191 124 { 125 int mpfd = IPC_GET_ARG1(*request); 126 192 127 /* 193 128 * We expect the library to do the device-name to device-handle … … 195 130 * in the request. 196 131 */ 197 service_id_t service_id = (service_id_t) IPC_GET_ARG 1(*request);132 service_id_t service_id = (service_id_t) IPC_GET_ARG2(*request); 198 133 199 134 /* 200 135 * Mount flags are passed as ARG2. 201 136 */ 202 unsigned int flags = (unsigned int) IPC_GET_ARG 2(*request);137 unsigned int flags = (unsigned int) IPC_GET_ARG3(*request); 203 138 204 139 /* 205 140 * Instance number is passed as ARG3. 206 141 */ 207 unsigned int instance = IPC_GET_ARG3(*request); 208 209 /* We want the client to send us the mount point. */ 210 char *mp; 211 int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN, 142 unsigned int instance = IPC_GET_ARG4(*request); 143 144 char *opts = NULL; 145 char *fs_name = NULL; 146 vfs_file_t *mp = NULL; 147 vfs_file_t *file = NULL; 148 int fd = -1; 149 mtab_ent_t *mtab_ent = NULL; 150 151 /* Now we expect to receive the mount options. */ 152 int rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN, 212 153 0, NULL); 213 154 if (rc != EOK) { 214 async_answer_0(rid, rc); 215 return; 216 } 217 218 /* Now we expect to receive the mount options. */ 219 char *opts; 220 rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN, 221 0, NULL); 222 if (rc != EOK) { 223 async_answer_0(rid, rc); 224 free(mp); 225 return; 155 async_data_write_void(rc); 156 goto out; 226 157 } 227 158 … … 230 161 * system. 231 162 */ 232 char *fs_name;233 163 rc = async_data_write_accept((void **) &fs_name, true, 0, 234 164 FS_NAME_MAXLEN, 0, NULL); 235 165 if (rc != EOK) { 236 async_answer_0(rid, rc); 237 free(mp); 238 free(opts); 239 return; 166 goto out; 167 } 168 169 if (!(flags & VFS_MOUNT_CONNECT_ONLY)) { 170 mp = vfs_file_get(mpfd); 171 if (mp == NULL) { 172 rc = EBADF; 173 goto out; 174 } 175 176 if (mp->node->mount != NULL) { 177 rc = EBUSY; 178 goto out; 179 } 180 181 if (mp->node->type != VFS_NODE_DIRECTORY) { 182 rc = ENOTDIR; 183 goto out; 184 } 185 186 if (vfs_node_has_children(mp->node)) { 187 rc = ENOTEMPTY; 188 goto out; 189 } 190 } 191 192 if (!(flags & VFS_MOUNT_NO_REF)) { 193 fd = vfs_fd_alloc(&file, false); 194 if (fd < 0) { 195 rc = fd; 196 goto out; 197 } 240 198 } 241 199 242 200 /* Add the filesystem info to the list of mounted filesystems */ 243 mtab_ent _t *mtab_ent= malloc(sizeof(mtab_ent_t));201 mtab_ent = malloc(sizeof(mtab_ent_t)); 244 202 if (!mtab_ent) { 245 async_answer_0(rid, ENOMEM); 246 free(mp); 247 free(fs_name); 248 free(opts); 249 return; 250 } 251 252 /* Mount the filesystem. */ 203 rc = ENOMEM; 204 goto out; 205 } 206 207 vfs_node_t *root = NULL; 208 253 209 fibril_rwlock_write_lock(&namespace_rwlock); 254 rc = vfs_mount_internal(service_id, flags, instance, opts, fs_name, mp); 210 211 rc = vfs_connect_internal(service_id, flags, instance, opts, fs_name, &root); 212 if (rc == EOK && !(flags & VFS_MOUNT_CONNECT_ONLY)) { 213 vfs_node_addref(mp->node); 214 vfs_node_addref(root); 215 mp->node->mount = root; 216 } 217 255 218 fibril_rwlock_write_unlock(&namespace_rwlock); 256 219 220 if (rc != EOK) { 221 goto out; 222 } 223 224 225 if (flags & VFS_MOUNT_NO_REF) { 226 vfs_node_delref(root); 227 } else { 228 assert(file != NULL); 229 230 file->node = root; 231 file->permissions = MODE_READ | MODE_WRITE | MODE_APPEND; 232 file->open_read = false; 233 file->open_write = false; 234 } 235 257 236 /* Add the filesystem info to the list of mounted filesystems */ 258 237 if (rc == EOK) { 259 str_cpy(mtab_ent->mp, MAX_PATH_LEN, mp);238 str_cpy(mtab_ent->mp, MAX_PATH_LEN, "fixme"); 260 239 str_cpy(mtab_ent->fs_name, FS_NAME_MAXLEN, fs_name); 261 240 str_cpy(mtab_ent->opts, MAX_MNTOPTS_LEN, opts); … … 269 248 mtab_size++; 270 249 fibril_mutex_unlock(&mtab_list_lock); 271 } 272 273 async_answer_0(rid, rc); 274 275 free(mp); 276 free(fs_name); 277 free(opts); 250 } 251 252 rc = EOK; 253 254 out: 255 async_answer_1(rid, rc, rc == EOK ? fd : 0); 256 257 if (opts) { 258 free(opts); 259 } 260 if (fs_name) { 261 free(fs_name); 262 } 263 if (mp) { 264 vfs_file_put(mp); 265 } 266 if (file) { 267 vfs_file_put(file); 268 } 269 if (rc != EOK && fd >= 0) { 270 vfs_fd_free(fd); 271 } 278 272 } 279 273 280 274 void vfs_unmount_srv(ipc_callid_t rid, ipc_call_t *request) 281 275 { 282 /* 283 * Receive the mount point path. 284 */ 285 char *mp; 286 int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN, 287 0, NULL); 288 if (rc != EOK) 289 async_answer_0(rid, rc); 290 291 /* 292 * Taking the namespace lock will do two things for us. First, it will 293 * prevent races with other lookup operations. Second, it will stop new 294 * references to already existing VFS nodes and creation of new VFS 295 * nodes. This is because new references are added as a result of some 296 * lookup operation or at least of some operation which is protected by 297 * the namespace lock. 298 */ 276 int mpfd = IPC_GET_ARG1(*request); 277 278 vfs_file_t *mp = vfs_file_get(mpfd); 279 if (mp == NULL) { 280 async_answer_0(rid, EBADF); 281 return; 282 } 283 284 if (mp->node->mount == NULL) { 285 async_answer_0(rid, ENOENT); 286 vfs_file_put(mp); 287 return; 288 } 289 299 290 fibril_rwlock_write_lock(&namespace_rwlock); 300 301 if (str_cmp(mp, "/") == 0) {302 free(mp);303 304 /*305 * Unmounting the root file system.306 *307 * In this case, there is no mount point node and we send308 * VFS_OUT_UNMOUNTED directly to the mounted file system.309 */310 311 if (!root) {312 fibril_rwlock_write_unlock(&namespace_rwlock);313 async_answer_0(rid, ENOENT);314 return;315 }316 317 /*318 * Count the total number of references for the mounted file system. We319 * are expecting at least one, which we got when the file system was mounted.320 * If we find more, it means that321 * the file system cannot be gracefully unmounted at the moment because322 * someone is working with it.323 */324 if (vfs_nodes_refcount_sum_get(root->fs_handle, root->service_id) != 1) {325 fibril_rwlock_write_unlock(&namespace_rwlock);326 async_answer_0(rid, EBUSY);327 return;328 }329 330 async_exch_t *exch = vfs_exchange_grab(root->fs_handle);331 rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, root->service_id);332 vfs_exchange_release(exch);333 334 fibril_rwlock_write_unlock(&namespace_rwlock);335 if (rc == EOK) {336 vfs_node_forget(root);337 root = NULL;338 }339 async_answer_0(rid, rc);340 return;341 }342 343 /*344 * Lookup the mounted root and instantiate it.345 */346 vfs_lookup_res_t mp_res;347 rc = vfs_lookup_internal(root, mp, L_MP, &mp_res);348 if (rc != EOK) {349 fibril_rwlock_write_unlock(&namespace_rwlock);350 free(mp);351 async_answer_0(rid, rc);352 return;353 }354 vfs_node_t *mp_node = vfs_node_get(&mp_res);355 if (!mp_node) {356 fibril_rwlock_write_unlock(&namespace_rwlock);357 free(mp);358 async_answer_0(rid, ENOMEM);359 return;360 }361 362 if (mp_node->mount == NULL) {363 fibril_rwlock_write_unlock(&namespace_rwlock);364 vfs_node_put(mp_node);365 free(mp);366 async_answer_0(rid, ENOENT);367 return;368 }369 291 370 292 /* 371 293 * Count the total number of references for the mounted file system. We 372 * are expecting at least one, which we got when the file system was mounted.294 * are expecting at least one, which is held by the mount point. 373 295 * If we find more, it means that 374 296 * the file system cannot be gracefully unmounted at the moment because 375 297 * someone is working with it. 376 298 */ 377 if (vfs_nodes_refcount_sum_get(mp_node->mount->fs_handle, mp_node->mount->service_id) != 1) { 299 if (vfs_nodes_refcount_sum_get(mp->node->mount->fs_handle, mp->node->mount->service_id) != 1) { 300 async_answer_0(rid, EBUSY); 301 vfs_file_put(mp); 378 302 fibril_rwlock_write_unlock(&namespace_rwlock); 379 vfs_node_put(mp_node); 380 free(mp); 381 async_answer_0(rid, EBUSY); 382 return; 383 } 384 385 /* Unmount the filesystem. */ 386 async_exch_t *exch = vfs_exchange_grab(mp_node->mount->fs_handle); 387 rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, mp_node->mount->service_id); 303 return; 304 } 305 306 async_exch_t *exch = vfs_exchange_grab(mp->node->mount->fs_handle); 307 int rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, mp->node->mount->service_id); 388 308 vfs_exchange_release(exch); 389 309 390 vfs_node_forget(mp_node->mount); 391 mp_node->mount = NULL; 392 393 vfs_node_put(mp_node); 310 if (rc != EOK) { 311 async_answer_0(rid, rc); 312 vfs_file_put(mp); 313 fibril_rwlock_write_unlock(&namespace_rwlock); 314 return; 315 } 316 317 vfs_node_forget(mp->node->mount); 318 vfs_node_put(mp->node); 319 mp->node->mount = NULL; 320 394 321 fibril_rwlock_write_unlock(&namespace_rwlock); 395 322 … … 398 325 399 326 list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) { 400 if (str_cmp(mtab_ent->mp, mp) == 0) { 327 // FIXME: mp name 328 if (str_cmp(mtab_ent->mp, "fixme") == 0) { 401 329 list_remove(&mtab_ent->link); 402 330 mtab_size--; … … 408 336 assert(found); 409 337 fibril_mutex_unlock(&mtab_list_lock); 410 411 free(mp); 412 338 339 vfs_file_put(mp); 413 340 async_answer_0(rid, EOK); 414 return;415 341 } 416 342 … … 448 374 if (flags&WALK_DIRECTORY) { 449 375 lflags |= L_DIRECTORY; 376 } 377 if (flags&WALK_MOUNT_POINT) { 378 lflags |= L_MP; 450 379 } 451 380 return lflags; … … 470 399 471 400 /* Lookup the file structure corresponding to the file descriptor. */ 472 vfs_file_t *parent = NULL; 473 vfs_node_t *parent_node = root; 474 // TODO: Client-side root. 475 if (parentfd != -1) { 476 parent = vfs_file_get(parentfd); 477 if (!parent) { 478 free(path); 479 async_answer_0(rid, EBADF); 480 return; 481 } 482 parent_node = parent->node; 401 vfs_file_t *parent = vfs_file_get(parentfd); 402 if (!parent) { 403 free(path); 404 async_answer_0(rid, EBADF); 405 return; 483 406 } 484 407 … … 486 409 487 410 vfs_lookup_res_t lr; 488 rc = vfs_lookup_internal(parent _node, path, walk_lookup_flags(flags), &lr);411 rc = vfs_lookup_internal(parent->node, path, walk_lookup_flags(flags), &lr); 489 412 free(path); 490 413 … … 963 886 vfs_file_t *parent = NULL; 964 887 vfs_file_t *expect = NULL; 965 vfs_node_t *parent_node = root;966 888 967 889 int parentfd = IPC_GET_ARG1(*request); … … 974 896 return; 975 897 } 898 if (parentfd == expectfd) { 899 async_answer_0(rid, EINVAL); 900 return; 901 } 976 902 977 903 fibril_rwlock_write_lock(&namespace_rwlock); … … 980 906 981 907 /* Files are retrieved in order of file descriptors, to prevent deadlock. */ 982 if (parentfd >= 0 && parentfd< expectfd) {908 if (parentfd < expectfd) { 983 909 parent = vfs_file_get(parentfd); 984 910 if (!parent) { 985 rc = E NOENT;911 rc = EBADF; 986 912 goto exit; 987 913 } … … 996 922 } 997 923 998 if (parentfd > = 0 && parentfd >=expectfd) {924 if (parentfd > expectfd) { 999 925 parent = vfs_file_get(parentfd); 1000 926 if (!parent) { 1001 rc = E NOENT;927 rc = EBADF; 1002 928 goto exit; 1003 929 } 1004 930 } 1005 931 1006 if (parent) { 1007 parent_node = parent->node; 1008 } 932 assert(parent != NULL); 1009 933 1010 934 if (expectfd >= 0) { 1011 935 vfs_lookup_res_t lr; 1012 rc = vfs_lookup_internal(parent _node, path, lflag, &lr);936 rc = vfs_lookup_internal(parent->node, path, lflag, &lr); 1013 937 if (rc != EOK) { 1014 938 goto exit; … … 1026 950 1027 951 vfs_lookup_res_t lr; 1028 rc = vfs_lookup_internal(parent _node, path, lflag | L_UNLINK, &lr);952 rc = vfs_lookup_internal(parent->node, path, lflag | L_UNLINK, &lr); 1029 953 if (rc != EOK) { 1030 954 goto exit; … … 1188 1112 1189 1113 /* Lookup the file structure corresponding to the file descriptor. */ 1190 vfs_node_t *base_node = root; 1191 // TODO: Client-side root. 1192 if (basefd != -1) { 1193 base = vfs_file_get(basefd); 1194 if (!base) { 1195 rc = EBADF; 1196 goto out; 1197 } 1198 base_node = base->node; 1199 } 1200 1201 rc = vfs_rename_internal(base_node, oldc, newc); 1114 base = vfs_file_get(basefd); 1115 if (!base) { 1116 rc = EBADF; 1117 goto out; 1118 } 1119 1120 rc = vfs_rename_internal(base->node, oldc, newc); 1202 1121 1203 1122 out: … … 1358 1277 /* Lookup the file structure corresponding to fd. */ 1359 1278 vfs_file_t *oldfile = vfs_file_get(oldfd); 1360 if ( !oldfile) {1279 if (oldfile == NULL) { 1361 1280 async_answer_0(rid, EBADF); 1362 1281 return; … … 1365 1284 vfs_file_t *newfile; 1366 1285 int newfd = vfs_fd_alloc(&newfile, desc); 1286 async_answer_0(rid, newfd); 1287 1367 1288 if (newfd < 0) { 1368 async_answer_0(rid, newfd);1369 1289 vfs_file_put(oldfile); 1370 1290 return; … … 1379 1299 vfs_file_put(oldfile); 1380 1300 vfs_file_put(newfile); 1381 1382 async_answer_0(rid, newfd);1383 1301 } 1384 1302
Note:
See TracChangeset
for help on using the changeset viewer.