Branch data Line data Source code
1 : : /*
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>
26 : : #include <linux/btrfs.h>
27 : :
28 : : #include "ctree.h"
29 : : #include "transaction.h"
30 : : #include "disk-io.h"
31 : : #include "locking.h"
32 : : #include "ulist.h"
33 : : #include "backref.h"
34 : : #include "extent_io.h"
35 : :
36 : : /* TODO XXX FIXME
37 : : * - subvol delete -> delete when ref goes to 0? delete limits also?
38 : : * - reorganize keys
39 : : * - compressed
40 : : * - sync
41 : : * - 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 : : */
51 : : struct 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 : : */
94 : : struct 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 : :
101 : : static int
102 : : qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
103 : : int init_flags);
104 : : static void qgroup_rescan_zero_tracking(struct btrfs_fs_info *fs_info);
105 : :
106 : : /* must be called with qgroup_ioctl_lock held */
107 : : static struct btrfs_qgroup *find_qgroup_rb(struct btrfs_fs_info *fs_info,
108 : : u64 qgroupid)
109 : : {
110 : : struct rb_node *n = fs_info->qgroup_tree.rb_node;
111 : : struct btrfs_qgroup *qgroup;
112 : :
113 [ # # ][ # # ]: 0 : while (n) {
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
114 : 0 : qgroup = rb_entry(n, struct btrfs_qgroup, node);
115 [ # # ][ # # ]: 0 : if (qgroup->qgroupid < qgroupid)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
116 : 0 : n = n->rb_left;
117 [ # # ][ # # ]: 0 : else if (qgroup->qgroupid > qgroupid)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
118 : 0 : n = n->rb_right;
119 : : else
120 : : return qgroup;
121 : : }
122 : : return NULL;
123 : : }
124 : :
125 : : /* must be called with qgroup_lock held */
126 : 0 : static struct btrfs_qgroup *add_qgroup_rb(struct btrfs_fs_info *fs_info,
127 : : u64 qgroupid)
128 : : {
129 : 0 : struct rb_node **p = &fs_info->qgroup_tree.rb_node;
130 : : struct rb_node *parent = NULL;
131 : : struct btrfs_qgroup *qgroup;
132 : :
133 [ # # ]: 0 : while (*p) {
134 : : parent = *p;
135 : 0 : qgroup = rb_entry(parent, struct btrfs_qgroup, node);
136 : :
137 [ # # ]: 0 : if (qgroup->qgroupid < qgroupid)
138 : 0 : p = &(*p)->rb_left;
139 [ # # ]: 0 : else if (qgroup->qgroupid > qgroupid)
140 : 0 : p = &(*p)->rb_right;
141 : : else
142 : : return qgroup;
143 : : }
144 : :
145 : : qgroup = kzalloc(sizeof(*qgroup), GFP_ATOMIC);
146 [ # # ]: 0 : if (!qgroup)
147 : : return ERR_PTR(-ENOMEM);
148 : :
149 : 0 : qgroup->qgroupid = qgroupid;
150 : 0 : INIT_LIST_HEAD(&qgroup->groups);
151 : 0 : INIT_LIST_HEAD(&qgroup->members);
152 : 0 : INIT_LIST_HEAD(&qgroup->dirty);
153 : :
154 : 0 : rb_link_node(&qgroup->node, parent, p);
155 : 0 : rb_insert_color(&qgroup->node, &fs_info->qgroup_tree);
156 : :
157 : 0 : return qgroup;
158 : : }
159 : :
160 : 0 : static void __del_qgroup_rb(struct btrfs_qgroup *qgroup)
161 : : {
162 : : struct btrfs_qgroup_list *list;
163 : :
164 : : list_del(&qgroup->dirty);
165 [ # # ]: 0 : while (!list_empty(&qgroup->groups)) {
166 : : list = list_first_entry(&qgroup->groups,
167 : : struct btrfs_qgroup_list, next_group);
168 : : list_del(&list->next_group);
169 : : list_del(&list->next_member);
170 : 0 : kfree(list);
171 : : }
172 : :
173 [ # # ]: 0 : while (!list_empty(&qgroup->members)) {
174 : 0 : list = list_first_entry(&qgroup->members,
175 : : struct btrfs_qgroup_list, next_member);
176 : : list_del(&list->next_group);
177 : : list_del(&list->next_member);
178 : 0 : kfree(list);
179 : : }
180 : 0 : kfree(qgroup);
181 : 0 : }
182 : :
183 : : /* must be called with qgroup_lock held */
184 : 0 : static int del_qgroup_rb(struct btrfs_fs_info *fs_info, u64 qgroupid)
185 : : {
186 : : struct btrfs_qgroup *qgroup = find_qgroup_rb(fs_info, qgroupid);
187 : :
188 [ # # ]: 0 : if (!qgroup)
189 : : return -ENOENT;
190 : :
191 : 0 : rb_erase(&qgroup->node, &fs_info->qgroup_tree);
192 : 0 : __del_qgroup_rb(qgroup);
193 : 0 : return 0;
194 : : }
195 : :
196 : : /* must be called with qgroup_lock held */
197 : 0 : static int add_relation_rb(struct btrfs_fs_info *fs_info,
198 : : u64 memberid, u64 parentid)
199 : : {
200 : : struct btrfs_qgroup *member;
201 : : struct btrfs_qgroup *parent;
202 : : struct btrfs_qgroup_list *list;
203 : :
204 : : member = find_qgroup_rb(fs_info, memberid);
205 : : parent = find_qgroup_rb(fs_info, parentid);
206 [ # # ]: 0 : if (!member || !parent)
207 : : return -ENOENT;
208 : :
209 : : list = kzalloc(sizeof(*list), GFP_ATOMIC);
210 [ # # ]: 0 : if (!list)
211 : : return -ENOMEM;
212 : :
213 : 0 : list->group = parent;
214 : 0 : list->member = member;
215 : 0 : list_add_tail(&list->next_group, &member->groups);
216 : 0 : list_add_tail(&list->next_member, &parent->members);
217 : :
218 : 0 : return 0;
219 : : }
220 : :
221 : : /* must be called with qgroup_lock held */
222 : 0 : static int del_relation_rb(struct btrfs_fs_info *fs_info,
223 : : u64 memberid, u64 parentid)
224 : : {
225 : : struct btrfs_qgroup *member;
226 : : struct btrfs_qgroup *parent;
227 : : struct btrfs_qgroup_list *list;
228 : :
229 : : member = find_qgroup_rb(fs_info, memberid);
230 : : parent = find_qgroup_rb(fs_info, parentid);
231 [ # # ]: 0 : if (!member || !parent)
232 : : return -ENOENT;
233 : :
234 [ # # ]: 0 : list_for_each_entry(list, &member->groups, next_group) {
235 [ # # ]: 0 : if (list->group == parent) {
236 : : list_del(&list->next_group);
237 : : list_del(&list->next_member);
238 : 0 : kfree(list);
239 : 0 : return 0;
240 : : }
241 : : }
242 : : return -ENOENT;
243 : : }
244 : :
245 : : /*
246 : : * The full config is read in one go, only called from open_ctree()
247 : : * It doesn't use any locking, as at this point we're still single-threaded
248 : : */
249 : 0 : int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
250 : : {
251 : : struct btrfs_key key;
252 : : struct btrfs_key found_key;
253 : 0 : struct btrfs_root *quota_root = fs_info->quota_root;
254 : : struct btrfs_path *path = NULL;
255 : : struct extent_buffer *l;
256 : : int slot;
257 : : int ret = 0;
258 : : u64 flags = 0;
259 : : u64 rescan_progress = 0;
260 : :
261 [ # # ]: 0 : if (!fs_info->quota_enabled)
262 : : return 0;
263 : :
264 : 0 : fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS);
265 [ # # ]: 0 : if (!fs_info->qgroup_ulist) {
266 : : ret = -ENOMEM;
267 : : goto out;
268 : : }
269 : :
270 : 0 : path = btrfs_alloc_path();
271 [ # # ]: 0 : if (!path) {
272 : : ret = -ENOMEM;
273 : : goto out;
274 : : }
275 : :
276 : : /* default this to quota off, in case no status key is found */
277 : 0 : fs_info->qgroup_flags = 0;
278 : :
279 : : /*
280 : : * pass 1: read status, all qgroup infos and limits
281 : : */
282 : 0 : key.objectid = 0;
283 : 0 : key.type = 0;
284 : 0 : key.offset = 0;
285 : 0 : ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 1);
286 [ # # ]: 0 : if (ret)
287 : : goto out;
288 : :
289 : : while (1) {
290 : : struct btrfs_qgroup *qgroup;
291 : :
292 : 0 : slot = path->slots[0];
293 : 0 : l = path->nodes[0];
294 : : btrfs_item_key_to_cpu(l, &found_key, slot);
295 : :
296 [ # # ]: 0 : if (found_key.type == BTRFS_QGROUP_STATUS_KEY) {
297 : : struct btrfs_qgroup_status_item *ptr;
298 : :
299 : 0 : ptr = btrfs_item_ptr(l, slot,
300 : : struct btrfs_qgroup_status_item);
301 : :
302 [ # # ]: 0 : if (btrfs_qgroup_status_version(l, ptr) !=
303 : : BTRFS_QGROUP_STATUS_VERSION) {
304 : 0 : btrfs_err(fs_info,
305 : : "old qgroup version, quota disabled");
306 : 0 : goto out;
307 : : }
308 [ # # ]: 0 : if (btrfs_qgroup_status_generation(l, ptr) !=
309 : 0 : fs_info->generation) {
310 : : flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
311 : 0 : btrfs_err(fs_info,
312 : : "qgroup generation mismatch, "
313 : : "marked as inconsistent");
314 : : }
315 : 0 : fs_info->qgroup_flags = btrfs_qgroup_status_flags(l,
316 : : ptr);
317 : : rescan_progress = btrfs_qgroup_status_rescan(l, ptr);
318 : 0 : goto next1;
319 : : }
320 : :
321 [ # # ]: 0 : if (found_key.type != BTRFS_QGROUP_INFO_KEY &&
322 : : found_key.type != BTRFS_QGROUP_LIMIT_KEY)
323 : : goto next1;
324 : :
325 : : qgroup = find_qgroup_rb(fs_info, found_key.offset);
326 [ # # ][ # # ]: 0 : if ((qgroup && found_key.type == BTRFS_QGROUP_INFO_KEY) ||
[ # # ]
327 [ # # ]: 0 : (!qgroup && found_key.type == BTRFS_QGROUP_LIMIT_KEY)) {
328 : 0 : btrfs_err(fs_info, "inconsitent qgroup config");
329 : : flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
330 : : }
331 [ # # ]: 0 : if (!qgroup) {
332 : 0 : qgroup = add_qgroup_rb(fs_info, found_key.offset);
333 [ # # ]: 0 : if (IS_ERR(qgroup)) {
334 : : ret = PTR_ERR(qgroup);
335 : 0 : goto out;
336 : : }
337 : : }
338 [ # # # ]: 0 : switch (found_key.type) {
339 : : case BTRFS_QGROUP_INFO_KEY: {
340 : : struct btrfs_qgroup_info_item *ptr;
341 : :
342 : 0 : ptr = btrfs_item_ptr(l, slot,
343 : : struct btrfs_qgroup_info_item);
344 : 0 : qgroup->rfer = btrfs_qgroup_info_rfer(l, ptr);
345 : 0 : qgroup->rfer_cmpr = btrfs_qgroup_info_rfer_cmpr(l, ptr);
346 : 0 : qgroup->excl = btrfs_qgroup_info_excl(l, ptr);
347 : 0 : qgroup->excl_cmpr = btrfs_qgroup_info_excl_cmpr(l, ptr);
348 : : /* generation currently unused */
349 : 0 : break;
350 : : }
351 : : case BTRFS_QGROUP_LIMIT_KEY: {
352 : : struct btrfs_qgroup_limit_item *ptr;
353 : :
354 : 0 : ptr = btrfs_item_ptr(l, slot,
355 : : struct btrfs_qgroup_limit_item);
356 : 0 : qgroup->lim_flags = btrfs_qgroup_limit_flags(l, ptr);
357 : 0 : qgroup->max_rfer = btrfs_qgroup_limit_max_rfer(l, ptr);
358 : 0 : qgroup->max_excl = btrfs_qgroup_limit_max_excl(l, ptr);
359 : 0 : qgroup->rsv_rfer = btrfs_qgroup_limit_rsv_rfer(l, ptr);
360 : 0 : qgroup->rsv_excl = btrfs_qgroup_limit_rsv_excl(l, ptr);
361 : 0 : break;
362 : : }
363 : : }
364 : : next1:
365 : : ret = btrfs_next_item(quota_root, path);
366 [ # # ]: 0 : if (ret < 0)
367 : : goto out;
368 [ # # ]: 0 : if (ret)
369 : : break;
370 : : }
371 : 0 : btrfs_release_path(path);
372 : :
373 : : /*
374 : : * pass 2: read all qgroup relations
375 : : */
376 : 0 : key.objectid = 0;
377 : 0 : key.type = BTRFS_QGROUP_RELATION_KEY;
378 : 0 : key.offset = 0;
379 : 0 : ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 0);
380 [ # # ]: 0 : if (ret)
381 : : goto out;
382 : : while (1) {
383 : 0 : slot = path->slots[0];
384 : 0 : l = path->nodes[0];
385 : : btrfs_item_key_to_cpu(l, &found_key, slot);
386 : :
387 [ # # ]: 0 : if (found_key.type != BTRFS_QGROUP_RELATION_KEY)
388 : : goto next2;
389 : :
390 [ # # ]: 0 : if (found_key.objectid > found_key.offset) {
391 : : /* parent <- member, not needed to build config */
392 : : /* FIXME should we omit the key completely? */
393 : : goto next2;
394 : : }
395 : :
396 : 0 : ret = add_relation_rb(fs_info, found_key.objectid,
397 : : found_key.offset);
398 [ # # ]: 0 : if (ret == -ENOENT) {
399 : 0 : btrfs_warn(fs_info,
400 : : "orphan qgroup relation 0x%llx->0x%llx",
401 : : found_key.objectid, found_key.offset);
402 : : ret = 0; /* ignore the error */
403 : : }
404 [ # # ]: 0 : if (ret)
405 : : goto out;
406 : : next2:
407 : : ret = btrfs_next_item(quota_root, path);
408 [ # # ]: 0 : if (ret < 0)
409 : : goto out;
410 [ # # ]: 0 : if (ret)
411 : : break;
412 : : }
413 : : out:
414 : 0 : fs_info->qgroup_flags |= flags;
415 [ # # ]: 0 : if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON)) {
416 : 0 : fs_info->quota_enabled = 0;
417 : 0 : fs_info->pending_quota_state = 0;
418 [ # # ][ # # ]: 0 : } else if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN &&
419 : : ret >= 0) {
420 : 0 : ret = qgroup_rescan_init(fs_info, rescan_progress, 0);
421 : : }
422 : 0 : btrfs_free_path(path);
423 : :
424 [ # # ]: 0 : if (ret < 0) {
425 : 0 : ulist_free(fs_info->qgroup_ulist);
426 : 0 : fs_info->qgroup_ulist = NULL;
427 : 0 : fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
428 : : }
429 : :
430 : 0 : return ret < 0 ? ret : 0;
431 : : }
432 : :
433 : : /*
434 : : * This is called from close_ctree() or open_ctree() or btrfs_quota_disable(),
435 : : * first two are in single-threaded paths.And for the third one, we have set
436 : : * quota_root to be null with qgroup_lock held before, so it is safe to clean
437 : : * up the in-memory structures without qgroup_lock held.
438 : : */
439 : 0 : void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info)
440 : : {
441 : : struct rb_node *n;
442 : : struct btrfs_qgroup *qgroup;
443 : :
444 [ # # ]: 0 : while ((n = rb_first(&fs_info->qgroup_tree))) {
445 : 0 : qgroup = rb_entry(n, struct btrfs_qgroup, node);
446 : 0 : rb_erase(n, &fs_info->qgroup_tree);
447 : 0 : __del_qgroup_rb(qgroup);
448 : : }
449 : : /*
450 : : * we call btrfs_free_qgroup_config() when umounting
451 : : * filesystem and disabling quota, so we set qgroup_ulit
452 : : * to be null here to avoid double free.
453 : : */
454 : 0 : ulist_free(fs_info->qgroup_ulist);
455 : 0 : fs_info->qgroup_ulist = NULL;
456 : 0 : }
457 : :
458 : 0 : static int add_qgroup_relation_item(struct btrfs_trans_handle *trans,
459 : : struct btrfs_root *quota_root,
460 : : u64 src, u64 dst)
461 : : {
462 : : int ret;
463 : : struct btrfs_path *path;
464 : : struct btrfs_key key;
465 : :
466 : 0 : path = btrfs_alloc_path();
467 [ # # ]: 0 : if (!path)
468 : : return -ENOMEM;
469 : :
470 : 0 : key.objectid = src;
471 : 0 : key.type = BTRFS_QGROUP_RELATION_KEY;
472 : 0 : key.offset = dst;
473 : :
474 : : ret = btrfs_insert_empty_item(trans, quota_root, path, &key, 0);
475 : :
476 : 0 : btrfs_mark_buffer_dirty(path->nodes[0]);
477 : :
478 : 0 : btrfs_free_path(path);
479 : 0 : return ret;
480 : : }
481 : :
482 : 0 : static int del_qgroup_relation_item(struct btrfs_trans_handle *trans,
483 : : struct btrfs_root *quota_root,
484 : : u64 src, u64 dst)
485 : : {
486 : : int ret;
487 : : struct btrfs_path *path;
488 : : struct btrfs_key key;
489 : :
490 : 0 : path = btrfs_alloc_path();
491 [ # # ]: 0 : if (!path)
492 : : return -ENOMEM;
493 : :
494 : 0 : key.objectid = src;
495 : 0 : key.type = BTRFS_QGROUP_RELATION_KEY;
496 : 0 : key.offset = dst;
497 : :
498 : 0 : ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
499 [ # # ]: 0 : if (ret < 0)
500 : : goto out;
501 : :
502 [ # # ]: 0 : if (ret > 0) {
503 : : ret = -ENOENT;
504 : : goto out;
505 : : }
506 : :
507 : : ret = btrfs_del_item(trans, quota_root, path);
508 : : out:
509 : 0 : btrfs_free_path(path);
510 : 0 : return ret;
511 : : }
512 : :
513 : 0 : static int add_qgroup_item(struct btrfs_trans_handle *trans,
514 : : struct btrfs_root *quota_root, u64 qgroupid)
515 : : {
516 : : int ret;
517 : : struct btrfs_path *path;
518 : : struct btrfs_qgroup_info_item *qgroup_info;
519 : : struct btrfs_qgroup_limit_item *qgroup_limit;
520 : : struct extent_buffer *leaf;
521 : : struct btrfs_key key;
522 : :
523 : 0 : path = btrfs_alloc_path();
524 [ # # ]: 0 : if (!path)
525 : : return -ENOMEM;
526 : :
527 : 0 : key.objectid = 0;
528 : 0 : key.type = BTRFS_QGROUP_INFO_KEY;
529 : 0 : key.offset = qgroupid;
530 : :
531 : : ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
532 : : sizeof(*qgroup_info));
533 [ # # ]: 0 : if (ret)
534 : : goto out;
535 : :
536 : 0 : leaf = path->nodes[0];
537 : 0 : qgroup_info = btrfs_item_ptr(leaf, path->slots[0],
538 : : struct btrfs_qgroup_info_item);
539 : 0 : btrfs_set_qgroup_info_generation(leaf, qgroup_info, trans->transid);
540 : : btrfs_set_qgroup_info_rfer(leaf, qgroup_info, 0);
541 : : btrfs_set_qgroup_info_rfer_cmpr(leaf, qgroup_info, 0);
542 : : btrfs_set_qgroup_info_excl(leaf, qgroup_info, 0);
543 : : btrfs_set_qgroup_info_excl_cmpr(leaf, qgroup_info, 0);
544 : :
545 : 0 : btrfs_mark_buffer_dirty(leaf);
546 : :
547 : 0 : btrfs_release_path(path);
548 : :
549 : 0 : key.type = BTRFS_QGROUP_LIMIT_KEY;
550 : : ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
551 : : sizeof(*qgroup_limit));
552 [ # # ]: 0 : if (ret)
553 : : goto out;
554 : :
555 : 0 : leaf = path->nodes[0];
556 : 0 : qgroup_limit = btrfs_item_ptr(leaf, path->slots[0],
557 : : struct btrfs_qgroup_limit_item);
558 : : btrfs_set_qgroup_limit_flags(leaf, qgroup_limit, 0);
559 : : btrfs_set_qgroup_limit_max_rfer(leaf, qgroup_limit, 0);
560 : : btrfs_set_qgroup_limit_max_excl(leaf, qgroup_limit, 0);
561 : : btrfs_set_qgroup_limit_rsv_rfer(leaf, qgroup_limit, 0);
562 : : btrfs_set_qgroup_limit_rsv_excl(leaf, qgroup_limit, 0);
563 : :
564 : 0 : btrfs_mark_buffer_dirty(leaf);
565 : :
566 : : ret = 0;
567 : : out:
568 : 0 : btrfs_free_path(path);
569 : 0 : return ret;
570 : : }
571 : :
572 : 0 : static int del_qgroup_item(struct btrfs_trans_handle *trans,
573 : : struct btrfs_root *quota_root, u64 qgroupid)
574 : : {
575 : : int ret;
576 : : struct btrfs_path *path;
577 : : struct btrfs_key key;
578 : :
579 : 0 : path = btrfs_alloc_path();
580 [ # # ]: 0 : if (!path)
581 : : return -ENOMEM;
582 : :
583 : 0 : key.objectid = 0;
584 : 0 : key.type = BTRFS_QGROUP_INFO_KEY;
585 : 0 : key.offset = qgroupid;
586 : 0 : ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
587 [ # # ]: 0 : if (ret < 0)
588 : : goto out;
589 : :
590 [ # # ]: 0 : if (ret > 0) {
591 : : ret = -ENOENT;
592 : : goto out;
593 : : }
594 : :
595 : : ret = btrfs_del_item(trans, quota_root, path);
596 [ # # ]: 0 : if (ret)
597 : : goto out;
598 : :
599 : 0 : btrfs_release_path(path);
600 : :
601 : 0 : key.type = BTRFS_QGROUP_LIMIT_KEY;
602 : 0 : ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
603 [ # # ]: 0 : if (ret < 0)
604 : : goto out;
605 : :
606 [ # # ]: 0 : if (ret > 0) {
607 : : ret = -ENOENT;
608 : : goto out;
609 : : }
610 : :
611 : : ret = btrfs_del_item(trans, quota_root, path);
612 : :
613 : : out:
614 : 0 : btrfs_free_path(path);
615 : 0 : return ret;
616 : : }
617 : :
618 : 0 : static int update_qgroup_limit_item(struct btrfs_trans_handle *trans,
619 : : struct btrfs_root *root, u64 qgroupid,
620 : : u64 flags, u64 max_rfer, u64 max_excl,
621 : : u64 rsv_rfer, u64 rsv_excl)
622 : : {
623 : : struct btrfs_path *path;
624 : : struct btrfs_key key;
625 : : struct extent_buffer *l;
626 : : struct btrfs_qgroup_limit_item *qgroup_limit;
627 : : int ret;
628 : : int slot;
629 : :
630 : 0 : key.objectid = 0;
631 : 0 : key.type = BTRFS_QGROUP_LIMIT_KEY;
632 : 0 : key.offset = qgroupid;
633 : :
634 : 0 : path = btrfs_alloc_path();
635 [ # # ]: 0 : if (!path)
636 : : return -ENOMEM;
637 : :
638 : 0 : ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
639 [ # # ]: 0 : if (ret > 0)
640 : : ret = -ENOENT;
641 : :
642 [ # # ]: 0 : if (ret)
643 : : goto out;
644 : :
645 : 0 : l = path->nodes[0];
646 : 0 : slot = path->slots[0];
647 : 0 : qgroup_limit = btrfs_item_ptr(l, slot, struct btrfs_qgroup_limit_item);
648 : : btrfs_set_qgroup_limit_flags(l, qgroup_limit, flags);
649 : : btrfs_set_qgroup_limit_max_rfer(l, qgroup_limit, max_rfer);
650 : : btrfs_set_qgroup_limit_max_excl(l, qgroup_limit, max_excl);
651 : : btrfs_set_qgroup_limit_rsv_rfer(l, qgroup_limit, rsv_rfer);
652 : : btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, rsv_excl);
653 : :
654 : 0 : btrfs_mark_buffer_dirty(l);
655 : :
656 : : out:
657 : 0 : btrfs_free_path(path);
658 : 0 : return ret;
659 : : }
660 : :
661 : 0 : static int update_qgroup_info_item(struct btrfs_trans_handle *trans,
662 : : struct btrfs_root *root,
663 : : struct btrfs_qgroup *qgroup)
664 : : {
665 : : struct btrfs_path *path;
666 : : struct btrfs_key key;
667 : : struct extent_buffer *l;
668 : : struct btrfs_qgroup_info_item *qgroup_info;
669 : : int ret;
670 : : int slot;
671 : :
672 : 0 : key.objectid = 0;
673 : 0 : key.type = BTRFS_QGROUP_INFO_KEY;
674 : 0 : key.offset = qgroup->qgroupid;
675 : :
676 : 0 : path = btrfs_alloc_path();
677 [ # # ]: 0 : if (!path)
678 : : return -ENOMEM;
679 : :
680 : 0 : ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
681 [ # # ]: 0 : if (ret > 0)
682 : : ret = -ENOENT;
683 : :
684 [ # # ]: 0 : if (ret)
685 : : goto out;
686 : :
687 : 0 : l = path->nodes[0];
688 : 0 : slot = path->slots[0];
689 : 0 : qgroup_info = btrfs_item_ptr(l, slot, struct btrfs_qgroup_info_item);
690 : 0 : btrfs_set_qgroup_info_generation(l, qgroup_info, trans->transid);
691 : 0 : btrfs_set_qgroup_info_rfer(l, qgroup_info, qgroup->rfer);
692 : 0 : btrfs_set_qgroup_info_rfer_cmpr(l, qgroup_info, qgroup->rfer_cmpr);
693 : 0 : btrfs_set_qgroup_info_excl(l, qgroup_info, qgroup->excl);
694 : 0 : btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, qgroup->excl_cmpr);
695 : :
696 : 0 : btrfs_mark_buffer_dirty(l);
697 : :
698 : : out:
699 : 0 : btrfs_free_path(path);
700 : 0 : return ret;
701 : : }
702 : :
703 : 0 : static int update_qgroup_status_item(struct btrfs_trans_handle *trans,
704 : : struct btrfs_fs_info *fs_info,
705 : : struct btrfs_root *root)
706 : : {
707 : : struct btrfs_path *path;
708 : : struct btrfs_key key;
709 : : struct extent_buffer *l;
710 : : struct btrfs_qgroup_status_item *ptr;
711 : : int ret;
712 : : int slot;
713 : :
714 : 0 : key.objectid = 0;
715 : 0 : key.type = BTRFS_QGROUP_STATUS_KEY;
716 : 0 : key.offset = 0;
717 : :
718 : 0 : path = btrfs_alloc_path();
719 [ # # ]: 0 : if (!path)
720 : : return -ENOMEM;
721 : :
722 : 0 : ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
723 [ # # ]: 0 : if (ret > 0)
724 : : ret = -ENOENT;
725 : :
726 [ # # ]: 0 : if (ret)
727 : : goto out;
728 : :
729 : 0 : l = path->nodes[0];
730 : 0 : slot = path->slots[0];
731 : 0 : ptr = btrfs_item_ptr(l, slot, struct btrfs_qgroup_status_item);
732 : 0 : btrfs_set_qgroup_status_flags(l, ptr, fs_info->qgroup_flags);
733 : 0 : btrfs_set_qgroup_status_generation(l, ptr, trans->transid);
734 : 0 : btrfs_set_qgroup_status_rescan(l, ptr,
735 : : fs_info->qgroup_rescan_progress.objectid);
736 : :
737 : 0 : btrfs_mark_buffer_dirty(l);
738 : :
739 : : out:
740 : 0 : btrfs_free_path(path);
741 : : return ret;
742 : : }
743 : :
744 : : /*
745 : : * called with qgroup_lock held
746 : : */
747 : 0 : static int btrfs_clean_quota_tree(struct btrfs_trans_handle *trans,
748 : : struct btrfs_root *root)
749 : : {
750 : : struct btrfs_path *path;
751 : : struct btrfs_key key;
752 : 0 : struct extent_buffer *leaf = NULL;
753 : : int ret;
754 : : int nr = 0;
755 : :
756 : 0 : path = btrfs_alloc_path();
757 [ # # ]: 0 : if (!path)
758 : : return -ENOMEM;
759 : :
760 : 0 : path->leave_spinning = 1;
761 : :
762 : 0 : key.objectid = 0;
763 : 0 : key.offset = 0;
764 : 0 : key.type = 0;
765 : :
766 : : while (1) {
767 : 0 : ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
768 [ # # ]: 0 : if (ret < 0)
769 : : goto out;
770 : 0 : leaf = path->nodes[0];
771 : 0 : nr = btrfs_header_nritems(leaf);
772 [ # # ]: 0 : if (!nr)
773 : : break;
774 : : /*
775 : : * delete the leaf one by one
776 : : * since the whole tree is going
777 : : * to be deleted.
778 : : */
779 : 0 : path->slots[0] = 0;
780 : 0 : ret = btrfs_del_items(trans, root, path, 0, nr);
781 [ # # ]: 0 : if (ret)
782 : : goto out;
783 : :
784 : 0 : btrfs_release_path(path);
785 : 0 : }
786 : : ret = 0;
787 : : out:
788 : 0 : root->fs_info->pending_quota_state = 0;
789 : 0 : btrfs_free_path(path);
790 : 0 : return ret;
791 : : }
792 : :
793 : 0 : int btrfs_quota_enable(struct btrfs_trans_handle *trans,
794 : : struct btrfs_fs_info *fs_info)
795 : : {
796 : : struct btrfs_root *quota_root;
797 : 0 : struct btrfs_root *tree_root = fs_info->tree_root;
798 : : struct btrfs_path *path = NULL;
799 : : struct btrfs_qgroup_status_item *ptr;
800 : : struct extent_buffer *leaf;
801 : : struct btrfs_key key;
802 : : struct btrfs_key found_key;
803 : : struct btrfs_qgroup *qgroup = NULL;
804 : : int ret = 0;
805 : : int slot;
806 : :
807 : 0 : mutex_lock(&fs_info->qgroup_ioctl_lock);
808 [ # # ]: 0 : if (fs_info->quota_root) {
809 : 0 : fs_info->pending_quota_state = 1;
810 : 0 : goto out;
811 : : }
812 : :
813 : 0 : fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS);
814 [ # # ]: 0 : if (!fs_info->qgroup_ulist) {
815 : : ret = -ENOMEM;
816 : : goto out;
817 : : }
818 : :
819 : : /*
820 : : * initially create the quota tree
821 : : */
822 : 0 : quota_root = btrfs_create_tree(trans, fs_info,
823 : : BTRFS_QUOTA_TREE_OBJECTID);
824 [ # # ]: 0 : if (IS_ERR(quota_root)) {
825 : : ret = PTR_ERR(quota_root);
826 : 0 : goto out;
827 : : }
828 : :
829 : 0 : path = btrfs_alloc_path();
830 [ # # ]: 0 : if (!path) {
831 : : ret = -ENOMEM;
832 : : goto out_free_root;
833 : : }
834 : :
835 : 0 : key.objectid = 0;
836 : 0 : key.type = BTRFS_QGROUP_STATUS_KEY;
837 : 0 : key.offset = 0;
838 : :
839 : : ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
840 : : sizeof(*ptr));
841 [ # # ]: 0 : if (ret)
842 : : goto out_free_path;
843 : :
844 : 0 : leaf = path->nodes[0];
845 : 0 : ptr = btrfs_item_ptr(leaf, path->slots[0],
846 : : struct btrfs_qgroup_status_item);
847 : 0 : btrfs_set_qgroup_status_generation(leaf, ptr, trans->transid);
848 : : btrfs_set_qgroup_status_version(leaf, ptr, BTRFS_QGROUP_STATUS_VERSION);
849 : 0 : fs_info->qgroup_flags = BTRFS_QGROUP_STATUS_FLAG_ON |
850 : : BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
851 : : btrfs_set_qgroup_status_flags(leaf, ptr, fs_info->qgroup_flags);
852 : : btrfs_set_qgroup_status_rescan(leaf, ptr, 0);
853 : :
854 : 0 : btrfs_mark_buffer_dirty(leaf);
855 : :
856 : 0 : key.objectid = 0;
857 : 0 : key.type = BTRFS_ROOT_REF_KEY;
858 : 0 : key.offset = 0;
859 : :
860 : 0 : btrfs_release_path(path);
861 : 0 : ret = btrfs_search_slot_for_read(tree_root, &key, path, 1, 0);
862 [ # # ]: 0 : if (ret > 0)
863 : : goto out_add_root;
864 [ # # ]: 0 : if (ret < 0)
865 : : goto out_free_path;
866 : :
867 : :
868 : : while (1) {
869 : 0 : slot = path->slots[0];
870 : 0 : leaf = path->nodes[0];
871 : : btrfs_item_key_to_cpu(leaf, &found_key, slot);
872 : :
873 [ # # ]: 0 : if (found_key.type == BTRFS_ROOT_REF_KEY) {
874 : 0 : ret = add_qgroup_item(trans, quota_root,
875 : : found_key.offset);
876 [ # # ]: 0 : if (ret)
877 : : goto out_free_path;
878 : :
879 : 0 : qgroup = add_qgroup_rb(fs_info, found_key.offset);
880 [ # # ]: 0 : if (IS_ERR(qgroup)) {
881 : : ret = PTR_ERR(qgroup);
882 : 0 : goto out_free_path;
883 : : }
884 : : }
885 : : ret = btrfs_next_item(tree_root, path);
886 [ # # ]: 0 : if (ret < 0)
887 : : goto out_free_path;
888 [ # # ]: 0 : if (ret)
889 : : break;
890 : : }
891 : :
892 : : out_add_root:
893 : 0 : btrfs_release_path(path);
894 : 0 : ret = add_qgroup_item(trans, quota_root, BTRFS_FS_TREE_OBJECTID);
895 [ # # ]: 0 : if (ret)
896 : : goto out_free_path;
897 : :
898 : 0 : qgroup = add_qgroup_rb(fs_info, BTRFS_FS_TREE_OBJECTID);
899 [ # # ]: 0 : if (IS_ERR(qgroup)) {
900 : : ret = PTR_ERR(qgroup);
901 : 0 : goto out_free_path;
902 : : }
903 : : spin_lock(&fs_info->qgroup_lock);
904 : 0 : fs_info->quota_root = quota_root;
905 : 0 : fs_info->pending_quota_state = 1;
906 : : spin_unlock(&fs_info->qgroup_lock);
907 : : out_free_path:
908 : 0 : btrfs_free_path(path);
909 : : out_free_root:
910 [ # # ]: 0 : if (ret) {
911 : 0 : free_extent_buffer(quota_root->node);
912 : 0 : free_extent_buffer(quota_root->commit_root);
913 : 0 : kfree(quota_root);
914 : : }
915 : : out:
916 [ # # ]: 0 : if (ret) {
917 : 0 : ulist_free(fs_info->qgroup_ulist);
918 : 0 : fs_info->qgroup_ulist = NULL;
919 : : }
920 : 0 : mutex_unlock(&fs_info->qgroup_ioctl_lock);
921 : 0 : return ret;
922 : : }
923 : :
924 : 0 : int btrfs_quota_disable(struct btrfs_trans_handle *trans,
925 : : struct btrfs_fs_info *fs_info)
926 : : {
927 : 0 : struct btrfs_root *tree_root = fs_info->tree_root;
928 : : struct btrfs_root *quota_root;
929 : : int ret = 0;
930 : :
931 : 0 : mutex_lock(&fs_info->qgroup_ioctl_lock);
932 [ # # ]: 0 : if (!fs_info->quota_root)
933 : : goto out;
934 : : spin_lock(&fs_info->qgroup_lock);
935 : 0 : fs_info->quota_enabled = 0;
936 : 0 : fs_info->pending_quota_state = 0;
937 : 0 : quota_root = fs_info->quota_root;
938 : 0 : fs_info->quota_root = NULL;
939 : : spin_unlock(&fs_info->qgroup_lock);
940 : :
941 : 0 : btrfs_free_qgroup_config(fs_info);
942 : :
943 : 0 : ret = btrfs_clean_quota_tree(trans, quota_root);
944 [ # # ]: 0 : if (ret)
945 : : goto out;
946 : :
947 : 0 : ret = btrfs_del_root(trans, tree_root, "a_root->root_key);
948 [ # # ]: 0 : if (ret)
949 : : goto out;
950 : :
951 : : list_del("a_root->dirty_list);
952 : :
953 : 0 : btrfs_tree_lock(quota_root->node);
954 : 0 : clean_tree_block(trans, tree_root, quota_root->node);
955 : 0 : btrfs_tree_unlock(quota_root->node);
956 : 0 : btrfs_free_tree_block(trans, quota_root, quota_root->node, 0, 1);
957 : :
958 : 0 : free_extent_buffer(quota_root->node);
959 : 0 : free_extent_buffer(quota_root->commit_root);
960 : 0 : kfree(quota_root);
961 : : out:
962 : 0 : mutex_unlock(&fs_info->qgroup_ioctl_lock);
963 : 0 : return ret;
964 : : }
965 : :
966 : : static void qgroup_dirty(struct btrfs_fs_info *fs_info,
967 : : struct btrfs_qgroup *qgroup)
968 : : {
969 [ # # ][ # # ]: 0 : if (list_empty(&qgroup->dirty))
[ # # ][ # # ]
[ # # ]
970 : 0 : list_add(&qgroup->dirty, &fs_info->dirty_qgroups);
971 : : }
972 : :
973 : 0 : int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
974 : 0 : struct btrfs_fs_info *fs_info, u64 src, u64 dst)
975 : : {
976 : : struct btrfs_root *quota_root;
977 : : struct btrfs_qgroup *parent;
978 : : struct btrfs_qgroup *member;
979 : : struct btrfs_qgroup_list *list;
980 : : int ret = 0;
981 : :
982 : 0 : mutex_lock(&fs_info->qgroup_ioctl_lock);
983 : 0 : quota_root = fs_info->quota_root;
984 [ # # ]: 0 : if (!quota_root) {
985 : : ret = -EINVAL;
986 : : goto out;
987 : : }
988 : : member = find_qgroup_rb(fs_info, src);
989 : : parent = find_qgroup_rb(fs_info, dst);
990 [ # # ]: 0 : if (!member || !parent) {
991 : : ret = -EINVAL;
992 : : goto out;
993 : : }
994 : :
995 : : /* check if such qgroup relation exist firstly */
996 [ # # ]: 0 : list_for_each_entry(list, &member->groups, next_group) {
997 [ # # ]: 0 : if (list->group == parent) {
998 : : ret = -EEXIST;
999 : : goto out;
1000 : : }
1001 : : }
1002 : :
1003 : 0 : ret = add_qgroup_relation_item(trans, quota_root, src, dst);
1004 [ # # ]: 0 : if (ret)
1005 : : goto out;
1006 : :
1007 : 0 : ret = add_qgroup_relation_item(trans, quota_root, dst, src);
1008 [ # # ]: 0 : if (ret) {
1009 : 0 : del_qgroup_relation_item(trans, quota_root, src, dst);
1010 : 0 : goto out;
1011 : : }
1012 : :
1013 : : spin_lock(&fs_info->qgroup_lock);
1014 : 0 : ret = add_relation_rb(quota_root->fs_info, src, dst);
1015 : : spin_unlock(&fs_info->qgroup_lock);
1016 : : out:
1017 : 0 : mutex_unlock(&fs_info->qgroup_ioctl_lock);
1018 : 0 : return ret;
1019 : : }
1020 : :
1021 : 0 : int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
1022 : 0 : struct btrfs_fs_info *fs_info, u64 src, u64 dst)
1023 : : {
1024 : : struct btrfs_root *quota_root;
1025 : : struct btrfs_qgroup *parent;
1026 : : struct btrfs_qgroup *member;
1027 : : struct btrfs_qgroup_list *list;
1028 : : int ret = 0;
1029 : : int err;
1030 : :
1031 : 0 : mutex_lock(&fs_info->qgroup_ioctl_lock);
1032 : 0 : quota_root = fs_info->quota_root;
1033 [ # # ]: 0 : if (!quota_root) {
1034 : : ret = -EINVAL;
1035 : : goto out;
1036 : : }
1037 : :
1038 : : member = find_qgroup_rb(fs_info, src);
1039 : : parent = find_qgroup_rb(fs_info, dst);
1040 [ # # ]: 0 : if (!member || !parent) {
1041 : : ret = -EINVAL;
1042 : : goto out;
1043 : : }
1044 : :
1045 : : /* check if such qgroup relation exist firstly */
1046 [ # # ]: 0 : list_for_each_entry(list, &member->groups, next_group) {
1047 [ # # ]: 0 : if (list->group == parent)
1048 : : goto exist;
1049 : : }
1050 : : ret = -ENOENT;
1051 : : goto out;
1052 : : exist:
1053 : 0 : ret = del_qgroup_relation_item(trans, quota_root, src, dst);
1054 : 0 : err = del_qgroup_relation_item(trans, quota_root, dst, src);
1055 [ # # ]: 0 : if (err && !ret)
1056 : : ret = err;
1057 : :
1058 : : spin_lock(&fs_info->qgroup_lock);
1059 : 0 : del_relation_rb(fs_info, src, dst);
1060 : : spin_unlock(&fs_info->qgroup_lock);
1061 : : out:
1062 : 0 : mutex_unlock(&fs_info->qgroup_ioctl_lock);
1063 : 0 : return ret;
1064 : : }
1065 : :
1066 : 0 : int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
1067 : 0 : struct btrfs_fs_info *fs_info, u64 qgroupid, char *name)
1068 : : {
1069 : : struct btrfs_root *quota_root;
1070 : : struct btrfs_qgroup *qgroup;
1071 : : int ret = 0;
1072 : :
1073 : 0 : mutex_lock(&fs_info->qgroup_ioctl_lock);
1074 : 0 : quota_root = fs_info->quota_root;
1075 [ # # ]: 0 : if (!quota_root) {
1076 : : ret = -EINVAL;
1077 : : goto out;
1078 : : }
1079 : : qgroup = find_qgroup_rb(fs_info, qgroupid);
1080 [ # # ]: 0 : if (qgroup) {
1081 : : ret = -EEXIST;
1082 : : goto out;
1083 : : }
1084 : :
1085 : 0 : ret = add_qgroup_item(trans, quota_root, qgroupid);
1086 [ # # ]: 0 : if (ret)
1087 : : goto out;
1088 : :
1089 : : spin_lock(&fs_info->qgroup_lock);
1090 : 0 : qgroup = add_qgroup_rb(fs_info, qgroupid);
1091 : : spin_unlock(&fs_info->qgroup_lock);
1092 : :
1093 [ # # ]: 0 : if (IS_ERR(qgroup))
1094 : : ret = PTR_ERR(qgroup);
1095 : : out:
1096 : 0 : mutex_unlock(&fs_info->qgroup_ioctl_lock);
1097 : 0 : return ret;
1098 : : }
1099 : :
1100 : 0 : int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
1101 : 0 : struct btrfs_fs_info *fs_info, u64 qgroupid)
1102 : : {
1103 : : struct btrfs_root *quota_root;
1104 : : struct btrfs_qgroup *qgroup;
1105 : : int ret = 0;
1106 : :
1107 : 0 : mutex_lock(&fs_info->qgroup_ioctl_lock);
1108 : 0 : quota_root = fs_info->quota_root;
1109 [ # # ]: 0 : if (!quota_root) {
1110 : : ret = -EINVAL;
1111 : : goto out;
1112 : : }
1113 : :
1114 : : qgroup = find_qgroup_rb(fs_info, qgroupid);
1115 [ # # ]: 0 : if (!qgroup) {
1116 : : ret = -ENOENT;
1117 : : goto out;
1118 : : } else {
1119 : : /* check if there are no relations to this qgroup */
1120 [ # # ][ # # ]: 0 : if (!list_empty(&qgroup->groups) ||
1121 : 0 : !list_empty(&qgroup->members)) {
1122 : : ret = -EBUSY;
1123 : : goto out;
1124 : : }
1125 : : }
1126 : 0 : ret = del_qgroup_item(trans, quota_root, qgroupid);
1127 : :
1128 : : spin_lock(&fs_info->qgroup_lock);
1129 : 0 : del_qgroup_rb(quota_root->fs_info, qgroupid);
1130 : : spin_unlock(&fs_info->qgroup_lock);
1131 : : out:
1132 : 0 : mutex_unlock(&fs_info->qgroup_ioctl_lock);
1133 : 0 : return ret;
1134 : : }
1135 : :
1136 : 0 : int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
1137 : 0 : struct btrfs_fs_info *fs_info, u64 qgroupid,
1138 : : struct btrfs_qgroup_limit *limit)
1139 : : {
1140 : : struct btrfs_root *quota_root;
1141 : : struct btrfs_qgroup *qgroup;
1142 : : int ret = 0;
1143 : :
1144 : 0 : mutex_lock(&fs_info->qgroup_ioctl_lock);
1145 : 0 : quota_root = fs_info->quota_root;
1146 [ # # ]: 0 : if (!quota_root) {
1147 : : ret = -EINVAL;
1148 : : goto out;
1149 : : }
1150 : :
1151 : : qgroup = find_qgroup_rb(fs_info, qgroupid);
1152 [ # # ]: 0 : if (!qgroup) {
1153 : : ret = -ENOENT;
1154 : : goto out;
1155 : : }
1156 : 0 : ret = update_qgroup_limit_item(trans, quota_root, qgroupid,
1157 : : limit->flags, limit->max_rfer,
1158 : : limit->max_excl, limit->rsv_rfer,
1159 : : limit->rsv_excl);
1160 [ # # ]: 0 : if (ret) {
1161 : 0 : fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
1162 : 0 : btrfs_info(fs_info, "unable to update quota limit for %llu",
1163 : : qgroupid);
1164 : : }
1165 : :
1166 : : spin_lock(&fs_info->qgroup_lock);
1167 : 0 : qgroup->lim_flags = limit->flags;
1168 : 0 : qgroup->max_rfer = limit->max_rfer;
1169 : 0 : qgroup->max_excl = limit->max_excl;
1170 : 0 : qgroup->rsv_rfer = limit->rsv_rfer;
1171 : 0 : qgroup->rsv_excl = limit->rsv_excl;
1172 : : spin_unlock(&fs_info->qgroup_lock);
1173 : : out:
1174 : 0 : mutex_unlock(&fs_info->qgroup_ioctl_lock);
1175 : 0 : return ret;
1176 : : }
1177 : :
1178 : : /*
1179 : : * btrfs_qgroup_record_ref is called when the ref is added or deleted. it puts
1180 : : * the modification into a list that's later used by btrfs_end_transaction to
1181 : : * pass the recorded modifications on to btrfs_qgroup_account_ref.
1182 : : */
1183 : 0 : int btrfs_qgroup_record_ref(struct btrfs_trans_handle *trans,
1184 : : struct btrfs_delayed_ref_node *node,
1185 : : struct btrfs_delayed_extent_op *extent_op)
1186 : : {
1187 : : struct qgroup_update *u;
1188 : :
1189 [ # # ]: 0 : BUG_ON(!trans->delayed_ref_elem.seq);
1190 : : u = kmalloc(sizeof(*u), GFP_NOFS);
1191 [ # # ]: 0 : if (!u)
1192 : : return -ENOMEM;
1193 : :
1194 : 0 : u->node = node;
1195 : 0 : u->extent_op = extent_op;
1196 : 0 : list_add_tail(&u->list, &trans->qgroup_ref_list);
1197 : :
1198 : 0 : return 0;
1199 : : }
1200 : :
1201 : 0 : static int qgroup_account_ref_step1(struct btrfs_fs_info *fs_info,
1202 : : struct ulist *roots, struct ulist *tmp,
1203 : : u64 seq)
1204 : : {
1205 : : struct ulist_node *unode;
1206 : : struct ulist_iterator uiter;
1207 : : struct ulist_node *tmp_unode;
1208 : : struct ulist_iterator tmp_uiter;
1209 : : struct btrfs_qgroup *qg;
1210 : : int ret;
1211 : :
1212 : 0 : ULIST_ITER_INIT(&uiter);
1213 [ # # ]: 0 : while ((unode = ulist_next(roots, &uiter))) {
1214 : 0 : qg = find_qgroup_rb(fs_info, unode->val);
1215 [ # # ]: 0 : if (!qg)
1216 : 0 : continue;
1217 : :
1218 : 0 : ulist_reinit(tmp);
1219 : : /* XXX id not needed */
1220 : 0 : ret = ulist_add(tmp, qg->qgroupid,
1221 : 0 : (u64)(uintptr_t)qg, GFP_ATOMIC);
1222 [ # # ]: 0 : if (ret < 0)
1223 : : return ret;
1224 : 0 : ULIST_ITER_INIT(&tmp_uiter);
1225 [ # # ]: 0 : while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
1226 : : struct btrfs_qgroup_list *glist;
1227 : :
1228 : 0 : qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
1229 [ # # ]: 0 : if (qg->refcnt < seq)
1230 : 0 : qg->refcnt = seq + 1;
1231 : : else
1232 : 0 : ++qg->refcnt;
1233 : :
1234 [ # # ]: 0 : list_for_each_entry(glist, &qg->groups, next_group) {
1235 : 0 : ret = ulist_add(tmp, glist->group->qgroupid,
1236 : 0 : (u64)(uintptr_t)glist->group,
1237 : : GFP_ATOMIC);
1238 [ # # ]: 0 : if (ret < 0)
1239 : : return ret;
1240 : : }
1241 : : }
1242 : : }
1243 : :
1244 : : return 0;
1245 : : }
1246 : :
1247 : 0 : static int qgroup_account_ref_step2(struct btrfs_fs_info *fs_info,
1248 : : struct ulist *roots, struct ulist *tmp,
1249 : : u64 seq, int sgn, u64 num_bytes,
1250 : : struct btrfs_qgroup *qgroup)
1251 : : {
1252 : : struct ulist_node *unode;
1253 : : struct ulist_iterator uiter;
1254 : : struct btrfs_qgroup *qg;
1255 : : struct btrfs_qgroup_list *glist;
1256 : : int ret;
1257 : :
1258 : 0 : ulist_reinit(tmp);
1259 : 0 : ret = ulist_add(tmp, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
1260 [ # # ]: 0 : if (ret < 0)
1261 : : return ret;
1262 : :
1263 : 0 : ULIST_ITER_INIT(&uiter);
1264 [ # # ]: 0 : while ((unode = ulist_next(tmp, &uiter))) {
1265 : 0 : qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
1266 [ # # ]: 0 : if (qg->refcnt < seq) {
1267 : : /* not visited by step 1 */
1268 : 0 : qg->rfer += sgn * num_bytes;
1269 : 0 : qg->rfer_cmpr += sgn * num_bytes;
1270 [ # # ]: 0 : if (roots->nnodes == 0) {
1271 : 0 : qg->excl += sgn * num_bytes;
1272 : 0 : qg->excl_cmpr += sgn * num_bytes;
1273 : : }
1274 : : qgroup_dirty(fs_info, qg);
1275 : : }
1276 [ # # ]: 0 : WARN_ON(qg->tag >= seq);
1277 : 0 : qg->tag = seq;
1278 : :
1279 [ # # ]: 0 : list_for_each_entry(glist, &qg->groups, next_group) {
1280 : 0 : ret = ulist_add(tmp, glist->group->qgroupid,
1281 : 0 : (uintptr_t)glist->group, GFP_ATOMIC);
1282 [ # # ]: 0 : if (ret < 0)
1283 : : return ret;
1284 : : }
1285 : : }
1286 : :
1287 : : return 0;
1288 : : }
1289 : :
1290 : 0 : static int qgroup_account_ref_step3(struct btrfs_fs_info *fs_info,
1291 : : struct ulist *roots, struct ulist *tmp,
1292 : : u64 seq, int sgn, u64 num_bytes)
1293 : : {
1294 : : struct ulist_node *unode;
1295 : : struct ulist_iterator uiter;
1296 : : struct btrfs_qgroup *qg;
1297 : : struct ulist_node *tmp_unode;
1298 : : struct ulist_iterator tmp_uiter;
1299 : : int ret;
1300 : :
1301 : 0 : ULIST_ITER_INIT(&uiter);
1302 [ # # ]: 0 : while ((unode = ulist_next(roots, &uiter))) {
1303 : 0 : qg = find_qgroup_rb(fs_info, unode->val);
1304 [ # # ]: 0 : if (!qg)
1305 : 0 : continue;
1306 : :
1307 : 0 : ulist_reinit(tmp);
1308 : 0 : ret = ulist_add(tmp, qg->qgroupid, (uintptr_t)qg, GFP_ATOMIC);
1309 [ # # ]: 0 : if (ret < 0)
1310 : : return ret;
1311 : :
1312 : 0 : ULIST_ITER_INIT(&tmp_uiter);
1313 [ # # ]: 0 : while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
1314 : : struct btrfs_qgroup_list *glist;
1315 : :
1316 : 0 : qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
1317 [ # # ]: 0 : if (qg->tag == seq)
1318 : 0 : continue;
1319 : :
1320 [ # # ]: 0 : if (qg->refcnt - seq == roots->nnodes) {
1321 : 0 : qg->excl -= sgn * num_bytes;
1322 : 0 : qg->excl_cmpr -= sgn * num_bytes;
1323 : : qgroup_dirty(fs_info, qg);
1324 : : }
1325 : :
1326 [ # # ]: 0 : list_for_each_entry(glist, &qg->groups, next_group) {
1327 : 0 : ret = ulist_add(tmp, glist->group->qgroupid,
1328 : 0 : (uintptr_t)glist->group,
1329 : : GFP_ATOMIC);
1330 [ # # ]: 0 : if (ret < 0)
1331 : : return ret;
1332 : : }
1333 : : }
1334 : : }
1335 : :
1336 : : return 0;
1337 : : }
1338 : :
1339 : : /*
1340 : : * btrfs_qgroup_account_ref is called for every ref that is added to or deleted
1341 : : * from the fs. First, all roots referencing the extent are searched, and
1342 : : * then the space is accounted accordingly to the different roots. The
1343 : : * accounting algorithm works in 3 steps documented inline.
1344 : : */
1345 : 0 : int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
1346 : 0 : struct btrfs_fs_info *fs_info,
1347 : : struct btrfs_delayed_ref_node *node,
1348 : : struct btrfs_delayed_extent_op *extent_op)
1349 : : {
1350 : : struct btrfs_root *quota_root;
1351 : : u64 ref_root;
1352 : : struct btrfs_qgroup *qgroup;
1353 : 0 : struct ulist *roots = NULL;
1354 : : u64 seq;
1355 : : int ret = 0;
1356 : : int sgn;
1357 : :
1358 [ # # ]: 0 : if (!fs_info->quota_enabled)
1359 : : return 0;
1360 : :
1361 [ # # ]: 0 : BUG_ON(!fs_info->quota_root);
1362 : :
1363 [ # # ]: 0 : if (node->type == BTRFS_TREE_BLOCK_REF_KEY ||
1364 : : node->type == BTRFS_SHARED_BLOCK_REF_KEY) {
1365 : : struct btrfs_delayed_tree_ref *ref;
1366 : : ref = btrfs_delayed_node_to_tree_ref(node);
1367 : 0 : ref_root = ref->root;
1368 [ # # ]: 0 : } else if (node->type == BTRFS_EXTENT_DATA_REF_KEY ||
1369 : : node->type == BTRFS_SHARED_DATA_REF_KEY) {
1370 : : struct btrfs_delayed_data_ref *ref;
1371 : : ref = btrfs_delayed_node_to_data_ref(node);
1372 : 0 : ref_root = ref->root;
1373 : : } else {
1374 : 0 : BUG();
1375 : : }
1376 : :
1377 [ # # ]: 0 : if (!is_fstree(ref_root)) {
1378 : : /*
1379 : : * non-fs-trees are not being accounted
1380 : : */
1381 : : return 0;
1382 : : }
1383 : :
1384 [ # # # # ]: 0 : switch (node->action) {
1385 : : case BTRFS_ADD_DELAYED_REF:
1386 : : case BTRFS_ADD_DELAYED_EXTENT:
1387 : : sgn = 1;
1388 : 0 : seq = btrfs_tree_mod_seq_prev(node->seq);
1389 : 0 : break;
1390 : : case BTRFS_DROP_DELAYED_REF:
1391 : : sgn = -1;
1392 : 0 : seq = node->seq;
1393 : 0 : break;
1394 : : case BTRFS_UPDATE_DELAYED_HEAD:
1395 : : return 0;
1396 : : default:
1397 : 0 : BUG();
1398 : : }
1399 : :
1400 : 0 : mutex_lock(&fs_info->qgroup_rescan_lock);
1401 [ # # ]: 0 : if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
1402 [ # # ]: 0 : if (fs_info->qgroup_rescan_progress.objectid <= node->bytenr) {
1403 : 0 : mutex_unlock(&fs_info->qgroup_rescan_lock);
1404 : 0 : return 0;
1405 : : }
1406 : : }
1407 : 0 : mutex_unlock(&fs_info->qgroup_rescan_lock);
1408 : :
1409 : : /*
1410 : : * the delayed ref sequence number we pass depends on the direction of
1411 : : * the operation. for add operations, we pass
1412 : : * tree_mod_log_prev_seq(node->seq) to skip
1413 : : * the delayed ref's current sequence number, because we need the state
1414 : : * of the tree before the add operation. for delete operations, we pass
1415 : : * (node->seq) to include the delayed ref's current sequence number,
1416 : : * because we need the state of the tree after the delete operation.
1417 : : */
1418 : 0 : ret = btrfs_find_all_roots(trans, fs_info, node->bytenr, seq, &roots);
1419 [ # # ]: 0 : if (ret < 0)
1420 : : return ret;
1421 : :
1422 : : spin_lock(&fs_info->qgroup_lock);
1423 : :
1424 : 0 : quota_root = fs_info->quota_root;
1425 [ # # ]: 0 : if (!quota_root)
1426 : : goto unlock;
1427 : :
1428 : : qgroup = find_qgroup_rb(fs_info, ref_root);
1429 [ # # ]: 0 : if (!qgroup)
1430 : : goto unlock;
1431 : :
1432 : : /*
1433 : : * step 1: for each old ref, visit all nodes once and inc refcnt
1434 : : */
1435 : 0 : ulist_reinit(fs_info->qgroup_ulist);
1436 : 0 : seq = fs_info->qgroup_seq;
1437 : 0 : fs_info->qgroup_seq += roots->nnodes + 1; /* max refcnt */
1438 : :
1439 : 0 : ret = qgroup_account_ref_step1(fs_info, roots, fs_info->qgroup_ulist,
1440 : : seq);
1441 [ # # ]: 0 : if (ret)
1442 : : goto unlock;
1443 : :
1444 : : /*
1445 : : * step 2: walk from the new root
1446 : : */
1447 : 0 : ret = qgroup_account_ref_step2(fs_info, roots, fs_info->qgroup_ulist,
1448 : : seq, sgn, node->num_bytes, qgroup);
1449 [ # # ]: 0 : if (ret)
1450 : : goto unlock;
1451 : :
1452 : : /*
1453 : : * step 3: walk again from old refs
1454 : : */
1455 : 0 : ret = qgroup_account_ref_step3(fs_info, roots, fs_info->qgroup_ulist,
1456 : : seq, sgn, node->num_bytes);
1457 : : if (ret)
1458 : : goto unlock;
1459 : :
1460 : : unlock:
1461 : : spin_unlock(&fs_info->qgroup_lock);
1462 : 0 : ulist_free(roots);
1463 : :
1464 : 0 : return ret;
1465 : : }
1466 : :
1467 : : /*
1468 : : * called from commit_transaction. Writes all changed qgroups to disk.
1469 : : */
1470 : 0 : int btrfs_run_qgroups(struct btrfs_trans_handle *trans,
1471 : : struct btrfs_fs_info *fs_info)
1472 : : {
1473 : 0 : struct btrfs_root *quota_root = fs_info->quota_root;
1474 : : int ret = 0;
1475 : : int start_rescan_worker = 0;
1476 : :
1477 [ # # ]: 0 : if (!quota_root)
1478 : : goto out;
1479 : :
1480 [ # # ]: 0 : if (!fs_info->quota_enabled && fs_info->pending_quota_state)
1481 : : start_rescan_worker = 1;
1482 : :
1483 : 0 : fs_info->quota_enabled = fs_info->pending_quota_state;
1484 : :
1485 : : spin_lock(&fs_info->qgroup_lock);
1486 [ # # ]: 0 : while (!list_empty(&fs_info->dirty_qgroups)) {
1487 : : struct btrfs_qgroup *qgroup;
1488 : 0 : qgroup = list_first_entry(&fs_info->dirty_qgroups,
1489 : : struct btrfs_qgroup, dirty);
1490 : 0 : list_del_init(&qgroup->dirty);
1491 : : spin_unlock(&fs_info->qgroup_lock);
1492 : 0 : ret = update_qgroup_info_item(trans, quota_root, qgroup);
1493 [ # # ]: 0 : if (ret)
1494 : 0 : fs_info->qgroup_flags |=
1495 : : BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
1496 : : spin_lock(&fs_info->qgroup_lock);
1497 : : }
1498 [ # # ]: 0 : if (fs_info->quota_enabled)
1499 : 0 : fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_ON;
1500 : : else
1501 : 0 : fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
1502 : : spin_unlock(&fs_info->qgroup_lock);
1503 : :
1504 : 0 : ret = update_qgroup_status_item(trans, fs_info, quota_root);
1505 [ # # ]: 0 : if (ret)
1506 : 0 : fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
1507 : :
1508 [ # # ]: 0 : if (!ret && start_rescan_worker) {
1509 : 0 : ret = qgroup_rescan_init(fs_info, 0, 1);
1510 [ # # ]: 0 : if (!ret) {
1511 : 0 : qgroup_rescan_zero_tracking(fs_info);
1512 : 0 : btrfs_queue_worker(&fs_info->qgroup_rescan_workers,
1513 : : &fs_info->qgroup_rescan_work);
1514 : : }
1515 : : ret = 0;
1516 : : }
1517 : :
1518 : : out:
1519 : :
1520 : 0 : return ret;
1521 : : }
1522 : :
1523 : : /*
1524 : : * copy the acounting information between qgroups. This is necessary when a
1525 : : * snapshot or a subvolume is created
1526 : : */
1527 : 0 : int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
1528 : 0 : struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid,
1529 : : struct btrfs_qgroup_inherit *inherit)
1530 : : {
1531 : : int ret = 0;
1532 : : int i;
1533 : : u64 *i_qgroups;
1534 : 0 : struct btrfs_root *quota_root = fs_info->quota_root;
1535 : : struct btrfs_qgroup *srcgroup;
1536 : : struct btrfs_qgroup *dstgroup;
1537 : : u32 level_size = 0;
1538 : : u64 nums;
1539 : :
1540 : 0 : mutex_lock(&fs_info->qgroup_ioctl_lock);
1541 [ # # ]: 0 : if (!fs_info->quota_enabled)
1542 : : goto out;
1543 : :
1544 [ # # ]: 0 : if (!quota_root) {
1545 : : ret = -EINVAL;
1546 : : goto out;
1547 : : }
1548 : :
1549 [ # # ]: 0 : if (inherit) {
1550 : 0 : i_qgroups = (u64 *)(inherit + 1);
1551 : 0 : nums = inherit->num_qgroups + 2 * inherit->num_ref_copies +
1552 : 0 : 2 * inherit->num_excl_copies;
1553 [ # # ]: 0 : for (i = 0; i < nums; ++i) {
1554 : 0 : srcgroup = find_qgroup_rb(fs_info, *i_qgroups);
1555 [ # # ]: 0 : if (!srcgroup) {
1556 : : ret = -EINVAL;
1557 : : goto out;
1558 : : }
1559 : 0 : ++i_qgroups;
1560 : : }
1561 : : }
1562 : :
1563 : : /*
1564 : : * create a tracking group for the subvol itself
1565 : : */
1566 : 0 : ret = add_qgroup_item(trans, quota_root, objectid);
1567 [ # # ]: 0 : if (ret)
1568 : : goto out;
1569 : :
1570 [ # # ][ # # ]: 0 : if (inherit && inherit->flags & BTRFS_QGROUP_INHERIT_SET_LIMITS) {
1571 : 0 : ret = update_qgroup_limit_item(trans, quota_root, objectid,
1572 : : inherit->lim.flags,
1573 : : inherit->lim.max_rfer,
1574 : : inherit->lim.max_excl,
1575 : : inherit->lim.rsv_rfer,
1576 : : inherit->lim.rsv_excl);
1577 [ # # ]: 0 : if (ret)
1578 : : goto out;
1579 : : }
1580 : :
1581 [ # # ]: 0 : if (srcid) {
1582 : 0 : struct btrfs_root *srcroot;
1583 : : struct btrfs_key srckey;
1584 : : int srcroot_level;
1585 : :
1586 : 0 : srckey.objectid = srcid;
1587 : 0 : srckey.type = BTRFS_ROOT_ITEM_KEY;
1588 : 0 : srckey.offset = (u64)-1;
1589 : : srcroot = btrfs_read_fs_root_no_name(fs_info, &srckey);
1590 [ # # ]: 0 : if (IS_ERR(srcroot)) {
1591 : : ret = PTR_ERR(srcroot);
1592 : 0 : goto out;
1593 : : }
1594 : :
1595 : : rcu_read_lock();
1596 : 0 : srcroot_level = btrfs_header_level(srcroot->node);
1597 : : level_size = btrfs_level_size(srcroot, srcroot_level);
1598 : : rcu_read_unlock();
1599 : : }
1600 : :
1601 : : /*
1602 : : * add qgroup to all inherited groups
1603 : : */
1604 [ # # ]: 0 : if (inherit) {
1605 : 0 : i_qgroups = (u64 *)(inherit + 1);
1606 [ # # ]: 0 : for (i = 0; i < inherit->num_qgroups; ++i) {
1607 : 0 : ret = add_qgroup_relation_item(trans, quota_root,
1608 : : objectid, *i_qgroups);
1609 [ # # ]: 0 : if (ret)
1610 : : goto out;
1611 : 0 : ret = add_qgroup_relation_item(trans, quota_root,
1612 : : *i_qgroups, objectid);
1613 [ # # ]: 0 : if (ret)
1614 : : goto out;
1615 : 0 : ++i_qgroups;
1616 : : }
1617 : : }
1618 : :
1619 : :
1620 : : spin_lock(&fs_info->qgroup_lock);
1621 : :
1622 : 0 : dstgroup = add_qgroup_rb(fs_info, objectid);
1623 [ # # ]: 0 : if (IS_ERR(dstgroup)) {
1624 : : ret = PTR_ERR(dstgroup);
1625 : 0 : goto unlock;
1626 : : }
1627 : :
1628 [ # # ]: 0 : if (srcid) {
1629 : : srcgroup = find_qgroup_rb(fs_info, srcid);
1630 [ # # ]: 0 : if (!srcgroup)
1631 : : goto unlock;
1632 : 0 : dstgroup->rfer = srcgroup->rfer - level_size;
1633 : 0 : dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size;
1634 : 0 : srcgroup->excl = level_size;
1635 : 0 : srcgroup->excl_cmpr = level_size;
1636 : : qgroup_dirty(fs_info, dstgroup);
1637 : : qgroup_dirty(fs_info, srcgroup);
1638 : : }
1639 : :
1640 [ # # ]: 0 : if (!inherit)
1641 : : goto unlock;
1642 : :
1643 : 0 : i_qgroups = (u64 *)(inherit + 1);
1644 [ # # ]: 0 : for (i = 0; i < inherit->num_qgroups; ++i) {
1645 : 0 : ret = add_relation_rb(quota_root->fs_info, objectid,
1646 : : *i_qgroups);
1647 [ # # ]: 0 : if (ret)
1648 : : goto unlock;
1649 : 0 : ++i_qgroups;
1650 : : }
1651 : :
1652 [ # # ]: 0 : for (i = 0; i < inherit->num_ref_copies; ++i) {
1653 : : struct btrfs_qgroup *src;
1654 : : struct btrfs_qgroup *dst;
1655 : :
1656 : 0 : src = find_qgroup_rb(fs_info, i_qgroups[0]);
1657 : 0 : dst = find_qgroup_rb(fs_info, i_qgroups[1]);
1658 : :
1659 [ # # ]: 0 : if (!src || !dst) {
1660 : : ret = -EINVAL;
1661 : : goto unlock;
1662 : : }
1663 : :
1664 : 0 : dst->rfer = src->rfer - level_size;
1665 : 0 : dst->rfer_cmpr = src->rfer_cmpr - level_size;
1666 : 0 : i_qgroups += 2;
1667 : : }
1668 [ # # ]: 0 : for (i = 0; i < inherit->num_excl_copies; ++i) {
1669 : : struct btrfs_qgroup *src;
1670 : : struct btrfs_qgroup *dst;
1671 : :
1672 : 0 : src = find_qgroup_rb(fs_info, i_qgroups[0]);
1673 : 0 : dst = find_qgroup_rb(fs_info, i_qgroups[1]);
1674 : :
1675 [ # # ]: 0 : if (!src || !dst) {
1676 : : ret = -EINVAL;
1677 : : goto unlock;
1678 : : }
1679 : :
1680 : 0 : dst->excl = src->excl + level_size;
1681 : 0 : dst->excl_cmpr = src->excl_cmpr + level_size;
1682 : 0 : i_qgroups += 2;
1683 : : }
1684 : :
1685 : : unlock:
1686 : : spin_unlock(&fs_info->qgroup_lock);
1687 : : out:
1688 : 0 : mutex_unlock(&fs_info->qgroup_ioctl_lock);
1689 : 0 : return ret;
1690 : : }
1691 : :
1692 : : /*
1693 : : * reserve some space for a qgroup and all its parents. The reservation takes
1694 : : * place with start_transaction or dealloc_reserve, similar to ENOSPC
1695 : : * accounting. If not enough space is available, EDQUOT is returned.
1696 : : * We assume that the requested space is new for all qgroups.
1697 : : */
1698 : 0 : int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
1699 : : {
1700 : : struct btrfs_root *quota_root;
1701 : : struct btrfs_qgroup *qgroup;
1702 : 0 : struct btrfs_fs_info *fs_info = root->fs_info;
1703 : 0 : u64 ref_root = root->root_key.objectid;
1704 : : int ret = 0;
1705 : : struct ulist_node *unode;
1706 : : struct ulist_iterator uiter;
1707 : :
1708 [ # # ]: 0 : if (!is_fstree(ref_root))
1709 : : return 0;
1710 : :
1711 [ # # ]: 0 : if (num_bytes == 0)
1712 : : return 0;
1713 : :
1714 : : spin_lock(&fs_info->qgroup_lock);
1715 : 0 : quota_root = fs_info->quota_root;
1716 [ # # ]: 0 : if (!quota_root)
1717 : : goto out;
1718 : :
1719 : : qgroup = find_qgroup_rb(fs_info, ref_root);
1720 [ # # ]: 0 : if (!qgroup)
1721 : : goto out;
1722 : :
1723 : : /*
1724 : : * in a first step, we check all affected qgroups if any limits would
1725 : : * be exceeded
1726 : : */
1727 : 0 : ulist_reinit(fs_info->qgroup_ulist);
1728 : 0 : ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
1729 : 0 : (uintptr_t)qgroup, GFP_ATOMIC);
1730 [ # # ]: 0 : if (ret < 0)
1731 : : goto out;
1732 : 0 : ULIST_ITER_INIT(&uiter);
1733 [ # # ]: 0 : while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
1734 : : struct btrfs_qgroup *qg;
1735 : : struct btrfs_qgroup_list *glist;
1736 : :
1737 : 0 : qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
1738 : :
1739 [ # # ][ # # ]: 0 : if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
1740 : 0 : qg->reserved + (s64)qg->rfer + num_bytes >
1741 : 0 : qg->max_rfer) {
1742 : : ret = -EDQUOT;
1743 : : goto out;
1744 : : }
1745 : :
1746 [ # # ][ # # ]: 0 : if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
1747 : 0 : qg->reserved + (s64)qg->excl + num_bytes >
1748 : 0 : qg->max_excl) {
1749 : : ret = -EDQUOT;
1750 : : goto out;
1751 : : }
1752 : :
1753 [ # # ]: 0 : list_for_each_entry(glist, &qg->groups, next_group) {
1754 : 0 : ret = ulist_add(fs_info->qgroup_ulist,
1755 : 0 : glist->group->qgroupid,
1756 : 0 : (uintptr_t)glist->group, GFP_ATOMIC);
1757 [ # # ]: 0 : if (ret < 0)
1758 : : goto out;
1759 : : }
1760 : : }
1761 : : ret = 0;
1762 : : /*
1763 : : * no limits exceeded, now record the reservation into all qgroups
1764 : : */
1765 : 0 : ULIST_ITER_INIT(&uiter);
1766 [ # # ]: 0 : while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
1767 : : struct btrfs_qgroup *qg;
1768 : :
1769 : 0 : qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
1770 : :
1771 : 0 : qg->reserved += num_bytes;
1772 : : }
1773 : :
1774 : : out:
1775 : : spin_unlock(&fs_info->qgroup_lock);
1776 : 0 : return ret;
1777 : : }
1778 : :
1779 : 0 : void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes)
1780 : : {
1781 : : struct btrfs_root *quota_root;
1782 : : struct btrfs_qgroup *qgroup;
1783 : 0 : struct btrfs_fs_info *fs_info = root->fs_info;
1784 : : struct ulist_node *unode;
1785 : : struct ulist_iterator uiter;
1786 : 0 : u64 ref_root = root->root_key.objectid;
1787 : : int ret = 0;
1788 : :
1789 [ # # ]: 0 : if (!is_fstree(ref_root))
1790 : 0 : return;
1791 : :
1792 [ # # ]: 0 : if (num_bytes == 0)
1793 : : return;
1794 : :
1795 : : spin_lock(&fs_info->qgroup_lock);
1796 : :
1797 : 0 : quota_root = fs_info->quota_root;
1798 [ # # ]: 0 : if (!quota_root)
1799 : : goto out;
1800 : :
1801 : : qgroup = find_qgroup_rb(fs_info, ref_root);
1802 [ # # ]: 0 : if (!qgroup)
1803 : : goto out;
1804 : :
1805 : 0 : ulist_reinit(fs_info->qgroup_ulist);
1806 : 0 : ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
1807 : 0 : (uintptr_t)qgroup, GFP_ATOMIC);
1808 [ # # ]: 0 : if (ret < 0)
1809 : : goto out;
1810 : 0 : ULIST_ITER_INIT(&uiter);
1811 [ # # ]: 0 : while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
1812 : : struct btrfs_qgroup *qg;
1813 : : struct btrfs_qgroup_list *glist;
1814 : :
1815 : 0 : qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
1816 : :
1817 : 0 : qg->reserved -= num_bytes;
1818 : :
1819 [ # # ]: 0 : list_for_each_entry(glist, &qg->groups, next_group) {
1820 : 0 : ret = ulist_add(fs_info->qgroup_ulist,
1821 : 0 : glist->group->qgroupid,
1822 : 0 : (uintptr_t)glist->group, GFP_ATOMIC);
1823 [ # # ]: 0 : if (ret < 0)
1824 : : goto out;
1825 : : }
1826 : : }
1827 : :
1828 : : out:
1829 : : spin_unlock(&fs_info->qgroup_lock);
1830 : : }
1831 : :
1832 : 0 : void assert_qgroups_uptodate(struct btrfs_trans_handle *trans)
1833 : : {
1834 [ # # ][ # # ]: 0 : if (list_empty(&trans->qgroup_ref_list) && !trans->delayed_ref_elem.seq)
1835 : 0 : return;
1836 [ # # ]: 0 : btrfs_err(trans->root->fs_info,
1837 : : "qgroups not uptodate in trans handle %p: list is%s empty, "
1838 : : "seq is %#x.%x",
1839 : : trans, list_empty(&trans->qgroup_ref_list) ? "" : " not",
1840 : : (u32)(trans->delayed_ref_elem.seq >> 32),
1841 : : (u32)trans->delayed_ref_elem.seq);
1842 : 0 : BUG();
1843 : : }
1844 : :
1845 : : /*
1846 : : * returns < 0 on error, 0 when more leafs are to be scanned.
1847 : : * returns 1 when done, 2 when done and FLAG_INCONSISTENT was cleared.
1848 : : */
1849 : : static int
1850 : 0 : qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, struct btrfs_path *path,
1851 : : struct btrfs_trans_handle *trans, struct ulist *tmp,
1852 : 0 : struct extent_buffer *scratch_leaf)
1853 : : {
1854 : : struct btrfs_key found;
1855 : 0 : struct ulist *roots = NULL;
1856 : : struct ulist_node *unode;
1857 : : struct ulist_iterator uiter;
1858 : 0 : struct seq_list tree_mod_seq_elem = {};
1859 : : u64 seq;
1860 : : int slot;
1861 : : int ret;
1862 : :
1863 : 0 : path->leave_spinning = 1;
1864 : 0 : mutex_lock(&fs_info->qgroup_rescan_lock);
1865 : 0 : ret = btrfs_search_slot_for_read(fs_info->extent_root,
1866 : : &fs_info->qgroup_rescan_progress,
1867 : : path, 1, 0);
1868 : :
1869 : : pr_debug("current progress key (%llu %u %llu), search_slot ret %d\n",
1870 : : fs_info->qgroup_rescan_progress.objectid,
1871 : : fs_info->qgroup_rescan_progress.type,
1872 : : fs_info->qgroup_rescan_progress.offset, ret);
1873 : :
1874 [ # # ]: 0 : if (ret) {
1875 : : /*
1876 : : * The rescan is about to end, we will not be scanning any
1877 : : * further blocks. We cannot unset the RESCAN flag here, because
1878 : : * we want to commit the transaction if everything went well.
1879 : : * To make the live accounting work in this phase, we set our
1880 : : * scan progress pointer such that every real extent objectid
1881 : : * will be smaller.
1882 : : */
1883 : 0 : fs_info->qgroup_rescan_progress.objectid = (u64)-1;
1884 : 0 : btrfs_release_path(path);
1885 : 0 : mutex_unlock(&fs_info->qgroup_rescan_lock);
1886 : 0 : return ret;
1887 : : }
1888 : :
1889 : 0 : btrfs_item_key_to_cpu(path->nodes[0], &found,
1890 : 0 : btrfs_header_nritems(path->nodes[0]) - 1);
1891 : 0 : fs_info->qgroup_rescan_progress.objectid = found.objectid + 1;
1892 : :
1893 : 0 : btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1894 : 0 : memcpy(scratch_leaf, path->nodes[0], sizeof(*scratch_leaf));
1895 : 0 : slot = path->slots[0];
1896 : 0 : btrfs_release_path(path);
1897 : 0 : mutex_unlock(&fs_info->qgroup_rescan_lock);
1898 : :
1899 [ # # ]: 0 : for (; slot < btrfs_header_nritems(scratch_leaf); ++slot) {
1900 : : u64 num_bytes;
1901 : :
1902 : : btrfs_item_key_to_cpu(scratch_leaf, &found, slot);
1903 [ # # ]: 0 : if (found.type != BTRFS_EXTENT_ITEM_KEY &&
1904 : : found.type != BTRFS_METADATA_ITEM_KEY)
1905 : 0 : continue;
1906 [ # # ]: 0 : if (found.type == BTRFS_METADATA_ITEM_KEY)
1907 : 0 : num_bytes = fs_info->extent_root->leafsize;
1908 : : else
1909 : : num_bytes = found.offset;
1910 : :
1911 : 0 : ret = btrfs_find_all_roots(trans, fs_info, found.objectid,
1912 : : tree_mod_seq_elem.seq, &roots);
1913 [ # # ]: 0 : if (ret < 0)
1914 : : goto out;
1915 : : spin_lock(&fs_info->qgroup_lock);
1916 : 0 : seq = fs_info->qgroup_seq;
1917 : 0 : fs_info->qgroup_seq += roots->nnodes + 1; /* max refcnt */
1918 : :
1919 : 0 : ret = qgroup_account_ref_step1(fs_info, roots, tmp, seq);
1920 [ # # ]: 0 : if (ret) {
1921 : : spin_unlock(&fs_info->qgroup_lock);
1922 : 0 : ulist_free(roots);
1923 : 0 : goto out;
1924 : : }
1925 : :
1926 : : /*
1927 : : * step2 of btrfs_qgroup_account_ref works from a single root,
1928 : : * we're doing all at once here.
1929 : : */
1930 : 0 : ulist_reinit(tmp);
1931 : 0 : ULIST_ITER_INIT(&uiter);
1932 [ # # ]: 0 : while ((unode = ulist_next(roots, &uiter))) {
1933 : : struct btrfs_qgroup *qg;
1934 : :
1935 : 0 : qg = find_qgroup_rb(fs_info, unode->val);
1936 [ # # ]: 0 : if (!qg)
1937 : 0 : continue;
1938 : :
1939 : 0 : ret = ulist_add(tmp, qg->qgroupid, (uintptr_t)qg,
1940 : : GFP_ATOMIC);
1941 [ # # ]: 0 : if (ret < 0) {
1942 : : spin_unlock(&fs_info->qgroup_lock);
1943 : 0 : ulist_free(roots);
1944 : 0 : goto out;
1945 : : }
1946 : : }
1947 : :
1948 : : /* this loop is similar to step 2 of btrfs_qgroup_account_ref */
1949 : 0 : ULIST_ITER_INIT(&uiter);
1950 [ # # ]: 0 : while ((unode = ulist_next(tmp, &uiter))) {
1951 : : struct btrfs_qgroup *qg;
1952 : : struct btrfs_qgroup_list *glist;
1953 : :
1954 : 0 : qg = (struct btrfs_qgroup *)(uintptr_t) unode->aux;
1955 : 0 : qg->rfer += num_bytes;
1956 : 0 : qg->rfer_cmpr += num_bytes;
1957 [ # # ]: 0 : WARN_ON(qg->tag >= seq);
1958 [ # # ]: 0 : if (qg->refcnt - seq == roots->nnodes) {
1959 : 0 : qg->excl += num_bytes;
1960 : 0 : qg->excl_cmpr += num_bytes;
1961 : : }
1962 : : qgroup_dirty(fs_info, qg);
1963 : :
1964 [ # # ]: 0 : list_for_each_entry(glist, &qg->groups, next_group) {
1965 : 0 : ret = ulist_add(tmp, glist->group->qgroupid,
1966 : 0 : (uintptr_t)glist->group,
1967 : : GFP_ATOMIC);
1968 [ # # ]: 0 : if (ret < 0) {
1969 : : spin_unlock(&fs_info->qgroup_lock);
1970 : 0 : ulist_free(roots);
1971 : 0 : goto out;
1972 : : }
1973 : : }
1974 : : }
1975 : :
1976 : : spin_unlock(&fs_info->qgroup_lock);
1977 : 0 : ulist_free(roots);
1978 : : ret = 0;
1979 : : }
1980 : :
1981 : : out:
1982 : 0 : btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1983 : :
1984 : 0 : return ret;
1985 : : }
1986 : :
1987 : 0 : static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
1988 : : {
1989 : 0 : struct btrfs_fs_info *fs_info = container_of(work, struct btrfs_fs_info,
1990 : : qgroup_rescan_work);
1991 : : struct btrfs_path *path;
1992 : : struct btrfs_trans_handle *trans = NULL;
1993 : : struct ulist *tmp = NULL;
1994 : : struct extent_buffer *scratch_leaf = NULL;
1995 : : int err = -ENOMEM;
1996 : :
1997 : 0 : path = btrfs_alloc_path();
1998 [ # # ]: 0 : if (!path)
1999 : : goto out;
2000 : 0 : tmp = ulist_alloc(GFP_NOFS);
2001 [ # # ]: 0 : if (!tmp)
2002 : : goto out;
2003 : : scratch_leaf = kmalloc(sizeof(*scratch_leaf), GFP_NOFS);
2004 [ # # ]: 0 : if (!scratch_leaf)
2005 : : goto out;
2006 : :
2007 : : err = 0;
2008 [ # # ]: 0 : while (!err) {
2009 : 0 : trans = btrfs_start_transaction(fs_info->fs_root, 0);
2010 [ # # ]: 0 : if (IS_ERR(trans)) {
2011 : : err = PTR_ERR(trans);
2012 : 0 : break;
2013 : : }
2014 [ # # ]: 0 : if (!fs_info->quota_enabled) {
2015 : : err = -EINTR;
2016 : : } else {
2017 : 0 : err = qgroup_rescan_leaf(fs_info, path, trans,
2018 : : tmp, scratch_leaf);
2019 : : }
2020 [ # # ]: 0 : if (err > 0)
2021 : 0 : btrfs_commit_transaction(trans, fs_info->fs_root);
2022 : : else
2023 : 0 : btrfs_end_transaction(trans, fs_info->fs_root);
2024 : : }
2025 : :
2026 : : out:
2027 : 0 : kfree(scratch_leaf);
2028 : 0 : ulist_free(tmp);
2029 : 0 : btrfs_free_path(path);
2030 : :
2031 : 0 : mutex_lock(&fs_info->qgroup_rescan_lock);
2032 : 0 : fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2033 : :
2034 [ # # ][ # # ]: 0 : if (err == 2 &&
2035 : 0 : fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) {
2036 : 0 : fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
2037 [ # # ]: 0 : } else if (err < 0) {
2038 : 0 : fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
2039 : : }
2040 : 0 : mutex_unlock(&fs_info->qgroup_rescan_lock);
2041 : :
2042 [ # # ]: 0 : if (err >= 0) {
2043 [ # # ]: 0 : btrfs_info(fs_info, "qgroup scan completed%s",
2044 : : err == 2 ? " (inconsistency flag cleared)" : "");
2045 : : } else {
2046 : 0 : btrfs_err(fs_info, "qgroup scan failed with %d", err);
2047 : : }
2048 : :
2049 : 0 : complete_all(&fs_info->qgroup_rescan_completion);
2050 : 0 : }
2051 : :
2052 : : /*
2053 : : * Checks that (a) no rescan is running and (b) quota is enabled. Allocates all
2054 : : * memory required for the rescan context.
2055 : : */
2056 : : static int
2057 : 0 : qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
2058 : : int init_flags)
2059 : : {
2060 : : int ret = 0;
2061 : :
2062 [ # # ][ # # ]: 0 : if (!init_flags &&
2063 [ # # ]: 0 : (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) ||
2064 : 0 : !(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON))) {
2065 : : ret = -EINVAL;
2066 : : goto err;
2067 : : }
2068 : :
2069 : 0 : mutex_lock(&fs_info->qgroup_rescan_lock);
2070 : : spin_lock(&fs_info->qgroup_lock);
2071 : :
2072 [ # # ]: 0 : if (init_flags) {
2073 [ # # ]: 0 : if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN)
2074 : : ret = -EINPROGRESS;
2075 [ # # ]: 0 : else if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON))
2076 : : ret = -EINVAL;
2077 : :
2078 [ # # ]: 0 : if (ret) {
2079 : : spin_unlock(&fs_info->qgroup_lock);
2080 : 0 : mutex_unlock(&fs_info->qgroup_rescan_lock);
2081 : 0 : goto err;
2082 : : }
2083 : :
2084 : 0 : fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2085 : : }
2086 : :
2087 : 0 : memset(&fs_info->qgroup_rescan_progress, 0,
2088 : : sizeof(fs_info->qgroup_rescan_progress));
2089 : 0 : fs_info->qgroup_rescan_progress.objectid = progress_objectid;
2090 : :
2091 : : spin_unlock(&fs_info->qgroup_lock);
2092 : 0 : mutex_unlock(&fs_info->qgroup_rescan_lock);
2093 : :
2094 : : init_completion(&fs_info->qgroup_rescan_completion);
2095 : :
2096 : 0 : memset(&fs_info->qgroup_rescan_work, 0,
2097 : : sizeof(fs_info->qgroup_rescan_work));
2098 : 0 : fs_info->qgroup_rescan_work.func = btrfs_qgroup_rescan_worker;
2099 : :
2100 [ # # ]: 0 : if (ret) {
2101 : : err:
2102 : 0 : btrfs_info(fs_info, "qgroup_rescan_init failed with %d", ret);
2103 : 0 : return ret;
2104 : : }
2105 : :
2106 : : return 0;
2107 : : }
2108 : :
2109 : : static void
2110 : 0 : qgroup_rescan_zero_tracking(struct btrfs_fs_info *fs_info)
2111 : : {
2112 : : struct rb_node *n;
2113 : : struct btrfs_qgroup *qgroup;
2114 : :
2115 : : spin_lock(&fs_info->qgroup_lock);
2116 : : /* clear all current qgroup tracking information */
2117 [ # # ]: 0 : for (n = rb_first(&fs_info->qgroup_tree); n; n = rb_next(n)) {
2118 : : qgroup = rb_entry(n, struct btrfs_qgroup, node);
2119 : 0 : qgroup->rfer = 0;
2120 : 0 : qgroup->rfer_cmpr = 0;
2121 : 0 : qgroup->excl = 0;
2122 : 0 : qgroup->excl_cmpr = 0;
2123 : : }
2124 : : spin_unlock(&fs_info->qgroup_lock);
2125 : 0 : }
2126 : :
2127 : : int
2128 : 0 : btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
2129 : : {
2130 : : int ret = 0;
2131 : : struct btrfs_trans_handle *trans;
2132 : :
2133 : 0 : ret = qgroup_rescan_init(fs_info, 0, 1);
2134 [ # # ]: 0 : if (ret)
2135 : : return ret;
2136 : :
2137 : : /*
2138 : : * We have set the rescan_progress to 0, which means no more
2139 : : * delayed refs will be accounted by btrfs_qgroup_account_ref.
2140 : : * However, btrfs_qgroup_account_ref may be right after its call
2141 : : * to btrfs_find_all_roots, in which case it would still do the
2142 : : * accounting.
2143 : : * To solve this, we're committing the transaction, which will
2144 : : * ensure we run all delayed refs and only after that, we are
2145 : : * going to clear all tracking information for a clean start.
2146 : : */
2147 : :
2148 : 0 : trans = btrfs_join_transaction(fs_info->fs_root);
2149 [ # # ]: 0 : if (IS_ERR(trans)) {
2150 : 0 : fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2151 : 0 : return PTR_ERR(trans);
2152 : : }
2153 : 0 : ret = btrfs_commit_transaction(trans, fs_info->fs_root);
2154 [ # # ]: 0 : if (ret) {
2155 : 0 : fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2156 : 0 : return ret;
2157 : : }
2158 : :
2159 : 0 : qgroup_rescan_zero_tracking(fs_info);
2160 : :
2161 : 0 : btrfs_queue_worker(&fs_info->qgroup_rescan_workers,
2162 : : &fs_info->qgroup_rescan_work);
2163 : :
2164 : 0 : return 0;
2165 : : }
2166 : :
2167 : 0 : int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info)
2168 : : {
2169 : : int running;
2170 : : int ret = 0;
2171 : :
2172 : 0 : mutex_lock(&fs_info->qgroup_rescan_lock);
2173 : : spin_lock(&fs_info->qgroup_lock);
2174 : 0 : running = fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2175 : : spin_unlock(&fs_info->qgroup_lock);
2176 : 0 : mutex_unlock(&fs_info->qgroup_rescan_lock);
2177 : :
2178 [ # # ]: 0 : if (running)
2179 : 0 : ret = wait_for_completion_interruptible(
2180 : : &fs_info->qgroup_rescan_completion);
2181 : :
2182 : 0 : return ret;
2183 : : }
2184 : :
2185 : : /*
2186 : : * this is only called from open_ctree where we're still single threaded, thus
2187 : : * locking is omitted here.
2188 : : */
2189 : : void
2190 : 0 : btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info)
2191 : : {
2192 [ # # ]: 0 : if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN)
2193 : 0 : btrfs_queue_worker(&fs_info->qgroup_rescan_workers,
2194 : : &fs_info->qgroup_rescan_work);
2195 : 0 : }
|