1 Index: linux-2.6.18.i386/fs/ext4/iopen.c
2 ===================================================================
3 --- linux-2.6.18.i386.orig/fs/ext4/iopen.c
4 +++ linux-2.6.18.i386/fs/ext4/iopen.c
5 @@ -91,9 +91,12 @@ static struct dentry *iopen_lookup(struc
6 assert(!(alternate->d_flags & DCACHE_DISCONNECTED));
9 - if (!list_empty(&inode->i_dentry)) {
10 - alternate = list_entry(inode->i_dentry.next,
11 - struct dentry, d_alias);
12 + list_for_each(lp, &inode->i_dentry) {
13 + alternate = list_entry(lp, struct dentry, d_alias);
14 + /* ignore dentries created for ".." to preserve
15 + * proper dcache hierarchy -- bug 10458 */
16 + if (alternate->d_flags & DCACHE_NFSFS_RENAMED)
18 dget_locked(alternate);
19 spin_lock(&alternate->d_lock);
20 alternate->d_flags |= DCACHE_REFERENCED;
21 Index: linux-2.6.18.i386/fs/ext4/namei.c
22 ===================================================================
23 --- linux-2.6.18.i386.orig/fs/ext4/namei.c
24 +++ linux-2.6.18.i386/fs/ext4/namei.c
25 @@ -1067,6 +1067,38 @@ static struct dentry *ext4_lookup(struct
26 return ERR_CAST(inode);
29 + /* ".." shouldn't go into dcache to preserve dcache hierarchy
30 + * otherwise we'll get parent being a child of actual child.
31 + * see bug 10458 for details -bzzz */
32 + if (inode && (dentry->d_name.name[0] == '.' && (dentry->d_name.len == 1 ||
33 + (dentry->d_name.len == 2 && dentry->d_name.name[1] == '.')))) {
34 + struct dentry *tmp, *goal = NULL;
35 + struct list_head *lp;
37 + /* first, look for an existing dentry - any one is good */
38 + spin_lock(&dcache_lock);
39 + list_for_each(lp, &inode->i_dentry) {
40 + tmp = list_entry(lp, struct dentry, d_alias);
46 + /* there is no alias, we need to make current dentry:
47 + * a) inaccessible for __d_lookup()
48 + * b) inaccessible for iopen */
49 + J_ASSERT(list_empty(&dentry->d_alias));
50 + dentry->d_flags |= DCACHE_NFSFS_RENAMED;
51 + /* this is d_instantiate() ... */
52 + list_add(&dentry->d_alias, &inode->i_dentry);
53 + dentry->d_inode = inode;
55 + spin_unlock(&dcache_lock);
61 return iopen_connect_dentry(dentry, inode, 1);