mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
xfs: restore nofs context unconditionally in xfs_trans_roll
commit0241ea5fb0upstream. When __xfs_trans_commit() fails in xfs_trans_roll(), the NOFS context is cleared but only restored in the success path. This leaves the error path without nofs protection, causing a circular lock dependency between xfs_nondir_ilock_class and fs_reclaim: CPU0 CPU1 ---- ---- lock(&xfs_nondir_ilock_class); lock(fs_reclaim); lock(&xfs_nondir_ilock_class); lock(fs_reclaim); Fix this by moving xfs_trans_set_context() before the error check so that nofs context is always restored on the new transaction. Reported-by: syzbot+59178abfeb0ea3f0ab20@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=59178abfeb0ea3f0ab20 Fixes:a1ca658d64("xfs: fix incorrect context handling in xfs_trans_roll") Cc: stable@vger.kernel.org Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Yun Zhou <yun.zhou@windriver.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
c35da2bac6
commit
4d00a39c67
+9
-7
@@ -1029,6 +1029,15 @@ xfs_trans_roll(
|
||||
* duplicate transaction that gets returned.
|
||||
*/
|
||||
error = __xfs_trans_commit(tp, true);
|
||||
|
||||
tp = *tpp;
|
||||
/*
|
||||
* __xfs_trans_commit cleared the NOFS flag by calling into
|
||||
* xfs_trans_free. Set it again here before doing memory
|
||||
* allocations.
|
||||
*/
|
||||
xfs_trans_set_context(tp);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -1040,13 +1049,6 @@ xfs_trans_roll(
|
||||
* either nothing be locked across this call, or that anything that is
|
||||
* locked be logged in the prior and the next transactions.
|
||||
*/
|
||||
tp = *tpp;
|
||||
/*
|
||||
* __xfs_trans_commit cleared the NOFS flag by calling into
|
||||
* xfs_trans_free. Set it again here before doing memory
|
||||
* allocations.
|
||||
*/
|
||||
xfs_trans_set_context(tp);
|
||||
error = xfs_log_regrant(tp->t_mountp, tp->t_ticket);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
Reference in New Issue
Block a user