Commit 4f981868 authored by Ritesh Harjani's avatar Ritesh Harjani Committed by Theodore Ts'o

jbd2: refactor wait logic for transaction updates into a common function

No functionality change as such in this patch. This only refactors the
common piece of code which waits for t_updates to finish into a common
function named as jbd2_journal_wait_updates(journal_t *)
Signed-off-by: default avatarRitesh Harjani <riteshh@linux.ibm.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/8c564f70f4b2591171677a2a74fccb22a7b6c3a4.1642416995.git.riteshh@linux.ibm.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 3ca40c0d
...@@ -484,22 +484,9 @@ void jbd2_journal_commit_transaction(journal_t *journal) ...@@ -484,22 +484,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
stats.run.rs_running = jbd2_time_diff(commit_transaction->t_start, stats.run.rs_running = jbd2_time_diff(commit_transaction->t_start,
stats.run.rs_locked); stats.run.rs_locked);
spin_lock(&commit_transaction->t_handle_lock); // waits for any t_updates to finish
while (atomic_read(&commit_transaction->t_updates)) { jbd2_journal_wait_updates(journal);
DEFINE_WAIT(wait);
prepare_to_wait(&journal->j_wait_updates, &wait,
TASK_UNINTERRUPTIBLE);
if (atomic_read(&commit_transaction->t_updates)) {
spin_unlock(&commit_transaction->t_handle_lock);
write_unlock(&journal->j_state_lock);
schedule();
write_lock(&journal->j_state_lock);
spin_lock(&commit_transaction->t_handle_lock);
}
finish_wait(&journal->j_wait_updates, &wait);
}
spin_unlock(&commit_transaction->t_handle_lock);
commit_transaction->t_state = T_SWITCH; commit_transaction->t_state = T_SWITCH;
write_unlock(&journal->j_state_lock); write_unlock(&journal->j_state_lock);
...@@ -817,7 +804,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) ...@@ -817,7 +804,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
commit_transaction->t_state = T_COMMIT_DFLUSH; commit_transaction->t_state = T_COMMIT_DFLUSH;
write_unlock(&journal->j_state_lock); write_unlock(&journal->j_state_lock);
/* /*
* If the journal is not located on the file system device, * If the journal is not located on the file system device,
* then we must flush the file system device before we issue * then we must flush the file system device before we issue
* the commit record * the commit record
......
...@@ -449,7 +449,7 @@ static int start_this_handle(journal_t *journal, handle_t *handle, ...@@ -449,7 +449,7 @@ static int start_this_handle(journal_t *journal, handle_t *handle,
} }
/* OK, account for the buffers that this operation expects to /* OK, account for the buffers that this operation expects to
* use and add the handle to the running transaction. * use and add the handle to the running transaction.
*/ */
update_t_max_wait(transaction, ts); update_t_max_wait(transaction, ts);
handle->h_transaction = transaction; handle->h_transaction = transaction;
...@@ -836,6 +836,35 @@ int jbd2_journal_restart(handle_t *handle, int nblocks) ...@@ -836,6 +836,35 @@ int jbd2_journal_restart(handle_t *handle, int nblocks)
} }
EXPORT_SYMBOL(jbd2_journal_restart); EXPORT_SYMBOL(jbd2_journal_restart);
/*
* Waits for any outstanding t_updates to finish.
* This is called with write j_state_lock held.
*/
void jbd2_journal_wait_updates(journal_t *journal)
{
transaction_t *commit_transaction = journal->j_running_transaction;
if (!commit_transaction)
return;
spin_lock(&commit_transaction->t_handle_lock);
while (atomic_read(&commit_transaction->t_updates)) {
DEFINE_WAIT(wait);
prepare_to_wait(&journal->j_wait_updates, &wait,
TASK_UNINTERRUPTIBLE);
if (atomic_read(&commit_transaction->t_updates)) {
spin_unlock(&commit_transaction->t_handle_lock);
write_unlock(&journal->j_state_lock);
schedule();
write_lock(&journal->j_state_lock);
spin_lock(&commit_transaction->t_handle_lock);
}
finish_wait(&journal->j_wait_updates, &wait);
}
spin_unlock(&commit_transaction->t_handle_lock);
}
/** /**
* jbd2_journal_lock_updates () - establish a transaction barrier. * jbd2_journal_lock_updates () - establish a transaction barrier.
* @journal: Journal to establish a barrier on. * @journal: Journal to establish a barrier on.
...@@ -863,27 +892,9 @@ void jbd2_journal_lock_updates(journal_t *journal) ...@@ -863,27 +892,9 @@ void jbd2_journal_lock_updates(journal_t *journal)
write_lock(&journal->j_state_lock); write_lock(&journal->j_state_lock);
} }
/* Wait until there are no running updates */ /* Wait until there are no running t_updates */
while (1) { jbd2_journal_wait_updates(journal);
transaction_t *transaction = journal->j_running_transaction;
if (!transaction)
break;
spin_lock(&transaction->t_handle_lock);
prepare_to_wait(&journal->j_wait_updates, &wait,
TASK_UNINTERRUPTIBLE);
if (!atomic_read(&transaction->t_updates)) {
spin_unlock(&transaction->t_handle_lock);
finish_wait(&journal->j_wait_updates, &wait);
break;
}
spin_unlock(&transaction->t_handle_lock);
write_unlock(&journal->j_state_lock);
schedule();
finish_wait(&journal->j_wait_updates, &wait);
write_lock(&journal->j_state_lock);
}
write_unlock(&journal->j_state_lock); write_unlock(&journal->j_state_lock);
/* /*
......
...@@ -594,7 +594,7 @@ struct transaction_s ...@@ -594,7 +594,7 @@ struct transaction_s
*/ */
unsigned long t_log_start; unsigned long t_log_start;
/* /*
* Number of buffers on the t_buffers list [j_list_lock, no locks * Number of buffers on the t_buffers list [j_list_lock, no locks
* needed for jbd2 thread] * needed for jbd2 thread]
*/ */
...@@ -1538,6 +1538,8 @@ extern int jbd2_journal_flush(journal_t *journal, unsigned int flags); ...@@ -1538,6 +1538,8 @@ extern int jbd2_journal_flush(journal_t *journal, unsigned int flags);
extern void jbd2_journal_lock_updates (journal_t *); extern void jbd2_journal_lock_updates (journal_t *);
extern void jbd2_journal_unlock_updates (journal_t *); extern void jbd2_journal_unlock_updates (journal_t *);
void jbd2_journal_wait_updates(journal_t *);
extern journal_t * jbd2_journal_init_dev(struct block_device *bdev, extern journal_t * jbd2_journal_init_dev(struct block_device *bdev,
struct block_device *fs_dev, struct block_device *fs_dev,
unsigned long long start, int len, int bsize); unsigned long long start, int len, int bsize);
......
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