Commit ae396a3b authored by Nikolay Borisov's avatar Nikolay Borisov Committed by David Sterba
Browse files

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: default avatarQu Wenruo <wqu@suse.com>
Signed-off-by: default avatarNikolay Borisov <nborisov@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent e5ce9886
Loading
Loading
Loading
Loading
+7 −28
Original line number Diff line number Diff line
@@ -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);
out:
	clear_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state);
	wake_up(&root->qgroup_flush_wait);