Changeset 39258 in vbox
- Timestamp:
- Nov 9, 2011 6:50:33 PM (13 years ago)
- Location:
- trunk/src/VBox/Additions/solaris/SharedFolders
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c
r39249 r39258 864 864 sfp_mount_t *mnt, 865 865 char *path, 866 sffs_dirents_t **dirents, 867 sffs_stats_t **stats) 866 sffs_dirents_t **dirents) 868 867 { 869 868 int error; … … 880 879 off_t offset; 881 880 sffs_dirents_t *cur_buf; 882 sffs_stats_t *cur_stats; 883 struct dirent64 *dirent; 881 struct sffs_dirent *dirent; 884 882 sffs_stat_t *stat; 885 883 unsigned short reclen; 884 unsigned short entlen; 886 885 887 886 *dirents = NULL; 888 *stats = NULL;889 887 890 888 error = sfprov_open(mnt, path, &fp); … … 893 891 894 892 /* 895 * Allocate the first dirents and statsbuffers.893 * Allocate the first dirents buffers. 896 894 */ 897 895 *dirents = kmem_alloc(SFFS_DIRENTS_SIZE, KM_SLEEP); … … 903 901 cur_buf->sf_next = NULL; 904 902 cur_buf->sf_len = 0; 905 906 *stats = kmem_alloc(sizeof(**stats), KM_SLEEP);907 if (*stats == NULL) {908 error = (ENOSPC);909 goto done;910 }911 cur_stats = *stats;912 cur_stats->sf_next = NULL;913 cur_stats->sf_num = 0;914 903 915 904 /* … … 964 953 /* expand buffers if we need more space */ 965 954 reclen = DIRENT64_RECLEN(strlen(info->name.String.utf8)); 966 if (SFFS_DIRENTS_OFF + cur_buf->sf_len + reclen > SFFS_DIRENTS_SIZE) { 955 entlen = sizeof(sffs_stat_t) + reclen; 956 if (SFFS_DIRENTS_OFF + cur_buf->sf_len + entlen > SFFS_DIRENTS_SIZE) { 967 957 cur_buf->sf_next = kmem_alloc(SFFS_DIRENTS_SIZE, KM_SLEEP); 968 958 if (cur_buf->sf_next == NULL) { … … 975 965 } 976 966 977 if (cur_stats->sf_num >= SFFS_STATS_LEN) {978 cur_stats->sf_next = kmem_alloc(sizeof(**stats), KM_SLEEP);979 if (cur_stats->sf_next == NULL) {980 error = (ENOSPC);981 goto done;982 }983 cur_stats = cur_stats->sf_next;984 cur_stats->sf_next = NULL;985 cur_stats->sf_num = 0;986 }987 988 967 /* create the dirent with the name, offset, and len */ 989 dirent = ( dirent64_t *)968 dirent = (struct sffs_dirent *) 990 969 (((char *) &cur_buf->sf_entries[0]) + cur_buf->sf_len); 991 strncpy(&dirent->d_name[0], info->name.String.utf8, DIRENT64_NAMELEN(reclen)); 992 dirent->d_reclen = reclen; 993 offset += reclen; 994 dirent->d_off = offset; 995 996 cur_buf->sf_len += reclen; 970 strncpy(&dirent->sf_entry.d_name[0], info->name.String.utf8, DIRENT64_NAMELEN(reclen)); 971 dirent->sf_entry.d_reclen = reclen; 972 offset += entlen; 973 dirent->sf_entry.d_off = offset; 997 974 998 975 /* save the stats */ 999 stat = &cur_stats->sf_stats[cur_stats->sf_num]; 1000 ++cur_stats->sf_num; 976 stat = &dirent->sf_stat; 1001 977 1002 978 sfprov_mode_from_fmode(&stat->sf_mode, info->Info.Attr.fMode); … … 1007 983 1008 984 /* next info */ 985 cur_buf->sf_len += entlen; 1009 986 size = offsetof (SHFLDIRINFO, name.String) + info->name.u16Size; 1010 987 info = (SHFLDIRINFO *) ((uintptr_t) info + size); … … 1025 1002 *dirents = cur_buf; 1026 1003 } 1027 while (*stats) {1028 cur_stats = (*stats)->sf_next;1029 kmem_free(*stats, sizeof(**stats));1030 *stats = cur_stats;1031 }1032 1004 } 1033 1005 if (infobuff != NULL) -
trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h
r31691 r39258 120 120 extern int sfprov_rename(sfp_mount_t *, char *from, char *to, uint_t is_dir); 121 121 122 /*123 * Read directory entries.124 */125 /*126 * a singly linked list of buffers, each containing an array of dirent's.127 * sf_len is length of the sf_entries array, in bytes.128 */129 typedef struct sffs_dirents {130 struct sffs_dirents *sf_next;131 len_t sf_len;132 dirent64_t sf_entries[1];133 } sffs_dirents_t;134 135 #define SFFS_DIRENTS_SIZE 8192136 #define SFFS_DIRENTS_OFF (offsetof(sffs_dirents_t, sf_entries[0]))137 #define SFFS_STATS_LEN 100138 139 122 typedef struct sffs_stat { 140 123 mode_t sf_mode; … … 145 128 } sffs_stat_t; 146 129 147 typedef struct sffs_stats { 148 struct sffs_stats *sf_next; 149 len_t sf_num; 150 sffs_stat_t sf_stats[SFFS_STATS_LEN]; 151 } sffs_stats_t; 130 /* 131 * Read directory entries. 132 */ 133 /* 134 * a singly linked list of buffers, each containing an array of stat's+dirent's. 135 * sf_len is length of the sf_entries array, in bytes. 136 */ 137 typedef struct sffs_dirents { 138 struct sffs_dirents *sf_next; 139 len_t sf_len; 140 struct sffs_dirent { 141 sffs_stat_t sf_stat; 142 dirent64_t sf_entry; /* this is variable length */ 143 } sf_entries[1]; 144 } sffs_dirents_t; 152 145 153 extern int sfprov_readdir(sfp_mount_t *mnt, char *path, sffs_dirents_t **dirents, 154 sffs_stats_t **stats); 146 #define SFFS_DIRENTS_SIZE 8192 147 #define SFFS_DIRENTS_OFF (offsetof(sffs_dirents_t, sf_entries[0])) 148 149 extern int sfprov_readdir(sfp_mount_t *mnt, char *path, 150 sffs_dirents_t **dirents); 155 151 156 152 #ifdef __cplusplus -
trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
r39249 r39258 171 171 node->sf_dir_list = next; 172 172 } 173 174 while (node->sf_dir_stats != NULL) {175 sffs_stats_t *next = node->sf_dir_stats->sf_next;176 kmem_free(node->sf_dir_stats, sizeof(*node->sf_dir_stats));177 node->sf_dir_stats = next;178 }179 173 } 180 174 … … 262 256 ++parent->sf_children; 263 257 node->sf_dir_list = NULL; 264 node->sf_dir_stats = NULL;265 258 if (stat != NULL) { 266 259 node->sf_stat = *stat; … … 702 695 sfnode_t *dir = VN2SFN(vp); 703 696 sfnode_t *node; 704 struct dirent64 *dirent;697 struct sffs_dirent *dirent = NULL; 705 698 sffs_dirents_t *cur_buf; 706 sffs_stats_t *cur_stats; 707 int cur_snum; 708 offset_t offset; 699 offset_t offset = 0; 700 offset_t orig_off = uiop->uio_loffset; 709 701 int dummy_eof; 710 702 int error = 0; … … 734 726 if (dir->sf_dir_list == NULL) { 735 727 error = sfprov_readdir(dir->sf_sffs->sf_handle, dir->sf_path, 736 &dir->sf_dir_list , &dir->sf_dir_stats);728 &dir->sf_dir_list); 737 729 if (error != 0) 738 730 goto done; 739 731 } 740 732 733 /* 734 * Validate and skip to the desired offset. 735 */ 736 cur_buf = dir->sf_dir_list; 737 offset = 0; 738 739 while (cur_buf != NULL && 740 offset + cur_buf->sf_len <= uiop->uio_loffset) { 741 offset += cur_buf->sf_len; 742 cur_buf = cur_buf->sf_next; 743 } 744 745 if (cur_buf == NULL && offset != uiop->uio_loffset) { 746 error = EINVAL; 747 goto done; 748 } 749 if (cur_buf != NULL && offset != uiop->uio_loffset) { 750 offset_t off = offset; 751 int step; 752 dirent = &cur_buf->sf_entries[0]; 753 754 while (off < uiop->uio_loffset) { 755 if (dirent->sf_entry.d_off == uiop->uio_loffset) 756 break; 757 step = sizeof(sffs_stat_t) + dirent->sf_entry.d_reclen; 758 dirent = (struct sffs_dirent *) (((char *) dirent) + step); 759 off += step; 760 } 761 762 if (off >= uiop->uio_loffset) { 763 error = EINVAL; 764 goto done; 765 } 766 } 767 768 offset = uiop->uio_loffset - offset; 769 741 770 /* 742 771 * Lookup each of the names, so that we have ino's, and copy to 743 772 * result buffer. 744 773 */ 745 offset = 0;746 cur_buf = dir->sf_dir_list;747 cur_stats = dir->sf_dir_stats;748 cur_snum = 0;749 774 while (cur_buf != NULL) { 750 if (offset + cur_buf->sf_len <= uiop->uio_loffset) { 751 offset += cur_buf->sf_len; 775 if (offset >= cur_buf->sf_len) { 752 776 cur_buf = cur_buf->sf_next; 777 offset = 0; 753 778 continue; 754 779 } 755 780 756 if (cur_snum >= SFFS_STATS_LEN) { 757 cur_stats = cur_stats->sf_next; 758 cur_snum = 0; 759 } 760 761 dirent = (dirent64_t *) 762 (((char *) &cur_buf->sf_entries[0]) + 763 (uiop->uio_loffset - offset)); 764 if (dirent->d_reclen > uiop->uio_resid) 781 dirent = (struct sffs_dirent *) 782 (((char *) &cur_buf->sf_entries[0]) + offset); 783 if (dirent->sf_entry.d_reclen > uiop->uio_resid) 765 784 break; 766 785 767 if (strcmp(dirent-> d_name, ".") == 0) {786 if (strcmp(dirent->sf_entry.d_name, ".") == 0) { 768 787 node = dir; 769 } else if (strcmp(dirent-> d_name, "..") == 0) {788 } else if (strcmp(dirent->sf_entry.d_name, "..") == 0) { 770 789 node = dir->sf_parent; 771 790 if (node == NULL) 772 791 node = dir; 773 792 } else { 774 node = sfnode_lookup(dir, dirent->d_name, VNON, 775 &cur_stats->sf_stats[cur_snum], 776 sfnode_cur_time_usec(), NULL); 793 node = sfnode_lookup(dir, dirent->sf_entry.d_name, VNON, 794 &dirent->sf_stat, sfnode_cur_time_usec(), NULL); 777 795 if (node == NULL) 778 796 panic("sffs_readdir() lookup failed"); 779 797 } 780 dirent->d_ino = node->sf_ino; 781 782 error = uiomove(dirent, dirent->d_reclen, UIO_READ, uiop); 783 ++cur_snum; 798 dirent->sf_entry.d_ino = node->sf_ino; 799 800 error = uiomove(&dirent->sf_entry, dirent->sf_entry.d_reclen, UIO_READ, uiop); 784 801 if (error != 0) 785 802 break; 803 804 uiop->uio_loffset= dirent->sf_entry.d_off; 805 offset += sizeof(sffs_stat_t) + dirent->sf_entry.d_reclen; 786 806 } 787 807 if (error == 0 && cur_buf == NULL) … … 789 809 done: 790 810 mutex_exit(&sffs_lock); 811 if (error != 0) 812 uiop->uio_loffset = orig_off; 791 813 return (error); 792 814 } -
trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h
r38901 r39258 60 60 uint64_t sf_stat_time; /* last-modified time of sf_stat */ 61 61 sffs_dirents_t *sf_dir_list; /* list of entries for this directory */ 62 sffs_stats_t *sf_dir_stats; /* file attrs for the above entries */63 62 } sfnode_t; 64 63
Note:
See TracChangeset
for help on using the changeset viewer.