On Mon, Nov 19, 2018 at 09:48:12AM +0000, fdmanana@xxxxxxxxxx wrote:
> From: Filipe Manana <fdmanana@xxxxxxxx>
>
> The available allocation bits members from struct btrfs_fs_info are
> protected by a sequence lock, and when starting balance we access them
> incorrectly in two different ways:
>
> 1) In the read sequence lock loop at btrfs_balance() we use the values we
> read from fs_info->avail_*_alloc_bits and we can immediately do actions
> that have side effects and can not be undone (printing a message and
> jumping to a label). This is wrong because a retry might be needed, so
> our actions must not have side effects and must be repeatable as long
> as read_seqretry() returns a non-zero value. In other words, we were
> essentially ignoring the sequence lock;
>
> 2) Right below the read sequence lock loop, we were reading the values
> from avail_metadata_alloc_bits and avail_data_alloc_bits without any
> protection from concurrent writers, that is, reading them outside of
> the read sequence lock critical section.
>
> So fix this by making sure we only read the available allocation bits
> while in a read sequence lock critical section and that what we do in the
> critical section is repeatable (has nothing that can not be undone) so
> that any eventual retry that is needed is handled properly.
>
> Fixes: de98ced9e743 ("Btrfs: use seqlock to protect fs_info->avail_{data, metadata, system}_alloc_bits")
> Fixes: 14506127979a ("btrfs: fix a bogus warning when converting only data or metadata")
> Signed-off-by: Filipe Manana <fdmanana@xxxxxxxx>
Added to misc-next, thanks.