diff options
-rw-r--r-- | fs/jbd/checkpoint.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index fe8521933243..1bd8d4acc6f2 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c | |||
@@ -127,14 +127,29 @@ void __log_wait_for_space(journal_t *journal) | |||
127 | 127 | ||
128 | /* | 128 | /* |
129 | * Test again, another process may have checkpointed while we | 129 | * 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. | ||
131 | */ | 133 | */ |
132 | spin_lock(&journal->j_state_lock); | 134 | spin_lock(&journal->j_state_lock); |
135 | spin_lock(&journal->j_list_lock); | ||
133 | nblocks = jbd_space_needed(journal); | 136 | nblocks = jbd_space_needed(journal); |
134 | if (__log_space_left(journal) < nblocks) { | 137 | if (__log_space_left(journal) < nblocks) { |
138 | int chkpt = journal->j_checkpoint_transactions != NULL; | ||
139 | |||
140 | spin_unlock(&journal->j_list_lock); | ||
135 | spin_unlock(&journal->j_state_lock); | 141 | 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 | |||
137 | spin_lock(&journal->j_state_lock); | 150 | spin_lock(&journal->j_state_lock); |
151 | } else { | ||
152 | spin_unlock(&journal->j_list_lock); | ||
138 | } | 153 | } |
139 | mutex_unlock(&journal->j_checkpoint_mutex); | 154 | mutex_unlock(&journal->j_checkpoint_mutex); |
140 | } | 155 | } |