diff options
Diffstat (limited to 'fs/jbd2/transaction.c')
| -rw-r--r-- | fs/jbd2/transaction.c | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index e5aba56e1fd5..ddcd3549c6c2 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -33,6 +33,35 @@ | |||
| 33 | static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); | 33 | static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); |
| 34 | static void __jbd2_journal_unfile_buffer(struct journal_head *jh); | 34 | static void __jbd2_journal_unfile_buffer(struct journal_head *jh); |
| 35 | 35 | ||
| 36 | static struct kmem_cache *transaction_cache; | ||
| 37 | int __init jbd2_journal_init_transaction_cache(void) | ||
| 38 | { | ||
| 39 | J_ASSERT(!transaction_cache); | ||
| 40 | transaction_cache = kmem_cache_create("jbd2_transaction_s", | ||
| 41 | sizeof(transaction_t), | ||
| 42 | 0, | ||
| 43 | SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY, | ||
| 44 | NULL); | ||
| 45 | if (transaction_cache) | ||
| 46 | return 0; | ||
| 47 | return -ENOMEM; | ||
| 48 | } | ||
| 49 | |||
| 50 | void jbd2_journal_destroy_transaction_cache(void) | ||
| 51 | { | ||
| 52 | if (transaction_cache) { | ||
| 53 | kmem_cache_destroy(transaction_cache); | ||
| 54 | transaction_cache = NULL; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | void jbd2_journal_free_transaction(transaction_t *transaction) | ||
| 59 | { | ||
| 60 | if (unlikely(ZERO_OR_NULL_PTR(transaction))) | ||
| 61 | return; | ||
| 62 | kmem_cache_free(transaction_cache, transaction); | ||
| 63 | } | ||
| 64 | |||
| 36 | /* | 65 | /* |
| 37 | * jbd2_get_transaction: obtain a new transaction_t object. | 66 | * jbd2_get_transaction: obtain a new transaction_t object. |
| 38 | * | 67 | * |
| @@ -133,7 +162,8 @@ static int start_this_handle(journal_t *journal, handle_t *handle, | |||
| 133 | 162 | ||
| 134 | alloc_transaction: | 163 | alloc_transaction: |
| 135 | if (!journal->j_running_transaction) { | 164 | if (!journal->j_running_transaction) { |
| 136 | new_transaction = kzalloc(sizeof(*new_transaction), gfp_mask); | 165 | new_transaction = kmem_cache_alloc(transaction_cache, |
| 166 | gfp_mask | __GFP_ZERO); | ||
| 137 | if (!new_transaction) { | 167 | if (!new_transaction) { |
| 138 | /* | 168 | /* |
| 139 | * If __GFP_FS is not present, then we may be | 169 | * If __GFP_FS is not present, then we may be |
| @@ -162,7 +192,7 @@ repeat: | |||
| 162 | if (is_journal_aborted(journal) || | 192 | if (is_journal_aborted(journal) || |
| 163 | (journal->j_errno != 0 && !(journal->j_flags & JBD2_ACK_ERR))) { | 193 | (journal->j_errno != 0 && !(journal->j_flags & JBD2_ACK_ERR))) { |
| 164 | read_unlock(&journal->j_state_lock); | 194 | read_unlock(&journal->j_state_lock); |
| 165 | kfree(new_transaction); | 195 | jbd2_journal_free_transaction(new_transaction); |
| 166 | return -EROFS; | 196 | return -EROFS; |
| 167 | } | 197 | } |
| 168 | 198 | ||
| @@ -284,7 +314,7 @@ repeat: | |||
| 284 | read_unlock(&journal->j_state_lock); | 314 | read_unlock(&journal->j_state_lock); |
| 285 | 315 | ||
| 286 | lock_map_acquire(&handle->h_lockdep_map); | 316 | lock_map_acquire(&handle->h_lockdep_map); |
| 287 | kfree(new_transaction); | 317 | jbd2_journal_free_transaction(new_transaction); |
| 288 | return 0; | 318 | return 0; |
| 289 | } | 319 | } |
| 290 | 320 | ||
| @@ -1549,9 +1579,9 @@ __blist_del_buffer(struct journal_head **list, struct journal_head *jh) | |||
| 1549 | * of these pointers, it could go bad. Generally the caller needs to re-read | 1579 | * of these pointers, it could go bad. Generally the caller needs to re-read |
| 1550 | * the pointer from the transaction_t. | 1580 | * the pointer from the transaction_t. |
| 1551 | * | 1581 | * |
| 1552 | * Called under j_list_lock. The journal may not be locked. | 1582 | * Called under j_list_lock. |
| 1553 | */ | 1583 | */ |
| 1554 | void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh) | 1584 | static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh) |
| 1555 | { | 1585 | { |
| 1556 | struct journal_head **list = NULL; | 1586 | struct journal_head **list = NULL; |
| 1557 | transaction_t *transaction; | 1587 | transaction_t *transaction; |
| @@ -1646,10 +1676,8 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) | |||
| 1646 | spin_lock(&journal->j_list_lock); | 1676 | spin_lock(&journal->j_list_lock); |
| 1647 | if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) { | 1677 | if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) { |
| 1648 | /* written-back checkpointed metadata buffer */ | 1678 | /* written-back checkpointed metadata buffer */ |
| 1649 | if (jh->b_jlist == BJ_None) { | 1679 | JBUFFER_TRACE(jh, "remove from checkpoint list"); |
| 1650 | JBUFFER_TRACE(jh, "remove from checkpoint list"); | 1680 | __jbd2_journal_remove_checkpoint(jh); |
| 1651 | __jbd2_journal_remove_checkpoint(jh); | ||
| 1652 | } | ||
| 1653 | } | 1681 | } |
| 1654 | spin_unlock(&journal->j_list_lock); | 1682 | spin_unlock(&journal->j_list_lock); |
| 1655 | out: | 1683 | out: |
| @@ -1949,6 +1977,8 @@ zap_buffer_unlocked: | |||
| 1949 | clear_buffer_mapped(bh); | 1977 | clear_buffer_mapped(bh); |
| 1950 | clear_buffer_req(bh); | 1978 | clear_buffer_req(bh); |
| 1951 | clear_buffer_new(bh); | 1979 | clear_buffer_new(bh); |
| 1980 | clear_buffer_delay(bh); | ||
| 1981 | clear_buffer_unwritten(bh); | ||
| 1952 | bh->b_bdev = NULL; | 1982 | bh->b_bdev = NULL; |
| 1953 | return may_free; | 1983 | return may_free; |
| 1954 | } | 1984 | } |
