1 diff -Nurb linux-2.6.22.19/fs/dcookies.c linux-2.6.22.19-dcookies/fs/dcookies.c
2 --- linux-2.6.22.19/fs/dcookies.c 2008-02-25 18:59:40.000000000 -0500
3 +++ linux-2.6.22.19-dcookies/fs/dcookies.c 2009-03-16 14:44:24.000000000 -0400
5 static LIST_HEAD(dcookie_users);
6 static DEFINE_MUTEX(dcookie_mutex);
7 static struct kmem_cache *dcookie_cache __read_mostly;
8 -static struct list_head *dcookie_hashtable __read_mostly;
9 +static struct list_head *dcookie_hashtable[3] __read_mostly;
10 static size_t hash_size __read_mostly;
11 +unsigned int current_hash = 0, old_hash = -1;
13 static inline int is_live(void)
15 return !(list_empty(&dcookie_users));
18 +static inline int is_shared(void)
20 + return !(list_empty(&dcookie_users)) && !(list_empty(dcookie_users.next));
23 /* The dentry is locked, its address will do for the cookie */
24 static inline unsigned long dcookie_value(struct dcookie_struct * dcs)
26 struct list_head * pos;
27 struct list_head * list;
29 - list = dcookie_hashtable + dcookie_hash(dcookie);
30 + list = dcookie_hashtable[current_hash] + dcookie_hash(dcookie);
32 list_for_each(pos, list) {
33 dcs = list_entry(pos, struct dcookie_struct, hash_list);
38 + if (!found && (old_hash!=-1)) {
39 + list = dcookie_hashtable[old_hash] + dcookie_hash(dcookie);
41 + list_for_each(pos, list) {
42 + dcs = list_entry(pos, struct dcookie_struct, hash_list);
43 + if (dcookie_value(dcs) == dcookie) {
55 static void hash_dcookie(struct dcookie_struct * dcs)
57 - struct list_head * list = dcookie_hashtable + dcookie_hash(dcookie_value(dcs));
58 + struct list_head * list = dcookie_hashtable[current_hash] + dcookie_hash(dcookie_value(dcs));
59 list_add(&dcs->hash_list, list);
63 static struct dcookie_struct * alloc_dcookie(struct dentry * dentry,
64 struct vfsmount * vfsmnt)
66 - struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_KERNEL);
67 + struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_ATOMIC);
75 - dcookie_hashtable = kmalloc(PAGE_SIZE, GFP_KERNEL);
76 - if (!dcookie_hashtable)
77 + dcookie_hashtable[0] = kmalloc(PAGE_SIZE, GFP_KERNEL);
78 + if (!dcookie_hashtable[0])
81 + dcookie_hashtable[1] = kmalloc(PAGE_SIZE, GFP_KERNEL);
82 + if (!dcookie_hashtable[1])
85 + dcookie_hashtable[2] = kmalloc(PAGE_SIZE, GFP_KERNEL);
86 + if (!dcookie_hashtable[0])
94 hash_size = 1UL << hash_bits;
96 /* And initialize the newly allocated array */
97 - d = dcookie_hashtable;
99 + d = dcookie_hashtable[0];
107 + d = dcookie_hashtable[1];
115 + d = dcookie_hashtable[2];
120 kmem_cache_free(dcookie_cache, dcs);
123 +int dcookie_swap(void) {
127 + old_hash=current_hash;
128 + current_hash = (current_hash + 1) % 3;
132 +/* Switch to the second hash */
133 +int dcookie_garbage_collect(void) {
134 + struct list_head * list;
135 + struct list_head * pos;
136 + struct list_head * pos2;
137 + struct dcookie_struct * dcs;
139 + int next_hash=(current_hash + 1) % 3;
144 + /* XXX consider the consequence of dcookie allocation concurring with this cleanup */
145 + for (i = 0; i < hash_size; ++i) {
146 + list = dcookie_hashtable[next_hash] + i;
147 + list_for_each_safe(pos, pos2, list) {
148 + dcs = list_entry(pos, struct dcookie_struct, hash_list);
149 + list_del(&dcs->hash_list);
157 static void dcookie_exit(void)
162 for (i = 0; i < hash_size; ++i) {
163 - list = dcookie_hashtable + i;
164 + list = dcookie_hashtable[0] + i;
165 + list_for_each_safe(pos, pos2, list) {
166 + dcs = list_entry(pos, struct dcookie_struct, hash_list);
167 + list_del(&dcs->hash_list);
171 + list = dcookie_hashtable[1] + i;
172 list_for_each_safe(pos, pos2, list) {
173 dcs = list_entry(pos, struct dcookie_struct, hash_list);
174 list_del(&dcs->hash_list);
179 - kfree(dcookie_hashtable);
180 + kfree(dcookie_hashtable[0]);
181 + kfree(dcookie_hashtable[1]);
182 kmem_cache_destroy(dcookie_cache);
186 EXPORT_SYMBOL_GPL(dcookie_register);
187 EXPORT_SYMBOL_GPL(dcookie_unregister);
188 EXPORT_SYMBOL_GPL(get_dcookie);
189 +EXPORT_SYMBOL_GPL(dcookie_garbage_collect);
190 +EXPORT_SYMBOL_GPL(dcookie_swap);
191 diff -Nurb linux-2.6.22.19/include/linux/dcookies.h linux-2.6.22.19-dcookies/include/linux/dcookies.h
192 --- linux-2.6.22.19/include/linux/dcookies.h 2008-02-25 18:59:40.000000000 -0500
193 +++ linux-2.6.22.19-dcookies/include/linux/dcookies.h 2009-03-16 15:15:13.000000000 -0400
195 int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt,
196 unsigned long * cookie);
200 + * dcookie_swap - switch to the next dcookie epoch
202 + * Deactivate the current dcookie hash table and activate
205 + * Returns 0 on success
208 +int dcookie_swap(void);
211 + * dcookie_garbage_collect - clear the hash table next in line
213 + * Clear the hash table to be activated in the next epoch.
215 + * Returns 0 on success
218 +int dcookie_garbage_colect(void);
221 static inline struct dcookie_user * dcookie_register(void)