Skip to content

Commit 5b094d6

Browse files
Christoph Hellwigdjwong
authored andcommitted
xfs: fix multi-AG deadlock in xfs_bunmapi
Just like in the allocator we must avoid touching multiple AGs out of order when freeing blocks, as freeing still locks the AGF and can cause the same AB-BA deadlocks as in the allocation path. Signed-off-by: Christoph Hellwig <[email protected]> Reported-by: Nikolay Borisov <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 6215894 commit 5b094d6

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

fs/xfs/libxfs/xfs_bmap.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5435,6 +5435,7 @@ __xfs_bunmapi(
54355435
xfs_fsblock_t sum;
54365436
xfs_filblks_t len = *rlen; /* length to unmap in file */
54375437
xfs_fileoff_t max_len;
5438+
xfs_agnumber_t prev_agno = NULLAGNUMBER, agno;
54385439

54395440
trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_);
54405441

@@ -5534,6 +5535,17 @@ __xfs_bunmapi(
55345535
*/
55355536
del = got;
55365537
wasdel = isnullstartblock(del.br_startblock);
5538+
5539+
/*
5540+
* Make sure we don't touch multiple AGF headers out of order
5541+
* in a single transaction, as that could cause AB-BA deadlocks.
5542+
*/
5543+
if (!wasdel) {
5544+
agno = XFS_FSB_TO_AGNO(mp, del.br_startblock);
5545+
if (prev_agno != NULLAGNUMBER && prev_agno > agno)
5546+
break;
5547+
prev_agno = agno;
5548+
}
55375549
if (got.br_startoff < start) {
55385550
del.br_startoff = start;
55395551
del.br_blockcount -= start - got.br_startoff;

0 commit comments

Comments
 (0)