blob: c6ce6427686937103084e30ae780b38882c609db [file] [log] [blame]
Arne Jansenbed92ea2012-06-28 18:03:02 +02001/*
2 * Copyright (C) 2011 STRATO. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
17 */
18
19#include <linux/sched.h>
20#include <linux/pagemap.h>
21#include <linux/writeback.h>
22#include <linux/blkdev.h>
23#include <linux/rbtree.h>
24#include <linux/slab.h>
25#include <linux/workqueue.h>
Filipe Brandenburger55e301f2013-01-29 06:04:50 +000026#include <linux/btrfs.h>
Arne Jansenbed92ea2012-06-28 18:03:02 +020027
28#include "ctree.h"
29#include "transaction.h"
30#include "disk-io.h"
31#include "locking.h"
32#include "ulist.h"
Arne Jansenbed92ea2012-06-28 18:03:02 +020033#include "backref.h"
Jan Schmidt2f232032013-04-25 16:04:51 +000034#include "extent_io.h"
Arne Jansenbed92ea2012-06-28 18:03:02 +020035
36/* TODO XXX FIXME
37 * - subvol delete -> delete when ref goes to 0? delete limits also?
38 * - reorganize keys
39 * - compressed
40 * - sync
Arne Jansenbed92ea2012-06-28 18:03:02 +020041 * - copy also limits on subvol creation
42 * - limit
43 * - caches fuer ulists
44 * - performance benchmarks
45 * - check all ioctl parameters
46 */
47
48/*
49 * one struct for each qgroup, organized in fs_info->qgroup_tree.
50 */
51struct btrfs_qgroup {
52 u64 qgroupid;
53
54 /*
55 * state
56 */
57 u64 rfer; /* referenced */
58 u64 rfer_cmpr; /* referenced compressed */
59 u64 excl; /* exclusive */
60 u64 excl_cmpr; /* exclusive compressed */
61
62 /*
63 * limits
64 */
65 u64 lim_flags; /* which limits are set */
66 u64 max_rfer;
67 u64 max_excl;
68 u64 rsv_rfer;
69 u64 rsv_excl;
70
71 /*
72 * reservation tracking
73 */
74 u64 reserved;
75
76 /*
77 * lists
78 */
79 struct list_head groups; /* groups this group is member of */
80 struct list_head members; /* groups that are members of this group */
81 struct list_head dirty; /* dirty groups */
82 struct rb_node node; /* tree of qgroups */
83
84 /*
85 * temp variables for accounting operations
86 */
87 u64 tag;
88 u64 refcnt;
89};
90
91/*
92 * glue structure to represent the relations between qgroups.
93 */
94struct btrfs_qgroup_list {
95 struct list_head next_group;
96 struct list_head next_member;
97 struct btrfs_qgroup *group;
98 struct btrfs_qgroup *member;
99};
100
Jan Schmidt2f232032013-04-25 16:04:51 +0000101struct qgroup_rescan {
102 struct btrfs_work work;
103 struct btrfs_fs_info *fs_info;
104};
105
106static void qgroup_rescan_start(struct btrfs_fs_info *fs_info,
107 struct qgroup_rescan *qscan);
108
Wang Shilong58400fc2013-04-07 10:50:17 +0000109/* must be called with qgroup_ioctl_lock held */
Arne Jansenbed92ea2012-06-28 18:03:02 +0200110static struct btrfs_qgroup *find_qgroup_rb(struct btrfs_fs_info *fs_info,
111 u64 qgroupid)
112{
113 struct rb_node *n = fs_info->qgroup_tree.rb_node;
114 struct btrfs_qgroup *qgroup;
115
116 while (n) {
117 qgroup = rb_entry(n, struct btrfs_qgroup, node);
118 if (qgroup->qgroupid < qgroupid)
119 n = n->rb_left;
120 else if (qgroup->qgroupid > qgroupid)
121 n = n->rb_right;
122 else
123 return qgroup;
124 }
125 return NULL;
126}
127
128/* must be called with qgroup_lock held */
129static struct btrfs_qgroup *add_qgroup_rb(struct btrfs_fs_info *fs_info,
130 u64 qgroupid)
131{
132 struct rb_node **p = &fs_info->qgroup_tree.rb_node;
133 struct rb_node *parent = NULL;
134 struct btrfs_qgroup *qgroup;
135
136 while (*p) {
137 parent = *p;
138 qgroup = rb_entry(parent, struct btrfs_qgroup, node);
139
140 if (qgroup->qgroupid < qgroupid)
141 p = &(*p)->rb_left;
142 else if (qgroup->qgroupid > qgroupid)
143 p = &(*p)->rb_right;
144 else
145 return qgroup;
146 }
147
148 qgroup = kzalloc(sizeof(*qgroup), GFP_ATOMIC);
149 if (!qgroup)
150 return ERR_PTR(-ENOMEM);
151
152 qgroup->qgroupid = qgroupid;
153 INIT_LIST_HEAD(&qgroup->groups);
154 INIT_LIST_HEAD(&qgroup->members);
155 INIT_LIST_HEAD(&qgroup->dirty);
156
157 rb_link_node(&qgroup->node, parent, p);
158 rb_insert_color(&qgroup->node, &fs_info->qgroup_tree);
159
160 return qgroup;
161}
162
163/* must be called with qgroup_lock held */
164static int del_qgroup_rb(struct btrfs_fs_info *fs_info, u64 qgroupid)
165{
166 struct btrfs_qgroup *qgroup = find_qgroup_rb(fs_info, qgroupid);
167 struct btrfs_qgroup_list *list;
168
169 if (!qgroup)
170 return -ENOENT;
171
172 rb_erase(&qgroup->node, &fs_info->qgroup_tree);
173 list_del(&qgroup->dirty);
174
175 while (!list_empty(&qgroup->groups)) {
176 list = list_first_entry(&qgroup->groups,
177 struct btrfs_qgroup_list, next_group);
178 list_del(&list->next_group);
179 list_del(&list->next_member);
180 kfree(list);
181 }
182
183 while (!list_empty(&qgroup->members)) {
184 list = list_first_entry(&qgroup->members,
185 struct btrfs_qgroup_list, next_member);
186 list_del(&list->next_group);
187 list_del(&list->next_member);
188 kfree(list);
189 }
190 kfree(qgroup);
191
192 return 0;
193}
194
195/* must be called with qgroup_lock held */
196static int add_relation_rb(struct btrfs_fs_info *fs_info,
197 u64 memberid, u64 parentid)
198{
199 struct btrfs_qgroup *member;
200 struct btrfs_qgroup *parent;
201 struct btrfs_qgroup_list *list;
202
203 member = find_qgroup_rb(fs_info, memberid);
204 parent = find_qgroup_rb(fs_info, parentid);
205 if (!member || !parent)
206 return -ENOENT;
207
208 list = kzalloc(sizeof(*list), GFP_ATOMIC);
209 if (!list)
210 return -ENOMEM;
211
212 list->group = parent;
213 list->member = member;
214 list_add_tail(&list->next_group, &member->groups);
215 list_add_tail(&list->next_member, &parent->members);
216
217 return 0;
218}
219
220/* must be called with qgroup_lock held */
221static int del_relation_rb(struct btrfs_fs_info *fs_info,
222 u64 memberid, u64 parentid)
223{
224 struct btrfs_qgroup *member;
225 struct btrfs_qgroup *parent;
226 struct btrfs_qgroup_list *list;
227
228 member = find_qgroup_rb(fs_info, memberid);
229 parent = find_qgroup_rb(fs_info, parentid);
230 if (!member || !parent)
231 return -ENOENT;
232
233 list_for_each_entry(list, &member->groups, next_group) {
234 if (list->group == parent) {
235 list_del(&list->next_group);
236 list_del(&list->next_member);
237 kfree(list);
238 return 0;
239 }
240 }
241 return -ENOENT;
242}
243
244/*
245 * The full config is read in one go, only called from open_ctree()
246 * It doesn't use any locking, as at this point we're still single-threaded
247 */
248int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
249{
250 struct btrfs_key key;
251 struct btrfs_key found_key;
252 struct btrfs_root *quota_root = fs_info->quota_root;
253 struct btrfs_path *path = NULL;
254 struct extent_buffer *l;
255 int slot;
256 int ret = 0;
257 u64 flags = 0;
258
259 if (!fs_info->quota_enabled)
260 return 0;
261
Wang Shilong1e8f9152013-05-06 11:03:27 +0000262 fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS);
263 if (!fs_info->qgroup_ulist) {
264 ret = -ENOMEM;
265 goto out;
266 }
267
Arne Jansenbed92ea2012-06-28 18:03:02 +0200268 path = btrfs_alloc_path();
269 if (!path) {
270 ret = -ENOMEM;
271 goto out;
272 }
273
274 /* default this to quota off, in case no status key is found */
275 fs_info->qgroup_flags = 0;
276
277 /*
278 * pass 1: read status, all qgroup infos and limits
279 */
280 key.objectid = 0;
281 key.type = 0;
282 key.offset = 0;
283 ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 1);
284 if (ret)
285 goto out;
286
287 while (1) {
288 struct btrfs_qgroup *qgroup;
289
290 slot = path->slots[0];
291 l = path->nodes[0];
292 btrfs_item_key_to_cpu(l, &found_key, slot);
293
294 if (found_key.type == BTRFS_QGROUP_STATUS_KEY) {
295 struct btrfs_qgroup_status_item *ptr;
296
297 ptr = btrfs_item_ptr(l, slot,
298 struct btrfs_qgroup_status_item);
299
300 if (btrfs_qgroup_status_version(l, ptr) !=
301 BTRFS_QGROUP_STATUS_VERSION) {
302 printk(KERN_ERR
303 "btrfs: old qgroup version, quota disabled\n");
304 goto out;
305 }
306 if (btrfs_qgroup_status_generation(l, ptr) !=
307 fs_info->generation) {
308 flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
309 printk(KERN_ERR
310 "btrfs: qgroup generation mismatch, "
311 "marked as inconsistent\n");
312 }
313 fs_info->qgroup_flags = btrfs_qgroup_status_flags(l,
314 ptr);
Jan Schmidt2f232032013-04-25 16:04:51 +0000315 fs_info->qgroup_rescan_progress.objectid =
316 btrfs_qgroup_status_rescan(l, ptr);
317 if (fs_info->qgroup_flags &
318 BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
319 struct qgroup_rescan *qscan =
320 kmalloc(sizeof(*qscan), GFP_NOFS);
321 if (!qscan) {
322 ret = -ENOMEM;
323 goto out;
324 }
325 fs_info->qgroup_rescan_progress.type = 0;
326 fs_info->qgroup_rescan_progress.offset = 0;
327 qgroup_rescan_start(fs_info, qscan);
328 }
Arne Jansenbed92ea2012-06-28 18:03:02 +0200329 goto next1;
330 }
331
332 if (found_key.type != BTRFS_QGROUP_INFO_KEY &&
333 found_key.type != BTRFS_QGROUP_LIMIT_KEY)
334 goto next1;
335
336 qgroup = find_qgroup_rb(fs_info, found_key.offset);
337 if ((qgroup && found_key.type == BTRFS_QGROUP_INFO_KEY) ||
338 (!qgroup && found_key.type == BTRFS_QGROUP_LIMIT_KEY)) {
339 printk(KERN_ERR "btrfs: inconsitent qgroup config\n");
340 flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
341 }
342 if (!qgroup) {
343 qgroup = add_qgroup_rb(fs_info, found_key.offset);
344 if (IS_ERR(qgroup)) {
345 ret = PTR_ERR(qgroup);
346 goto out;
347 }
348 }
349 switch (found_key.type) {
350 case BTRFS_QGROUP_INFO_KEY: {
351 struct btrfs_qgroup_info_item *ptr;
352
353 ptr = btrfs_item_ptr(l, slot,
354 struct btrfs_qgroup_info_item);
355 qgroup->rfer = btrfs_qgroup_info_rfer(l, ptr);
356 qgroup->rfer_cmpr = btrfs_qgroup_info_rfer_cmpr(l, ptr);
357 qgroup->excl = btrfs_qgroup_info_excl(l, ptr);
358 qgroup->excl_cmpr = btrfs_qgroup_info_excl_cmpr(l, ptr);
359 /* generation currently unused */
360 break;
361 }
362 case BTRFS_QGROUP_LIMIT_KEY: {
363 struct btrfs_qgroup_limit_item *ptr;
364
365 ptr = btrfs_item_ptr(l, slot,
366 struct btrfs_qgroup_limit_item);
367 qgroup->lim_flags = btrfs_qgroup_limit_flags(l, ptr);
368 qgroup->max_rfer = btrfs_qgroup_limit_max_rfer(l, ptr);
369 qgroup->max_excl = btrfs_qgroup_limit_max_excl(l, ptr);
370 qgroup->rsv_rfer = btrfs_qgroup_limit_rsv_rfer(l, ptr);
371 qgroup->rsv_excl = btrfs_qgroup_limit_rsv_excl(l, ptr);
372 break;
373 }
374 }
375next1:
376 ret = btrfs_next_item(quota_root, path);
377 if (ret < 0)
378 goto out;
379 if (ret)
380 break;
381 }
382 btrfs_release_path(path);
383
384 /*
385 * pass 2: read all qgroup relations
386 */
387 key.objectid = 0;
388 key.type = BTRFS_QGROUP_RELATION_KEY;
389 key.offset = 0;
390 ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 0);
391 if (ret)
392 goto out;
393 while (1) {
394 slot = path->slots[0];
395 l = path->nodes[0];
396 btrfs_item_key_to_cpu(l, &found_key, slot);
397
398 if (found_key.type != BTRFS_QGROUP_RELATION_KEY)
399 goto next2;
400
401 if (found_key.objectid > found_key.offset) {
402 /* parent <- member, not needed to build config */
403 /* FIXME should we omit the key completely? */
404 goto next2;
405 }
406
407 ret = add_relation_rb(fs_info, found_key.objectid,
408 found_key.offset);
Arne Jansenff248582013-01-17 01:22:08 -0700409 if (ret == -ENOENT) {
410 printk(KERN_WARNING
411 "btrfs: orphan qgroup relation 0x%llx->0x%llx\n",
412 (unsigned long long)found_key.objectid,
413 (unsigned long long)found_key.offset);
414 ret = 0; /* ignore the error */
415 }
Arne Jansenbed92ea2012-06-28 18:03:02 +0200416 if (ret)
417 goto out;
418next2:
419 ret = btrfs_next_item(quota_root, path);
420 if (ret < 0)
421 goto out;
422 if (ret)
423 break;
424 }
425out:
426 fs_info->qgroup_flags |= flags;
427 if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON)) {
428 fs_info->quota_enabled = 0;
429 fs_info->pending_quota_state = 0;
430 }
431 btrfs_free_path(path);
432
Jan Schmidteb1716a2013-05-28 15:47:23 +0000433 if (ret < 0) {
Wang Shilong1e8f9152013-05-06 11:03:27 +0000434 ulist_free(fs_info->qgroup_ulist);
Jan Schmidteb1716a2013-05-28 15:47:23 +0000435 fs_info->qgroup_ulist = NULL;
436 }
Wang Shilong1e8f9152013-05-06 11:03:27 +0000437
Arne Jansenbed92ea2012-06-28 18:03:02 +0200438 return ret < 0 ? ret : 0;
439}
440
441/*
442 * This is only called from close_ctree() or open_ctree(), both in single-
443 * treaded paths. Clean up the in-memory structures. No locking needed.
444 */
445void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info)
446{
447 struct rb_node *n;
448 struct btrfs_qgroup *qgroup;
449 struct btrfs_qgroup_list *list;
450
451 while ((n = rb_first(&fs_info->qgroup_tree))) {
452 qgroup = rb_entry(n, struct btrfs_qgroup, node);
453 rb_erase(n, &fs_info->qgroup_tree);
454
Arne Jansenbed92ea2012-06-28 18:03:02 +0200455 while (!list_empty(&qgroup->groups)) {
456 list = list_first_entry(&qgroup->groups,
457 struct btrfs_qgroup_list,
458 next_group);
459 list_del(&list->next_group);
460 list_del(&list->next_member);
461 kfree(list);
462 }
463
464 while (!list_empty(&qgroup->members)) {
465 list = list_first_entry(&qgroup->members,
466 struct btrfs_qgroup_list,
467 next_member);
468 list_del(&list->next_group);
469 list_del(&list->next_member);
470 kfree(list);
471 }
472 kfree(qgroup);
473 }
Wang Shilong1e8f9152013-05-06 11:03:27 +0000474 ulist_free(fs_info->qgroup_ulist);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200475}
476
477static int add_qgroup_relation_item(struct btrfs_trans_handle *trans,
478 struct btrfs_root *quota_root,
479 u64 src, u64 dst)
480{
481 int ret;
482 struct btrfs_path *path;
483 struct btrfs_key key;
484
485 path = btrfs_alloc_path();
486 if (!path)
487 return -ENOMEM;
488
489 key.objectid = src;
490 key.type = BTRFS_QGROUP_RELATION_KEY;
491 key.offset = dst;
492
493 ret = btrfs_insert_empty_item(trans, quota_root, path, &key, 0);
494
495 btrfs_mark_buffer_dirty(path->nodes[0]);
496
497 btrfs_free_path(path);
498 return ret;
499}
500
501static int del_qgroup_relation_item(struct btrfs_trans_handle *trans,
502 struct btrfs_root *quota_root,
503 u64 src, u64 dst)
504{
505 int ret;
506 struct btrfs_path *path;
507 struct btrfs_key key;
508
509 path = btrfs_alloc_path();
510 if (!path)
511 return -ENOMEM;
512
513 key.objectid = src;
514 key.type = BTRFS_QGROUP_RELATION_KEY;
515 key.offset = dst;
516
517 ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
518 if (ret < 0)
519 goto out;
520
521 if (ret > 0) {
522 ret = -ENOENT;
523 goto out;
524 }
525
526 ret = btrfs_del_item(trans, quota_root, path);
527out:
528 btrfs_free_path(path);
529 return ret;
530}
531
532static int add_qgroup_item(struct btrfs_trans_handle *trans,
533 struct btrfs_root *quota_root, u64 qgroupid)
534{
535 int ret;
536 struct btrfs_path *path;
537 struct btrfs_qgroup_info_item *qgroup_info;
538 struct btrfs_qgroup_limit_item *qgroup_limit;
539 struct extent_buffer *leaf;
540 struct btrfs_key key;
541
542 path = btrfs_alloc_path();
543 if (!path)
544 return -ENOMEM;
545
546 key.objectid = 0;
547 key.type = BTRFS_QGROUP_INFO_KEY;
548 key.offset = qgroupid;
549
550 ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
551 sizeof(*qgroup_info));
552 if (ret)
553 goto out;
554
555 leaf = path->nodes[0];
556 qgroup_info = btrfs_item_ptr(leaf, path->slots[0],
557 struct btrfs_qgroup_info_item);
558 btrfs_set_qgroup_info_generation(leaf, qgroup_info, trans->transid);
559 btrfs_set_qgroup_info_rfer(leaf, qgroup_info, 0);
560 btrfs_set_qgroup_info_rfer_cmpr(leaf, qgroup_info, 0);
561 btrfs_set_qgroup_info_excl(leaf, qgroup_info, 0);
562 btrfs_set_qgroup_info_excl_cmpr(leaf, qgroup_info, 0);
563
564 btrfs_mark_buffer_dirty(leaf);
565
566 btrfs_release_path(path);
567
568 key.type = BTRFS_QGROUP_LIMIT_KEY;
569 ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
570 sizeof(*qgroup_limit));
571 if (ret)
572 goto out;
573
574 leaf = path->nodes[0];
575 qgroup_limit = btrfs_item_ptr(leaf, path->slots[0],
576 struct btrfs_qgroup_limit_item);
577 btrfs_set_qgroup_limit_flags(leaf, qgroup_limit, 0);
578 btrfs_set_qgroup_limit_max_rfer(leaf, qgroup_limit, 0);
579 btrfs_set_qgroup_limit_max_excl(leaf, qgroup_limit, 0);
580 btrfs_set_qgroup_limit_rsv_rfer(leaf, qgroup_limit, 0);
581 btrfs_set_qgroup_limit_rsv_excl(leaf, qgroup_limit, 0);
582
583 btrfs_mark_buffer_dirty(leaf);
584
585 ret = 0;
586out:
587 btrfs_free_path(path);
588 return ret;
589}
590
591static int del_qgroup_item(struct btrfs_trans_handle *trans,
592 struct btrfs_root *quota_root, u64 qgroupid)
593{
594 int ret;
595 struct btrfs_path *path;
596 struct btrfs_key key;
597
598 path = btrfs_alloc_path();
599 if (!path)
600 return -ENOMEM;
601
602 key.objectid = 0;
603 key.type = BTRFS_QGROUP_INFO_KEY;
604 key.offset = qgroupid;
605 ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
606 if (ret < 0)
607 goto out;
608
609 if (ret > 0) {
610 ret = -ENOENT;
611 goto out;
612 }
613
614 ret = btrfs_del_item(trans, quota_root, path);
615 if (ret)
616 goto out;
617
618 btrfs_release_path(path);
619
620 key.type = BTRFS_QGROUP_LIMIT_KEY;
621 ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
622 if (ret < 0)
623 goto out;
624
625 if (ret > 0) {
626 ret = -ENOENT;
627 goto out;
628 }
629
630 ret = btrfs_del_item(trans, quota_root, path);
631
632out:
633 btrfs_free_path(path);
634 return ret;
635}
636
637static int update_qgroup_limit_item(struct btrfs_trans_handle *trans,
638 struct btrfs_root *root, u64 qgroupid,
639 u64 flags, u64 max_rfer, u64 max_excl,
640 u64 rsv_rfer, u64 rsv_excl)
641{
642 struct btrfs_path *path;
643 struct btrfs_key key;
644 struct extent_buffer *l;
645 struct btrfs_qgroup_limit_item *qgroup_limit;
646 int ret;
647 int slot;
648
649 key.objectid = 0;
650 key.type = BTRFS_QGROUP_LIMIT_KEY;
651 key.offset = qgroupid;
652
653 path = btrfs_alloc_path();
Wang Shilong84cbe2f2013-02-27 11:20:56 +0000654 if (!path)
655 return -ENOMEM;
656
Arne Jansenbed92ea2012-06-28 18:03:02 +0200657 ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
658 if (ret > 0)
659 ret = -ENOENT;
660
661 if (ret)
662 goto out;
663
664 l = path->nodes[0];
665 slot = path->slots[0];
666 qgroup_limit = btrfs_item_ptr(l, path->slots[0],
667 struct btrfs_qgroup_limit_item);
668 btrfs_set_qgroup_limit_flags(l, qgroup_limit, flags);
669 btrfs_set_qgroup_limit_max_rfer(l, qgroup_limit, max_rfer);
670 btrfs_set_qgroup_limit_max_excl(l, qgroup_limit, max_excl);
671 btrfs_set_qgroup_limit_rsv_rfer(l, qgroup_limit, rsv_rfer);
672 btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, rsv_excl);
673
674 btrfs_mark_buffer_dirty(l);
675
676out:
677 btrfs_free_path(path);
678 return ret;
679}
680
681static int update_qgroup_info_item(struct btrfs_trans_handle *trans,
682 struct btrfs_root *root,
683 struct btrfs_qgroup *qgroup)
684{
685 struct btrfs_path *path;
686 struct btrfs_key key;
687 struct extent_buffer *l;
688 struct btrfs_qgroup_info_item *qgroup_info;
689 int ret;
690 int slot;
691
692 key.objectid = 0;
693 key.type = BTRFS_QGROUP_INFO_KEY;
694 key.offset = qgroup->qgroupid;
695
696 path = btrfs_alloc_path();
Wang Shilong84cbe2f2013-02-27 11:20:56 +0000697 if (!path)
698 return -ENOMEM;
699
Arne Jansenbed92ea2012-06-28 18:03:02 +0200700 ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
701 if (ret > 0)
702 ret = -ENOENT;
703
704 if (ret)
705 goto out;
706
707 l = path->nodes[0];
708 slot = path->slots[0];
709 qgroup_info = btrfs_item_ptr(l, path->slots[0],
710 struct btrfs_qgroup_info_item);
711 btrfs_set_qgroup_info_generation(l, qgroup_info, trans->transid);
712 btrfs_set_qgroup_info_rfer(l, qgroup_info, qgroup->rfer);
713 btrfs_set_qgroup_info_rfer_cmpr(l, qgroup_info, qgroup->rfer_cmpr);
714 btrfs_set_qgroup_info_excl(l, qgroup_info, qgroup->excl);
715 btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, qgroup->excl_cmpr);
716
717 btrfs_mark_buffer_dirty(l);
718
719out:
720 btrfs_free_path(path);
721 return ret;
722}
723
724static int update_qgroup_status_item(struct btrfs_trans_handle *trans,
725 struct btrfs_fs_info *fs_info,
726 struct btrfs_root *root)
727{
728 struct btrfs_path *path;
729 struct btrfs_key key;
730 struct extent_buffer *l;
731 struct btrfs_qgroup_status_item *ptr;
732 int ret;
733 int slot;
734
735 key.objectid = 0;
736 key.type = BTRFS_QGROUP_STATUS_KEY;
737 key.offset = 0;
738
739 path = btrfs_alloc_path();
Wang Shilong84cbe2f2013-02-27 11:20:56 +0000740 if (!path)
741 return -ENOMEM;
742
Arne Jansenbed92ea2012-06-28 18:03:02 +0200743 ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
744 if (ret > 0)
745 ret = -ENOENT;
746
747 if (ret)
748 goto out;
749
750 l = path->nodes[0];
751 slot = path->slots[0];
752 ptr = btrfs_item_ptr(l, slot, struct btrfs_qgroup_status_item);
753 btrfs_set_qgroup_status_flags(l, ptr, fs_info->qgroup_flags);
754 btrfs_set_qgroup_status_generation(l, ptr, trans->transid);
Jan Schmidt2f232032013-04-25 16:04:51 +0000755 btrfs_set_qgroup_status_rescan(l, ptr,
756 fs_info->qgroup_rescan_progress.objectid);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200757
758 btrfs_mark_buffer_dirty(l);
759
760out:
761 btrfs_free_path(path);
762 return ret;
763}
764
765/*
766 * called with qgroup_lock held
767 */
768static int btrfs_clean_quota_tree(struct btrfs_trans_handle *trans,
769 struct btrfs_root *root)
770{
771 struct btrfs_path *path;
772 struct btrfs_key key;
Wang Shilong06b3a862013-02-27 11:16:57 +0000773 struct extent_buffer *leaf = NULL;
Arne Jansenbed92ea2012-06-28 18:03:02 +0200774 int ret;
Wang Shilong06b3a862013-02-27 11:16:57 +0000775 int nr = 0;
Arne Jansenbed92ea2012-06-28 18:03:02 +0200776
Arne Jansenbed92ea2012-06-28 18:03:02 +0200777 path = btrfs_alloc_path();
778 if (!path)
779 return -ENOMEM;
780
Wang Shilong06b3a862013-02-27 11:16:57 +0000781 path->leave_spinning = 1;
782
783 key.objectid = 0;
784 key.offset = 0;
785 key.type = 0;
786
Arne Jansenbed92ea2012-06-28 18:03:02 +0200787 while (1) {
Arne Jansenbed92ea2012-06-28 18:03:02 +0200788 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
Wang Shilong06b3a862013-02-27 11:16:57 +0000789 if (ret < 0)
790 goto out;
791 leaf = path->nodes[0];
792 nr = btrfs_header_nritems(leaf);
793 if (!nr)
Arne Jansenbed92ea2012-06-28 18:03:02 +0200794 break;
Wang Shilong06b3a862013-02-27 11:16:57 +0000795 /*
796 * delete the leaf one by one
797 * since the whole tree is going
798 * to be deleted.
799 */
800 path->slots[0] = 0;
801 ret = btrfs_del_items(trans, root, path, 0, nr);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200802 if (ret)
803 goto out;
Wang Shilong06b3a862013-02-27 11:16:57 +0000804
Arne Jansenbed92ea2012-06-28 18:03:02 +0200805 btrfs_release_path(path);
806 }
807 ret = 0;
808out:
809 root->fs_info->pending_quota_state = 0;
810 btrfs_free_path(path);
811 return ret;
812}
813
814int btrfs_quota_enable(struct btrfs_trans_handle *trans,
815 struct btrfs_fs_info *fs_info)
816{
817 struct btrfs_root *quota_root;
Wang Shilong7708f022013-04-07 10:24:57 +0000818 struct btrfs_root *tree_root = fs_info->tree_root;
Arne Jansenbed92ea2012-06-28 18:03:02 +0200819 struct btrfs_path *path = NULL;
820 struct btrfs_qgroup_status_item *ptr;
821 struct extent_buffer *leaf;
822 struct btrfs_key key;
Wang Shilong7708f022013-04-07 10:24:57 +0000823 struct btrfs_key found_key;
824 struct btrfs_qgroup *qgroup = NULL;
Arne Jansenbed92ea2012-06-28 18:03:02 +0200825 int ret = 0;
Wang Shilong7708f022013-04-07 10:24:57 +0000826 int slot;
Arne Jansenbed92ea2012-06-28 18:03:02 +0200827
Wang Shilongf2f6ed32013-04-07 10:50:16 +0000828 mutex_lock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200829 if (fs_info->quota_root) {
830 fs_info->pending_quota_state = 1;
Arne Jansenbed92ea2012-06-28 18:03:02 +0200831 goto out;
832 }
Arne Jansenbed92ea2012-06-28 18:03:02 +0200833
Wang Shilong1e8f9152013-05-06 11:03:27 +0000834 fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS);
835 if (!fs_info->qgroup_ulist) {
836 ret = -ENOMEM;
837 goto out;
838 }
839
Arne Jansenbed92ea2012-06-28 18:03:02 +0200840 /*
841 * initially create the quota tree
842 */
843 quota_root = btrfs_create_tree(trans, fs_info,
844 BTRFS_QUOTA_TREE_OBJECTID);
845 if (IS_ERR(quota_root)) {
846 ret = PTR_ERR(quota_root);
847 goto out;
848 }
849
850 path = btrfs_alloc_path();
Tsutomu Itoh5b7ff5b2012-10-16 05:44:21 +0000851 if (!path) {
852 ret = -ENOMEM;
853 goto out_free_root;
854 }
Arne Jansenbed92ea2012-06-28 18:03:02 +0200855
856 key.objectid = 0;
857 key.type = BTRFS_QGROUP_STATUS_KEY;
858 key.offset = 0;
859
860 ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
861 sizeof(*ptr));
862 if (ret)
Tsutomu Itoh5b7ff5b2012-10-16 05:44:21 +0000863 goto out_free_path;
Arne Jansenbed92ea2012-06-28 18:03:02 +0200864
865 leaf = path->nodes[0];
866 ptr = btrfs_item_ptr(leaf, path->slots[0],
867 struct btrfs_qgroup_status_item);
868 btrfs_set_qgroup_status_generation(leaf, ptr, trans->transid);
869 btrfs_set_qgroup_status_version(leaf, ptr, BTRFS_QGROUP_STATUS_VERSION);
870 fs_info->qgroup_flags = BTRFS_QGROUP_STATUS_FLAG_ON |
871 BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
872 btrfs_set_qgroup_status_flags(leaf, ptr, fs_info->qgroup_flags);
Jan Schmidt2f232032013-04-25 16:04:51 +0000873 btrfs_set_qgroup_status_rescan(leaf, ptr, 0);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200874
875 btrfs_mark_buffer_dirty(leaf);
876
Wang Shilong7708f022013-04-07 10:24:57 +0000877 key.objectid = 0;
878 key.type = BTRFS_ROOT_REF_KEY;
879 key.offset = 0;
880
881 btrfs_release_path(path);
882 ret = btrfs_search_slot_for_read(tree_root, &key, path, 1, 0);
883 if (ret > 0)
884 goto out_add_root;
885 if (ret < 0)
886 goto out_free_path;
887
888
889 while (1) {
890 slot = path->slots[0];
891 leaf = path->nodes[0];
892 btrfs_item_key_to_cpu(leaf, &found_key, slot);
893
894 if (found_key.type == BTRFS_ROOT_REF_KEY) {
895 ret = add_qgroup_item(trans, quota_root,
896 found_key.offset);
897 if (ret)
898 goto out_free_path;
899
Wang Shilong7708f022013-04-07 10:24:57 +0000900 qgroup = add_qgroup_rb(fs_info, found_key.offset);
901 if (IS_ERR(qgroup)) {
Wang Shilong7708f022013-04-07 10:24:57 +0000902 ret = PTR_ERR(qgroup);
903 goto out_free_path;
904 }
Wang Shilong7708f022013-04-07 10:24:57 +0000905 }
906 ret = btrfs_next_item(tree_root, path);
907 if (ret < 0)
908 goto out_free_path;
909 if (ret)
910 break;
911 }
912
913out_add_root:
914 btrfs_release_path(path);
915 ret = add_qgroup_item(trans, quota_root, BTRFS_FS_TREE_OBJECTID);
916 if (ret)
917 goto out_free_path;
918
Wang Shilong7708f022013-04-07 10:24:57 +0000919 qgroup = add_qgroup_rb(fs_info, BTRFS_FS_TREE_OBJECTID);
920 if (IS_ERR(qgroup)) {
Wang Shilong7708f022013-04-07 10:24:57 +0000921 ret = PTR_ERR(qgroup);
922 goto out_free_path;
923 }
Wang Shilong58400fc2013-04-07 10:50:17 +0000924 spin_lock(&fs_info->qgroup_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200925 fs_info->quota_root = quota_root;
926 fs_info->pending_quota_state = 1;
927 spin_unlock(&fs_info->qgroup_lock);
Tsutomu Itoh5b7ff5b2012-10-16 05:44:21 +0000928out_free_path:
Arne Jansenbed92ea2012-06-28 18:03:02 +0200929 btrfs_free_path(path);
Tsutomu Itoh5b7ff5b2012-10-16 05:44:21 +0000930out_free_root:
931 if (ret) {
932 free_extent_buffer(quota_root->node);
933 free_extent_buffer(quota_root->commit_root);
934 kfree(quota_root);
935 }
936out:
Jan Schmidteb1716a2013-05-28 15:47:23 +0000937 if (ret) {
Wang Shilong1e8f9152013-05-06 11:03:27 +0000938 ulist_free(fs_info->qgroup_ulist);
Jan Schmidteb1716a2013-05-28 15:47:23 +0000939 fs_info->qgroup_ulist = NULL;
940 }
Wang Shilongf2f6ed32013-04-07 10:50:16 +0000941 mutex_unlock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200942 return ret;
943}
944
945int btrfs_quota_disable(struct btrfs_trans_handle *trans,
946 struct btrfs_fs_info *fs_info)
947{
948 struct btrfs_root *tree_root = fs_info->tree_root;
949 struct btrfs_root *quota_root;
950 int ret = 0;
951
Wang Shilongf2f6ed32013-04-07 10:50:16 +0000952 mutex_lock(&fs_info->qgroup_ioctl_lock);
Wang Shilong58400fc2013-04-07 10:50:17 +0000953 if (!fs_info->quota_root)
Wang Shilongf2f6ed32013-04-07 10:50:16 +0000954 goto out;
Wang Shilong58400fc2013-04-07 10:50:17 +0000955 spin_lock(&fs_info->qgroup_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200956 fs_info->quota_enabled = 0;
957 fs_info->pending_quota_state = 0;
958 quota_root = fs_info->quota_root;
959 fs_info->quota_root = NULL;
960 btrfs_free_qgroup_config(fs_info);
961 spin_unlock(&fs_info->qgroup_lock);
962
Wang Shilongf2f6ed32013-04-07 10:50:16 +0000963 if (!quota_root) {
964 ret = -EINVAL;
965 goto out;
966 }
Arne Jansenbed92ea2012-06-28 18:03:02 +0200967
968 ret = btrfs_clean_quota_tree(trans, quota_root);
969 if (ret)
970 goto out;
971
972 ret = btrfs_del_root(trans, tree_root, &quota_root->root_key);
973 if (ret)
974 goto out;
975
976 list_del(&quota_root->dirty_list);
977
978 btrfs_tree_lock(quota_root->node);
979 clean_tree_block(trans, tree_root, quota_root->node);
980 btrfs_tree_unlock(quota_root->node);
981 btrfs_free_tree_block(trans, quota_root, quota_root->node, 0, 1);
982
983 free_extent_buffer(quota_root->node);
984 free_extent_buffer(quota_root->commit_root);
985 kfree(quota_root);
986out:
Wang Shilongf2f6ed32013-04-07 10:50:16 +0000987 mutex_unlock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200988 return ret;
989}
990
Jan Schmidt2f232032013-04-25 16:04:51 +0000991static void qgroup_dirty(struct btrfs_fs_info *fs_info,
992 struct btrfs_qgroup *qgroup)
Arne Jansenbed92ea2012-06-28 18:03:02 +0200993{
Jan Schmidt2f232032013-04-25 16:04:51 +0000994 if (list_empty(&qgroup->dirty))
995 list_add(&qgroup->dirty, &fs_info->dirty_qgroups);
Arne Jansenbed92ea2012-06-28 18:03:02 +0200996}
997
998int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
999 struct btrfs_fs_info *fs_info, u64 src, u64 dst)
1000{
1001 struct btrfs_root *quota_root;
Wang Shilongb7fef4f2013-04-07 10:50:18 +00001002 struct btrfs_qgroup *parent;
1003 struct btrfs_qgroup *member;
Wang Shilong534e6622013-04-17 14:49:51 +00001004 struct btrfs_qgroup_list *list;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001005 int ret = 0;
1006
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001007 mutex_lock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001008 quota_root = fs_info->quota_root;
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001009 if (!quota_root) {
1010 ret = -EINVAL;
1011 goto out;
1012 }
Wang Shilongb7fef4f2013-04-07 10:50:18 +00001013 member = find_qgroup_rb(fs_info, src);
1014 parent = find_qgroup_rb(fs_info, dst);
1015 if (!member || !parent) {
1016 ret = -EINVAL;
1017 goto out;
1018 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001019
Wang Shilong534e6622013-04-17 14:49:51 +00001020 /* check if such qgroup relation exist firstly */
1021 list_for_each_entry(list, &member->groups, next_group) {
1022 if (list->group == parent) {
1023 ret = -EEXIST;
1024 goto out;
1025 }
1026 }
1027
Arne Jansenbed92ea2012-06-28 18:03:02 +02001028 ret = add_qgroup_relation_item(trans, quota_root, src, dst);
1029 if (ret)
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001030 goto out;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001031
1032 ret = add_qgroup_relation_item(trans, quota_root, dst, src);
1033 if (ret) {
1034 del_qgroup_relation_item(trans, quota_root, src, dst);
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001035 goto out;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001036 }
1037
1038 spin_lock(&fs_info->qgroup_lock);
1039 ret = add_relation_rb(quota_root->fs_info, src, dst);
1040 spin_unlock(&fs_info->qgroup_lock);
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001041out:
1042 mutex_unlock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001043 return ret;
1044}
1045
1046int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
1047 struct btrfs_fs_info *fs_info, u64 src, u64 dst)
1048{
1049 struct btrfs_root *quota_root;
Wang Shilong534e6622013-04-17 14:49:51 +00001050 struct btrfs_qgroup *parent;
1051 struct btrfs_qgroup *member;
1052 struct btrfs_qgroup_list *list;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001053 int ret = 0;
1054 int err;
1055
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001056 mutex_lock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001057 quota_root = fs_info->quota_root;
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001058 if (!quota_root) {
1059 ret = -EINVAL;
1060 goto out;
1061 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001062
Wang Shilong534e6622013-04-17 14:49:51 +00001063 member = find_qgroup_rb(fs_info, src);
1064 parent = find_qgroup_rb(fs_info, dst);
1065 if (!member || !parent) {
1066 ret = -EINVAL;
1067 goto out;
1068 }
1069
1070 /* check if such qgroup relation exist firstly */
1071 list_for_each_entry(list, &member->groups, next_group) {
1072 if (list->group == parent)
1073 goto exist;
1074 }
1075 ret = -ENOENT;
1076 goto out;
1077exist:
Arne Jansenbed92ea2012-06-28 18:03:02 +02001078 ret = del_qgroup_relation_item(trans, quota_root, src, dst);
1079 err = del_qgroup_relation_item(trans, quota_root, dst, src);
1080 if (err && !ret)
1081 ret = err;
1082
1083 spin_lock(&fs_info->qgroup_lock);
1084 del_relation_rb(fs_info, src, dst);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001085 spin_unlock(&fs_info->qgroup_lock);
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001086out:
1087 mutex_unlock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001088 return ret;
1089}
1090
1091int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
1092 struct btrfs_fs_info *fs_info, u64 qgroupid, char *name)
1093{
1094 struct btrfs_root *quota_root;
1095 struct btrfs_qgroup *qgroup;
1096 int ret = 0;
1097
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001098 mutex_lock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001099 quota_root = fs_info->quota_root;
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001100 if (!quota_root) {
1101 ret = -EINVAL;
1102 goto out;
1103 }
Wang Shilong534e6622013-04-17 14:49:51 +00001104 qgroup = find_qgroup_rb(fs_info, qgroupid);
1105 if (qgroup) {
1106 ret = -EEXIST;
1107 goto out;
1108 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001109
1110 ret = add_qgroup_item(trans, quota_root, qgroupid);
Wang Shilong534e6622013-04-17 14:49:51 +00001111 if (ret)
1112 goto out;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001113
1114 spin_lock(&fs_info->qgroup_lock);
1115 qgroup = add_qgroup_rb(fs_info, qgroupid);
1116 spin_unlock(&fs_info->qgroup_lock);
1117
1118 if (IS_ERR(qgroup))
1119 ret = PTR_ERR(qgroup);
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001120out:
1121 mutex_unlock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001122 return ret;
1123}
1124
1125int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
1126 struct btrfs_fs_info *fs_info, u64 qgroupid)
1127{
1128 struct btrfs_root *quota_root;
Arne Jansen2cf68702013-01-17 01:22:09 -07001129 struct btrfs_qgroup *qgroup;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001130 int ret = 0;
1131
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001132 mutex_lock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001133 quota_root = fs_info->quota_root;
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001134 if (!quota_root) {
1135 ret = -EINVAL;
1136 goto out;
1137 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001138
Arne Jansen2cf68702013-01-17 01:22:09 -07001139 qgroup = find_qgroup_rb(fs_info, qgroupid);
Wang Shilong534e6622013-04-17 14:49:51 +00001140 if (!qgroup) {
1141 ret = -ENOENT;
1142 goto out;
1143 } else {
1144 /* check if there are no relations to this qgroup */
1145 if (!list_empty(&qgroup->groups) ||
1146 !list_empty(&qgroup->members)) {
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001147 ret = -EBUSY;
1148 goto out;
Arne Jansen2cf68702013-01-17 01:22:09 -07001149 }
1150 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001151 ret = del_qgroup_item(trans, quota_root, qgroupid);
1152
1153 spin_lock(&fs_info->qgroup_lock);
1154 del_qgroup_rb(quota_root->fs_info, qgroupid);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001155 spin_unlock(&fs_info->qgroup_lock);
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001156out:
1157 mutex_unlock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001158 return ret;
1159}
1160
1161int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
1162 struct btrfs_fs_info *fs_info, u64 qgroupid,
1163 struct btrfs_qgroup_limit *limit)
1164{
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001165 struct btrfs_root *quota_root;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001166 struct btrfs_qgroup *qgroup;
1167 int ret = 0;
1168
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001169 mutex_lock(&fs_info->qgroup_ioctl_lock);
1170 quota_root = fs_info->quota_root;
1171 if (!quota_root) {
1172 ret = -EINVAL;
1173 goto out;
1174 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001175
Wang Shilongddb47af2013-04-07 10:50:20 +00001176 qgroup = find_qgroup_rb(fs_info, qgroupid);
1177 if (!qgroup) {
1178 ret = -ENOENT;
1179 goto out;
1180 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001181 ret = update_qgroup_limit_item(trans, quota_root, qgroupid,
1182 limit->flags, limit->max_rfer,
1183 limit->max_excl, limit->rsv_rfer,
1184 limit->rsv_excl);
1185 if (ret) {
1186 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
1187 printk(KERN_INFO "unable to update quota limit for %llu\n",
1188 (unsigned long long)qgroupid);
1189 }
1190
Wang Shilong58400fc2013-04-07 10:50:17 +00001191 spin_lock(&fs_info->qgroup_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001192 qgroup->lim_flags = limit->flags;
1193 qgroup->max_rfer = limit->max_rfer;
1194 qgroup->max_excl = limit->max_excl;
1195 qgroup->rsv_rfer = limit->rsv_rfer;
1196 qgroup->rsv_excl = limit->rsv_excl;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001197 spin_unlock(&fs_info->qgroup_lock);
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001198out:
1199 mutex_unlock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001200 return ret;
1201}
1202
Arne Jansenbed92ea2012-06-28 18:03:02 +02001203/*
1204 * btrfs_qgroup_record_ref is called when the ref is added or deleted. it puts
1205 * the modification into a list that's later used by btrfs_end_transaction to
1206 * pass the recorded modifications on to btrfs_qgroup_account_ref.
1207 */
1208int btrfs_qgroup_record_ref(struct btrfs_trans_handle *trans,
1209 struct btrfs_delayed_ref_node *node,
1210 struct btrfs_delayed_extent_op *extent_op)
1211{
1212 struct qgroup_update *u;
1213
1214 BUG_ON(!trans->delayed_ref_elem.seq);
1215 u = kmalloc(sizeof(*u), GFP_NOFS);
1216 if (!u)
1217 return -ENOMEM;
1218
1219 u->node = node;
1220 u->extent_op = extent_op;
1221 list_add_tail(&u->list, &trans->qgroup_ref_list);
1222
1223 return 0;
1224}
1225
Jan Schmidt46b665c2013-04-25 16:04:50 +00001226static int qgroup_account_ref_step1(struct btrfs_fs_info *fs_info,
1227 struct ulist *roots, struct ulist *tmp,
1228 u64 seq)
1229{
1230 struct ulist_node *unode;
1231 struct ulist_iterator uiter;
1232 struct ulist_node *tmp_unode;
1233 struct ulist_iterator tmp_uiter;
1234 struct btrfs_qgroup *qg;
1235 int ret;
1236
1237 ULIST_ITER_INIT(&uiter);
1238 while ((unode = ulist_next(roots, &uiter))) {
1239 qg = find_qgroup_rb(fs_info, unode->val);
1240 if (!qg)
1241 continue;
1242
1243 ulist_reinit(tmp);
1244 /* XXX id not needed */
1245 ret = ulist_add(tmp, qg->qgroupid,
1246 (u64)(uintptr_t)qg, GFP_ATOMIC);
1247 if (ret < 0)
1248 return ret;
1249 ULIST_ITER_INIT(&tmp_uiter);
1250 while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
1251 struct btrfs_qgroup_list *glist;
1252
1253 qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
1254 if (qg->refcnt < seq)
1255 qg->refcnt = seq + 1;
1256 else
1257 ++qg->refcnt;
1258
1259 list_for_each_entry(glist, &qg->groups, next_group) {
1260 ret = ulist_add(tmp, glist->group->qgroupid,
1261 (u64)(uintptr_t)glist->group,
1262 GFP_ATOMIC);
1263 if (ret < 0)
1264 return ret;
1265 }
1266 }
1267 }
1268
1269 return 0;
1270}
1271
1272static int qgroup_account_ref_step2(struct btrfs_fs_info *fs_info,
1273 struct ulist *roots, struct ulist *tmp,
1274 u64 seq, int sgn, u64 num_bytes,
1275 struct btrfs_qgroup *qgroup)
1276{
1277 struct ulist_node *unode;
1278 struct ulist_iterator uiter;
1279 struct btrfs_qgroup *qg;
1280 struct btrfs_qgroup_list *glist;
1281 int ret;
1282
1283 ulist_reinit(tmp);
1284 ret = ulist_add(tmp, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
1285 if (ret < 0)
1286 return ret;
1287
1288 ULIST_ITER_INIT(&uiter);
1289 while ((unode = ulist_next(tmp, &uiter))) {
1290 qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
1291 if (qg->refcnt < seq) {
1292 /* not visited by step 1 */
1293 qg->rfer += sgn * num_bytes;
1294 qg->rfer_cmpr += sgn * num_bytes;
1295 if (roots->nnodes == 0) {
1296 qg->excl += sgn * num_bytes;
1297 qg->excl_cmpr += sgn * num_bytes;
1298 }
1299 qgroup_dirty(fs_info, qg);
1300 }
1301 WARN_ON(qg->tag >= seq);
1302 qg->tag = seq;
1303
1304 list_for_each_entry(glist, &qg->groups, next_group) {
1305 ret = ulist_add(tmp, glist->group->qgroupid,
1306 (uintptr_t)glist->group, GFP_ATOMIC);
1307 if (ret < 0)
1308 return ret;
1309 }
1310 }
1311
1312 return 0;
1313}
1314
1315static int qgroup_account_ref_step3(struct btrfs_fs_info *fs_info,
1316 struct ulist *roots, struct ulist *tmp,
1317 u64 seq, int sgn, u64 num_bytes)
1318{
1319 struct ulist_node *unode;
1320 struct ulist_iterator uiter;
1321 struct btrfs_qgroup *qg;
1322 struct ulist_node *tmp_unode;
1323 struct ulist_iterator tmp_uiter;
1324 int ret;
1325
1326 ULIST_ITER_INIT(&uiter);
1327 while ((unode = ulist_next(roots, &uiter))) {
1328 qg = find_qgroup_rb(fs_info, unode->val);
1329 if (!qg)
1330 continue;
1331
1332 ulist_reinit(tmp);
1333 ret = ulist_add(tmp, qg->qgroupid, (uintptr_t)qg, GFP_ATOMIC);
1334 if (ret < 0)
1335 return ret;
1336
1337 ULIST_ITER_INIT(&tmp_uiter);
1338 while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
1339 struct btrfs_qgroup_list *glist;
1340
1341 qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
1342 if (qg->tag == seq)
1343 continue;
1344
1345 if (qg->refcnt - seq == roots->nnodes) {
1346 qg->excl -= sgn * num_bytes;
1347 qg->excl_cmpr -= sgn * num_bytes;
1348 qgroup_dirty(fs_info, qg);
1349 }
1350
1351 list_for_each_entry(glist, &qg->groups, next_group) {
1352 ret = ulist_add(tmp, glist->group->qgroupid,
1353 (uintptr_t)glist->group,
1354 GFP_ATOMIC);
1355 if (ret < 0)
1356 return ret;
1357 }
1358 }
1359 }
1360
1361 return 0;
1362}
1363
Arne Jansenbed92ea2012-06-28 18:03:02 +02001364/*
1365 * btrfs_qgroup_account_ref is called for every ref that is added to or deleted
1366 * from the fs. First, all roots referencing the extent are searched, and
1367 * then the space is accounted accordingly to the different roots. The
1368 * accounting algorithm works in 3 steps documented inline.
1369 */
1370int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
1371 struct btrfs_fs_info *fs_info,
1372 struct btrfs_delayed_ref_node *node,
1373 struct btrfs_delayed_extent_op *extent_op)
1374{
1375 struct btrfs_key ins;
1376 struct btrfs_root *quota_root;
1377 u64 ref_root;
1378 struct btrfs_qgroup *qgroup;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001379 struct ulist *roots = NULL;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001380 u64 seq;
1381 int ret = 0;
1382 int sgn;
1383
1384 if (!fs_info->quota_enabled)
1385 return 0;
1386
1387 BUG_ON(!fs_info->quota_root);
1388
1389 ins.objectid = node->bytenr;
1390 ins.offset = node->num_bytes;
1391 ins.type = BTRFS_EXTENT_ITEM_KEY;
1392
1393 if (node->type == BTRFS_TREE_BLOCK_REF_KEY ||
1394 node->type == BTRFS_SHARED_BLOCK_REF_KEY) {
1395 struct btrfs_delayed_tree_ref *ref;
1396 ref = btrfs_delayed_node_to_tree_ref(node);
1397 ref_root = ref->root;
1398 } else if (node->type == BTRFS_EXTENT_DATA_REF_KEY ||
1399 node->type == BTRFS_SHARED_DATA_REF_KEY) {
1400 struct btrfs_delayed_data_ref *ref;
1401 ref = btrfs_delayed_node_to_data_ref(node);
1402 ref_root = ref->root;
1403 } else {
1404 BUG();
1405 }
1406
1407 if (!is_fstree(ref_root)) {
1408 /*
1409 * non-fs-trees are not being accounted
1410 */
1411 return 0;
1412 }
1413
1414 switch (node->action) {
1415 case BTRFS_ADD_DELAYED_REF:
1416 case BTRFS_ADD_DELAYED_EXTENT:
1417 sgn = 1;
Jan Schmidtfc36ed7e2013-04-24 16:57:33 +00001418 seq = btrfs_tree_mod_seq_prev(node->seq);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001419 break;
1420 case BTRFS_DROP_DELAYED_REF:
1421 sgn = -1;
Jan Schmidtfc36ed7e2013-04-24 16:57:33 +00001422 seq = node->seq;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001423 break;
1424 case BTRFS_UPDATE_DELAYED_HEAD:
1425 return 0;
1426 default:
1427 BUG();
1428 }
1429
Jan Schmidt2f232032013-04-25 16:04:51 +00001430 mutex_lock(&fs_info->qgroup_rescan_lock);
1431 if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
1432 if (fs_info->qgroup_rescan_progress.objectid <= node->bytenr) {
1433 mutex_unlock(&fs_info->qgroup_rescan_lock);
1434 return 0;
1435 }
1436 }
1437 mutex_unlock(&fs_info->qgroup_rescan_lock);
1438
Arne Jansenbed92ea2012-06-28 18:03:02 +02001439 /*
1440 * the delayed ref sequence number we pass depends on the direction of
Jan Schmidtfc36ed7e2013-04-24 16:57:33 +00001441 * the operation. for add operations, we pass
1442 * tree_mod_log_prev_seq(node->seq) to skip
Arne Jansenbed92ea2012-06-28 18:03:02 +02001443 * the delayed ref's current sequence number, because we need the state
1444 * of the tree before the add operation. for delete operations, we pass
1445 * (node->seq) to include the delayed ref's current sequence number,
1446 * because we need the state of the tree after the delete operation.
1447 */
Jan Schmidtfc36ed7e2013-04-24 16:57:33 +00001448 ret = btrfs_find_all_roots(trans, fs_info, node->bytenr, seq, &roots);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001449 if (ret < 0)
Wang Shilonga7975022013-03-25 11:08:23 +00001450 return ret;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001451
Jan Schmidt2f232032013-04-25 16:04:51 +00001452 mutex_lock(&fs_info->qgroup_rescan_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001453 spin_lock(&fs_info->qgroup_lock);
Jan Schmidt2f232032013-04-25 16:04:51 +00001454 if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
1455 if (fs_info->qgroup_rescan_progress.objectid <= node->bytenr) {
1456 ret = 0;
1457 goto unlock;
1458 }
1459 }
1460
Arne Jansenbed92ea2012-06-28 18:03:02 +02001461 quota_root = fs_info->quota_root;
1462 if (!quota_root)
1463 goto unlock;
1464
1465 qgroup = find_qgroup_rb(fs_info, ref_root);
1466 if (!qgroup)
1467 goto unlock;
1468
1469 /*
1470 * step 1: for each old ref, visit all nodes once and inc refcnt
1471 */
Wang Shilong1e8f9152013-05-06 11:03:27 +00001472 ulist_reinit(fs_info->qgroup_ulist);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001473 seq = fs_info->qgroup_seq;
1474 fs_info->qgroup_seq += roots->nnodes + 1; /* max refcnt */
1475
Wang Shilong1e8f9152013-05-06 11:03:27 +00001476 ret = qgroup_account_ref_step1(fs_info, roots, fs_info->qgroup_ulist,
1477 seq);
Jan Schmidt46b665c2013-04-25 16:04:50 +00001478 if (ret)
1479 goto unlock;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001480
1481 /*
1482 * step 2: walk from the new root
1483 */
Wang Shilong1e8f9152013-05-06 11:03:27 +00001484 ret = qgroup_account_ref_step2(fs_info, roots, fs_info->qgroup_ulist,
1485 seq, sgn, node->num_bytes, qgroup);
Jan Schmidt46b665c2013-04-25 16:04:50 +00001486 if (ret)
Wang Shilong3c971852013-04-17 14:00:36 +00001487 goto unlock;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001488
1489 /*
1490 * step 3: walk again from old refs
1491 */
Wang Shilong1e8f9152013-05-06 11:03:27 +00001492 ret = qgroup_account_ref_step3(fs_info, roots, fs_info->qgroup_ulist,
1493 seq, sgn, node->num_bytes);
Jan Schmidt46b665c2013-04-25 16:04:50 +00001494 if (ret)
1495 goto unlock;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001496
Arne Jansenbed92ea2012-06-28 18:03:02 +02001497unlock:
1498 spin_unlock(&fs_info->qgroup_lock);
Jan Schmidt2f232032013-04-25 16:04:51 +00001499 mutex_unlock(&fs_info->qgroup_rescan_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001500 ulist_free(roots);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001501
1502 return ret;
1503}
1504
1505/*
1506 * called from commit_transaction. Writes all changed qgroups to disk.
1507 */
1508int btrfs_run_qgroups(struct btrfs_trans_handle *trans,
1509 struct btrfs_fs_info *fs_info)
1510{
1511 struct btrfs_root *quota_root = fs_info->quota_root;
1512 int ret = 0;
Jan Schmidt3d7b5a22013-04-25 16:04:52 +00001513 int start_rescan_worker = 0;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001514
1515 if (!quota_root)
1516 goto out;
1517
Jan Schmidt3d7b5a22013-04-25 16:04:52 +00001518 if (!fs_info->quota_enabled && fs_info->pending_quota_state)
1519 start_rescan_worker = 1;
1520
Arne Jansenbed92ea2012-06-28 18:03:02 +02001521 fs_info->quota_enabled = fs_info->pending_quota_state;
1522
1523 spin_lock(&fs_info->qgroup_lock);
1524 while (!list_empty(&fs_info->dirty_qgroups)) {
1525 struct btrfs_qgroup *qgroup;
1526 qgroup = list_first_entry(&fs_info->dirty_qgroups,
1527 struct btrfs_qgroup, dirty);
1528 list_del_init(&qgroup->dirty);
1529 spin_unlock(&fs_info->qgroup_lock);
1530 ret = update_qgroup_info_item(trans, quota_root, qgroup);
1531 if (ret)
1532 fs_info->qgroup_flags |=
1533 BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
1534 spin_lock(&fs_info->qgroup_lock);
1535 }
1536 if (fs_info->quota_enabled)
1537 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_ON;
1538 else
1539 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
1540 spin_unlock(&fs_info->qgroup_lock);
1541
1542 ret = update_qgroup_status_item(trans, fs_info, quota_root);
1543 if (ret)
1544 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
1545
Jan Schmidt3d7b5a22013-04-25 16:04:52 +00001546 if (!ret && start_rescan_worker) {
1547 ret = btrfs_qgroup_rescan(fs_info);
1548 if (ret)
1549 pr_err("btrfs: start rescan quota failed: %d\n", ret);
1550 ret = 0;
1551 }
1552
Arne Jansenbed92ea2012-06-28 18:03:02 +02001553out:
1554
1555 return ret;
1556}
1557
1558/*
1559 * copy the acounting information between qgroups. This is necessary when a
1560 * snapshot or a subvolume is created
1561 */
1562int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
1563 struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid,
1564 struct btrfs_qgroup_inherit *inherit)
1565{
1566 int ret = 0;
1567 int i;
1568 u64 *i_qgroups;
1569 struct btrfs_root *quota_root = fs_info->quota_root;
1570 struct btrfs_qgroup *srcgroup;
1571 struct btrfs_qgroup *dstgroup;
1572 u32 level_size = 0;
Wang Shilong3f5e2d32013-04-07 10:50:19 +00001573 u64 nums;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001574
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001575 mutex_lock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001576 if (!fs_info->quota_enabled)
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001577 goto out;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001578
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001579 if (!quota_root) {
1580 ret = -EINVAL;
1581 goto out;
1582 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001583
Wang Shilong3f5e2d32013-04-07 10:50:19 +00001584 if (inherit) {
1585 i_qgroups = (u64 *)(inherit + 1);
1586 nums = inherit->num_qgroups + 2 * inherit->num_ref_copies +
1587 2 * inherit->num_excl_copies;
1588 for (i = 0; i < nums; ++i) {
1589 srcgroup = find_qgroup_rb(fs_info, *i_qgroups);
1590 if (!srcgroup) {
1591 ret = -EINVAL;
1592 goto out;
1593 }
1594 ++i_qgroups;
1595 }
1596 }
1597
Arne Jansenbed92ea2012-06-28 18:03:02 +02001598 /*
1599 * create a tracking group for the subvol itself
1600 */
1601 ret = add_qgroup_item(trans, quota_root, objectid);
1602 if (ret)
1603 goto out;
1604
1605 if (inherit && inherit->flags & BTRFS_QGROUP_INHERIT_SET_LIMITS) {
1606 ret = update_qgroup_limit_item(trans, quota_root, objectid,
1607 inherit->lim.flags,
1608 inherit->lim.max_rfer,
1609 inherit->lim.max_excl,
1610 inherit->lim.rsv_rfer,
1611 inherit->lim.rsv_excl);
1612 if (ret)
1613 goto out;
1614 }
1615
1616 if (srcid) {
1617 struct btrfs_root *srcroot;
1618 struct btrfs_key srckey;
1619 int srcroot_level;
1620
1621 srckey.objectid = srcid;
1622 srckey.type = BTRFS_ROOT_ITEM_KEY;
1623 srckey.offset = (u64)-1;
1624 srcroot = btrfs_read_fs_root_no_name(fs_info, &srckey);
1625 if (IS_ERR(srcroot)) {
1626 ret = PTR_ERR(srcroot);
1627 goto out;
1628 }
1629
1630 rcu_read_lock();
1631 srcroot_level = btrfs_header_level(srcroot->node);
1632 level_size = btrfs_level_size(srcroot, srcroot_level);
1633 rcu_read_unlock();
1634 }
1635
1636 /*
1637 * add qgroup to all inherited groups
1638 */
1639 if (inherit) {
1640 i_qgroups = (u64 *)(inherit + 1);
1641 for (i = 0; i < inherit->num_qgroups; ++i) {
1642 ret = add_qgroup_relation_item(trans, quota_root,
1643 objectid, *i_qgroups);
1644 if (ret)
1645 goto out;
1646 ret = add_qgroup_relation_item(trans, quota_root,
1647 *i_qgroups, objectid);
1648 if (ret)
1649 goto out;
1650 ++i_qgroups;
1651 }
1652 }
1653
1654
1655 spin_lock(&fs_info->qgroup_lock);
1656
1657 dstgroup = add_qgroup_rb(fs_info, objectid);
Dan Carpenter57a5a882012-07-30 02:15:43 -06001658 if (IS_ERR(dstgroup)) {
1659 ret = PTR_ERR(dstgroup);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001660 goto unlock;
Dan Carpenter57a5a882012-07-30 02:15:43 -06001661 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001662
1663 if (srcid) {
1664 srcgroup = find_qgroup_rb(fs_info, srcid);
Chris Masonf3a87f12012-09-14 20:06:30 -04001665 if (!srcgroup)
Arne Jansenbed92ea2012-06-28 18:03:02 +02001666 goto unlock;
1667 dstgroup->rfer = srcgroup->rfer - level_size;
1668 dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size;
1669 srcgroup->excl = level_size;
1670 srcgroup->excl_cmpr = level_size;
1671 qgroup_dirty(fs_info, dstgroup);
1672 qgroup_dirty(fs_info, srcgroup);
1673 }
1674
Chris Masonf3a87f12012-09-14 20:06:30 -04001675 if (!inherit)
Arne Jansenbed92ea2012-06-28 18:03:02 +02001676 goto unlock;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001677
1678 i_qgroups = (u64 *)(inherit + 1);
1679 for (i = 0; i < inherit->num_qgroups; ++i) {
1680 ret = add_relation_rb(quota_root->fs_info, objectid,
1681 *i_qgroups);
1682 if (ret)
1683 goto unlock;
1684 ++i_qgroups;
1685 }
1686
1687 for (i = 0; i < inherit->num_ref_copies; ++i) {
1688 struct btrfs_qgroup *src;
1689 struct btrfs_qgroup *dst;
1690
1691 src = find_qgroup_rb(fs_info, i_qgroups[0]);
1692 dst = find_qgroup_rb(fs_info, i_qgroups[1]);
1693
1694 if (!src || !dst) {
1695 ret = -EINVAL;
1696 goto unlock;
1697 }
1698
1699 dst->rfer = src->rfer - level_size;
1700 dst->rfer_cmpr = src->rfer_cmpr - level_size;
1701 i_qgroups += 2;
1702 }
1703 for (i = 0; i < inherit->num_excl_copies; ++i) {
1704 struct btrfs_qgroup *src;
1705 struct btrfs_qgroup *dst;
1706
1707 src = find_qgroup_rb(fs_info, i_qgroups[0]);
1708 dst = find_qgroup_rb(fs_info, i_qgroups[1]);
1709
1710 if (!src || !dst) {
1711 ret = -EINVAL;
1712 goto unlock;
1713 }
1714
1715 dst->excl = src->excl + level_size;
1716 dst->excl_cmpr = src->excl_cmpr + level_size;
1717 i_qgroups += 2;
1718 }
1719
1720unlock:
1721 spin_unlock(&fs_info->qgroup_lock);
1722out:
Wang Shilongf2f6ed32013-04-07 10:50:16 +00001723 mutex_unlock(&fs_info->qgroup_ioctl_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001724 return ret;
1725}
1726
1727/*
1728 * reserve some space for a qgroup and all its parents. The reservation takes
1729 * place with start_transaction or dealloc_reserve, similar to ENOSPC
1730 * accounting. If not enough space is available, EDQUOT is returned.
1731 * We assume that the requested space is new for all qgroups.
1732 */
1733int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
1734{
1735 struct btrfs_root *quota_root;
1736 struct btrfs_qgroup *qgroup;
1737 struct btrfs_fs_info *fs_info = root->fs_info;
1738 u64 ref_root = root->root_key.objectid;
1739 int ret = 0;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001740 struct ulist_node *unode;
1741 struct ulist_iterator uiter;
1742
1743 if (!is_fstree(ref_root))
1744 return 0;
1745
1746 if (num_bytes == 0)
1747 return 0;
1748
1749 spin_lock(&fs_info->qgroup_lock);
1750 quota_root = fs_info->quota_root;
1751 if (!quota_root)
1752 goto out;
1753
1754 qgroup = find_qgroup_rb(fs_info, ref_root);
1755 if (!qgroup)
1756 goto out;
1757
1758 /*
1759 * in a first step, we check all affected qgroups if any limits would
1760 * be exceeded
1761 */
Wang Shilong1e8f9152013-05-06 11:03:27 +00001762 ulist_reinit(fs_info->qgroup_ulist);
1763 ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
Wang Shilong3c971852013-04-17 14:00:36 +00001764 (uintptr_t)qgroup, GFP_ATOMIC);
1765 if (ret < 0)
1766 goto out;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001767 ULIST_ITER_INIT(&uiter);
Wang Shilong1e8f9152013-05-06 11:03:27 +00001768 while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
Arne Jansenbed92ea2012-06-28 18:03:02 +02001769 struct btrfs_qgroup *qg;
1770 struct btrfs_qgroup_list *glist;
1771
Jan Schmidt995e01b2012-08-13 02:52:38 -06001772 qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001773
1774 if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
Wang Shilongb4fcd6b2013-04-15 12:56:49 +00001775 qg->reserved + (s64)qg->rfer + num_bytes >
Wang Shilong720f1e22013-03-06 11:51:47 +00001776 qg->max_rfer) {
Arne Jansenbed92ea2012-06-28 18:03:02 +02001777 ret = -EDQUOT;
Wang Shilong720f1e22013-03-06 11:51:47 +00001778 goto out;
1779 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001780
1781 if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
Wang Shilongb4fcd6b2013-04-15 12:56:49 +00001782 qg->reserved + (s64)qg->excl + num_bytes >
Wang Shilong720f1e22013-03-06 11:51:47 +00001783 qg->max_excl) {
Arne Jansenbed92ea2012-06-28 18:03:02 +02001784 ret = -EDQUOT;
Wang Shilong720f1e22013-03-06 11:51:47 +00001785 goto out;
1786 }
Arne Jansenbed92ea2012-06-28 18:03:02 +02001787
1788 list_for_each_entry(glist, &qg->groups, next_group) {
Wang Shilong1e8f9152013-05-06 11:03:27 +00001789 ret = ulist_add(fs_info->qgroup_ulist,
1790 glist->group->qgroupid,
Wang Shilong3c971852013-04-17 14:00:36 +00001791 (uintptr_t)glist->group, GFP_ATOMIC);
1792 if (ret < 0)
1793 goto out;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001794 }
1795 }
Wang Shilong3c971852013-04-17 14:00:36 +00001796 ret = 0;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001797 /*
1798 * no limits exceeded, now record the reservation into all qgroups
1799 */
1800 ULIST_ITER_INIT(&uiter);
Wang Shilong1e8f9152013-05-06 11:03:27 +00001801 while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
Arne Jansenbed92ea2012-06-28 18:03:02 +02001802 struct btrfs_qgroup *qg;
1803
Jan Schmidt995e01b2012-08-13 02:52:38 -06001804 qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001805
1806 qg->reserved += num_bytes;
1807 }
1808
1809out:
1810 spin_unlock(&fs_info->qgroup_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001811 return ret;
1812}
1813
1814void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes)
1815{
1816 struct btrfs_root *quota_root;
1817 struct btrfs_qgroup *qgroup;
1818 struct btrfs_fs_info *fs_info = root->fs_info;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001819 struct ulist_node *unode;
1820 struct ulist_iterator uiter;
1821 u64 ref_root = root->root_key.objectid;
Wang Shilong3c971852013-04-17 14:00:36 +00001822 int ret = 0;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001823
1824 if (!is_fstree(ref_root))
1825 return;
1826
1827 if (num_bytes == 0)
1828 return;
1829
1830 spin_lock(&fs_info->qgroup_lock);
1831
1832 quota_root = fs_info->quota_root;
1833 if (!quota_root)
1834 goto out;
1835
1836 qgroup = find_qgroup_rb(fs_info, ref_root);
1837 if (!qgroup)
1838 goto out;
1839
Wang Shilong1e8f9152013-05-06 11:03:27 +00001840 ulist_reinit(fs_info->qgroup_ulist);
1841 ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
Wang Shilong3c971852013-04-17 14:00:36 +00001842 (uintptr_t)qgroup, GFP_ATOMIC);
1843 if (ret < 0)
1844 goto out;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001845 ULIST_ITER_INIT(&uiter);
Wang Shilong1e8f9152013-05-06 11:03:27 +00001846 while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
Arne Jansenbed92ea2012-06-28 18:03:02 +02001847 struct btrfs_qgroup *qg;
1848 struct btrfs_qgroup_list *glist;
1849
Jan Schmidt995e01b2012-08-13 02:52:38 -06001850 qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001851
1852 qg->reserved -= num_bytes;
1853
1854 list_for_each_entry(glist, &qg->groups, next_group) {
Wang Shilong1e8f9152013-05-06 11:03:27 +00001855 ret = ulist_add(fs_info->qgroup_ulist,
1856 glist->group->qgroupid,
Wang Shilong3c971852013-04-17 14:00:36 +00001857 (uintptr_t)glist->group, GFP_ATOMIC);
1858 if (ret < 0)
1859 goto out;
Arne Jansenbed92ea2012-06-28 18:03:02 +02001860 }
1861 }
1862
1863out:
1864 spin_unlock(&fs_info->qgroup_lock);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001865}
1866
1867void assert_qgroups_uptodate(struct btrfs_trans_handle *trans)
1868{
1869 if (list_empty(&trans->qgroup_ref_list) && !trans->delayed_ref_elem.seq)
1870 return;
Jan Schmidtfc36ed7e2013-04-24 16:57:33 +00001871 pr_err("btrfs: qgroups not uptodate in trans handle %p: list is%s empty, seq is %#x.%x\n",
Arne Jansenbed92ea2012-06-28 18:03:02 +02001872 trans, list_empty(&trans->qgroup_ref_list) ? "" : " not",
Jan Schmidtfc36ed7e2013-04-24 16:57:33 +00001873 (u32)(trans->delayed_ref_elem.seq >> 32),
1874 (u32)trans->delayed_ref_elem.seq);
Arne Jansenbed92ea2012-06-28 18:03:02 +02001875 BUG();
1876}
Jan Schmidt2f232032013-04-25 16:04:51 +00001877
1878/*
1879 * returns < 0 on error, 0 when more leafs are to be scanned.
1880 * returns 1 when done, 2 when done and FLAG_INCONSISTENT was cleared.
1881 */
1882static int
1883qgroup_rescan_leaf(struct qgroup_rescan *qscan, struct btrfs_path *path,
1884 struct btrfs_trans_handle *trans, struct ulist *tmp,
1885 struct extent_buffer *scratch_leaf)
1886{
1887 struct btrfs_key found;
1888 struct btrfs_fs_info *fs_info = qscan->fs_info;
1889 struct ulist *roots = NULL;
1890 struct ulist_node *unode;
1891 struct ulist_iterator uiter;
1892 struct seq_list tree_mod_seq_elem = {};
1893 u64 seq;
1894 int slot;
1895 int ret;
1896
1897 path->leave_spinning = 1;
1898 mutex_lock(&fs_info->qgroup_rescan_lock);
1899 ret = btrfs_search_slot_for_read(fs_info->extent_root,
1900 &fs_info->qgroup_rescan_progress,
1901 path, 1, 0);
1902
1903 pr_debug("current progress key (%llu %u %llu), search_slot ret %d\n",
1904 (unsigned long long)fs_info->qgroup_rescan_progress.objectid,
1905 fs_info->qgroup_rescan_progress.type,
1906 (unsigned long long)fs_info->qgroup_rescan_progress.offset,
1907 ret);
1908
1909 if (ret) {
1910 /*
1911 * The rescan is about to end, we will not be scanning any
1912 * further blocks. We cannot unset the RESCAN flag here, because
1913 * we want to commit the transaction if everything went well.
1914 * To make the live accounting work in this phase, we set our
1915 * scan progress pointer such that every real extent objectid
1916 * will be smaller.
1917 */
1918 fs_info->qgroup_rescan_progress.objectid = (u64)-1;
1919 btrfs_release_path(path);
1920 mutex_unlock(&fs_info->qgroup_rescan_lock);
1921 return ret;
1922 }
1923
1924 btrfs_item_key_to_cpu(path->nodes[0], &found,
1925 btrfs_header_nritems(path->nodes[0]) - 1);
1926 fs_info->qgroup_rescan_progress.objectid = found.objectid + 1;
1927
1928 btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1929 memcpy(scratch_leaf, path->nodes[0], sizeof(*scratch_leaf));
1930 slot = path->slots[0];
1931 btrfs_release_path(path);
1932 mutex_unlock(&fs_info->qgroup_rescan_lock);
1933
1934 for (; slot < btrfs_header_nritems(scratch_leaf); ++slot) {
1935 btrfs_item_key_to_cpu(scratch_leaf, &found, slot);
1936 if (found.type != BTRFS_EXTENT_ITEM_KEY)
1937 continue;
1938 ret = btrfs_find_all_roots(trans, fs_info, found.objectid,
1939 tree_mod_seq_elem.seq, &roots);
1940 if (ret < 0)
1941 goto out;
1942 spin_lock(&fs_info->qgroup_lock);
1943 seq = fs_info->qgroup_seq;
1944 fs_info->qgroup_seq += roots->nnodes + 1; /* max refcnt */
1945
1946 ret = qgroup_account_ref_step1(fs_info, roots, tmp, seq);
1947 if (ret) {
1948 spin_unlock(&fs_info->qgroup_lock);
1949 ulist_free(roots);
1950 goto out;
1951 }
1952
1953 /*
1954 * step2 of btrfs_qgroup_account_ref works from a single root,
1955 * we're doing all at once here.
1956 */
1957 ulist_reinit(tmp);
1958 ULIST_ITER_INIT(&uiter);
1959 while ((unode = ulist_next(roots, &uiter))) {
1960 struct btrfs_qgroup *qg;
1961
1962 qg = find_qgroup_rb(fs_info, unode->val);
1963 if (!qg)
1964 continue;
1965
1966 ret = ulist_add(tmp, qg->qgroupid, (uintptr_t)qg,
1967 GFP_ATOMIC);
1968 if (ret < 0) {
1969 spin_unlock(&fs_info->qgroup_lock);
1970 ulist_free(roots);
1971 goto out;
1972 }
1973 }
1974
1975 /* this loop is similar to step 2 of btrfs_qgroup_account_ref */
1976 ULIST_ITER_INIT(&uiter);
1977 while ((unode = ulist_next(tmp, &uiter))) {
1978 struct btrfs_qgroup *qg;
1979 struct btrfs_qgroup_list *glist;
1980
1981 qg = (struct btrfs_qgroup *)(uintptr_t) unode->aux;
1982 qg->rfer += found.offset;
1983 qg->rfer_cmpr += found.offset;
1984 WARN_ON(qg->tag >= seq);
1985 if (qg->refcnt - seq == roots->nnodes) {
1986 qg->excl += found.offset;
1987 qg->excl_cmpr += found.offset;
1988 }
1989 qgroup_dirty(fs_info, qg);
1990
1991 list_for_each_entry(glist, &qg->groups, next_group) {
1992 ret = ulist_add(tmp, glist->group->qgroupid,
1993 (uintptr_t)glist->group,
1994 GFP_ATOMIC);
1995 if (ret < 0) {
1996 spin_unlock(&fs_info->qgroup_lock);
1997 ulist_free(roots);
1998 goto out;
1999 }
2000 }
2001 }
2002
2003 spin_unlock(&fs_info->qgroup_lock);
2004 ulist_free(roots);
2005 ret = 0;
2006 }
2007
2008out:
2009 btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem);
2010
2011 return ret;
2012}
2013
2014static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
2015{
2016 struct qgroup_rescan *qscan = container_of(work, struct qgroup_rescan,
2017 work);
2018 struct btrfs_path *path;
2019 struct btrfs_trans_handle *trans = NULL;
2020 struct btrfs_fs_info *fs_info = qscan->fs_info;
2021 struct ulist *tmp = NULL;
2022 struct extent_buffer *scratch_leaf = NULL;
2023 int err = -ENOMEM;
2024
2025 path = btrfs_alloc_path();
2026 if (!path)
2027 goto out;
2028 tmp = ulist_alloc(GFP_NOFS);
2029 if (!tmp)
2030 goto out;
2031 scratch_leaf = kmalloc(sizeof(*scratch_leaf), GFP_NOFS);
2032 if (!scratch_leaf)
2033 goto out;
2034
2035 err = 0;
2036 while (!err) {
2037 trans = btrfs_start_transaction(fs_info->fs_root, 0);
2038 if (IS_ERR(trans)) {
2039 err = PTR_ERR(trans);
2040 break;
2041 }
2042 if (!fs_info->quota_enabled) {
2043 err = -EINTR;
2044 } else {
2045 err = qgroup_rescan_leaf(qscan, path, trans,
2046 tmp, scratch_leaf);
2047 }
2048 if (err > 0)
2049 btrfs_commit_transaction(trans, fs_info->fs_root);
2050 else
2051 btrfs_end_transaction(trans, fs_info->fs_root);
2052 }
2053
2054out:
2055 kfree(scratch_leaf);
2056 ulist_free(tmp);
2057 btrfs_free_path(path);
2058 kfree(qscan);
2059
2060 mutex_lock(&fs_info->qgroup_rescan_lock);
2061 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2062
2063 if (err == 2 &&
2064 fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) {
2065 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
2066 } else if (err < 0) {
2067 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
2068 }
2069 mutex_unlock(&fs_info->qgroup_rescan_lock);
2070
2071 if (err >= 0) {
2072 pr_info("btrfs: qgroup scan completed%s\n",
2073 err == 2 ? " (inconsistency flag cleared)" : "");
2074 } else {
2075 pr_err("btrfs: qgroup scan failed with %d\n", err);
2076 }
Jan Schmidt57254b6e2013-05-06 19:14:17 +00002077
2078 complete_all(&fs_info->qgroup_rescan_completion);
Jan Schmidt2f232032013-04-25 16:04:51 +00002079}
2080
2081static void
2082qgroup_rescan_start(struct btrfs_fs_info *fs_info, struct qgroup_rescan *qscan)
2083{
2084 memset(&qscan->work, 0, sizeof(qscan->work));
2085 qscan->work.func = btrfs_qgroup_rescan_worker;
2086 qscan->fs_info = fs_info;
2087
2088 pr_info("btrfs: qgroup scan started\n");
2089 btrfs_queue_worker(&fs_info->qgroup_rescan_workers, &qscan->work);
2090}
2091
2092int
2093btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
2094{
2095 int ret = 0;
2096 struct rb_node *n;
2097 struct btrfs_qgroup *qgroup;
2098 struct qgroup_rescan *qscan = kmalloc(sizeof(*qscan), GFP_NOFS);
2099
2100 if (!qscan)
2101 return -ENOMEM;
2102
2103 mutex_lock(&fs_info->qgroup_rescan_lock);
2104 spin_lock(&fs_info->qgroup_lock);
2105 if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN)
2106 ret = -EINPROGRESS;
2107 else if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON))
2108 ret = -EINVAL;
2109 if (ret) {
2110 spin_unlock(&fs_info->qgroup_lock);
2111 mutex_unlock(&fs_info->qgroup_rescan_lock);
2112 kfree(qscan);
2113 return ret;
2114 }
2115
2116 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2117 memset(&fs_info->qgroup_rescan_progress, 0,
2118 sizeof(fs_info->qgroup_rescan_progress));
Jan Schmidt57254b6e2013-05-06 19:14:17 +00002119 init_completion(&fs_info->qgroup_rescan_completion);
Jan Schmidt2f232032013-04-25 16:04:51 +00002120
2121 /* clear all current qgroup tracking information */
2122 for (n = rb_first(&fs_info->qgroup_tree); n; n = rb_next(n)) {
2123 qgroup = rb_entry(n, struct btrfs_qgroup, node);
2124 qgroup->rfer = 0;
2125 qgroup->rfer_cmpr = 0;
2126 qgroup->excl = 0;
2127 qgroup->excl_cmpr = 0;
2128 }
2129 spin_unlock(&fs_info->qgroup_lock);
2130 mutex_unlock(&fs_info->qgroup_rescan_lock);
2131
2132 qgroup_rescan_start(fs_info, qscan);
2133
2134 return 0;
2135}
Jan Schmidt57254b6e2013-05-06 19:14:17 +00002136
2137int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info)
2138{
2139 int running;
2140 int ret = 0;
2141
2142 mutex_lock(&fs_info->qgroup_rescan_lock);
2143 spin_lock(&fs_info->qgroup_lock);
2144 running = fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2145 spin_unlock(&fs_info->qgroup_lock);
2146 mutex_unlock(&fs_info->qgroup_rescan_lock);
2147
2148 if (running)
2149 ret = wait_for_completion_interruptible(
2150 &fs_info->qgroup_rescan_completion);
2151
2152 return ret;
2153}