19 #include <linux/sched.h>
23 #include <linux/rbtree.h>
24 #include <linux/slab.h>
112 else if (qgroup->
qgroupid > qgroupid)
134 else if (qgroup->
qgroupid > qgroupid)
140 qgroup = kzalloc(
sizeof(*qgroup),
GFP_ATOMIC);
145 INIT_LIST_HEAD(&qgroup->
groups);
146 INIT_LIST_HEAD(&qgroup->
members);
147 INIT_LIST_HEAD(&qgroup->
dirty);
149 rb_link_node(&qgroup->
node, parent, p);
158 struct btrfs_qgroup *qgroup = find_qgroup_rb(fs_info, qgroupid);
167 while (!list_empty(&qgroup->
groups)) {
175 while (!list_empty(&qgroup->
members)) {
189 u64 memberid,
u64 parentid)
195 member = find_qgroup_rb(fs_info, memberid);
196 parent = find_qgroup_rb(fs_info, parentid);
197 if (!member || !parent)
204 list->
group = parent;
214 u64 memberid,
u64 parentid)
220 member = find_qgroup_rb(fs_info, memberid);
221 parent = find_qgroup_rb(fs_info, parentid);
222 if (!member || !parent)
226 if (list->
group == parent) {
276 slot = path->
slots[0];
278 btrfs_item_key_to_cpu(l, &found_key, slot);
286 if (btrfs_qgroup_status_version(l, ptr) !=
289 "btrfs: old qgroup version, quota disabled\n");
292 if (btrfs_qgroup_status_generation(l, ptr) !=
296 "btrfs: qgroup generation mismatch, "
297 "marked as inconsistent\n");
309 qgroup = find_qgroup_rb(fs_info, found_key.
offset);
316 qgroup = add_qgroup_rb(fs_info, found_key.
offset);
317 if (IS_ERR(qgroup)) {
318 ret = PTR_ERR(qgroup);
322 switch (found_key.
type) {
328 qgroup->
rfer = btrfs_qgroup_info_rfer(l, ptr);
329 qgroup->
rfer_cmpr = btrfs_qgroup_info_rfer_cmpr(l, ptr);
330 qgroup->
excl = btrfs_qgroup_info_excl(l, ptr);
331 qgroup->
excl_cmpr = btrfs_qgroup_info_excl_cmpr(l, ptr);
340 qgroup->
lim_flags = btrfs_qgroup_limit_flags(l, ptr);
341 qgroup->
max_rfer = btrfs_qgroup_limit_max_rfer(l, ptr);
342 qgroup->
max_excl = btrfs_qgroup_limit_max_excl(l, ptr);
343 qgroup->
rsv_rfer = btrfs_qgroup_limit_rsv_rfer(l, ptr);
344 qgroup->
rsv_excl = btrfs_qgroup_limit_rsv_excl(l, ptr);
349 ret = btrfs_next_item(quota_root, path);
367 slot = path->
slots[0];
369 btrfs_item_key_to_cpu(l, &found_key, slot);
380 ret = add_relation_rb(fs_info, found_key.
objectid,
385 ret = btrfs_next_item(quota_root, path);
399 return ret < 0 ? ret : 0;
418 while (!list_empty(&qgroup->
groups)) {
427 while (!list_empty(&qgroup->
members)) {
455 ret = btrfs_insert_empty_item(trans, quota_root, path, &
key, 0);
488 ret = btrfs_del_item(trans, quota_root, path);
510 key.offset = qgroupid;
512 ret = btrfs_insert_empty_item(trans, quota_root, path, &
key,
513 sizeof(*qgroup_info));
517 leaf = path->nodes[0];
520 btrfs_set_qgroup_info_generation(leaf, qgroup_info, trans->
transid);
521 btrfs_set_qgroup_info_rfer(leaf, qgroup_info, 0);
522 btrfs_set_qgroup_info_rfer_cmpr(leaf, qgroup_info, 0);
523 btrfs_set_qgroup_info_excl(leaf, qgroup_info, 0);
524 btrfs_set_qgroup_info_excl_cmpr(leaf, qgroup_info, 0);
531 ret = btrfs_insert_empty_item(trans, quota_root, path, &
key,
532 sizeof(*qgroup_limit));
536 leaf = path->nodes[0];
539 btrfs_set_qgroup_limit_flags(leaf, qgroup_limit, 0);
540 btrfs_set_qgroup_limit_max_rfer(leaf, qgroup_limit, 0);
541 btrfs_set_qgroup_limit_max_excl(leaf, qgroup_limit, 0);
542 btrfs_set_qgroup_limit_rsv_rfer(leaf, qgroup_limit, 0);
543 btrfs_set_qgroup_limit_rsv_excl(leaf, qgroup_limit, 0);
566 key.offset = qgroupid;
576 ret = btrfs_del_item(trans, quota_root, path);
592 ret = btrfs_del_item(trans, quota_root, path);
613 key.offset = qgroupid;
625 slot = path->
slots[0];
628 btrfs_set_qgroup_limit_flags(l, qgroup_limit, flags);
629 btrfs_set_qgroup_limit_max_rfer(l, qgroup_limit, max_rfer);
630 btrfs_set_qgroup_limit_max_excl(l, qgroup_limit, max_excl);
631 btrfs_set_qgroup_limit_rsv_rfer(l, qgroup_limit, rsv_rfer);
632 btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, rsv_excl);
666 slot = path->
slots[0];
669 btrfs_set_qgroup_info_generation(l, qgroup_info, trans->
transid);
670 btrfs_set_qgroup_info_rfer(l, qgroup_info, qgroup->
rfer);
671 btrfs_set_qgroup_info_rfer_cmpr(l, qgroup_info, qgroup->
rfer_cmpr);
672 btrfs_set_qgroup_info_excl(l, qgroup_info, qgroup->
excl);
673 btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, qgroup->
excl_cmpr);
707 slot = path->
slots[0];
709 btrfs_set_qgroup_status_flags(l, ptr, fs_info->
qgroup_flags);
710 btrfs_set_qgroup_status_generation(l, ptr, trans->
transid);
745 if (path->
slots[0] == 0)
748 }
else if (ret < 0) {
752 ret = btrfs_del_item(trans, root, path);
759 root->
fs_info->pending_quota_state = 0;
787 if (IS_ERR(quota_root)) {
788 ret = PTR_ERR(quota_root);
802 ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
807 leaf = path->
nodes[0];
810 btrfs_set_qgroup_status_generation(leaf, ptr, trans->
transid);
814 btrfs_set_qgroup_status_flags(leaf, ptr, fs_info->
qgroup_flags);
815 btrfs_set_qgroup_status_scan(leaf, ptr, 0);
853 ret = btrfs_clean_quota_tree(trans, quota_root);
891 ret = add_qgroup_relation_item(trans, quota_root, src, dst);
895 ret = add_qgroup_relation_item(trans, quota_root, dst, src);
897 del_qgroup_relation_item(trans, quota_root, src, dst);
902 ret = add_relation_rb(quota_root->
fs_info, src, dst);
919 ret = del_qgroup_relation_item(trans, quota_root, src, dst);
920 err = del_qgroup_relation_item(trans, quota_root, dst, src);
925 del_relation_rb(fs_info, src, dst);
943 ret = add_qgroup_item(trans, quota_root, qgroupid);
946 qgroup = add_qgroup_rb(fs_info, qgroupid);
950 ret = PTR_ERR(qgroup);
965 ret = del_qgroup_item(trans, quota_root, qgroupid);
968 del_qgroup_rb(quota_root->
fs_info, qgroupid);
986 ret = update_qgroup_limit_item(trans, quota_root, qgroupid,
993 (
unsigned long long)qgroupid);
998 qgroup = find_qgroup_rb(fs_info, qgroupid);
1018 if (list_empty(&qgroup->
dirty))
1080 ref = btrfs_delayed_node_to_tree_ref(node);
1081 ref_root = ref->
root;
1085 ref = btrfs_delayed_node_to_data_ref(node);
1086 ref_root = ref->
root;
1091 if (!is_fstree(ref_root)) {
1121 sgn > 0 ? node->
seq - 1 : node->
seq, &roots);
1130 qgroup = find_qgroup_rb(fs_info, ref_root);
1146 while ((unode =
ulist_next(roots, &uiter))) {
1151 qg = find_qgroup_rb(fs_info, unode->
val);
1159 while ((tmp_unode =
ulist_next(tmp, &tmp_uiter))) {
1163 if (qg->refcnt < seq)
1164 qg->refcnt = seq + 1;
1191 if (roots->
nnodes == 0) {
1195 qgroup_dirty(fs_info, qg);
1210 while ((unode =
ulist_next(roots, &uiter))) {
1215 qg = find_qgroup_rb(fs_info, unode->
val);
1222 while ((tmp_unode =
ulist_next(tmp, &tmp_uiter))) {
1229 if (qg->refcnt - seq == roots->
nnodes) {
1232 qgroup_dirty(fs_info, qg);
1271 list_del_init(&qgroup->
dirty);
1273 ret = update_qgroup_info_item(trans, quota_root, qgroup);
1285 ret = update_qgroup_status_item(trans, fs_info, quota_root);
1319 ret = add_qgroup_item(trans, quota_root, objectid);
1324 ret = update_qgroup_limit_item(trans, quota_root, objectid,
1326 inherit->
lim.max_rfer,
1327 inherit->
lim.max_excl,
1328 inherit->
lim.rsv_rfer,
1329 inherit->
lim.rsv_excl);
1343 if (IS_ERR(srcroot)) {
1344 ret = PTR_ERR(srcroot);
1349 srcroot_level = btrfs_header_level(srcroot->
node);
1350 level_size = btrfs_level_size(srcroot, srcroot_level);
1358 i_qgroups = (
u64 *)(inherit + 1);
1360 ret = add_qgroup_relation_item(trans, quota_root,
1361 objectid, *i_qgroups);
1364 ret = add_qgroup_relation_item(trans, quota_root,
1365 *i_qgroups, objectid);
1375 dstgroup = add_qgroup_rb(fs_info, objectid);
1376 if (IS_ERR(dstgroup)) {
1377 ret = PTR_ERR(dstgroup);
1382 srcgroup = find_qgroup_rb(fs_info, srcid);
1385 dstgroup->
rfer = srcgroup->
rfer - level_size;
1387 srcgroup->
excl = level_size;
1389 qgroup_dirty(fs_info, dstgroup);
1390 qgroup_dirty(fs_info, srcgroup);
1396 i_qgroups = (
u64 *)(inherit + 1);
1398 ret = add_relation_rb(quota_root->
fs_info, objectid,
1409 src = find_qgroup_rb(fs_info, i_qgroups[0]);
1410 dst = find_qgroup_rb(fs_info, i_qgroups[1]);
1417 dst->
rfer = src->
rfer - level_size;
1425 src = find_qgroup_rb(fs_info, i_qgroups[0]);
1426 dst = find_qgroup_rb(fs_info, i_qgroups[1]);
1433 dst->
excl = src->
excl + level_size;
1461 if (!is_fstree(ref_root))
1472 qgroup = find_qgroup_rb(fs_info, ref_root);
1487 while ((unode =
ulist_next(ulist, &uiter))) {
1515 while ((unode =
ulist_next(ulist, &uiter))) {
1540 if (!is_fstree(ref_root))
1552 qgroup = find_qgroup_rb(fs_info, ref_root);
1563 while ((unode =
ulist_next(ulist, &uiter))) {
1586 printk(
KERN_ERR "btrfs: qgroups not uptodate in trans handle %p: list is%s empty, seq is %llu\n",