Commit fba1fdee authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] JBD: fix log_start_commit race

In start_this_handle() the caller does not have a handle ref pinning the
transaction open, and so the call to log_start_commit() is racy because some
other CPU could take the transaction into commit state independently.

Fix that by holding j_state_lock (which pins j_running_transaction) across
the log_start_commit() call.
parent 28a4dd1b
......@@ -442,7 +442,7 @@ int __log_space_left(journal_t *journal)
/*
* Called under j_state_lock.
*/
static tid_t __log_start_commit(journal_t *journal, transaction_t *transaction)
tid_t __log_start_commit(journal_t *journal, transaction_t *transaction)
{
tid_t target = journal->j_commit_request;
......
......@@ -171,12 +171,12 @@ static int start_this_handle(journal_t *journal, handle_t *handle)
*/
DEFINE_WAIT(wait);
spin_unlock(&transaction->t_handle_lock);
spin_unlock(&journal->j_state_lock);
jbd_debug(2, "Handle %p starting new commit...\n", handle);
spin_unlock(&transaction->t_handle_lock);
prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
TASK_UNINTERRUPTIBLE);
log_start_commit(journal, transaction);
__log_start_commit(journal, transaction);
spin_unlock(&journal->j_state_lock);
schedule();
finish_wait(&journal->j_wait_transaction_locked, &wait);
goto repeat;
......
......@@ -991,6 +991,7 @@ extern void journal_switch_revoke_table(journal_t *journal);
int __log_space_left(journal_t *); /* Called with journal locked */
extern tid_t log_start_commit (journal_t *, transaction_t *);
extern tid_t __log_start_commit(journal_t *, transaction_t *);
extern int log_wait_commit (journal_t *, tid_t);
extern int log_do_checkpoint (journal_t *, int);
......
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