diff options
-rw-r--r-- | fs/jbd2/checkpoint.c | 17 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 2 |
2 files changed, 16 insertions, 3 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 26f8d7e46462..02e0b79753e7 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
@@ -113,7 +113,7 @@ void __jbd2_log_wait_for_space(journal_t *journal) | |||
113 | nblocks = jbd2_space_needed(journal); | 113 | nblocks = jbd2_space_needed(journal); |
114 | while (jbd2_log_space_left(journal) < nblocks) { | 114 | while (jbd2_log_space_left(journal) < nblocks) { |
115 | write_unlock(&journal->j_state_lock); | 115 | write_unlock(&journal->j_state_lock); |
116 | mutex_lock(&journal->j_checkpoint_mutex); | 116 | mutex_lock_io(&journal->j_checkpoint_mutex); |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * Test again, another process may have checkpointed while we | 119 | * Test again, another process may have checkpointed while we |
@@ -276,9 +276,22 @@ restart: | |||
276 | "JBD2: %s: Waiting for Godot: block %llu\n", | 276 | "JBD2: %s: Waiting for Godot: block %llu\n", |
277 | journal->j_devname, (unsigned long long) bh->b_blocknr); | 277 | journal->j_devname, (unsigned long long) bh->b_blocknr); |
278 | 278 | ||
279 | if (batch_count) | ||
280 | __flush_batch(journal, &batch_count); | ||
279 | jbd2_log_start_commit(journal, tid); | 281 | jbd2_log_start_commit(journal, tid); |
282 | /* | ||
283 | * jbd2_journal_commit_transaction() may want | ||
284 | * to take the checkpoint_mutex if JBD2_FLUSHED | ||
285 | * is set, jbd2_update_log_tail() called by | ||
286 | * jbd2_journal_commit_transaction() may also take | ||
287 | * checkpoint_mutex. So we need to temporarily | ||
288 | * drop it. | ||
289 | */ | ||
290 | mutex_unlock(&journal->j_checkpoint_mutex); | ||
280 | jbd2_log_wait_commit(journal, tid); | 291 | jbd2_log_wait_commit(journal, tid); |
281 | goto retry; | 292 | mutex_lock_io(&journal->j_checkpoint_mutex); |
293 | spin_lock(&journal->j_list_lock); | ||
294 | goto restart; | ||
282 | } | 295 | } |
283 | if (!buffer_dirty(bh)) { | 296 | if (!buffer_dirty(bh)) { |
284 | if (unlikely(buffer_write_io_error(bh)) && !result) | 297 | if (unlikely(buffer_write_io_error(bh)) && !result) |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 8ef6b6daaa7a..88d8f22d2cba 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -2067,7 +2067,7 @@ int jbd2_journal_wipe(journal_t *journal, int write) | |||
2067 | err = jbd2_journal_skip_recovery(journal); | 2067 | err = jbd2_journal_skip_recovery(journal); |
2068 | if (write) { | 2068 | if (write) { |
2069 | /* Lock to make assertions happy... */ | 2069 | /* Lock to make assertions happy... */ |
2070 | mutex_lock(&journal->j_checkpoint_mutex); | 2070 | mutex_lock_io(&journal->j_checkpoint_mutex); |
2071 | jbd2_mark_journal_empty(journal, REQ_SYNC | REQ_FUA); | 2071 | jbd2_mark_journal_empty(journal, REQ_SYNC | REQ_FUA); |
2072 | mutex_unlock(&journal->j_checkpoint_mutex); | 2072 | mutex_unlock(&journal->j_checkpoint_mutex); |
2073 | } | 2073 | } |