Skip to content

Commit be07c4e

Browse files
duanegtorvalds
authored andcommitted
jbd: abort instead of waiting for nonexistent transactions
The __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> Tested-by: Sami Liedes <sliedes@cc.hut.fi> Cc: <linux-ext4@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 9f818b4 commit be07c4e

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

fs/jbd/checkpoint.c

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

128128
/*
129129
* Test again, another process may have checkpointed while we
130-
* were waiting for the checkpoint lock
130+
* were waiting for the checkpoint lock. If there are no
131+
* outstanding transactions there is nothing to checkpoint and
132+
* we can't make progress. Abort the journal in this case.
131133
*/
132134
spin_lock(&journal->j_state_lock);
135+
spin_lock(&journal->j_list_lock);
133136
nblocks = jbd_space_needed(journal);
134137
if (__log_space_left(journal) < nblocks) {
138+
int chkpt = journal->j_checkpoint_transactions != NULL;
139+
140+
spin_unlock(&journal->j_list_lock);
135141
spin_unlock(&journal->j_state_lock);
136-
log_do_checkpoint(journal);
142+
if (chkpt) {
143+
log_do_checkpoint(journal);
144+
} else {
145+
printk(KERN_ERR "%s: no transactions\n",
146+
__func__);
147+
journal_abort(journal, 0);
148+
}
149+
137150
spin_lock(&journal->j_state_lock);
151+
} else {
152+
spin_unlock(&journal->j_list_lock);
138153
}
139154
mutex_unlock(&journal->j_checkpoint_mutex);
140155
}

0 commit comments

Comments
 (0)