diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/jbd2/journal.c | 9 | ||||
| -rw-r--r-- | fs/jbd2/transaction.c | 21 |
2 files changed, 21 insertions, 9 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 9e4686900f18..97e73469b2c4 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
| @@ -473,7 +473,8 @@ int __jbd2_log_space_left(journal_t *journal) | |||
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | /* | 475 | /* |
| 476 | * Called under j_state_lock. Returns true if a transaction commit was started. | 476 | * Called with j_state_lock locked for writing. |
| 477 | * Returns true if a transaction commit was started. | ||
| 477 | */ | 478 | */ |
| 478 | int __jbd2_log_start_commit(journal_t *journal, tid_t target) | 479 | int __jbd2_log_start_commit(journal_t *journal, tid_t target) |
| 479 | { | 480 | { |
| @@ -520,11 +521,13 @@ int jbd2_journal_force_commit_nested(journal_t *journal) | |||
| 520 | { | 521 | { |
| 521 | transaction_t *transaction = NULL; | 522 | transaction_t *transaction = NULL; |
| 522 | tid_t tid; | 523 | tid_t tid; |
| 524 | int need_to_start = 0; | ||
| 523 | 525 | ||
| 524 | read_lock(&journal->j_state_lock); | 526 | read_lock(&journal->j_state_lock); |
| 525 | if (journal->j_running_transaction && !current->journal_info) { | 527 | if (journal->j_running_transaction && !current->journal_info) { |
| 526 | transaction = journal->j_running_transaction; | 528 | transaction = journal->j_running_transaction; |
| 527 | __jbd2_log_start_commit(journal, transaction->t_tid); | 529 | if (!tid_geq(journal->j_commit_request, transaction->t_tid)) |
| 530 | need_to_start = 1; | ||
| 528 | } else if (journal->j_committing_transaction) | 531 | } else if (journal->j_committing_transaction) |
| 529 | transaction = journal->j_committing_transaction; | 532 | transaction = journal->j_committing_transaction; |
| 530 | 533 | ||
| @@ -535,6 +538,8 @@ int jbd2_journal_force_commit_nested(journal_t *journal) | |||
| 535 | 538 | ||
| 536 | tid = transaction->t_tid; | 539 | tid = transaction->t_tid; |
| 537 | read_unlock(&journal->j_state_lock); | 540 | read_unlock(&journal->j_state_lock); |
| 541 | if (need_to_start) | ||
| 542 | jbd2_log_start_commit(journal, tid); | ||
| 538 | jbd2_log_wait_commit(journal, tid); | 543 | jbd2_log_wait_commit(journal, tid); |
| 539 | return 1; | 544 | return 1; |
| 540 | } | 545 | } |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index faad2bd787c7..1d1191050f99 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -117,10 +117,10 @@ static inline void update_t_max_wait(transaction_t *transaction) | |||
| 117 | static int start_this_handle(journal_t *journal, handle_t *handle, | 117 | static int start_this_handle(journal_t *journal, handle_t *handle, |
| 118 | int gfp_mask) | 118 | int gfp_mask) |
| 119 | { | 119 | { |
| 120 | transaction_t *transaction; | 120 | transaction_t *transaction, *new_transaction = NULL; |
| 121 | int needed; | 121 | tid_t tid; |
| 122 | int nblocks = handle->h_buffer_credits; | 122 | int needed, need_to_start; |
| 123 | transaction_t *new_transaction = NULL; | 123 | int nblocks = handle->h_buffer_credits; |
| 124 | 124 | ||
| 125 | if (nblocks > journal->j_max_transaction_buffers) { | 125 | if (nblocks > journal->j_max_transaction_buffers) { |
| 126 | printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", | 126 | printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", |
| @@ -222,8 +222,11 @@ repeat: | |||
| 222 | atomic_sub(nblocks, &transaction->t_outstanding_credits); | 222 | atomic_sub(nblocks, &transaction->t_outstanding_credits); |
| 223 | prepare_to_wait(&journal->j_wait_transaction_locked, &wait, | 223 | prepare_to_wait(&journal->j_wait_transaction_locked, &wait, |
| 224 | TASK_UNINTERRUPTIBLE); | 224 | TASK_UNINTERRUPTIBLE); |
| 225 | __jbd2_log_start_commit(journal, transaction->t_tid); | 225 | tid = transaction->t_tid; |
| 226 | need_to_start = !tid_geq(journal->j_commit_request, tid); | ||
| 226 | read_unlock(&journal->j_state_lock); | 227 | read_unlock(&journal->j_state_lock); |
| 228 | if (need_to_start) | ||
| 229 | jbd2_log_start_commit(journal, tid); | ||
| 227 | schedule(); | 230 | schedule(); |
| 228 | finish_wait(&journal->j_wait_transaction_locked, &wait); | 231 | finish_wait(&journal->j_wait_transaction_locked, &wait); |
| 229 | goto repeat; | 232 | goto repeat; |
| @@ -442,7 +445,8 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, int gfp_mask) | |||
| 442 | { | 445 | { |
| 443 | transaction_t *transaction = handle->h_transaction; | 446 | transaction_t *transaction = handle->h_transaction; |
| 444 | journal_t *journal = transaction->t_journal; | 447 | journal_t *journal = transaction->t_journal; |
| 445 | int ret; | 448 | tid_t tid; |
| 449 | int need_to_start, ret; | ||
| 446 | 450 | ||
| 447 | /* If we've had an abort of any type, don't even think about | 451 | /* If we've had an abort of any type, don't even think about |
| 448 | * actually doing the restart! */ | 452 | * actually doing the restart! */ |
| @@ -465,8 +469,11 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, int gfp_mask) | |||
| 465 | spin_unlock(&transaction->t_handle_lock); | 469 | spin_unlock(&transaction->t_handle_lock); |
| 466 | 470 | ||
| 467 | jbd_debug(2, "restarting handle %p\n", handle); | 471 | jbd_debug(2, "restarting handle %p\n", handle); |
| 468 | __jbd2_log_start_commit(journal, transaction->t_tid); | 472 | tid = transaction->t_tid; |
| 473 | need_to_start = !tid_geq(journal->j_commit_request, tid); | ||
| 469 | read_unlock(&journal->j_state_lock); | 474 | read_unlock(&journal->j_state_lock); |
| 475 | if (need_to_start) | ||
| 476 | jbd2_log_start_commit(journal, tid); | ||
| 470 | 477 | ||
| 471 | lock_map_release(&handle->h_lockdep_map); | 478 | lock_map_release(&handle->h_lockdep_map); |
| 472 | handle->h_buffer_credits = nblocks; | 479 | handle->h_buffer_credits = nblocks; |
