int ret = 0;
        int slot;
 
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
        spin_lock(&fs_info->qgroup_lock);
        if (fs_info->quota_root) {
                fs_info->pending_quota_state = 1;
                kfree(quota_root);
        }
 out:
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;
 }
 
        struct btrfs_root *quota_root;
        int ret = 0;
 
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
        spin_lock(&fs_info->qgroup_lock);
        if (!fs_info->quota_root) {
                spin_unlock(&fs_info->qgroup_lock);
-               return 0;
+               goto out;
        }
        fs_info->quota_enabled = 0;
        fs_info->pending_quota_state = 0;
        btrfs_free_qgroup_config(fs_info);
        spin_unlock(&fs_info->qgroup_lock);
 
-       if (!quota_root)
-               return -EINVAL;
+       if (!quota_root) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        ret = btrfs_clean_quota_tree(trans, quota_root);
        if (ret)
        free_extent_buffer(quota_root->commit_root);
        kfree(quota_root);
 out:
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;
 }
 
        struct btrfs_root *quota_root;
        int ret = 0;
 
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
        quota_root = fs_info->quota_root;
-       if (!quota_root)
-               return -EINVAL;
+       if (!quota_root) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        ret = add_qgroup_relation_item(trans, quota_root, src, dst);
        if (ret)
-               return ret;
+               goto out;
 
        ret = add_qgroup_relation_item(trans, quota_root, dst, src);
        if (ret) {
                del_qgroup_relation_item(trans, quota_root, src, dst);
-               return ret;
+               goto out;
        }
 
        spin_lock(&fs_info->qgroup_lock);
        ret = add_relation_rb(quota_root->fs_info, src, dst);
        spin_unlock(&fs_info->qgroup_lock);
-
+out:
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;
 }
 
        int ret = 0;
        int err;
 
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
        quota_root = fs_info->quota_root;
-       if (!quota_root)
-               return -EINVAL;
+       if (!quota_root) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        ret = del_qgroup_relation_item(trans, quota_root, src, dst);
        err = del_qgroup_relation_item(trans, quota_root, dst, src);
        del_relation_rb(fs_info, src, dst);
 
        spin_unlock(&fs_info->qgroup_lock);
-
+out:
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;
 }
 
        struct btrfs_qgroup *qgroup;
        int ret = 0;
 
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
        quota_root = fs_info->quota_root;
-       if (!quota_root)
-               return -EINVAL;
+       if (!quota_root) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        ret = add_qgroup_item(trans, quota_root, qgroupid);
 
 
        if (IS_ERR(qgroup))
                ret = PTR_ERR(qgroup);
-
+out:
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;
 }
 
        struct btrfs_qgroup *qgroup;
        int ret = 0;
 
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
        quota_root = fs_info->quota_root;
-       if (!quota_root)
-               return -EINVAL;
+       if (!quota_root) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        /* check if there are no relations to this qgroup */
        spin_lock(&fs_info->qgroup_lock);
        if (qgroup) {
                if (!list_empty(&qgroup->groups) || !list_empty(&qgroup->members)) {
                        spin_unlock(&fs_info->qgroup_lock);
-                       return -EBUSY;
+                       ret = -EBUSY;
+                       goto out;
                }
        }
        spin_unlock(&fs_info->qgroup_lock);
        spin_lock(&fs_info->qgroup_lock);
        del_qgroup_rb(quota_root->fs_info, qgroupid);
        spin_unlock(&fs_info->qgroup_lock);
-
+out:
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;
 }
 
                       struct btrfs_fs_info *fs_info, u64 qgroupid,
                       struct btrfs_qgroup_limit *limit)
 {
-       struct btrfs_root *quota_root = fs_info->quota_root;
+       struct btrfs_root *quota_root;
        struct btrfs_qgroup *qgroup;
        int ret = 0;
 
-       if (!quota_root)
-               return -EINVAL;
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
+       quota_root = fs_info->quota_root;
+       if (!quota_root) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        ret = update_qgroup_limit_item(trans, quota_root, qgroupid,
                                       limit->flags, limit->max_rfer,
 
 unlock:
        spin_unlock(&fs_info->qgroup_lock);
-
+out:
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;
 }
 
        struct btrfs_qgroup *dstgroup;
        u32 level_size = 0;
 
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
        if (!fs_info->quota_enabled)
-               return 0;
+               goto out;
 
-       if (!quota_root)
-               return -EINVAL;
+       if (!quota_root) {
+               ret = -EINVAL;
+               goto out;
+       }
 
        /*
         * create a tracking group for the subvol itself
 unlock:
        spin_unlock(&fs_info->qgroup_lock);
 out:
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;
 }