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 --- 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) { _