btrfs: reject new qgroup rescan during subvolume dropping
Commit
011b46c30476 ("btrfs: skip subtree scan if it's too high to avoid
low stall in btrfs_commit_transaction()") introduced a threshold to skip
huge subtree scan during subvolume dropping.
But that's not covering all cases, e.g. rescan can still be started
immediately after that huge subtree skipping.
This will cause rescan to do the same accounting for that subtree
anyway, still causing a long stall during transaction commit.
Introduce a new runtime qgroup flag,
BTRFS_QGROUP_RUNTIME_BIT_REJECT_RESCAN, so that during cleanup of a
subvolume, no new qgroup rescan can be initiated.
The rejection uses the same -EINPROGRESS, as if there is already a
running qgroup rescan.
And since we have the extra bit, we can no longer allow plain assignment
in btrfs_quota_enable(), as the plain assignment will override the
REJECT_RESCAN bit.
To co-operate this new flag:
- Make btrfs_quota_enable() to only set BTRFS_QGROUP_STATUS_BIT_ON
So it won't override the existing
BTRFS_QGROUP_RUNTIME_BIT_REJECT_RESCAN bit.
- Make btrfs_quota_disable() to clear every non-rescan bit
This includes:
* BTRFS_QGROUP_STATUS_BIT_ON
* BTRFS_QGROUP_STATUS_BIT_INCONSISTENT
* BTRFS_QGROUP_RUNTIME_BIT_NO_ACCOUNTING
For rescan related bits, they are either cleared by the rescan thread,
or by the caller who rejects rescan.
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>