Changeset a8e9ab8d in mainline for uspace/srv
- 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
- Location:
- uspace/srv
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/tmpfs/tmpfs_ops.c
r2664838b ra8e9ab8d 71 71 /* Forward declarations of static functions. */ 72 72 static bool tmpfs_match(void *, void *, const char *); 73 static void *tmpfs_node_get(int, int, unsigned long); 73 74 static void *tmpfs_create_node(int); 74 75 static bool tmpfs_link_node(void *, void *, const char *); … … 125 126 libfs_ops_t tmpfs_libfs_ops = { 126 127 .match = tmpfs_match, 128 .node_get = tmpfs_node_get, 127 129 .create = tmpfs_create_node, 128 130 .destroy = tmpfs_destroy_node, … … 259 261 260 262 return !strcmp(namep->name, component); 263 } 264 265 void *tmpfs_node_get(int fs_handle, int dev_handle, unsigned long index) 266 { 267 link_t *lnk = hash_table_find(&dentries, &index); 268 if (!lnk) 269 return NULL; 270 return hash_table_get_instance(lnk, tmpfs_dentry_t, dh_link); 261 271 } 262 272 -
uspace/srv/vfs/vfs.c
r2664838b ra8e9ab8d 115 115 vfs_unlink(callid, &call); 116 116 break; 117 case VFS_RENAME: 118 vfs_rename(callid, &call); 119 break; 117 120 default: 118 121 ipc_answer_0(callid, ENOTSUP); -
uspace/srv/vfs/vfs.h
r2664838b ra8e9ab8d 167 167 #define L_CREATE 8 168 168 /** 169 * L_DESTROY is used to remove leaves from the file system namespace. This flag 169 * L_LINK is used for linking to an already existing nodes. 170 */ 171 #define L_LINK 16 172 /** 173 * L_UNLINK is used to remove leaves from the file system namespace. This flag 170 174 * cannot be passed directly by the client, but will be set by VFS during 171 175 * VFS_UNLINK. 172 176 */ 173 #define L_DESTROY 16 177 #define L_UNLINK 32 178 /** 179 * L_PARENT performs a lookup but returns the triplet of the parent node. 180 * This flag may not be combined with any other lookup flag. 181 */ 182 #define L_PARENT 64 174 183 175 184 typedef struct { … … 251 260 extern int fs_name_to_handle(char *, bool); 252 261 253 extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *, vfs_pair_t *); 262 extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *, vfs_pair_t *, 263 ...); 254 264 255 265 extern bool vfs_nodes_init(void); … … 280 290 extern void vfs_mkdir(ipc_callid_t, ipc_call_t *); 281 291 extern void vfs_unlink(ipc_callid_t, ipc_call_t *); 292 extern void vfs_rename(ipc_callid_t, ipc_call_t *); 282 293 283 294 #endif -
uspace/srv/vfs/vfs_lookup.c
r2664838b ra8e9ab8d 41 41 #include <errno.h> 42 42 #include <string.h> 43 #include <stdarg.h> 43 44 #include <bool.h> 44 45 #include <futex.h> … … 66 67 */ 67 68 int vfs_lookup_internal(char *path, int lflag, vfs_lookup_res_t *result, 68 vfs_pair_t *altroot )69 vfs_pair_t *altroot, ...) 69 70 { 70 71 vfs_pair_t *root; … … 82 83 if (!path) 83 84 return EINVAL; 85 86 unsigned long index = 0; 87 if (lflag & L_LINK) { 88 va_list ap; 89 90 va_start(ap, altroot); 91 index = va_arg(ap, unsigned long); 92 va_end(ap); 93 } 84 94 85 95 futex_down(&plb_futex); … … 150 160 ipc_call_t answer; 151 161 int phone = vfs_grab_phone(root->fs_handle); 152 aid_t req = async_send_ 4(phone, VFS_LOOKUP, (ipcarg_t) first,162 aid_t req = async_send_5(phone, VFS_LOOKUP, (ipcarg_t) first, 153 163 (ipcarg_t) (first + len - 1) % PLB_SIZE, 154 (ipcarg_t) root->dev_handle, (ipcarg_t) lflag, &answer); 164 (ipcarg_t) root->dev_handle, (ipcarg_t) lflag, (ipcarg_t) index, 165 &answer); 155 166 vfs_release_phone(phone); 156 167 -
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.