btrfs: hold block group refcount during async discard
authorBoris Burkov <boris@bur.io>
Fri, 13 Jan 2023 00:05:11 +0000 (16:05 -0800)
committerDavid Sterba <dsterba@suse.com>
Wed, 15 Feb 2023 18:38:50 +0000 (19:38 +0100)
commit2b5463fcbdfb24e898916bcae2b1359042d26963
tree3d789298e5d721a8c64579b18c6a49047318f3e7
parent3e49363be6330f49e670240e8f46e6fe0bf5628a
btrfs: hold block group refcount during async discard

Async discard does not acquire the block group reference count while it
holds a reference on the discard list. This is generally OK, as the
paths which destroy block groups tend to try to synchronize on
cancelling async discard work. However, relying on cancelling work
requires careful analysis to be sure it is safe from races with
unpinning scheduling more work.

While I am unable to find a race with unpinning in the current code for
either the unused bgs or relocation paths, I believe we have one in an
older version of auto relocation in a Meta internal build. This suggests
that this is in fact an error prone model, and could be fragile to
future changes to these bg deletion paths.

To make this ownership more clear, add a refcount for async discard. If
work is queued for a block group, its refcount should be incremented,
and when work is completed or canceled, it should be decremented.

CC: stable@vger.kernel.org # 5.15+
Signed-off-by: Boris Burkov <boris@bur.io>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/discard.c