Changeset a8e9ab8d in mainline for uspace/srv/vfs/vfs_ops.c
- Timestamp:
- 2008-03-09T17:18:30Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4072980
- Parents:
- 2664838b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_ops.c
r2664838b ra8e9ab8d 36 36 */ 37 37 38 #include "vfs.h" 38 39 #include <ipc/ipc.h> 39 40 #include <async.h> … … 51 52 #include <assert.h> 52 53 #include <atomic.h> 53 #include "vfs.h"54 #include <vfs/canonify.h> 54 55 55 56 /* Forward declarations of static functions. */ … … 307 308 return; 308 309 } 309 310 /*311 * Now we are on the verge of accepting the path.312 *313 * There is one optimization we could do in the future: copy the path314 * directly into the PLB using some kind of a callback.315 */316 310 char *path = malloc(len + 1); 317 318 311 if (!path) { 319 312 ipc_answer_0(callid, ENOMEM); … … 321 314 return; 322 315 } 323 324 316 int rc; 325 317 if ((rc = ipc_data_write_finalize(callid, path, len))) { … … 630 622 return; 631 623 } 632 633 /*634 * Now we are on the verge of accepting the path.635 *636 * There is one optimization we could do in the future: copy the path637 * directly into the PLB using some kind of a callback.638 */639 624 char *path = malloc(len + 1); 640 641 625 if (!path) { 642 626 ipc_answer_0(callid, ENOMEM); … … 644 628 return; 645 629 } 646 647 630 int rc; 648 631 if ((rc = ipc_data_write_finalize(callid, path, len))) { … … 673 656 return; 674 657 } 675 676 /*677 * Now we are on the verge of accepting the path.678 *679 * There is one optimization we could do in the future: copy the path680 * directly into the PLB using some kind of a callback.681 */682 658 char *path = malloc(len + 1); 683 684 659 if (!path) { 685 660 ipc_answer_0(callid, ENOMEM); … … 687 662 return; 688 663 } 689 690 664 int rc; 691 665 if ((rc = ipc_data_write_finalize(callid, path, len))) { … … 699 673 lflag &= L_DIRECTORY; /* sanitize lflag */ 700 674 vfs_lookup_res_t lr; 701 rc = vfs_lookup_internal(path, lflag | L_ DESTROY, &lr, NULL);675 rc = vfs_lookup_internal(path, lflag | L_UNLINK, &lr, NULL); 702 676 free(path); 703 677 if (rc != EOK) { … … 719 693 } 720 694 695 void vfs_rename(ipc_callid_t rid, ipc_call_t *request) 696 { 697 size_t len; 698 ipc_callid_t callid; 699 int rc; 700 701 /* Retrieve the old path. */ 702 if (!ipc_data_write_receive(&callid, &len)) { 703 ipc_answer_0(callid, EINVAL); 704 ipc_answer_0(rid, EINVAL); 705 return; 706 } 707 char *old = malloc(len + 1); 708 if (!old) { 709 ipc_answer_0(callid, ENOMEM); 710 ipc_answer_0(rid, ENOMEM); 711 return; 712 } 713 if ((rc = ipc_data_write_finalize(callid, old, len))) { 714 ipc_answer_0(rid, rc); 715 free(old); 716 return; 717 } 718 old[len] = '\0'; 719 720 /* Retrieve the new path. */ 721 if (!ipc_data_write_receive(&callid, &len)) { 722 ipc_answer_0(callid, EINVAL); 723 ipc_answer_0(rid, EINVAL); 724 free(old); 725 return; 726 } 727 char *new = malloc(len + 1); 728 if (!new) { 729 ipc_answer_0(callid, ENOMEM); 730 ipc_answer_0(rid, ENOMEM); 731 free(old); 732 return; 733 } 734 if ((rc = ipc_data_write_finalize(callid, new, len))) { 735 ipc_answer_0(rid, rc); 736 free(old); 737 free(new); 738 return; 739 } 740 new[len] = '\0'; 741 742 char *oldc = canonify(old, &len); 743 char *newc = canonify(new, NULL); 744 if (!oldc || !newc) { 745 ipc_answer_0(rid, EINVAL); 746 free(old); 747 free(new); 748 return; 749 } 750 if (!strncmp(newc, oldc, len)) { 751 /* oldc is a prefix of newc */ 752 ipc_answer_0(rid, EINVAL); 753 free(old); 754 free(new); 755 return; 756 } 757 758 vfs_lookup_res_t old_lr; 759 vfs_lookup_res_t new_lr; 760 vfs_lookup_res_t new_par_lr; 761 rwlock_write_lock(&namespace_rwlock); 762 /* Lookup the node belonging to the old file name. */ 763 rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL); 764 if (rc != EOK) { 765 rwlock_write_unlock(&namespace_rwlock); 766 ipc_answer_0(rid, rc); 767 free(old); 768 free(new); 769 return; 770 } 771 vfs_node_t *old_node = vfs_node_get(&old_lr); 772 if (!old_node) { 773 rwlock_write_unlock(&namespace_rwlock); 774 ipc_answer_0(rid, ENOMEM); 775 free(old); 776 free(new); 777 return; 778 } 779 /* Lookup parent of the new file name. */ 780 rc = vfs_lookup_internal(newc, L_PARENT, &new_par_lr, NULL); 781 if (rc != EOK) { 782 rwlock_write_unlock(&namespace_rwlock); 783 ipc_answer_0(rid, rc); 784 free(old); 785 free(new); 786 return; 787 } 788 /* Check whether linking to the same file system instance. */ 789 if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) || 790 (old_node->dev_handle != new_par_lr.triplet.dev_handle)) { 791 rwlock_write_unlock(&namespace_rwlock); 792 ipc_answer_0(rid, EXDEV); /* different file systems */ 793 free(old); 794 free(new); 795 return; 796 } 797 /* Destroy the old link for the new name. */ 798 vfs_node_t *new_node = NULL; 799 rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL); 800 switch (rc) { 801 case ENOENT: 802 /* simply not in our way */ 803 break; 804 case EOK: 805 new_node = vfs_node_get(&new_lr); 806 if (!new_node) { 807 rwlock_write_unlock(&namespace_rwlock); 808 ipc_answer_0(rid, ENOMEM); 809 free(old); 810 free(new); 811 return; 812 } 813 new_node->lnkcnt--; 814 break; 815 default: 816 rwlock_write_unlock(&namespace_rwlock); 817 ipc_answer_0(rid, ENOTEMPTY); 818 free(old); 819 free(new); 820 return; 821 } 822 /* Create the new link for the new name. */ 823 rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index); 824 if (rc != EOK) { 825 rwlock_write_unlock(&namespace_rwlock); 826 if (new_node) 827 vfs_node_put(new_node); 828 ipc_answer_0(rid, rc); 829 free(old); 830 free(new); 831 return; 832 } 833 old_node->lnkcnt++; 834 /* Destroy the link for the old name. */ 835 rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL); 836 if (rc != EOK) { 837 rwlock_write_unlock(&namespace_rwlock); 838 vfs_node_put(old_node); 839 if (new_node) 840 vfs_node_put(new_node); 841 ipc_answer_0(rid, rc); 842 free(old); 843 free(new); 844 return; 845 } 846 old_node->lnkcnt--; 847 rwlock_write_unlock(&namespace_rwlock); 848 vfs_node_put(old_node); 849 if (new_node) 850 vfs_node_put(new_node); 851 free(old); 852 free(new); 853 ipc_answer_0(rid, EOK); 854 } 855 721 856 /** 722 857 * @}
Note:
See TracChangeset
for help on using the changeset viewer.