diff options
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r-- | fs/jbd2/commit.c | 83 |
1 files changed, 38 insertions, 45 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 75716d3d2be..7c068c189d8 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -101,7 +101,6 @@ static int journal_submit_commit_record(journal_t *journal, | |||
101 | struct commit_header *tmp; | 101 | struct commit_header *tmp; |
102 | struct buffer_head *bh; | 102 | struct buffer_head *bh; |
103 | int ret; | 103 | int ret; |
104 | int barrier_done = 0; | ||
105 | struct timespec now = current_kernel_time(); | 104 | struct timespec now = current_kernel_time(); |
106 | 105 | ||
107 | if (is_journal_aborted(journal)) | 106 | if (is_journal_aborted(journal)) |
@@ -136,30 +135,22 @@ static int journal_submit_commit_record(journal_t *journal, | |||
136 | if (journal->j_flags & JBD2_BARRIER && | 135 | if (journal->j_flags & JBD2_BARRIER && |
137 | !JBD2_HAS_INCOMPAT_FEATURE(journal, | 136 | !JBD2_HAS_INCOMPAT_FEATURE(journal, |
138 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { | 137 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { |
139 | set_buffer_ordered(bh); | 138 | ret = submit_bh(WRITE_SYNC_PLUG | WRITE_BARRIER, bh); |
140 | barrier_done = 1; | 139 | if (ret == -EOPNOTSUPP) { |
141 | } | 140 | printk(KERN_WARNING |
142 | ret = submit_bh(WRITE_SYNC_PLUG, bh); | 141 | "JBD2: Disabling barriers on %s, " |
143 | if (barrier_done) | 142 | "not supported by device\n", journal->j_devname); |
144 | clear_buffer_ordered(bh); | 143 | write_lock(&journal->j_state_lock); |
145 | 144 | journal->j_flags &= ~JBD2_BARRIER; | |
146 | /* is it possible for another commit to fail at roughly | 145 | write_unlock(&journal->j_state_lock); |
147 | * the same time as this one? If so, we don't want to | 146 | |
148 | * trust the barrier flag in the super, but instead want | 147 | /* And try again, without the barrier */ |
149 | * to remember if we sent a barrier request | 148 | lock_buffer(bh); |
150 | */ | 149 | set_buffer_uptodate(bh); |
151 | if (ret == -EOPNOTSUPP && barrier_done) { | 150 | clear_buffer_dirty(bh); |
152 | printk(KERN_WARNING | 151 | ret = submit_bh(WRITE_SYNC_PLUG, bh); |
153 | "JBD: barrier-based sync failed on %s - " | 152 | } |
154 | "disabling barriers\n", journal->j_devname); | 153 | } else { |
155 | spin_lock(&journal->j_state_lock); | ||
156 | journal->j_flags &= ~JBD2_BARRIER; | ||
157 | spin_unlock(&journal->j_state_lock); | ||
158 | |||
159 | /* And try again, without the barrier */ | ||
160 | lock_buffer(bh); | ||
161 | set_buffer_uptodate(bh); | ||
162 | clear_buffer_dirty(bh); | ||
163 | ret = submit_bh(WRITE_SYNC_PLUG, bh); | 154 | ret = submit_bh(WRITE_SYNC_PLUG, bh); |
164 | } | 155 | } |
165 | *cbh = bh; | 156 | *cbh = bh; |
@@ -180,11 +171,11 @@ retry: | |||
180 | wait_on_buffer(bh); | 171 | wait_on_buffer(bh); |
181 | if (buffer_eopnotsupp(bh) && (journal->j_flags & JBD2_BARRIER)) { | 172 | if (buffer_eopnotsupp(bh) && (journal->j_flags & JBD2_BARRIER)) { |
182 | printk(KERN_WARNING | 173 | printk(KERN_WARNING |
183 | "JBD2: wait_on_commit_record: sync failed on %s - " | 174 | "JBD2: %s: disabling barries on %s - not supported " |
184 | "disabling barriers\n", journal->j_devname); | 175 | "by device\n", __func__, journal->j_devname); |
185 | spin_lock(&journal->j_state_lock); | 176 | write_lock(&journal->j_state_lock); |
186 | journal->j_flags &= ~JBD2_BARRIER; | 177 | journal->j_flags &= ~JBD2_BARRIER; |
187 | spin_unlock(&journal->j_state_lock); | 178 | write_unlock(&journal->j_state_lock); |
188 | 179 | ||
189 | lock_buffer(bh); | 180 | lock_buffer(bh); |
190 | clear_buffer_dirty(bh); | 181 | clear_buffer_dirty(bh); |
@@ -400,7 +391,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
400 | jbd_debug(1, "JBD: starting commit of transaction %d\n", | 391 | jbd_debug(1, "JBD: starting commit of transaction %d\n", |
401 | commit_transaction->t_tid); | 392 | commit_transaction->t_tid); |
402 | 393 | ||
403 | spin_lock(&journal->j_state_lock); | 394 | write_lock(&journal->j_state_lock); |
404 | commit_transaction->t_state = T_LOCKED; | 395 | commit_transaction->t_state = T_LOCKED; |
405 | 396 | ||
406 | /* | 397 | /* |
@@ -417,23 +408,23 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
417 | stats.run.rs_locked); | 408 | stats.run.rs_locked); |
418 | 409 | ||
419 | spin_lock(&commit_transaction->t_handle_lock); | 410 | spin_lock(&commit_transaction->t_handle_lock); |
420 | while (commit_transaction->t_updates) { | 411 | while (atomic_read(&commit_transaction->t_updates)) { |
421 | DEFINE_WAIT(wait); | 412 | DEFINE_WAIT(wait); |
422 | 413 | ||
423 | prepare_to_wait(&journal->j_wait_updates, &wait, | 414 | prepare_to_wait(&journal->j_wait_updates, &wait, |
424 | TASK_UNINTERRUPTIBLE); | 415 | TASK_UNINTERRUPTIBLE); |
425 | if (commit_transaction->t_updates) { | 416 | if (atomic_read(&commit_transaction->t_updates)) { |
426 | spin_unlock(&commit_transaction->t_handle_lock); | 417 | spin_unlock(&commit_transaction->t_handle_lock); |
427 | spin_unlock(&journal->j_state_lock); | 418 | write_unlock(&journal->j_state_lock); |
428 | schedule(); | 419 | schedule(); |
429 | spin_lock(&journal->j_state_lock); | 420 | write_lock(&journal->j_state_lock); |
430 | spin_lock(&commit_transaction->t_handle_lock); | 421 | spin_lock(&commit_transaction->t_handle_lock); |
431 | } | 422 | } |
432 | finish_wait(&journal->j_wait_updates, &wait); | 423 | finish_wait(&journal->j_wait_updates, &wait); |
433 | } | 424 | } |
434 | spin_unlock(&commit_transaction->t_handle_lock); | 425 | spin_unlock(&commit_transaction->t_handle_lock); |
435 | 426 | ||
436 | J_ASSERT (commit_transaction->t_outstanding_credits <= | 427 | J_ASSERT (atomic_read(&commit_transaction->t_outstanding_credits) <= |
437 | journal->j_max_transaction_buffers); | 428 | journal->j_max_transaction_buffers); |
438 | 429 | ||
439 | /* | 430 | /* |
@@ -497,7 +488,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
497 | start_time = ktime_get(); | 488 | start_time = ktime_get(); |
498 | commit_transaction->t_log_start = journal->j_head; | 489 | commit_transaction->t_log_start = journal->j_head; |
499 | wake_up(&journal->j_wait_transaction_locked); | 490 | wake_up(&journal->j_wait_transaction_locked); |
500 | spin_unlock(&journal->j_state_lock); | 491 | write_unlock(&journal->j_state_lock); |
501 | 492 | ||
502 | jbd_debug (3, "JBD: commit phase 2\n"); | 493 | jbd_debug (3, "JBD: commit phase 2\n"); |
503 | 494 | ||
@@ -519,19 +510,20 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
519 | * transaction! Now comes the tricky part: we need to write out | 510 | * transaction! Now comes the tricky part: we need to write out |
520 | * metadata. Loop over the transaction's entire buffer list: | 511 | * metadata. Loop over the transaction's entire buffer list: |
521 | */ | 512 | */ |
522 | spin_lock(&journal->j_state_lock); | 513 | write_lock(&journal->j_state_lock); |
523 | commit_transaction->t_state = T_COMMIT; | 514 | commit_transaction->t_state = T_COMMIT; |
524 | spin_unlock(&journal->j_state_lock); | 515 | write_unlock(&journal->j_state_lock); |
525 | 516 | ||
526 | trace_jbd2_commit_logging(journal, commit_transaction); | 517 | trace_jbd2_commit_logging(journal, commit_transaction); |
527 | stats.run.rs_logging = jiffies; | 518 | stats.run.rs_logging = jiffies; |
528 | stats.run.rs_flushing = jbd2_time_diff(stats.run.rs_flushing, | 519 | stats.run.rs_flushing = jbd2_time_diff(stats.run.rs_flushing, |
529 | stats.run.rs_logging); | 520 | stats.run.rs_logging); |
530 | stats.run.rs_blocks = commit_transaction->t_outstanding_credits; | 521 | stats.run.rs_blocks = |
522 | atomic_read(&commit_transaction->t_outstanding_credits); | ||
531 | stats.run.rs_blocks_logged = 0; | 523 | stats.run.rs_blocks_logged = 0; |
532 | 524 | ||
533 | J_ASSERT(commit_transaction->t_nr_buffers <= | 525 | J_ASSERT(commit_transaction->t_nr_buffers <= |
534 | commit_transaction->t_outstanding_credits); | 526 | atomic_read(&commit_transaction->t_outstanding_credits)); |
535 | 527 | ||
536 | err = 0; | 528 | err = 0; |
537 | descriptor = NULL; | 529 | descriptor = NULL; |
@@ -616,7 +608,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
616 | * the free space in the log, but this counter is changed | 608 | * the free space in the log, but this counter is changed |
617 | * by jbd2_journal_next_log_block() also. | 609 | * by jbd2_journal_next_log_block() also. |
618 | */ | 610 | */ |
619 | commit_transaction->t_outstanding_credits--; | 611 | atomic_dec(&commit_transaction->t_outstanding_credits); |
620 | 612 | ||
621 | /* Bump b_count to prevent truncate from stumbling over | 613 | /* Bump b_count to prevent truncate from stumbling over |
622 | the shadowed buffer! @@@ This can go if we ever get | 614 | the shadowed buffer! @@@ This can go if we ever get |
@@ -977,7 +969,7 @@ restart_loop: | |||
977 | * __jbd2_journal_drop_transaction(). Otherwise we could race with | 969 | * __jbd2_journal_drop_transaction(). Otherwise we could race with |
978 | * other checkpointing code processing the transaction... | 970 | * other checkpointing code processing the transaction... |
979 | */ | 971 | */ |
980 | spin_lock(&journal->j_state_lock); | 972 | write_lock(&journal->j_state_lock); |
981 | spin_lock(&journal->j_list_lock); | 973 | spin_lock(&journal->j_list_lock); |
982 | /* | 974 | /* |
983 | * Now recheck if some buffers did not get attached to the transaction | 975 | * Now recheck if some buffers did not get attached to the transaction |
@@ -985,7 +977,7 @@ restart_loop: | |||
985 | */ | 977 | */ |
986 | if (commit_transaction->t_forget) { | 978 | if (commit_transaction->t_forget) { |
987 | spin_unlock(&journal->j_list_lock); | 979 | spin_unlock(&journal->j_list_lock); |
988 | spin_unlock(&journal->j_state_lock); | 980 | write_unlock(&journal->j_state_lock); |
989 | goto restart_loop; | 981 | goto restart_loop; |
990 | } | 982 | } |
991 | 983 | ||
@@ -1003,7 +995,8 @@ restart_loop: | |||
1003 | * File the transaction statistics | 995 | * File the transaction statistics |
1004 | */ | 996 | */ |
1005 | stats.ts_tid = commit_transaction->t_tid; | 997 | stats.ts_tid = commit_transaction->t_tid; |
1006 | stats.run.rs_handle_count = commit_transaction->t_handle_count; | 998 | stats.run.rs_handle_count = |
999 | atomic_read(&commit_transaction->t_handle_count); | ||
1007 | trace_jbd2_run_stats(journal->j_fs_dev->bd_dev, | 1000 | trace_jbd2_run_stats(journal->j_fs_dev->bd_dev, |
1008 | commit_transaction->t_tid, &stats.run); | 1001 | commit_transaction->t_tid, &stats.run); |
1009 | 1002 | ||
@@ -1037,7 +1030,7 @@ restart_loop: | |||
1037 | journal->j_average_commit_time*3) / 4; | 1030 | journal->j_average_commit_time*3) / 4; |
1038 | else | 1031 | else |
1039 | journal->j_average_commit_time = commit_time; | 1032 | journal->j_average_commit_time = commit_time; |
1040 | spin_unlock(&journal->j_state_lock); | 1033 | write_unlock(&journal->j_state_lock); |
1041 | 1034 | ||
1042 | if (commit_transaction->t_checkpoint_list == NULL && | 1035 | if (commit_transaction->t_checkpoint_list == NULL && |
1043 | commit_transaction->t_checkpoint_io_list == NULL) { | 1036 | commit_transaction->t_checkpoint_io_list == NULL) { |