| .. | .. |
|---|
| 106 | 106 | * for a checkpoint to free up some space in the log. |
|---|
| 107 | 107 | */ |
|---|
| 108 | 108 | void __jbd2_log_wait_for_space(journal_t *journal) |
|---|
| 109 | +__acquires(&journal->j_state_lock) |
|---|
| 110 | +__releases(&journal->j_state_lock) |
|---|
| 109 | 111 | { |
|---|
| 110 | 112 | int nblocks, space_left; |
|---|
| 111 | 113 | /* assert_spin_locked(&journal->j_state_lock); */ |
|---|
| 112 | 114 | |
|---|
| 113 | | - nblocks = jbd2_space_needed(journal); |
|---|
| 115 | + nblocks = journal->j_max_transaction_buffers; |
|---|
| 114 | 116 | while (jbd2_log_space_left(journal) < nblocks) { |
|---|
| 115 | 117 | write_unlock(&journal->j_state_lock); |
|---|
| 116 | | - mutex_lock(&journal->j_checkpoint_mutex); |
|---|
| 118 | + mutex_lock_io(&journal->j_checkpoint_mutex); |
|---|
| 117 | 119 | |
|---|
| 118 | 120 | /* |
|---|
| 119 | 121 | * Test again, another process may have checkpointed while we |
|---|
| .. | .. |
|---|
| 132 | 134 | return; |
|---|
| 133 | 135 | } |
|---|
| 134 | 136 | spin_lock(&journal->j_list_lock); |
|---|
| 135 | | - nblocks = jbd2_space_needed(journal); |
|---|
| 136 | 137 | space_left = jbd2_log_space_left(journal); |
|---|
| 137 | 138 | if (space_left < nblocks) { |
|---|
| 138 | 139 | int chkpt = journal->j_checkpoint_transactions != NULL; |
|---|
| .. | .. |
|---|
| 276 | 277 | "JBD2: %s: Waiting for Godot: block %llu\n", |
|---|
| 277 | 278 | journal->j_devname, (unsigned long long) bh->b_blocknr); |
|---|
| 278 | 279 | |
|---|
| 280 | + if (batch_count) |
|---|
| 281 | + __flush_batch(journal, &batch_count); |
|---|
| 279 | 282 | jbd2_log_start_commit(journal, tid); |
|---|
| 283 | + /* |
|---|
| 284 | + * jbd2_journal_commit_transaction() may want |
|---|
| 285 | + * to take the checkpoint_mutex if JBD2_FLUSHED |
|---|
| 286 | + * is set, jbd2_update_log_tail() called by |
|---|
| 287 | + * jbd2_journal_commit_transaction() may also take |
|---|
| 288 | + * checkpoint_mutex. So we need to temporarily |
|---|
| 289 | + * drop it. |
|---|
| 290 | + */ |
|---|
| 291 | + mutex_unlock(&journal->j_checkpoint_mutex); |
|---|
| 280 | 292 | jbd2_log_wait_commit(journal, tid); |
|---|
| 281 | | - goto retry; |
|---|
| 293 | + mutex_lock_io(&journal->j_checkpoint_mutex); |
|---|
| 294 | + spin_lock(&journal->j_list_lock); |
|---|
| 295 | + goto restart; |
|---|
| 282 | 296 | } |
|---|
| 283 | 297 | if (!buffer_dirty(bh)) { |
|---|
| 284 | 298 | if (unlikely(buffer_write_io_error(bh)) && !result) |
|---|
| .. | .. |
|---|
| 402 | 416 | * jbd2_cleanup_journal_tail() doesn't get called all that often. |
|---|
| 403 | 417 | */ |
|---|
| 404 | 418 | if (journal->j_flags & JBD2_BARRIER) |
|---|
| 405 | | - blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL); |
|---|
| 419 | + blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS); |
|---|
| 406 | 420 | |
|---|
| 407 | 421 | return __jbd2_update_log_tail(journal, first_tid, blocknr); |
|---|
| 408 | 422 | } |
|---|