1 --- linux-chopstix/include/linux/dcookies.h.orig 2009-03-05 08:45:29.000000000 -0500
2 +++ linux-chopstix/include/linux/dcookies.h 2009-03-12 13:43:53.000000000 -0400
4 int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt,
5 unsigned long * cookie);
9 + * dcookie_swap - switch to the next dcookie epoch
11 + * Deactivate the current dcookie hash table and activate
14 + * Returns 0 on success
17 +int dcookie_swap(void);
20 + * dcookie_garbage_collect - clear the hash table next in line
22 + * Clear the hash table to be activated in the next epoch.
24 + * Returns 0 on success
27 +int dcookie_garbage_colect(void);
30 static inline struct dcookie_user * dcookie_register(void)
31 --- linux-chopstix/fs/dcookies.c.orig 2009-03-05 08:46:09.000000000 -0500
32 +++ linux-chopstix/fs/dcookies.c 2009-04-06 11:04:30.000000000 -0400
34 static LIST_HEAD(dcookie_users);
35 static DEFINE_MUTEX(dcookie_mutex);
36 static struct kmem_cache *dcookie_cache __read_mostly;
37 -static struct list_head *dcookie_hashtable __read_mostly;
38 +static struct list_head *dcookie_hashtable[3] __read_mostly;
39 static size_t hash_size __read_mostly;
40 +unsigned int current_hash = 1, old_hash = 0;
42 static inline int is_live(void)
44 return !(list_empty(&dcookie_users));
47 +static inline int is_shared(void)
49 + return !(list_empty(&dcookie_users)) && !(list_empty(dcookie_users.next));
52 /* The dentry is locked, its address will do for the cookie */
53 static inline unsigned long dcookie_value(struct dcookie_struct * dcs)
55 struct list_head * pos;
56 struct list_head * list;
58 - list = dcookie_hashtable + dcookie_hash(dcookie);
59 + list = dcookie_hashtable[current_hash] + dcookie_hash(dcookie);
61 list_for_each(pos, list) {
62 dcs = list_entry(pos, struct dcookie_struct, hash_list);
68 + list = dcookie_hashtable[old_hash] + dcookie_hash(dcookie);
70 + list_for_each(pos, list) {
71 + dcs = list_entry(pos, struct dcookie_struct, hash_list);
72 + if (dcookie_value(dcs) == dcookie) {
84 static void hash_dcookie(struct dcookie_struct * dcs)
86 - struct list_head * list = dcookie_hashtable + dcookie_hash(dcookie_value(dcs));
87 + struct list_head * list = dcookie_hashtable[current_hash] + dcookie_hash(dcookie_value(dcs));
88 list_add(&dcs->hash_list, list);
92 static struct dcookie_struct * alloc_dcookie(struct dentry * dentry,
93 struct vfsmount * vfsmnt)
95 - struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_KERNEL);
96 + struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_ATOMIC);
100 @@ -210,10 +228,19 @@
104 - dcookie_hashtable = kmalloc(PAGE_SIZE, GFP_KERNEL);
105 - if (!dcookie_hashtable)
106 + dcookie_hashtable[0] = kmalloc(PAGE_SIZE, GFP_KERNEL);
107 + if (!dcookie_hashtable[0])
110 + dcookie_hashtable[1] = kmalloc(PAGE_SIZE, GFP_KERNEL);
111 + if (!dcookie_hashtable[1])
114 + dcookie_hashtable[2] = kmalloc(PAGE_SIZE, GFP_KERNEL);
115 + if (!dcookie_hashtable[2])
123 hash_size = 1UL << hash_bits;
125 /* And initialize the newly allocated array */
126 - d = dcookie_hashtable;
128 + d = dcookie_hashtable[0];
136 + d = dcookie_hashtable[1];
144 + d = dcookie_hashtable[2];
149 kmem_cache_free(dcookie_cache, dcs);
152 +int dcookie_swap(void) {
156 + old_hash=current_hash;
157 + current_hash = (current_hash + 1) % 3;
161 +/* Switch to the second hash */
162 +int dcookie_garbage_collect(void) {
163 + struct list_head * list;
164 + struct list_head * pos;
165 + struct list_head * pos2;
166 + struct dcookie_struct * dcs;
168 + int next_hash=(current_hash + 1) % 3;
173 + /* XXX consider the consequence of dcookie allocation concurring with this cleanup */
174 + for (i = 0; i < hash_size; ++i) {
175 + list = dcookie_hashtable[next_hash] + i;
176 + list_for_each_safe(pos, pos2, list) {
177 + dcs = list_entry(pos, struct dcookie_struct, hash_list);
178 + list_del(&dcs->hash_list);
186 static void dcookie_exit(void)
191 for (i = 0; i < hash_size; ++i) {
192 - list = dcookie_hashtable + i;
193 + list = dcookie_hashtable[0] + i;
194 + list_for_each_safe(pos, pos2, list) {
195 + dcs = list_entry(pos, struct dcookie_struct, hash_list);
196 + list_del(&dcs->hash_list);
200 + list = dcookie_hashtable[1] + i;
201 + list_for_each_safe(pos, pos2, list) {
202 + dcs = list_entry(pos, struct dcookie_struct, hash_list);
203 + list_del(&dcs->hash_list);
207 + list = dcookie_hashtable[2] + i;
208 list_for_each_safe(pos, pos2, list) {
209 dcs = list_entry(pos, struct dcookie_struct, hash_list);
210 list_del(&dcs->hash_list);
215 - kfree(dcookie_hashtable);
216 + kfree(dcookie_hashtable[0]);
217 + kfree(dcookie_hashtable[1]);
218 + kfree(dcookie_hashtable[2]);
219 kmem_cache_destroy(dcookie_cache);
223 EXPORT_SYMBOL_GPL(dcookie_register);
224 EXPORT_SYMBOL_GPL(dcookie_unregister);
225 EXPORT_SYMBOL_GPL(get_dcookie);
226 +EXPORT_SYMBOL_GPL(dcookie_garbage_collect);
227 +EXPORT_SYMBOL_GPL(dcookie_swap);