jbd2: Call the commit callback before the transaction could get dropped

The transaction can potentially get dropped if there are no buffers
that need to be written.  Make sure we call the commit callback before
potentially deciding to drop the transaction.  Also avoid
dereferencing the commit_transaction pointer in the marker for the
same reason.

This patch fixes the bug reported by Eric Paris at:
http://bugzilla.kernel.org/show_bug.cgi?id=11838

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Acked-by: Eric Sandeen <sandeen@redhat.com>
Tested-by: Eric Paris <eparis@redhat.com>
This commit is contained in:
Theodore Ts'o 2008-10-28 21:08:20 -04:00
parent ef2cabf7c6
commit 6c20ec8503

View File

@ -974,6 +974,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
journal->j_committing_transaction = NULL; journal->j_committing_transaction = NULL;
spin_unlock(&journal->j_state_lock); spin_unlock(&journal->j_state_lock);
if (journal->j_commit_callback)
journal->j_commit_callback(journal, commit_transaction);
if (commit_transaction->t_checkpoint_list == NULL && if (commit_transaction->t_checkpoint_list == NULL &&
commit_transaction->t_checkpoint_io_list == NULL) { commit_transaction->t_checkpoint_io_list == NULL) {
__jbd2_journal_drop_transaction(journal, commit_transaction); __jbd2_journal_drop_transaction(journal, commit_transaction);
@ -995,11 +998,8 @@ void jbd2_journal_commit_transaction(journal_t *journal)
} }
spin_unlock(&journal->j_list_lock); spin_unlock(&journal->j_list_lock);
if (journal->j_commit_callback)
journal->j_commit_callback(journal, commit_transaction);
trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", trace_mark(jbd2_end_commit, "dev %s transaction %d head %d",
journal->j_devname, commit_transaction->t_tid, journal->j_devname, journal->j_commit_sequence,
journal->j_tail_sequence); journal->j_tail_sequence);
jbd_debug(1, "JBD: commit %d complete, head %d\n", jbd_debug(1, "JBD: commit %d complete, head %d\n",
journal->j_commit_sequence, journal->j_tail_sequence); journal->j_commit_sequence, journal->j_tail_sequence);