hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/fs/jbd2/checkpoint.c
....@@ -106,14 +106,16 @@
106106 * for a checkpoint to free up some space in the log.
107107 */
108108 void __jbd2_log_wait_for_space(journal_t *journal)
109
+__acquires(&journal->j_state_lock)
110
+__releases(&journal->j_state_lock)
109111 {
110112 int nblocks, space_left;
111113 /* assert_spin_locked(&journal->j_state_lock); */
112114
113
- nblocks = jbd2_space_needed(journal);
115
+ nblocks = journal->j_max_transaction_buffers;
114116 while (jbd2_log_space_left(journal) < nblocks) {
115117 write_unlock(&journal->j_state_lock);
116
- mutex_lock(&journal->j_checkpoint_mutex);
118
+ mutex_lock_io(&journal->j_checkpoint_mutex);
117119
118120 /*
119121 * Test again, another process may have checkpointed while we
....@@ -132,7 +134,6 @@
132134 return;
133135 }
134136 spin_lock(&journal->j_list_lock);
135
- nblocks = jbd2_space_needed(journal);
136137 space_left = jbd2_log_space_left(journal);
137138 if (space_left < nblocks) {
138139 int chkpt = journal->j_checkpoint_transactions != NULL;
....@@ -276,9 +277,22 @@
276277 "JBD2: %s: Waiting for Godot: block %llu\n",
277278 journal->j_devname, (unsigned long long) bh->b_blocknr);
278279
280
+ if (batch_count)
281
+ __flush_batch(journal, &batch_count);
279282 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);
280292 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;
282296 }
283297 if (!buffer_dirty(bh)) {
284298 if (unlikely(buffer_write_io_error(bh)) && !result)
....@@ -402,7 +416,7 @@
402416 * jbd2_cleanup_journal_tail() doesn't get called all that often.
403417 */
404418 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);
406420
407421 return __jbd2_update_log_tail(journal, first_tid, blocknr);
408422 }