Changeset 05b9912 in mainline for uspace/srv/vfs/vfs_ops.c
- Timestamp:
- 2009-06-03T18:54:49Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 17fd1d4
- Parents:
- 215abc1
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_ops.c
r215abc1 r05b9912 94 94 aid_t msg; 95 95 ipc_call_t answer; 96 96 97 97 /* Resolve the path to the mountpoint. */ 98 98 rwlock_write_lock(&namespace_rwlock); … … 491 491 return; 492 492 } 493 493 494 494 /* 495 495 * The POSIX interface is open(path, oflag, mode). … … 504 504 int mode = IPC_GET_ARG3(*request); 505 505 size_t len; 506 506 507 507 /* 508 508 * Make sure that we are called with exactly one of L_FILE and 509 * L_DIRECTORY. 510 */ 511 if ((lflag & (L_FILE | L_DIRECTORY)) == 0 || 512 (lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) { 513 ipc_answer_0(rid, EINVAL); 514 return; 515 } 516 509 * L_DIRECTORY. Make sure that the user does not pass L_OPEN. 510 */ 511 if (((lflag & (L_FILE | L_DIRECTORY)) == 0) 512 || ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) 513 || ((lflag & L_OPEN) != 0)) { 514 ipc_answer_0(rid, EINVAL); 515 return; 516 } 517 517 518 if (oflag & O_CREAT) 518 519 lflag |= L_CREATE; 519 520 if (oflag & O_EXCL) 520 521 lflag |= L_EXCLUSIVE; 521 522 522 523 ipc_callid_t callid; 523 524 524 if (!ipc_data_write_receive(&callid, &len)) { 525 525 ipc_answer_0(callid, EINVAL); … … 527 527 return; 528 528 } 529 529 530 char *path = malloc(len + 1); 530 531 if (!path) { … … 533 534 return; 534 535 } 536 535 537 int rc; 536 538 if ((rc = ipc_data_write_finalize(callid, path, len))) { … … 550 552 else 551 553 rwlock_read_lock(&namespace_rwlock); 552 554 553 555 /* The path is now populated and we can call vfs_lookup_internal(). */ 554 556 vfs_lookup_res_t lr; 555 rc = vfs_lookup_internal(path, lflag , &lr, NULL);556 if (rc ) {557 rc = vfs_lookup_internal(path, lflag | L_OPEN, &lr, NULL); 558 if (rc != EOK) { 557 559 if (lflag & L_CREATE) 558 560 rwlock_write_unlock(&namespace_rwlock); … … 563 565 return; 564 566 } 565 567 566 568 /* Path is no longer needed. */ 567 569 free(path); 568 570 569 571 vfs_node_t *node = vfs_node_get(&lr); 570 572 if (lflag & L_CREATE) … … 572 574 else 573 575 rwlock_read_unlock(&namespace_rwlock); 574 576 575 577 /* Truncate the file if requested and if necessary. */ 576 578 if (oflag & O_TRUNC) { … … 589 591 rwlock_write_unlock(&node->contents_rwlock); 590 592 } 591 593 592 594 /* 593 595 * Get ourselves a file descriptor and the corresponding vfs_file_t … … 602 604 vfs_file_t *file = vfs_file_get(fd); 603 605 file->node = node; 604 if (oflag & O_APPEND) 606 if (oflag & O_APPEND) 605 607 file->append = true; 606 608 607 609 /* 608 610 * The following increase in reference count is for the fact that the … … 614 616 vfs_node_addref(node); 615 617 vfs_node_put(node); 616 618 617 619 /* Success! Return the new file descriptor to the client. */ 618 620 ipc_answer_1(rid, EOK, fd); 619 621 } 620 622 623 void vfs_open_node(ipc_callid_t rid, ipc_call_t *request) 624 { 625 // FIXME: check for sanity of the supplied fs, dev and index 626 627 if (!vfs_files_init()) { 628 ipc_answer_0(rid, ENOMEM); 629 return; 630 } 631 632 /* 633 * The interface is open_node(fs, dev, index, oflag). 634 */ 635 vfs_lookup_res_t lr; 636 637 lr.triplet.fs_handle = IPC_GET_ARG1(*request); 638 lr.triplet.dev_handle = IPC_GET_ARG2(*request); 639 lr.triplet.index = IPC_GET_ARG3(*request); 640 int oflag = IPC_GET_ARG4(*request); 641 642 rwlock_read_lock(&namespace_rwlock); 643 644 int rc = vfs_open_node_internal(&lr); 645 if (rc != EOK) { 646 rwlock_read_unlock(&namespace_rwlock); 647 ipc_answer_0(rid, rc); 648 return; 649 } 650 651 vfs_node_t *node = vfs_node_get(&lr); 652 rwlock_read_unlock(&namespace_rwlock); 653 654 /* Truncate the file if requested and if necessary. */ 655 if (oflag & O_TRUNC) { 656 rwlock_write_lock(&node->contents_rwlock); 657 if (node->size) { 658 rc = vfs_truncate_internal(node->fs_handle, 659 node->dev_handle, node->index, 0); 660 if (rc) { 661 rwlock_write_unlock(&node->contents_rwlock); 662 vfs_node_put(node); 663 ipc_answer_0(rid, rc); 664 return; 665 } 666 node->size = 0; 667 } 668 rwlock_write_unlock(&node->contents_rwlock); 669 } 670 671 /* 672 * Get ourselves a file descriptor and the corresponding vfs_file_t 673 * structure. 674 */ 675 int fd = vfs_fd_alloc(); 676 if (fd < 0) { 677 vfs_node_put(node); 678 ipc_answer_0(rid, fd); 679 return; 680 } 681 vfs_file_t *file = vfs_file_get(fd); 682 file->node = node; 683 if (oflag & O_APPEND) 684 file->append = true; 685 686 /* 687 * The following increase in reference count is for the fact that the 688 * file is being opened and that a file structure is pointing to it. 689 * It is necessary so that the file will not disappear when 690 * vfs_node_put() is called. The reference will be dropped by the 691 * respective VFS_CLOSE. 692 */ 693 vfs_node_addref(node); 694 vfs_node_put(node); 695 696 /* Success! Return the new file descriptor to the client. */ 697 ipc_answer_1(rid, EOK, fd); 698 } 699 700 void vfs_node(ipc_callid_t rid, ipc_call_t *request) 701 { 702 int fd = IPC_GET_ARG1(*request); 703 704 /* Lookup the file structure corresponding to the file descriptor. */ 705 vfs_file_t *file = vfs_file_get(fd); 706 if (!file) { 707 ipc_answer_0(rid, ENOENT); 708 return; 709 } 710 711 ipc_answer_3(rid, EOK, file->node->fs_handle, 712 file->node->dev_handle, file->node->index); 713 } 714 715 void vfs_device(ipc_callid_t rid, ipc_call_t *request) 716 { 717 int fd = IPC_GET_ARG1(*request); 718 719 /* Lookup the file structure corresponding to the file descriptor. */ 720 vfs_file_t *file = vfs_file_get(fd); 721 if (!file) { 722 ipc_answer_0(rid, ENOENT); 723 return; 724 } 725 726 /* 727 * Lock the open file structure so that no other thread can manipulate 728 * the same open file at a time. 729 */ 730 futex_down(&file->lock); 731 int fs_phone = vfs_grab_phone(file->node->fs_handle); 732 733 /* Make a VFS_DEVICE request at the destination FS server. */ 734 aid_t msg; 735 ipc_call_t answer; 736 msg = async_send_2(fs_phone, IPC_GET_METHOD(*request), 737 file->node->dev_handle, file->node->index, &answer); 738 739 /* Wait for reply from the FS server. */ 740 ipcarg_t rc; 741 async_wait_for(msg, &rc); 742 743 vfs_release_phone(fs_phone); 744 futex_up(&file->lock); 745 746 ipc_answer_1(rid, EOK, IPC_GET_ARG1(answer)); 747 } 748 749 void vfs_sync(ipc_callid_t rid, ipc_call_t *request) 750 { 751 int fd = IPC_GET_ARG1(*request); 752 753 /* Lookup the file structure corresponding to the file descriptor. */ 754 vfs_file_t *file = vfs_file_get(fd); 755 if (!file) { 756 ipc_answer_0(rid, ENOENT); 757 return; 758 } 759 760 /* 761 * Lock the open file structure so that no other thread can manipulate 762 * the same open file at a time. 763 */ 764 futex_down(&file->lock); 765 int fs_phone = vfs_grab_phone(file->node->fs_handle); 766 767 /* Make a VFS_SYMC request at the destination FS server. */ 768 aid_t msg; 769 ipc_call_t answer; 770 msg = async_send_2(fs_phone, IPC_GET_METHOD(*request), 771 file->node->dev_handle, file->node->index, &answer); 772 773 /* Wait for reply from the FS server. */ 774 ipcarg_t rc; 775 async_wait_for(msg, &rc); 776 777 vfs_release_phone(fs_phone); 778 futex_up(&file->lock); 779 780 ipc_answer_0(rid, rc); 781 } 782 621 783 void vfs_close(ipc_callid_t rid, ipc_call_t *request) 622 784 { 623 785 int fd = IPC_GET_ARG1(*request); 624 int rc = vfs_fd_free(fd); 625 ipc_answer_0(rid, rc); 786 787 /* Lookup the file structure corresponding to the file descriptor. */ 788 vfs_file_t *file = vfs_file_get(fd); 789 if (!file) { 790 ipc_answer_0(rid, ENOENT); 791 return; 792 } 793 794 /* 795 * Lock the open file structure so that no other thread can manipulate 796 * the same open file at a time. 797 */ 798 futex_down(&file->lock); 799 800 int fs_phone = vfs_grab_phone(file->node->fs_handle); 801 802 /* Make a VFS_CLOSE request at the destination FS server. */ 803 aid_t msg; 804 ipc_call_t answer; 805 msg = async_send_2(fs_phone, IPC_GET_METHOD(*request), 806 file->node->dev_handle, file->node->index, &answer); 807 808 /* Wait for reply from the FS server. */ 809 ipcarg_t rc; 810 async_wait_for(msg, &rc); 811 812 vfs_release_phone(fs_phone); 813 futex_up(&file->lock); 814 815 int retval = IPC_GET_ARG1(answer); 816 if (retval != EOK) 817 ipc_answer_0(rid, retval); 818 819 retval = vfs_fd_free(fd); 820 ipc_answer_0(rid, retval); 626 821 } 627 822 … … 706 901 ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 707 902 708 vfs_release_phone(fs_phone);709 710 903 /* Wait for reply from the FS server. */ 711 904 ipcarg_t rc; 712 905 async_wait_for(msg, &rc); 906 907 vfs_release_phone(fs_phone); 908 713 909 size_t bytes = IPC_GET_ARG1(answer); 714 910 … … 1117 1313 /** 1118 1314 * @} 1119 */ 1315 */
Note:
See TracChangeset
for help on using the changeset viewer.