struct btrfs_qgroup *member;
        struct btrfs_qgroup_list *list;
        struct ulist *tmp;
+       bool found = false;
        int ret = 0;
-       int err;
+       int ret2;
 
        tmp = ulist_alloc(GFP_KERNEL);
        if (!tmp)
 
        member = find_qgroup_rb(fs_info, src);
        parent = find_qgroup_rb(fs_info, dst);
-       if (!member || !parent) {
-               ret = -EINVAL;
-               goto out;
-       }
+       /*
+        * The parent/member pair doesn't exist, then try to delete the dead
+        * relation items only.
+        */
+       if (!member || !parent)
+               goto delete_item;
 
        /* check if such qgroup relation exist firstly */
        list_for_each_entry(list, &member->groups, next_group) {
-               if (list->group == parent)
-                       goto exist;
+               if (list->group == parent) {
+                       found = true;
+                       break;
+               }
        }
-       ret = -ENOENT;
-       goto out;
-exist:
+
+delete_item:
        ret = del_qgroup_relation_item(trans, src, dst);
-       err = del_qgroup_relation_item(trans, dst, src);
-       if (err && !ret)
-               ret = err;
+       if (ret < 0 && ret != -ENOENT)
+               goto out;
+       ret2 = del_qgroup_relation_item(trans, dst, src);
+       if (ret2 < 0 && ret2 != -ENOENT)
+               goto out;
 
-       spin_lock(&fs_info->qgroup_lock);
-       del_relation_rb(fs_info, src, dst);
-       ret = quick_update_accounting(fs_info, tmp, src, dst, -1);
-       spin_unlock(&fs_info->qgroup_lock);
+       /* At least one deletion succeeded, return 0 */
+       if (!ret || !ret2)
+               ret = 0;
+
+       if (found) {
+               spin_lock(&fs_info->qgroup_lock);
+               del_relation_rb(fs_info, src, dst);
+               ret = quick_update_accounting(fs_info, tmp, src, dst, -1);
+               spin_unlock(&fs_info->qgroup_lock);
+       }
 out:
        ulist_free(tmp);
        return ret;