Changeset 5126f80 in mainline for uspace/lib/c/generic/vfs/vfs.c
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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;
Note:
See TracChangeset
for help on using the changeset viewer.