Whamcloud - gitweb
b=19872
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-lookup-dotdot-2.6.9.patch
1 Index: linux-2.6.9-full/fs/ext3/iopen.c
2 ===================================================================
3 --- linux-2.6.9-full.orig/fs/ext3/iopen.c       2006-04-25 08:51:11.000000000 +0400
4 +++ linux-2.6.9-full/fs/ext3/iopen.c    2006-05-06 01:21:11.000000000 +0400
5 @@ -94,9 +94,12 @@ static struct dentry *iopen_lookup(struc
6                 assert(!(alternate->d_flags & DCACHE_DISCONNECTED));
7         }
8  
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)
17 +                       continue;
18                 dget_locked(alternate);
19                 spin_lock(&alternate->d_lock);
20                 alternate->d_flags |= DCACHE_REFERENCED;
21 Index: linux-2.6.9-full/fs/ext3/namei.c
22 ===================================================================
23 --- linux-2.6.9-full.orig/fs/ext3/namei.c       2006-05-06 01:21:10.000000000 +0400
24 +++ linux-2.6.9-full/fs/ext3/namei.c    2006-05-06 01:29:30.000000000 +0400
25 @@ -1003,6 +1003,38 @@ static struct dentry *ext3_lookup(struct
26                         return ERR_PTR(-EACCES);
27         }
28  
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;
36 +
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);
41 +                       goal = tmp;
42 +                       dget_locked(goal);
43 +                       break;
44 +               }
45 +               if (goal == NULL) {
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;
54 +               }
55 +               spin_unlock(&dcache_lock);
56 +               if (goal)
57 +                       iput(inode);
58 +               return goal;
59 +       }
60 +
61         return iopen_connect_dentry(dentry, inode, 1);
62  }
63