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 | } |
