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;
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 */
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);
27 static kmem_cache_t *dentry_cache;
29 +#define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname))
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;
37 if (dname_external(dentry)) {
38 - kfree(dentry->d_qstr);
39 + kfree(dentry->d_name.name);
41 kmem_cache_free(dentry_cache, dentry);
43 @@ -678,8 +680,6 @@ static int shrink_dcache_memory(int nr,
44 return dentry_stat.nr_unused;
47 -#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
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 *
55 struct dentry *dentry;
58 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
62 if (name->len > DNAME_INLINE_LEN-1) {
63 - qstr = kmalloc(sizeof(*qstr) + NAME_ALLOC_LEN(name->len),
66 + str = kmalloc(name->len + 1, GFP_KERNEL);
68 kmem_cache_free(dentry_cache, dentry);
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;
77 - dentry->d_qstr = &dentry->d_name;
78 str = dentry->d_iname;
81 @@ -1010,7 +1002,7 @@ struct dentry * __d_lookup(struct dentry
82 if (dentry->d_parent != parent)
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)
92 static inline void switch_names(struct dentry * dentry, struct dentry * target)
94 - const unsigned char *old_name, *new_name;
95 - struct qstr *old_qstr, *new_qstr;
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;
106 - if (new_name == dentry->d_iname) {
107 - new_name = target->d_iname;
108 - new_qstr = &target->d_name;
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)) {
117 + * Both external: swap the pointers
119 + do_switch(target->d_name.name, dentry->d_name.name);
122 + * dentry:internal, target:external. Steal target's
123 + * storage and make target internal.
125 + dentry->d_name.name = target->d_name.name;
126 + target->d_name.name = target->d_iname;
129 + if (dname_external(dentry)) {
131 + * dentry:external, target:internal. Give dentry's
132 + * storage to target and make dentry internal
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;
140 + * Both are internal. Just copy target to dentry
142 + memcpy(dentry->d_iname, target->d_name.name,
143 + target->d_name.len + 1);