There is a race between jbd2_journal_try_to_free_buffers() and jbd2_journal_destroy(), so the jbd2_log_do_checkpoint() may still missing to detect the buffer write io error flag and lead to filesystem inconsistency. jbd2_journal_try_to_free_buffers() ext4_put_super() jbd2_journal_destroy() __jbd2_journal_remove_checkpoint() detect buffer write error jbd2_log_do_checkpoint() jbd2_cleanup_journal_tail() <--- lead to inconsistency jbd2_journal_abort() Fix this issue by add j_checkpoint_mutex to protect journal buffer release on jbd2_journal_try_to_free_buffers(). Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx> --- fs/jbd2/transaction.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 9396666b7314..b935b20cbae4 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -2123,6 +2123,7 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal, struct page *page) J_ASSERT(PageLocked(page)); + mutex_lock(&journal->j_checkpoint_mutex); head = page_buffers(page); bh = head; do { @@ -2163,6 +2164,7 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal, struct page *page) if (has_write_io_error) jbd2_journal_abort(journal, -EIO); + mutex_unlock(&journal->j_checkpoint_mutex); return ret; } -- 2.25.4