diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/jbd/revoke.c | 127 |
1 files changed, 51 insertions, 76 deletions
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index 1bb43e987f4b..8ff5a7b89b9a 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c | |||
@@ -195,109 +195,84 @@ void journal_destroy_revoke_caches(void) | |||
195 | revoke_table_cache = NULL; | 195 | revoke_table_cache = NULL; |
196 | } | 196 | } |
197 | 197 | ||
198 | /* Initialise the revoke table for a given journal to a given size. */ | 198 | static struct jbd_revoke_table_s *journal_init_revoke_table(int hash_size) |
199 | |||
200 | int journal_init_revoke(journal_t *journal, int hash_size) | ||
201 | { | 199 | { |
202 | int shift, tmp; | 200 | int shift = 0; |
201 | int tmp = hash_size; | ||
202 | struct jbd_revoke_table_s *table; | ||
203 | 203 | ||
204 | J_ASSERT (journal->j_revoke_table[0] == NULL); | 204 | table = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); |
205 | if (!table) | ||
206 | goto out; | ||
205 | 207 | ||
206 | shift = 0; | ||
207 | tmp = hash_size; | ||
208 | while((tmp >>= 1UL) != 0UL) | 208 | while((tmp >>= 1UL) != 0UL) |
209 | shift++; | 209 | shift++; |
210 | 210 | ||
211 | journal->j_revoke_table[0] = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); | 211 | table->hash_size = hash_size; |
212 | if (!journal->j_revoke_table[0]) | 212 | table->hash_shift = shift; |
213 | return -ENOMEM; | 213 | table->hash_table = |
214 | journal->j_revoke = journal->j_revoke_table[0]; | ||
215 | |||
216 | /* Check that the hash_size is a power of two */ | ||
217 | J_ASSERT(is_power_of_2(hash_size)); | ||
218 | |||
219 | journal->j_revoke->hash_size = hash_size; | ||
220 | |||
221 | journal->j_revoke->hash_shift = shift; | ||
222 | |||
223 | journal->j_revoke->hash_table = | ||
224 | kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL); | 214 | kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL); |
225 | if (!journal->j_revoke->hash_table) { | 215 | if (!table->hash_table) { |
226 | kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]); | 216 | kmem_cache_free(revoke_table_cache, table); |
227 | journal->j_revoke = NULL; | 217 | table = NULL; |
228 | return -ENOMEM; | 218 | goto out; |
229 | } | 219 | } |
230 | 220 | ||
231 | for (tmp = 0; tmp < hash_size; tmp++) | 221 | for (tmp = 0; tmp < hash_size; tmp++) |
232 | INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]); | 222 | INIT_LIST_HEAD(&table->hash_table[tmp]); |
233 | 223 | ||
234 | journal->j_revoke_table[1] = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); | 224 | out: |
235 | if (!journal->j_revoke_table[1]) { | 225 | return table; |
236 | kfree(journal->j_revoke_table[0]->hash_table); | 226 | } |
237 | kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]); | 227 | |
238 | return -ENOMEM; | 228 | static void journal_destroy_revoke_table(struct jbd_revoke_table_s *table) |
229 | { | ||
230 | int i; | ||
231 | struct list_head *hash_list; | ||
232 | |||
233 | for (i = 0; i < table->hash_size; i++) { | ||
234 | hash_list = &table->hash_table[i]; | ||
235 | J_ASSERT(list_empty(hash_list)); | ||
239 | } | 236 | } |
240 | 237 | ||
241 | journal->j_revoke = journal->j_revoke_table[1]; | 238 | kfree(table->hash_table); |
239 | kmem_cache_free(revoke_table_cache, table); | ||
240 | } | ||
242 | 241 | ||
243 | /* Check that the hash_size is a power of two */ | 242 | /* Initialise the revoke table for a given journal to a given size. */ |
243 | int journal_init_revoke(journal_t *journal, int hash_size) | ||
244 | { | ||
245 | J_ASSERT(journal->j_revoke_table[0] == NULL); | ||
244 | J_ASSERT(is_power_of_2(hash_size)); | 246 | J_ASSERT(is_power_of_2(hash_size)); |
245 | 247 | ||
246 | journal->j_revoke->hash_size = hash_size; | 248 | journal->j_revoke_table[0] = journal_init_revoke_table(hash_size); |
249 | if (!journal->j_revoke_table[0]) | ||
250 | goto fail0; | ||
247 | 251 | ||
248 | journal->j_revoke->hash_shift = shift; | 252 | journal->j_revoke_table[1] = journal_init_revoke_table(hash_size); |
253 | if (!journal->j_revoke_table[1]) | ||
254 | goto fail1; | ||
249 | 255 | ||
250 | journal->j_revoke->hash_table = | 256 | journal->j_revoke = journal->j_revoke_table[1]; |
251 | kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL); | ||
252 | if (!journal->j_revoke->hash_table) { | ||
253 | kfree(journal->j_revoke_table[0]->hash_table); | ||
254 | kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]); | ||
255 | kmem_cache_free(revoke_table_cache, journal->j_revoke_table[1]); | ||
256 | journal->j_revoke = NULL; | ||
257 | return -ENOMEM; | ||
258 | } | ||
259 | |||
260 | for (tmp = 0; tmp < hash_size; tmp++) | ||
261 | INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]); | ||
262 | 257 | ||
263 | spin_lock_init(&journal->j_revoke_lock); | 258 | spin_lock_init(&journal->j_revoke_lock); |
264 | 259 | ||
265 | return 0; | 260 | return 0; |
266 | } | ||
267 | 261 | ||
268 | /* Destoy a journal's revoke table. The table must already be empty! */ | 262 | fail1: |
263 | journal_destroy_revoke_table(journal->j_revoke_table[0]); | ||
264 | fail0: | ||
265 | return -ENOMEM; | ||
266 | } | ||
269 | 267 | ||
268 | /* Destroy a journal's revoke table. The table must already be empty! */ | ||
270 | void journal_destroy_revoke(journal_t *journal) | 269 | void journal_destroy_revoke(journal_t *journal) |
271 | { | 270 | { |
272 | struct jbd_revoke_table_s *table; | ||
273 | struct list_head *hash_list; | ||
274 | int i; | ||
275 | |||
276 | table = journal->j_revoke_table[0]; | ||
277 | if (!table) | ||
278 | return; | ||
279 | |||
280 | for (i=0; i<table->hash_size; i++) { | ||
281 | hash_list = &table->hash_table[i]; | ||
282 | J_ASSERT (list_empty(hash_list)); | ||
283 | } | ||
284 | |||
285 | kfree(table->hash_table); | ||
286 | kmem_cache_free(revoke_table_cache, table); | ||
287 | journal->j_revoke = NULL; | ||
288 | |||
289 | table = journal->j_revoke_table[1]; | ||
290 | if (!table) | ||
291 | return; | ||
292 | |||
293 | for (i=0; i<table->hash_size; i++) { | ||
294 | hash_list = &table->hash_table[i]; | ||
295 | J_ASSERT (list_empty(hash_list)); | ||
296 | } | ||
297 | |||
298 | kfree(table->hash_table); | ||
299 | kmem_cache_free(revoke_table_cache, table); | ||
300 | journal->j_revoke = NULL; | 271 | journal->j_revoke = NULL; |
272 | if (journal->j_revoke_table[0]) | ||
273 | journal_destroy_revoke_table(journal->j_revoke_table[0]); | ||
274 | if (journal->j_revoke_table[1]) | ||
275 | journal_destroy_revoke_table(journal->j_revoke_table[1]); | ||
301 | } | 276 | } |
302 | 277 | ||
303 | 278 | ||