diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 14:34:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 14:34:40 -0400 |
commit | 2ac232f37fa0e8551856a575fe299c47b65b4d66 (patch) | |
tree | 58ff15ecdbc383415a82ea678e5191db16a479f3 /fs/jbd/commit.c | |
parent | fa8f53ace4af9470d8414427cb3dc3c0ffc4f182 (diff) | |
parent | 5cf49d763eb141d236e92be6d4a0dc94e31fa886 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6:
jbd: change the field "b_cow_tid" of struct journal_head from type unsigned to tid_t
ext3.txt: update the links in the section "useful links" to the latest ones
ext3: Fix data corruption in inodes with journalled data
ext2: check xattr name_len before acquiring xattr_sem in ext2_xattr_get
ext3: Fix compilation with -DDX_DEBUG
quota: Remove unused declaration
jbd: Use WRITE_SYNC in journal checkpoint.
jbd: Fix oops in journal_remove_journal_head()
ext3: Return -EINVAL when start is beyond the end of fs in ext3_trim_fs()
ext3/ioctl.c: silence sparse warnings about different address spaces
ext3/ext4 Documentation: remove bh/nobh since it has been deprecated
ext3: Improve truncate error handling
ext3: use proper little-endian bitops
ext2: include fs.h into ext2_fs.h
ext3: Fix oops in ext3_try_to_allocate_with_rsv()
jbd: fix a bug of leaking jh->b_jcount
jbd: remove dependency on __GFP_NOFAIL
ext3: Convert ext3 to new truncate calling convention
jbd: Add fixed tracepoints
ext3: Add fixed tracepoints
Resolve conflicts in fs/ext3/fsync.c due to fsync locking push-down and
new fixed tracepoints.
Diffstat (limited to 'fs/jbd/commit.c')
-rw-r--r-- | fs/jbd/commit.c | 57 |
1 files changed, 32 insertions, 25 deletions
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index 72ffa974b0b8..8799207df058 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/pagemap.h> | 21 | #include <linux/pagemap.h> |
22 | #include <linux/bio.h> | 22 | #include <linux/bio.h> |
23 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
24 | #include <trace/events/jbd.h> | ||
24 | 25 | ||
25 | /* | 26 | /* |
26 | * Default IO end handler for temporary BJ_IO buffer_heads. | 27 | * Default IO end handler for temporary BJ_IO buffer_heads. |
@@ -204,6 +205,8 @@ write_out_data: | |||
204 | if (!trylock_buffer(bh)) { | 205 | if (!trylock_buffer(bh)) { |
205 | BUFFER_TRACE(bh, "needs blocking lock"); | 206 | BUFFER_TRACE(bh, "needs blocking lock"); |
206 | spin_unlock(&journal->j_list_lock); | 207 | spin_unlock(&journal->j_list_lock); |
208 | trace_jbd_do_submit_data(journal, | ||
209 | commit_transaction); | ||
207 | /* Write out all data to prevent deadlocks */ | 210 | /* Write out all data to prevent deadlocks */ |
208 | journal_do_submit_data(wbuf, bufs, write_op); | 211 | journal_do_submit_data(wbuf, bufs, write_op); |
209 | bufs = 0; | 212 | bufs = 0; |
@@ -236,6 +239,8 @@ write_out_data: | |||
236 | jbd_unlock_bh_state(bh); | 239 | jbd_unlock_bh_state(bh); |
237 | if (bufs == journal->j_wbufsize) { | 240 | if (bufs == journal->j_wbufsize) { |
238 | spin_unlock(&journal->j_list_lock); | 241 | spin_unlock(&journal->j_list_lock); |
242 | trace_jbd_do_submit_data(journal, | ||
243 | commit_transaction); | ||
239 | journal_do_submit_data(wbuf, bufs, write_op); | 244 | journal_do_submit_data(wbuf, bufs, write_op); |
240 | bufs = 0; | 245 | bufs = 0; |
241 | goto write_out_data; | 246 | goto write_out_data; |
@@ -253,10 +258,6 @@ write_out_data: | |||
253 | jbd_unlock_bh_state(bh); | 258 | jbd_unlock_bh_state(bh); |
254 | if (locked) | 259 | if (locked) |
255 | unlock_buffer(bh); | 260 | unlock_buffer(bh); |
256 | journal_remove_journal_head(bh); | ||
257 | /* One for our safety reference, other for | ||
258 | * journal_remove_journal_head() */ | ||
259 | put_bh(bh); | ||
260 | release_data_buffer(bh); | 261 | release_data_buffer(bh); |
261 | } | 262 | } |
262 | 263 | ||
@@ -266,6 +267,7 @@ write_out_data: | |||
266 | } | 267 | } |
267 | } | 268 | } |
268 | spin_unlock(&journal->j_list_lock); | 269 | spin_unlock(&journal->j_list_lock); |
270 | trace_jbd_do_submit_data(journal, commit_transaction); | ||
269 | journal_do_submit_data(wbuf, bufs, write_op); | 271 | journal_do_submit_data(wbuf, bufs, write_op); |
270 | 272 | ||
271 | return err; | 273 | return err; |
@@ -316,12 +318,14 @@ void journal_commit_transaction(journal_t *journal) | |||
316 | commit_transaction = journal->j_running_transaction; | 318 | commit_transaction = journal->j_running_transaction; |
317 | J_ASSERT(commit_transaction->t_state == T_RUNNING); | 319 | J_ASSERT(commit_transaction->t_state == T_RUNNING); |
318 | 320 | ||
321 | trace_jbd_start_commit(journal, commit_transaction); | ||
319 | jbd_debug(1, "JBD: starting commit of transaction %d\n", | 322 | jbd_debug(1, "JBD: starting commit of transaction %d\n", |
320 | commit_transaction->t_tid); | 323 | commit_transaction->t_tid); |
321 | 324 | ||
322 | spin_lock(&journal->j_state_lock); | 325 | spin_lock(&journal->j_state_lock); |
323 | commit_transaction->t_state = T_LOCKED; | 326 | commit_transaction->t_state = T_LOCKED; |
324 | 327 | ||
328 | trace_jbd_commit_locking(journal, commit_transaction); | ||
325 | spin_lock(&commit_transaction->t_handle_lock); | 329 | spin_lock(&commit_transaction->t_handle_lock); |
326 | while (commit_transaction->t_updates) { | 330 | while (commit_transaction->t_updates) { |
327 | DEFINE_WAIT(wait); | 331 | DEFINE_WAIT(wait); |
@@ -392,6 +396,7 @@ void journal_commit_transaction(journal_t *journal) | |||
392 | */ | 396 | */ |
393 | journal_switch_revoke_table(journal); | 397 | journal_switch_revoke_table(journal); |
394 | 398 | ||
399 | trace_jbd_commit_flushing(journal, commit_transaction); | ||
395 | commit_transaction->t_state = T_FLUSH; | 400 | commit_transaction->t_state = T_FLUSH; |
396 | journal->j_committing_transaction = commit_transaction; | 401 | journal->j_committing_transaction = commit_transaction; |
397 | journal->j_running_transaction = NULL; | 402 | journal->j_running_transaction = NULL; |
@@ -446,14 +451,9 @@ void journal_commit_transaction(journal_t *journal) | |||
446 | } | 451 | } |
447 | if (buffer_jbd(bh) && bh2jh(bh) == jh && | 452 | if (buffer_jbd(bh) && bh2jh(bh) == jh && |
448 | jh->b_transaction == commit_transaction && | 453 | jh->b_transaction == commit_transaction && |
449 | jh->b_jlist == BJ_Locked) { | 454 | jh->b_jlist == BJ_Locked) |
450 | __journal_unfile_buffer(jh); | 455 | __journal_unfile_buffer(jh); |
451 | jbd_unlock_bh_state(bh); | 456 | jbd_unlock_bh_state(bh); |
452 | journal_remove_journal_head(bh); | ||
453 | put_bh(bh); | ||
454 | } else { | ||
455 | jbd_unlock_bh_state(bh); | ||
456 | } | ||
457 | release_data_buffer(bh); | 457 | release_data_buffer(bh); |
458 | cond_resched_lock(&journal->j_list_lock); | 458 | cond_resched_lock(&journal->j_list_lock); |
459 | } | 459 | } |
@@ -493,6 +493,7 @@ void journal_commit_transaction(journal_t *journal) | |||
493 | commit_transaction->t_state = T_COMMIT; | 493 | commit_transaction->t_state = T_COMMIT; |
494 | spin_unlock(&journal->j_state_lock); | 494 | spin_unlock(&journal->j_state_lock); |
495 | 495 | ||
496 | trace_jbd_commit_logging(journal, commit_transaction); | ||
496 | J_ASSERT(commit_transaction->t_nr_buffers <= | 497 | J_ASSERT(commit_transaction->t_nr_buffers <= |
497 | commit_transaction->t_outstanding_credits); | 498 | commit_transaction->t_outstanding_credits); |
498 | 499 | ||
@@ -797,10 +798,16 @@ restart_loop: | |||
797 | while (commit_transaction->t_forget) { | 798 | while (commit_transaction->t_forget) { |
798 | transaction_t *cp_transaction; | 799 | transaction_t *cp_transaction; |
799 | struct buffer_head *bh; | 800 | struct buffer_head *bh; |
801 | int try_to_free = 0; | ||
800 | 802 | ||
801 | jh = commit_transaction->t_forget; | 803 | jh = commit_transaction->t_forget; |
802 | spin_unlock(&journal->j_list_lock); | 804 | spin_unlock(&journal->j_list_lock); |
803 | bh = jh2bh(jh); | 805 | bh = jh2bh(jh); |
806 | /* | ||
807 | * Get a reference so that bh cannot be freed before we are | ||
808 | * done with it. | ||
809 | */ | ||
810 | get_bh(bh); | ||
804 | jbd_lock_bh_state(bh); | 811 | jbd_lock_bh_state(bh); |
805 | J_ASSERT_JH(jh, jh->b_transaction == commit_transaction || | 812 | J_ASSERT_JH(jh, jh->b_transaction == commit_transaction || |
806 | jh->b_transaction == journal->j_running_transaction); | 813 | jh->b_transaction == journal->j_running_transaction); |
@@ -858,28 +865,27 @@ restart_loop: | |||
858 | __journal_insert_checkpoint(jh, commit_transaction); | 865 | __journal_insert_checkpoint(jh, commit_transaction); |
859 | if (is_journal_aborted(journal)) | 866 | if (is_journal_aborted(journal)) |
860 | clear_buffer_jbddirty(bh); | 867 | clear_buffer_jbddirty(bh); |
861 | JBUFFER_TRACE(jh, "refile for checkpoint writeback"); | ||
862 | __journal_refile_buffer(jh); | ||
863 | jbd_unlock_bh_state(bh); | ||
864 | } else { | 868 | } else { |
865 | J_ASSERT_BH(bh, !buffer_dirty(bh)); | 869 | J_ASSERT_BH(bh, !buffer_dirty(bh)); |
866 | /* The buffer on BJ_Forget list and not jbddirty means | 870 | /* |
871 | * The buffer on BJ_Forget list and not jbddirty means | ||
867 | * it has been freed by this transaction and hence it | 872 | * it has been freed by this transaction and hence it |
868 | * could not have been reallocated until this | 873 | * could not have been reallocated until this |
869 | * transaction has committed. *BUT* it could be | 874 | * transaction has committed. *BUT* it could be |
870 | * reallocated once we have written all the data to | 875 | * reallocated once we have written all the data to |
871 | * disk and before we process the buffer on BJ_Forget | 876 | * disk and before we process the buffer on BJ_Forget |
872 | * list. */ | 877 | * list. |
873 | JBUFFER_TRACE(jh, "refile or unfile freed buffer"); | 878 | */ |
874 | __journal_refile_buffer(jh); | 879 | if (!jh->b_next_transaction) |
875 | if (!jh->b_transaction) { | 880 | try_to_free = 1; |
876 | jbd_unlock_bh_state(bh); | ||
877 | /* needs a brelse */ | ||
878 | journal_remove_journal_head(bh); | ||
879 | release_buffer_page(bh); | ||
880 | } else | ||
881 | jbd_unlock_bh_state(bh); | ||
882 | } | 881 | } |
882 | JBUFFER_TRACE(jh, "refile or unfile freed buffer"); | ||
883 | __journal_refile_buffer(jh); | ||
884 | jbd_unlock_bh_state(bh); | ||
885 | if (try_to_free) | ||
886 | release_buffer_page(bh); | ||
887 | else | ||
888 | __brelse(bh); | ||
883 | cond_resched_lock(&journal->j_list_lock); | 889 | cond_resched_lock(&journal->j_list_lock); |
884 | } | 890 | } |
885 | spin_unlock(&journal->j_list_lock); | 891 | spin_unlock(&journal->j_list_lock); |
@@ -946,6 +952,7 @@ restart_loop: | |||
946 | } | 952 | } |
947 | spin_unlock(&journal->j_list_lock); | 953 | spin_unlock(&journal->j_list_lock); |
948 | 954 | ||
955 | trace_jbd_end_commit(journal, commit_transaction); | ||
949 | jbd_debug(1, "JBD: commit %d complete, head %d\n", | 956 | jbd_debug(1, "JBD: commit %d complete, head %d\n", |
950 | journal->j_commit_sequence, journal->j_tail_sequence); | 957 | journal->j_commit_sequence, journal->j_tail_sequence); |
951 | 958 | ||