diff options
Diffstat (limited to 'fs/jbd/revoke.c')
| -rw-r--r-- | fs/jbd/revoke.c | 163 |
1 files changed, 74 insertions, 89 deletions
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index 1bb43e987f4b..c7bd649bbbdc 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c | |||
| @@ -166,138 +166,123 @@ static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal, | |||
| 166 | return NULL; | 166 | return NULL; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | void journal_destroy_revoke_caches(void) | ||
| 170 | { | ||
| 171 | if (revoke_record_cache) { | ||
| 172 | kmem_cache_destroy(revoke_record_cache); | ||
| 173 | revoke_record_cache = NULL; | ||
| 174 | } | ||
| 175 | if (revoke_table_cache) { | ||
| 176 | kmem_cache_destroy(revoke_table_cache); | ||
| 177 | revoke_table_cache = NULL; | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 169 | int __init journal_init_revoke_caches(void) | 181 | int __init journal_init_revoke_caches(void) |
| 170 | { | 182 | { |
| 183 | J_ASSERT(!revoke_record_cache); | ||
| 184 | J_ASSERT(!revoke_table_cache); | ||
| 185 | |||
| 171 | revoke_record_cache = kmem_cache_create("revoke_record", | 186 | revoke_record_cache = kmem_cache_create("revoke_record", |
| 172 | sizeof(struct jbd_revoke_record_s), | 187 | sizeof(struct jbd_revoke_record_s), |
| 173 | 0, | 188 | 0, |
| 174 | SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY, | 189 | SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY, |
| 175 | NULL); | 190 | NULL); |
| 176 | if (!revoke_record_cache) | 191 | if (!revoke_record_cache) |
| 177 | return -ENOMEM; | 192 | goto record_cache_failure; |
| 178 | 193 | ||
| 179 | revoke_table_cache = kmem_cache_create("revoke_table", | 194 | revoke_table_cache = kmem_cache_create("revoke_table", |
| 180 | sizeof(struct jbd_revoke_table_s), | 195 | sizeof(struct jbd_revoke_table_s), |
| 181 | 0, SLAB_TEMPORARY, NULL); | 196 | 0, SLAB_TEMPORARY, NULL); |
| 182 | if (!revoke_table_cache) { | 197 | if (!revoke_table_cache) |
| 183 | kmem_cache_destroy(revoke_record_cache); | 198 | goto table_cache_failure; |
| 184 | revoke_record_cache = NULL; | 199 | |
| 185 | return -ENOMEM; | ||
| 186 | } | ||
| 187 | return 0; | 200 | return 0; |
| 188 | } | ||
| 189 | 201 | ||
| 190 | void journal_destroy_revoke_caches(void) | 202 | table_cache_failure: |
| 191 | { | 203 | journal_destroy_revoke_caches(); |
| 192 | kmem_cache_destroy(revoke_record_cache); | 204 | record_cache_failure: |
| 193 | revoke_record_cache = NULL; | 205 | return -ENOMEM; |
| 194 | kmem_cache_destroy(revoke_table_cache); | ||
| 195 | revoke_table_cache = NULL; | ||
| 196 | } | 206 | } |
| 197 | 207 | ||
| 198 | /* Initialise the revoke table for a given journal to a given size. */ | 208 | 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 | { | 209 | { |
| 202 | int shift, tmp; | 210 | int shift = 0; |
| 211 | int tmp = hash_size; | ||
| 212 | struct jbd_revoke_table_s *table; | ||
| 203 | 213 | ||
| 204 | J_ASSERT (journal->j_revoke_table[0] == NULL); | 214 | table = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); |
| 215 | if (!table) | ||
| 216 | goto out; | ||
| 205 | 217 | ||
| 206 | shift = 0; | ||
| 207 | tmp = hash_size; | ||
| 208 | while((tmp >>= 1UL) != 0UL) | 218 | while((tmp >>= 1UL) != 0UL) |
| 209 | shift++; | 219 | shift++; |
| 210 | 220 | ||
| 211 | journal->j_revoke_table[0] = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); | 221 | table->hash_size = hash_size; |
| 212 | if (!journal->j_revoke_table[0]) | 222 | table->hash_shift = shift; |
| 213 | return -ENOMEM; | 223 | 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); | 224 | kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL); |
| 225 | if (!journal->j_revoke->hash_table) { | 225 | if (!table->hash_table) { |
| 226 | kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]); | 226 | kmem_cache_free(revoke_table_cache, table); |
| 227 | journal->j_revoke = NULL; | 227 | table = NULL; |
| 228 | return -ENOMEM; | 228 | goto out; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | for (tmp = 0; tmp < hash_size; tmp++) | 231 | for (tmp = 0; tmp < hash_size; tmp++) |
| 232 | INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]); | 232 | INIT_LIST_HEAD(&table->hash_table[tmp]); |
| 233 | 233 | ||
| 234 | journal->j_revoke_table[1] = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); | 234 | out: |
| 235 | if (!journal->j_revoke_table[1]) { | 235 | return table; |
| 236 | kfree(journal->j_revoke_table[0]->hash_table); | 236 | } |
| 237 | kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]); | 237 | |
| 238 | return -ENOMEM; | 238 | static void journal_destroy_revoke_table(struct jbd_revoke_table_s *table) |
| 239 | { | ||
| 240 | int i; | ||
| 241 | struct list_head *hash_list; | ||
| 242 | |||
| 243 | for (i = 0; i < table->hash_size; i++) { | ||
| 244 | hash_list = &table->hash_table[i]; | ||
| 245 | J_ASSERT(list_empty(hash_list)); | ||
| 239 | } | 246 | } |
| 240 | 247 | ||
| 241 | journal->j_revoke = journal->j_revoke_table[1]; | 248 | kfree(table->hash_table); |
| 249 | kmem_cache_free(revoke_table_cache, table); | ||
| 250 | } | ||
| 242 | 251 | ||
| 243 | /* Check that the hash_size is a power of two */ | 252 | /* Initialise the revoke table for a given journal to a given size. */ |
| 253 | int journal_init_revoke(journal_t *journal, int hash_size) | ||
| 254 | { | ||
| 255 | J_ASSERT(journal->j_revoke_table[0] == NULL); | ||
| 244 | J_ASSERT(is_power_of_2(hash_size)); | 256 | J_ASSERT(is_power_of_2(hash_size)); |
| 245 | 257 | ||
| 246 | journal->j_revoke->hash_size = hash_size; | 258 | journal->j_revoke_table[0] = journal_init_revoke_table(hash_size); |
| 259 | if (!journal->j_revoke_table[0]) | ||
| 260 | goto fail0; | ||
| 247 | 261 | ||
| 248 | journal->j_revoke->hash_shift = shift; | 262 | journal->j_revoke_table[1] = journal_init_revoke_table(hash_size); |
| 263 | if (!journal->j_revoke_table[1]) | ||
| 264 | goto fail1; | ||
| 249 | 265 | ||
| 250 | journal->j_revoke->hash_table = | 266 | 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 | 267 | ||
| 263 | spin_lock_init(&journal->j_revoke_lock); | 268 | spin_lock_init(&journal->j_revoke_lock); |
| 264 | 269 | ||
| 265 | return 0; | 270 | return 0; |
| 266 | } | ||
| 267 | 271 | ||
| 268 | /* Destoy a journal's revoke table. The table must already be empty! */ | 272 | fail1: |
| 273 | journal_destroy_revoke_table(journal->j_revoke_table[0]); | ||
| 274 | fail0: | ||
| 275 | return -ENOMEM; | ||
| 276 | } | ||
| 269 | 277 | ||
| 278 | /* Destroy a journal's revoke table. The table must already be empty! */ | ||
| 270 | void journal_destroy_revoke(journal_t *journal) | 279 | void journal_destroy_revoke(journal_t *journal) |
| 271 | { | 280 | { |
| 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; | 281 | journal->j_revoke = NULL; |
| 282 | if (journal->j_revoke_table[0]) | ||
| 283 | journal_destroy_revoke_table(journal->j_revoke_table[0]); | ||
| 284 | if (journal->j_revoke_table[1]) | ||
| 285 | journal_destroy_revoke_table(journal->j_revoke_table[1]); | ||
| 301 | } | 286 | } |
| 302 | 287 | ||
| 303 | 288 | ||
