Skip to content

Commit 23f8b79

Browse files
duanegtytso
authored andcommitted
jbd2: abort instead of waiting for nonexistent transaction
The __jbd2_log_wait_for_space function sits in a loop checkpointing transactions until there is sufficient space free in the journal. However, if there are no transactions to be processed (e.g. because the free space calculation is wrong due to a corrupted filesystem) it will never progress. Check for space being required when no transactions are outstanding and abort the journal instead of endlessly looping. This patch fixes the bug reported by Sami Liedes at: http://bugzilla.kernel.org/show_bug.cgi?id=10976 Signed-off-by: Duane Griffin <duaneg@dghda.com> Cc: Sami Liedes <sliedes@cc.hut.fi> Cc: <linux-ext4@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
1 parent c806e68 commit 23f8b79

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

fs/jbd2/checkpoint.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,29 @@ void __jbd2_log_wait_for_space(journal_t *journal)
126126

127127
/*
128128
* Test again, another process may have checkpointed while we
129-
* were waiting for the checkpoint lock
129+
* were waiting for the checkpoint lock. If there are no
130+
* outstanding transactions there is nothing to checkpoint and
131+
* we can't make progress. Abort the journal in this case.
130132
*/
131133
spin_lock(&journal->j_state_lock);
134+
spin_lock(&journal->j_list_lock);
132135
nblocks = jbd_space_needed(journal);
133136
if (__jbd2_log_space_left(journal) < nblocks) {
137+
int chkpt = journal->j_checkpoint_transactions != NULL;
138+
139+
spin_unlock(&journal->j_list_lock);
134140
spin_unlock(&journal->j_state_lock);
135-
jbd2_log_do_checkpoint(journal);
141+
if (chkpt) {
142+
jbd2_log_do_checkpoint(journal);
143+
} else {
144+
printk(KERN_ERR "%s: no transactions\n",
145+
__func__);
146+
jbd2_journal_abort(journal, 0);
147+
}
148+
136149
spin_lock(&journal->j_state_lock);
150+
} else {
151+
spin_unlock(&journal->j_list_lock);
137152
}
138153
mutex_unlock(&journal->j_checkpoint_mutex);
139154
}

0 commit comments

Comments
 (0)