diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-11-07 04:08:01 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-11-07 04:08:01 -0800 |
| commit | 332d2f06c39331c6984701200dc38ee296f0e551 (patch) | |
| tree | 866d89229dac7cf97f7a8aac292e04afc5ebfd0e /fs | |
| parent | 22d1d71aa7fc4b53b19e5b25f8999a744ac7c2a2 (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.c | 13 |
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) { |
