On Wed, Jun 28, 2023 at 08:44:06 AM +1000, Dave Chinner wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > Btrees that aren't freespace management trees use the normal extent > allocation and freeing routines for their blocks. Hence when a btree > block is freed, a direct call to xfs_free_extent() is made and the > extent is immediately freed. This puts the entire free space > management btrees under this path, so we are stacking btrees on > btrees in the call stack. The inobt, finobt and refcount btrees > all do this. > > However, the bmap btree does not do this - it calls > xfs_free_extent_later() to defer the extent free operation via an > XEFI and hence it gets processed in deferred operation processing > during the commit of the primary transaction (i.e. via intent > chaining). > > We need to change xfs_free_extent() to behave in a non-blocking > manner so that we can avoid deadlocks with busy extents near ENOSPC > in transactions that free multiple extents. Inserting or removing a > record from a btree can cause a multi-level tree merge operation and > that will free multiple blocks from the btree in a single > transaction. i.e. we can call xfs_free_extent() multiple times, and > hence the btree manipulation transaction is vulnerable to this busy > extent deadlock vector. > > To fix this, convert all the remaining callers of xfs_free_extent() > to use xfs_free_extent_later() to queue XEFIs and hence defer > processing of the extent frees to a context that can be safely > restarted if a deadlock condition is detected. > The changes look good to me. Reviewed-by: Chandan Babu R <chandan.babu@xxxxxxxxxx> -- chandan