void jbd2_journal_wait_updates(journal_t *journal)
{
	DEFINE_WAIT(wait);

	while (1) {
		/*
		 * Note that the running transaction can get freed under us if
		 * this transaction is getting committed in
		 * jbd2_journal_commit_transaction() ->
		 * jbd2_journal_free_transaction(). This can only happen when we
		 * release j_state_lock -> schedule() -> acquire j_state_lock.
		 * Hence we should everytime retrieve new j_running_transaction
		 * value (after j_state_lock release acquire cycle), else it may
		 * lead to use-after-free of old freed transaction.
		 */
		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);
	}
}
Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code.