Changes in uspace/srv/vfs/vfs_ops.c [e6da6d5:ccca251] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_ops.c
re6da6d5 rccca251 52 52 #include <assert.h> 53 53 #include <vfs/canonify.h> 54 #include <vfs/vfs_mtab.h>55 56 FIBRIL_MUTEX_INITIALIZE(mtab_list_lock);57 LIST_INITIALIZE(mtab_list);58 static size_t mtab_size = 0;59 54 60 55 /* Forward declarations of static functions. */ 61 static int vfs_truncate_internal(fs_handle_t, service_id_t, fs_index_t,56 static int vfs_truncate_internal(fs_handle_t, devmap_handle_t, fs_index_t, 62 57 aoff64_t); 63 58 … … 70 65 vfs_pair_t rootfs = { 71 66 .fs_handle = 0, 72 . service_id= 067 .devmap_handle = 0 73 68 }; 74 69 75 static int vfs_mount_internal(ipc_callid_t rid, service_id_t service_id,70 static void vfs_mount_internal(ipc_callid_t rid, devmap_handle_t devmap_handle, 76 71 fs_handle_t fs_handle, char *mp, char *opts) 77 72 { … … 81 76 vfs_node_t *mr_node; 82 77 fs_index_t rindex; 83 aoff64_t rsize;78 size_t rsize; 84 79 unsigned rlnkcnt; 85 async_exch_t *exch;86 80 sysarg_t rc; 81 int phone; 87 82 aid_t msg; 88 83 ipc_call_t answer; … … 96 91 fibril_rwlock_write_unlock(&namespace_rwlock); 97 92 async_answer_0(rid, EBUSY); 98 return EBUSY;93 return; 99 94 } 100 95 … … 104 99 fibril_rwlock_write_unlock(&namespace_rwlock); 105 100 async_answer_0(rid, rc); 106 return rc;101 return; 107 102 } 108 103 … … 111 106 fibril_rwlock_write_unlock(&namespace_rwlock); 112 107 async_answer_0(rid, ENOMEM); 113 return ENOMEM;108 return; 114 109 } 115 110 … … 128 123 129 124 /* Tell the mountee that it is being mounted. */ 130 exch = vfs_exchange_grab(fs_handle);131 msg = async_send_1( exch, VFS_OUT_MOUNTED,132 (sysarg_t) service_id, &answer);133 /* Send the mount options */134 rc = async_data_write_start( exch, (void *)opts,125 phone = vfs_grab_phone(fs_handle); 126 msg = async_send_1(phone, VFS_OUT_MOUNTED, 127 (sysarg_t) devmap_handle, &answer); 128 /* send the mount options */ 129 rc = async_data_write_start(phone, (void *)opts, 135 130 str_size(opts)); 136 vfs_exchange_release(exch);137 138 131 if (rc != EOK) { 139 132 async_wait_for(msg, NULL); 133 vfs_release_phone(fs_handle, phone); 140 134 fibril_rwlock_write_unlock(&namespace_rwlock); 141 135 async_answer_0(rid, rc); 142 return rc;136 return; 143 137 } 144 138 async_wait_for(msg, &rc); 139 vfs_release_phone(fs_handle, phone); 145 140 146 141 if (rc != EOK) { 147 142 fibril_rwlock_write_unlock(&namespace_rwlock); 148 143 async_answer_0(rid, rc); 149 return rc;144 return; 150 145 } 151 146 152 147 rindex = (fs_index_t) IPC_GET_ARG1(answer); 153 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), 154 IPC_GET_ARG3(answer)); 155 rlnkcnt = (unsigned) IPC_GET_ARG4(answer); 148 rsize = (size_t) IPC_GET_ARG2(answer); 149 rlnkcnt = (unsigned) IPC_GET_ARG3(answer); 156 150 157 151 mr_res.triplet.fs_handle = fs_handle; 158 mr_res.triplet. service_id = service_id;152 mr_res.triplet.devmap_handle = devmap_handle; 159 153 mr_res.triplet.index = rindex; 160 154 mr_res.size = rsize; … … 163 157 164 158 rootfs.fs_handle = fs_handle; 165 rootfs. service_id = service_id;159 rootfs.devmap_handle = devmap_handle; 166 160 167 161 /* Add reference to the mounted root. */ … … 171 165 fibril_rwlock_write_unlock(&namespace_rwlock); 172 166 async_answer_0(rid, rc); 173 return rc;167 return; 174 168 } else { 175 169 /* … … 179 173 fibril_rwlock_write_unlock(&namespace_rwlock); 180 174 async_answer_0(rid, ENOENT); 181 return ENOENT;182 } 183 } 184 185 /* 186 * At this point, we have all necessary pieces: file system handle187 * and service ID, and we know the mount point VFS node.188 */ 189 190 async_exch_t *mountee_exch = vfs_exchange_grab(fs_handle);191 assert(mountee_ exch);192 193 exch = vfs_exchange_grab(mp_res.triplet.fs_handle);194 msg = async_send_4( exch, VFS_OUT_MOUNT,195 (sysarg_t) mp_res.triplet. service_id,175 return; 176 } 177 } 178 179 /* 180 * At this point, we have all necessary pieces: file system and device 181 * handles, and we know the mount point VFS node. 182 */ 183 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 (sysarg_t) mp_res.triplet.devmap_handle, 196 190 (sysarg_t) mp_res.triplet.index, 197 191 (sysarg_t) fs_handle, 198 (sysarg_t) service_id, &answer); 199 200 /* Send connection */ 201 rc = async_exchange_clone(exch, mountee_exch); 202 vfs_exchange_release(mountee_exch); 203 204 if (rc != EOK) { 205 vfs_exchange_release(exch); 192 (sysarg_t) devmap_handle, &answer); 193 194 /* send connection */ 195 rc = async_req_1_0(phone, IPC_M_CONNECTION_CLONE, mountee_phone); 196 if (rc != EOK) { 206 197 async_wait_for(msg, NULL); 207 198 vfs_release_phone(fs_handle, mountee_phone); 199 vfs_release_phone(mp_res.triplet.fs_handle, phone); 208 200 /* Mount failed, drop reference to mp_node. */ 209 201 if (mp_node) 210 202 vfs_node_put(mp_node); 211 212 203 async_answer_0(rid, rc); 213 204 fibril_rwlock_write_unlock(&namespace_rwlock); 214 return rc; 215 } 205 return; 206 } 207 208 vfs_release_phone(fs_handle, mountee_phone); 216 209 217 210 /* send the mount options */ 218 rc = async_data_write_start(exch, (void *) opts, str_size(opts)); 219 if (rc != EOK) { 220 vfs_exchange_release(exch); 211 rc = async_data_write_start(phone, (void *)opts, str_size(opts)); 212 if (rc != EOK) { 221 213 async_wait_for(msg, NULL); 222 214 vfs_release_phone(mp_res.triplet.fs_handle, phone); 223 215 /* Mount failed, drop reference to mp_node. */ 224 216 if (mp_node) 225 217 vfs_node_put(mp_node); 226 227 218 fibril_rwlock_write_unlock(&namespace_rwlock); 228 219 async_answer_0(rid, rc); 229 return rc; 230 } 231 232 /* 233 * Wait for the answer before releasing the exchange to avoid deadlock 234 * in case the answer depends on further calls to the same file system. 235 * Think of a case when mounting a FS on a file_bd backed by a file on 236 * the same FS. 237 */ 220 return; 221 } 238 222 async_wait_for(msg, &rc); 239 vfs_ exchange_release(exch);223 vfs_release_phone(mp_res.triplet.fs_handle, phone); 240 224 241 225 if (rc == EOK) { 242 226 rindex = (fs_index_t) IPC_GET_ARG1(answer); 243 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), 244 IPC_GET_ARG3(answer)); 245 rlnkcnt = (unsigned) IPC_GET_ARG4(answer); 246 227 rsize = (size_t) IPC_GET_ARG2(answer); 228 rlnkcnt = (unsigned) IPC_GET_ARG3(answer); 229 247 230 mr_res.triplet.fs_handle = fs_handle; 248 mr_res.triplet. service_id = service_id;231 mr_res.triplet.devmap_handle = devmap_handle; 249 232 mr_res.triplet.index = rindex; 250 233 mr_res.size = rsize; 251 234 mr_res.lnkcnt = rlnkcnt; 252 235 mr_res.type = VFS_NODE_DIRECTORY; 253 236 254 237 /* Add reference to the mounted root. */ 255 238 mr_node = vfs_node_get(&mr_res); … … 260 243 vfs_node_put(mp_node); 261 244 } 262 245 263 246 async_answer_0(rid, rc); 264 247 fibril_rwlock_write_unlock(&namespace_rwlock); 265 return rc;266 248 } 267 249 268 250 void vfs_mount(ipc_callid_t rid, ipc_call_t *request) 269 251 { 270 service_id_t service_id;252 devmap_handle_t devmap_handle; 271 253 272 254 /* … … 275 257 * in the request. 276 258 */ 277 service_id = (service_id_t) IPC_GET_ARG1(*request);259 devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 278 260 279 261 /* … … 283 265 284 266 /* 285 * Instance number is passed as ARG3.286 * /287 unsigned int instance = IPC_GET_ARG3(*request);288 267 * For now, don't make use of ARG3, but it can be used to 268 * carry mount options in the future. 269 */ 270 289 271 /* We want the client to send us the mount point. */ 290 272 char *mp; … … 321 303 322 304 /* 323 * 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 324 306 * fs_name. 325 307 */ 326 308 ipc_call_t data; 327 309 ipc_callid_t callid = async_get_call(&data); 328 if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {310 if (IPC_GET_IMETHOD(data) != IPC_M_PING) { 329 311 async_answer_0(callid, ENOTSUP); 330 312 async_answer_0(rid, ENOTSUP); … … 339 321 * This will also give us its file system handle. 340 322 */ 341 fibril_mutex_lock(&fs_ list_lock);323 fibril_mutex_lock(&fs_head_lock); 342 324 fs_handle_t fs_handle; 343 325 recheck: 344 fs_handle = fs_name_to_handle( instance,fs_name, false);326 fs_handle = fs_name_to_handle(fs_name, false); 345 327 if (!fs_handle) { 346 328 if (flags & IPC_FLAG_BLOCKING) { 347 fibril_condvar_wait(&fs_ list_cv, &fs_list_lock);329 fibril_condvar_wait(&fs_head_cv, &fs_head_lock); 348 330 goto recheck; 349 331 } 350 332 351 fibril_mutex_unlock(&fs_ list_lock);333 fibril_mutex_unlock(&fs_head_lock); 352 334 async_answer_0(callid, ENOENT); 353 335 async_answer_0(rid, ENOENT); … … 357 339 return; 358 340 } 359 fibril_mutex_unlock(&fs_list_lock); 360 361 /* Add the filesystem info to the list of mounted filesystems */ 362 mtab_ent_t *mtab_ent = malloc(sizeof(mtab_ent_t)); 363 if (!mtab_ent) { 364 async_answer_0(callid, ENOMEM); 365 async_answer_0(rid, ENOMEM); 366 free(mp); 367 free(fs_name); 368 free(opts); 369 return; 370 } 371 341 fibril_mutex_unlock(&fs_head_lock); 342 343 /* Acknowledge that we know fs_name. */ 344 async_answer_0(callid, EOK); 345 372 346 /* Do the mount */ 373 rc = vfs_mount_internal(rid, service_id, fs_handle, mp, opts); 374 if (rc != EOK) { 375 async_answer_0(callid, ENOTSUP); 376 async_answer_0(rid, ENOTSUP); 377 free(mtab_ent); 378 free(mp); 379 free(opts); 380 free(fs_name); 381 return; 382 } 383 384 /* Add the filesystem info to the list of mounted filesystems */ 385 386 str_cpy(mtab_ent->mp, MAX_PATH_LEN, mp); 387 str_cpy(mtab_ent->fs_name, FS_NAME_MAXLEN, fs_name); 388 str_cpy(mtab_ent->opts, MAX_MNTOPTS_LEN, opts); 389 mtab_ent->instance = instance; 390 mtab_ent->service_id = service_id; 391 392 link_initialize(&mtab_ent->link); 393 394 fibril_mutex_lock(&mtab_list_lock); 395 list_append(&mtab_ent->link, &mtab_list); 396 mtab_size++; 397 fibril_mutex_unlock(&mtab_list_lock); 398 347 vfs_mount_internal(rid, devmap_handle, fs_handle, mp, opts); 399 348 free(mp); 400 349 free(fs_name); 401 350 free(opts); 402 403 /* Acknowledge that we know fs_name. */404 async_answer_0(callid, EOK);405 351 } 406 352 … … 412 358 vfs_lookup_res_t mr_res; 413 359 vfs_node_t *mr_node; 414 async_exch_t *exch;415 360 int phone; 361 416 362 /* 417 363 * Receive the mount point path. … … 421 367 if (rc != EOK) 422 368 async_answer_0(rid, rc); 423 369 424 370 /* 425 371 * Taking the namespace lock will do two things for us. First, it will … … 449 395 return; 450 396 } 451 397 452 398 /* 453 399 * Count the total number of references for the mounted file system. We … … 458 404 */ 459 405 if (vfs_nodes_refcount_sum_get(mr_node->fs_handle, 460 mr_node-> service_id) != 2) {406 mr_node->devmap_handle) != 2) { 461 407 fibril_rwlock_write_unlock(&namespace_rwlock); 462 408 vfs_node_put(mr_node); … … 465 411 return; 466 412 } 467 413 468 414 if (str_cmp(mp, "/") == 0) { 469 415 470 416 /* 471 417 * Unmounting the root file system. … … 474 420 * VFS_OUT_UNMOUNTED directly to the mounted file system. 475 421 */ 476 477 exch = vfs_exchange_grab(mr_node->fs_handle);478 rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED,479 mr_node->service_id);480 vfs_exchange_release(exch);481 422 423 free(mp); 424 phone = vfs_grab_phone(mr_node->fs_handle); 425 rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED, 426 mr_node->devmap_handle); 427 vfs_release_phone(mr_node->fs_handle, phone); 482 428 if (rc != EOK) { 483 429 fibril_rwlock_write_unlock(&namespace_rwlock); 484 free(mp);485 430 vfs_node_put(mr_node); 486 431 async_answer_0(rid, rc); 487 432 return; 488 433 } 489 490 434 rootfs.fs_handle = 0; 491 rootfs. service_id= 0;435 rootfs.devmap_handle = 0; 492 436 } else { 493 437 494 438 /* 495 439 * Unmounting a non-root file system. … … 498 442 * file system, so we delegate the operation to it. 499 443 */ 500 444 501 445 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL); 446 free(mp); 502 447 if (rc != EOK) { 503 448 fibril_rwlock_write_unlock(&namespace_rwlock); 504 free(mp);505 449 vfs_node_put(mr_node); 506 450 async_answer_0(rid, rc); 507 451 return; 508 452 } 509 510 453 vfs_node_t *mp_node = vfs_node_get(&mp_res); 511 454 if (!mp_node) { 512 455 fibril_rwlock_write_unlock(&namespace_rwlock); 513 free(mp);514 456 vfs_node_put(mr_node); 515 457 async_answer_0(rid, ENOMEM); 516 458 return; 517 459 } 518 519 exch = vfs_exchange_grab(mp_node->fs_handle); 520 rc = async_req_2_0(exch, VFS_OUT_UNMOUNT, 521 mp_node->service_id, mp_node->index); 522 vfs_exchange_release(exch); 523 460 461 phone = vfs_grab_phone(mp_node->fs_handle); 462 rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, 463 mp_node->devmap_handle, mp_node->index); 464 vfs_release_phone(mp_node->fs_handle, phone); 524 465 if (rc != EOK) { 525 466 fibril_rwlock_write_unlock(&namespace_rwlock); 526 free(mp);527 467 vfs_node_put(mp_node); 528 468 vfs_node_put(mr_node); … … 530 470 return; 531 471 } 532 472 533 473 /* Drop the reference we got above. */ 534 474 vfs_node_put(mp_node); … … 536 476 vfs_node_put(mp_node); 537 477 } 538 478 479 539 480 /* 540 481 * All went well, the mounted file system was successfully unmounted. … … 542 483 */ 543 484 vfs_node_forget(mr_node); 485 544 486 fibril_rwlock_write_unlock(&namespace_rwlock); 545 546 fibril_mutex_lock(&mtab_list_lock);547 548 int found = 0;549 550 list_foreach(mtab_list, cur) {551 mtab_ent_t *mtab_ent = list_get_instance(cur, mtab_ent_t,552 link);553 554 if (str_cmp(mtab_ent->mp, mp) == 0) {555 list_remove(&mtab_ent->link);556 mtab_size--;557 free(mtab_ent);558 found = 1;559 break;560 }561 }562 assert(found);563 fibril_mutex_unlock(&mtab_list_lock);564 565 free(mp);566 567 487 async_answer_0(rid, EOK); 568 488 } … … 646 566 if (node->size) { 647 567 rc = vfs_truncate_internal(node->fs_handle, 648 node-> service_id, node->index, 0);568 node->devmap_handle, node->index, 0); 649 569 if (rc) { 650 570 fibril_rwlock_write_unlock(&node->contents_rwlock); … … 689 609 } 690 610 611 void vfs_open_node(ipc_callid_t rid, ipc_call_t *request) 612 { 613 // FIXME: check for sanity of the supplied fs, dev and index 614 615 /* 616 * The interface is open_node(fs, dev, index, oflag). 617 */ 618 vfs_lookup_res_t lr; 619 620 lr.triplet.fs_handle = IPC_GET_ARG1(*request); 621 lr.triplet.devmap_handle = IPC_GET_ARG2(*request); 622 lr.triplet.index = IPC_GET_ARG3(*request); 623 int oflag = IPC_GET_ARG4(*request); 624 625 fibril_rwlock_read_lock(&namespace_rwlock); 626 627 int rc = vfs_open_node_internal(&lr); 628 if (rc != EOK) { 629 fibril_rwlock_read_unlock(&namespace_rwlock); 630 async_answer_0(rid, rc); 631 return; 632 } 633 634 vfs_node_t *node = vfs_node_get(&lr); 635 fibril_rwlock_read_unlock(&namespace_rwlock); 636 637 /* Truncate the file if requested and if necessary. */ 638 if (oflag & O_TRUNC) { 639 fibril_rwlock_write_lock(&node->contents_rwlock); 640 if (node->size) { 641 rc = vfs_truncate_internal(node->fs_handle, 642 node->devmap_handle, node->index, 0); 643 if (rc) { 644 fibril_rwlock_write_unlock(&node->contents_rwlock); 645 vfs_node_put(node); 646 async_answer_0(rid, rc); 647 return; 648 } 649 node->size = 0; 650 } 651 fibril_rwlock_write_unlock(&node->contents_rwlock); 652 } 653 654 /* 655 * Get ourselves a file descriptor and the corresponding vfs_file_t 656 * structure. 657 */ 658 int fd = vfs_fd_alloc((oflag & O_DESC) != 0); 659 if (fd < 0) { 660 vfs_node_put(node); 661 async_answer_0(rid, fd); 662 return; 663 } 664 vfs_file_t *file = vfs_file_get(fd); 665 file->node = node; 666 if (oflag & O_APPEND) 667 file->append = true; 668 669 /* 670 * The following increase in reference count is for the fact that the 671 * file is being opened and that a file structure is pointing to it. 672 * It is necessary so that the file will not disappear when 673 * vfs_node_put() is called. The reference will be dropped by the 674 * respective VFS_IN_CLOSE. 675 */ 676 vfs_node_addref(node); 677 vfs_node_put(node); 678 vfs_file_put(file); 679 680 /* Success! Return the new file descriptor to the client. */ 681 async_answer_1(rid, EOK, fd); 682 } 683 691 684 void vfs_sync(ipc_callid_t rid, ipc_call_t *request) 692 685 { … … 705 698 */ 706 699 fibril_mutex_lock(&file->lock); 707 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);700 int fs_phone = vfs_grab_phone(file->node->fs_handle); 708 701 709 702 /* Make a VFS_OUT_SYMC request at the destination FS server. */ 710 703 aid_t msg; 711 704 ipc_call_t answer; 712 msg = async_send_2(fs_ exch, VFS_OUT_SYNC, file->node->service_id,705 msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->devmap_handle, 713 706 file->node->index, &answer); 714 715 vfs_exchange_release(fs_exch); 716 707 717 708 /* Wait for reply from the FS server. */ 718 709 sysarg_t rc; 719 710 async_wait_for(msg, &rc); 720 711 712 vfs_release_phone(file->node->fs_handle, fs_phone); 721 713 fibril_mutex_unlock(&file->lock); 722 714 723 715 vfs_file_put(file); 724 716 async_answer_0(rid, rc); 725 717 } 726 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 727 754 void vfs_close(ipc_callid_t rid, ipc_call_t *request) 728 755 { 729 756 int fd = IPC_GET_ARG1(*request); 730 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); 731 771 async_answer_0(rid, ret); 732 772 } … … 734 774 static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read) 735 775 { 776 vfs_info_t *vi; 777 736 778 /* 737 779 * The following code strongly depends on the fact that the files data … … 743 785 * open files supports parallel access! 744 786 */ 745 787 746 788 int fd = IPC_GET_ARG1(*request); 747 789 … … 758 800 */ 759 801 fibril_mutex_lock(&file->lock); 760 761 v fs_info_t *fs_info= fs_handle_to_info(file->node->fs_handle);762 assert( fs_info);763 802 803 vi = fs_handle_to_info(file->node->fs_handle); 804 assert(vi); 805 764 806 /* 765 807 * Lock the file's node so that no other client can read/write to it at … … 767 809 * write implementation does not modify the file size. 768 810 */ 769 if ((read) || 770 ((fs_info->concurrent_read_write) && (fs_info->write_retains_size))) 811 if (read || (vi->concurrent_read_write && vi->write_retains_size)) 771 812 fibril_rwlock_read_lock(&file->node->contents_rwlock); 772 813 else 773 814 fibril_rwlock_write_lock(&file->node->contents_rwlock); 774 815 775 816 if (file->node->type == VFS_NODE_DIRECTORY) { 776 817 /* … … 782 823 } 783 824 784 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);825 int fs_phone = vfs_grab_phone(file->node->fs_handle); 785 826 786 827 /* … … 794 835 ipc_call_t answer; 795 836 if (read) { 796 rc = async_data_read_forward_ 4_1(fs_exch, VFS_OUT_READ,797 file->node-> service_id, file->node->index,798 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); 799 840 } else { 800 841 if (file->append) 801 842 file->pos = file->node->size; 802 843 803 rc = async_data_write_forward_ 4_1(fs_exch, VFS_OUT_WRITE,804 file->node-> service_id, file->node->index,805 LOWER32(file->pos), UPPER32(file->pos),&answer);806 } 807 808 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); 809 850 810 851 size_t bytes = IPC_GET_ARG1(answer); … … 814 855 815 856 /* Unlock the VFS node. */ 816 if ((read) || 817 ((fs_info->concurrent_read_write) && (fs_info->write_retains_size))) 857 if (read || (vi->concurrent_read_write && vi->write_retains_size)) 818 858 fibril_rwlock_read_unlock(&file->node->contents_rwlock); 819 859 else { 820 860 /* Update the cached version of node's size. */ 821 861 if (rc == EOK) 822 file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer), 823 IPC_GET_ARG3(answer)); 862 file->node->size = IPC_GET_ARG2(answer); 824 863 fibril_rwlock_write_unlock(&file->node->contents_rwlock); 825 864 } … … 933 972 } 934 973 935 int vfs_truncate_internal(fs_handle_t fs_handle, service_id_t service_id,974 int vfs_truncate_internal(fs_handle_t fs_handle, devmap_handle_t devmap_handle, 936 975 fs_index_t index, aoff64_t size) 937 976 { 938 async_exch_t *exch = vfs_exchange_grab(fs_handle); 939 sysarg_t rc = async_req_4_0(exch, VFS_OUT_TRUNCATE, 940 (sysarg_t) service_id, (sysarg_t) index, LOWER32(size), 941 UPPER32(size)); 942 vfs_exchange_release(exch); 943 944 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; 945 985 } 946 986 … … 961 1001 fibril_rwlock_write_lock(&file->node->contents_rwlock); 962 1002 rc = vfs_truncate_internal(file->node->fs_handle, 963 file->node-> service_id, file->node->index, size);1003 file->node->devmap_handle, file->node->index, size); 964 1004 if (rc == EOK) 965 1005 file->node->size = size; … … 992 1032 fibril_mutex_lock(&file->lock); 993 1033 994 async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);1034 int fs_phone = vfs_grab_phone(file->node->fs_handle); 995 1035 996 1036 aid_t msg; 997 msg = async_send_3( exch, VFS_OUT_STAT, file->node->service_id,1037 msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->devmap_handle, 998 1038 file->node->index, true, NULL); 999 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1000 1001 vfs_exchange_release(exch); 1002 1039 async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1003 1040 async_wait_for(msg, &rc); 1004 1041 vfs_release_phone(file->node->fs_handle, fs_phone); 1042 1005 1043 fibril_mutex_unlock(&file->lock); 1006 1044 vfs_file_put(file); … … 1045 1083 fibril_rwlock_read_unlock(&namespace_rwlock); 1046 1084 1047 async_exch_t *exch = vfs_exchange_grab(node->fs_handle); 1048 1085 int fs_phone = vfs_grab_phone(node->fs_handle); 1049 1086 aid_t msg; 1050 msg = async_send_3( exch, VFS_OUT_STAT, node->service_id,1087 msg = async_send_3(fs_phone, VFS_OUT_STAT, node->devmap_handle, 1051 1088 node->index, false, NULL); 1052 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1053 1054 vfs_exchange_release(exch); 1089 async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1055 1090 1056 1091 sysarg_t rv; 1057 1092 async_wait_for(msg, &rv); 1093 vfs_release_phone(node->fs_handle, fs_phone); 1058 1094 1059 1095 async_answer_0(rid, rv); … … 1225 1261 /* Check whether linking to the same file system instance. */ 1226 1262 if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) || 1227 (old_node-> service_id != new_par_lr.triplet.service_id)) {1263 (old_node->devmap_handle != new_par_lr.triplet.devmap_handle)) { 1228 1264 fibril_rwlock_write_unlock(&namespace_rwlock); 1229 1265 vfs_node_put(old_node); … … 1333 1369 fibril_mutex_lock(&oldfile->lock); 1334 1370 1335 /* Make sure newfd is closed. */ 1336 (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 } 1337 1394 1338 1395 /* Assign the old file to newfd. */ … … 1347 1404 } 1348 1405 1349 void vfs_wait_handle(ipc_callid_t rid, ipc_call_t *request)1350 {1351 int fd = vfs_wait_handle_internal();1352 async_answer_1(rid, EOK, fd);1353 }1354 1355 void vfs_get_mtab(ipc_callid_t rid, ipc_call_t *request)1356 {1357 ipc_callid_t callid;1358 ipc_call_t data;1359 sysarg_t rc = EOK;1360 size_t len;1361 1362 fibril_mutex_lock(&mtab_list_lock);1363 1364 /* Send to the caller the number of mounted filesystems */1365 callid = async_get_call(&data);1366 if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {1367 rc = ENOTSUP;1368 async_answer_0(callid, rc);1369 goto exit;1370 }1371 async_answer_1(callid, EOK, mtab_size);1372 1373 list_foreach(mtab_list, cur) {1374 mtab_ent_t *mtab_ent = list_get_instance(cur, mtab_ent_t,1375 link);1376 1377 rc = ENOTSUP;1378 1379 if (!async_data_read_receive(&callid, &len)) {1380 async_answer_0(callid, rc);1381 goto exit;1382 }1383 1384 (void) async_data_read_finalize(callid, mtab_ent->mp,1385 str_size(mtab_ent->mp));1386 1387 if (!async_data_read_receive(&callid, &len)) {1388 async_answer_0(callid, rc);1389 goto exit;1390 }1391 1392 (void) async_data_read_finalize(callid, mtab_ent->opts,1393 str_size(mtab_ent->opts));1394 1395 if (!async_data_read_receive(&callid, &len)) {1396 async_answer_0(callid, rc);1397 goto exit;1398 }1399 1400 (void) async_data_read_finalize(callid, mtab_ent->fs_name,1401 str_size(mtab_ent->fs_name));1402 1403 callid = async_get_call(&data);1404 1405 if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {1406 async_answer_0(callid, rc);1407 goto exit;1408 }1409 1410 rc = EOK;1411 async_answer_2(callid, rc, mtab_ent->instance,1412 mtab_ent->service_id);1413 }1414 1415 exit:1416 fibril_mutex_unlock(&mtab_list_lock);1417 async_answer_0(rid, rc);1418 }1419 1420 1406 /** 1421 1407 * @}
Note:
See TracChangeset
for help on using the changeset viewer.