When there are more than one entry in fname linked list, the current
implementation of ext3_dx_readdir() can not traverse all entries correctly
in the case that call_filldir() fails.

If we use system call readdir() to read entries in a directory which
happens that "." and ".." in the same fname linked list.  Each time we call
readdir(), it will return the "." entry and never returns 0 which indicates
that all entries are read.

Although chances that more than one entry are in one fname linked list are
very slim, it does exist.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/ext3/dir.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff -puN fs/ext3/dir.c~fix-ext3_dx_readdir fs/ext3/dir.c
--- 25/fs/ext3/dir.c~fix-ext3_dx_readdir	Mon Nov  1 16:06:23 2004
+++ 25-akpm/fs/ext3/dir.c	Mon Nov  1 16:06:23 2004
@@ -418,7 +418,7 @@ static int call_filldir(struct file * fi
 				get_dtype(sb, fname->file_type));
 		if (error) {
 			filp->f_pos = curr_pos;
-			info->extra_fname = fname->next;
+			info->extra_fname = fname;
 			return error;
 		}
 		fname = fname->next;
@@ -457,9 +457,12 @@ static int ext3_dx_readdir(struct file *
 	 * If there are any leftover names on the hash collision
 	 * chain, return them first.
 	 */
-	if (info->extra_fname &&
-	    call_filldir(filp, dirent, filldir, info->extra_fname))
-		goto finished;
+	if (info->extra_fname) {
+		if(call_filldir(filp, dirent, filldir, info->extra_fname))
+			goto finished;
+		else
+			goto next_entry;
+	}
 
 	if (!info->curr_node)
 		info->curr_node = rb_first(&info->root);
@@ -492,7 +495,7 @@ static int ext3_dx_readdir(struct file *
 		info->curr_minor_hash = fname->minor_hash;
 		if (call_filldir(filp, dirent, filldir, fname))
 			break;
-
+next_entry:
 		info->curr_node = rb_next(info->curr_node);
 		if (!info->curr_node) {
 			if (info->next_hash == ~0) {
_