There's a gap in what we can specify with the current balance usage
filter. This command doesn't balance all data block groups:
1. btrfs balance start -dusage=0..100 /fs
and neither does this one:
2. btrfs balance start -dusage=100 /fs
and since commit
a105bb88f46b6 in 2013, we can't work around with:
3. btrfs balance start -dusage=101 /fs/that/is/raid1
and there's a related problem when resuming paused balances, e.g. during
a mount.
Commands #1 and #2 fail as documented in the btrfs-balance man page:
usage=<percent>, usage=<range>
Balances only block groups with usage under the given
percentage.
Since completely full block groups are not "under" 100%, the filter
expression "usage=100" covers any block group with at least 1 unused byte,
but not completely full block groups.
Command #3 fails because of commit
a105bb88f46b6 "Btrfs: fix a regression
in balance usage filter" which removed the ability to specify percentage
values over 100; however, we don't want to revert that because we do
want to guard against integer overflows and other surprises that arise
from truly bad user inputs.
There are a few ways to fix this. This patch implements one that does not
alter any existing behavior: we allow 'usage=101' with the meaning "100%
+ 1 byte". This leaves "usage=100" referring to any block group that is
not completely full, in case anyone relies on that filter behavior, while
allowing a method for accepting completely full blocks in the filter.
It also allows 'usage=101' to work around the balance recovery issue
below.
Starting with commit
596410151e "Btrfs: recover balance on mount",
btrfs will insert a 'usage=90' filter when resuming a balance if no
'usage' filter was used on the original balance. If the original balance
does not use 'convert' or 'usage', then 'usage=90' will be inserted.
This can be surprising when pausing balances to let snapshot deletes run,
as in this log:
BTRFS info (device dm-0): balance: start -dlimit=999
BTRFS info (device dm-0): relocating block group
1776771137536 flags data
BTRFS info (device dm-0): found 18 extents, stage: move data extents
BTRFS info (device dm-0): found 18 extents, stage: update data pointers
BTRFS info (device dm-0): balance: paused
BTRFS debug (device dm-0): cleaner removing 2649
BTRFS info (device dm-0): balance: resume -dusage=90,limit=998
BTRFS info (device dm-0): balance: ended with status: 0
We expected to balance 999 block groups, instead we got one, because the
resumed balance used a very different filter than the original. If we set
'usage=100', we avoid this behavior on balance resume, but we also fail
to balance all but one of the full block groups. To work around this,
we need a way to set the BTRFS_BALANCE_ARGS_USAGE flag without losing
the ability to select full block groups.
Signed-off-by: Zygo Blaxell <ce3g8jdj@umail.furryterror.org>
(cherry picked from commit
f8392690b5fb1010484f7fa33b36e37c4a894de2)