diff options
author | Christoph Hellwig <hch@lst.de> | 2017-07-31 15:08:13 -0500 |
---|---|---|
committer | Eric Sandeen <sandeen@redhat.com> | 2017-07-31 15:08:13 -0500 |
commit | 15a8bccc9403c0ab1dbe869aa3afce7be9e1dd49 (patch) | |
tree | 387f9b5918dcebac973f995cce88e710a04daf36 | |
parent | f9f5e90c212052f896cc2ffbbb062498dd026b1a (diff) | |
download | xfsprogs-dev-15a8bccc9403c0ab1dbe869aa3afce7be9e1dd49.tar.gz |
xfs: fix multi-AG deadlock in xfs_bunmapi
Source kernel commit: 5b094d6dac0451ad89b1dc088395c7b399b7e9e8
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 <hch@lst.de>
Reported-by: Nikolay Borisov <n.borisov.lkml@gmail.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r-- | libxfs/xfs_bmap.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index d11e4d6567..e26bd239c4 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -5426,6 +5426,7 @@ __xfs_bunmapi( xfs_fsblock_t sum; xfs_filblks_t len = *rlen; /* length to unmap in file */ xfs_fileoff_t max_len; + xfs_agnumber_t prev_agno = NULLAGNUMBER, agno; trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); @@ -5525,6 +5526,17 @@ __xfs_bunmapi( */ del = got; wasdel = isnullstartblock(del.br_startblock); + + /* + * Make sure we don't touch multiple AGF headers out of order + * in a single transaction, as that could cause AB-BA deadlocks. + */ + if (!wasdel) { + agno = XFS_FSB_TO_AGNO(mp, del.br_startblock); + if (prev_agno != NULLAGNUMBER && prev_agno > agno) + break; + prev_agno = agno; + } if (got.br_startoff < start) { del.br_startoff = start; del.br_blockcount -= start - got.br_startoff; |