When failing from creating cache jbd2_inode_cache, we will destroy the previously created cache jbd2_handle_cache twice. This patch fixes this by moving each cache initialization/destruction to its own separate, individual function.
Unified · Split
| @@ -2375,22 +2375,19 @@ static struct kmem_cache *jbd2_journal_head_cache; · 2374 unmodified lines | ||
| 2375 | 2375 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); |
| 2376 | 2376 | #endif |
| 2377 | 2377 | |
| 2378 | −static int jbd2_journal_init_journal_head_cache(void) | |
| 2378 | +static int __init jbd2_journal_init_journal_head_cache(void) | |
| 2379 | 2379 | { |
| 2380 | − int retval; | |
| 2381 | − | |
| 2382 | − J_ASSERT(jbd2_journal_head_cache == NULL); | |
| 2380 | + J_ASSERT(!jbd2_journal_head_cache); | |
| 2383 | 2381 | jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head", |
| 2384 | 2382 | sizeof(struct journal_head), |
| 2385 | 2383 | 0, /* offset */ |
| 2386 | 2384 | SLAB_TEMPORARY | SLAB_TYPESAFE_BY_RCU, |
| 2387 | 2385 | NULL); /* ctor */ |
| 2388 | − retval = 0; | |
| 2389 | 2386 | if (!jbd2_journal_head_cache) { |
| 2390 | − retval = -ENOMEM; | |
| 2391 | 2387 | printk(KERN_EMERG "JBD2: no memory for journal_head cache\n"); |
| 2388 | + return -ENOMEM; | |
| 2392 | 2389 | } |
| 2393 | − return retval; | |
| 2390 | + return 0; | |
| 2394 | 2391 | } |
| 2395 | 2392 | |
| 2396 | 2393 | static void jbd2_journal_destroy_journal_head_cache(void) |
| @@ -2636,28 +2633,38 @@ static void __exit jbd2_remove_jbd_stats_proc_entry(void) · 239 unmodified lines | ||
| 2636 | 2633 | |
| 2637 | 2634 | struct kmem_cache *jbd2_handle_cache, *jbd2_inode_cache; |
| 2638 | 2635 | |
| 2636 | +static int __init jbd2_journal_init_inode_cache(void) | |
| 2637 | +{ | |
| 2638 | + J_ASSERT(!jbd2_inode_cache); | |
| 2639 | + jbd2_inode_cache = KMEM_CACHE(jbd2_inode, 0); | |
| 2640 | + if (!jbd2_inode_cache) { | |
| 2641 | + pr_emerg("JBD2: failed to create inode cache\n"); | |
| 2642 | + return -ENOMEM; | |
| 2643 | + } | |
| 2644 | + return 0; | |
| 2645 | +} | |
| 2646 | + | |
| 2639 | 2647 | static int __init jbd2_journal_init_handle_cache(void) |
| 2640 | 2648 | { |
| 2649 | + J_ASSERT(!jbd2_handle_cache); | |
| 2641 | 2650 | jbd2_handle_cache = KMEM_CACHE(jbd2_journal_handle, SLAB_TEMPORARY); |
| 2642 | − if (jbd2_handle_cache == NULL) { | |
| 2651 | + if (!jbd2_handle_cache) { | |
| 2643 | 2652 | printk(KERN_EMERG "JBD2: failed to create handle cache\n"); |
| 2644 | 2653 | return -ENOMEM; |
| 2645 | 2654 | } |
| 2646 | − jbd2_inode_cache = KMEM_CACHE(jbd2_inode, 0); | |
| 2647 | − if (jbd2_inode_cache == NULL) { | |
| 2648 | − printk(KERN_EMERG "JBD2: failed to create inode cache\n"); | |
| 2649 | − kmem_cache_destroy(jbd2_handle_cache); | |
| 2650 | − return -ENOMEM; | |
| 2651 | − } | |
| 2652 | 2655 | return 0; |
| 2653 | 2656 | } |
| 2654 | 2657 | |
| 2658 | +static void jbd2_journal_destroy_inode_cache(void) | |
| 2659 | +{ | |
| 2660 | + kmem_cache_destroy(jbd2_inode_cache); | |
| 2661 | + jbd2_inode_cache = NULL; | |
| 2662 | +} | |
| 2663 | + | |
| 2655 | 2664 | static void jbd2_journal_destroy_handle_cache(void) |
| 2656 | 2665 | { |
| 2657 | 2666 | kmem_cache_destroy(jbd2_handle_cache); |
| 2658 | 2667 | jbd2_handle_cache = NULL; |
| 2659 | − kmem_cache_destroy(jbd2_inode_cache); | |
| 2660 | − jbd2_inode_cache = NULL; | |
| 2661 | 2668 | } |
| 2662 | 2669 | |
| 2663 | 2670 | /* |
| @@ -2668,11 +2675,15 @@ static int __init journal_init_caches(void) · 4 unmodified lines | ||
| 2668 | 2675 | { |
| 2669 | 2676 | int ret; |
| 2670 | 2677 | |
| 2671 | − ret = jbd2_journal_init_revoke_caches(); | |
| 2678 | + ret = jbd2_journal_init_revoke_record_cache(); | |
| 2679 | + if (ret == 0) | |
| 2680 | + ret = jbd2_journal_init_revoke_table_cache(); | |
| 2672 | 2681 | if (ret == 0) |
| 2673 | 2682 | ret = jbd2_journal_init_journal_head_cache(); |
| 2674 | 2683 | if (ret == 0) |
| 2675 | 2684 | ret = jbd2_journal_init_handle_cache(); |
| 2685 | + if (ret == 0) | |
| 2686 | + ret = jbd2_journal_init_inode_cache(); | |
| 2676 | 2687 | if (ret == 0) |
| 2677 | 2688 | ret = jbd2_journal_init_transaction_cache(); |
| 2678 | 2689 | return ret; |
| @@ -2680,9 +2691,11 @@ static int __init journal_init_caches(void) · 1 unmodified line | ||
| 2680 | 2691 | |
| 2681 | 2692 | static void jbd2_journal_destroy_caches(void) |
| 2682 | 2693 | { |
| 2683 | − jbd2_journal_destroy_revoke_caches(); | |
| 2694 | + jbd2_journal_destroy_revoke_record_cache(); | |
| 2695 | + jbd2_journal_destroy_revoke_table_cache(); | |
| 2684 | 2696 | jbd2_journal_destroy_journal_head_cache(); |
| 2685 | 2697 | jbd2_journal_destroy_handle_cache(); |
| 2698 | + jbd2_journal_destroy_inode_cache(); | |
| 2686 | 2699 | jbd2_journal_destroy_transaction_cache(); |
| 2687 | 2700 | jbd2_journal_destroy_slabs(); |
| 2688 | 2701 | } |
| @@ -178,33 +178,41 @@ static struct jbd2_revoke_record_s *find_revoke_record(journal_t *journal, · 177 unmodified lines | ||
| 178 | 178 | return NULL; |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | −void jbd2_journal_destroy_revoke_caches(void) | |
| 181 | +void jbd2_journal_destroy_revoke_record_cache(void) | |
| 182 | 182 | { |
| 183 | 183 | kmem_cache_destroy(jbd2_revoke_record_cache); |
| 184 | 184 | jbd2_revoke_record_cache = NULL; |
| 185 | +} | |
| 186 | + | |
| 187 | +void jbd2_journal_destroy_revoke_table_cache(void) | |
| 188 | +{ | |
| 185 | 189 | kmem_cache_destroy(jbd2_revoke_table_cache); |
| 186 | 190 | jbd2_revoke_table_cache = NULL; |
| 187 | 191 | } |
| 188 | 192 | |
| 189 | −int __init jbd2_journal_init_revoke_caches(void) | |
| 193 | +int __init jbd2_journal_init_revoke_record_cache(void) | |
| 190 | 194 | { |
| 191 | 195 | J_ASSERT(!jbd2_revoke_record_cache); |
| 192 | − J_ASSERT(!jbd2_revoke_table_cache); | |
| 193 | − | |
| 194 | 196 | jbd2_revoke_record_cache = KMEM_CACHE(jbd2_revoke_record_s, |
| 195 | 197 | SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY); |
| 196 | − if (!jbd2_revoke_record_cache) | |
| 197 | − goto record_cache_failure; | |
| 198 | 198 | |
| 199 | + if (!jbd2_revoke_record_cache) { | |
| 200 | + pr_emerg("JBD2: failed to create revoke_record cache\n"); | |
| 201 | + return -ENOMEM; | |
| 202 | + } | |
| 203 | + return 0; | |
| 204 | +} | |
| 205 | + | |
| 206 | +int __init jbd2_journal_init_revoke_table_cache(void) | |
| 207 | +{ | |
| 208 | + J_ASSERT(!jbd2_revoke_table_cache); | |
| 199 | 209 | jbd2_revoke_table_cache = KMEM_CACHE(jbd2_revoke_table_s, |
| 200 | 210 | SLAB_TEMPORARY); |
| 201 | − if (!jbd2_revoke_table_cache) | |
| 202 | − goto table_cache_failure; | |
| 203 | − return 0; | |
| 204 | −table_cache_failure: | |
| 205 | − jbd2_journal_destroy_revoke_caches(); | |
| 206 | −record_cache_failure: | |
| 211 | + if (!jbd2_revoke_table_cache) { | |
| 212 | + pr_emerg("JBD2: failed to create revoke_table cache\n"); | |
| 207 | 213 | return -ENOMEM; |
| 214 | + } | |
| 215 | + return 0; | |
| 208 | 216 | } |
| 209 | 217 | |
| 210 | 218 | static struct jbd2_revoke_table_s *jbd2_journal_init_revoke_table(int hash_size) |
| @@ -42,9 +42,11 @@ int __init jbd2_journal_init_transaction_cache(void) · 41 unmodified lines | ||
| 42 | 42 | 0, |
| 43 | 43 | SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY, |
| 44 | 44 | NULL); |
| 45 | − if (transaction_cache) | |
| 46 | − return 0; | |
| 47 | − return -ENOMEM; | |
| 45 | + if (!transaction_cache) { | |
| 46 | + pr_emerg("JBD2: failed to create transaction cache\n"); | |
| 47 | + return -ENOMEM; | |
| 48 | + } | |
| 49 | + return 0; | |
| 48 | 50 | } |
| 49 | 51 | |
| 50 | 52 | void jbd2_journal_destroy_transaction_cache(void) |
| @@ -1318,7 +1318,7 @@ extern void __wait_on_journal (journal_t *); · 1317 unmodified lines | ||
| 1318 | 1318 | |
| 1319 | 1319 | /* Transaction cache support */ |
| 1320 | 1320 | extern void jbd2_journal_destroy_transaction_cache(void); |
| 1321 | −extern int jbd2_journal_init_transaction_cache(void); | |
| 1321 | +extern int __init jbd2_journal_init_transaction_cache(void); | |
| 1322 | 1322 | extern void jbd2_journal_free_transaction(transaction_t *); |
| 1323 | 1323 | |
| 1324 | 1324 | /* |
| @@ -1446,8 +1446,10 @@ static inline void jbd2_free_inode(struct jbd2_inode *jinode) · 121 unmodified lines | ||
| 1446 | 1446 | /* Primary revoke support */ |
| 1447 | 1447 | #define JOURNAL_REVOKE_DEFAULT_HASH 256 |
| 1448 | 1448 | extern int jbd2_journal_init_revoke(journal_t *, int); |
| 1449 | −extern void jbd2_journal_destroy_revoke_caches(void); | |
| 1450 | −extern int jbd2_journal_init_revoke_caches(void); | |
| 1449 | +extern void jbd2_journal_destroy_revoke_record_cache(void); | |
| 1450 | +extern void jbd2_journal_destroy_revoke_table_cache(void); | |
| 1451 | +extern int __init jbd2_journal_init_revoke_record_cache(void); | |
| 1452 | +extern int __init jbd2_journal_init_revoke_table_cache(void); | |
| 1451 | 1453 | |
| 1452 | 1454 | extern void jbd2_journal_destroy_revoke(journal_t *); |
| 1453 | 1455 | extern int jbd2_journal_revoke (handle_t *, unsigned long long, struct buffer_head *); |