Rebase to 2.6.27-rc8
[ext4-patch-queue.git] / jbd2-abort-instead-of-waiting-for-nonexistent-transactions
blob26ce8779d85ccfd0ebce8dd422b6df61bc5395a1
1 jbd2: abort instead of waiting for nonexistent transaction
3 The __jbd2_log_wait_for_space function sits in a loop checkpointing
4 transactions until there is sufficient space free in the journal. 
5 However, if there are no transactions to be processed (e.g.  because the
6 free space calculation is wrong due to a corrupted filesystem) it will
7 never progress.
9 Check for space being required when no transactions are outstanding and
10 abort the journal instead of endlessly looping.
12 This patch fixes the bug reported by Sami Liedes at:
13 http://bugzilla.kernel.org/show_bug.cgi?id=10976
15 Signed-off-by: Duane Griffin <duaneg@dghda.com>
16 Cc: Sami Liedes <sliedes@cc.hut.fi>
17 Cc: <linux-ext4@vger.kernel.org>
18 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
19 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
20 diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
21 index 91389c8..af4651b 100644
22 --- a/fs/jbd2/checkpoint.c
23 +++ b/fs/jbd2/checkpoint.c
24 @@ -126,14 +126,29 @@ void __jbd2_log_wait_for_space(journal_t *journal)
26                 /*
27                  * Test again, another process may have checkpointed while we
28 -                * were waiting for the checkpoint lock
29 +                * were waiting for the checkpoint lock. If there are no
30 +                * outstanding transactions there is nothing to checkpoint and
31 +                * we can't make progress. Abort the journal in this case.
32                  */
33                 spin_lock(&journal->j_state_lock);
34 +               spin_lock(&journal->j_list_lock);
35                 nblocks = jbd_space_needed(journal);
36                 if (__jbd2_log_space_left(journal) < nblocks) {
37 +                       int chkpt = journal->j_checkpoint_transactions != NULL;
39 +                       spin_unlock(&journal->j_list_lock);
40                         spin_unlock(&journal->j_state_lock);
41 -                       jbd2_log_do_checkpoint(journal);
42 +                       if (chkpt) {
43 +                               jbd2_log_do_checkpoint(journal);
44 +                       } else {
45 +                               printk(KERN_ERR "%s: no transactions\n",
46 +                                      __func__);
47 +                               jbd2_journal_abort(journal, 0);
48 +                       }
50                         spin_lock(&journal->j_state_lock);
51 +               } else {
52 +                       spin_unlock(&journal->j_list_lock);
53                 }
54                 mutex_unlock(&journal->j_checkpoint_mutex);
55         }