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:
Родитель
e5ce988690
Коммит
ae396a3b7a
|
@ -3543,37 +3543,19 @@ static int try_flush_qgroup(struct btrfs_root *root)
|
||||||
{
|
{
|
||||||
struct btrfs_trans_handle *trans;
|
struct btrfs_trans_handle *trans;
|
||||||
int ret;
|
int ret;
|
||||||
bool can_commit = true;
|
|
||||||
|
|
||||||
/*
|
/* Can't hold an open transaction or we run the risk of deadlocking */
|
||||||
* If current process holds a transaction, we shouldn't flush, as we
|
ASSERT(current->journal_info == NULL ||
|
||||||
* assume all space reservation happens before a transaction handle is
|
current->journal_info == BTRFS_SEND_TRANS_STUB);
|
||||||
* held.
|
if (WARN_ON(current->journal_info &&
|
||||||
*
|
current->journal_info != BTRFS_SEND_TRANS_STUB))
|
||||||
* But there are cases like btrfs_delayed_item_reserve_metadata() where
|
return 0;
|
||||||
* 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;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't want to run flush again and again, so if there is a running
|
* 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.
|
* one, we won't try to start a new flush, but exit directly.
|
||||||
*/
|
*/
|
||||||
if (test_and_set_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state)) {
|
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,
|
wait_event(root->qgroup_flush_wait,
|
||||||
!test_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state));
|
!test_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3590,10 +3572,7 @@ static int try_flush_qgroup(struct btrfs_root *root)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_commit)
|
ret = btrfs_commit_transaction(trans);
|
||||||
ret = btrfs_commit_transaction(trans);
|
|
||||||
else
|
|
||||||
ret = btrfs_end_transaction(trans);
|
|
||||||
out:
|
out:
|
||||||
clear_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state);
|
clear_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state);
|
||||||
wake_up(&root->qgroup_flush_wait);
|
wake_up(&root->qgroup_flush_wait);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче