Changes in uspace/srv/vfs/vfs_ops.c [ccca251:e6da6d5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_ops.c
rccca251 re6da6d5 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; 54 59 55 60 /* Forward declarations of static functions. */ 56 static int vfs_truncate_internal(fs_handle_t, devmap_handle_t, fs_index_t,61 static int vfs_truncate_internal(fs_handle_t, service_id_t, fs_index_t, 57 62 aoff64_t); 58 63 … … 65 70 vfs_pair_t rootfs = { 66 71 .fs_handle = 0, 67 . devmap_handle= 072 .service_id = 0 68 73 }; 69 74 70 static void vfs_mount_internal(ipc_callid_t rid, devmap_handle_t devmap_handle,75 static int vfs_mount_internal(ipc_callid_t rid, service_id_t service_id, 71 76 fs_handle_t fs_handle, char *mp, char *opts) 72 77 { … … 76 81 vfs_node_t *mr_node; 77 82 fs_index_t rindex; 78 size_t rsize;83 aoff64_t rsize; 79 84 unsigned rlnkcnt; 85 async_exch_t *exch; 80 86 sysarg_t rc; 81 int phone;82 87 aid_t msg; 83 88 ipc_call_t answer; … … 91 96 fibril_rwlock_write_unlock(&namespace_rwlock); 92 97 async_answer_0(rid, EBUSY); 93 return ;98 return EBUSY; 94 99 } 95 100 … … 99 104 fibril_rwlock_write_unlock(&namespace_rwlock); 100 105 async_answer_0(rid, rc); 101 return ;106 return rc; 102 107 } 103 108 … … 106 111 fibril_rwlock_write_unlock(&namespace_rwlock); 107 112 async_answer_0(rid, ENOMEM); 108 return ;113 return ENOMEM; 109 114 } 110 115 … … 123 128 124 129 /* Tell the mountee that it is being mounted. */ 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,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, 130 135 str_size(opts)); 136 vfs_exchange_release(exch); 137 131 138 if (rc != EOK) { 132 139 async_wait_for(msg, NULL); 133 vfs_release_phone(fs_handle, phone);134 140 fibril_rwlock_write_unlock(&namespace_rwlock); 135 141 async_answer_0(rid, rc); 136 return ;142 return rc; 137 143 } 138 144 async_wait_for(msg, &rc); 139 vfs_release_phone(fs_handle, phone);140 145 141 146 if (rc != EOK) { 142 147 fibril_rwlock_write_unlock(&namespace_rwlock); 143 148 async_answer_0(rid, rc); 144 return ;149 return rc; 145 150 } 146 151 147 152 rindex = (fs_index_t) IPC_GET_ARG1(answer); 148 rsize = (size_t) IPC_GET_ARG2(answer); 149 rlnkcnt = (unsigned) IPC_GET_ARG3(answer); 153 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), 154 IPC_GET_ARG3(answer)); 155 rlnkcnt = (unsigned) IPC_GET_ARG4(answer); 150 156 151 157 mr_res.triplet.fs_handle = fs_handle; 152 mr_res.triplet. devmap_handle = devmap_handle;158 mr_res.triplet.service_id = service_id; 153 159 mr_res.triplet.index = rindex; 154 160 mr_res.size = rsize; … … 157 163 158 164 rootfs.fs_handle = fs_handle; 159 rootfs. devmap_handle = devmap_handle;165 rootfs.service_id = service_id; 160 166 161 167 /* Add reference to the mounted root. */ … … 165 171 fibril_rwlock_write_unlock(&namespace_rwlock); 166 172 async_answer_0(rid, rc); 167 return ;173 return rc; 168 174 } else { 169 175 /* … … 173 179 fibril_rwlock_write_unlock(&namespace_rwlock); 174 180 async_answer_0(rid, ENOENT); 175 return ;176 } 177 } 178 179 /* 180 * At this point, we have all necessary pieces: file system and device181 * 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,181 return ENOENT; 182 } 183 } 184 185 /* 186 * At this point, we have all necessary pieces: file system handle 187 * 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, 190 196 (sysarg_t) mp_res.triplet.index, 191 197 (sysarg_t) fs_handle, 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) { 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); 197 206 async_wait_for(msg, NULL); 198 vfs_release_phone(fs_handle, mountee_phone); 199 vfs_release_phone(mp_res.triplet.fs_handle, phone); 207 200 208 /* Mount failed, drop reference to mp_node. */ 201 209 if (mp_node) 202 210 vfs_node_put(mp_node); 211 203 212 async_answer_0(rid, rc); 204 213 fibril_rwlock_write_unlock(&namespace_rwlock); 205 return; 206 } 207 208 vfs_release_phone(fs_handle, mountee_phone); 214 return rc; 215 } 209 216 210 217 /* send the mount options */ 211 rc = async_data_write_start(phone, (void *)opts, str_size(opts)); 212 if (rc != EOK) { 218 rc = async_data_write_start(exch, (void *) opts, str_size(opts)); 219 if (rc != EOK) { 220 vfs_exchange_release(exch); 213 221 async_wait_for(msg, NULL); 214 vfs_release_phone(mp_res.triplet.fs_handle, phone);222 215 223 /* Mount failed, drop reference to mp_node. */ 216 224 if (mp_node) 217 225 vfs_node_put(mp_node); 226 218 227 fibril_rwlock_write_unlock(&namespace_rwlock); 219 228 async_answer_0(rid, rc); 220 return; 221 } 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 */ 222 238 async_wait_for(msg, &rc); 223 vfs_ release_phone(mp_res.triplet.fs_handle, phone);239 vfs_exchange_release(exch); 224 240 225 241 if (rc == EOK) { 226 242 rindex = (fs_index_t) IPC_GET_ARG1(answer); 227 rsize = (size_t) IPC_GET_ARG2(answer); 228 rlnkcnt = (unsigned) IPC_GET_ARG3(answer); 229 243 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), 244 IPC_GET_ARG3(answer)); 245 rlnkcnt = (unsigned) IPC_GET_ARG4(answer); 246 230 247 mr_res.triplet.fs_handle = fs_handle; 231 mr_res.triplet. devmap_handle = devmap_handle;248 mr_res.triplet.service_id = service_id; 232 249 mr_res.triplet.index = rindex; 233 250 mr_res.size = rsize; 234 251 mr_res.lnkcnt = rlnkcnt; 235 252 mr_res.type = VFS_NODE_DIRECTORY; 236 253 237 254 /* Add reference to the mounted root. */ 238 255 mr_node = vfs_node_get(&mr_res); … … 243 260 vfs_node_put(mp_node); 244 261 } 245 262 246 263 async_answer_0(rid, rc); 247 264 fibril_rwlock_write_unlock(&namespace_rwlock); 265 return rc; 248 266 } 249 267 250 268 void vfs_mount(ipc_callid_t rid, ipc_call_t *request) 251 269 { 252 devmap_handle_t devmap_handle;270 service_id_t service_id; 253 271 254 272 /* … … 257 275 * in the request. 258 276 */ 259 devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);277 service_id = (service_id_t) IPC_GET_ARG1(*request); 260 278 261 279 /* … … 265 283 266 284 /* 267 * For now, don't make use of ARG3, but it can be used to268 * carry mount options in the future.269 */270 285 * Instance number is passed as ARG3. 286 */ 287 unsigned int instance = IPC_GET_ARG3(*request); 288 271 289 /* We want the client to send us the mount point. */ 272 290 char *mp; … … 303 321 304 322 /* 305 * Wait for IPC_M_PING so that we can return an error if we don't know323 * Wait for VFS_IN_PING so that we can return an error if we don't know 306 324 * fs_name. 307 325 */ 308 326 ipc_call_t data; 309 327 ipc_callid_t callid = async_get_call(&data); 310 if (IPC_GET_IMETHOD(data) != IPC_M_PING) {328 if (IPC_GET_IMETHOD(data) != VFS_IN_PING) { 311 329 async_answer_0(callid, ENOTSUP); 312 330 async_answer_0(rid, ENOTSUP); … … 321 339 * This will also give us its file system handle. 322 340 */ 323 fibril_mutex_lock(&fs_ head_lock);341 fibril_mutex_lock(&fs_list_lock); 324 342 fs_handle_t fs_handle; 325 343 recheck: 326 fs_handle = fs_name_to_handle( fs_name, false);344 fs_handle = fs_name_to_handle(instance, fs_name, false); 327 345 if (!fs_handle) { 328 346 if (flags & IPC_FLAG_BLOCKING) { 329 fibril_condvar_wait(&fs_ head_cv, &fs_head_lock);347 fibril_condvar_wait(&fs_list_cv, &fs_list_lock); 330 348 goto recheck; 331 349 } 332 350 333 fibril_mutex_unlock(&fs_ head_lock);351 fibril_mutex_unlock(&fs_list_lock); 334 352 async_answer_0(callid, ENOENT); 335 353 async_answer_0(rid, ENOENT); … … 339 357 return; 340 358 } 341 fibril_mutex_unlock(&fs_head_lock); 342 343 /* Acknowledge that we know fs_name. */ 344 async_answer_0(callid, EOK); 345 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 346 372 /* Do the mount */ 347 vfs_mount_internal(rid, devmap_handle, fs_handle, mp, opts); 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 348 399 free(mp); 349 400 free(fs_name); 350 401 free(opts); 402 403 /* Acknowledge that we know fs_name. */ 404 async_answer_0(callid, EOK); 351 405 } 352 406 … … 358 412 vfs_lookup_res_t mr_res; 359 413 vfs_node_t *mr_node; 360 int phone;361 414 async_exch_t *exch; 415 362 416 /* 363 417 * Receive the mount point path. … … 367 421 if (rc != EOK) 368 422 async_answer_0(rid, rc); 369 423 370 424 /* 371 425 * Taking the namespace lock will do two things for us. First, it will … … 395 449 return; 396 450 } 397 451 398 452 /* 399 453 * Count the total number of references for the mounted file system. We … … 404 458 */ 405 459 if (vfs_nodes_refcount_sum_get(mr_node->fs_handle, 406 mr_node-> devmap_handle) != 2) {460 mr_node->service_id) != 2) { 407 461 fibril_rwlock_write_unlock(&namespace_rwlock); 408 462 vfs_node_put(mr_node); … … 411 465 return; 412 466 } 413 467 414 468 if (str_cmp(mp, "/") == 0) { 415 469 416 470 /* 417 471 * Unmounting the root file system. … … 420 474 * VFS_OUT_UNMOUNTED directly to the mounted file system. 421 475 */ 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);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 428 482 if (rc != EOK) { 429 483 fibril_rwlock_write_unlock(&namespace_rwlock); 484 free(mp); 430 485 vfs_node_put(mr_node); 431 486 async_answer_0(rid, rc); 432 487 return; 433 488 } 489 434 490 rootfs.fs_handle = 0; 435 rootfs. devmap_handle= 0;491 rootfs.service_id = 0; 436 492 } else { 437 493 438 494 /* 439 495 * Unmounting a non-root file system. … … 442 498 * file system, so we delegate the operation to it. 443 499 */ 444 500 445 501 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL); 446 free(mp);447 502 if (rc != EOK) { 448 503 fibril_rwlock_write_unlock(&namespace_rwlock); 504 free(mp); 449 505 vfs_node_put(mr_node); 450 506 async_answer_0(rid, rc); 451 507 return; 452 508 } 509 453 510 vfs_node_t *mp_node = vfs_node_get(&mp_res); 454 511 if (!mp_node) { 455 512 fibril_rwlock_write_unlock(&namespace_rwlock); 513 free(mp); 456 514 vfs_node_put(mr_node); 457 515 async_answer_0(rid, ENOMEM); 458 516 return; 459 517 } 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); 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 465 524 if (rc != EOK) { 466 525 fibril_rwlock_write_unlock(&namespace_rwlock); 526 free(mp); 467 527 vfs_node_put(mp_node); 468 528 vfs_node_put(mr_node); … … 470 530 return; 471 531 } 472 532 473 533 /* Drop the reference we got above. */ 474 534 vfs_node_put(mp_node); … … 476 536 vfs_node_put(mp_node); 477 537 } 478 479 538 480 539 /* 481 540 * All went well, the mounted file system was successfully unmounted. … … 483 542 */ 484 543 vfs_node_forget(mr_node); 485 486 544 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 487 567 async_answer_0(rid, EOK); 488 568 } … … 566 646 if (node->size) { 567 647 rc = vfs_truncate_internal(node->fs_handle, 568 node-> devmap_handle, node->index, 0);648 node->service_id, node->index, 0); 569 649 if (rc) { 570 650 fibril_rwlock_write_unlock(&node->contents_rwlock); … … 609 689 } 610 690 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 index614 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_t656 * 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 the671 * file is being opened and that a file structure is pointing to it.672 * It is necessary so that the file will not disappear when673 * vfs_node_put() is called. The reference will be dropped by the674 * 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 684 691 void vfs_sync(ipc_callid_t rid, ipc_call_t *request) 685 692 { … … 698 705 */ 699 706 fibril_mutex_lock(&file->lock); 700 int fs_phone = vfs_grab_phone(file->node->fs_handle);707 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle); 701 708 702 709 /* Make a VFS_OUT_SYMC request at the destination FS server. */ 703 710 aid_t msg; 704 711 ipc_call_t answer; 705 msg = async_send_2(fs_ phone, VFS_OUT_SYNC, file->node->devmap_handle,712 msg = async_send_2(fs_exch, VFS_OUT_SYNC, file->node->service_id, 706 713 file->node->index, &answer); 707 714 715 vfs_exchange_release(fs_exch); 716 708 717 /* Wait for reply from the FS server. */ 709 718 sysarg_t rc; 710 719 async_wait_for(msg, &rc); 711 720 712 vfs_release_phone(file->node->fs_handle, fs_phone);713 721 fibril_mutex_unlock(&file->lock); 714 722 715 723 vfs_file_put(file); 716 724 async_answer_0(rid, rc); 717 725 } 718 726 719 int vfs_close_internal(vfs_file_t *file)720 {721 /*722 * Lock the open file structure so that no other thread can manipulate723 * 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 server729 if there are no more file descriptors (except the730 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 754 727 void vfs_close(ipc_callid_t rid, ipc_call_t *request) 755 728 { 756 729 int fd = IPC_GET_ARG1(*request); 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); 730 int ret = vfs_fd_free(fd); 771 731 async_answer_0(rid, ret); 772 732 } … … 774 734 static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read) 775 735 { 776 vfs_info_t *vi;777 778 736 /* 779 737 * The following code strongly depends on the fact that the files data … … 785 743 * open files supports parallel access! 786 744 */ 787 745 788 746 int fd = IPC_GET_ARG1(*request); 789 747 … … 800 758 */ 801 759 fibril_mutex_lock(&file->lock); 802 803 v i= fs_handle_to_info(file->node->fs_handle);804 assert( vi);805 760 761 vfs_info_t *fs_info = fs_handle_to_info(file->node->fs_handle); 762 assert(fs_info); 763 806 764 /* 807 765 * Lock the file's node so that no other client can read/write to it at … … 809 767 * write implementation does not modify the file size. 810 768 */ 811 if (read || (vi->concurrent_read_write && vi->write_retains_size)) 769 if ((read) || 770 ((fs_info->concurrent_read_write) && (fs_info->write_retains_size))) 812 771 fibril_rwlock_read_lock(&file->node->contents_rwlock); 813 772 else 814 773 fibril_rwlock_write_lock(&file->node->contents_rwlock); 815 774 816 775 if (file->node->type == VFS_NODE_DIRECTORY) { 817 776 /* … … 823 782 } 824 783 825 int fs_phone = vfs_grab_phone(file->node->fs_handle);784 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle); 826 785 827 786 /* … … 835 794 ipc_call_t answer; 836 795 if (read) { 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);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); 840 799 } else { 841 800 if (file->append) 842 801 file->pos = file->node->size; 843 802 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);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); 850 809 851 810 size_t bytes = IPC_GET_ARG1(answer); … … 855 814 856 815 /* Unlock the VFS node. */ 857 if (read || (vi->concurrent_read_write && vi->write_retains_size)) 816 if ((read) || 817 ((fs_info->concurrent_read_write) && (fs_info->write_retains_size))) 858 818 fibril_rwlock_read_unlock(&file->node->contents_rwlock); 859 819 else { 860 820 /* Update the cached version of node's size. */ 861 821 if (rc == EOK) 862 file->node->size = IPC_GET_ARG2(answer); 822 file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer), 823 IPC_GET_ARG3(answer)); 863 824 fibril_rwlock_write_unlock(&file->node->contents_rwlock); 864 825 } … … 972 933 } 973 934 974 int vfs_truncate_internal(fs_handle_t fs_handle, devmap_handle_t devmap_handle,935 int vfs_truncate_internal(fs_handle_t fs_handle, service_id_t service_id, 975 936 fs_index_t index, aoff64_t size) 976 937 { 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; 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; 985 945 } 986 946 … … 1001 961 fibril_rwlock_write_lock(&file->node->contents_rwlock); 1002 962 rc = vfs_truncate_internal(file->node->fs_handle, 1003 file->node-> devmap_handle, file->node->index, size);963 file->node->service_id, file->node->index, size); 1004 964 if (rc == EOK) 1005 965 file->node->size = size; … … 1032 992 fibril_mutex_lock(&file->lock); 1033 993 1034 int fs_phone = vfs_grab_phone(file->node->fs_handle);994 async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle); 1035 995 1036 996 aid_t msg; 1037 msg = async_send_3( fs_phone, VFS_OUT_STAT, file->node->devmap_handle,997 msg = async_send_3(exch, VFS_OUT_STAT, file->node->service_id, 1038 998 file->node->index, true, NULL); 1039 async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 999 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1000 1001 vfs_exchange_release(exch); 1002 1040 1003 async_wait_for(msg, &rc); 1041 vfs_release_phone(file->node->fs_handle, fs_phone); 1042 1004 1043 1005 fibril_mutex_unlock(&file->lock); 1044 1006 vfs_file_put(file); … … 1083 1045 fibril_rwlock_read_unlock(&namespace_rwlock); 1084 1046 1085 int fs_phone = vfs_grab_phone(node->fs_handle); 1047 async_exch_t *exch = vfs_exchange_grab(node->fs_handle); 1048 1086 1049 aid_t msg; 1087 msg = async_send_3( fs_phone, VFS_OUT_STAT, node->devmap_handle,1050 msg = async_send_3(exch, VFS_OUT_STAT, node->service_id, 1088 1051 node->index, false, NULL); 1089 async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1052 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1053 1054 vfs_exchange_release(exch); 1090 1055 1091 1056 sysarg_t rv; 1092 1057 async_wait_for(msg, &rv); 1093 vfs_release_phone(node->fs_handle, fs_phone);1094 1058 1095 1059 async_answer_0(rid, rv); … … 1261 1225 /* Check whether linking to the same file system instance. */ 1262 1226 if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) || 1263 (old_node-> devmap_handle != new_par_lr.triplet.devmap_handle)) {1227 (old_node->service_id != new_par_lr.triplet.service_id)) { 1264 1228 fibril_rwlock_write_unlock(&namespace_rwlock); 1265 1229 vfs_node_put(old_node); … … 1369 1333 fibril_mutex_lock(&oldfile->lock); 1370 1334 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 } 1335 /* Make sure newfd is closed. */ 1336 (void) vfs_fd_free(newfd); 1394 1337 1395 1338 /* Assign the old file to newfd. */ … … 1404 1347 } 1405 1348 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 1406 1420 /** 1407 1421 * @}
Note:
See TracChangeset
for help on using the changeset viewer.