Commit 28a4dd1b authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] JBD: additional transaction shutdown locking

Plug a conceivable race with the freeing up of trasnactions, and add some
more debug checks.
parent 833f3d15
......@@ -538,7 +538,8 @@ void __journal_remove_checkpoint(struct journal_head *jh)
* checkpoint list is empty, the transaction obviously cannot be
* dropped!
*
* AKPM2: locking here around j_committing_transaction is a bit flakey.
* The locking here around j_committing_transaction is a bit sleazy.
* See the comment at the end of journal_commit_transaction().
*/
if (transaction == journal->j_committing_transaction) {
JBUFFER_TRACE(jh, "belongs to committing transaction");
......@@ -608,6 +609,7 @@ void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
journal->j_checkpoint_transactions = NULL;
}
J_ASSERT(transaction->t_state == T_FINISHED);
J_ASSERT(transaction->t_buffers == NULL);
J_ASSERT(transaction->t_sync_datalist == NULL);
J_ASSERT(transaction->t_forget == NULL);
......@@ -617,10 +619,9 @@ void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
J_ASSERT(transaction->t_checkpoint_list == NULL);
J_ASSERT(transaction->t_updates == 0);
J_ASSERT(list_empty(&transaction->t_jcb));
J_ASSERT(journal->j_committing_transaction != transaction);
J_ASSERT(journal->j_running_transaction != transaction);
jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
kfree(transaction);
}
......@@ -704,14 +704,20 @@ void journal_commit_transaction(journal_t *journal)
J_ASSERT(commit_transaction->t_state == T_COMMIT);
/*
* This is a bit sleazy. We borrow j_list_lock to protect
* journal->j_committing_transaction in __journal_remove_checkpoint.
* Really, __jornal_remove_checkpoint should be using j_state_lock but
* it's a bit hassle to hold that across __journal_remove_checkpoint
*/
spin_lock(&journal->j_state_lock);
spin_lock(&journal->j_list_lock);
commit_transaction->t_state = T_FINISHED;
J_ASSERT(commit_transaction == journal->j_committing_transaction);
journal->j_commit_sequence = commit_transaction->t_tid;
journal->j_committing_transaction = NULL;
spin_unlock(&journal->j_state_lock);
spin_lock(&journal->j_list_lock);
if (commit_transaction->t_checkpoint_list == NULL) {
__journal_drop_transaction(journal, commit_transaction);
} else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment