Changes in uspace/srv/vfs/vfs_ops.c [5bb9907:ccca251] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_ops.c
r5bb9907 rccca251 76 76 vfs_node_t *mr_node; 77 77 fs_index_t rindex; 78 aoff64_t rsize;78 size_t rsize; 79 79 unsigned rlnkcnt; 80 async_exch_t *exch;81 80 sysarg_t rc; 81 int phone; 82 82 aid_t msg; 83 83 ipc_call_t answer; … … 123 123 124 124 /* Tell the mountee that it is being mounted. */ 125 exch = vfs_exchange_grab(fs_handle);126 msg = async_send_1( exch, VFS_OUT_MOUNTED,125 phone = vfs_grab_phone(fs_handle); 126 msg = async_send_1(phone, VFS_OUT_MOUNTED, 127 127 (sysarg_t) devmap_handle, &answer); 128 /* Send the mount options */129 rc = async_data_write_start( exch, (void *)opts,128 /* send the mount options */ 129 rc = async_data_write_start(phone, (void *)opts, 130 130 str_size(opts)); 131 vfs_exchange_release(exch);132 133 131 if (rc != EOK) { 134 132 async_wait_for(msg, NULL); 133 vfs_release_phone(fs_handle, phone); 135 134 fibril_rwlock_write_unlock(&namespace_rwlock); 136 135 async_answer_0(rid, rc); … … 138 137 } 139 138 async_wait_for(msg, &rc); 139 vfs_release_phone(fs_handle, phone); 140 140 141 141 if (rc != EOK) { … … 146 146 147 147 rindex = (fs_index_t) IPC_GET_ARG1(answer); 148 rsize = ( aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));149 rlnkcnt = (unsigned) IPC_GET_ARG 4(answer);148 rsize = (size_t) IPC_GET_ARG2(answer); 149 rlnkcnt = (unsigned) IPC_GET_ARG3(answer); 150 150 151 151 mr_res.triplet.fs_handle = fs_handle; … … 182 182 */ 183 183 184 async_exch_t *mountee_exch = vfs_exchange_grab(fs_handle);185 assert(mountee_ exch);186 187 exch = vfs_exchange_grab(mp_res.triplet.fs_handle);188 msg = async_send_4( exch, VFS_OUT_MOUNT,184 int mountee_phone = vfs_grab_phone(fs_handle); 185 assert(mountee_phone >= 0); 186 187 phone = vfs_grab_phone(mp_res.triplet.fs_handle); 188 msg = async_send_4(phone, VFS_OUT_MOUNT, 189 189 (sysarg_t) mp_res.triplet.devmap_handle, 190 190 (sysarg_t) mp_res.triplet.index, … … 192 192 (sysarg_t) devmap_handle, &answer); 193 193 194 /* Send connection */ 195 rc = async_exchange_clone(exch, mountee_exch); 196 vfs_exchange_release(mountee_exch); 197 198 if (rc != EOK) { 199 vfs_exchange_release(exch); 194 /* send connection */ 195 rc = async_req_1_0(phone, IPC_M_CONNECTION_CLONE, mountee_phone); 196 if (rc != EOK) { 200 197 async_wait_for(msg, NULL); 201 198 vfs_release_phone(fs_handle, mountee_phone); 199 vfs_release_phone(mp_res.triplet.fs_handle, phone); 202 200 /* Mount failed, drop reference to mp_node. */ 203 201 if (mp_node) 204 202 vfs_node_put(mp_node); 205 206 203 async_answer_0(rid, rc); 207 204 fibril_rwlock_write_unlock(&namespace_rwlock); 208 205 return; 209 206 } 207 208 vfs_release_phone(fs_handle, mountee_phone); 210 209 211 210 /* send the mount options */ 212 rc = async_data_write_start(exch, (void *) opts, str_size(opts)); 213 if (rc != EOK) { 214 vfs_exchange_release(exch); 211 rc = async_data_write_start(phone, (void *)opts, str_size(opts)); 212 if (rc != EOK) { 215 213 async_wait_for(msg, NULL); 216 214 vfs_release_phone(mp_res.triplet.fs_handle, phone); 217 215 /* Mount failed, drop reference to mp_node. */ 218 216 if (mp_node) 219 217 vfs_node_put(mp_node); 220 221 218 fibril_rwlock_write_unlock(&namespace_rwlock); 222 219 async_answer_0(rid, rc); 223 220 return; 224 221 } 225 226 vfs_exchange_release(exch);227 222 async_wait_for(msg, &rc); 223 vfs_release_phone(mp_res.triplet.fs_handle, phone); 228 224 229 225 if (rc == EOK) { 230 226 rindex = (fs_index_t) IPC_GET_ARG1(answer); 231 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), 232 IPC_GET_ARG3(answer)); 233 rlnkcnt = (unsigned) IPC_GET_ARG4(answer); 234 227 rsize = (size_t) IPC_GET_ARG2(answer); 228 rlnkcnt = (unsigned) IPC_GET_ARG3(answer); 229 235 230 mr_res.triplet.fs_handle = fs_handle; 236 231 mr_res.triplet.devmap_handle = devmap_handle; … … 239 234 mr_res.lnkcnt = rlnkcnt; 240 235 mr_res.type = VFS_NODE_DIRECTORY; 241 236 242 237 /* Add reference to the mounted root. */ 243 238 mr_node = vfs_node_get(&mr_res); … … 248 243 vfs_node_put(mp_node); 249 244 } 250 245 251 246 async_answer_0(rid, rc); 252 247 fibril_rwlock_write_unlock(&namespace_rwlock); … … 308 303 309 304 /* 310 * Wait for VFS_IN_PING so that we can return an error if we don't know305 * Wait for IPC_M_PING so that we can return an error if we don't know 311 306 * fs_name. 312 307 */ 313 308 ipc_call_t data; 314 309 ipc_callid_t callid = async_get_call(&data); 315 if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {310 if (IPC_GET_IMETHOD(data) != IPC_M_PING) { 316 311 async_answer_0(callid, ENOTSUP); 317 312 async_answer_0(rid, ENOTSUP); … … 326 321 * This will also give us its file system handle. 327 322 */ 328 fibril_mutex_lock(&fs_ list_lock);323 fibril_mutex_lock(&fs_head_lock); 329 324 fs_handle_t fs_handle; 330 325 recheck: … … 332 327 if (!fs_handle) { 333 328 if (flags & IPC_FLAG_BLOCKING) { 334 fibril_condvar_wait(&fs_ list_cv, &fs_list_lock);329 fibril_condvar_wait(&fs_head_cv, &fs_head_lock); 335 330 goto recheck; 336 331 } 337 332 338 fibril_mutex_unlock(&fs_ list_lock);333 fibril_mutex_unlock(&fs_head_lock); 339 334 async_answer_0(callid, ENOENT); 340 335 async_answer_0(rid, ENOENT); … … 344 339 return; 345 340 } 346 fibril_mutex_unlock(&fs_ list_lock);341 fibril_mutex_unlock(&fs_head_lock); 347 342 348 343 /* Acknowledge that we know fs_name. */ … … 363 358 vfs_lookup_res_t mr_res; 364 359 vfs_node_t *mr_node; 365 async_exch_t *exch;366 360 int phone; 361 367 362 /* 368 363 * Receive the mount point path. … … 372 367 if (rc != EOK) 373 368 async_answer_0(rid, rc); 374 369 375 370 /* 376 371 * Taking the namespace lock will do two things for us. First, it will … … 400 395 return; 401 396 } 402 397 403 398 /* 404 399 * Count the total number of references for the mounted file system. We … … 416 411 return; 417 412 } 418 413 419 414 if (str_cmp(mp, "/") == 0) { 420 415 421 416 /* 422 417 * Unmounting the root file system. … … 425 420 * VFS_OUT_UNMOUNTED directly to the mounted file system. 426 421 */ 427 422 428 423 free(mp); 429 430 exch = vfs_exchange_grab(mr_node->fs_handle); 431 rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, 424 phone = vfs_grab_phone(mr_node->fs_handle); 425 rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED, 432 426 mr_node->devmap_handle); 433 vfs_exchange_release(exch); 434 427 vfs_release_phone(mr_node->fs_handle, phone); 435 428 if (rc != EOK) { 436 429 fibril_rwlock_write_unlock(&namespace_rwlock); … … 439 432 return; 440 433 } 441 442 434 rootfs.fs_handle = 0; 443 435 rootfs.devmap_handle = 0; 444 436 } else { 445 437 446 438 /* 447 439 * Unmounting a non-root file system. … … 450 442 * file system, so we delegate the operation to it. 451 443 */ 452 444 453 445 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL); 454 446 free(mp); … … 459 451 return; 460 452 } 461 462 453 vfs_node_t *mp_node = vfs_node_get(&mp_res); 463 454 if (!mp_node) { … … 467 458 return; 468 459 } 469 470 exch = vfs_exchange_grab(mp_node->fs_handle);471 rc = async_req_2_0( exch, VFS_OUT_UNMOUNT,460 461 phone = vfs_grab_phone(mp_node->fs_handle); 462 rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, 472 463 mp_node->devmap_handle, mp_node->index); 473 vfs_exchange_release(exch); 474 464 vfs_release_phone(mp_node->fs_handle, phone); 475 465 if (rc != EOK) { 476 466 fibril_rwlock_write_unlock(&namespace_rwlock); … … 480 470 return; 481 471 } 482 472 483 473 /* Drop the reference we got above. */ 484 474 vfs_node_put(mp_node); … … 486 476 vfs_node_put(mp_node); 487 477 } 488 478 479 489 480 /* 490 481 * All went well, the mounted file system was successfully unmounted. … … 492 483 */ 493 484 vfs_node_forget(mr_node); 494 485 495 486 fibril_rwlock_write_unlock(&namespace_rwlock); 496 487 async_answer_0(rid, EOK); … … 707 698 */ 708 699 fibril_mutex_lock(&file->lock); 709 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);700 int fs_phone = vfs_grab_phone(file->node->fs_handle); 710 701 711 702 /* Make a VFS_OUT_SYMC request at the destination FS server. */ 712 703 aid_t msg; 713 704 ipc_call_t answer; 714 msg = async_send_2(fs_ exch, VFS_OUT_SYNC, file->node->devmap_handle,705 msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->devmap_handle, 715 706 file->node->index, &answer); 716 717 vfs_exchange_release(fs_exch); 718 707 719 708 /* Wait for reply from the FS server. */ 720 709 sysarg_t rc; 721 710 async_wait_for(msg, &rc); 722 711 712 vfs_release_phone(file->node->fs_handle, fs_phone); 723 713 fibril_mutex_unlock(&file->lock); 724 714 725 715 vfs_file_put(file); 726 716 async_answer_0(rid, rc); 727 717 } 728 718 719 int vfs_close_internal(vfs_file_t *file) 720 { 721 /* 722 * Lock the open file structure so that no other thread can manipulate 723 * the same open file at a time. 724 */ 725 fibril_mutex_lock(&file->lock); 726 727 if (file->refcnt <= 1) { 728 /* Only close the file on the destination FS server 729 if there are no more file descriptors (except the 730 present one) pointing to this file. */ 731 732 int fs_phone = vfs_grab_phone(file->node->fs_handle); 733 734 /* Make a VFS_OUT_CLOSE request at the destination FS server. */ 735 aid_t msg; 736 ipc_call_t answer; 737 msg = async_send_2(fs_phone, VFS_OUT_CLOSE, 738 file->node->devmap_handle, file->node->index, &answer); 739 740 /* Wait for reply from the FS server. */ 741 sysarg_t rc; 742 async_wait_for(msg, &rc); 743 744 vfs_release_phone(file->node->fs_handle, fs_phone); 745 fibril_mutex_unlock(&file->lock); 746 747 return IPC_GET_ARG1(answer); 748 } 749 750 fibril_mutex_unlock(&file->lock); 751 return EOK; 752 } 753 729 754 void vfs_close(ipc_callid_t rid, ipc_call_t *request) 730 755 { 731 756 int fd = IPC_GET_ARG1(*request); 732 int ret = vfs_fd_free(fd); 757 758 /* Lookup the file structure corresponding to the file descriptor. */ 759 vfs_file_t *file = vfs_file_get(fd); 760 if (!file) { 761 async_answer_0(rid, ENOENT); 762 return; 763 } 764 765 int ret = vfs_close_internal(file); 766 if (ret != EOK) 767 async_answer_0(rid, ret); 768 769 vfs_file_put(file); 770 ret = vfs_fd_free(fd); 733 771 async_answer_0(rid, ret); 734 772 } … … 736 774 static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read) 737 775 { 776 vfs_info_t *vi; 777 738 778 /* 739 779 * The following code strongly depends on the fact that the files data … … 745 785 * open files supports parallel access! 746 786 */ 747 787 748 788 int fd = IPC_GET_ARG1(*request); 749 789 … … 760 800 */ 761 801 fibril_mutex_lock(&file->lock); 762 763 v fs_info_t *fs_info= fs_handle_to_info(file->node->fs_handle);764 assert( fs_info);765 802 803 vi = fs_handle_to_info(file->node->fs_handle); 804 assert(vi); 805 766 806 /* 767 807 * Lock the file's node so that no other client can read/write to it at … … 769 809 * write implementation does not modify the file size. 770 810 */ 771 if ((read) || 772 ((fs_info->concurrent_read_write) && (fs_info->write_retains_size))) 811 if (read || (vi->concurrent_read_write && vi->write_retains_size)) 773 812 fibril_rwlock_read_lock(&file->node->contents_rwlock); 774 813 else 775 814 fibril_rwlock_write_lock(&file->node->contents_rwlock); 776 815 777 816 if (file->node->type == VFS_NODE_DIRECTORY) { 778 817 /* … … 784 823 } 785 824 786 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);825 int fs_phone = vfs_grab_phone(file->node->fs_handle); 787 826 788 827 /* … … 796 835 ipc_call_t answer; 797 836 if (read) { 798 rc = async_data_read_forward_ 4_1(fs_exch, VFS_OUT_READ,799 file->node->devmap_handle, file->node->index, 800 LOWER32(file->pos), UPPER32(file->pos),&answer);837 rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ, 838 file->node->devmap_handle, file->node->index, file->pos, 839 &answer); 801 840 } else { 802 841 if (file->append) 803 842 file->pos = file->node->size; 804 843 805 rc = async_data_write_forward_ 4_1(fs_exch, VFS_OUT_WRITE,806 file->node->devmap_handle, file->node->index, 807 LOWER32(file->pos), UPPER32(file->pos),&answer);808 } 809 810 vfs_ exchange_release(fs_exch);844 rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE, 845 file->node->devmap_handle, file->node->index, file->pos, 846 &answer); 847 } 848 849 vfs_release_phone(file->node->fs_handle, fs_phone); 811 850 812 851 size_t bytes = IPC_GET_ARG1(answer); … … 816 855 817 856 /* Unlock the VFS node. */ 818 if ((read) || 819 ((fs_info->concurrent_read_write) && (fs_info->write_retains_size))) 857 if (read || (vi->concurrent_read_write && vi->write_retains_size)) 820 858 fibril_rwlock_read_unlock(&file->node->contents_rwlock); 821 859 else { 822 860 /* Update the cached version of node's size. */ 823 861 if (rc == EOK) 824 file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer), 825 IPC_GET_ARG3(answer)); 862 file->node->size = IPC_GET_ARG2(answer); 826 863 fibril_rwlock_write_unlock(&file->node->contents_rwlock); 827 864 } … … 938 975 fs_index_t index, aoff64_t size) 939 976 { 940 async_exch_t *exch = vfs_exchange_grab(fs_handle); 941 sysarg_t rc = async_req_4_0(exch, VFS_OUT_TRUNCATE, 942 (sysarg_t) devmap_handle, (sysarg_t) index, LOWER32(size), 943 UPPER32(size)); 944 vfs_exchange_release(exch); 945 946 return (int) rc; 977 sysarg_t rc; 978 int fs_phone; 979 980 fs_phone = vfs_grab_phone(fs_handle); 981 rc = async_req_4_0(fs_phone, VFS_OUT_TRUNCATE, (sysarg_t) devmap_handle, 982 (sysarg_t) index, LOWER32(size), UPPER32(size)); 983 vfs_release_phone(fs_handle, fs_phone); 984 return (int)rc; 947 985 } 948 986 … … 994 1032 fibril_mutex_lock(&file->lock); 995 1033 996 async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);1034 int fs_phone = vfs_grab_phone(file->node->fs_handle); 997 1035 998 1036 aid_t msg; 999 msg = async_send_3( exch, VFS_OUT_STAT, file->node->devmap_handle,1037 msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->devmap_handle, 1000 1038 file->node->index, true, NULL); 1001 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1002 1003 vfs_exchange_release(exch); 1004 1039 async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1005 1040 async_wait_for(msg, &rc); 1006 1041 vfs_release_phone(file->node->fs_handle, fs_phone); 1042 1007 1043 fibril_mutex_unlock(&file->lock); 1008 1044 vfs_file_put(file); … … 1047 1083 fibril_rwlock_read_unlock(&namespace_rwlock); 1048 1084 1049 async_exch_t *exch = vfs_exchange_grab(node->fs_handle); 1050 1085 int fs_phone = vfs_grab_phone(node->fs_handle); 1051 1086 aid_t msg; 1052 msg = async_send_3( exch, VFS_OUT_STAT, node->devmap_handle,1087 msg = async_send_3(fs_phone, VFS_OUT_STAT, node->devmap_handle, 1053 1088 node->index, false, NULL); 1054 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1055 1056 vfs_exchange_release(exch); 1089 async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1057 1090 1058 1091 sysarg_t rv; 1059 1092 async_wait_for(msg, &rv); 1093 vfs_release_phone(node->fs_handle, fs_phone); 1060 1094 1061 1095 async_answer_0(rid, rv); … … 1335 1369 fibril_mutex_lock(&oldfile->lock); 1336 1370 1337 /* Make sure newfd is closed. */ 1338 (void) vfs_fd_free(newfd); 1371 /* Lookup an open file structure possibly corresponding to newfd. */ 1372 vfs_file_t *newfile = vfs_file_get(newfd); 1373 if (newfile) { 1374 /* Close the originally opened file. */ 1375 int ret = vfs_close_internal(newfile); 1376 if (ret != EOK) { 1377 fibril_mutex_unlock(&oldfile->lock); 1378 vfs_file_put(oldfile); 1379 vfs_file_put(newfile); 1380 async_answer_0(rid, ret); 1381 return; 1382 } 1383 1384 ret = vfs_fd_free(newfd); 1385 if (ret != EOK) { 1386 fibril_mutex_unlock(&oldfile->lock); 1387 vfs_file_put(oldfile); 1388 vfs_file_put(newfile); 1389 async_answer_0(rid, ret); 1390 return; 1391 } 1392 vfs_file_put(newfile); 1393 } 1339 1394 1340 1395 /* Assign the old file to newfd. */
Note:
See TracChangeset
for help on using the changeset viewer.