diff options
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r-- | fs/jbd2/commit.c | 67 |
1 files changed, 58 insertions, 9 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index ebc667bc54a8..62804e57a44c 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/crc32.h> | 25 | #include <linux/crc32.h> |
26 | #include <linux/writeback.h> | 26 | #include <linux/writeback.h> |
27 | #include <linux/backing-dev.h> | 27 | #include <linux/backing-dev.h> |
28 | #include <linux/bio.h> | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * Default IO end handler for temporary BJ_IO buffer_heads. | 31 | * Default IO end handler for temporary BJ_IO buffer_heads. |
@@ -137,7 +138,7 @@ static int journal_submit_commit_record(journal_t *journal, | |||
137 | set_buffer_ordered(bh); | 138 | set_buffer_ordered(bh); |
138 | barrier_done = 1; | 139 | barrier_done = 1; |
139 | } | 140 | } |
140 | ret = submit_bh(WRITE, bh); | 141 | ret = submit_bh(WRITE_SYNC, bh); |
141 | if (barrier_done) | 142 | if (barrier_done) |
142 | clear_buffer_ordered(bh); | 143 | clear_buffer_ordered(bh); |
143 | 144 | ||
@@ -158,7 +159,7 @@ static int journal_submit_commit_record(journal_t *journal, | |||
158 | lock_buffer(bh); | 159 | lock_buffer(bh); |
159 | set_buffer_uptodate(bh); | 160 | set_buffer_uptodate(bh); |
160 | clear_buffer_dirty(bh); | 161 | clear_buffer_dirty(bh); |
161 | ret = submit_bh(WRITE, bh); | 162 | ret = submit_bh(WRITE_SYNC, bh); |
162 | } | 163 | } |
163 | *cbh = bh; | 164 | *cbh = bh; |
164 | return ret; | 165 | return ret; |
@@ -168,12 +169,34 @@ static int journal_submit_commit_record(journal_t *journal, | |||
168 | * This function along with journal_submit_commit_record | 169 | * This function along with journal_submit_commit_record |
169 | * allows to write the commit record asynchronously. | 170 | * allows to write the commit record asynchronously. |
170 | */ | 171 | */ |
171 | static int journal_wait_on_commit_record(struct buffer_head *bh) | 172 | static int journal_wait_on_commit_record(journal_t *journal, |
173 | struct buffer_head *bh) | ||
172 | { | 174 | { |
173 | int ret = 0; | 175 | int ret = 0; |
174 | 176 | ||
177 | retry: | ||
175 | clear_buffer_dirty(bh); | 178 | clear_buffer_dirty(bh); |
176 | wait_on_buffer(bh); | 179 | wait_on_buffer(bh); |
180 | if (buffer_eopnotsupp(bh) && (journal->j_flags & JBD2_BARRIER)) { | ||
181 | printk(KERN_WARNING | ||
182 | "JBD2: wait_on_commit_record: sync failed on %s - " | ||
183 | "disabling barriers\n", journal->j_devname); | ||
184 | spin_lock(&journal->j_state_lock); | ||
185 | journal->j_flags &= ~JBD2_BARRIER; | ||
186 | spin_unlock(&journal->j_state_lock); | ||
187 | |||
188 | lock_buffer(bh); | ||
189 | clear_buffer_dirty(bh); | ||
190 | set_buffer_uptodate(bh); | ||
191 | bh->b_end_io = journal_end_buffer_io_sync; | ||
192 | |||
193 | ret = submit_bh(WRITE_SYNC, bh); | ||
194 | if (ret) { | ||
195 | unlock_buffer(bh); | ||
196 | return ret; | ||
197 | } | ||
198 | goto retry; | ||
199 | } | ||
177 | 200 | ||
178 | if (unlikely(!buffer_uptodate(bh))) | 201 | if (unlikely(!buffer_uptodate(bh))) |
179 | ret = -EIO; | 202 | ret = -EIO; |
@@ -332,13 +355,15 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
332 | int flags; | 355 | int flags; |
333 | int err; | 356 | int err; |
334 | unsigned long long blocknr; | 357 | unsigned long long blocknr; |
358 | ktime_t start_time; | ||
359 | u64 commit_time; | ||
335 | char *tagp = NULL; | 360 | char *tagp = NULL; |
336 | journal_header_t *header; | 361 | journal_header_t *header; |
337 | journal_block_tag_t *tag = NULL; | 362 | journal_block_tag_t *tag = NULL; |
338 | int space_left = 0; | 363 | int space_left = 0; |
339 | int first_tag = 0; | 364 | int first_tag = 0; |
340 | int tag_flag; | 365 | int tag_flag; |
341 | int i; | 366 | int i, to_free = 0; |
342 | int tag_bytes = journal_tag_bytes(journal); | 367 | int tag_bytes = journal_tag_bytes(journal); |
343 | struct buffer_head *cbh = NULL; /* For transactional checksums */ | 368 | struct buffer_head *cbh = NULL; /* For transactional checksums */ |
344 | __u32 crc32_sum = ~0; | 369 | __u32 crc32_sum = ~0; |
@@ -458,6 +483,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
458 | commit_transaction->t_state = T_FLUSH; | 483 | commit_transaction->t_state = T_FLUSH; |
459 | journal->j_committing_transaction = commit_transaction; | 484 | journal->j_committing_transaction = commit_transaction; |
460 | journal->j_running_transaction = NULL; | 485 | journal->j_running_transaction = NULL; |
486 | start_time = ktime_get(); | ||
461 | commit_transaction->t_log_start = journal->j_head; | 487 | commit_transaction->t_log_start = journal->j_head; |
462 | wake_up(&journal->j_wait_transaction_locked); | 488 | wake_up(&journal->j_wait_transaction_locked); |
463 | spin_unlock(&journal->j_state_lock); | 489 | spin_unlock(&journal->j_state_lock); |
@@ -509,6 +535,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
509 | if (is_journal_aborted(journal)) { | 535 | if (is_journal_aborted(journal)) { |
510 | clear_buffer_jbddirty(jh2bh(jh)); | 536 | clear_buffer_jbddirty(jh2bh(jh)); |
511 | JBUFFER_TRACE(jh, "journal is aborting: refile"); | 537 | JBUFFER_TRACE(jh, "journal is aborting: refile"); |
538 | jbd2_buffer_abort_trigger(jh, | ||
539 | jh->b_frozen_data ? | ||
540 | jh->b_frozen_triggers : | ||
541 | jh->b_triggers); | ||
512 | jbd2_journal_refile_buffer(journal, jh); | 542 | jbd2_journal_refile_buffer(journal, jh); |
513 | /* If that was the last one, we need to clean up | 543 | /* If that was the last one, we need to clean up |
514 | * any descriptor buffers which may have been | 544 | * any descriptor buffers which may have been |
@@ -799,7 +829,7 @@ wait_for_iobuf: | |||
799 | __jbd2_journal_abort_hard(journal); | 829 | __jbd2_journal_abort_hard(journal); |
800 | } | 830 | } |
801 | if (!err && !is_journal_aborted(journal)) | 831 | if (!err && !is_journal_aborted(journal)) |
802 | err = journal_wait_on_commit_record(cbh); | 832 | err = journal_wait_on_commit_record(journal, cbh); |
803 | 833 | ||
804 | if (err) | 834 | if (err) |
805 | jbd2_journal_abort(journal, err); | 835 | jbd2_journal_abort(journal, err); |
@@ -844,6 +874,9 @@ restart_loop: | |||
844 | * data. | 874 | * data. |
845 | * | 875 | * |
846 | * Otherwise, we can just throw away the frozen data now. | 876 | * Otherwise, we can just throw away the frozen data now. |
877 | * | ||
878 | * We also know that the frozen data has already fired | ||
879 | * its triggers if they exist, so we can clear that too. | ||
847 | */ | 880 | */ |
848 | if (jh->b_committed_data) { | 881 | if (jh->b_committed_data) { |
849 | jbd2_free(jh->b_committed_data, bh->b_size); | 882 | jbd2_free(jh->b_committed_data, bh->b_size); |
@@ -851,10 +884,12 @@ restart_loop: | |||
851 | if (jh->b_frozen_data) { | 884 | if (jh->b_frozen_data) { |
852 | jh->b_committed_data = jh->b_frozen_data; | 885 | jh->b_committed_data = jh->b_frozen_data; |
853 | jh->b_frozen_data = NULL; | 886 | jh->b_frozen_data = NULL; |
887 | jh->b_frozen_triggers = NULL; | ||
854 | } | 888 | } |
855 | } else if (jh->b_frozen_data) { | 889 | } else if (jh->b_frozen_data) { |
856 | jbd2_free(jh->b_frozen_data, bh->b_size); | 890 | jbd2_free(jh->b_frozen_data, bh->b_size); |
857 | jh->b_frozen_data = NULL; | 891 | jh->b_frozen_data = NULL; |
892 | jh->b_frozen_triggers = NULL; | ||
858 | } | 893 | } |
859 | 894 | ||
860 | spin_lock(&journal->j_list_lock); | 895 | spin_lock(&journal->j_list_lock); |
@@ -972,14 +1007,23 @@ restart_loop: | |||
972 | J_ASSERT(commit_transaction == journal->j_committing_transaction); | 1007 | J_ASSERT(commit_transaction == journal->j_committing_transaction); |
973 | journal->j_commit_sequence = commit_transaction->t_tid; | 1008 | journal->j_commit_sequence = commit_transaction->t_tid; |
974 | journal->j_committing_transaction = NULL; | 1009 | journal->j_committing_transaction = NULL; |
975 | spin_unlock(&journal->j_state_lock); | 1010 | commit_time = ktime_to_ns(ktime_sub(ktime_get(), start_time)); |
976 | 1011 | ||
977 | if (journal->j_commit_callback) | 1012 | /* |
978 | journal->j_commit_callback(journal, commit_transaction); | 1013 | * weight the commit time higher than the average time so we don't |
1014 | * react too strongly to vast changes in the commit time | ||
1015 | */ | ||
1016 | if (likely(journal->j_average_commit_time)) | ||
1017 | journal->j_average_commit_time = (commit_time + | ||
1018 | journal->j_average_commit_time*3) / 4; | ||
1019 | else | ||
1020 | journal->j_average_commit_time = commit_time; | ||
1021 | spin_unlock(&journal->j_state_lock); | ||
979 | 1022 | ||
980 | if (commit_transaction->t_checkpoint_list == NULL && | 1023 | if (commit_transaction->t_checkpoint_list == NULL && |
981 | commit_transaction->t_checkpoint_io_list == NULL) { | 1024 | commit_transaction->t_checkpoint_io_list == NULL) { |
982 | __jbd2_journal_drop_transaction(journal, commit_transaction); | 1025 | __jbd2_journal_drop_transaction(journal, commit_transaction); |
1026 | to_free = 1; | ||
983 | } else { | 1027 | } else { |
984 | if (journal->j_checkpoint_transactions == NULL) { | 1028 | if (journal->j_checkpoint_transactions == NULL) { |
985 | journal->j_checkpoint_transactions = commit_transaction; | 1029 | journal->j_checkpoint_transactions = commit_transaction; |
@@ -998,11 +1042,16 @@ restart_loop: | |||
998 | } | 1042 | } |
999 | spin_unlock(&journal->j_list_lock); | 1043 | spin_unlock(&journal->j_list_lock); |
1000 | 1044 | ||
1045 | if (journal->j_commit_callback) | ||
1046 | journal->j_commit_callback(journal, commit_transaction); | ||
1047 | |||
1001 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", | 1048 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", |
1002 | journal->j_devname, journal->j_commit_sequence, | 1049 | journal->j_devname, commit_transaction->t_tid, |
1003 | journal->j_tail_sequence); | 1050 | journal->j_tail_sequence); |
1004 | jbd_debug(1, "JBD: commit %d complete, head %d\n", | 1051 | jbd_debug(1, "JBD: commit %d complete, head %d\n", |
1005 | journal->j_commit_sequence, journal->j_tail_sequence); | 1052 | journal->j_commit_sequence, journal->j_tail_sequence); |
1053 | if (to_free) | ||
1054 | kfree(commit_transaction); | ||
1006 | 1055 | ||
1007 | wake_up(&journal->j_wait_done_commit); | 1056 | wake_up(&journal->j_wait_done_commit); |
1008 | } | 1057 | } |