2004-11-17 02:39:36

by Chuck Ebbert

[permalink] [raw]
Subject: Re: [POSSIBLE-BUG] telldir() broken on ext3

r6144 wrote:
> telldir() broken on large ext3 dir_index'd directories because
> getdents() gives d_off==0 for the first entry

Does this patch fix your problem?

# ext3_readdir.patch
# fs/ext3/dir.c -5 +8
#
# 2004/11/07 20:08:01-08:00 [email protected]
# [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 <[email protected]>
# Signed-off-by: Linus Torvalds <[email protected]>
#
--- 2.6.9/fs/ext3/dir.c
+++ 2.6.9.1/fs/ext3/dir.c
@@ -418,7 +418,7 @@
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 @@
* 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 @@
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) {

--Chuck Ebbert 16-Nov-04 18:22:33