]> git.baikalelectronics.ru Git - kernel.git/commit
xfs: Fix deadlock between AGI and AGF when target_ip exists in xfs_rename()
authorkaixuxia <xiakaixu1987@gmail.com>
Sat, 24 Sep 2022 12:56:45 +0000 (18:26 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Sep 2022 09:04:10 +0000 (11:04 +0200)
commitb3e652efba63dcbc2f1c827661fdd922a4b6957d
tree54e932b8071b639747af9c5c1920c1455c48c07e
parent1a761a2f5adb2f5934f064377e40c6e2fe37a6a0
xfs: Fix deadlock between AGI and AGF when target_ip exists in xfs_rename()

commit 5e2d313969e0b0d065a096f4028fdce9f92f77ba upstream.

When target_ip exists in xfs_rename(), the xfs_dir_replace() call may
need to hold the AGF lock to allocate more blocks, and then invoking
the xfs_droplink() call to hold AGI lock to drop target_ip onto the
unlinked list, so we get the lock order AGF->AGI. This would break the
ordering constraint on AGI and AGF locking - inode allocation locks
the AGI, then can allocate a new extent for new inodes, locking the
AGF after the AGI.

In this patch we check whether the replace operation need more
blocks firstly. If so, acquire the agi lock firstly to preserve
locking order(AGI/AGF). Actually, the locking order problem only
occurs when we are locking the AGI/AGF of the same AG. For multiple
AGs the AGI lock will be released after the transaction committed.

Signed-off-by: kaixuxia <kaixuxia@tencent.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
[darrick: reword the comment]
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Acked-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/xfs/libxfs/xfs_dir2.h
fs/xfs/libxfs/xfs_dir2_sf.c
fs/xfs/xfs_inode.c