Index: trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c
===================================================================
--- trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c	(revision 39257)
+++ trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c	(revision 39258)
@@ -864,6 +864,5 @@
 	sfp_mount_t *mnt,
 	char *path,
-	sffs_dirents_t **dirents,
-	sffs_stats_t **stats)
+	sffs_dirents_t **dirents)
 {
 	int error;
@@ -880,11 +879,10 @@
 	off_t offset;
 	sffs_dirents_t *cur_buf;
-	sffs_stats_t *cur_stats;
-	struct dirent64 *dirent;
+	struct sffs_dirent *dirent;
 	sffs_stat_t *stat;
 	unsigned short reclen;
+	unsigned short entlen;
 
 	*dirents = NULL;
-	*stats = NULL;
 
 	error = sfprov_open(mnt, path, &fp);
@@ -893,5 +891,5 @@
 
 	/*
-	 * Allocate the first dirents and stats buffers.
+	 * Allocate the first dirents buffers.
 	 */
 	*dirents = kmem_alloc(SFFS_DIRENTS_SIZE, KM_SLEEP);
@@ -903,13 +901,4 @@
 	cur_buf->sf_next = NULL;
 	cur_buf->sf_len = 0;
-
-	*stats = kmem_alloc(sizeof(**stats), KM_SLEEP);
-	if (*stats == NULL) {
-		error = (ENOSPC);
-		goto done;
-	}
-	cur_stats = *stats;
-	cur_stats->sf_next = NULL;
-	cur_stats->sf_num = 0;
 
 	/*
@@ -964,5 +953,6 @@
 			/* expand buffers if we need more space */
 			reclen = DIRENT64_RECLEN(strlen(info->name.String.utf8));
-			if (SFFS_DIRENTS_OFF + cur_buf->sf_len + reclen > SFFS_DIRENTS_SIZE) {
+			entlen = sizeof(sffs_stat_t) + reclen;
+			if (SFFS_DIRENTS_OFF + cur_buf->sf_len + entlen > SFFS_DIRENTS_SIZE) {
 				cur_buf->sf_next = kmem_alloc(SFFS_DIRENTS_SIZE, KM_SLEEP);
 				if (cur_buf->sf_next == NULL) {
@@ -975,28 +965,14 @@
 			}
 
-			if (cur_stats->sf_num >= SFFS_STATS_LEN) {
-				cur_stats->sf_next = kmem_alloc(sizeof(**stats), KM_SLEEP);
-				if (cur_stats->sf_next == NULL) {
-					error = (ENOSPC);
-					goto done;
-				}
-				cur_stats = cur_stats->sf_next;
-				cur_stats->sf_next = NULL;
-				cur_stats->sf_num = 0;
-			}
-
 			/* create the dirent with the name, offset, and len */
-			dirent = (dirent64_t *)
+			dirent = (struct sffs_dirent *)
 			    (((char *) &cur_buf->sf_entries[0]) + cur_buf->sf_len);
-			strncpy(&dirent->d_name[0], info->name.String.utf8, DIRENT64_NAMELEN(reclen));
-			dirent->d_reclen = reclen;
-			offset += reclen;
-			dirent->d_off = offset;
-
-			cur_buf->sf_len += reclen;
+			strncpy(&dirent->sf_entry.d_name[0], info->name.String.utf8, DIRENT64_NAMELEN(reclen));
+			dirent->sf_entry.d_reclen = reclen;
+			offset += entlen;
+			dirent->sf_entry.d_off = offset;
 
 			/* save the stats */
-			stat = &cur_stats->sf_stats[cur_stats->sf_num];
-			++cur_stats->sf_num;
+			stat = &dirent->sf_stat;
 
 			sfprov_mode_from_fmode(&stat->sf_mode, info->Info.Attr.fMode);
@@ -1007,4 +983,5 @@
 
 			/* next info */
+			cur_buf->sf_len += entlen;
 			size = offsetof (SHFLDIRINFO, name.String) + info->name.u16Size;
 			info = (SHFLDIRINFO *) ((uintptr_t) info + size);
@@ -1025,9 +1002,4 @@
 			*dirents = cur_buf;
 		}
-		while (*stats) {
-			cur_stats = (*stats)->sf_next;
-			kmem_free(*stats, sizeof(**stats));
-			*stats = cur_stats;
-		}
 	}
 	if (infobuff != NULL)
Index: trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h
===================================================================
--- trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h	(revision 39257)
+++ trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h	(revision 39258)
@@ -120,21 +120,4 @@
 extern int sfprov_rename(sfp_mount_t *, char *from, char *to, uint_t is_dir);
 
-/*
- * Read directory entries.
- */
-/*
- * a singly linked list of buffers, each containing an array of dirent's.
- * sf_len is length of the sf_entries array, in bytes.
- */
-typedef struct sffs_dirents {
-	struct sffs_dirents	*sf_next;
-	len_t			sf_len;
-	dirent64_t		sf_entries[1];
-} sffs_dirents_t;
-
-#define SFFS_DIRENTS_SIZE	8192
-#define SFFS_DIRENTS_OFF	(offsetof(sffs_dirents_t, sf_entries[0]))
-#define SFFS_STATS_LEN		100
-
 typedef struct sffs_stat {
 	mode_t		sf_mode;
@@ -145,12 +128,25 @@
 } sffs_stat_t;
 
-typedef struct sffs_stats {
-	struct sffs_stats	*sf_next;
-	len_t			sf_num;
-	sffs_stat_t		sf_stats[SFFS_STATS_LEN];
-} sffs_stats_t;
+/*
+ * Read directory entries.
+ */
+/*
+ * a singly linked list of buffers, each containing an array of stat's+dirent's.
+ * sf_len is length of the sf_entries array, in bytes.
+ */
+typedef struct sffs_dirents {
+	struct sffs_dirents	*sf_next;
+	len_t			sf_len;
+	struct sffs_dirent {
+		sffs_stat_t	sf_stat;
+		dirent64_t	sf_entry;	/* this is variable length */
+	}			sf_entries[1];
+} sffs_dirents_t;
 
-extern int sfprov_readdir(sfp_mount_t *mnt, char *path, sffs_dirents_t **dirents,
-    sffs_stats_t **stats);
+#define SFFS_DIRENTS_SIZE	8192
+#define SFFS_DIRENTS_OFF	(offsetof(sffs_dirents_t, sf_entries[0]))
+
+extern int sfprov_readdir(sfp_mount_t *mnt, char *path,
+	sffs_dirents_t **dirents);
 
 #ifdef	__cplusplus
Index: trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
===================================================================
--- trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c	(revision 39257)
+++ trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c	(revision 39258)
@@ -171,10 +171,4 @@
 		node->sf_dir_list = next;
 	}
