Patch "jbd2: fix outstanding credits assert in jbd2_journal_commit_transaction()" has been added to the 5.18-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    jbd2: fix outstanding credits assert in jbd2_journal_commit_transaction()

to the 5.18-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     jbd2-fix-outstanding-credits-assert-in-jbd2_journal_.patch
and it can be found in the queue-5.18 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 00ad96c0c623a183b9a1ab3f0112a71fde1c988c
Author: Zhang Yi <yi.zhang@xxxxxxxxxx>
Date:   Sat Jun 11 21:04:26 2022 +0800

    jbd2: fix outstanding credits assert in jbd2_journal_commit_transaction()
    
    [ Upstream commit a89573ce4ad32f19f43ec669771726817e185be0 ]
    
    We catch an assert problem in jbd2_journal_commit_transaction() when
    doing fsstress and request falut injection tests. The problem is
    happened in a race condition between jbd2_journal_commit_transaction()
    and ext4_end_io_end(). Firstly, ext4_writepages() writeback dirty pages
    and start reserved handle, and then the journal was aborted due to some
    previous metadata IO error, jbd2_journal_abort() start to commit current
    running transaction, the committing procedure could be raced by
    ext4_end_io_end() and lead to subtract j_reserved_credits twice from
    commit_transaction->t_outstanding_credits, finally the
    t_outstanding_credits is mistakenly smaller than t_nr_buffers and
    trigger assert.
    
    kjournald2           kworker
    
    jbd2_journal_commit_transaction()
     write_unlock(&journal->j_state_lock);
     atomic_sub(j_reserved_credits, t_outstanding_credits); //sub once
    
                         jbd2_journal_start_reserved()
                          start_this_handle()  //detect aborted journal
                          jbd2_journal_free_reserved()  //get running transaction
                           read_lock(&journal->j_state_lock)
                            __jbd2_journal_unreserve_handle()
                           atomic_sub(j_reserved_credits, t_outstanding_credits);
                           //sub again
                           read_unlock(&journal->j_state_lock);
    
     journal->j_running_transaction = NULL;
     J_ASSERT(t_nr_buffers <= t_outstanding_credits) //bomb!!!
    
    Fix this issue by using journal->j_state_lock to protect the subtraction
    in jbd2_journal_commit_transaction().
    
    Fixes: 96f1e0974575 ("jbd2: avoid long hold times of j_state_lock while committing a transaction")
    Signed-off-by: Zhang Yi <yi.zhang@xxxxxxxxxx>
    Reviewed-by: Jan Kara <jack@xxxxxxx>
    Link: https://lore.kernel.org/r/20220611130426.2013258-1-yi.zhang@xxxxxxxxxx
    Signed-off-by: Theodore Ts'o <tytso@xxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index ac7f067b7bdd..f306b52b8e0b 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -551,13 +551,13 @@ void jbd2_journal_commit_transaction(journal_t *journal)
 	 */
 	jbd2_journal_switch_revoke_table(journal);
 
+	write_lock(&journal->j_state_lock);
 	/*
 	 * Reserved credits cannot be claimed anymore, free them
 	 */
 	atomic_sub(atomic_read(&journal->j_reserved_credits),
 		   &commit_transaction->t_outstanding_credits);
 
-	write_lock(&journal->j_state_lock);
 	trace_jbd2_commit_flushing(journal, commit_transaction);
 	stats.run.rs_flushing = jiffies;
 	stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked,



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux