|
@@ -126,14 +126,29 @@ void __jbd2_log_wait_for_space(journal_t *journal)
|
|
|
|
|
|
/*
|
|
|
* Test again, another process may have checkpointed while we
|
|
|
- * were waiting for the checkpoint lock
|
|
|
+ * were waiting for the checkpoint lock. If there are no
|
|
|
+ * outstanding transactions there is nothing to checkpoint and
|
|
|
+ * we can't make progress. Abort the journal in this case.
|
|
|
*/
|
|
|
spin_lock(&journal->j_state_lock);
|
|
|
+ spin_lock(&journal->j_list_lock);
|
|
|
nblocks = jbd_space_needed(journal);
|
|
|
if (__jbd2_log_space_left(journal) < nblocks) {
|
|
|
+ int chkpt = journal->j_checkpoint_transactions != NULL;
|
|
|
+
|
|
|
+ spin_unlock(&journal->j_list_lock);
|
|
|
spin_unlock(&journal->j_state_lock);
|
|
|
- jbd2_log_do_checkpoint(journal);
|
|
|
+ if (chkpt) {
|
|
|
+ jbd2_log_do_checkpoint(journal);
|
|
|
+ } else {
|
|
|
+ printk(KERN_ERR "%s: no transactions\n",
|
|
|
+ __func__);
|
|
|
+ jbd2_journal_abort(journal, 0);
|
|
|
+ }
|
|
|
+
|
|
|
spin_lock(&journal->j_state_lock);
|
|
|
+ } else {
|
|
|
+ spin_unlock(&journal->j_list_lock);
|
|
|
}
|
|
|
mutex_unlock(&journal->j_checkpoint_mutex);
|
|
|
}
|