aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/namei.c
diff options
context:
space:
mode:
authorAndreas Dilger <adilger@clusterfs.com>2005-06-23 03:09:45 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-23 12:45:26 -0400
commitacfa1823d33859b0db77701726c9ca5ccc6e6f25 (patch)
tree356c2edeed8e8a505ed03c6f9d04dc659e84d341 /fs/ext3/namei.c
parentd6e711448137ca3301512cec41a2c2ce852b3d0a (diff)
[PATCH] Support for dx directories in ext3_get_parent (NFSD)
Henrik Grubbstrom noted: The 2.6.10 ext3_get_parent attempts to use ext3_find_entry to look up the entry "..", which fails for dx directories since ".." is not present in the directory hash table. The patch below solves this by looking up the dotdot entry in the dx_root block. Typical symptoms of the above bug are intermittent claims by nfsd that files or directories are missing on exported ext3 filesystems. cf https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=3D150759 and https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=3D144556 ext3_get_parent() is IMHO the wrong place to fix this bug as it introduces a lot of internals from htree into that function. Instead, I think this should be fixed in ext3_find_entry() as in the below patch. This has the added advantage that it works for any callers of ext3_find_entry() and not just ext3_lookup_parent(). Signed-off-by: Andreas Dilger <adilger@clusterfs.com> Signed-off-by: Henrik Grubbstrom <grubba@grubba.org> Cc: <ext2-devel@lists.sourceforge.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ext3/namei.c')
-rw-r--r--fs/ext3/namei.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 79742d824a0a..60e44e6dd7a6 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -932,8 +932,16 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
932 struct inode *dir = dentry->d_parent->d_inode; 932 struct inode *dir = dentry->d_parent->d_inode;
933 933
934 sb = dir->i_sb; 934 sb = dir->i_sb;
935 if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err))) 935 /* NFS may look up ".." - look at dx_root directory block */
936 return NULL; 936 if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
937 if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))
938 return NULL;
939 } else {
940 frame = frames;
941 frame->bh = NULL; /* for dx_release() */
942 frame->at = (struct dx_entry *)frames; /* hack for zero entry*/
943 dx_set_block(frame->at, 0); /* dx_root block is 0 */
944 }
937 hash = hinfo.hash; 945 hash = hinfo.hash;
938 do { 946 do {
939 block = dx_get_block(frame->at); 947 block = dx_get_block(frame->at);