Whamcloud - gitweb
Branch b1_4_mountconf
[fs/lustre-release.git] / lustre / kernel_patches / patches / dcache-qstr-api-fix-2.6-suse.patch
1 Index: linux-2.6.5-7.201/include/linux/dcache.h
2 ===================================================================
3 --- linux-2.6.5-7.201.orig/include/linux/dcache.h       2005-10-11 00:12:48.000000000 +0400
4 +++ linux-2.6.5-7.201/include/linux/dcache.h    2005-12-20 23:16:31.000000000 +0300
5 @@ -38,7 +38,6 @@ struct qstr {
6         const unsigned char * name;
7         unsigned int len;
8         unsigned int hash;
9 -       char name_str[0];
10  };
11  
12  #include <linux/namei.h>
13 @@ -104,7 +103,6 @@ struct dentry {
14         struct rcu_head d_rcu;
15         struct dcookie_struct * d_cookie; /* cookie, if any */
16         unsigned long d_move_count;     /* to indicated moved dentry while lockless lookup */
17 -       struct qstr * d_qstr;           /* quick str ptr used in lockless lookup and concurrent d_move */
18         struct dentry * d_parent;       /* parent directory */
19         struct qstr d_name;
20         struct hlist_node d_hash;       /* lookup hash list */  
21 Index: linux-2.6.5-7.201/fs/dcache.c
22 ===================================================================
23 --- linux-2.6.5-7.201.orig/fs/dcache.c  2005-10-11 00:12:45.000000000 +0400
24 +++ linux-2.6.5-7.201/fs/dcache.c       2005-12-20 23:16:31.000000000 +0300
25 @@ -41,6 +41,8 @@ EXPORT_SYMBOL(dcache_lock);
26  
27  static kmem_cache_t *dentry_cache; 
28  
29 +#define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname))
30 +
31  /*
32   * This is the single most critical data structure when it comes
33   * to the dcache: the hashtable for lookups. Somebody should try
34 @@ -67,7 +69,7 @@ static void d_callback(void *arg)
35         struct dentry * dentry = (struct dentry *)arg;
36  
37         if (dname_external(dentry)) {
38 -               kfree(dentry->d_qstr);
39 +               kfree(dentry->d_name.name);
40         }
41         kmem_cache_free(dentry_cache, dentry); 
42  }
43 @@ -678,8 +680,6 @@ static int shrink_dcache_memory(int nr, 
44         return dentry_stat.nr_unused;
45  }
46  
47 -#define NAME_ALLOC_LEN(len)    ((len+16) & ~15)
48 -
49  /**
50   * d_alloc     -       allocate a dcache entry
51   * @parent: parent of entry to allocate
52 @@ -694,26 +694,18 @@ struct dentry * d_alloc(struct dentry * 
53  {
54         char * str;
55         struct dentry *dentry;
56 -       struct qstr * qstr;
57  
58         dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); 
59         if (!dentry)
60                 return NULL;
61  
62         if (name->len > DNAME_INLINE_LEN-1) {
63 -               qstr = kmalloc(sizeof(*qstr) + NAME_ALLOC_LEN(name->len), 
64 -                               GFP_KERNEL);  
65 -               if (!qstr) {
66 +               str = kmalloc(name->len + 1, GFP_KERNEL);
67 +               if (!str) {
68                         kmem_cache_free(dentry_cache, dentry); 
69                         return NULL;
70                 }
71 -               qstr->name = qstr->name_str;
72 -               qstr->len = name->len;
73 -               qstr->hash = name->hash;
74 -               dentry->d_qstr = qstr;
75 -               str = qstr->name_str;
76         } else  {
77 -               dentry->d_qstr = &dentry->d_name;
78                 str = dentry->d_iname;
79         }       
80  
81 @@ -1010,7 +1002,7 @@ struct dentry * __d_lookup(struct dentry
82                 if (dentry->d_parent != parent)
83                         continue;
84  
85 -               qstr = dentry->d_qstr;
86 +               qstr = &dentry->d_name;
87                 smp_read_barrier_depends();
88                 if (parent->d_op && parent->d_op->d_compare) {
89                         if (parent->d_op->d_compare(parent, qstr, name))
90 @@ -1163,26 +1155,38 @@ void d_rehash(struct dentry * entry)
91   */
92  static inline void switch_names(struct dentry * dentry, struct dentry * target)
93  {
94 -       const unsigned char *old_name, *new_name;
95 -       struct qstr *old_qstr, *new_qstr;
96 -
97 -       memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); 
98 -       old_qstr = target->d_qstr;
99 -       old_name = target->d_name.name;
100 -       new_qstr = dentry->d_qstr;
101 -       new_name = dentry->d_name.name;
102 -       if (old_name == target->d_iname) {
103 -               old_name = dentry->d_iname;
104 -               old_qstr = &dentry->d_name;
105 -       }
106 -       if (new_name == dentry->d_iname) {
107 -               new_name = target->d_iname;
108 -               new_qstr = &target->d_name;
109 -       }
110 -       target->d_name.name = new_name;
111 -       dentry->d_name.name = old_name;
112 -       target->d_qstr = new_qstr;
113 -       dentry->d_qstr = old_qstr;
114 +       if (dname_external(target)) {
115 +               if (dname_external(dentry)) {
116 +                       /*
117 +                        * Both external: swap the pointers
118 +                        */
119 +                       do_switch(target->d_name.name, dentry->d_name.name);
120 +               } else {
121 +                       /*
122 +                        * dentry:internal, target:external.  Steal target's
123 +                        * storage and make target internal.
124 +                        */
125 +                       dentry->d_name.name = target->d_name.name;
126 +                       target->d_name.name = target->d_iname;
127 +               }
128 +       } else {
129 +               if (dname_external(dentry)) {
130 +                       /*
131 +                        * dentry:external, target:internal.  Give dentry's
132 +                        * storage to target and make dentry internal
133 +                        */
134 +                       memcpy(dentry->d_iname, target->d_name.name,
135 +                                       target->d_name.len + 1);
136 +                       target->d_name.name = dentry->d_name.name;
137 +                       dentry->d_name.name = dentry->d_iname;
138 +               } else {
139 +                       /*
140 +                        * Both are internal.  Just copy target to dentry
141 +                        */
142 +                       memcpy(dentry->d_iname, target->d_name.name,
143 +                                       target->d_name.len + 1);
144 +               }
145 +       }
146  }
147  
148  /*