diff options
author | Yongqiang Yang <xiaoqiangnk@gmail.com> | 2012-02-20 17:53:02 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-02-20 17:53:02 -0500 |
commit | 0c2022eccb01630c037f2024531e9ff1afbe1564 (patch) | |
tree | 704d54db298e64a84fd60330fd7985d27117d98c /fs/jbd2 | |
parent | 18aadd47f88464928b5ce57791c2e8f9f2aaece0 (diff) |
jbd2: allocate transaction from separate slab cache
There is normally only a handful of these active at any one time, but
putting them in a separate slab cache makes debugging memory
corruption problems easier. Manish Katiyar also wanted this make it
easier to test memory failure scenarios in the jbd2 layer.
Cc: Manish Katiyar <mkatiyar@gmail.com>
Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/jbd2')
-rw-r--r-- | fs/jbd2/checkpoint.c | 2 | ||||
-rw-r--r-- | fs/jbd2/commit.c | 2 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 3 | ||||
-rw-r--r-- | fs/jbd2/transaction.c | 36 |
4 files changed, 38 insertions, 5 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 453c9068b7d7..253e91890e71 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
@@ -722,7 +722,7 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) | |||
722 | transaction->t_tid, stats); | 722 | transaction->t_tid, stats); |
723 | 723 | ||
724 | __jbd2_journal_drop_transaction(journal, transaction); | 724 | __jbd2_journal_drop_transaction(journal, transaction); |
725 | kfree(transaction); | 725 | jbd2_journal_free_transaction(transaction); |
726 | 726 | ||
727 | /* Just in case anybody was waiting for more transactions to be | 727 | /* Just in case anybody was waiting for more transactions to be |
728 | checkpointed... */ | 728 | checkpointed... */ |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 5069b8475150..8adc5d460f56 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -1048,7 +1048,7 @@ restart_loop: | |||
1048 | jbd_debug(1, "JBD2: commit %d complete, head %d\n", | 1048 | jbd_debug(1, "JBD2: commit %d complete, head %d\n", |
1049 | journal->j_commit_sequence, journal->j_tail_sequence); | 1049 | journal->j_commit_sequence, journal->j_tail_sequence); |
1050 | if (to_free) | 1050 | if (to_free) |
1051 | kfree(commit_transaction); | 1051 | jbd2_journal_free_transaction(commit_transaction); |
1052 | 1052 | ||
1053 | wake_up(&journal->j_wait_done_commit); | 1053 | wake_up(&journal->j_wait_done_commit); |
1054 | } | 1054 | } |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 93a595c69616..aa8f5986f8da 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -2361,6 +2361,8 @@ static int __init journal_init_caches(void) | |||
2361 | ret = journal_init_jbd2_journal_head_cache(); | 2361 | ret = journal_init_jbd2_journal_head_cache(); |
2362 | if (ret == 0) | 2362 | if (ret == 0) |
2363 | ret = journal_init_handle_cache(); | 2363 | ret = journal_init_handle_cache(); |
2364 | if (ret == 0) | ||
2365 | ret = jbd2_journal_init_transaction_cache(); | ||
2364 | return ret; | 2366 | return ret; |
2365 | } | 2367 | } |
2366 | 2368 | ||
@@ -2369,6 +2371,7 @@ static void jbd2_journal_destroy_caches(void) | |||
2369 | jbd2_journal_destroy_revoke_caches(); | 2371 | jbd2_journal_destroy_revoke_caches(); |
2370 | jbd2_journal_destroy_jbd2_journal_head_cache(); | 2372 | jbd2_journal_destroy_jbd2_journal_head_cache(); |
2371 | jbd2_journal_destroy_handle_cache(); | 2373 | jbd2_journal_destroy_handle_cache(); |
2374 | jbd2_journal_destroy_transaction_cache(); | ||
2372 | jbd2_journal_destroy_slabs(); | 2375 | jbd2_journal_destroy_slabs(); |
2373 | } | 2376 | } |
2374 | 2377 | ||
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 526533062548..d0a8b017b281 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 | ||