Changeset 05b9912 in mainline
- 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
- Location:
- uspace/srv/vfs
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs.c
r215abc1 r05b9912 95 95 vfs_open(callid, &call); 96 96 break; 97 case VFS_OPEN_NODE: 98 vfs_open_node(callid, &call); 99 break; 97 100 case VFS_CLOSE: 98 101 vfs_close(callid, &call); … … 118 121 case VFS_RENAME: 119 122 vfs_rename(callid, &call); 123 break; 124 case VFS_DEVICE: 125 vfs_device(callid, &call); 126 break; 127 case VFS_SYNC: 128 vfs_sync(callid, &call); 129 break; 130 case VFS_NODE: 131 vfs_node(callid, &call); 120 132 break; 121 133 default: … … 165 177 * Set a connectio handling function/fibril. 166 178 */ 179 async_set_pending(vfs_process_pending_mount); 167 180 async_set_client_connection(vfs_connection); 168 181 -
uspace/srv/vfs/vfs.h
r215abc1 r05b9912 29 29 /** @addtogroup fs 30 30 * @{ 31 */ 31 */ 32 32 33 33 #ifndef VFS_VFS_H_ … … 41 41 #include <devmap.h> 42 42 #include <bool.h> 43 #include <ipc/vfs.h> 43 44 44 45 // FIXME: according to CONFIG_DEBUG 45 // #define dprintf(...) 46 // #define dprintf(...) printf(__VA_ARGS__) 46 47 47 48 #define dprintf(...) 48 49 #define VFS_FIRST IPC_FIRST_USER_METHOD50 51 /* Basic types. */52 typedef int16_t fs_handle_t;53 typedef uint32_t fs_index_t;54 55 typedef enum {56 VFS_READ = VFS_FIRST,57 VFS_WRITE,58 VFS_TRUNCATE,59 VFS_MOUNT,60 VFS_UNMOUNT,61 VFS_LAST_CMN, /* keep this the last member of this enum */62 } vfs_request_cmn_t;63 64 typedef enum {65 VFS_LOOKUP = VFS_LAST_CMN,66 VFS_MOUNTED,67 VFS_DESTROY,68 VFS_LAST_CLNT, /* keep this the last member of this enum */69 } vfs_request_clnt_t;70 71 typedef enum {72 VFS_REGISTER = VFS_LAST_CMN,73 VFS_OPEN,74 VFS_CLOSE,75 VFS_SEEK,76 VFS_MKDIR,77 VFS_UNLINK,78 VFS_RENAME,79 VFS_LAST_SRV, /* keep this the last member of this enum */80 } vfs_request_srv_t;81 82 #define FS_NAME_MAXLEN 2083 84 /**85 * A structure like this is passed to VFS by each individual FS upon its86 * registration. It assosiates a human-readable identifier with each87 * registered FS.88 */89 typedef struct {90 /** Unique identifier of the fs. */91 char name[FS_NAME_MAXLEN + 1];92 } vfs_info_t;93 49 94 50 /** … … 106 62 * VFS_PAIR uniquely represents a file system instance. 107 63 */ 108 #define VFS_PAIR 109 fs_handle_t fs_handle; 64 #define VFS_PAIR \ 65 fs_handle_t fs_handle; \ 110 66 dev_handle_t dev_handle; 111 67 … … 117 73 * IPC reply. 118 74 */ 119 #define VFS_TRIPLET 120 VFS_PAIR; 75 #define VFS_TRIPLET \ 76 VFS_PAIR; \ 121 77 fs_index_t index; 122 78 … … 128 84 VFS_TRIPLET; 129 85 } vfs_triplet_t; 130 131 /*132 * Lookup flags.133 */134 /**135 * No lookup flags used.136 */137 #define L_NONE 0138 /**139 * Lookup will succeed only if the object is a regular file. If L_CREATE is140 * specified, an empty file will be created. This flag is mutually exclusive141 * with L_DIRECTORY.142 */143 #define L_FILE 1144 /**145 * Lookup wil succeed only if the object is a directory. If L_CREATE is146 * specified, an empty directory will be created. This flag is mutually147 * exclusive with L_FILE.148 */149 #define L_DIRECTORY 2150 /**151 * When used with L_CREATE, L_EXCLUSIVE will cause the lookup to fail if the152 * object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used.153 */154 #define L_EXCLUSIVE 4155 /**156 * L_CREATE is used for creating both regular files and directories.157 */158 #define L_CREATE 8159 /**160 * L_LINK is used for linking to an already existing nodes.161 */162 #define L_LINK 16163 /**164 * L_UNLINK is used to remove leaves from the file system namespace. This flag165 * cannot be passed directly by the client, but will be set by VFS during166 * VFS_UNLINK.167 */168 #define L_UNLINK 32169 86 170 87 typedef enum vfs_node_type { … … 235 152 extern vfs_pair_t rootfs; /**< Root file system. */ 236 153 237 #define MAX_PATH_LEN (64 * 1024)238 239 #define PLB_SIZE (2 * MAX_PATH_LEN)240 241 154 /** Each instance of this type describes one path lookup in progress. */ 242 155 typedef struct { … … 260 173 extern fs_handle_t fs_name_to_handle(char *, bool); 261 174 262 extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *, vfs_pair_t *, 263 ...); 175 extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *, 176 vfs_pair_t *, ...); 177 extern int vfs_open_node_internal(vfs_lookup_res_t *); 264 178 265 179 extern bool vfs_nodes_init(void); … … 284 198 extern void vfs_mount(ipc_callid_t, ipc_call_t *); 285 199 extern void vfs_open(ipc_callid_t, ipc_call_t *); 200 extern void vfs_open_node(ipc_callid_t, ipc_call_t *); 201 extern void vfs_device(ipc_callid_t, ipc_call_t *); 202 extern void vfs_sync(ipc_callid_t, ipc_call_t *); 203 extern void vfs_node(ipc_callid_t, ipc_call_t *); 286 204 extern void vfs_close(ipc_callid_t, ipc_call_t *); 287 205 extern void vfs_read(ipc_callid_t, ipc_call_t *); -
uspace/srv/vfs/vfs_lookup.c
r215abc1 r05b9912 29 29 /** @addtogroup fs 30 30 * @{ 31 */ 31 */ 32 32 33 33 /** 34 * @file 34 * @file vfs_lookup.c 35 35 * @brief 36 36 */ … … 47 47 #include <vfs/canonify.h> 48 48 49 #define min(a, b) 49 #define min(a, b) ((a) < (b) ? (a) : (b)) 50 50 51 51 futex_t plb_futex = FUTEX_INITIALIZER; 52 link_t plb_head; 52 link_t plb_head; /**< PLB entry ring buffer. */ 53 53 uint8_t *plb = NULL; 54 54 55 55 /** Perform a path lookup. 56 56 * 57 * @param path Path to be resolved; it must be a NULL-terminated 58 * string. 59 * @param lflag Flags to be used during lookup. 60 * @param result Empty structure where the lookup result will be stored. 61 * Can be NULL. 62 * @param altroot If non-empty, will be used instead of rootfs as the root 63 * of the whole VFS tree. 64 * 65 * @return EOK on success or an error code from errno.h. 57 * @param path Path to be resolved; it must be a NULL-terminated 58 * string. 59 * @param lflag Flags to be used during lookup. 60 * @param result Empty structure where the lookup result will be stored. 61 * Can be NULL. 62 * @param altroot If non-empty, will be used instead of rootfs as the root 63 * of the whole VFS tree. 64 * 65 * @return EOK on success or an error code from errno.h. 66 * 66 67 */ 67 68 int vfs_lookup_internal(char *path, int lflag, vfs_lookup_res_t *result, … … 179 180 futex_up(&plb_futex); 180 181 181 if ((rc == EOK) && result) {182 if ((rc == EOK) && (result)) { 182 183 result->triplet.fs_handle = (fs_handle_t) IPC_GET_ARG1(answer); 183 184 result->triplet.dev_handle = (dev_handle_t) IPC_GET_ARG2(answer); … … 196 197 } 197 198 199 /** Perform a node open operation. 200 * 201 * @return EOK on success or an error code from errno.h. 202 * 203 */ 204 int vfs_open_node_internal(vfs_lookup_res_t *result) 205 { 206 int phone = vfs_grab_phone(result->triplet.fs_handle); 207 208 ipc_call_t answer; 209 aid_t req = async_send_2(phone, VFS_OPEN_NODE, 210 (ipcarg_t) result->triplet.dev_handle, 211 (ipcarg_t) result->triplet.index, &answer); 212 213 vfs_release_phone(phone); 214 215 async_serialize_start(); 216 ipcarg_t rc; 217 async_wait_for(req, &rc); 218 async_serialize_end(); 219 220 if (rc == EOK) { 221 result->size = (size_t) IPC_GET_ARG1(answer); 222 result->lnkcnt = (unsigned) IPC_GET_ARG2(answer); 223 if (IPC_GET_ARG3(answer) & L_FILE) 224 result->type = VFS_NODE_FILE; 225 else if (IPC_GET_ARG3(answer) & L_DIRECTORY) 226 result->type = VFS_NODE_DIRECTORY; 227 else 228 result->type = VFS_NODE_UNKNOWN; 229 } 230 231 return rc; 232 } 233 198 234 /** 199 235 * @} -
uspace/srv/vfs/vfs_node.c
r215abc1 r05b9912 181 181 hash_table_insert(&nodes, key, &node->nh_link); 182 182 } else { 183 node = hash_table_get_instance(tmp, vfs_node_t, nh_link); 183 node = hash_table_get_instance(tmp, vfs_node_t, nh_link); 184 184 if (node->type == VFS_NODE_UNKNOWN && 185 185 result->type != VFS_NODE_UNKNOWN) { … … 234 234 /** 235 235 * @} 236 */ 236 */ -
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 */ -
uspace/srv/vfs/vfs_register.c
r215abc1 r05b9912 279 279 dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n", 280 280 FS_NAME_MAXLEN, fs_info->vfs_info.name, fs_info->fs_handle); 281 282 /* Process pending mount requests possibly waiting283 * for this filesystem implementation.284 */285 vfs_process_pending_mount();286 281 } 287 282 … … 321 316 */ 322 317 fibril_inc_sercount(); 323 return fs->phone; 318 return fs->phone; 324 319 } 325 320 }
Note:
See TracChangeset
for help on using the changeset viewer.