aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/qgroup.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index f9fb52e52bb6..f175471da882 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -956,6 +956,7 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
956 struct btrfs_root *quota_root; 956 struct btrfs_root *quota_root;
957 struct btrfs_qgroup *parent; 957 struct btrfs_qgroup *parent;
958 struct btrfs_qgroup *member; 958 struct btrfs_qgroup *member;
959 struct btrfs_qgroup_list *list;
959 int ret = 0; 960 int ret = 0;
960 961
961 mutex_lock(&fs_info->qgroup_ioctl_lock); 962 mutex_lock(&fs_info->qgroup_ioctl_lock);
@@ -971,6 +972,14 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
971 goto out; 972 goto out;
972 } 973 }
973 974
975 /* check if such qgroup relation exist firstly */
976 list_for_each_entry(list, &member->groups, next_group) {
977 if (list->group == parent) {
978 ret = -EEXIST;
979 goto out;
980 }
981 }
982
974 ret = add_qgroup_relation_item(trans, quota_root, src, dst); 983 ret = add_qgroup_relation_item(trans, quota_root, src, dst);
975 if (ret) 984 if (ret)
976 goto out; 985 goto out;
@@ -993,6 +1002,9 @@ int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
993 struct btrfs_fs_info *fs_info, u64 src, u64 dst) 1002 struct btrfs_fs_info *fs_info, u64 src, u64 dst)
994{ 1003{
995 struct btrfs_root *quota_root; 1004 struct btrfs_root *quota_root;
1005 struct btrfs_qgroup *parent;
1006 struct btrfs_qgroup *member;
1007 struct btrfs_qgroup_list *list;
996 int ret = 0; 1008 int ret = 0;
997 int err; 1009 int err;
998 1010
@@ -1003,6 +1015,21 @@ int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
1003 goto out; 1015 goto out;
1004 } 1016 }
1005 1017
1018 member = find_qgroup_rb(fs_info, src);
1019 parent = find_qgroup_rb(fs_info, dst);
1020 if (!member || !parent) {
1021 ret = -EINVAL;
1022 goto out;
1023 }
1024
1025 /* check if such qgroup relation exist firstly */
1026 list_for_each_entry(list, &member->groups, next_group) {
1027 if (list->group == parent)
1028 goto exist;
1029 }
1030 ret = -ENOENT;
1031 goto out;
1032exist:
1006 ret = del_qgroup_relation_item(trans, quota_root, src, dst); 1033 ret = del_qgroup_relation_item(trans, quota_root, src, dst);
1007 err = del_qgroup_relation_item(trans, quota_root, dst, src); 1034 err = del_qgroup_relation_item(trans, quota_root, dst, src);
1008 if (err && !ret) 1035 if (err && !ret)
@@ -1010,7 +1037,6 @@ int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
1010 1037
1011 spin_lock(&fs_info->qgroup_lock); 1038 spin_lock(&fs_info->qgroup_lock);
1012 del_relation_rb(fs_info, src, dst); 1039 del_relation_rb(fs_info, src, dst);
1013
1014 spin_unlock(&fs_info->qgroup_lock); 1040 spin_unlock(&fs_info->qgroup_lock);
1015out: 1041out:
1016 mutex_unlock(&fs_info->qgroup_ioctl_lock); 1042 mutex_unlock(&fs_info->qgroup_ioctl_lock);
@@ -1030,8 +1056,15 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
1030 ret = -EINVAL; 1056 ret = -EINVAL;
1031 goto out; 1057 goto out;
1032 } 1058 }
1059 qgroup = find_qgroup_rb(fs_info, qgroupid);
1060 if (qgroup) {
1061 ret = -EEXIST;
1062 goto out;
1063 }
1033 1064
1034 ret = add_qgroup_item(trans, quota_root, qgroupid); 1065 ret = add_qgroup_item(trans, quota_root, qgroupid);
1066 if (ret)
1067 goto out;
1035 1068
1036 spin_lock(&fs_info->qgroup_lock); 1069 spin_lock(&fs_info->qgroup_lock);
1037 qgroup = add_qgroup_rb(fs_info, qgroupid); 1070 qgroup = add_qgroup_rb(fs_info, qgroupid);
@@ -1058,15 +1091,18 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
1058 goto out; 1091 goto out;
1059 } 1092 }
1060 1093
1061 /* check if there are no relations to this qgroup */
1062 qgroup = find_qgroup_rb(fs_info, qgroupid); 1094 qgroup = find_qgroup_rb(fs_info, qgroupid);
1063 if (qgroup) { 1095 if (!qgroup) {
1064 if (!list_empty(&qgroup->groups) || !list_empty(&qgroup->members)) { 1096 ret = -ENOENT;
1097 goto out;
1098 } else {
1099 /* check if there are no relations to this qgroup */
1100 if (!list_empty(&qgroup->groups) ||
1101 !list_empty(&qgroup->members)) {
1065 ret = -EBUSY; 1102 ret = -EBUSY;
1066 goto out; 1103 goto out;
1067 } 1104 }
1068 } 1105 }
1069
1070 ret = del_qgroup_item(trans, quota_root, qgroupid); 1106 ret = del_qgroup_item(trans, quota_root, qgroupid);
1071 1107
1072 spin_lock(&fs_info->qgroup_lock); 1108 spin_lock(&fs_info->qgroup_lock);