btrfs: simplify commit logic in try_flush_qgroup

It's no longer expected to call this function with an open transaction
so all the workarounds concerning this can be removed. In fact it'll
constitute a bug to call this function with a transaction already held
so WARN in this case.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Nikolay Borisov 2021-02-22 18:40:45 +02:00 committed by David Sterba
parent e5ce988690
commit ae396a3b7a
1 changed files with 7 additions and 28 deletions

View File

@ -3543,37 +3543,19 @@ static int try_flush_qgroup(struct btrfs_root *root)
{
struct btrfs_trans_handle *trans;
int ret;
bool can_commit = true;
/*
* If current process holds a transaction, we shouldn't flush, as we
* assume all space reservation happens before a transaction handle is
* held.
*
* But there are cases like btrfs_delayed_item_reserve_metadata() where
* we try to reserve space with one transction handle already held.
* In that case we can't commit transaction, but at least try to end it
* and hope the started data writes can free some space.
*/
if (current->journal_info &&
current->journal_info != BTRFS_SEND_TRANS_STUB)
can_commit = false;
/* Can't hold an open transaction or we run the risk of deadlocking */
ASSERT(current->journal_info == NULL ||
current->journal_info == BTRFS_SEND_TRANS_STUB);
if (WARN_ON(current->journal_info &&
current->journal_info != BTRFS_SEND_TRANS_STUB))
return 0;
/*
* We don't want to run flush again and again, so if there is a running
* one, we won't try to start a new flush, but exit directly.
*/
if (test_and_set_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state)) {
/*
* We are already holding a transaction, thus we can block other
* threads from flushing. So exit right now. This increases
* the chance of EDQUOT for heavy load and near limit cases.
* But we can argue that if we're already near limit, EDQUOT is
* unavoidable anyway.
*/
if (!can_commit)
return 0;
wait_event(root->qgroup_flush_wait,
!test_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state));
return 0;
@ -3590,10 +3572,7 @@ static int try_flush_qgroup(struct btrfs_root *root)
goto out;
}
if (can_commit)
ret = btrfs_commit_transaction(trans);
else
ret = btrfs_end_transaction(trans);
ret = btrfs_commit_transaction(trans);
out:
clear_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state);
wake_up(&root->qgroup_flush_wait);