Weeding out temporary files.
[linux-2.6.git] / linux-2.6-590-GC-dcookies.patch
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
3 @@ -45,6 +45,27 @@
4  int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt,
5         unsigned long * cookie);
6  
7 +
8 +/**
9 + * dcookie_swap - switch to the next dcookie epoch
10 + *
11 + * Deactivate the current dcookie hash table and activate
12 + * the next one
13 + *
14 + * Returns 0 on success
15 + */
16 +
17 +int dcookie_swap(void);
18 +
19 +/**
20 + * dcookie_garbage_collect - clear the hash table next in line
21 + *
22 + * Clear the hash table to be activated in the next epoch.
23 + *
24 + * Returns 0 on success
25 + */
26 +
27 +int dcookie_garbage_colect(void);
28  #else
29  
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
33 @@ -38,14 +38,19 @@
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;
41  
42  static inline int is_live(void)
43  {
44         return !(list_empty(&dcookie_users));
45  }
46  
47 +static inline int is_shared(void)
48 +{
49 +       return !(list_empty(&dcookie_users)) && !(list_empty(dcookie_users.next));
50 +}
51  
52  /* The dentry is locked, its address will do for the cookie */
53  static inline unsigned long dcookie_value(struct dcookie_struct * dcs)
54 @@ -67,7 +72,7 @@
55         struct list_head * pos;
56         struct list_head * list;
57  
58 -       list = dcookie_hashtable + dcookie_hash(dcookie);
59 +       list = dcookie_hashtable[current_hash] + dcookie_hash(dcookie);
60  
61         list_for_each(pos, list) {
62                 dcs = list_entry(pos, struct dcookie_struct, hash_list);
63 @@ -77,13 +82,26 @@
64                 }
65         }
66  
67 +    if (!found) {
68 +        list = dcookie_hashtable[old_hash] + dcookie_hash(dcookie);
69 +
70 +        list_for_each(pos, list) {
71 +            dcs = list_entry(pos, struct dcookie_struct, hash_list);
72 +            if (dcookie_value(dcs) == dcookie) {
73 +                found = dcs;
74 +                break;
75 +            }
76 +        }
77 +
78 +    }
79 +
80         return found;
81  }
82  
83  
84  static void hash_dcookie(struct dcookie_struct * dcs)
85  {
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);
89  }
90  
91 @@ -91,7 +109,7 @@
92  static struct dcookie_struct * alloc_dcookie(struct dentry * dentry,
93         struct vfsmount * vfsmnt)
94  {
95 -       struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_KERNEL);
96 +       struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_ATOMIC);
97         if (!dcs)
98                 return NULL;
99  
100 @@ -210,10 +228,19 @@
101         if (!dcookie_cache)
102                 goto out;
103  
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])
108 +               goto out_kmem;
109 +    
110 +    dcookie_hashtable[1] = kmalloc(PAGE_SIZE, GFP_KERNEL);
111 +       if (!dcookie_hashtable[1])
112                 goto out_kmem;
113  
114 +    dcookie_hashtable[2] = kmalloc(PAGE_SIZE, GFP_KERNEL);
115 +       if (!dcookie_hashtable[2])
116 +               goto out_kmem;
117 +    
118 +
119         err = 0;
120  
121         /*
122 @@ -235,7 +262,24 @@
123         hash_size = 1UL << hash_bits;
124  
125         /* And initialize the newly allocated array */
126 -       d = dcookie_hashtable;
127 +
128 +       d = dcookie_hashtable[0];
129 +       i = hash_size;
130 +       do {
131 +               INIT_LIST_HEAD(d);
132 +               d++;
133 +               i--;
134 +       } while (i);
135 +
136 +    d = dcookie_hashtable[1];
137 +       i = hash_size;
138 +       do {
139 +               INIT_LIST_HEAD(d);
140 +               d++;
141 +               i--;
142 +       } while (i);
143 +
144 +    d = dcookie_hashtable[2];
145         i = hash_size;
146         do {
147                 INIT_LIST_HEAD(d);
148 @@ -259,6 +303,39 @@
149         kmem_cache_free(dcookie_cache, dcs);
150  }
151  
152 +int dcookie_swap(void) {
153 +    if (is_shared())
154 +        return -EAGAIN;
155 +
156 +    old_hash=current_hash;
157 +    current_hash = (current_hash + 1) % 3;
158 +    return 0;
159 +}
160 +
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;
167 +       size_t i;
168 +    int next_hash=(current_hash + 1) % 3;
169 +
170 +    if (is_shared())
171 +        return -EAGAIN;
172 +
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);
179 +                       free_dcookie(dcs);
180 +               }
181 +       }
182 +
183 +    return 0;
184 +}
185  
186  static void dcookie_exit(void)
187  {
188 @@ -269,7 +346,21 @@
189         size_t i;
190  
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);
197 +                       free_dcookie(dcs);
198 +               }
199 +
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);
204 +                       free_dcookie(dcs);
205 +               }
206 +
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);
211 @@ -277,7 +368,9 @@
212                 }
213         }
214  
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);
220  }
221  
222 @@ -327,3 +420,5 @@
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);