diff options
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r-- | fs/jbd2/commit.c | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 6e28000a4b21..eef6979821a4 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -219,7 +219,6 @@ static int journal_submit_data_buffers(journal_t *journal, | |||
219 | ret = err; | 219 | ret = err; |
220 | spin_lock(&journal->j_list_lock); | 220 | spin_lock(&journal->j_list_lock); |
221 | J_ASSERT(jinode->i_transaction == commit_transaction); | 221 | J_ASSERT(jinode->i_transaction == commit_transaction); |
222 | commit_transaction->t_flushed_data_blocks = 1; | ||
223 | clear_bit(__JI_COMMIT_RUNNING, &jinode->i_flags); | 222 | clear_bit(__JI_COMMIT_RUNNING, &jinode->i_flags); |
224 | smp_mb__after_clear_bit(); | 223 | smp_mb__after_clear_bit(); |
225 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); | 224 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); |
@@ -338,12 +337,6 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
338 | * all outstanding updates to complete. | 337 | * all outstanding updates to complete. |
339 | */ | 338 | */ |
340 | 339 | ||
341 | #ifdef COMMIT_STATS | ||
342 | spin_lock(&journal->j_list_lock); | ||
343 | summarise_journal_usage(journal); | ||
344 | spin_unlock(&journal->j_list_lock); | ||
345 | #endif | ||
346 | |||
347 | /* Do we need to erase the effects of a prior jbd2_journal_flush? */ | 340 | /* Do we need to erase the effects of a prior jbd2_journal_flush? */ |
348 | if (journal->j_flags & JBD2_FLUSHED) { | 341 | if (journal->j_flags & JBD2_FLUSHED) { |
349 | jbd_debug(3, "super block updated\n"); | 342 | jbd_debug(3, "super block updated\n"); |
@@ -678,12 +671,16 @@ start_journal_io: | |||
678 | err = 0; | 671 | err = 0; |
679 | } | 672 | } |
680 | 673 | ||
674 | write_lock(&journal->j_state_lock); | ||
675 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | ||
676 | commit_transaction->t_state = T_COMMIT_DFLUSH; | ||
677 | write_unlock(&journal->j_state_lock); | ||
681 | /* | 678 | /* |
682 | * If the journal is not located on the file system device, | 679 | * If the journal is not located on the file system device, |
683 | * then we must flush the file system device before we issue | 680 | * then we must flush the file system device before we issue |
684 | * the commit record | 681 | * the commit record |
685 | */ | 682 | */ |
686 | if (commit_transaction->t_flushed_data_blocks && | 683 | if (commit_transaction->t_need_data_flush && |
687 | (journal->j_fs_dev != journal->j_dev) && | 684 | (journal->j_fs_dev != journal->j_dev) && |
688 | (journal->j_flags & JBD2_BARRIER)) | 685 | (journal->j_flags & JBD2_BARRIER)) |
689 | blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); | 686 | blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); |
@@ -760,8 +757,13 @@ wait_for_iobuf: | |||
760 | required. */ | 757 | required. */ |
761 | JBUFFER_TRACE(jh, "file as BJ_Forget"); | 758 | JBUFFER_TRACE(jh, "file as BJ_Forget"); |
762 | jbd2_journal_file_buffer(jh, commit_transaction, BJ_Forget); | 759 | jbd2_journal_file_buffer(jh, commit_transaction, BJ_Forget); |
763 | /* Wake up any transactions which were waiting for this | 760 | /* |
764 | IO to complete */ | 761 | * Wake up any transactions which were waiting for this IO to |
762 | * complete. The barrier must be here so that changes by | ||
763 | * jbd2_journal_file_buffer() take effect before wake_up_bit() | ||
764 | * does the waitqueue check. | ||
765 | */ | ||
766 | smp_mb(); | ||
765 | wake_up_bit(&bh->b_state, BH_Unshadow); | 767 | wake_up_bit(&bh->b_state, BH_Unshadow); |
766 | JBUFFER_TRACE(jh, "brelse shadowed buffer"); | 768 | JBUFFER_TRACE(jh, "brelse shadowed buffer"); |
767 | __brelse(bh); | 769 | __brelse(bh); |
@@ -800,6 +802,10 @@ wait_for_iobuf: | |||
800 | jbd2_journal_abort(journal, err); | 802 | jbd2_journal_abort(journal, err); |
801 | 803 | ||
802 | jbd_debug(3, "JBD: commit phase 5\n"); | 804 | jbd_debug(3, "JBD: commit phase 5\n"); |
805 | write_lock(&journal->j_state_lock); | ||
806 | J_ASSERT(commit_transaction->t_state == T_COMMIT_DFLUSH); | ||
807 | commit_transaction->t_state = T_COMMIT_JFLUSH; | ||
808 | write_unlock(&journal->j_state_lock); | ||
803 | 809 | ||
804 | if (!JBD2_HAS_INCOMPAT_FEATURE(journal, | 810 | if (!JBD2_HAS_INCOMPAT_FEATURE(journal, |
805 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { | 811 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { |
@@ -842,10 +848,16 @@ restart_loop: | |||
842 | while (commit_transaction->t_forget) { | 848 | while (commit_transaction->t_forget) { |
843 | transaction_t *cp_transaction; | 849 | transaction_t *cp_transaction; |
844 | struct buffer_head *bh; | 850 | struct buffer_head *bh; |
851 | int try_to_free = 0; | ||
845 | 852 | ||
846 | jh = commit_transaction->t_forget; | 853 | jh = commit_transaction->t_forget; |
847 | spin_unlock(&journal->j_list_lock); | 854 | spin_unlock(&journal->j_list_lock); |
848 | bh = jh2bh(jh); | 855 | bh = jh2bh(jh); |
856 | /* | ||
857 | * Get a reference so that bh cannot be freed before we are | ||
858 | * done with it. | ||
859 | */ | ||
860 | get_bh(bh); | ||
849 | jbd_lock_bh_state(bh); | 861 | jbd_lock_bh_state(bh); |
850 | J_ASSERT_JH(jh, jh->b_transaction == commit_transaction); | 862 | J_ASSERT_JH(jh, jh->b_transaction == commit_transaction); |
851 | 863 | ||
@@ -908,28 +920,27 @@ restart_loop: | |||
908 | __jbd2_journal_insert_checkpoint(jh, commit_transaction); | 920 | __jbd2_journal_insert_checkpoint(jh, commit_transaction); |
909 | if (is_journal_aborted(journal)) | 921 | if (is_journal_aborted(journal)) |
910 | clear_buffer_jbddirty(bh); | 922 | clear_buffer_jbddirty(bh); |
911 | JBUFFER_TRACE(jh, "refile for checkpoint writeback"); | ||
912 | __jbd2_journal_refile_buffer(jh); | ||
913 | jbd_unlock_bh_state(bh); | ||
914 | } else { | 923 | } else { |
915 | J_ASSERT_BH(bh, !buffer_dirty(bh)); | 924 | J_ASSERT_BH(bh, !buffer_dirty(bh)); |
916 | /* The buffer on BJ_Forget list and not jbddirty means | 925 | /* |
926 | * The buffer on BJ_Forget list and not jbddirty means | ||
917 | * it has been freed by this transaction and hence it | 927 | * it has been freed by this transaction and hence it |
918 | * could not have been reallocated until this | 928 | * could not have been reallocated until this |
919 | * transaction has committed. *BUT* it could be | 929 | * transaction has committed. *BUT* it could be |
920 | * reallocated once we have written all the data to | 930 | * reallocated once we have written all the data to |
921 | * disk and before we process the buffer on BJ_Forget | 931 | * disk and before we process the buffer on BJ_Forget |
922 | * list. */ | 932 | * list. |
923 | JBUFFER_TRACE(jh, "refile or unfile freed buffer"); | 933 | */ |
924 | __jbd2_journal_refile_buffer(jh); | 934 | if (!jh->b_next_transaction) |
925 | if (!jh->b_transaction) { | 935 | try_to_free = 1; |
926 | jbd_unlock_bh_state(bh); | ||
927 | /* needs a brelse */ | ||
928 | jbd2_journal_remove_journal_head(bh); | ||
929 | release_buffer_page(bh); | ||
930 | } else | ||
931 | jbd_unlock_bh_state(bh); | ||
932 | } | 936 | } |
937 | JBUFFER_TRACE(jh, "refile or unfile buffer"); | ||
938 | __jbd2_journal_refile_buffer(jh); | ||
939 | jbd_unlock_bh_state(bh); | ||
940 | if (try_to_free) | ||
941 | release_buffer_page(bh); /* Drops bh reference */ | ||
942 | else | ||
943 | __brelse(bh); | ||
933 | cond_resched_lock(&journal->j_list_lock); | 944 | cond_resched_lock(&journal->j_list_lock); |
934 | } | 945 | } |
935 | spin_unlock(&journal->j_list_lock); | 946 | spin_unlock(&journal->j_list_lock); |
@@ -955,7 +966,7 @@ restart_loop: | |||
955 | 966 | ||
956 | jbd_debug(3, "JBD: commit phase 7\n"); | 967 | jbd_debug(3, "JBD: commit phase 7\n"); |
957 | 968 | ||
958 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | 969 | J_ASSERT(commit_transaction->t_state == T_COMMIT_JFLUSH); |
959 | 970 | ||
960 | commit_transaction->t_start = jiffies; | 971 | commit_transaction->t_start = jiffies; |
961 | stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, | 972 | stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, |