-
-	while (node->sf_dir_stats != NULL) {
-		sffs_stats_t *next = node->sf_dir_stats->sf_next;
-		kmem_free(node->sf_dir_stats, sizeof(*node->sf_dir_stats));
-		node->sf_dir_stats = next;
-	}
 }
 
@@ -262,5 +256,4 @@
 		++parent->sf_children;
 	node->sf_dir_list = NULL;
-	node->sf_dir_stats = NULL;
 	if (stat != NULL) {
 		node->sf_stat = *stat;
@@ -702,9 +695,8 @@
 	sfnode_t *dir = VN2SFN(vp);
 	sfnode_t *node;
-	struct dirent64 *dirent;
+	struct sffs_dirent *dirent = NULL;
 	sffs_dirents_t *cur_buf;
-	sffs_stats_t *cur_stats;
-	int cur_snum;
-	offset_t offset;
+	offset_t offset = 0;
+	offset_t orig_off = uiop->uio_loffset;
 	int dummy_eof;
 	int error = 0;
@@ -734,54 +726,82 @@
 	if (dir->sf_dir_list == NULL) {
 		error = sfprov_readdir(dir->sf_sffs->sf_handle, dir->sf_path,
-		    &dir->sf_dir_list, &dir->sf_dir_stats);
+		    &dir->sf_dir_list);
 		if (error != 0)
 			goto done;
 	}
 
