diff -u -r -p -N ../../src.old/lib/libc/gen/closedir.c libc/gen/closedir.c
--- lib/libc/gen/closedir.c	2005-04-26 10:04:59.000000000 -0500
+++ lib/libc/gen/closedir.c	2008-04-16 20:38:41.000000000 -0500
@@ -44,6 +44,7 @@
 #include "un-namespace.h"
 
 #include "libc_private.h"
+#include "dirent_private.h"
 
 /*
  * close a directory.
@@ -55,12 +56,19 @@ closedir(DIR *dirp)
 
 	if (__isthreaded)
 		_pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
-	_seekdir(dirp, dirp->dd_rewind);	/* free seekdir storage */
+
 	fd = dirp->dd_fd;
 	dirp->dd_fd = -1;
 	dirp->dd_loc = 0;
-	free(dirp->dd_buf);
-	_reclaim_telldir(dirp);
+        free(dirp->dd_buf);
+
+        /* free seekdir/telldir storage */
+        for (poslist = dirp->dd_internal; poslist; ) {
+                struct dirpos *nextpos = poslist->dp_next;
+                free(poslist);
+                poslist = nextpos;
+        }
+
 	if (__isthreaded) {
 		_pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
 		_pthread_mutex_destroy((pthread_mutex_t *)&dirp->dd_lock);
diff -u -r -p -N ../../src.old/lib/libc/gen/dirent_private.h libc/gen/dirent_private.h
--- /dev/null	1969-12-31 18:00:00.000000000 -0600
+++ lib/libc/gen/dirent_private.h	2008-04-16 20:39:14.000000000 -0500
@@ -0,0 +1,20 @@
+
+/*      $NetBSD: dirent_private.h,v 1.1 2006/05/17 20:36:50 christos Exp $      */
+
+/*
+ * One struct _dirpos is malloced to describe the current directory
+ * position each time telldir is called. It records the current magic
+ * cookie returned by getdirentries and the offset within the buffer
+ * associated with that return value.
+ */
+struct dirpos {
+        struct dirpos *dp_next; /* next structure in list */
+        off_t   dp_seek;        /* magic cookie returned by getdirentries */
+        long    dp_loc;         /* offset of entry in buffer */
+};
+
+struct _dirdesc;
+void _seekdir_unlocked(struct _dirdesc *, long);
+long _telldir_unlocked(struct _dirdesc *);
+
+
diff -u -r -p -N ../../src.old/lib/libc/gen/opendir.c libc/gen/opendir.c
--- lib/libc/gen/opendir.c	2005-11-12 18:07:42.000000000 -0600
+++ lib/libc/gen/opendir.c	2008-04-16 20:42:41.000000000 -0500
@@ -47,6 +47,7 @@
 #include <string.h>
 #include <unistd.h>
 #include "un-namespace.h"
+#include "dirent_private.h"
 
 /*
  * Open a directory.
@@ -113,7 +114,8 @@ __opendir2(const char *name, int flags)
 	/*
 	 * Set up seek point for rewinddir.
 	 */
-	dirp->dd_rewind = telldir(dirp);
+	dirp->dd_internal = NULL;
+	(void)telldir(dirp);
 
 	return (dirp);
 
diff -u -r -p -N ../../src.old/lib/libc/gen/rewinddir.c libc/gen/rewinddir.c
--- lib/libc/gen/rewinddir.c	2005-04-26 03:48:19.000000000 -0500
+++ lib/libc/gen/rewinddir.c	2008-04-16 20:43:18.000000000 -0500
@@ -37,10 +37,16 @@
  */
 
 #include <dirent.h>
+#include "dirent_private.h"
 
 void
 rewinddir(DIR *dirp)
 {
-	_seekdir(dirp, dirp->dd_rewind);
-	dirp->dd_rewind = telldir(dirp);
+       struct dirpos *dp = dirp->dd_internal;
+
+       while (dp->dp_next)
+               dp = dp->dp_next;
+
+       _seekdir(dirp, (long)(intptr_t)dp);
+
 }
diff -u -r -p -N ../../src.old/lib/libc/gen/seekdir.c libc/gen/seekdir.c
--- lib/libc/gen/seekdir.c	2005-11-19 16:32:53.000000000 -0600
+++ lib/libc/gen/seekdir.c	2008-04-16 20:43:54.000000000 -0500
@@ -43,6 +43,7 @@
 #include "un-namespace.h"
 
 #include "libc_private.h"
+#include "dirent_private.h"
 
 /*
  * Seek to an entry in a directory.
diff -u -r -p -N lib/libc/gen/telldir.c libc/gen/telldir.c
--- lib/libc/gen/telldir.c	2007-11-20 23:48:31.000000000 -0600
+++ lib/libc/gen/telldir.c	2008-04-16 20:53:06.000000000 -0500
@@ -45,57 +45,30 @@
 #include "un-namespace.h"
 
 #include "libc_private.h"
-
-/*
- * The option SINGLEUSE may be defined to say that a telldir
- * cookie may be used only once before it is freed. This option
- * is used to avoid having memory usage grow without bound.
- */
-#define SINGLEUSE
-
-/*
- * One of these structures is malloced to describe the current directory
- * position each time telldir is called. It records the current magic
- * cookie returned by getdirentries and the offset within the buffer
- * associated with that return value.
- */
-struct ddloc {
-	struct	ddloc *loc_next;/* next structure in list */
-	long	loc_index;	/* key associated with structure */
-	off_t	loc_seek;	/* magic cookie returned by getdirentries */
-	long	loc_loc;	/* offset of entry in buffer */
-	const DIR* loc_dirp;	/* directory which used this entry */
-};
-
-#define	NDIRHASH	32	/* Num of hash lists, must be a power of 2 */
-#define	LOCHASH(i)	((i)&(NDIRHASH-1))
-
-static long	dd_loccnt;	/* Index of entry for sequential readdir's */
-static struct	ddloc *dd_hash[NDIRHASH];   /* Hash list heads for ddlocs */
+#include "dirent_private.h"
 
 /*
  * return a pointer into a directory
  */
 long
-telldir(const DIR *dirp)
+telldir(DIR *dirp)
 {
-	int index;
-	struct ddloc *lp;
+        struct dirpos *lp;
 
-	if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL)
-		return (-1);
-	if (__isthreaded)
-		_pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
-	index = dd_loccnt++;
-	lp->loc_index = index;
-	lp->loc_seek = dirp->dd_seek;
-	lp->loc_loc = dirp->dd_loc;
-	lp->loc_dirp = dirp;
-	lp->loc_next = dd_hash[LOCHASH(index)];
-	dd_hash[LOCHASH(index)] = lp;
-	if (__isthreaded)
-		_pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
-	return (index);
+        for (lp = dirp->dd_internal; lp; lp = lp->dp_next)
+                if (lp->dp_seek == dirp->dd_seek &&
+                    lp->dp_loc == dirp->dd_loc)
+                        return (intptr_t)lp;
+        if ((lp = malloc(sizeof(*lp))) == NULL)
+                return (-1);
+
+        lp->dp_seek = dirp->dd_seek;
+        lp->dp_loc = dirp->dd_loc;
+        lp->dp_next = dirp->dd_internal;
+        dirp->dd_internal = lp;
+ 
+        return (intptr_t)lp;
+  
 }
 
 /*
@@ -105,59 +78,21 @@ telldir(const DIR *dirp)
 void
 _seekdir(DIR *dirp, long loc)
 {
-	struct ddloc *lp;
-	struct ddloc **prevlp;
-	struct dirent *dp;
-
-	prevlp = &dd_hash[LOCHASH(loc)];
-	lp = *prevlp;
-	while (lp != NULL) {
-		if (lp->loc_index == loc)
-			break;
-		prevlp = &lp->loc_next;
-		lp = lp->loc_next;
-	}
-	if (lp == NULL)
-		return;
-	if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
-		goto found;
-	lseek(dirp->dd_fd, lp->loc_seek, SEEK_SET);
-	dirp->dd_seek = lp->loc_seek;
-	dirp->dd_loc = 0;
-	while (dirp->dd_loc < lp->loc_loc) {
-		dp = _readdir_unlocked(dirp);
-		if (dp == NULL)
-			break;
-	}
-found:
-#ifdef SINGLEUSE
-	*prevlp = lp->loc_next;
-	free((caddr_t)lp);
-#endif
-}
+        struct dirpos *lp;
+        for (lp = dirp->dd_internal; lp; lp = lp->dp_next)
+                if ((intptr_t)lp == loc)
+                        break;
+
+        if (lp == NULL)
+                return;
+
+        if (lp->dp_loc == dirp->dd_loc && lp->dp_seek == dirp->dd_seek)
+                return;
+
+        dirp->dd_seek = lseek(dirp->dd_fd, lp->dp_seek, SEEK_SET);
+        dirp->dd_loc = 0;
+        while (dirp->dd_loc < lp->dp_loc)
+                if (_readdir_unlocked(dirp) == NULL)
+                        break;
 
-/*
- * Reclaim memory for telldir cookies which weren't used.
- */
-void
-_reclaim_telldir(DIR *dirp)
-{
-	struct ddloc *lp;
-	struct ddloc **prevlp;
-	int i;
-
-	for (i = 0; i < NDIRHASH; i++) {
-		prevlp = &dd_hash[i];
-		lp = *prevlp;
-		while (lp != NULL) {
-			if (lp->loc_dirp == dirp) {
-				*prevlp = lp->loc_next;
-				free((caddr_t)lp);
-				lp = *prevlp;
-				continue;
-			}
-			prevlp = &lp->loc_next;
-			lp = lp->loc_next;
-		}
-	}
 }
--- include/dirent.h	2007-11-20 15:03:43.000000000 -0600
+++ include/dirent.h	2008-03-12 11:17:12.000000000 -0500
@@ -59,7 +59,7 @@
 	char	*dd_buf;	/* data buffer */
 	int	dd_len;		/* size of data buffer */
 	long	dd_unused01;	/* old magic cookie returned by getdirentries */
-	long	dd_rewind;	/* magic cookie for rewinding */
+	void    *dd_internal;   /* state for seekdir/telldir */
 	int	dd_flags;	/* flags for readdir */
 	void	*dd_lock;	/* hack to avoid include <pthread.h> */
 	off_t	dd_seek;	/* new magic cookie returned by getdirentries */
@@ -90,7 +90,7 @@
 int closedir (DIR *);
 #ifndef _POSIX_SOURCE
 DIR *__opendir2 (const char *, int);
-long telldir (const DIR *);
+long telldir (DIR *);
 struct dirent *_readdir_unlocked(DIR *);
 void seekdir(DIR *, long);
 void _reclaim_telldir(DIR *);
