summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-11-07 04:08:01 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-11-07 04:08:01 -0800
commit332d2f06c39331c6984701200dc38ee296f0e551 (patch)
tree866d89229dac7cf97f7a8aac292e04afc5ebfd0e /fs
parent22d1d71aa7fc4b53b19e5b25f8999a744ac7c2a2 (diff)
[PATCH] Fix ext3_dx_readdir
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> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext3/dir.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index b2bb90817371..2e2af5cba1ce 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -418,7 +418,7 @@ static int call_filldir(struct file * filp, void * dirent,
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 * filp,
* 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 * filp,
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) {