+ 	/*
+	 * Validate and skip to the desired offset.
+	 */
+	cur_buf = dir->sf_dir_list;
+	offset = 0;
+
+	while (cur_buf != NULL &&
+	    offset + cur_buf->sf_len <= uiop->uio_loffset) {
+		offset += cur_buf->sf_len;
+		cur_buf = cur_buf->sf_next;
+	}
+
+	if (cur_buf == NULL && offset != uiop->uio_loffset) {
+		error = EINVAL;
+		goto done;
+	}
+	if (cur_buf != NULL && offset != uiop->uio_loffset) {
+		offset_t off = offset;
+		int step;
+		dirent = &cur_buf->sf_entries[0];
+
+		while (off < uiop->uio_loffset) {
+			if (dirent->sf_entry.d_off == uiop->uio_loffset)
+				break;
+			step = sizeof(sffs_stat_t) + dirent->sf_entry.d_reclen;
+			dirent = (struct sffs_dirent *) (((char *) dirent) + step);
+			off += step;
+		}
+
+		if (off >= uiop->uio_loffset) {
+			error = EINVAL;
+			goto done;
+		}
+	}
+
+	offset = uiop->uio_loffset - offset;
+
 	/*
 	 * Lookup each of the names, so that we have ino's, and copy to
 	 * result buffer.
 	 */
-	offset = 0;
-	cur_buf = dir->sf_dir_list;
-	cur_stats = dir->sf_dir_stats;
-	cur_snum = 0;
 	while (cur_buf != NULL) {
-		if (offset + cur_buf->sf_len <= uiop->uio_loffset) {
-			offset += cur_buf->sf_len;
+		if (offset >= cur_buf->sf_len) {
 			cur_buf = cur_buf->sf_next;
+			offset = 0;
 			continue;
 		}
 
-		if (cur_snum >= SFFS_STATS_LEN) {
-			cur_stats = cur_stats->sf_next;
-			cur_snum = 0;
-		}
-
-		dirent = (dirent64_t *)
-		    (((char *) &cur_buf->sf_entries[0]) +
-		     (uiop->uio_loffset - offset));
-		if (dirent->d_reclen > uiop->uio_resid)
+		dirent = (struct sffs_dirent *)
+		    (((char *) &cur_buf->sf_entries[0]) + offset);
+		if (dirent->sf_entry.d_reclen > uiop->uio_resid)
 			break;
 
-		if (strcmp(dirent->d_name, ".") == 0) {
+		if (strcmp(dirent->sf_entry.d_name, ".") == 0) {
 			node = dir;
-		} else if (strcmp(dirent->d_name, "..") == 0) {
+		} else if (strcmp(dirent->sf_entry.d_name, "..") == 0) {
 			node = dir->sf_parent;
 			if (node == NULL)
 				node = dir;
 		} else {
-			node = sfnode_lookup(dir, dirent->d_name, VNON,
-			    &cur_stats->sf_stats[cur_snum],
-			    sfnode_cur_time_usec(), NULL);
+			node = sfnode_lookup(dir, dirent->sf_entry.d_name, VNON,
+			    &dirent->sf_stat, sfnode_cur_time_usec(), NULL);
 			if (node == NULL)
 				panic("sffs_readdir() lookup failed");
 		}
-		dirent->d_ino = node->sf_ino;
-
-		error = uiomove(dirent, dirent->d_reclen, UIO_READ, uiop);
-		++cur_snum;
+		dirent->sf_entry.d_ino = node->sf_ino;
+
+		error = uiomove(&dirent->sf_entry, dirent->sf_entry.d_reclen, UIO_READ, uiop);
 		if (error != 0)
 			break;
+
+		uiop->uio_loffset= dirent->sf_entry.d_off;
+		offset += sizeof(sffs_stat_t) + dirent->sf_entry.d_reclen;
 	}
 	if (error == 0 && cur_buf == NULL)
@@ -789,4 +809,6 @@
 done:
 	mutex_exit(&sffs_lock);
+	if (error != 0)
+		uiop->uio_loffset = orig_off;
 	return (error);
 }
Index: trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h
===================================================================
--- trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h	(revision 39257)
+++ trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h	(revision 39258)
@@ -60,5 +60,4 @@
 	uint64_t	sf_stat_time;	/* last-modified time of sf_stat */
 	sffs_dirents_t	*sf_dir_list;	/* list of entries for this directory */
-	sffs_stats_t	*sf_dir_stats;	/* file attrs for the above entries */
 } sfnode_t;
 
