1c1d7c514SDavid Sterba // SPDX-License-Identifier: GPL-2.0
2bed92eaeSArne Jansen /*
3bed92eaeSArne Jansen * Copyright (C) 2011 STRATO. All rights reserved.
4bed92eaeSArne Jansen */
5bed92eaeSArne Jansen
6bed92eaeSArne Jansen #include <linux/sched.h>
7bed92eaeSArne Jansen #include <linux/pagemap.h>
8bed92eaeSArne Jansen #include <linux/writeback.h>
9bed92eaeSArne Jansen #include <linux/blkdev.h>
10bed92eaeSArne Jansen #include <linux/rbtree.h>
11bed92eaeSArne Jansen #include <linux/slab.h>
12bed92eaeSArne Jansen #include <linux/workqueue.h>
1355e301fdSFilipe Brandenburger #include <linux/btrfs.h>
147aa6d359SFilipe Manana #include <linux/sched/mm.h>
15bed92eaeSArne Jansen
16bed92eaeSArne Jansen #include "ctree.h"
17bed92eaeSArne Jansen #include "transaction.h"
18bed92eaeSArne Jansen #include "disk-io.h"
19bed92eaeSArne Jansen #include "locking.h"
20bed92eaeSArne Jansen #include "ulist.h"
21bed92eaeSArne Jansen #include "backref.h"
222f232036SJan Schmidt #include "extent_io.h"
23fcebe456SJosef Bacik #include "qgroup.h"
24aac0023cSJosef Bacik #include "block-group.h"
2549e5fb46SQu Wenruo #include "sysfs.h"
26f3a84ccdSFilipe Manana #include "tree-mod-log.h"
27c7f13d42SJosef Bacik #include "fs.h"
2807e81dc9SJosef Bacik #include "accessors.h"
29a0231804SJosef Bacik #include "extent-tree.h"
3045c40c8fSJosef Bacik #include "root-tree.h"
3127137facSChristoph Hellwig #include "tree-checker.h"
32e69bcee3SQu Wenruo
33f59c0347SQu Wenruo /*
34f59c0347SQu Wenruo * Helpers to access qgroup reservation
35f59c0347SQu Wenruo *
36f59c0347SQu Wenruo * Callers should ensure the lock context and type are valid
37f59c0347SQu Wenruo */
38f59c0347SQu Wenruo
qgroup_rsv_total(const struct btrfs_qgroup * qgroup)39f59c0347SQu Wenruo static u64 qgroup_rsv_total(const struct btrfs_qgroup *qgroup)
40f59c0347SQu Wenruo {
41f59c0347SQu Wenruo u64 ret = 0;
42f59c0347SQu Wenruo int i;
43f59c0347SQu Wenruo
44f59c0347SQu Wenruo for (i = 0; i < BTRFS_QGROUP_RSV_LAST; i++)
45f59c0347SQu Wenruo ret += qgroup->rsv.values[i];
46f59c0347SQu Wenruo
47f59c0347SQu Wenruo return ret;
48f59c0347SQu Wenruo }
49f59c0347SQu Wenruo
50f59c0347SQu Wenruo #ifdef CONFIG_BTRFS_DEBUG
qgroup_rsv_type_str(enum btrfs_qgroup_rsv_type type)51f59c0347SQu Wenruo static const char *qgroup_rsv_type_str(enum btrfs_qgroup_rsv_type type)
52f59c0347SQu Wenruo {
53f59c0347SQu Wenruo if (type == BTRFS_QGROUP_RSV_DATA)
54f59c0347SQu Wenruo return "data";
55733e03a0SQu Wenruo if (type == BTRFS_QGROUP_RSV_META_PERTRANS)
56733e03a0SQu Wenruo return "meta_pertrans";
57733e03a0SQu Wenruo if (type == BTRFS_QGROUP_RSV_META_PREALLOC)
58733e03a0SQu Wenruo return "meta_prealloc";
59f59c0347SQu Wenruo return NULL;
60f59c0347SQu Wenruo }
61f59c0347SQu Wenruo #endif
62f59c0347SQu Wenruo
qgroup_rsv_add(struct btrfs_fs_info * fs_info,struct btrfs_qgroup * qgroup,u64 num_bytes,enum btrfs_qgroup_rsv_type type)6364ee4e75SQu Wenruo static void qgroup_rsv_add(struct btrfs_fs_info *fs_info,
6464ee4e75SQu Wenruo struct btrfs_qgroup *qgroup, u64 num_bytes,
65f59c0347SQu Wenruo enum btrfs_qgroup_rsv_type type)
66f59c0347SQu Wenruo {
6764ee4e75SQu Wenruo trace_qgroup_update_reserve(fs_info, qgroup, num_bytes, type);
68f59c0347SQu Wenruo qgroup->rsv.values[type] += num_bytes;
69f59c0347SQu Wenruo }
70f59c0347SQu Wenruo
qgroup_rsv_release(struct btrfs_fs_info * fs_info,struct btrfs_qgroup * qgroup,u64 num_bytes,enum btrfs_qgroup_rsv_type type)7164ee4e75SQu Wenruo static void qgroup_rsv_release(struct btrfs_fs_info *fs_info,
7264ee4e75SQu Wenruo struct btrfs_qgroup *qgroup, u64 num_bytes,
73f59c0347SQu Wenruo enum btrfs_qgroup_rsv_type type)
74f59c0347SQu Wenruo {
7564ee4e75SQu Wenruo trace_qgroup_update_reserve(fs_info, qgroup, -(s64)num_bytes, type);
76f59c0347SQu Wenruo if (qgroup->rsv.values[type] >= num_bytes) {
77f59c0347SQu Wenruo qgroup->rsv.values[type] -= num_bytes;
78f59c0347SQu Wenruo return;
79f59c0347SQu Wenruo }
80f59c0347SQu Wenruo #ifdef CONFIG_BTRFS_DEBUG
81f59c0347SQu Wenruo WARN_RATELIMIT(1,
82f59c0347SQu Wenruo "qgroup %llu %s reserved space underflow, have %llu to free %llu",
83f59c0347SQu Wenruo qgroup->qgroupid, qgroup_rsv_type_str(type),
84f59c0347SQu Wenruo qgroup->rsv.values[type], num_bytes);
85f59c0347SQu Wenruo #endif
86f59c0347SQu Wenruo qgroup->rsv.values[type] = 0;
87f59c0347SQu Wenruo }
88f59c0347SQu Wenruo
qgroup_rsv_add_by_qgroup(struct btrfs_fs_info * fs_info,struct btrfs_qgroup * dest,struct btrfs_qgroup * src)8964ee4e75SQu Wenruo static void qgroup_rsv_add_by_qgroup(struct btrfs_fs_info *fs_info,
9064ee4e75SQu Wenruo struct btrfs_qgroup *dest,
91f59c0347SQu Wenruo struct btrfs_qgroup *src)
92f59c0347SQu Wenruo {
93f59c0347SQu Wenruo int i;
94f59c0347SQu Wenruo
95f59c0347SQu Wenruo for (i = 0; i < BTRFS_QGROUP_RSV_LAST; i++)
9664ee4e75SQu Wenruo qgroup_rsv_add(fs_info, dest, src->rsv.values[i], i);
97f59c0347SQu Wenruo }
98f59c0347SQu Wenruo
qgroup_rsv_release_by_qgroup(struct btrfs_fs_info * fs_info,struct btrfs_qgroup * dest,struct btrfs_qgroup * src)9964ee4e75SQu Wenruo static void qgroup_rsv_release_by_qgroup(struct btrfs_fs_info *fs_info,
10064ee4e75SQu Wenruo struct btrfs_qgroup *dest,
101f59c0347SQu Wenruo struct btrfs_qgroup *src)
102f59c0347SQu Wenruo {
103f59c0347SQu Wenruo int i;
104f59c0347SQu Wenruo
105f59c0347SQu Wenruo for (i = 0; i < BTRFS_QGROUP_RSV_LAST; i++)
10664ee4e75SQu Wenruo qgroup_rsv_release(fs_info, dest, src->rsv.values[i], i);
107f59c0347SQu Wenruo }
108f59c0347SQu Wenruo
btrfs_qgroup_update_old_refcnt(struct btrfs_qgroup * qg,u64 seq,int mod)1099c542136SQu Wenruo static void btrfs_qgroup_update_old_refcnt(struct btrfs_qgroup *qg, u64 seq,
1109c542136SQu Wenruo int mod)
1119c542136SQu Wenruo {
1129c542136SQu Wenruo if (qg->old_refcnt < seq)
1139c542136SQu Wenruo qg->old_refcnt = seq;
1149c542136SQu Wenruo qg->old_refcnt += mod;
1159c542136SQu Wenruo }
1169c542136SQu Wenruo
btrfs_qgroup_update_new_refcnt(struct btrfs_qgroup * qg,u64 seq,int mod)1179c542136SQu Wenruo static void btrfs_qgroup_update_new_refcnt(struct btrfs_qgroup *qg, u64 seq,
1189c542136SQu Wenruo int mod)
1199c542136SQu Wenruo {
1209c542136SQu Wenruo if (qg->new_refcnt < seq)
1219c542136SQu Wenruo qg->new_refcnt = seq;
1229c542136SQu Wenruo qg->new_refcnt += mod;
1239c542136SQu Wenruo }
1249c542136SQu Wenruo
btrfs_qgroup_get_old_refcnt(struct btrfs_qgroup * qg,u64 seq)1259c542136SQu Wenruo static inline u64 btrfs_qgroup_get_old_refcnt(struct btrfs_qgroup *qg, u64 seq)
1269c542136SQu Wenruo {
1279c542136SQu Wenruo if (qg->old_refcnt < seq)
1289c542136SQu Wenruo return 0;
1299c542136SQu Wenruo return qg->old_refcnt - seq;
1309c542136SQu Wenruo }
1319c542136SQu Wenruo
btrfs_qgroup_get_new_refcnt(struct btrfs_qgroup * qg,u64 seq)1329c542136SQu Wenruo static inline u64 btrfs_qgroup_get_new_refcnt(struct btrfs_qgroup *qg, u64 seq)
1339c542136SQu Wenruo {
1349c542136SQu Wenruo if (qg->new_refcnt < seq)
1359c542136SQu Wenruo return 0;
1369c542136SQu Wenruo return qg->new_refcnt - seq;
1379c542136SQu Wenruo }
1389c542136SQu Wenruo
139bed92eaeSArne Jansen /*
140bed92eaeSArne Jansen * glue structure to represent the relations between qgroups.
141bed92eaeSArne Jansen */
142bed92eaeSArne Jansen struct btrfs_qgroup_list {
143bed92eaeSArne Jansen struct list_head next_group;
144bed92eaeSArne Jansen struct list_head next_member;
145bed92eaeSArne Jansen struct btrfs_qgroup *group;
146bed92eaeSArne Jansen struct btrfs_qgroup *member;
147bed92eaeSArne Jansen };
148bed92eaeSArne Jansen
qgroup_to_aux(struct btrfs_qgroup * qg)149ef2fff64SDavid Sterba static inline u64 qgroup_to_aux(struct btrfs_qgroup *qg)
150ef2fff64SDavid Sterba {
151ef2fff64SDavid Sterba return (u64)(uintptr_t)qg;
152ef2fff64SDavid Sterba }
153ef2fff64SDavid Sterba
unode_aux_to_qgroup(struct ulist_node * n)154ef2fff64SDavid Sterba static inline struct btrfs_qgroup* unode_aux_to_qgroup(struct ulist_node *n)
155ef2fff64SDavid Sterba {
156ef2fff64SDavid Sterba return (struct btrfs_qgroup *)(uintptr_t)n->aux;
157ef2fff64SDavid Sterba }
158fcebe456SJosef Bacik
159b382a324SJan Schmidt static int
160b382a324SJan Schmidt qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
161b382a324SJan Schmidt int init_flags);
162b382a324SJan Schmidt static void qgroup_rescan_zero_tracking(struct btrfs_fs_info *fs_info);
1632f232036SJan Schmidt
16458400fceSWang Shilong /* must be called with qgroup_ioctl_lock held */
find_qgroup_rb(struct btrfs_fs_info * fs_info,u64 qgroupid)165bed92eaeSArne Jansen static struct btrfs_qgroup *find_qgroup_rb(struct btrfs_fs_info *fs_info,
166bed92eaeSArne Jansen u64 qgroupid)
167bed92eaeSArne Jansen {
168bed92eaeSArne Jansen struct rb_node *n = fs_info->qgroup_tree.rb_node;
169bed92eaeSArne Jansen struct btrfs_qgroup *qgroup;
170bed92eaeSArne Jansen
171bed92eaeSArne Jansen while (n) {
172bed92eaeSArne Jansen qgroup = rb_entry(n, struct btrfs_qgroup, node);
173bed92eaeSArne Jansen if (qgroup->qgroupid < qgroupid)
174bed92eaeSArne Jansen n = n->rb_left;
175bed92eaeSArne Jansen else if (qgroup->qgroupid > qgroupid)
176bed92eaeSArne Jansen n = n->rb_right;
177bed92eaeSArne Jansen else
178bed92eaeSArne Jansen return qgroup;
179bed92eaeSArne Jansen }
180bed92eaeSArne Jansen return NULL;
181bed92eaeSArne Jansen }
182bed92eaeSArne Jansen
183bed92eaeSArne Jansen /* must be called with qgroup_lock held */
add_qgroup_rb(struct btrfs_fs_info * fs_info,u64 qgroupid)184bed92eaeSArne Jansen static struct btrfs_qgroup *add_qgroup_rb(struct btrfs_fs_info *fs_info,
185bed92eaeSArne Jansen u64 qgroupid)
186bed92eaeSArne Jansen {
187bed92eaeSArne Jansen struct rb_node **p = &fs_info->qgroup_tree.rb_node;
188bed92eaeSArne Jansen struct rb_node *parent = NULL;
189bed92eaeSArne Jansen struct btrfs_qgroup *qgroup;
190bed92eaeSArne Jansen
191bed92eaeSArne Jansen while (*p) {
192bed92eaeSArne Jansen parent = *p;
193bed92eaeSArne Jansen qgroup = rb_entry(parent, struct btrfs_qgroup, node);
194bed92eaeSArne Jansen
195bed92eaeSArne Jansen if (qgroup->qgroupid < qgroupid)
196bed92eaeSArne Jansen p = &(*p)->rb_left;
197bed92eaeSArne Jansen else if (qgroup->qgroupid > qgroupid)
198bed92eaeSArne Jansen p = &(*p)->rb_right;
199bed92eaeSArne Jansen else
200bed92eaeSArne Jansen return qgroup;
201bed92eaeSArne Jansen }
202bed92eaeSArne Jansen
203bed92eaeSArne Jansen qgroup = kzalloc(sizeof(*qgroup), GFP_ATOMIC);
204bed92eaeSArne Jansen if (!qgroup)
205bed92eaeSArne Jansen return ERR_PTR(-ENOMEM);
206bed92eaeSArne Jansen
207bed92eaeSArne Jansen qgroup->qgroupid = qgroupid;
208bed92eaeSArne Jansen INIT_LIST_HEAD(&qgroup->groups);
209bed92eaeSArne Jansen INIT_LIST_HEAD(&qgroup->members);
210bed92eaeSArne Jansen INIT_LIST_HEAD(&qgroup->dirty);
2111c9a5c49SQu Wenruo INIT_LIST_HEAD(&qgroup->iterator);
212bed92eaeSArne Jansen
213bed92eaeSArne Jansen rb_link_node(&qgroup->node, parent, p);
214bed92eaeSArne Jansen rb_insert_color(&qgroup->node, &fs_info->qgroup_tree);
215bed92eaeSArne Jansen
216bed92eaeSArne Jansen return qgroup;
217bed92eaeSArne Jansen }
218bed92eaeSArne Jansen
__del_qgroup_rb(struct btrfs_fs_info * fs_info,struct btrfs_qgroup * qgroup)21949e5fb46SQu Wenruo static void __del_qgroup_rb(struct btrfs_fs_info *fs_info,
22049e5fb46SQu Wenruo struct btrfs_qgroup *qgroup)
221bed92eaeSArne Jansen {
222bed92eaeSArne Jansen struct btrfs_qgroup_list *list;
223bed92eaeSArne Jansen
224bed92eaeSArne Jansen list_del(&qgroup->dirty);
225bed92eaeSArne Jansen while (!list_empty(&qgroup->groups)) {
226bed92eaeSArne Jansen list = list_first_entry(&qgroup->groups,
227bed92eaeSArne Jansen struct btrfs_qgroup_list, next_group);
228bed92eaeSArne Jansen list_del(&list->next_group);
229bed92eaeSArne Jansen list_del(&list->next_member);
230bed92eaeSArne Jansen kfree(list);
231bed92eaeSArne Jansen }
232bed92eaeSArne Jansen
233bed92eaeSArne Jansen while (!list_empty(&qgroup->members)) {
234bed92eaeSArne Jansen list = list_first_entry(&qgroup->members,
235bed92eaeSArne Jansen struct btrfs_qgroup_list, next_member);
236bed92eaeSArne Jansen list_del(&list->next_group);
237bed92eaeSArne Jansen list_del(&list->next_member);
238bed92eaeSArne Jansen kfree(list);
239bed92eaeSArne Jansen }
2404082bd3dSWang Shilong }
241bed92eaeSArne Jansen
2424082bd3dSWang Shilong /* must be called with qgroup_lock held */
del_qgroup_rb(struct btrfs_fs_info * fs_info,u64 qgroupid)2434082bd3dSWang Shilong static int del_qgroup_rb(struct btrfs_fs_info *fs_info, u64 qgroupid)
2444082bd3dSWang Shilong {
2454082bd3dSWang Shilong struct btrfs_qgroup *qgroup = find_qgroup_rb(fs_info, qgroupid);
2464082bd3dSWang Shilong
2474082bd3dSWang Shilong if (!qgroup)
2484082bd3dSWang Shilong return -ENOENT;
2494082bd3dSWang Shilong
2504082bd3dSWang Shilong rb_erase(&qgroup->node, &fs_info->qgroup_tree);
25149e5fb46SQu Wenruo __del_qgroup_rb(fs_info, qgroup);
252bed92eaeSArne Jansen return 0;
253bed92eaeSArne Jansen }
254bed92eaeSArne Jansen
255a8f6f619SSidong Yang /*
256a8f6f619SSidong Yang * Add relation specified by two qgroups.
257a8f6f619SSidong Yang *
258a8f6f619SSidong Yang * Must be called with qgroup_lock held.
259a8f6f619SSidong Yang *
260a8f6f619SSidong Yang * Return: 0 on success
261a8f6f619SSidong Yang * -ENOENT if one of the qgroups is NULL
262a8f6f619SSidong Yang * <0 other errors
263a8f6f619SSidong Yang */
__add_relation_rb(struct btrfs_qgroup * member,struct btrfs_qgroup * parent)264a8f6f619SSidong Yang static int __add_relation_rb(struct btrfs_qgroup *member, struct btrfs_qgroup *parent)
265bed92eaeSArne Jansen {
266bed92eaeSArne Jansen struct btrfs_qgroup_list *list;
267bed92eaeSArne Jansen
268bed92eaeSArne Jansen if (!member || !parent)
269bed92eaeSArne Jansen return -ENOENT;
270bed92eaeSArne Jansen
271bed92eaeSArne Jansen list = kzalloc(sizeof(*list), GFP_ATOMIC);
272bed92eaeSArne Jansen if (!list)
273bed92eaeSArne Jansen return -ENOMEM;
274bed92eaeSArne Jansen
275bed92eaeSArne Jansen list->group = parent;
276bed92eaeSArne Jansen list->member = member;
277bed92eaeSArne Jansen list_add_tail(&list->next_group, &member->groups);
278bed92eaeSArne Jansen list_add_tail(&list->next_member, &parent->members);
279bed92eaeSArne Jansen
280bed92eaeSArne Jansen return 0;
281bed92eaeSArne Jansen }
282bed92eaeSArne Jansen
283a8f6f619SSidong Yang /*
28403ad2531SChristophe JAILLET * Add relation specified by two qgroup ids.
285a8f6f619SSidong Yang *
286a8f6f619SSidong Yang * Must be called with qgroup_lock held.
287a8f6f619SSidong Yang *
288a8f6f619SSidong Yang * Return: 0 on success
289a8f6f619SSidong Yang * -ENOENT if one of the ids does not exist
290a8f6f619SSidong Yang * <0 other errors
291a8f6f619SSidong Yang */
add_relation_rb(struct btrfs_fs_info * fs_info,u64 memberid,u64 parentid)292a8f6f619SSidong Yang static int add_relation_rb(struct btrfs_fs_info *fs_info, u64 memberid, u64 parentid)
293a8f6f619SSidong Yang {
294a8f6f619SSidong Yang struct btrfs_qgroup *member;
295a8f6f619SSidong Yang struct btrfs_qgroup *parent;
296a8f6f619SSidong Yang
297a8f6f619SSidong Yang member = find_qgroup_rb(fs_info, memberid);
298a8f6f619SSidong Yang parent = find_qgroup_rb(fs_info, parentid);
299a8f6f619SSidong Yang
300a8f6f619SSidong Yang return __add_relation_rb(member, parent);
301a8f6f619SSidong Yang }
302a8f6f619SSidong Yang
303a8f6f619SSidong Yang /* Must be called with qgroup_lock held */
del_relation_rb(struct btrfs_fs_info * fs_info,u64 memberid,u64 parentid)304bed92eaeSArne Jansen static int del_relation_rb(struct btrfs_fs_info *fs_info,
305bed92eaeSArne Jansen u64 memberid, u64 parentid)
306bed92eaeSArne Jansen {
307bed92eaeSArne Jansen struct btrfs_qgroup *member;
308bed92eaeSArne Jansen struct btrfs_qgroup *parent;
309bed92eaeSArne Jansen struct btrfs_qgroup_list *list;
310bed92eaeSArne Jansen
311bed92eaeSArne Jansen member = find_qgroup_rb(fs_info, memberid);
312bed92eaeSArne Jansen parent = find_qgroup_rb(fs_info, parentid);
313bed92eaeSArne Jansen if (!member || !parent)
314bed92eaeSArne Jansen return -ENOENT;
315bed92eaeSArne Jansen
316bed92eaeSArne Jansen list_for_each_entry(list, &member->groups, next_group) {
317bed92eaeSArne Jansen if (list->group == parent) {
318bed92eaeSArne Jansen list_del(&list->next_group);
319bed92eaeSArne Jansen list_del(&list->next_member);
320bed92eaeSArne Jansen kfree(list);
321bed92eaeSArne Jansen return 0;
322bed92eaeSArne Jansen }
323bed92eaeSArne Jansen }
324bed92eaeSArne Jansen return -ENOENT;
325bed92eaeSArne Jansen }
326bed92eaeSArne Jansen
327faa2dbf0SJosef Bacik #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
btrfs_verify_qgroup_counts(struct btrfs_fs_info * fs_info,u64 qgroupid,u64 rfer,u64 excl)328faa2dbf0SJosef Bacik int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid,
329faa2dbf0SJosef Bacik u64 rfer, u64 excl)
330faa2dbf0SJosef Bacik {
331faa2dbf0SJosef Bacik struct btrfs_qgroup *qgroup;
332faa2dbf0SJosef Bacik
333faa2dbf0SJosef Bacik qgroup = find_qgroup_rb(fs_info, qgroupid);
334faa2dbf0SJosef Bacik if (!qgroup)
335faa2dbf0SJosef Bacik return -EINVAL;
336faa2dbf0SJosef Bacik if (qgroup->rfer != rfer || qgroup->excl != excl)
337faa2dbf0SJosef Bacik return -EINVAL;
338faa2dbf0SJosef Bacik return 0;
339faa2dbf0SJosef Bacik }
340faa2dbf0SJosef Bacik #endif
341faa2dbf0SJosef Bacik
qgroup_mark_inconsistent(struct btrfs_fs_info * fs_info)342e562a8bdSQu Wenruo static void qgroup_mark_inconsistent(struct btrfs_fs_info *fs_info)
343e562a8bdSQu Wenruo {
344e562a8bdSQu Wenruo fs_info->qgroup_flags |= (BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT |
345e15e9f43SQu Wenruo BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN |
346e15e9f43SQu Wenruo BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING);
347e562a8bdSQu Wenruo }
348e562a8bdSQu Wenruo
349bed92eaeSArne Jansen /*
350bed92eaeSArne Jansen * The full config is read in one go, only called from open_ctree()
351bed92eaeSArne Jansen * It doesn't use any locking, as at this point we're still single-threaded
352bed92eaeSArne Jansen */
btrfs_read_qgroup_config(struct btrfs_fs_info * fs_info)353bed92eaeSArne Jansen int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
354bed92eaeSArne Jansen {
355bed92eaeSArne Jansen struct btrfs_key key;
356bed92eaeSArne Jansen struct btrfs_key found_key;
357bed92eaeSArne Jansen struct btrfs_root *quota_root = fs_info->quota_root;
358bed92eaeSArne Jansen struct btrfs_path *path = NULL;
359bed92eaeSArne Jansen struct extent_buffer *l;
360bed92eaeSArne Jansen int slot;
361bed92eaeSArne Jansen int ret = 0;
362bed92eaeSArne Jansen u64 flags = 0;
363b382a324SJan Schmidt u64 rescan_progress = 0;
364bed92eaeSArne Jansen
365afcdd129SJosef Bacik if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
366bed92eaeSArne Jansen return 0;
367bed92eaeSArne Jansen
368323b88f4SDavid Sterba fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL);
3691e8f9158SWang Shilong if (!fs_info->qgroup_ulist) {
3701e8f9158SWang Shilong ret = -ENOMEM;
3711e8f9158SWang Shilong goto out;
3721e8f9158SWang Shilong }
3731e8f9158SWang Shilong
374bed92eaeSArne Jansen path = btrfs_alloc_path();
375bed92eaeSArne Jansen if (!path) {
376bed92eaeSArne Jansen ret = -ENOMEM;
377bed92eaeSArne Jansen goto out;
378bed92eaeSArne Jansen }
379bed92eaeSArne Jansen
38049e5fb46SQu Wenruo ret = btrfs_sysfs_add_qgroups(fs_info);
38149e5fb46SQu Wenruo if (ret < 0)
38249e5fb46SQu Wenruo goto out;
383bed92eaeSArne Jansen /* default this to quota off, in case no status key is found */
384bed92eaeSArne Jansen fs_info->qgroup_flags = 0;
385bed92eaeSArne Jansen
386bed92eaeSArne Jansen /*
387bed92eaeSArne Jansen * pass 1: read status, all qgroup infos and limits
388bed92eaeSArne Jansen */
389bed92eaeSArne Jansen key.objectid = 0;
390bed92eaeSArne Jansen key.type = 0;
391bed92eaeSArne Jansen key.offset = 0;
392bed92eaeSArne Jansen ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 1);
393bed92eaeSArne Jansen if (ret)
394bed92eaeSArne Jansen goto out;
395bed92eaeSArne Jansen
396bed92eaeSArne Jansen while (1) {
397bed92eaeSArne Jansen struct btrfs_qgroup *qgroup;
398bed92eaeSArne Jansen
399bed92eaeSArne Jansen slot = path->slots[0];
400bed92eaeSArne Jansen l = path->nodes[0];
401bed92eaeSArne Jansen btrfs_item_key_to_cpu(l, &found_key, slot);
402bed92eaeSArne Jansen
403bed92eaeSArne Jansen if (found_key.type == BTRFS_QGROUP_STATUS_KEY) {
404bed92eaeSArne Jansen struct btrfs_qgroup_status_item *ptr;
405bed92eaeSArne Jansen
406bed92eaeSArne Jansen ptr = btrfs_item_ptr(l, slot,
407bed92eaeSArne Jansen struct btrfs_qgroup_status_item);
408bed92eaeSArne Jansen
409bed92eaeSArne Jansen if (btrfs_qgroup_status_version(l, ptr) !=
410bed92eaeSArne Jansen BTRFS_QGROUP_STATUS_VERSION) {
411efe120a0SFrank Holton btrfs_err(fs_info,
412efe120a0SFrank Holton "old qgroup version, quota disabled");
413bed92eaeSArne Jansen goto out;
414bed92eaeSArne Jansen }
415bed92eaeSArne Jansen if (btrfs_qgroup_status_generation(l, ptr) !=
416bed92eaeSArne Jansen fs_info->generation) {
417e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
418efe120a0SFrank Holton btrfs_err(fs_info,
4195d163e0eSJeff Mahoney "qgroup generation mismatch, marked as inconsistent");
420bed92eaeSArne Jansen }
421bed92eaeSArne Jansen fs_info->qgroup_flags = btrfs_qgroup_status_flags(l,
422bed92eaeSArne Jansen ptr);
423b382a324SJan Schmidt rescan_progress = btrfs_qgroup_status_rescan(l, ptr);
424bed92eaeSArne Jansen goto next1;
425bed92eaeSArne Jansen }
426bed92eaeSArne Jansen
427bed92eaeSArne Jansen if (found_key.type != BTRFS_QGROUP_INFO_KEY &&
428bed92eaeSArne Jansen found_key.type != BTRFS_QGROUP_LIMIT_KEY)
429bed92eaeSArne Jansen goto next1;
430bed92eaeSArne Jansen
431bed92eaeSArne Jansen qgroup = find_qgroup_rb(fs_info, found_key.offset);
432bed92eaeSArne Jansen if ((qgroup && found_key.type == BTRFS_QGROUP_INFO_KEY) ||
433bed92eaeSArne Jansen (!qgroup && found_key.type == BTRFS_QGROUP_LIMIT_KEY)) {
434d41e36a0SGeert Uytterhoeven btrfs_err(fs_info, "inconsistent qgroup config");
435e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
436bed92eaeSArne Jansen }
437bed92eaeSArne Jansen if (!qgroup) {
438bed92eaeSArne Jansen qgroup = add_qgroup_rb(fs_info, found_key.offset);
439bed92eaeSArne Jansen if (IS_ERR(qgroup)) {
440bed92eaeSArne Jansen ret = PTR_ERR(qgroup);
441bed92eaeSArne Jansen goto out;
442bed92eaeSArne Jansen }
443bed92eaeSArne Jansen }
44449e5fb46SQu Wenruo ret = btrfs_sysfs_add_one_qgroup(fs_info, qgroup);
44549e5fb46SQu Wenruo if (ret < 0)
44649e5fb46SQu Wenruo goto out;
44749e5fb46SQu Wenruo
448bed92eaeSArne Jansen switch (found_key.type) {
449bed92eaeSArne Jansen case BTRFS_QGROUP_INFO_KEY: {
450bed92eaeSArne Jansen struct btrfs_qgroup_info_item *ptr;
451bed92eaeSArne Jansen
452bed92eaeSArne Jansen ptr = btrfs_item_ptr(l, slot,
453bed92eaeSArne Jansen struct btrfs_qgroup_info_item);
454bed92eaeSArne Jansen qgroup->rfer = btrfs_qgroup_info_rfer(l, ptr);
455bed92eaeSArne Jansen qgroup->rfer_cmpr = btrfs_qgroup_info_rfer_cmpr(l, ptr);
456bed92eaeSArne Jansen qgroup->excl = btrfs_qgroup_info_excl(l, ptr);
457bed92eaeSArne Jansen qgroup->excl_cmpr = btrfs_qgroup_info_excl_cmpr(l, ptr);
458bed92eaeSArne Jansen /* generation currently unused */
459bed92eaeSArne Jansen break;
460bed92eaeSArne Jansen }
461bed92eaeSArne Jansen case BTRFS_QGROUP_LIMIT_KEY: {
462bed92eaeSArne Jansen struct btrfs_qgroup_limit_item *ptr;
463bed92eaeSArne Jansen
464bed92eaeSArne Jansen ptr = btrfs_item_ptr(l, slot,
465bed92eaeSArne Jansen struct btrfs_qgroup_limit_item);
466bed92eaeSArne Jansen qgroup->lim_flags = btrfs_qgroup_limit_flags(l, ptr);
467bed92eaeSArne Jansen qgroup->max_rfer = btrfs_qgroup_limit_max_rfer(l, ptr);
468bed92eaeSArne Jansen qgroup->max_excl = btrfs_qgroup_limit_max_excl(l, ptr);
469bed92eaeSArne Jansen qgroup->rsv_rfer = btrfs_qgroup_limit_rsv_rfer(l, ptr);
470bed92eaeSArne Jansen qgroup->rsv_excl = btrfs_qgroup_limit_rsv_excl(l, ptr);
471bed92eaeSArne Jansen break;
472bed92eaeSArne Jansen }
473bed92eaeSArne Jansen }
474bed92eaeSArne Jansen next1:
475bed92eaeSArne Jansen ret = btrfs_next_item(quota_root, path);
476bed92eaeSArne Jansen if (ret < 0)
477bed92eaeSArne Jansen goto out;
478bed92eaeSArne Jansen if (ret)
479bed92eaeSArne Jansen break;
480bed92eaeSArne Jansen }
481bed92eaeSArne Jansen btrfs_release_path(path);
482bed92eaeSArne Jansen
483bed92eaeSArne Jansen /*
484bed92eaeSArne Jansen * pass 2: read all qgroup relations
485bed92eaeSArne Jansen */
486bed92eaeSArne Jansen key.objectid = 0;
487bed92eaeSArne Jansen key.type = BTRFS_QGROUP_RELATION_KEY;
488bed92eaeSArne Jansen key.offset = 0;
489bed92eaeSArne Jansen ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 0);
490bed92eaeSArne Jansen if (ret)
491bed92eaeSArne Jansen goto out;
492bed92eaeSArne Jansen while (1) {
493bed92eaeSArne Jansen slot = path->slots[0];
494bed92eaeSArne Jansen l = path->nodes[0];
495bed92eaeSArne Jansen btrfs_item_key_to_cpu(l, &found_key, slot);
496bed92eaeSArne Jansen
497bed92eaeSArne Jansen if (found_key.type != BTRFS_QGROUP_RELATION_KEY)
498bed92eaeSArne Jansen goto next2;
499bed92eaeSArne Jansen
500bed92eaeSArne Jansen if (found_key.objectid > found_key.offset) {
501bed92eaeSArne Jansen /* parent <- member, not needed to build config */
502bed92eaeSArne Jansen /* FIXME should we omit the key completely? */
503bed92eaeSArne Jansen goto next2;
504bed92eaeSArne Jansen }
505bed92eaeSArne Jansen
506bed92eaeSArne Jansen ret = add_relation_rb(fs_info, found_key.objectid,
507bed92eaeSArne Jansen found_key.offset);
508ff24858cSArne Jansen if (ret == -ENOENT) {
509efe120a0SFrank Holton btrfs_warn(fs_info,
510efe120a0SFrank Holton "orphan qgroup relation 0x%llx->0x%llx",
511c1c9ff7cSGeert Uytterhoeven found_key.objectid, found_key.offset);
512ff24858cSArne Jansen ret = 0; /* ignore the error */
513ff24858cSArne Jansen }
514bed92eaeSArne Jansen if (ret)
515bed92eaeSArne Jansen goto out;
516bed92eaeSArne Jansen next2:
517bed92eaeSArne Jansen ret = btrfs_next_item(quota_root, path);
518bed92eaeSArne Jansen if (ret < 0)
519bed92eaeSArne Jansen goto out;
520bed92eaeSArne Jansen if (ret)
521bed92eaeSArne Jansen break;
522bed92eaeSArne Jansen }
523bed92eaeSArne Jansen out:
5243d05cad3SFilipe Manana btrfs_free_path(path);
525bed92eaeSArne Jansen fs_info->qgroup_flags |= flags;
526afcdd129SJosef Bacik if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON))
527afcdd129SJosef Bacik clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
528afcdd129SJosef Bacik else if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN &&
529afcdd129SJosef Bacik ret >= 0)
530b382a324SJan Schmidt ret = qgroup_rescan_init(fs_info, rescan_progress, 0);
531bed92eaeSArne Jansen
532eb1716afSJan Schmidt if (ret < 0) {
5331e8f9158SWang Shilong ulist_free(fs_info->qgroup_ulist);
534eb1716afSJan Schmidt fs_info->qgroup_ulist = NULL;
535b382a324SJan Schmidt fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
53649e5fb46SQu Wenruo btrfs_sysfs_del_qgroups(fs_info);
537eb1716afSJan Schmidt }
5381e8f9158SWang Shilong
539bed92eaeSArne Jansen return ret < 0 ? ret : 0;
540bed92eaeSArne Jansen }
541bed92eaeSArne Jansen
5425958253cSQu Wenruo /*
5435958253cSQu Wenruo * Called in close_ctree() when quota is still enabled. This verifies we don't
5445958253cSQu Wenruo * leak some reserved space.
5455958253cSQu Wenruo *
5465958253cSQu Wenruo * Return false if no reserved space is left.
5475958253cSQu Wenruo * Return true if some reserved space is leaked.
5485958253cSQu Wenruo */
btrfs_check_quota_leak(struct btrfs_fs_info * fs_info)5495958253cSQu Wenruo bool btrfs_check_quota_leak(struct btrfs_fs_info *fs_info)
5505958253cSQu Wenruo {
5515958253cSQu Wenruo struct rb_node *node;
5525958253cSQu Wenruo bool ret = false;
5535958253cSQu Wenruo
5545958253cSQu Wenruo if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
5555958253cSQu Wenruo return ret;
5565958253cSQu Wenruo /*
5575958253cSQu Wenruo * Since we're unmounting, there is no race and no need to grab qgroup
5585958253cSQu Wenruo * lock. And here we don't go post-order to provide a more user
5595958253cSQu Wenruo * friendly sorted result.
5605958253cSQu Wenruo */
5615958253cSQu Wenruo for (node = rb_first(&fs_info->qgroup_tree); node; node = rb_next(node)) {
5625958253cSQu Wenruo struct btrfs_qgroup *qgroup;
5635958253cSQu Wenruo int i;
5645958253cSQu Wenruo
5655958253cSQu Wenruo qgroup = rb_entry(node, struct btrfs_qgroup, node);
5665958253cSQu Wenruo for (i = 0; i < BTRFS_QGROUP_RSV_LAST; i++) {
5675958253cSQu Wenruo if (qgroup->rsv.values[i]) {
5685958253cSQu Wenruo ret = true;
5695958253cSQu Wenruo btrfs_warn(fs_info,
57006f67c47SQu Wenruo "qgroup %hu/%llu has unreleased space, type %d rsv %llu",
5715958253cSQu Wenruo btrfs_qgroup_level(qgroup->qgroupid),
5725958253cSQu Wenruo btrfs_qgroup_subvolid(qgroup->qgroupid),
5735958253cSQu Wenruo i, qgroup->rsv.values[i]);
5745958253cSQu Wenruo }
5755958253cSQu Wenruo }
5765958253cSQu Wenruo }
5775958253cSQu Wenruo return ret;
5785958253cSQu Wenruo }
5795958253cSQu Wenruo
580bed92eaeSArne Jansen /*
581e685da14SWang Shilong * This is called from close_ctree() or open_ctree() or btrfs_quota_disable(),
582e685da14SWang Shilong * first two are in single-threaded paths.And for the third one, we have set
583e685da14SWang Shilong * quota_root to be null with qgroup_lock held before, so it is safe to clean
584e685da14SWang Shilong * up the in-memory structures without qgroup_lock held.
585bed92eaeSArne Jansen */
btrfs_free_qgroup_config(struct btrfs_fs_info * fs_info)586bed92eaeSArne Jansen void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info)
587bed92eaeSArne Jansen {
588bed92eaeSArne Jansen struct rb_node *n;
589bed92eaeSArne Jansen struct btrfs_qgroup *qgroup;
590bed92eaeSArne Jansen
591bed92eaeSArne Jansen while ((n = rb_first(&fs_info->qgroup_tree))) {
592bed92eaeSArne Jansen qgroup = rb_entry(n, struct btrfs_qgroup, node);
593bed92eaeSArne Jansen rb_erase(n, &fs_info->qgroup_tree);
59449e5fb46SQu Wenruo __del_qgroup_rb(fs_info, qgroup);
5950bb78830SFilipe Manana btrfs_sysfs_del_one_qgroup(fs_info, qgroup);
5960bb78830SFilipe Manana kfree(qgroup);
597bed92eaeSArne Jansen }
5981e7bac1eSWang Shilong /*
59952042d8eSAndrea Gelmini * We call btrfs_free_qgroup_config() when unmounting
60001327610SNicholas D Steeves * filesystem and disabling quota, so we set qgroup_ulist
6011e7bac1eSWang Shilong * to be null here to avoid double free.
6021e7bac1eSWang Shilong */
6031e8f9158SWang Shilong ulist_free(fs_info->qgroup_ulist);
6041e7bac1eSWang Shilong fs_info->qgroup_ulist = NULL;
60549e5fb46SQu Wenruo btrfs_sysfs_del_qgroups(fs_info);
606bed92eaeSArne Jansen }
607bed92eaeSArne Jansen
add_qgroup_relation_item(struct btrfs_trans_handle * trans,u64 src,u64 dst)608711169c4SLu Fengqi static int add_qgroup_relation_item(struct btrfs_trans_handle *trans, u64 src,
609711169c4SLu Fengqi u64 dst)
610bed92eaeSArne Jansen {
611bed92eaeSArne Jansen int ret;
612711169c4SLu Fengqi struct btrfs_root *quota_root = trans->fs_info->quota_root;
613bed92eaeSArne Jansen struct btrfs_path *path;
614bed92eaeSArne Jansen struct btrfs_key key;
615bed92eaeSArne Jansen
616bed92eaeSArne Jansen path = btrfs_alloc_path();
617bed92eaeSArne Jansen if (!path)
618bed92eaeSArne Jansen return -ENOMEM;
619bed92eaeSArne Jansen
620bed92eaeSArne Jansen key.objectid = src;
621bed92eaeSArne Jansen key.type = BTRFS_QGROUP_RELATION_KEY;
622bed92eaeSArne Jansen key.offset = dst;
623bed92eaeSArne Jansen
624bed92eaeSArne Jansen ret = btrfs_insert_empty_item(trans, quota_root, path, &key, 0);
625bed92eaeSArne Jansen
626d5e09e38SFilipe Manana btrfs_mark_buffer_dirty(trans, path->nodes[0]);
627bed92eaeSArne Jansen
628bed92eaeSArne Jansen btrfs_free_path(path);
629bed92eaeSArne Jansen return ret;
630bed92eaeSArne Jansen }
631bed92eaeSArne Jansen
del_qgroup_relation_item(struct btrfs_trans_handle * trans,u64 src,u64 dst)63299d7f09aSLu Fengqi static int del_qgroup_relation_item(struct btrfs_trans_handle *trans, u64 src,
63399d7f09aSLu Fengqi u64 dst)
634bed92eaeSArne Jansen {
635bed92eaeSArne Jansen int ret;
63699d7f09aSLu Fengqi struct btrfs_root *quota_root = trans->fs_info->quota_root;
637bed92eaeSArne Jansen struct btrfs_path *path;
638bed92eaeSArne Jansen struct btrfs_key key;
639bed92eaeSArne Jansen
640bed92eaeSArne Jansen path = btrfs_alloc_path();
641bed92eaeSArne Jansen if (!path)
642bed92eaeSArne Jansen return -ENOMEM;
643bed92eaeSArne Jansen
644bed92eaeSArne Jansen key.objectid = src;
645bed92eaeSArne Jansen key.type = BTRFS_QGROUP_RELATION_KEY;
646bed92eaeSArne Jansen key.offset = dst;
647bed92eaeSArne Jansen
648bed92eaeSArne Jansen ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
649bed92eaeSArne Jansen if (ret < 0)
650bed92eaeSArne Jansen goto out;
651bed92eaeSArne Jansen
652bed92eaeSArne Jansen if (ret > 0) {
653bed92eaeSArne Jansen ret = -ENOENT;
654bed92eaeSArne Jansen goto out;
655bed92eaeSArne Jansen }
656bed92eaeSArne Jansen
657bed92eaeSArne Jansen ret = btrfs_del_item(trans, quota_root, path);
658bed92eaeSArne Jansen out:
659bed92eaeSArne Jansen btrfs_free_path(path);
660bed92eaeSArne Jansen return ret;
661bed92eaeSArne Jansen }
662bed92eaeSArne Jansen
add_qgroup_item(struct btrfs_trans_handle * trans,struct btrfs_root * quota_root,u64 qgroupid)663bed92eaeSArne Jansen static int add_qgroup_item(struct btrfs_trans_handle *trans,
664bed92eaeSArne Jansen struct btrfs_root *quota_root, u64 qgroupid)
665bed92eaeSArne Jansen {
666bed92eaeSArne Jansen int ret;
667bed92eaeSArne Jansen struct btrfs_path *path;
668bed92eaeSArne Jansen struct btrfs_qgroup_info_item *qgroup_info;
669bed92eaeSArne Jansen struct btrfs_qgroup_limit_item *qgroup_limit;
670bed92eaeSArne Jansen struct extent_buffer *leaf;
671bed92eaeSArne Jansen struct btrfs_key key;
672bed92eaeSArne Jansen
673f5ee5c9aSJeff Mahoney if (btrfs_is_testing(quota_root->fs_info))
674faa2dbf0SJosef Bacik return 0;
675fccb84c9SDavid Sterba
676bed92eaeSArne Jansen path = btrfs_alloc_path();
677bed92eaeSArne Jansen if (!path)
678bed92eaeSArne Jansen return -ENOMEM;
679bed92eaeSArne Jansen
680bed92eaeSArne Jansen key.objectid = 0;
681bed92eaeSArne Jansen key.type = BTRFS_QGROUP_INFO_KEY;
682bed92eaeSArne Jansen key.offset = qgroupid;
683bed92eaeSArne Jansen
6840b4699dcSMark Fasheh /*
6850b4699dcSMark Fasheh * Avoid a transaction abort by catching -EEXIST here. In that
6860b4699dcSMark Fasheh * case, we proceed by re-initializing the existing structure
6870b4699dcSMark Fasheh * on disk.
6880b4699dcSMark Fasheh */
6890b4699dcSMark Fasheh
690bed92eaeSArne Jansen ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
691bed92eaeSArne Jansen sizeof(*qgroup_info));
6920b4699dcSMark Fasheh if (ret && ret != -EEXIST)
693bed92eaeSArne Jansen goto out;
694bed92eaeSArne Jansen
695bed92eaeSArne Jansen leaf = path->nodes[0];
696bed92eaeSArne Jansen qgroup_info = btrfs_item_ptr(leaf, path->slots[0],
697bed92eaeSArne Jansen struct btrfs_qgroup_info_item);
698bed92eaeSArne Jansen btrfs_set_qgroup_info_generation(leaf, qgroup_info, trans->transid);
699bed92eaeSArne Jansen btrfs_set_qgroup_info_rfer(leaf, qgroup_info, 0);
700bed92eaeSArne Jansen btrfs_set_qgroup_info_rfer_cmpr(leaf, qgroup_info, 0);
701bed92eaeSArne Jansen btrfs_set_qgroup_info_excl(leaf, qgroup_info, 0);
702bed92eaeSArne Jansen btrfs_set_qgroup_info_excl_cmpr(leaf, qgroup_info, 0);
703bed92eaeSArne Jansen
704d5e09e38SFilipe Manana btrfs_mark_buffer_dirty(trans, leaf);
705bed92eaeSArne Jansen
706bed92eaeSArne Jansen btrfs_release_path(path);
707bed92eaeSArne Jansen
708bed92eaeSArne Jansen key.type = BTRFS_QGROUP_LIMIT_KEY;
709bed92eaeSArne Jansen ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
710bed92eaeSArne Jansen sizeof(*qgroup_limit));
7110b4699dcSMark Fasheh if (ret && ret != -EEXIST)
712bed92eaeSArne Jansen goto out;
713bed92eaeSArne Jansen
714bed92eaeSArne Jansen leaf = path->nodes[0];
715bed92eaeSArne Jansen qgroup_limit = btrfs_item_ptr(leaf, path->slots[0],
716bed92eaeSArne Jansen struct btrfs_qgroup_limit_item);
717bed92eaeSArne Jansen btrfs_set_qgroup_limit_flags(leaf, qgroup_limit, 0);
718bed92eaeSArne Jansen btrfs_set_qgroup_limit_max_rfer(leaf, qgroup_limit, 0);
719bed92eaeSArne Jansen btrfs_set_qgroup_limit_max_excl(leaf, qgroup_limit, 0);
720bed92eaeSArne Jansen btrfs_set_qgroup_limit_rsv_rfer(leaf, qgroup_limit, 0);
721bed92eaeSArne Jansen btrfs_set_qgroup_limit_rsv_excl(leaf, qgroup_limit, 0);
722bed92eaeSArne Jansen
723d5e09e38SFilipe Manana btrfs_mark_buffer_dirty(trans, leaf);
724bed92eaeSArne Jansen
725bed92eaeSArne Jansen ret = 0;
726bed92eaeSArne Jansen out:
727bed92eaeSArne Jansen btrfs_free_path(path);
728bed92eaeSArne Jansen return ret;
729bed92eaeSArne Jansen }
730bed92eaeSArne Jansen
del_qgroup_item(struct btrfs_trans_handle * trans,u64 qgroupid)73169104618SLu Fengqi static int del_qgroup_item(struct btrfs_trans_handle *trans, u64 qgroupid)
732bed92eaeSArne Jansen {
733bed92eaeSArne Jansen int ret;
73469104618SLu Fengqi struct btrfs_root *quota_root = trans->fs_info->quota_root;
735bed92eaeSArne Jansen struct btrfs_path *path;
736bed92eaeSArne Jansen struct btrfs_key key;
737bed92eaeSArne Jansen
738bed92eaeSArne Jansen path = btrfs_alloc_path();
739bed92eaeSArne Jansen if (!path)
740bed92eaeSArne Jansen return -ENOMEM;
741bed92eaeSArne Jansen
742bed92eaeSArne Jansen key.objectid = 0;
743bed92eaeSArne Jansen key.type = BTRFS_QGROUP_INFO_KEY;
744bed92eaeSArne Jansen key.offset = qgroupid;
745bed92eaeSArne Jansen ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
746bed92eaeSArne Jansen if (ret < 0)
747bed92eaeSArne Jansen goto out;
748bed92eaeSArne Jansen
749bed92eaeSArne Jansen if (ret > 0) {
750bed92eaeSArne Jansen ret = -ENOENT;
751bed92eaeSArne Jansen goto out;
752bed92eaeSArne Jansen }
753bed92eaeSArne Jansen
754bed92eaeSArne Jansen ret = btrfs_del_item(trans, quota_root, path);
755bed92eaeSArne Jansen if (ret)
756bed92eaeSArne Jansen goto out;
757bed92eaeSArne Jansen
758bed92eaeSArne Jansen btrfs_release_path(path);
759bed92eaeSArne Jansen
760bed92eaeSArne Jansen key.type = BTRFS_QGROUP_LIMIT_KEY;
761bed92eaeSArne Jansen ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
762bed92eaeSArne Jansen if (ret < 0)
763bed92eaeSArne Jansen goto out;
764bed92eaeSArne Jansen
765bed92eaeSArne Jansen if (ret > 0) {
766bed92eaeSArne Jansen ret = -ENOENT;
767bed92eaeSArne Jansen goto out;
768bed92eaeSArne Jansen }
769bed92eaeSArne Jansen
770bed92eaeSArne Jansen ret = btrfs_del_item(trans, quota_root, path);
771bed92eaeSArne Jansen
772bed92eaeSArne Jansen out:
773bed92eaeSArne Jansen btrfs_free_path(path);
774bed92eaeSArne Jansen return ret;
775bed92eaeSArne Jansen }
776bed92eaeSArne Jansen
update_qgroup_limit_item(struct btrfs_trans_handle * trans,struct btrfs_qgroup * qgroup)777bed92eaeSArne Jansen static int update_qgroup_limit_item(struct btrfs_trans_handle *trans,
7781510e71cSDongsheng Yang struct btrfs_qgroup *qgroup)
779bed92eaeSArne Jansen {
780ac8a866aSLu Fengqi struct btrfs_root *quota_root = trans->fs_info->quota_root;
781bed92eaeSArne Jansen struct btrfs_path *path;
782bed92eaeSArne Jansen struct btrfs_key key;
783bed92eaeSArne Jansen struct extent_buffer *l;
784bed92eaeSArne Jansen struct btrfs_qgroup_limit_item *qgroup_limit;
785bed92eaeSArne Jansen int ret;
786bed92eaeSArne Jansen int slot;
787bed92eaeSArne Jansen
788bed92eaeSArne Jansen key.objectid = 0;
789bed92eaeSArne Jansen key.type = BTRFS_QGROUP_LIMIT_KEY;
7901510e71cSDongsheng Yang key.offset = qgroup->qgroupid;
791bed92eaeSArne Jansen
792bed92eaeSArne Jansen path = btrfs_alloc_path();
79384cbe2f7SWang Shilong if (!path)
79484cbe2f7SWang Shilong return -ENOMEM;
79584cbe2f7SWang Shilong
796ac8a866aSLu Fengqi ret = btrfs_search_slot(trans, quota_root, &key, path, 0, 1);
797bed92eaeSArne Jansen if (ret > 0)
798bed92eaeSArne Jansen ret = -ENOENT;
799bed92eaeSArne Jansen
800bed92eaeSArne Jansen if (ret)
801bed92eaeSArne Jansen goto out;
802bed92eaeSArne Jansen
803bed92eaeSArne Jansen l = path->nodes[0];
804bed92eaeSArne Jansen slot = path->slots[0];
805a3df41eeSValentina Giusti qgroup_limit = btrfs_item_ptr(l, slot, struct btrfs_qgroup_limit_item);
8061510e71cSDongsheng Yang btrfs_set_qgroup_limit_flags(l, qgroup_limit, qgroup->lim_flags);
8071510e71cSDongsheng Yang btrfs_set_qgroup_limit_max_rfer(l, qgroup_limit, qgroup->max_rfer);
8081510e71cSDongsheng Yang btrfs_set_qgroup_limit_max_excl(l, qgroup_limit, qgroup->max_excl);
8091510e71cSDongsheng Yang btrfs_set_qgroup_limit_rsv_rfer(l, qgroup_limit, qgroup->rsv_rfer);
8101510e71cSDongsheng Yang btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, qgroup->rsv_excl);
811bed92eaeSArne Jansen
812d5e09e38SFilipe Manana btrfs_mark_buffer_dirty(trans, l);
813bed92eaeSArne Jansen
814bed92eaeSArne Jansen out:
815bed92eaeSArne Jansen btrfs_free_path(path);
816bed92eaeSArne Jansen return ret;
817bed92eaeSArne Jansen }
818bed92eaeSArne Jansen
update_qgroup_info_item(struct btrfs_trans_handle * trans,struct btrfs_qgroup * qgroup)819bed92eaeSArne Jansen static int update_qgroup_info_item(struct btrfs_trans_handle *trans,
820bed92eaeSArne Jansen struct btrfs_qgroup *qgroup)
821bed92eaeSArne Jansen {
8223e07e9a0SLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
8233e07e9a0SLu Fengqi struct btrfs_root *quota_root = fs_info->quota_root;
824bed92eaeSArne Jansen struct btrfs_path *path;
825bed92eaeSArne Jansen struct btrfs_key key;
826bed92eaeSArne Jansen struct extent_buffer *l;
827bed92eaeSArne Jansen struct btrfs_qgroup_info_item *qgroup_info;
828bed92eaeSArne Jansen int ret;
829bed92eaeSArne Jansen int slot;
830bed92eaeSArne Jansen
8313e07e9a0SLu Fengqi if (btrfs_is_testing(fs_info))
832faa2dbf0SJosef Bacik return 0;
833fccb84c9SDavid Sterba
834bed92eaeSArne Jansen key.objectid = 0;
835bed92eaeSArne Jansen key.type = BTRFS_QGROUP_INFO_KEY;
836bed92eaeSArne Jansen key.offset = qgroup->qgroupid;
837bed92eaeSArne Jansen
838bed92eaeSArne Jansen path = btrfs_alloc_path();
83984cbe2f7SWang Shilong if (!path)
84084cbe2f7SWang Shilong return -ENOMEM;
84184cbe2f7SWang Shilong
8423e07e9a0SLu Fengqi ret = btrfs_search_slot(trans, quota_root, &key, path, 0, 1);
843bed92eaeSArne Jansen if (ret > 0)
844bed92eaeSArne Jansen ret = -ENOENT;
845bed92eaeSArne Jansen
846bed92eaeSArne Jansen if (ret)
847bed92eaeSArne Jansen goto out;
848bed92eaeSArne Jansen
849bed92eaeSArne Jansen l = path->nodes[0];
850bed92eaeSArne Jansen slot = path->slots[0];
851a3df41eeSValentina Giusti qgroup_info = btrfs_item_ptr(l, slot, struct btrfs_qgroup_info_item);
852bed92eaeSArne Jansen btrfs_set_qgroup_info_generation(l, qgroup_info, trans->transid);
853bed92eaeSArne Jansen btrfs_set_qgroup_info_rfer(l, qgroup_info, qgroup->rfer);
854bed92eaeSArne Jansen btrfs_set_qgroup_info_rfer_cmpr(l, qgroup_info, qgroup->rfer_cmpr);
855bed92eaeSArne Jansen btrfs_set_qgroup_info_excl(l, qgroup_info, qgroup->excl);
856bed92eaeSArne Jansen btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, qgroup->excl_cmpr);
857bed92eaeSArne Jansen
858d5e09e38SFilipe Manana btrfs_mark_buffer_dirty(trans, l);
859bed92eaeSArne Jansen
860bed92eaeSArne Jansen out:
861bed92eaeSArne Jansen btrfs_free_path(path);
862bed92eaeSArne Jansen return ret;
863bed92eaeSArne Jansen }
864bed92eaeSArne Jansen
update_qgroup_status_item(struct btrfs_trans_handle * trans)8652e980acdSLu Fengqi static int update_qgroup_status_item(struct btrfs_trans_handle *trans)
866bed92eaeSArne Jansen {
8672e980acdSLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
8682e980acdSLu Fengqi struct btrfs_root *quota_root = fs_info->quota_root;
869bed92eaeSArne Jansen struct btrfs_path *path;
870bed92eaeSArne Jansen struct btrfs_key key;
871bed92eaeSArne Jansen struct extent_buffer *l;
872bed92eaeSArne Jansen struct btrfs_qgroup_status_item *ptr;
873bed92eaeSArne Jansen int ret;
874bed92eaeSArne Jansen int slot;
875bed92eaeSArne Jansen
876bed92eaeSArne Jansen key.objectid = 0;
877bed92eaeSArne Jansen key.type = BTRFS_QGROUP_STATUS_KEY;
878bed92eaeSArne Jansen key.offset = 0;
879bed92eaeSArne Jansen
880bed92eaeSArne Jansen path = btrfs_alloc_path();
88184cbe2f7SWang Shilong if (!path)
88284cbe2f7SWang Shilong return -ENOMEM;
88384cbe2f7SWang Shilong
8842e980acdSLu Fengqi ret = btrfs_search_slot(trans, quota_root, &key, path, 0, 1);
885bed92eaeSArne Jansen if (ret > 0)
886bed92eaeSArne Jansen ret = -ENOENT;
887bed92eaeSArne Jansen
888bed92eaeSArne Jansen if (ret)
889bed92eaeSArne Jansen goto out;
890bed92eaeSArne Jansen
891bed92eaeSArne Jansen l = path->nodes[0];
892bed92eaeSArne Jansen slot = path->slots[0];
893bed92eaeSArne Jansen ptr = btrfs_item_ptr(l, slot, struct btrfs_qgroup_status_item);
894e71564c0SQu Wenruo btrfs_set_qgroup_status_flags(l, ptr, fs_info->qgroup_flags &
895e71564c0SQu Wenruo BTRFS_QGROUP_STATUS_FLAGS_MASK);
896bed92eaeSArne Jansen btrfs_set_qgroup_status_generation(l, ptr, trans->transid);
8972f232036SJan Schmidt btrfs_set_qgroup_status_rescan(l, ptr,
8982f232036SJan Schmidt fs_info->qgroup_rescan_progress.objectid);
899bed92eaeSArne Jansen
900d5e09e38SFilipe Manana btrfs_mark_buffer_dirty(trans, l);
901bed92eaeSArne Jansen
902bed92eaeSArne Jansen out:
903bed92eaeSArne Jansen btrfs_free_path(path);
904bed92eaeSArne Jansen return ret;
905bed92eaeSArne Jansen }
906bed92eaeSArne Jansen
907bed92eaeSArne Jansen /*
908bed92eaeSArne Jansen * called with qgroup_lock held
909bed92eaeSArne Jansen */
btrfs_clean_quota_tree(struct btrfs_trans_handle * trans,struct btrfs_root * root)910bed92eaeSArne Jansen static int btrfs_clean_quota_tree(struct btrfs_trans_handle *trans,
911bed92eaeSArne Jansen struct btrfs_root *root)
912bed92eaeSArne Jansen {
913bed92eaeSArne Jansen struct btrfs_path *path;
914bed92eaeSArne Jansen struct btrfs_key key;
91506b3a860SWang Shilong struct extent_buffer *leaf = NULL;
916bed92eaeSArne Jansen int ret;
91706b3a860SWang Shilong int nr = 0;
918bed92eaeSArne Jansen
919bed92eaeSArne Jansen path = btrfs_alloc_path();
920bed92eaeSArne Jansen if (!path)
921bed92eaeSArne Jansen return -ENOMEM;
922bed92eaeSArne Jansen
923bed92eaeSArne Jansen key.objectid = 0;
924bed92eaeSArne Jansen key.offset = 0;
925bed92eaeSArne Jansen key.type = 0;
926bed92eaeSArne Jansen
92706b3a860SWang Shilong while (1) {
928bed92eaeSArne Jansen ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
92906b3a860SWang Shilong if (ret < 0)
93006b3a860SWang Shilong goto out;
93106b3a860SWang Shilong leaf = path->nodes[0];
93206b3a860SWang Shilong nr = btrfs_header_nritems(leaf);
93306b3a860SWang Shilong if (!nr)
934bed92eaeSArne Jansen break;
93506b3a860SWang Shilong /*
93606b3a860SWang Shilong * delete the leaf one by one
93706b3a860SWang Shilong * since the whole tree is going
93806b3a860SWang Shilong * to be deleted.
93906b3a860SWang Shilong */
94006b3a860SWang Shilong path->slots[0] = 0;
94106b3a860SWang Shilong ret = btrfs_del_items(trans, root, path, 0, nr);
942bed92eaeSArne Jansen if (ret)
943bed92eaeSArne Jansen goto out;
94406b3a860SWang Shilong
945bed92eaeSArne Jansen btrfs_release_path(path);
946bed92eaeSArne Jansen }
947bed92eaeSArne Jansen ret = 0;
948bed92eaeSArne Jansen out:
949bed92eaeSArne Jansen btrfs_free_path(path);
950bed92eaeSArne Jansen return ret;
951bed92eaeSArne Jansen }
952bed92eaeSArne Jansen
btrfs_quota_enable(struct btrfs_fs_info * fs_info)953340f1aa2SNikolay Borisov int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
954bed92eaeSArne Jansen {
955bed92eaeSArne Jansen struct btrfs_root *quota_root;
9567708f029SWang Shilong struct btrfs_root *tree_root = fs_info->tree_root;
957bed92eaeSArne Jansen struct btrfs_path *path = NULL;
958bed92eaeSArne Jansen struct btrfs_qgroup_status_item *ptr;
959bed92eaeSArne Jansen struct extent_buffer *leaf;
960bed92eaeSArne Jansen struct btrfs_key key;
9617708f029SWang Shilong struct btrfs_key found_key;
9627708f029SWang Shilong struct btrfs_qgroup *qgroup = NULL;
963340f1aa2SNikolay Borisov struct btrfs_trans_handle *trans = NULL;
964a855fbe6SFilipe Manana struct ulist *ulist = NULL;
965bed92eaeSArne Jansen int ret = 0;
9667708f029SWang Shilong int slot;
967bed92eaeSArne Jansen
968232796dfSFilipe Manana /*
969232796dfSFilipe Manana * We need to have subvol_sem write locked, to prevent races between
970232796dfSFilipe Manana * concurrent tasks trying to enable quotas, because we will unlock
971232796dfSFilipe Manana * and relock qgroup_ioctl_lock before setting fs_info->quota_root
972232796dfSFilipe Manana * and before setting BTRFS_FS_QUOTA_ENABLED.
973232796dfSFilipe Manana */
974232796dfSFilipe Manana lockdep_assert_held_write(&fs_info->subvol_sem);
975232796dfSFilipe Manana
976ef3eccc1SJosef Bacik if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
977ef3eccc1SJosef Bacik btrfs_err(fs_info,
978ef3eccc1SJosef Bacik "qgroups are currently unsupported in extent tree v2");
979ef3eccc1SJosef Bacik return -EINVAL;
980ef3eccc1SJosef Bacik }
981ef3eccc1SJosef Bacik
982f2f6ed3dSWang Shilong mutex_lock(&fs_info->qgroup_ioctl_lock);
9835d23515bSNikolay Borisov if (fs_info->quota_root)
984bed92eaeSArne Jansen goto out;
985bed92eaeSArne Jansen
986a855fbe6SFilipe Manana ulist = ulist_alloc(GFP_KERNEL);
987a855fbe6SFilipe Manana if (!ulist) {
9887503b83dSDavid Sterba ret = -ENOMEM;
9897503b83dSDavid Sterba goto out;
9907503b83dSDavid Sterba }
9917503b83dSDavid Sterba
99249e5fb46SQu Wenruo ret = btrfs_sysfs_add_qgroups(fs_info);
99349e5fb46SQu Wenruo if (ret < 0)
99449e5fb46SQu Wenruo goto out;
995a855fbe6SFilipe Manana
996a855fbe6SFilipe Manana /*
997a855fbe6SFilipe Manana * Unlock qgroup_ioctl_lock before starting the transaction. This is to
998a855fbe6SFilipe Manana * avoid lock acquisition inversion problems (reported by lockdep) between
999a855fbe6SFilipe Manana * qgroup_ioctl_lock and the vfs freeze semaphores, acquired when we
1000a855fbe6SFilipe Manana * start a transaction.
1001a855fbe6SFilipe Manana * After we started the transaction lock qgroup_ioctl_lock again and
1002a855fbe6SFilipe Manana * check if someone else created the quota root in the meanwhile. If so,
1003a855fbe6SFilipe Manana * just return success and release the transaction handle.
1004a855fbe6SFilipe Manana *
1005a855fbe6SFilipe Manana * Also we don't need to worry about someone else calling
1006a855fbe6SFilipe Manana * btrfs_sysfs_add_qgroups() after we unlock and getting an error because
1007a855fbe6SFilipe Manana * that function returns 0 (success) when the sysfs entries already exist.
1008a855fbe6SFilipe Manana */
1009a855fbe6SFilipe Manana mutex_unlock(&fs_info->qgroup_ioctl_lock);
1010a855fbe6SFilipe Manana
1011340f1aa2SNikolay Borisov /*
1012340f1aa2SNikolay Borisov * 1 for quota root item
1013340f1aa2SNikolay Borisov * 1 for BTRFS_QGROUP_STATUS item
1014340f1aa2SNikolay Borisov *
1015340f1aa2SNikolay Borisov * Yet we also need 2*n items for a QGROUP_INFO/QGROUP_LIMIT items
1016340f1aa2SNikolay Borisov * per subvolume. However those are not currently reserved since it
1017340f1aa2SNikolay Borisov * would be a lot of overkill.
1018340f1aa2SNikolay Borisov */
1019340f1aa2SNikolay Borisov trans = btrfs_start_transaction(tree_root, 2);
1020a855fbe6SFilipe Manana
1021a855fbe6SFilipe Manana mutex_lock(&fs_info->qgroup_ioctl_lock);
1022340f1aa2SNikolay Borisov if (IS_ERR(trans)) {
1023340f1aa2SNikolay Borisov ret = PTR_ERR(trans);
1024340f1aa2SNikolay Borisov trans = NULL;
1025340f1aa2SNikolay Borisov goto out;
1026340f1aa2SNikolay Borisov }
1027340f1aa2SNikolay Borisov
1028a855fbe6SFilipe Manana if (fs_info->quota_root)
1029a855fbe6SFilipe Manana goto out;
1030a855fbe6SFilipe Manana
1031a855fbe6SFilipe Manana fs_info->qgroup_ulist = ulist;
1032a855fbe6SFilipe Manana ulist = NULL;
1033a855fbe6SFilipe Manana
1034bed92eaeSArne Jansen /*
1035bed92eaeSArne Jansen * initially create the quota tree
1036bed92eaeSArne Jansen */
10379b7a2440SDavid Sterba quota_root = btrfs_create_tree(trans, BTRFS_QUOTA_TREE_OBJECTID);
1038bed92eaeSArne Jansen if (IS_ERR(quota_root)) {
1039bed92eaeSArne Jansen ret = PTR_ERR(quota_root);
1040340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
1041bed92eaeSArne Jansen goto out;
1042bed92eaeSArne Jansen }
1043bed92eaeSArne Jansen
1044bed92eaeSArne Jansen path = btrfs_alloc_path();
10455b7ff5b3STsutomu Itoh if (!path) {
10465b7ff5b3STsutomu Itoh ret = -ENOMEM;
1047340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
10485b7ff5b3STsutomu Itoh goto out_free_root;
10495b7ff5b3STsutomu Itoh }
1050bed92eaeSArne Jansen
1051bed92eaeSArne Jansen key.objectid = 0;
1052bed92eaeSArne Jansen key.type = BTRFS_QGROUP_STATUS_KEY;
1053bed92eaeSArne Jansen key.offset = 0;
1054bed92eaeSArne Jansen
1055bed92eaeSArne Jansen ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
1056bed92eaeSArne Jansen sizeof(*ptr));
1057340f1aa2SNikolay Borisov if (ret) {
1058340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
10595b7ff5b3STsutomu Itoh goto out_free_path;
1060340f1aa2SNikolay Borisov }
1061bed92eaeSArne Jansen
1062bed92eaeSArne Jansen leaf = path->nodes[0];
1063bed92eaeSArne Jansen ptr = btrfs_item_ptr(leaf, path->slots[0],
1064bed92eaeSArne Jansen struct btrfs_qgroup_status_item);
1065bed92eaeSArne Jansen btrfs_set_qgroup_status_generation(leaf, ptr, trans->transid);
1066bed92eaeSArne Jansen btrfs_set_qgroup_status_version(leaf, ptr, BTRFS_QGROUP_STATUS_VERSION);
1067bed92eaeSArne Jansen fs_info->qgroup_flags = BTRFS_QGROUP_STATUS_FLAG_ON |
1068bed92eaeSArne Jansen BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
1069e71564c0SQu Wenruo btrfs_set_qgroup_status_flags(leaf, ptr, fs_info->qgroup_flags &
1070e71564c0SQu Wenruo BTRFS_QGROUP_STATUS_FLAGS_MASK);
10712f232036SJan Schmidt btrfs_set_qgroup_status_rescan(leaf, ptr, 0);
1072bed92eaeSArne Jansen
1073d5e09e38SFilipe Manana btrfs_mark_buffer_dirty(trans, leaf);
1074bed92eaeSArne Jansen
10757708f029SWang Shilong key.objectid = 0;
10767708f029SWang Shilong key.type = BTRFS_ROOT_REF_KEY;
10777708f029SWang Shilong key.offset = 0;
10787708f029SWang Shilong
10797708f029SWang Shilong btrfs_release_path(path);
10807708f029SWang Shilong ret = btrfs_search_slot_for_read(tree_root, &key, path, 1, 0);
10817708f029SWang Shilong if (ret > 0)
10827708f029SWang Shilong goto out_add_root;
1083340f1aa2SNikolay Borisov if (ret < 0) {
1084340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
10857708f029SWang Shilong goto out_free_path;
1086340f1aa2SNikolay Borisov }
10877708f029SWang Shilong
10887708f029SWang Shilong while (1) {
10897708f029SWang Shilong slot = path->slots[0];
10907708f029SWang Shilong leaf = path->nodes[0];
10917708f029SWang Shilong btrfs_item_key_to_cpu(leaf, &found_key, slot);
10927708f029SWang Shilong
10937708f029SWang Shilong if (found_key.type == BTRFS_ROOT_REF_KEY) {
10945223cc60SJosef Bacik
10955223cc60SJosef Bacik /* Release locks on tree_root before we access quota_root */
10965223cc60SJosef Bacik btrfs_release_path(path);
10975223cc60SJosef Bacik
10987708f029SWang Shilong ret = add_qgroup_item(trans, quota_root,
10997708f029SWang Shilong found_key.offset);
1100340f1aa2SNikolay Borisov if (ret) {
1101340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
11027708f029SWang Shilong goto out_free_path;
1103340f1aa2SNikolay Borisov }
11047708f029SWang Shilong
11057708f029SWang Shilong qgroup = add_qgroup_rb(fs_info, found_key.offset);
11067708f029SWang Shilong if (IS_ERR(qgroup)) {
11077708f029SWang Shilong ret = PTR_ERR(qgroup);
1108340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
11097708f029SWang Shilong goto out_free_path;
11107708f029SWang Shilong }
111149e5fb46SQu Wenruo ret = btrfs_sysfs_add_one_qgroup(fs_info, qgroup);
111249e5fb46SQu Wenruo if (ret < 0) {
111349e5fb46SQu Wenruo btrfs_abort_transaction(trans, ret);
111449e5fb46SQu Wenruo goto out_free_path;
111549e5fb46SQu Wenruo }
11165223cc60SJosef Bacik ret = btrfs_search_slot_for_read(tree_root, &found_key,
11175223cc60SJosef Bacik path, 1, 0);
11185223cc60SJosef Bacik if (ret < 0) {
11195223cc60SJosef Bacik btrfs_abort_transaction(trans, ret);
11205223cc60SJosef Bacik goto out_free_path;
11215223cc60SJosef Bacik }
11225223cc60SJosef Bacik if (ret > 0) {
11235223cc60SJosef Bacik /*
11245223cc60SJosef Bacik * Shouldn't happen, but in case it does we
11255223cc60SJosef Bacik * don't need to do the btrfs_next_item, just
11265223cc60SJosef Bacik * continue.
11275223cc60SJosef Bacik */
11285223cc60SJosef Bacik continue;
11295223cc60SJosef Bacik }
11307708f029SWang Shilong }
11317708f029SWang Shilong ret = btrfs_next_item(tree_root, path);
1132340f1aa2SNikolay Borisov if (ret < 0) {
1133340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
11347708f029SWang Shilong goto out_free_path;
1135340f1aa2SNikolay Borisov }
11367708f029SWang Shilong if (ret)
11377708f029SWang Shilong break;
11387708f029SWang Shilong }
11397708f029SWang Shilong
11407708f029SWang Shilong out_add_root:
11417708f029SWang Shilong btrfs_release_path(path);
11427708f029SWang Shilong ret = add_qgroup_item(trans, quota_root, BTRFS_FS_TREE_OBJECTID);
1143340f1aa2SNikolay Borisov if (ret) {
1144340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
11457708f029SWang Shilong goto out_free_path;
1146340f1aa2SNikolay Borisov }
11477708f029SWang Shilong
11487708f029SWang Shilong qgroup = add_qgroup_rb(fs_info, BTRFS_FS_TREE_OBJECTID);
11497708f029SWang Shilong if (IS_ERR(qgroup)) {
11507708f029SWang Shilong ret = PTR_ERR(qgroup);
1151340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
11527708f029SWang Shilong goto out_free_path;
11537708f029SWang Shilong }
115449e5fb46SQu Wenruo ret = btrfs_sysfs_add_one_qgroup(fs_info, qgroup);
115549e5fb46SQu Wenruo if (ret < 0) {
115649e5fb46SQu Wenruo btrfs_abort_transaction(trans, ret);
115749e5fb46SQu Wenruo goto out_free_path;
115849e5fb46SQu Wenruo }
1159340f1aa2SNikolay Borisov
1160232796dfSFilipe Manana mutex_unlock(&fs_info->qgroup_ioctl_lock);
1161232796dfSFilipe Manana /*
1162232796dfSFilipe Manana * Commit the transaction while not holding qgroup_ioctl_lock, to avoid
1163232796dfSFilipe Manana * a deadlock with tasks concurrently doing other qgroup operations, such
1164232796dfSFilipe Manana * adding/removing qgroups or adding/deleting qgroup relations for example,
1165232796dfSFilipe Manana * because all qgroup operations first start or join a transaction and then
1166232796dfSFilipe Manana * lock the qgroup_ioctl_lock mutex.
1167232796dfSFilipe Manana * We are safe from a concurrent task trying to enable quotas, by calling
1168232796dfSFilipe Manana * this function, since we are serialized by fs_info->subvol_sem.
1169232796dfSFilipe Manana */
1170340f1aa2SNikolay Borisov ret = btrfs_commit_transaction(trans);
1171340f1aa2SNikolay Borisov trans = NULL;
1172232796dfSFilipe Manana mutex_lock(&fs_info->qgroup_ioctl_lock);
1173b9b8a41aSDan Carpenter if (ret)
1174340f1aa2SNikolay Borisov goto out_free_path;
1175340f1aa2SNikolay Borisov
11769a6f209eSFilipe Manana /*
11779a6f209eSFilipe Manana * Set quota enabled flag after committing the transaction, to avoid
11789a6f209eSFilipe Manana * deadlocks on fs_info->qgroup_ioctl_lock with concurrent snapshot
11799a6f209eSFilipe Manana * creation.
11809a6f209eSFilipe Manana */
11819a6f209eSFilipe Manana spin_lock(&fs_info->qgroup_lock);
11829a6f209eSFilipe Manana fs_info->quota_root = quota_root;
11839a6f209eSFilipe Manana set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
11849a6f209eSFilipe Manana spin_unlock(&fs_info->qgroup_lock);
11859a6f209eSFilipe Manana
11865d23515bSNikolay Borisov ret = qgroup_rescan_init(fs_info, 0, 1);
11875d23515bSNikolay Borisov if (!ret) {
11885d23515bSNikolay Borisov qgroup_rescan_zero_tracking(fs_info);
1189d61acbbfSQu Wenruo fs_info->qgroup_rescan_running = true;
11905d23515bSNikolay Borisov btrfs_queue_work(fs_info->qgroup_rescan_workers,
11915d23515bSNikolay Borisov &fs_info->qgroup_rescan_work);
1192331cd946SFilipe Manana } else {
1193331cd946SFilipe Manana /*
1194331cd946SFilipe Manana * We have set both BTRFS_FS_QUOTA_ENABLED and
1195331cd946SFilipe Manana * BTRFS_QGROUP_STATUS_FLAG_ON, so we can only fail with
1196331cd946SFilipe Manana * -EINPROGRESS. That can happen because someone started the
1197331cd946SFilipe Manana * rescan worker by calling quota rescan ioctl before we
1198331cd946SFilipe Manana * attempted to initialize the rescan worker. Failure due to
1199331cd946SFilipe Manana * quotas disabled in the meanwhile is not possible, because
1200331cd946SFilipe Manana * we are holding a write lock on fs_info->subvol_sem, which
1201331cd946SFilipe Manana * is also acquired when disabling quotas.
1202331cd946SFilipe Manana * Ignore such error, and any other error would need to undo
1203331cd946SFilipe Manana * everything we did in the transaction we just committed.
1204331cd946SFilipe Manana */
1205331cd946SFilipe Manana ASSERT(ret == -EINPROGRESS);
1206331cd946SFilipe Manana ret = 0;
12075d23515bSNikolay Borisov }
12085d23515bSNikolay Borisov
12095b7ff5b3STsutomu Itoh out_free_path:
1210bed92eaeSArne Jansen btrfs_free_path(path);
12115b7ff5b3STsutomu Itoh out_free_root:
12128c38938cSJosef Bacik if (ret)
121300246528SJosef Bacik btrfs_put_root(quota_root);
12145b7ff5b3STsutomu Itoh out:
1215eb1716afSJan Schmidt if (ret) {
12161e8f9158SWang Shilong ulist_free(fs_info->qgroup_ulist);
1217eb1716afSJan Schmidt fs_info->qgroup_ulist = NULL;
121849e5fb46SQu Wenruo btrfs_sysfs_del_qgroups(fs_info);
1219eb1716afSJan Schmidt }
1220f2f6ed3dSWang Shilong mutex_unlock(&fs_info->qgroup_ioctl_lock);
1221a855fbe6SFilipe Manana if (ret && trans)
1222a855fbe6SFilipe Manana btrfs_end_transaction(trans);
1223a855fbe6SFilipe Manana else if (trans)
1224a855fbe6SFilipe Manana ret = btrfs_end_transaction(trans);
1225a855fbe6SFilipe Manana ulist_free(ulist);
1226bed92eaeSArne Jansen return ret;
1227bed92eaeSArne Jansen }
1228bed92eaeSArne Jansen
btrfs_quota_disable(struct btrfs_fs_info * fs_info)1229340f1aa2SNikolay Borisov int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
1230bed92eaeSArne Jansen {
1231f88aeff5SFilipe Manana struct btrfs_root *quota_root = NULL;
1232340f1aa2SNikolay Borisov struct btrfs_trans_handle *trans = NULL;
1233bed92eaeSArne Jansen int ret = 0;
1234bed92eaeSArne Jansen
1235e804861bSShin'ichiro Kawasaki /*
12368a4a0b2aSFilipe Manana * We need to have subvol_sem write locked to prevent races with
12378a4a0b2aSFilipe Manana * snapshot creation.
1238e804861bSShin'ichiro Kawasaki */
1239e804861bSShin'ichiro Kawasaki lockdep_assert_held_write(&fs_info->subvol_sem);
1240e804861bSShin'ichiro Kawasaki
12418a4a0b2aSFilipe Manana /*
12428a4a0b2aSFilipe Manana * Lock the cleaner mutex to prevent races with concurrent relocation,
12438a4a0b2aSFilipe Manana * because relocation may be building backrefs for blocks of the quota
12448a4a0b2aSFilipe Manana * root while we are deleting the root. This is like dropping fs roots
12458a4a0b2aSFilipe Manana * of deleted snapshots/subvolumes, we need the same protection.
12468a4a0b2aSFilipe Manana *
12478a4a0b2aSFilipe Manana * This also prevents races between concurrent tasks trying to disable
12488a4a0b2aSFilipe Manana * quotas, because we will unlock and relock qgroup_ioctl_lock across
12498a4a0b2aSFilipe Manana * BTRFS_FS_QUOTA_ENABLED changes.
12508a4a0b2aSFilipe Manana */
12518a4a0b2aSFilipe Manana mutex_lock(&fs_info->cleaner_mutex);
12528a4a0b2aSFilipe Manana
1253f2f6ed3dSWang Shilong mutex_lock(&fs_info->qgroup_ioctl_lock);
125458400fceSWang Shilong if (!fs_info->quota_root)
1255f2f6ed3dSWang Shilong goto out;
1256e804861bSShin'ichiro Kawasaki
1257e804861bSShin'ichiro Kawasaki /*
1258d4aef1e1SSidong Yang * Unlock the qgroup_ioctl_lock mutex before waiting for the rescan worker to
1259d4aef1e1SSidong Yang * complete. Otherwise we can deadlock because btrfs_remove_qgroup() needs
1260d4aef1e1SSidong Yang * to lock that mutex while holding a transaction handle and the rescan
1261d4aef1e1SSidong Yang * worker needs to commit a transaction.
1262d4aef1e1SSidong Yang */
1263d4aef1e1SSidong Yang mutex_unlock(&fs_info->qgroup_ioctl_lock);
1264d4aef1e1SSidong Yang
1265d4aef1e1SSidong Yang /*
1266e804861bSShin'ichiro Kawasaki * Request qgroup rescan worker to complete and wait for it. This wait
1267e804861bSShin'ichiro Kawasaki * must be done before transaction start for quota disable since it may
1268e804861bSShin'ichiro Kawasaki * deadlock with transaction by the qgroup rescan worker.
1269e804861bSShin'ichiro Kawasaki */
1270e804861bSShin'ichiro Kawasaki clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
1271e804861bSShin'ichiro Kawasaki btrfs_qgroup_wait_for_completion(fs_info, false);
1272340f1aa2SNikolay Borisov
1273340f1aa2SNikolay Borisov /*
1274340f1aa2SNikolay Borisov * 1 For the root item
1275340f1aa2SNikolay Borisov *
1276340f1aa2SNikolay Borisov * We should also reserve enough items for the quota tree deletion in
1277340f1aa2SNikolay Borisov * btrfs_clean_quota_tree but this is not done.
1278a855fbe6SFilipe Manana *
1279a855fbe6SFilipe Manana * Also, we must always start a transaction without holding the mutex
1280a855fbe6SFilipe Manana * qgroup_ioctl_lock, see btrfs_quota_enable().
1281340f1aa2SNikolay Borisov */
1282340f1aa2SNikolay Borisov trans = btrfs_start_transaction(fs_info->tree_root, 1);
1283a855fbe6SFilipe Manana
1284a855fbe6SFilipe Manana mutex_lock(&fs_info->qgroup_ioctl_lock);
1285340f1aa2SNikolay Borisov if (IS_ERR(trans)) {
1286340f1aa2SNikolay Borisov ret = PTR_ERR(trans);
1287a855fbe6SFilipe Manana trans = NULL;
1288e804861bSShin'ichiro Kawasaki set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
1289340f1aa2SNikolay Borisov goto out;
1290340f1aa2SNikolay Borisov }
1291340f1aa2SNikolay Borisov
1292a855fbe6SFilipe Manana if (!fs_info->quota_root)
1293a855fbe6SFilipe Manana goto out;
1294a855fbe6SFilipe Manana
1295967ef513SJustin Maggard spin_lock(&fs_info->qgroup_lock);
1296bed92eaeSArne Jansen quota_root = fs_info->quota_root;
1297bed92eaeSArne Jansen fs_info->quota_root = NULL;
12988ea0ec9eSDongsheng Yang fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
1299011b46c3SQu Wenruo fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL;
1300bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
1301bed92eaeSArne Jansen
1302e685da14SWang Shilong btrfs_free_qgroup_config(fs_info);
1303e685da14SWang Shilong
1304bed92eaeSArne Jansen ret = btrfs_clean_quota_tree(trans, quota_root);
1305340f1aa2SNikolay Borisov if (ret) {
1306340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
1307a855fbe6SFilipe Manana goto out;
1308340f1aa2SNikolay Borisov }
1309bed92eaeSArne Jansen
1310ab9ce7d4SLu Fengqi ret = btrfs_del_root(trans, "a_root->root_key);
1311340f1aa2SNikolay Borisov if (ret) {
1312340f1aa2SNikolay Borisov btrfs_abort_transaction(trans, ret);
1313a855fbe6SFilipe Manana goto out;
1314340f1aa2SNikolay Borisov }
1315bed92eaeSArne Jansen
1316b31cb5a6SFilipe Manana spin_lock(&fs_info->trans_lock);
1317bed92eaeSArne Jansen list_del("a_root->dirty_list);
1318b31cb5a6SFilipe Manana spin_unlock(&fs_info->trans_lock);
1319bed92eaeSArne Jansen
1320bed92eaeSArne Jansen btrfs_tree_lock(quota_root->node);
1321190a8339SJosef Bacik btrfs_clear_buffer_dirty(trans, quota_root->node);
1322bed92eaeSArne Jansen btrfs_tree_unlock(quota_root->node);
1323*22d907bcSFilipe Manana ret = btrfs_free_tree_block(trans, btrfs_root_id(quota_root),
13247a163608SFilipe Manana quota_root->node, 0, 1);
1325bed92eaeSArne Jansen
1326*22d907bcSFilipe Manana if (ret < 0)
1327*22d907bcSFilipe Manana btrfs_abort_transaction(trans, ret);
1328340f1aa2SNikolay Borisov
1329bed92eaeSArne Jansen out:
1330f88aeff5SFilipe Manana btrfs_put_root(quota_root);
1331f2f6ed3dSWang Shilong mutex_unlock(&fs_info->qgroup_ioctl_lock);
1332a855fbe6SFilipe Manana if (ret && trans)
1333a855fbe6SFilipe Manana btrfs_end_transaction(trans);
1334a855fbe6SFilipe Manana else if (trans)
1335a855fbe6SFilipe Manana ret = btrfs_end_transaction(trans);
13368a4a0b2aSFilipe Manana mutex_unlock(&fs_info->cleaner_mutex);
1337a855fbe6SFilipe Manana
1338bed92eaeSArne Jansen return ret;
1339bed92eaeSArne Jansen }
1340bed92eaeSArne Jansen
qgroup_dirty(struct btrfs_fs_info * fs_info,struct btrfs_qgroup * qgroup)13412f232036SJan Schmidt static void qgroup_dirty(struct btrfs_fs_info *fs_info,
13422f232036SJan Schmidt struct btrfs_qgroup *qgroup)
1343bed92eaeSArne Jansen {
13442f232036SJan Schmidt if (list_empty(&qgroup->dirty))
13452f232036SJan Schmidt list_add(&qgroup->dirty, &fs_info->dirty_qgroups);
1346bed92eaeSArne Jansen }
1347bed92eaeSArne Jansen
qgroup_iterator_add(struct list_head * head,struct btrfs_qgroup * qgroup)13481c9a5c49SQu Wenruo static void qgroup_iterator_add(struct list_head *head, struct btrfs_qgroup *qgroup)
13491c9a5c49SQu Wenruo {
13501c9a5c49SQu Wenruo if (!list_empty(&qgroup->iterator))
13511c9a5c49SQu Wenruo return;
13521c9a5c49SQu Wenruo
13531c9a5c49SQu Wenruo list_add_tail(&qgroup->iterator, head);
13541c9a5c49SQu Wenruo }
13551c9a5c49SQu Wenruo
qgroup_iterator_clean(struct list_head * head)13561c9a5c49SQu Wenruo static void qgroup_iterator_clean(struct list_head *head)
13571c9a5c49SQu Wenruo {
13581c9a5c49SQu Wenruo while (!list_empty(head)) {
13591c9a5c49SQu Wenruo struct btrfs_qgroup *qgroup;
13601c9a5c49SQu Wenruo
13611c9a5c49SQu Wenruo qgroup = list_first_entry(head, struct btrfs_qgroup, iterator);
13621c9a5c49SQu Wenruo list_del_init(&qgroup->iterator);
13631c9a5c49SQu Wenruo }
13641c9a5c49SQu Wenruo }
13651c9a5c49SQu Wenruo
13669c8b35b1SQu Wenruo /*
1367429d6275SQu Wenruo * The easy accounting, we're updating qgroup relationship whose child qgroup
1368429d6275SQu Wenruo * only has exclusive extents.
1369429d6275SQu Wenruo *
137052042d8eSAndrea Gelmini * In this case, all exclusive extents will also be exclusive for parent, so
1371429d6275SQu Wenruo * excl/rfer just get added/removed.
1372429d6275SQu Wenruo *
1373429d6275SQu Wenruo * So is qgroup reservation space, which should also be added/removed to
1374429d6275SQu Wenruo * parent.
1375429d6275SQu Wenruo * Or when child tries to release reservation space, parent will underflow its
1376429d6275SQu Wenruo * reservation (for relationship adding case).
13779c8b35b1SQu Wenruo *
13789c8b35b1SQu Wenruo * Caller should hold fs_info->qgroup_lock.
13799c8b35b1SQu Wenruo */
__qgroup_excl_accounting(struct btrfs_fs_info * fs_info,struct ulist * tmp,u64 ref_root,struct btrfs_qgroup * src,int sign)13809c8b35b1SQu Wenruo static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info,
13819c8b35b1SQu Wenruo struct ulist *tmp, u64 ref_root,
1382429d6275SQu Wenruo struct btrfs_qgroup *src, int sign)
13839c8b35b1SQu Wenruo {
13849c8b35b1SQu Wenruo struct btrfs_qgroup *qgroup;
13859c8b35b1SQu Wenruo struct btrfs_qgroup_list *glist;
13869c8b35b1SQu Wenruo struct ulist_node *unode;
13879c8b35b1SQu Wenruo struct ulist_iterator uiter;
1388429d6275SQu Wenruo u64 num_bytes = src->excl;
13899c8b35b1SQu Wenruo int ret = 0;
13909c8b35b1SQu Wenruo
13919c8b35b1SQu Wenruo qgroup = find_qgroup_rb(fs_info, ref_root);
13929c8b35b1SQu Wenruo if (!qgroup)
13939c8b35b1SQu Wenruo goto out;
13949c8b35b1SQu Wenruo
13959c8b35b1SQu Wenruo qgroup->rfer += sign * num_bytes;
13969c8b35b1SQu Wenruo qgroup->rfer_cmpr += sign * num_bytes;
13979c8b35b1SQu Wenruo
13989c8b35b1SQu Wenruo WARN_ON(sign < 0 && qgroup->excl < num_bytes);
13999c8b35b1SQu Wenruo qgroup->excl += sign * num_bytes;
14009c8b35b1SQu Wenruo qgroup->excl_cmpr += sign * num_bytes;
1401429d6275SQu Wenruo
1402429d6275SQu Wenruo if (sign > 0)
140364ee4e75SQu Wenruo qgroup_rsv_add_by_qgroup(fs_info, qgroup, src);
140418dc22c1SQu Wenruo else
140564ee4e75SQu Wenruo qgroup_rsv_release_by_qgroup(fs_info, qgroup, src);
14069c8b35b1SQu Wenruo
14079c8b35b1SQu Wenruo qgroup_dirty(fs_info, qgroup);
14089c8b35b1SQu Wenruo
14099c8b35b1SQu Wenruo /* Get all of the parent groups that contain this qgroup */
14109c8b35b1SQu Wenruo list_for_each_entry(glist, &qgroup->groups, next_group) {
14119c8b35b1SQu Wenruo ret = ulist_add(tmp, glist->group->qgroupid,
1412ef2fff64SDavid Sterba qgroup_to_aux(glist->group), GFP_ATOMIC);
14139c8b35b1SQu Wenruo if (ret < 0)
14149c8b35b1SQu Wenruo goto out;
14159c8b35b1SQu Wenruo }
14169c8b35b1SQu Wenruo
14179c8b35b1SQu Wenruo /* Iterate all of the parents and adjust their reference counts */
14189c8b35b1SQu Wenruo ULIST_ITER_INIT(&uiter);
14199c8b35b1SQu Wenruo while ((unode = ulist_next(tmp, &uiter))) {
1420ef2fff64SDavid Sterba qgroup = unode_aux_to_qgroup(unode);
14219c8b35b1SQu Wenruo qgroup->rfer += sign * num_bytes;
14229c8b35b1SQu Wenruo qgroup->rfer_cmpr += sign * num_bytes;
14239c8b35b1SQu Wenruo WARN_ON(sign < 0 && qgroup->excl < num_bytes);
14249c8b35b1SQu Wenruo qgroup->excl += sign * num_bytes;
1425429d6275SQu Wenruo if (sign > 0)
142664ee4e75SQu Wenruo qgroup_rsv_add_by_qgroup(fs_info, qgroup, src);
142718dc22c1SQu Wenruo else
142864ee4e75SQu Wenruo qgroup_rsv_release_by_qgroup(fs_info, qgroup, src);
14299c8b35b1SQu Wenruo qgroup->excl_cmpr += sign * num_bytes;
14309c8b35b1SQu Wenruo qgroup_dirty(fs_info, qgroup);
14319c8b35b1SQu Wenruo
14329c8b35b1SQu Wenruo /* Add any parents of the parents */
14339c8b35b1SQu Wenruo list_for_each_entry(glist, &qgroup->groups, next_group) {
14349c8b35b1SQu Wenruo ret = ulist_add(tmp, glist->group->qgroupid,
1435ef2fff64SDavid Sterba qgroup_to_aux(glist->group), GFP_ATOMIC);
14369c8b35b1SQu Wenruo if (ret < 0)
14379c8b35b1SQu Wenruo goto out;
14389c8b35b1SQu Wenruo }
14399c8b35b1SQu Wenruo }
14409c8b35b1SQu Wenruo ret = 0;
14419c8b35b1SQu Wenruo out:
14429c8b35b1SQu Wenruo return ret;
14439c8b35b1SQu Wenruo }
14449c8b35b1SQu Wenruo
14459c8b35b1SQu Wenruo
14469c8b35b1SQu Wenruo /*
14479c8b35b1SQu Wenruo * Quick path for updating qgroup with only excl refs.
14489c8b35b1SQu Wenruo *
14499c8b35b1SQu Wenruo * In that case, just update all parent will be enough.
14509c8b35b1SQu Wenruo * Or we needs to do a full rescan.
14519c8b35b1SQu Wenruo * Caller should also hold fs_info->qgroup_lock.
14529c8b35b1SQu Wenruo *
14539c8b35b1SQu Wenruo * Return 0 for quick update, return >0 for need to full rescan
14549c8b35b1SQu Wenruo * and mark INCONSISTENT flag.
14559c8b35b1SQu Wenruo * Return < 0 for other error.
14569c8b35b1SQu Wenruo */
quick_update_accounting(struct btrfs_fs_info * fs_info,struct ulist * tmp,u64 src,u64 dst,int sign)14579c8b35b1SQu Wenruo static int quick_update_accounting(struct btrfs_fs_info *fs_info,
14589c8b35b1SQu Wenruo struct ulist *tmp, u64 src, u64 dst,
14599c8b35b1SQu Wenruo int sign)
14609c8b35b1SQu Wenruo {
14619c8b35b1SQu Wenruo struct btrfs_qgroup *qgroup;
14629c8b35b1SQu Wenruo int ret = 1;
14639c8b35b1SQu Wenruo int err = 0;
14649c8b35b1SQu Wenruo
14659c8b35b1SQu Wenruo qgroup = find_qgroup_rb(fs_info, src);
14669c8b35b1SQu Wenruo if (!qgroup)
14679c8b35b1SQu Wenruo goto out;
14689c8b35b1SQu Wenruo if (qgroup->excl == qgroup->rfer) {
14699c8b35b1SQu Wenruo ret = 0;
14709c8b35b1SQu Wenruo err = __qgroup_excl_accounting(fs_info, tmp, dst,
1471429d6275SQu Wenruo qgroup, sign);
14729c8b35b1SQu Wenruo if (err < 0) {
14739c8b35b1SQu Wenruo ret = err;
14749c8b35b1SQu Wenruo goto out;
14759c8b35b1SQu Wenruo }
14769c8b35b1SQu Wenruo }
14779c8b35b1SQu Wenruo out:
14789c8b35b1SQu Wenruo if (ret)
14799c8b35b1SQu Wenruo fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
14809c8b35b1SQu Wenruo return ret;
14819c8b35b1SQu Wenruo }
14829c8b35b1SQu Wenruo
btrfs_add_qgroup_relation(struct btrfs_trans_handle * trans,u64 src,u64 dst)14839f8a6ce6SLu Fengqi int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, u64 src,
14849f8a6ce6SLu Fengqi u64 dst)
1485bed92eaeSArne Jansen {
14869f8a6ce6SLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
1487b7fef4f5SWang Shilong struct btrfs_qgroup *parent;
1488b7fef4f5SWang Shilong struct btrfs_qgroup *member;
1489534e6623SWang Shilong struct btrfs_qgroup_list *list;
14909c8b35b1SQu Wenruo struct ulist *tmp;
14917aa6d359SFilipe Manana unsigned int nofs_flag;
1492bed92eaeSArne Jansen int ret = 0;
1493bed92eaeSArne Jansen
14948465ececSQu Wenruo /* Check the level of src and dst first */
14958465ececSQu Wenruo if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst))
14968465ececSQu Wenruo return -EINVAL;
14978465ececSQu Wenruo
14987aa6d359SFilipe Manana /* We hold a transaction handle open, must do a NOFS allocation. */
14997aa6d359SFilipe Manana nofs_flag = memalloc_nofs_save();
15006602caf1SDavid Sterba tmp = ulist_alloc(GFP_KERNEL);
15017aa6d359SFilipe Manana memalloc_nofs_restore(nofs_flag);
1502ab3680ddSChristian Engelmayer if (!tmp)
1503ab3680ddSChristian Engelmayer return -ENOMEM;
1504ab3680ddSChristian Engelmayer
1505f2f6ed3dSWang Shilong mutex_lock(&fs_info->qgroup_ioctl_lock);
1506e3b0edd2SMarcos Paulo de Souza if (!fs_info->quota_root) {
15078a36e408SMarcos Paulo de Souza ret = -ENOTCONN;
1508f2f6ed3dSWang Shilong goto out;
1509f2f6ed3dSWang Shilong }
1510b7fef4f5SWang Shilong member = find_qgroup_rb(fs_info, src);
1511b7fef4f5SWang Shilong parent = find_qgroup_rb(fs_info, dst);
1512b7fef4f5SWang Shilong if (!member || !parent) {
1513b7fef4f5SWang Shilong ret = -EINVAL;
1514b7fef4f5SWang Shilong goto out;
1515b7fef4f5SWang Shilong }
1516bed92eaeSArne Jansen
1517534e6623SWang Shilong /* check if such qgroup relation exist firstly */
1518534e6623SWang Shilong list_for_each_entry(list, &member->groups, next_group) {
1519534e6623SWang Shilong if (list->group == parent) {
1520534e6623SWang Shilong ret = -EEXIST;
1521534e6623SWang Shilong goto out;
1522534e6623SWang Shilong }
1523534e6623SWang Shilong }
1524534e6623SWang Shilong
1525711169c4SLu Fengqi ret = add_qgroup_relation_item(trans, src, dst);
1526bed92eaeSArne Jansen if (ret)
1527f2f6ed3dSWang Shilong goto out;
1528bed92eaeSArne Jansen
1529711169c4SLu Fengqi ret = add_qgroup_relation_item(trans, dst, src);
1530bed92eaeSArne Jansen if (ret) {
153199d7f09aSLu Fengqi del_qgroup_relation_item(trans, src, dst);
1532f2f6ed3dSWang Shilong goto out;
1533bed92eaeSArne Jansen }
1534bed92eaeSArne Jansen
1535bed92eaeSArne Jansen spin_lock(&fs_info->qgroup_lock);
1536a8f6f619SSidong Yang ret = __add_relation_rb(member, parent);
15379c8b35b1SQu Wenruo if (ret < 0) {
15389c8b35b1SQu Wenruo spin_unlock(&fs_info->qgroup_lock);
15399c8b35b1SQu Wenruo goto out;
15409c8b35b1SQu Wenruo }
15419c8b35b1SQu Wenruo ret = quick_update_accounting(fs_info, tmp, src, dst, 1);
1542bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
1543f2f6ed3dSWang Shilong out:
1544f2f6ed3dSWang Shilong mutex_unlock(&fs_info->qgroup_ioctl_lock);
15459c8b35b1SQu Wenruo ulist_free(tmp);
1546bed92eaeSArne Jansen return ret;
1547bed92eaeSArne Jansen }
1548bed92eaeSArne Jansen
__del_qgroup_relation(struct btrfs_trans_handle * trans,u64 src,u64 dst)15496b36f1aaSLu Fengqi static int __del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src,
15506b36f1aaSLu Fengqi u64 dst)
1551bed92eaeSArne Jansen {
15526b36f1aaSLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
1553534e6623SWang Shilong struct btrfs_qgroup *parent;
1554534e6623SWang Shilong struct btrfs_qgroup *member;
1555534e6623SWang Shilong struct btrfs_qgroup_list *list;
15569c8b35b1SQu Wenruo struct ulist *tmp;
155773798c46SQu Wenruo bool found = false;
15587aa6d359SFilipe Manana unsigned int nofs_flag;
1559bed92eaeSArne Jansen int ret = 0;
156073798c46SQu Wenruo int ret2;
1561bed92eaeSArne Jansen
15627aa6d359SFilipe Manana /* We hold a transaction handle open, must do a NOFS allocation. */
15637aa6d359SFilipe Manana nofs_flag = memalloc_nofs_save();
15646602caf1SDavid Sterba tmp = ulist_alloc(GFP_KERNEL);
15657aa6d359SFilipe Manana memalloc_nofs_restore(nofs_flag);
15669c8b35b1SQu Wenruo if (!tmp)
15679c8b35b1SQu Wenruo return -ENOMEM;
15689c8b35b1SQu Wenruo
1569e3b0edd2SMarcos Paulo de Souza if (!fs_info->quota_root) {
15708a36e408SMarcos Paulo de Souza ret = -ENOTCONN;
1571f2f6ed3dSWang Shilong goto out;
1572f2f6ed3dSWang Shilong }
1573bed92eaeSArne Jansen
1574534e6623SWang Shilong member = find_qgroup_rb(fs_info, src);
1575534e6623SWang Shilong parent = find_qgroup_rb(fs_info, dst);
157673798c46SQu Wenruo /*
157773798c46SQu Wenruo * The parent/member pair doesn't exist, then try to delete the dead
157873798c46SQu Wenruo * relation items only.
157973798c46SQu Wenruo */
158073798c46SQu Wenruo if (!member || !parent)
158173798c46SQu Wenruo goto delete_item;
1582534e6623SWang Shilong
1583534e6623SWang Shilong /* check if such qgroup relation exist firstly */
1584534e6623SWang Shilong list_for_each_entry(list, &member->groups, next_group) {
158573798c46SQu Wenruo if (list->group == parent) {
158673798c46SQu Wenruo found = true;
158773798c46SQu Wenruo break;
1588534e6623SWang Shilong }
158973798c46SQu Wenruo }
1590bed92eaeSArne Jansen
159173798c46SQu Wenruo delete_item:
159273798c46SQu Wenruo ret = del_qgroup_relation_item(trans, src, dst);
159373798c46SQu Wenruo if (ret < 0 && ret != -ENOENT)
159473798c46SQu Wenruo goto out;
159573798c46SQu Wenruo ret2 = del_qgroup_relation_item(trans, dst, src);
159673798c46SQu Wenruo if (ret2 < 0 && ret2 != -ENOENT)
159773798c46SQu Wenruo goto out;
159873798c46SQu Wenruo
159973798c46SQu Wenruo /* At least one deletion succeeded, return 0 */
160073798c46SQu Wenruo if (!ret || !ret2)
160173798c46SQu Wenruo ret = 0;
160273798c46SQu Wenruo
160373798c46SQu Wenruo if (found) {
1604bed92eaeSArne Jansen spin_lock(&fs_info->qgroup_lock);
1605bed92eaeSArne Jansen del_relation_rb(fs_info, src, dst);
16069c8b35b1SQu Wenruo ret = quick_update_accounting(fs_info, tmp, src, dst, -1);
1607bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
160873798c46SQu Wenruo }
1609f2f6ed3dSWang Shilong out:
16109c8b35b1SQu Wenruo ulist_free(tmp);
1611f5a6b1c5SDongsheng Yang return ret;
1612f5a6b1c5SDongsheng Yang }
1613f5a6b1c5SDongsheng Yang
btrfs_del_qgroup_relation(struct btrfs_trans_handle * trans,u64 src,u64 dst)161439616c27SLu Fengqi int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src,
161539616c27SLu Fengqi u64 dst)
1616f5a6b1c5SDongsheng Yang {
161739616c27SLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
1618f5a6b1c5SDongsheng Yang int ret = 0;
1619f5a6b1c5SDongsheng Yang
1620f5a6b1c5SDongsheng Yang mutex_lock(&fs_info->qgroup_ioctl_lock);
16216b36f1aaSLu Fengqi ret = __del_qgroup_relation(trans, src, dst);
1622f2f6ed3dSWang Shilong mutex_unlock(&fs_info->qgroup_ioctl_lock);
1623f5a6b1c5SDongsheng Yang
1624bed92eaeSArne Jansen return ret;
1625bed92eaeSArne Jansen }
1626bed92eaeSArne Jansen
btrfs_create_qgroup(struct btrfs_trans_handle * trans,u64 qgroupid)162749a05ecdSLu Fengqi int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
1628bed92eaeSArne Jansen {
162949a05ecdSLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
1630bed92eaeSArne Jansen struct btrfs_root *quota_root;
1631bed92eaeSArne Jansen struct btrfs_qgroup *qgroup;
1632bed92eaeSArne Jansen int ret = 0;
1633bed92eaeSArne Jansen
1634f2f6ed3dSWang Shilong mutex_lock(&fs_info->qgroup_ioctl_lock);
1635e3b0edd2SMarcos Paulo de Souza if (!fs_info->quota_root) {
16368a36e408SMarcos Paulo de Souza ret = -ENOTCONN;
1637f2f6ed3dSWang Shilong goto out;
1638f2f6ed3dSWang Shilong }
1639e3b0edd2SMarcos Paulo de Souza quota_root = fs_info->quota_root;
1640534e6623SWang Shilong qgroup = find_qgroup_rb(fs_info, qgroupid);
1641534e6623SWang Shilong if (qgroup) {
1642534e6623SWang Shilong ret = -EEXIST;
1643534e6623SWang Shilong goto out;
1644534e6623SWang Shilong }
1645bed92eaeSArne Jansen
1646bed92eaeSArne Jansen ret = add_qgroup_item(trans, quota_root, qgroupid);
1647534e6623SWang Shilong if (ret)
1648534e6623SWang Shilong goto out;
1649bed92eaeSArne Jansen
1650bed92eaeSArne Jansen spin_lock(&fs_info->qgroup_lock);
1651bed92eaeSArne Jansen qgroup = add_qgroup_rb(fs_info, qgroupid);
1652bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
1653bed92eaeSArne Jansen
165449e5fb46SQu Wenruo if (IS_ERR(qgroup)) {
1655bed92eaeSArne Jansen ret = PTR_ERR(qgroup);
165649e5fb46SQu Wenruo goto out;
165749e5fb46SQu Wenruo }
165849e5fb46SQu Wenruo ret = btrfs_sysfs_add_one_qgroup(fs_info, qgroup);
1659f2f6ed3dSWang Shilong out:
1660f2f6ed3dSWang Shilong mutex_unlock(&fs_info->qgroup_ioctl_lock);
1661bed92eaeSArne Jansen return ret;
1662bed92eaeSArne Jansen }
1663bed92eaeSArne Jansen
qgroup_has_usage(struct btrfs_qgroup * qgroup)166492182dc1SBoris Burkov static bool qgroup_has_usage(struct btrfs_qgroup *qgroup)
166592182dc1SBoris Burkov {
166692182dc1SBoris Burkov return (qgroup->rfer > 0 || qgroup->rfer_cmpr > 0 ||
166792182dc1SBoris Burkov qgroup->excl > 0 || qgroup->excl_cmpr > 0 ||
166892182dc1SBoris Burkov qgroup->rsv.values[BTRFS_QGROUP_RSV_DATA] > 0 ||
166992182dc1SBoris Burkov qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PREALLOC] > 0 ||
167092182dc1SBoris Burkov qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PERTRANS] > 0);
167192182dc1SBoris Burkov }
167292182dc1SBoris Burkov
btrfs_remove_qgroup(struct btrfs_trans_handle * trans,u64 qgroupid)16733efbee1dSLu Fengqi int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
1674bed92eaeSArne Jansen {
16753efbee1dSLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
16762cf68703SArne Jansen struct btrfs_qgroup *qgroup;
1677f5a6b1c5SDongsheng Yang struct btrfs_qgroup_list *list;
1678bed92eaeSArne Jansen int ret = 0;
1679bed92eaeSArne Jansen
1680f2f6ed3dSWang Shilong mutex_lock(&fs_info->qgroup_ioctl_lock);
1681e3b0edd2SMarcos Paulo de Souza if (!fs_info->quota_root) {
16828a36e408SMarcos Paulo de Souza ret = -ENOTCONN;
1683f2f6ed3dSWang Shilong goto out;
1684f2f6ed3dSWang Shilong }
1685bed92eaeSArne Jansen
16862cf68703SArne Jansen qgroup = find_qgroup_rb(fs_info, qgroupid);
1687534e6623SWang Shilong if (!qgroup) {
1688534e6623SWang Shilong ret = -ENOENT;
1689534e6623SWang Shilong goto out;
1690b90e22baSLu Fengqi }
1691b90e22baSLu Fengqi
169292182dc1SBoris Burkov if (is_fstree(qgroupid) && qgroup_has_usage(qgroup)) {
169392182dc1SBoris Burkov ret = -EBUSY;
169492182dc1SBoris Burkov goto out;
169592182dc1SBoris Burkov }
169692182dc1SBoris Burkov
1697b90e22baSLu Fengqi /* Check if there are no children of this qgroup */
1698f5a6b1c5SDongsheng Yang if (!list_empty(&qgroup->members)) {
1699f2f6ed3dSWang Shilong ret = -EBUSY;
1700f2f6ed3dSWang Shilong goto out;
17012cf68703SArne Jansen }
1702b90e22baSLu Fengqi
170369104618SLu Fengqi ret = del_qgroup_item(trans, qgroupid);
170436b96fdcSSargun Dhillon if (ret && ret != -ENOENT)
170536b96fdcSSargun Dhillon goto out;
1706bed92eaeSArne Jansen
1707f5a6b1c5SDongsheng Yang while (!list_empty(&qgroup->groups)) {
1708f5a6b1c5SDongsheng Yang list = list_first_entry(&qgroup->groups,
1709f5a6b1c5SDongsheng Yang struct btrfs_qgroup_list, next_group);
17106b36f1aaSLu Fengqi ret = __del_qgroup_relation(trans, qgroupid,
1711f5a6b1c5SDongsheng Yang list->group->qgroupid);
1712f5a6b1c5SDongsheng Yang if (ret)
1713f5a6b1c5SDongsheng Yang goto out;
1714f5a6b1c5SDongsheng Yang }
1715f5a6b1c5SDongsheng Yang
1716bed92eaeSArne Jansen spin_lock(&fs_info->qgroup_lock);
17170b246afaSJeff Mahoney del_qgroup_rb(fs_info, qgroupid);
1718bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
17190bb78830SFilipe Manana
17200bb78830SFilipe Manana /*
17210bb78830SFilipe Manana * Remove the qgroup from sysfs now without holding the qgroup_lock
17220bb78830SFilipe Manana * spinlock, since the sysfs_remove_group() function needs to take
17230bb78830SFilipe Manana * the mutex kernfs_mutex through kernfs_remove_by_name_ns().
17240bb78830SFilipe Manana */
17250bb78830SFilipe Manana btrfs_sysfs_del_one_qgroup(fs_info, qgroup);
17260bb78830SFilipe Manana kfree(qgroup);
1727f2f6ed3dSWang Shilong out:
1728f2f6ed3dSWang Shilong mutex_unlock(&fs_info->qgroup_ioctl_lock);
1729bed92eaeSArne Jansen return ret;
1730bed92eaeSArne Jansen }
1731bed92eaeSArne Jansen
btrfs_limit_qgroup(struct btrfs_trans_handle * trans,u64 qgroupid,struct btrfs_qgroup_limit * limit)1732f0042d5eSLu Fengqi int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid,
1733bed92eaeSArne Jansen struct btrfs_qgroup_limit *limit)
1734bed92eaeSArne Jansen {
1735f0042d5eSLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
1736bed92eaeSArne Jansen struct btrfs_qgroup *qgroup;
1737bed92eaeSArne Jansen int ret = 0;
1738fe759907SYang Dongsheng /* Sometimes we would want to clear the limit on this qgroup.
1739fe759907SYang Dongsheng * To meet this requirement, we treat the -1 as a special value
1740fe759907SYang Dongsheng * which tell kernel to clear the limit on this qgroup.
1741fe759907SYang Dongsheng */
1742fe759907SYang Dongsheng const u64 CLEAR_VALUE = -1;
1743bed92eaeSArne Jansen
1744f2f6ed3dSWang Shilong mutex_lock(&fs_info->qgroup_ioctl_lock);
1745e3b0edd2SMarcos Paulo de Souza if (!fs_info->quota_root) {
17468a36e408SMarcos Paulo de Souza ret = -ENOTCONN;
1747f2f6ed3dSWang Shilong goto out;
1748f2f6ed3dSWang Shilong }
1749bed92eaeSArne Jansen
1750ddb47afaSWang Shilong qgroup = find_qgroup_rb(fs_info, qgroupid);
1751ddb47afaSWang Shilong if (!qgroup) {
1752ddb47afaSWang Shilong ret = -ENOENT;
1753ddb47afaSWang Shilong goto out;
1754ddb47afaSWang Shilong }
1755bed92eaeSArne Jansen
175658400fceSWang Shilong spin_lock(&fs_info->qgroup_lock);
1757fe759907SYang Dongsheng if (limit->flags & BTRFS_QGROUP_LIMIT_MAX_RFER) {
1758fe759907SYang Dongsheng if (limit->max_rfer == CLEAR_VALUE) {
1759fe759907SYang Dongsheng qgroup->lim_flags &= ~BTRFS_QGROUP_LIMIT_MAX_RFER;
1760fe759907SYang Dongsheng limit->flags &= ~BTRFS_QGROUP_LIMIT_MAX_RFER;
1761fe759907SYang Dongsheng qgroup->max_rfer = 0;
1762fe759907SYang Dongsheng } else {
1763bed92eaeSArne Jansen qgroup->max_rfer = limit->max_rfer;
1764fe759907SYang Dongsheng }
1765fe759907SYang Dongsheng }
1766fe759907SYang Dongsheng if (limit->flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) {
1767fe759907SYang Dongsheng if (limit->max_excl == CLEAR_VALUE) {
1768fe759907SYang Dongsheng qgroup->lim_flags &= ~BTRFS_QGROUP_LIMIT_MAX_EXCL;
1769fe759907SYang Dongsheng limit->flags &= ~BTRFS_QGROUP_LIMIT_MAX_EXCL;
1770fe759907SYang Dongsheng qgroup->max_excl = 0;
1771fe759907SYang Dongsheng } else {
1772bed92eaeSArne Jansen qgroup->max_excl = limit->max_excl;
1773fe759907SYang Dongsheng }
1774fe759907SYang Dongsheng }
1775fe759907SYang Dongsheng if (limit->flags & BTRFS_QGROUP_LIMIT_RSV_RFER) {
1776fe759907SYang Dongsheng if (limit->rsv_rfer == CLEAR_VALUE) {
1777fe759907SYang Dongsheng qgroup->lim_flags &= ~BTRFS_QGROUP_LIMIT_RSV_RFER;
1778fe759907SYang Dongsheng limit->flags &= ~BTRFS_QGROUP_LIMIT_RSV_RFER;
1779fe759907SYang Dongsheng qgroup->rsv_rfer = 0;
1780fe759907SYang Dongsheng } else {
1781bed92eaeSArne Jansen qgroup->rsv_rfer = limit->rsv_rfer;
1782fe759907SYang Dongsheng }
1783fe759907SYang Dongsheng }
1784fe759907SYang Dongsheng if (limit->flags & BTRFS_QGROUP_LIMIT_RSV_EXCL) {
1785fe759907SYang Dongsheng if (limit->rsv_excl == CLEAR_VALUE) {
1786fe759907SYang Dongsheng qgroup->lim_flags &= ~BTRFS_QGROUP_LIMIT_RSV_EXCL;
1787fe759907SYang Dongsheng limit->flags &= ~BTRFS_QGROUP_LIMIT_RSV_EXCL;
1788fe759907SYang Dongsheng qgroup->rsv_excl = 0;
1789fe759907SYang Dongsheng } else {
1790bed92eaeSArne Jansen qgroup->rsv_excl = limit->rsv_excl;
1791fe759907SYang Dongsheng }
1792fe759907SYang Dongsheng }
179303477d94SDongsheng Yang qgroup->lim_flags |= limit->flags;
179403477d94SDongsheng Yang
1795bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
17961510e71cSDongsheng Yang
1797ac8a866aSLu Fengqi ret = update_qgroup_limit_item(trans, qgroup);
17981510e71cSDongsheng Yang if (ret) {
1799e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
18001510e71cSDongsheng Yang btrfs_info(fs_info, "unable to update quota limit for %llu",
18011510e71cSDongsheng Yang qgroupid);
18021510e71cSDongsheng Yang }
18031510e71cSDongsheng Yang
1804f2f6ed3dSWang Shilong out:
1805f2f6ed3dSWang Shilong mutex_unlock(&fs_info->qgroup_ioctl_lock);
1806bed92eaeSArne Jansen return ret;
1807bed92eaeSArne Jansen }
18081152651aSMark Fasheh
btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info * fs_info,struct btrfs_delayed_ref_root * delayed_refs,struct btrfs_qgroup_extent_record * record)180950b3e040SQu Wenruo int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info,
1810bc074524SJeff Mahoney struct btrfs_delayed_ref_root *delayed_refs,
18113368d001SQu Wenruo struct btrfs_qgroup_extent_record *record)
18123368d001SQu Wenruo {
18133368d001SQu Wenruo struct rb_node **p = &delayed_refs->dirty_extent_root.rb_node;
18143368d001SQu Wenruo struct rb_node *parent_node = NULL;
18153368d001SQu Wenruo struct btrfs_qgroup_extent_record *entry;
18163368d001SQu Wenruo u64 bytenr = record->bytenr;
18173368d001SQu Wenruo
1818a4666e68SDavid Sterba lockdep_assert_held(&delayed_refs->lock);
181950b3e040SQu Wenruo trace_btrfs_qgroup_trace_extent(fs_info, record);
182082bd101bSMark Fasheh
18213368d001SQu Wenruo while (*p) {
18223368d001SQu Wenruo parent_node = *p;
18233368d001SQu Wenruo entry = rb_entry(parent_node, struct btrfs_qgroup_extent_record,
18243368d001SQu Wenruo node);
18251418bae1SQu Wenruo if (bytenr < entry->bytenr) {
18263368d001SQu Wenruo p = &(*p)->rb_left;
18271418bae1SQu Wenruo } else if (bytenr > entry->bytenr) {
18283368d001SQu Wenruo p = &(*p)->rb_right;
18291418bae1SQu Wenruo } else {
18301418bae1SQu Wenruo if (record->data_rsv && !entry->data_rsv) {
18311418bae1SQu Wenruo entry->data_rsv = record->data_rsv;
18321418bae1SQu Wenruo entry->data_rsv_refroot =
18331418bae1SQu Wenruo record->data_rsv_refroot;
18341418bae1SQu Wenruo }
1835cb93b52cSQu Wenruo return 1;
18363368d001SQu Wenruo }
18371418bae1SQu Wenruo }
18383368d001SQu Wenruo
18393368d001SQu Wenruo rb_link_node(&record->node, parent_node, p);
18403368d001SQu Wenruo rb_insert_color(&record->node, &delayed_refs->dirty_extent_root);
1841cb93b52cSQu Wenruo return 0;
1842cb93b52cSQu Wenruo }
1843cb93b52cSQu Wenruo
btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle * trans,struct btrfs_qgroup_extent_record * qrecord)18448949b9a1SFilipe Manana int btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle *trans,
1845fb235dc0SQu Wenruo struct btrfs_qgroup_extent_record *qrecord)
1846fb235dc0SQu Wenruo {
1847a2c8d27eSFilipe Manana struct btrfs_backref_walk_ctx ctx = { 0 };
1848fb235dc0SQu Wenruo int ret;
1849fb235dc0SQu Wenruo
18508949b9a1SFilipe Manana /*
18518949b9a1SFilipe Manana * We are always called in a context where we are already holding a
18528949b9a1SFilipe Manana * transaction handle. Often we are called when adding a data delayed
18538949b9a1SFilipe Manana * reference from btrfs_truncate_inode_items() (truncating or unlinking),
18548949b9a1SFilipe Manana * in which case we will be holding a write lock on extent buffer from a
18558949b9a1SFilipe Manana * subvolume tree. In this case we can't allow btrfs_find_all_roots() to
18568949b9a1SFilipe Manana * acquire fs_info->commit_root_sem, because that is a higher level lock
18578949b9a1SFilipe Manana * that must be acquired before locking any extent buffers.
18588949b9a1SFilipe Manana *
18598949b9a1SFilipe Manana * So we want btrfs_find_all_roots() to not acquire the commit_root_sem
18608949b9a1SFilipe Manana * but we can't pass it a non-NULL transaction handle, because otherwise
18618949b9a1SFilipe Manana * it would not use commit roots and would lock extent buffers, causing
18628949b9a1SFilipe Manana * a deadlock if it ends up trying to read lock the same extent buffer
18638949b9a1SFilipe Manana * that was previously write locked at btrfs_truncate_inode_items().
18648949b9a1SFilipe Manana *
18658949b9a1SFilipe Manana * So pass a NULL transaction handle to btrfs_find_all_roots() and
18668949b9a1SFilipe Manana * explicitly tell it to not acquire the commit_root_sem - if we are
18678949b9a1SFilipe Manana * holding a transaction handle we don't need its protection.
18688949b9a1SFilipe Manana */
18698949b9a1SFilipe Manana ASSERT(trans != NULL);
18708949b9a1SFilipe Manana
1871e15e9f43SQu Wenruo if (trans->fs_info->qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING)
1872e15e9f43SQu Wenruo return 0;
1873e15e9f43SQu Wenruo
1874a2c8d27eSFilipe Manana ctx.bytenr = qrecord->bytenr;
1875a2c8d27eSFilipe Manana ctx.fs_info = trans->fs_info;
1876a2c8d27eSFilipe Manana
1877a2c8d27eSFilipe Manana ret = btrfs_find_all_roots(&ctx, true);
1878952bd3dbSNikolay Borisov if (ret < 0) {
1879e562a8bdSQu Wenruo qgroup_mark_inconsistent(trans->fs_info);
18808949b9a1SFilipe Manana btrfs_warn(trans->fs_info,
1881952bd3dbSNikolay Borisov "error accounting new delayed refs extent (err code: %d), quota inconsistent",
1882952bd3dbSNikolay Borisov ret);
1883952bd3dbSNikolay Borisov return 0;
1884952bd3dbSNikolay Borisov }
1885fb235dc0SQu Wenruo
1886fb235dc0SQu Wenruo /*
1887fb235dc0SQu Wenruo * Here we don't need to get the lock of
1888fb235dc0SQu Wenruo * trans->transaction->delayed_refs, since inserted qrecord won't
1889fb235dc0SQu Wenruo * be deleted, only qrecord->node may be modified (new qrecord insert)
1890fb235dc0SQu Wenruo *
1891fb235dc0SQu Wenruo * So modifying qrecord->old_roots is safe here
1892fb235dc0SQu Wenruo */
1893a2c8d27eSFilipe Manana qrecord->old_roots = ctx.roots;
1894fb235dc0SQu Wenruo return 0;
1895fb235dc0SQu Wenruo }
1896fb235dc0SQu Wenruo
btrfs_qgroup_trace_extent(struct btrfs_trans_handle * trans,u64 bytenr,u64 num_bytes)1897a95f3aafSLu Fengqi int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr,
1898e2896e79SDavid Sterba u64 num_bytes)
1899cb93b52cSQu Wenruo {
1900a95f3aafSLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
1901cb93b52cSQu Wenruo struct btrfs_qgroup_extent_record *record;
1902cb93b52cSQu Wenruo struct btrfs_delayed_ref_root *delayed_refs;
1903cb93b52cSQu Wenruo int ret;
1904cb93b52cSQu Wenruo
1905afcdd129SJosef Bacik if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)
1906afcdd129SJosef Bacik || bytenr == 0 || num_bytes == 0)
1907cb93b52cSQu Wenruo return 0;
1908e2896e79SDavid Sterba record = kzalloc(sizeof(*record), GFP_NOFS);
1909cb93b52cSQu Wenruo if (!record)
1910cb93b52cSQu Wenruo return -ENOMEM;
1911cb93b52cSQu Wenruo
1912cb93b52cSQu Wenruo delayed_refs = &trans->transaction->delayed_refs;
1913cb93b52cSQu Wenruo record->bytenr = bytenr;
1914cb93b52cSQu Wenruo record->num_bytes = num_bytes;
1915cb93b52cSQu Wenruo record->old_roots = NULL;
1916cb93b52cSQu Wenruo
1917cb93b52cSQu Wenruo spin_lock(&delayed_refs->lock);
19182ff7e61eSJeff Mahoney ret = btrfs_qgroup_trace_extent_nolock(fs_info, delayed_refs, record);
1919cb93b52cSQu Wenruo spin_unlock(&delayed_refs->lock);
1920fb235dc0SQu Wenruo if (ret > 0) {
1921cb93b52cSQu Wenruo kfree(record);
1922cb93b52cSQu Wenruo return 0;
19233368d001SQu Wenruo }
19248949b9a1SFilipe Manana return btrfs_qgroup_trace_extent_post(trans, record);
1925fb235dc0SQu Wenruo }
19263368d001SQu Wenruo
btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle * trans,struct extent_buffer * eb)192733d1f05cSQu Wenruo int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans,
192833d1f05cSQu Wenruo struct extent_buffer *eb)
192933d1f05cSQu Wenruo {
19308d38d7ebSLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
193133d1f05cSQu Wenruo int nr = btrfs_header_nritems(eb);
193233d1f05cSQu Wenruo int i, extent_type, ret;
193333d1f05cSQu Wenruo struct btrfs_key key;
193433d1f05cSQu Wenruo struct btrfs_file_extent_item *fi;
193533d1f05cSQu Wenruo u64 bytenr, num_bytes;
193633d1f05cSQu Wenruo
193733d1f05cSQu Wenruo /* We can be called directly from walk_up_proc() */
19380b246afaSJeff Mahoney if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
193933d1f05cSQu Wenruo return 0;
194033d1f05cSQu Wenruo
194133d1f05cSQu Wenruo for (i = 0; i < nr; i++) {
194233d1f05cSQu Wenruo btrfs_item_key_to_cpu(eb, &key, i);
194333d1f05cSQu Wenruo
194433d1f05cSQu Wenruo if (key.type != BTRFS_EXTENT_DATA_KEY)
194533d1f05cSQu Wenruo continue;
194633d1f05cSQu Wenruo
194733d1f05cSQu Wenruo fi = btrfs_item_ptr(eb, i, struct btrfs_file_extent_item);
194833d1f05cSQu Wenruo /* filter out non qgroup-accountable extents */
194933d1f05cSQu Wenruo extent_type = btrfs_file_extent_type(eb, fi);
195033d1f05cSQu Wenruo
195133d1f05cSQu Wenruo if (extent_type == BTRFS_FILE_EXTENT_INLINE)
195233d1f05cSQu Wenruo continue;
195333d1f05cSQu Wenruo
195433d1f05cSQu Wenruo bytenr = btrfs_file_extent_disk_bytenr(eb, fi);
195533d1f05cSQu Wenruo if (!bytenr)
195633d1f05cSQu Wenruo continue;
195733d1f05cSQu Wenruo
195833d1f05cSQu Wenruo num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi);
195933d1f05cSQu Wenruo
1960e2896e79SDavid Sterba ret = btrfs_qgroup_trace_extent(trans, bytenr, num_bytes);
196133d1f05cSQu Wenruo if (ret)
196233d1f05cSQu Wenruo return ret;
196333d1f05cSQu Wenruo }
1964cddf3b2cSJeff Mahoney cond_resched();
196533d1f05cSQu Wenruo return 0;
196633d1f05cSQu Wenruo }
196733d1f05cSQu Wenruo
196833d1f05cSQu Wenruo /*
196933d1f05cSQu Wenruo * Walk up the tree from the bottom, freeing leaves and any interior
197033d1f05cSQu Wenruo * nodes which have had all slots visited. If a node (leaf or
197133d1f05cSQu Wenruo * interior) is freed, the node above it will have it's slot
197233d1f05cSQu Wenruo * incremented. The root node will never be freed.
197333d1f05cSQu Wenruo *
197433d1f05cSQu Wenruo * At the end of this function, we should have a path which has all
197533d1f05cSQu Wenruo * slots incremented to the next position for a search. If we need to
197633d1f05cSQu Wenruo * read a new node it will be NULL and the node above it will have the
197733d1f05cSQu Wenruo * correct slot selected for a later read.
197833d1f05cSQu Wenruo *
197933d1f05cSQu Wenruo * If we increment the root nodes slot counter past the number of
198033d1f05cSQu Wenruo * elements, 1 is returned to signal completion of the search.
198133d1f05cSQu Wenruo */
adjust_slots_upwards(struct btrfs_path * path,int root_level)198215b34517SDavid Sterba static int adjust_slots_upwards(struct btrfs_path *path, int root_level)
198333d1f05cSQu Wenruo {
198433d1f05cSQu Wenruo int level = 0;
198533d1f05cSQu Wenruo int nr, slot;
198633d1f05cSQu Wenruo struct extent_buffer *eb;
198733d1f05cSQu Wenruo
198833d1f05cSQu Wenruo if (root_level == 0)
198933d1f05cSQu Wenruo return 1;
199033d1f05cSQu Wenruo
199133d1f05cSQu Wenruo while (level <= root_level) {
199233d1f05cSQu Wenruo eb = path->nodes[level];
199333d1f05cSQu Wenruo nr = btrfs_header_nritems(eb);
199433d1f05cSQu Wenruo path->slots[level]++;
199533d1f05cSQu Wenruo slot = path->slots[level];
199633d1f05cSQu Wenruo if (slot >= nr || level == 0) {
199733d1f05cSQu Wenruo /*
199833d1f05cSQu Wenruo * Don't free the root - we will detect this
199933d1f05cSQu Wenruo * condition after our loop and return a
200033d1f05cSQu Wenruo * positive value for caller to stop walking the tree.
200133d1f05cSQu Wenruo */
200233d1f05cSQu Wenruo if (level != root_level) {
200333d1f05cSQu Wenruo btrfs_tree_unlock_rw(eb, path->locks[level]);
200433d1f05cSQu Wenruo path->locks[level] = 0;
200533d1f05cSQu Wenruo
200633d1f05cSQu Wenruo free_extent_buffer(eb);
200733d1f05cSQu Wenruo path->nodes[level] = NULL;
200833d1f05cSQu Wenruo path->slots[level] = 0;
200933d1f05cSQu Wenruo }
201033d1f05cSQu Wenruo } else {
201133d1f05cSQu Wenruo /*
201233d1f05cSQu Wenruo * We have a valid slot to walk back down
201333d1f05cSQu Wenruo * from. Stop here so caller can process these
201433d1f05cSQu Wenruo * new nodes.
201533d1f05cSQu Wenruo */
201633d1f05cSQu Wenruo break;
201733d1f05cSQu Wenruo }
201833d1f05cSQu Wenruo
201933d1f05cSQu Wenruo level++;
202033d1f05cSQu Wenruo }
202133d1f05cSQu Wenruo
202233d1f05cSQu Wenruo eb = path->nodes[root_level];
202333d1f05cSQu Wenruo if (path->slots[root_level] >= btrfs_header_nritems(eb))
202433d1f05cSQu Wenruo return 1;
202533d1f05cSQu Wenruo
202633d1f05cSQu Wenruo return 0;
202733d1f05cSQu Wenruo }
202833d1f05cSQu Wenruo
202925982561SQu Wenruo /*
203025982561SQu Wenruo * Helper function to trace a subtree tree block swap.
203125982561SQu Wenruo *
203225982561SQu Wenruo * The swap will happen in highest tree block, but there may be a lot of
203325982561SQu Wenruo * tree blocks involved.
203425982561SQu Wenruo *
203525982561SQu Wenruo * For example:
203625982561SQu Wenruo * OO = Old tree blocks
203725982561SQu Wenruo * NN = New tree blocks allocated during balance
203825982561SQu Wenruo *
203925982561SQu Wenruo * File tree (257) Reloc tree for 257
204025982561SQu Wenruo * L2 OO NN
204125982561SQu Wenruo * / \ / \
204225982561SQu Wenruo * L1 OO OO (a) OO NN (a)
204325982561SQu Wenruo * / \ / \ / \ / \
204425982561SQu Wenruo * L0 OO OO OO OO OO OO NN NN
204525982561SQu Wenruo * (b) (c) (b) (c)
204625982561SQu Wenruo *
204725982561SQu Wenruo * When calling qgroup_trace_extent_swap(), we will pass:
204825982561SQu Wenruo * @src_eb = OO(a)
204925982561SQu Wenruo * @dst_path = [ nodes[1] = NN(a), nodes[0] = NN(c) ]
205025982561SQu Wenruo * @dst_level = 0
205125982561SQu Wenruo * @root_level = 1
205225982561SQu Wenruo *
205325982561SQu Wenruo * In that case, qgroup_trace_extent_swap() will search from OO(a) to
205425982561SQu Wenruo * reach OO(c), then mark both OO(c) and NN(c) as qgroup dirty.
205525982561SQu Wenruo *
205625982561SQu Wenruo * The main work of qgroup_trace_extent_swap() can be split into 3 parts:
205725982561SQu Wenruo *
205825982561SQu Wenruo * 1) Tree search from @src_eb
205925982561SQu Wenruo * It should acts as a simplified btrfs_search_slot().
206025982561SQu Wenruo * The key for search can be extracted from @dst_path->nodes[dst_level]
206125982561SQu Wenruo * (first key).
206225982561SQu Wenruo *
206325982561SQu Wenruo * 2) Mark the final tree blocks in @src_path and @dst_path qgroup dirty
206425982561SQu Wenruo * NOTE: In above case, OO(a) and NN(a) won't be marked qgroup dirty.
206552042d8eSAndrea Gelmini * They should be marked during previous (@dst_level = 1) iteration.
206625982561SQu Wenruo *
206725982561SQu Wenruo * 3) Mark file extents in leaves dirty
206825982561SQu Wenruo * We don't have good way to pick out new file extents only.
206925982561SQu Wenruo * So we still follow the old method by scanning all file extents in
207025982561SQu Wenruo * the leave.
207125982561SQu Wenruo *
207252042d8eSAndrea Gelmini * This function can free us from keeping two paths, thus later we only need
207325982561SQu Wenruo * to care about how to iterate all new tree blocks in reloc tree.
207425982561SQu Wenruo */
qgroup_trace_extent_swap(struct btrfs_trans_handle * trans,struct extent_buffer * src_eb,struct btrfs_path * dst_path,int dst_level,int root_level,bool trace_leaf)207525982561SQu Wenruo static int qgroup_trace_extent_swap(struct btrfs_trans_handle* trans,
207625982561SQu Wenruo struct extent_buffer *src_eb,
207725982561SQu Wenruo struct btrfs_path *dst_path,
20783d0174f7SQu Wenruo int dst_level, int root_level,
20793d0174f7SQu Wenruo bool trace_leaf)
208025982561SQu Wenruo {
208125982561SQu Wenruo struct btrfs_key key;
208225982561SQu Wenruo struct btrfs_path *src_path;
208325982561SQu Wenruo struct btrfs_fs_info *fs_info = trans->fs_info;
208425982561SQu Wenruo u32 nodesize = fs_info->nodesize;
208525982561SQu Wenruo int cur_level = root_level;
208625982561SQu Wenruo int ret;
208725982561SQu Wenruo
208825982561SQu Wenruo BUG_ON(dst_level > root_level);
208925982561SQu Wenruo /* Level mismatch */
209025982561SQu Wenruo if (btrfs_header_level(src_eb) != root_level)
209125982561SQu Wenruo return -EINVAL;
209225982561SQu Wenruo
209325982561SQu Wenruo src_path = btrfs_alloc_path();
209425982561SQu Wenruo if (!src_path) {
209525982561SQu Wenruo ret = -ENOMEM;
209625982561SQu Wenruo goto out;
209725982561SQu Wenruo }
209825982561SQu Wenruo
209925982561SQu Wenruo if (dst_level)
210025982561SQu Wenruo btrfs_node_key_to_cpu(dst_path->nodes[dst_level], &key, 0);
210125982561SQu Wenruo else
210225982561SQu Wenruo btrfs_item_key_to_cpu(dst_path->nodes[dst_level], &key, 0);
210325982561SQu Wenruo
210425982561SQu Wenruo /* For src_path */
210567439dadSDavid Sterba atomic_inc(&src_eb->refs);
210625982561SQu Wenruo src_path->nodes[root_level] = src_eb;
210725982561SQu Wenruo src_path->slots[root_level] = dst_path->slots[root_level];
210825982561SQu Wenruo src_path->locks[root_level] = 0;
210925982561SQu Wenruo
211025982561SQu Wenruo /* A simplified version of btrfs_search_slot() */
211125982561SQu Wenruo while (cur_level >= dst_level) {
211225982561SQu Wenruo struct btrfs_key src_key;
211325982561SQu Wenruo struct btrfs_key dst_key;
211425982561SQu Wenruo
211525982561SQu Wenruo if (src_path->nodes[cur_level] == NULL) {
211625982561SQu Wenruo struct extent_buffer *eb;
211725982561SQu Wenruo int parent_slot;
211825982561SQu Wenruo
211925982561SQu Wenruo eb = src_path->nodes[cur_level + 1];
212025982561SQu Wenruo parent_slot = src_path->slots[cur_level + 1];
212125982561SQu Wenruo
21226b2cb7cbSJosef Bacik eb = btrfs_read_node_slot(eb, parent_slot);
212325982561SQu Wenruo if (IS_ERR(eb)) {
212425982561SQu Wenruo ret = PTR_ERR(eb);
212525982561SQu Wenruo goto out;
212625982561SQu Wenruo }
212725982561SQu Wenruo
212825982561SQu Wenruo src_path->nodes[cur_level] = eb;
212925982561SQu Wenruo
213025982561SQu Wenruo btrfs_tree_read_lock(eb);
2131ac5887c8SJosef Bacik src_path->locks[cur_level] = BTRFS_READ_LOCK;
213225982561SQu Wenruo }
213325982561SQu Wenruo
213425982561SQu Wenruo src_path->slots[cur_level] = dst_path->slots[cur_level];
213525982561SQu Wenruo if (cur_level) {
213625982561SQu Wenruo btrfs_node_key_to_cpu(dst_path->nodes[cur_level],
213725982561SQu Wenruo &dst_key, dst_path->slots[cur_level]);
213825982561SQu Wenruo btrfs_node_key_to_cpu(src_path->nodes[cur_level],
213925982561SQu Wenruo &src_key, src_path->slots[cur_level]);
214025982561SQu Wenruo } else {
214125982561SQu Wenruo btrfs_item_key_to_cpu(dst_path->nodes[cur_level],
214225982561SQu Wenruo &dst_key, dst_path->slots[cur_level]);
214325982561SQu Wenruo btrfs_item_key_to_cpu(src_path->nodes[cur_level],
214425982561SQu Wenruo &src_key, src_path->slots[cur_level]);
214525982561SQu Wenruo }
214625982561SQu Wenruo /* Content mismatch, something went wrong */
214725982561SQu Wenruo if (btrfs_comp_cpu_keys(&dst_key, &src_key)) {
214825982561SQu Wenruo ret = -ENOENT;
214925982561SQu Wenruo goto out;
215025982561SQu Wenruo }
215125982561SQu Wenruo cur_level--;
215225982561SQu Wenruo }
215325982561SQu Wenruo
215425982561SQu Wenruo /*
215525982561SQu Wenruo * Now both @dst_path and @src_path have been populated, record the tree
215625982561SQu Wenruo * blocks for qgroup accounting.
215725982561SQu Wenruo */
215825982561SQu Wenruo ret = btrfs_qgroup_trace_extent(trans, src_path->nodes[dst_level]->start,
2159e2896e79SDavid Sterba nodesize);
216025982561SQu Wenruo if (ret < 0)
216125982561SQu Wenruo goto out;
2162e2896e79SDavid Sterba ret = btrfs_qgroup_trace_extent(trans, dst_path->nodes[dst_level]->start,
2163e2896e79SDavid Sterba nodesize);
216425982561SQu Wenruo if (ret < 0)
216525982561SQu Wenruo goto out;
216625982561SQu Wenruo
216725982561SQu Wenruo /* Record leaf file extents */
21683d0174f7SQu Wenruo if (dst_level == 0 && trace_leaf) {
216925982561SQu Wenruo ret = btrfs_qgroup_trace_leaf_items(trans, src_path->nodes[0]);
217025982561SQu Wenruo if (ret < 0)
217125982561SQu Wenruo goto out;
217225982561SQu Wenruo ret = btrfs_qgroup_trace_leaf_items(trans, dst_path->nodes[0]);
217325982561SQu Wenruo }
217425982561SQu Wenruo out:
217525982561SQu Wenruo btrfs_free_path(src_path);
217625982561SQu Wenruo return ret;
217725982561SQu Wenruo }
217825982561SQu Wenruo
2179ea49f3e7SQu Wenruo /*
2180ea49f3e7SQu Wenruo * Helper function to do recursive generation-aware depth-first search, to
2181ea49f3e7SQu Wenruo * locate all new tree blocks in a subtree of reloc tree.
2182ea49f3e7SQu Wenruo *
2183ea49f3e7SQu Wenruo * E.g. (OO = Old tree blocks, NN = New tree blocks, whose gen == last_snapshot)
2184ea49f3e7SQu Wenruo * reloc tree
2185ea49f3e7SQu Wenruo * L2 NN (a)
2186ea49f3e7SQu Wenruo * / \
2187ea49f3e7SQu Wenruo * L1 OO NN (b)
2188ea49f3e7SQu Wenruo * / \ / \
2189ea49f3e7SQu Wenruo * L0 OO OO OO NN
2190ea49f3e7SQu Wenruo * (c) (d)
2191ea49f3e7SQu Wenruo * If we pass:
2192ea49f3e7SQu Wenruo * @dst_path = [ nodes[1] = NN(b), nodes[0] = NULL ],
2193ea49f3e7SQu Wenruo * @cur_level = 1
2194ea49f3e7SQu Wenruo * @root_level = 1
2195ea49f3e7SQu Wenruo *
2196ea49f3e7SQu Wenruo * We will iterate through tree blocks NN(b), NN(d) and info qgroup to trace
2197ea49f3e7SQu Wenruo * above tree blocks along with their counter parts in file tree.
219852042d8eSAndrea Gelmini * While during search, old tree blocks OO(c) will be skipped as tree block swap
2199ea49f3e7SQu Wenruo * won't affect OO(c).
2200ea49f3e7SQu Wenruo */
qgroup_trace_new_subtree_blocks(struct btrfs_trans_handle * trans,struct extent_buffer * src_eb,struct btrfs_path * dst_path,int cur_level,int root_level,u64 last_snapshot,bool trace_leaf)2201ea49f3e7SQu Wenruo static int qgroup_trace_new_subtree_blocks(struct btrfs_trans_handle* trans,
2202ea49f3e7SQu Wenruo struct extent_buffer *src_eb,
2203ea49f3e7SQu Wenruo struct btrfs_path *dst_path,
2204ea49f3e7SQu Wenruo int cur_level, int root_level,
22053d0174f7SQu Wenruo u64 last_snapshot, bool trace_leaf)
2206ea49f3e7SQu Wenruo {
2207ea49f3e7SQu Wenruo struct btrfs_fs_info *fs_info = trans->fs_info;
2208ea49f3e7SQu Wenruo struct extent_buffer *eb;
2209ea49f3e7SQu Wenruo bool need_cleanup = false;
2210ea49f3e7SQu Wenruo int ret = 0;
2211ea49f3e7SQu Wenruo int i;
2212ea49f3e7SQu Wenruo
2213ea49f3e7SQu Wenruo /* Level sanity check */
22147ff2c2a1SNikolay Borisov if (cur_level < 0 || cur_level >= BTRFS_MAX_LEVEL - 1 ||
22157ff2c2a1SNikolay Borisov root_level < 0 || root_level >= BTRFS_MAX_LEVEL - 1 ||
2216ea49f3e7SQu Wenruo root_level < cur_level) {
2217ea49f3e7SQu Wenruo btrfs_err_rl(fs_info,
2218ea49f3e7SQu Wenruo "%s: bad levels, cur_level=%d root_level=%d",
2219ea49f3e7SQu Wenruo __func__, cur_level, root_level);
2220ea49f3e7SQu Wenruo return -EUCLEAN;
2221ea49f3e7SQu Wenruo }
2222ea49f3e7SQu Wenruo
2223ea49f3e7SQu Wenruo /* Read the tree block if needed */
2224ea49f3e7SQu Wenruo if (dst_path->nodes[cur_level] == NULL) {
2225ea49f3e7SQu Wenruo int parent_slot;
2226ea49f3e7SQu Wenruo u64 child_gen;
2227ea49f3e7SQu Wenruo
2228ea49f3e7SQu Wenruo /*
2229ea49f3e7SQu Wenruo * dst_path->nodes[root_level] must be initialized before
2230ea49f3e7SQu Wenruo * calling this function.
2231ea49f3e7SQu Wenruo */
2232ea49f3e7SQu Wenruo if (cur_level == root_level) {
2233ea49f3e7SQu Wenruo btrfs_err_rl(fs_info,
2234ea49f3e7SQu Wenruo "%s: dst_path->nodes[%d] not initialized, root_level=%d cur_level=%d",
2235ea49f3e7SQu Wenruo __func__, root_level, root_level, cur_level);
2236ea49f3e7SQu Wenruo return -EUCLEAN;
2237ea49f3e7SQu Wenruo }
2238ea49f3e7SQu Wenruo
2239ea49f3e7SQu Wenruo /*
2240ea49f3e7SQu Wenruo * We need to get child blockptr/gen from parent before we can
2241ea49f3e7SQu Wenruo * read it.
2242ea49f3e7SQu Wenruo */
2243ea49f3e7SQu Wenruo eb = dst_path->nodes[cur_level + 1];
2244ea49f3e7SQu Wenruo parent_slot = dst_path->slots[cur_level + 1];
2245ea49f3e7SQu Wenruo child_gen = btrfs_node_ptr_generation(eb, parent_slot);
2246ea49f3e7SQu Wenruo
2247ea49f3e7SQu Wenruo /* This node is old, no need to trace */
2248ea49f3e7SQu Wenruo if (child_gen < last_snapshot)
2249ea49f3e7SQu Wenruo goto out;
2250ea49f3e7SQu Wenruo
22513acfbd6aSJosef Bacik eb = btrfs_read_node_slot(eb, parent_slot);
2252ea49f3e7SQu Wenruo if (IS_ERR(eb)) {
2253ea49f3e7SQu Wenruo ret = PTR_ERR(eb);
2254ea49f3e7SQu Wenruo goto out;
2255ea49f3e7SQu Wenruo }
2256ea49f3e7SQu Wenruo
2257ea49f3e7SQu Wenruo dst_path->nodes[cur_level] = eb;
2258ea49f3e7SQu Wenruo dst_path->slots[cur_level] = 0;
2259ea49f3e7SQu Wenruo
2260ea49f3e7SQu Wenruo btrfs_tree_read_lock(eb);
2261ac5887c8SJosef Bacik dst_path->locks[cur_level] = BTRFS_READ_LOCK;
2262ea49f3e7SQu Wenruo need_cleanup = true;
2263ea49f3e7SQu Wenruo }
2264ea49f3e7SQu Wenruo
2265ea49f3e7SQu Wenruo /* Now record this tree block and its counter part for qgroups */
2266ea49f3e7SQu Wenruo ret = qgroup_trace_extent_swap(trans, src_eb, dst_path, cur_level,
22673d0174f7SQu Wenruo root_level, trace_leaf);
2268ea49f3e7SQu Wenruo if (ret < 0)
2269ea49f3e7SQu Wenruo goto cleanup;
2270ea49f3e7SQu Wenruo
2271ea49f3e7SQu Wenruo eb = dst_path->nodes[cur_level];
2272ea49f3e7SQu Wenruo
2273ea49f3e7SQu Wenruo if (cur_level > 0) {
2274ea49f3e7SQu Wenruo /* Iterate all child tree blocks */
2275ea49f3e7SQu Wenruo for (i = 0; i < btrfs_header_nritems(eb); i++) {
2276ea49f3e7SQu Wenruo /* Skip old tree blocks as they won't be swapped */
2277ea49f3e7SQu Wenruo if (btrfs_node_ptr_generation(eb, i) < last_snapshot)
2278ea49f3e7SQu Wenruo continue;
2279ea49f3e7SQu Wenruo dst_path->slots[cur_level] = i;
2280ea49f3e7SQu Wenruo
2281ea49f3e7SQu Wenruo /* Recursive call (at most 7 times) */
2282ea49f3e7SQu Wenruo ret = qgroup_trace_new_subtree_blocks(trans, src_eb,
2283ea49f3e7SQu Wenruo dst_path, cur_level - 1, root_level,
22843d0174f7SQu Wenruo last_snapshot, trace_leaf);
2285ea49f3e7SQu Wenruo if (ret < 0)
2286ea49f3e7SQu Wenruo goto cleanup;
2287ea49f3e7SQu Wenruo }
2288ea49f3e7SQu Wenruo }
2289ea49f3e7SQu Wenruo
2290ea49f3e7SQu Wenruo cleanup:
2291ea49f3e7SQu Wenruo if (need_cleanup) {
2292ea49f3e7SQu Wenruo /* Clean up */
2293ea49f3e7SQu Wenruo btrfs_tree_unlock_rw(dst_path->nodes[cur_level],
2294ea49f3e7SQu Wenruo dst_path->locks[cur_level]);
2295ea49f3e7SQu Wenruo free_extent_buffer(dst_path->nodes[cur_level]);
2296ea49f3e7SQu Wenruo dst_path->nodes[cur_level] = NULL;
2297ea49f3e7SQu Wenruo dst_path->slots[cur_level] = 0;
2298ea49f3e7SQu Wenruo dst_path->locks[cur_level] = 0;
2299ea49f3e7SQu Wenruo }
2300ea49f3e7SQu Wenruo out:
2301ea49f3e7SQu Wenruo return ret;
2302ea49f3e7SQu Wenruo }
2303ea49f3e7SQu Wenruo
qgroup_trace_subtree_swap(struct btrfs_trans_handle * trans,struct extent_buffer * src_eb,struct extent_buffer * dst_eb,u64 last_snapshot,bool trace_leaf)23045aea1a4fSQu Wenruo static int qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans,
23055aea1a4fSQu Wenruo struct extent_buffer *src_eb,
23065aea1a4fSQu Wenruo struct extent_buffer *dst_eb,
23075aea1a4fSQu Wenruo u64 last_snapshot, bool trace_leaf)
23085aea1a4fSQu Wenruo {
23095aea1a4fSQu Wenruo struct btrfs_fs_info *fs_info = trans->fs_info;
23105aea1a4fSQu Wenruo struct btrfs_path *dst_path = NULL;
23115aea1a4fSQu Wenruo int level;
23125aea1a4fSQu Wenruo int ret;
23135aea1a4fSQu Wenruo
23145aea1a4fSQu Wenruo if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
23155aea1a4fSQu Wenruo return 0;
23165aea1a4fSQu Wenruo
23175aea1a4fSQu Wenruo /* Wrong parameter order */
23185aea1a4fSQu Wenruo if (btrfs_header_generation(src_eb) > btrfs_header_generation(dst_eb)) {
23195aea1a4fSQu Wenruo btrfs_err_rl(fs_info,
23205aea1a4fSQu Wenruo "%s: bad parameter order, src_gen=%llu dst_gen=%llu", __func__,
23215aea1a4fSQu Wenruo btrfs_header_generation(src_eb),
23225aea1a4fSQu Wenruo btrfs_header_generation(dst_eb));
23235aea1a4fSQu Wenruo return -EUCLEAN;
23245aea1a4fSQu Wenruo }
23255aea1a4fSQu Wenruo
23265aea1a4fSQu Wenruo if (!extent_buffer_uptodate(src_eb) || !extent_buffer_uptodate(dst_eb)) {
23275aea1a4fSQu Wenruo ret = -EIO;
23285aea1a4fSQu Wenruo goto out;
23295aea1a4fSQu Wenruo }
23305aea1a4fSQu Wenruo
23315aea1a4fSQu Wenruo level = btrfs_header_level(dst_eb);
23325aea1a4fSQu Wenruo dst_path = btrfs_alloc_path();
23335aea1a4fSQu Wenruo if (!dst_path) {
23345aea1a4fSQu Wenruo ret = -ENOMEM;
23355aea1a4fSQu Wenruo goto out;
23365aea1a4fSQu Wenruo }
23375aea1a4fSQu Wenruo /* For dst_path */
233867439dadSDavid Sterba atomic_inc(&dst_eb->refs);
23395aea1a4fSQu Wenruo dst_path->nodes[level] = dst_eb;
23405aea1a4fSQu Wenruo dst_path->slots[level] = 0;
23415aea1a4fSQu Wenruo dst_path->locks[level] = 0;
23425aea1a4fSQu Wenruo
23435aea1a4fSQu Wenruo /* Do the generation aware breadth-first search */
23445aea1a4fSQu Wenruo ret = qgroup_trace_new_subtree_blocks(trans, src_eb, dst_path, level,
23455aea1a4fSQu Wenruo level, last_snapshot, trace_leaf);
23465aea1a4fSQu Wenruo if (ret < 0)
23475aea1a4fSQu Wenruo goto out;
23485aea1a4fSQu Wenruo ret = 0;
23495aea1a4fSQu Wenruo
23505aea1a4fSQu Wenruo out:
23515aea1a4fSQu Wenruo btrfs_free_path(dst_path);
23525aea1a4fSQu Wenruo if (ret < 0)
2353e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
23545aea1a4fSQu Wenruo return ret;
23555aea1a4fSQu Wenruo }
23565aea1a4fSQu Wenruo
btrfs_qgroup_trace_subtree(struct btrfs_trans_handle * trans,struct extent_buffer * root_eb,u64 root_gen,int root_level)235733d1f05cSQu Wenruo int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans,
235833d1f05cSQu Wenruo struct extent_buffer *root_eb,
235933d1f05cSQu Wenruo u64 root_gen, int root_level)
236033d1f05cSQu Wenruo {
2361deb40627SLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
236233d1f05cSQu Wenruo int ret = 0;
236333d1f05cSQu Wenruo int level;
2364011b46c3SQu Wenruo u8 drop_subptree_thres;
236533d1f05cSQu Wenruo struct extent_buffer *eb = root_eb;
236633d1f05cSQu Wenruo struct btrfs_path *path = NULL;
236733d1f05cSQu Wenruo
2368b6e6bca5SNikolay Borisov BUG_ON(root_level < 0 || root_level >= BTRFS_MAX_LEVEL);
236933d1f05cSQu Wenruo BUG_ON(root_eb == NULL);
237033d1f05cSQu Wenruo
23710b246afaSJeff Mahoney if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
237233d1f05cSQu Wenruo return 0;
237333d1f05cSQu Wenruo
2374011b46c3SQu Wenruo spin_lock(&fs_info->qgroup_lock);
2375011b46c3SQu Wenruo drop_subptree_thres = fs_info->qgroup_drop_subtree_thres;
2376011b46c3SQu Wenruo spin_unlock(&fs_info->qgroup_lock);
2377011b46c3SQu Wenruo
2378011b46c3SQu Wenruo /*
2379011b46c3SQu Wenruo * This function only gets called for snapshot drop, if we hit a high
2380011b46c3SQu Wenruo * node here, it means we are going to change ownership for quite a lot
2381011b46c3SQu Wenruo * of extents, which will greatly slow down btrfs_commit_transaction().
2382011b46c3SQu Wenruo *
2383011b46c3SQu Wenruo * So here if we find a high tree here, we just skip the accounting and
2384011b46c3SQu Wenruo * mark qgroup inconsistent.
2385011b46c3SQu Wenruo */
2386011b46c3SQu Wenruo if (root_level >= drop_subptree_thres) {
2387011b46c3SQu Wenruo qgroup_mark_inconsistent(fs_info);
2388011b46c3SQu Wenruo return 0;
2389011b46c3SQu Wenruo }
2390011b46c3SQu Wenruo
239133d1f05cSQu Wenruo if (!extent_buffer_uptodate(root_eb)) {
2392789d6a3aSQu Wenruo struct btrfs_tree_parent_check check = {
2393789d6a3aSQu Wenruo .has_first_key = false,
2394789d6a3aSQu Wenruo .transid = root_gen,
2395789d6a3aSQu Wenruo .level = root_level
2396789d6a3aSQu Wenruo };
2397789d6a3aSQu Wenruo
2398789d6a3aSQu Wenruo ret = btrfs_read_extent_buffer(root_eb, &check);
239933d1f05cSQu Wenruo if (ret)
240033d1f05cSQu Wenruo goto out;
240133d1f05cSQu Wenruo }
240233d1f05cSQu Wenruo
240333d1f05cSQu Wenruo if (root_level == 0) {
24048d38d7ebSLu Fengqi ret = btrfs_qgroup_trace_leaf_items(trans, root_eb);
240533d1f05cSQu Wenruo goto out;
240633d1f05cSQu Wenruo }
240733d1f05cSQu Wenruo
240833d1f05cSQu Wenruo path = btrfs_alloc_path();
240933d1f05cSQu Wenruo if (!path)
241033d1f05cSQu Wenruo return -ENOMEM;
241133d1f05cSQu Wenruo
241233d1f05cSQu Wenruo /*
241333d1f05cSQu Wenruo * Walk down the tree. Missing extent blocks are filled in as
241433d1f05cSQu Wenruo * we go. Metadata is accounted every time we read a new
241533d1f05cSQu Wenruo * extent block.
241633d1f05cSQu Wenruo *
241733d1f05cSQu Wenruo * When we reach a leaf, we account for file extent items in it,
241833d1f05cSQu Wenruo * walk back up the tree (adjusting slot pointers as we go)
241933d1f05cSQu Wenruo * and restart the search process.
242033d1f05cSQu Wenruo */
242167439dadSDavid Sterba atomic_inc(&root_eb->refs); /* For path */
242233d1f05cSQu Wenruo path->nodes[root_level] = root_eb;
242333d1f05cSQu Wenruo path->slots[root_level] = 0;
242433d1f05cSQu Wenruo path->locks[root_level] = 0; /* so release_path doesn't try to unlock */
242533d1f05cSQu Wenruo walk_down:
242633d1f05cSQu Wenruo level = root_level;
242733d1f05cSQu Wenruo while (level >= 0) {
242833d1f05cSQu Wenruo if (path->nodes[level] == NULL) {
242933d1f05cSQu Wenruo int parent_slot;
243033d1f05cSQu Wenruo u64 child_bytenr;
243133d1f05cSQu Wenruo
243233d1f05cSQu Wenruo /*
2433182c79fcSJosef Bacik * We need to get child blockptr from parent before we
2434182c79fcSJosef Bacik * can read it.
243533d1f05cSQu Wenruo */
243633d1f05cSQu Wenruo eb = path->nodes[level + 1];
243733d1f05cSQu Wenruo parent_slot = path->slots[level + 1];
243833d1f05cSQu Wenruo child_bytenr = btrfs_node_blockptr(eb, parent_slot);
243933d1f05cSQu Wenruo
2440182c79fcSJosef Bacik eb = btrfs_read_node_slot(eb, parent_slot);
244133d1f05cSQu Wenruo if (IS_ERR(eb)) {
244233d1f05cSQu Wenruo ret = PTR_ERR(eb);
244333d1f05cSQu Wenruo goto out;
244433d1f05cSQu Wenruo }
244533d1f05cSQu Wenruo
244633d1f05cSQu Wenruo path->nodes[level] = eb;
244733d1f05cSQu Wenruo path->slots[level] = 0;
244833d1f05cSQu Wenruo
244933d1f05cSQu Wenruo btrfs_tree_read_lock(eb);
2450ac5887c8SJosef Bacik path->locks[level] = BTRFS_READ_LOCK;
245133d1f05cSQu Wenruo
2452a95f3aafSLu Fengqi ret = btrfs_qgroup_trace_extent(trans, child_bytenr,
2453e2896e79SDavid Sterba fs_info->nodesize);
245433d1f05cSQu Wenruo if (ret)
245533d1f05cSQu Wenruo goto out;
245633d1f05cSQu Wenruo }
245733d1f05cSQu Wenruo
245833d1f05cSQu Wenruo if (level == 0) {
24598d38d7ebSLu Fengqi ret = btrfs_qgroup_trace_leaf_items(trans,
246033d1f05cSQu Wenruo path->nodes[level]);
246133d1f05cSQu Wenruo if (ret)
246233d1f05cSQu Wenruo goto out;
246333d1f05cSQu Wenruo
246433d1f05cSQu Wenruo /* Nonzero return here means we completed our search */
246515b34517SDavid Sterba ret = adjust_slots_upwards(path, root_level);
246633d1f05cSQu Wenruo if (ret)
246733d1f05cSQu Wenruo break;
246833d1f05cSQu Wenruo
246933d1f05cSQu Wenruo /* Restart search with new slots */
247033d1f05cSQu Wenruo goto walk_down;
247133d1f05cSQu Wenruo }
247233d1f05cSQu Wenruo
247333d1f05cSQu Wenruo level--;
247433d1f05cSQu Wenruo }
247533d1f05cSQu Wenruo
247633d1f05cSQu Wenruo ret = 0;
247733d1f05cSQu Wenruo out:
247833d1f05cSQu Wenruo btrfs_free_path(path);
247933d1f05cSQu Wenruo
248033d1f05cSQu Wenruo return ret;
248133d1f05cSQu Wenruo }
248233d1f05cSQu Wenruo
2483d810ef2bSQu Wenruo #define UPDATE_NEW 0
2484d810ef2bSQu Wenruo #define UPDATE_OLD 1
2485d810ef2bSQu Wenruo /*
2486d810ef2bSQu Wenruo * Walk all of the roots that points to the bytenr and adjust their refcnts.
2487d810ef2bSQu Wenruo */
qgroup_update_refcnt(struct btrfs_fs_info * fs_info,struct ulist * roots,struct ulist * tmp,struct ulist * qgroups,u64 seq,int update_old)2488d810ef2bSQu Wenruo static int qgroup_update_refcnt(struct btrfs_fs_info *fs_info,
2489d810ef2bSQu Wenruo struct ulist *roots, struct ulist *tmp,
2490d810ef2bSQu Wenruo struct ulist *qgroups, u64 seq, int update_old)
2491d810ef2bSQu Wenruo {
2492d810ef2bSQu Wenruo struct ulist_node *unode;
2493d810ef2bSQu Wenruo struct ulist_iterator uiter;
2494d810ef2bSQu Wenruo struct ulist_node *tmp_unode;
2495d810ef2bSQu Wenruo struct ulist_iterator tmp_uiter;
2496d810ef2bSQu Wenruo struct btrfs_qgroup *qg;
2497d810ef2bSQu Wenruo int ret = 0;
2498d810ef2bSQu Wenruo
2499d810ef2bSQu Wenruo if (!roots)
2500d810ef2bSQu Wenruo return 0;
2501d810ef2bSQu Wenruo ULIST_ITER_INIT(&uiter);
2502d810ef2bSQu Wenruo while ((unode = ulist_next(roots, &uiter))) {
2503d810ef2bSQu Wenruo qg = find_qgroup_rb(fs_info, unode->val);
2504d810ef2bSQu Wenruo if (!qg)
2505d810ef2bSQu Wenruo continue;
2506d810ef2bSQu Wenruo
2507d810ef2bSQu Wenruo ulist_reinit(tmp);
2508ef2fff64SDavid Sterba ret = ulist_add(qgroups, qg->qgroupid, qgroup_to_aux(qg),
2509d810ef2bSQu Wenruo GFP_ATOMIC);
2510d810ef2bSQu Wenruo if (ret < 0)
2511d810ef2bSQu Wenruo return ret;
2512ef2fff64SDavid Sterba ret = ulist_add(tmp, qg->qgroupid, qgroup_to_aux(qg), GFP_ATOMIC);
2513d810ef2bSQu Wenruo if (ret < 0)
2514d810ef2bSQu Wenruo return ret;
2515d810ef2bSQu Wenruo ULIST_ITER_INIT(&tmp_uiter);
2516d810ef2bSQu Wenruo while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
2517d810ef2bSQu Wenruo struct btrfs_qgroup_list *glist;
2518d810ef2bSQu Wenruo
2519ef2fff64SDavid Sterba qg = unode_aux_to_qgroup(tmp_unode);
2520d810ef2bSQu Wenruo if (update_old)
2521d810ef2bSQu Wenruo btrfs_qgroup_update_old_refcnt(qg, seq, 1);
2522d810ef2bSQu Wenruo else
2523d810ef2bSQu Wenruo btrfs_qgroup_update_new_refcnt(qg, seq, 1);
2524d810ef2bSQu Wenruo list_for_each_entry(glist, &qg->groups, next_group) {
2525d810ef2bSQu Wenruo ret = ulist_add(qgroups, glist->group->qgroupid,
2526ef2fff64SDavid Sterba qgroup_to_aux(glist->group),
2527d810ef2bSQu Wenruo GFP_ATOMIC);
2528d810ef2bSQu Wenruo if (ret < 0)
2529d810ef2bSQu Wenruo return ret;
2530d810ef2bSQu Wenruo ret = ulist_add(tmp, glist->group->qgroupid,
2531ef2fff64SDavid Sterba qgroup_to_aux(glist->group),
2532d810ef2bSQu Wenruo GFP_ATOMIC);
2533d810ef2bSQu Wenruo if (ret < 0)
2534d810ef2bSQu Wenruo return ret;
2535d810ef2bSQu Wenruo }
2536d810ef2bSQu Wenruo }
2537d810ef2bSQu Wenruo }
2538d810ef2bSQu Wenruo return 0;
2539d810ef2bSQu Wenruo }
2540d810ef2bSQu Wenruo
2541fcebe456SJosef Bacik /*
2542823ae5b8SQu Wenruo * Update qgroup rfer/excl counters.
2543823ae5b8SQu Wenruo * Rfer update is easy, codes can explain themselves.
2544e69bcee3SQu Wenruo *
2545260db43cSRandy Dunlap * Excl update is tricky, the update is split into 2 parts.
2546823ae5b8SQu Wenruo * Part 1: Possible exclusive <-> sharing detect:
2547823ae5b8SQu Wenruo * | A | !A |
2548823ae5b8SQu Wenruo * -------------------------------------
2549823ae5b8SQu Wenruo * B | * | - |
2550823ae5b8SQu Wenruo * -------------------------------------
2551823ae5b8SQu Wenruo * !B | + | ** |
2552823ae5b8SQu Wenruo * -------------------------------------
2553823ae5b8SQu Wenruo *
2554823ae5b8SQu Wenruo * Conditions:
2555823ae5b8SQu Wenruo * A: cur_old_roots < nr_old_roots (not exclusive before)
2556823ae5b8SQu Wenruo * !A: cur_old_roots == nr_old_roots (possible exclusive before)
2557823ae5b8SQu Wenruo * B: cur_new_roots < nr_new_roots (not exclusive now)
255801327610SNicholas D Steeves * !B: cur_new_roots == nr_new_roots (possible exclusive now)
2559823ae5b8SQu Wenruo *
2560823ae5b8SQu Wenruo * Results:
2561823ae5b8SQu Wenruo * +: Possible sharing -> exclusive -: Possible exclusive -> sharing
2562823ae5b8SQu Wenruo * *: Definitely not changed. **: Possible unchanged.
2563823ae5b8SQu Wenruo *
2564823ae5b8SQu Wenruo * For !A and !B condition, the exception is cur_old/new_roots == 0 case.
2565823ae5b8SQu Wenruo *
2566823ae5b8SQu Wenruo * To make the logic clear, we first use condition A and B to split
2567823ae5b8SQu Wenruo * combination into 4 results.
2568823ae5b8SQu Wenruo *
2569823ae5b8SQu Wenruo * Then, for result "+" and "-", check old/new_roots == 0 case, as in them
2570823ae5b8SQu Wenruo * only on variant maybe 0.
2571823ae5b8SQu Wenruo *
2572823ae5b8SQu Wenruo * Lastly, check result **, since there are 2 variants maybe 0, split them
2573823ae5b8SQu Wenruo * again(2x2).
2574823ae5b8SQu Wenruo * But this time we don't need to consider other things, the codes and logic
2575823ae5b8SQu Wenruo * is easy to understand now.
2576823ae5b8SQu Wenruo */
qgroup_update_counters(struct btrfs_fs_info * fs_info,struct ulist * qgroups,u64 nr_old_roots,u64 nr_new_roots,u64 num_bytes,u64 seq)2577823ae5b8SQu Wenruo static int qgroup_update_counters(struct btrfs_fs_info *fs_info,
2578823ae5b8SQu Wenruo struct ulist *qgroups,
2579823ae5b8SQu Wenruo u64 nr_old_roots,
2580823ae5b8SQu Wenruo u64 nr_new_roots,
2581823ae5b8SQu Wenruo u64 num_bytes, u64 seq)
2582823ae5b8SQu Wenruo {
2583823ae5b8SQu Wenruo struct ulist_node *unode;
2584823ae5b8SQu Wenruo struct ulist_iterator uiter;
2585823ae5b8SQu Wenruo struct btrfs_qgroup *qg;
2586823ae5b8SQu Wenruo u64 cur_new_count, cur_old_count;
2587823ae5b8SQu Wenruo
2588823ae5b8SQu Wenruo ULIST_ITER_INIT(&uiter);
2589823ae5b8SQu Wenruo while ((unode = ulist_next(qgroups, &uiter))) {
2590823ae5b8SQu Wenruo bool dirty = false;
2591823ae5b8SQu Wenruo
2592ef2fff64SDavid Sterba qg = unode_aux_to_qgroup(unode);
2593823ae5b8SQu Wenruo cur_old_count = btrfs_qgroup_get_old_refcnt(qg, seq);
2594823ae5b8SQu Wenruo cur_new_count = btrfs_qgroup_get_new_refcnt(qg, seq);
2595823ae5b8SQu Wenruo
25968b317901SQu Wenruo trace_qgroup_update_counters(fs_info, qg, cur_old_count,
25978b317901SQu Wenruo cur_new_count);
25980f5dcf8dSMark Fasheh
2599823ae5b8SQu Wenruo /* Rfer update part */
2600823ae5b8SQu Wenruo if (cur_old_count == 0 && cur_new_count > 0) {
2601823ae5b8SQu Wenruo qg->rfer += num_bytes;
2602823ae5b8SQu Wenruo qg->rfer_cmpr += num_bytes;
2603823ae5b8SQu Wenruo dirty = true;
2604823ae5b8SQu Wenruo }
2605823ae5b8SQu Wenruo if (cur_old_count > 0 && cur_new_count == 0) {
2606823ae5b8SQu Wenruo qg->rfer -= num_bytes;
2607823ae5b8SQu Wenruo qg->rfer_cmpr -= num_bytes;
2608823ae5b8SQu Wenruo dirty = true;
2609823ae5b8SQu Wenruo }
2610823ae5b8SQu Wenruo
2611823ae5b8SQu Wenruo /* Excl update part */
2612823ae5b8SQu Wenruo /* Exclusive/none -> shared case */
2613823ae5b8SQu Wenruo if (cur_old_count == nr_old_roots &&
2614823ae5b8SQu Wenruo cur_new_count < nr_new_roots) {
2615823ae5b8SQu Wenruo /* Exclusive -> shared */
2616823ae5b8SQu Wenruo if (cur_old_count != 0) {
2617823ae5b8SQu Wenruo qg->excl -= num_bytes;
2618823ae5b8SQu Wenruo qg->excl_cmpr -= num_bytes;
2619823ae5b8SQu Wenruo dirty = true;
2620823ae5b8SQu Wenruo }
2621823ae5b8SQu Wenruo }
2622823ae5b8SQu Wenruo
2623823ae5b8SQu Wenruo /* Shared -> exclusive/none case */
2624823ae5b8SQu Wenruo if (cur_old_count < nr_old_roots &&
2625823ae5b8SQu Wenruo cur_new_count == nr_new_roots) {
2626823ae5b8SQu Wenruo /* Shared->exclusive */
2627823ae5b8SQu Wenruo if (cur_new_count != 0) {
2628823ae5b8SQu Wenruo qg->excl += num_bytes;
2629823ae5b8SQu Wenruo qg->excl_cmpr += num_bytes;
2630823ae5b8SQu Wenruo dirty = true;
2631823ae5b8SQu Wenruo }
2632823ae5b8SQu Wenruo }
2633823ae5b8SQu Wenruo
2634823ae5b8SQu Wenruo /* Exclusive/none -> exclusive/none case */
2635823ae5b8SQu Wenruo if (cur_old_count == nr_old_roots &&
2636823ae5b8SQu Wenruo cur_new_count == nr_new_roots) {
2637823ae5b8SQu Wenruo if (cur_old_count == 0) {
2638823ae5b8SQu Wenruo /* None -> exclusive/none */
2639823ae5b8SQu Wenruo
2640823ae5b8SQu Wenruo if (cur_new_count != 0) {
2641823ae5b8SQu Wenruo /* None -> exclusive */
2642823ae5b8SQu Wenruo qg->excl += num_bytes;
2643823ae5b8SQu Wenruo qg->excl_cmpr += num_bytes;
2644823ae5b8SQu Wenruo dirty = true;
2645823ae5b8SQu Wenruo }
2646823ae5b8SQu Wenruo /* None -> none, nothing changed */
2647823ae5b8SQu Wenruo } else {
2648823ae5b8SQu Wenruo /* Exclusive -> exclusive/none */
2649823ae5b8SQu Wenruo
2650823ae5b8SQu Wenruo if (cur_new_count == 0) {
2651823ae5b8SQu Wenruo /* Exclusive -> none */
2652823ae5b8SQu Wenruo qg->excl -= num_bytes;
2653823ae5b8SQu Wenruo qg->excl_cmpr -= num_bytes;
2654823ae5b8SQu Wenruo dirty = true;
2655823ae5b8SQu Wenruo }
2656823ae5b8SQu Wenruo /* Exclusive -> exclusive, nothing changed */
2657823ae5b8SQu Wenruo }
2658823ae5b8SQu Wenruo }
2659c05f9429SQu Wenruo
2660823ae5b8SQu Wenruo if (dirty)
2661823ae5b8SQu Wenruo qgroup_dirty(fs_info, qg);
2662823ae5b8SQu Wenruo }
2663823ae5b8SQu Wenruo return 0;
2664823ae5b8SQu Wenruo }
2665823ae5b8SQu Wenruo
26665edfd9fdSQu Wenruo /*
26675edfd9fdSQu Wenruo * Check if the @roots potentially is a list of fs tree roots
26685edfd9fdSQu Wenruo *
26695edfd9fdSQu Wenruo * Return 0 for definitely not a fs/subvol tree roots ulist
26705edfd9fdSQu Wenruo * Return 1 for possible fs/subvol tree roots in the list (considering an empty
26715edfd9fdSQu Wenruo * one as well)
26725edfd9fdSQu Wenruo */
maybe_fs_roots(struct ulist * roots)26735edfd9fdSQu Wenruo static int maybe_fs_roots(struct ulist *roots)
26745edfd9fdSQu Wenruo {
26755edfd9fdSQu Wenruo struct ulist_node *unode;
26765edfd9fdSQu Wenruo struct ulist_iterator uiter;
26775edfd9fdSQu Wenruo
26785edfd9fdSQu Wenruo /* Empty one, still possible for fs roots */
26795edfd9fdSQu Wenruo if (!roots || roots->nnodes == 0)
26805edfd9fdSQu Wenruo return 1;
26815edfd9fdSQu Wenruo
26825edfd9fdSQu Wenruo ULIST_ITER_INIT(&uiter);
26835edfd9fdSQu Wenruo unode = ulist_next(roots, &uiter);
26845edfd9fdSQu Wenruo if (!unode)
26855edfd9fdSQu Wenruo return 1;
26865edfd9fdSQu Wenruo
26875edfd9fdSQu Wenruo /*
26885edfd9fdSQu Wenruo * If it contains fs tree roots, then it must belong to fs/subvol
26895edfd9fdSQu Wenruo * trees.
26905edfd9fdSQu Wenruo * If it contains a non-fs tree, it won't be shared with fs/subvol trees.
26915edfd9fdSQu Wenruo */
26925edfd9fdSQu Wenruo return is_fstree(unode->val);
26935edfd9fdSQu Wenruo }
26945edfd9fdSQu Wenruo
btrfs_qgroup_account_extent(struct btrfs_trans_handle * trans,u64 bytenr,u64 num_bytes,struct ulist * old_roots,struct ulist * new_roots)26958696d760SLu Fengqi int btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, u64 bytenr,
26968696d760SLu Fengqi u64 num_bytes, struct ulist *old_roots,
26978696d760SLu Fengqi struct ulist *new_roots)
2698550d7a2eSQu Wenruo {
26998696d760SLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
2700550d7a2eSQu Wenruo struct ulist *qgroups = NULL;
2701550d7a2eSQu Wenruo struct ulist *tmp = NULL;
2702550d7a2eSQu Wenruo u64 seq;
2703550d7a2eSQu Wenruo u64 nr_new_roots = 0;
2704550d7a2eSQu Wenruo u64 nr_old_roots = 0;
2705550d7a2eSQu Wenruo int ret = 0;
2706550d7a2eSQu Wenruo
270726ef8493SJohannes Thumshirn /*
27081a9fd417SDavid Sterba * If quotas get disabled meanwhile, the resources need to be freed and
270926ef8493SJohannes Thumshirn * we can't just exit here.
271026ef8493SJohannes Thumshirn */
2711e15e9f43SQu Wenruo if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
2712e15e9f43SQu Wenruo fs_info->qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING)
271326ef8493SJohannes Thumshirn goto out_free;
271481353d50SDavid Sterba
27155edfd9fdSQu Wenruo if (new_roots) {
27165edfd9fdSQu Wenruo if (!maybe_fs_roots(new_roots))
27175edfd9fdSQu Wenruo goto out_free;
2718550d7a2eSQu Wenruo nr_new_roots = new_roots->nnodes;
27195edfd9fdSQu Wenruo }
27205edfd9fdSQu Wenruo if (old_roots) {
27215edfd9fdSQu Wenruo if (!maybe_fs_roots(old_roots))
27225edfd9fdSQu Wenruo goto out_free;
2723550d7a2eSQu Wenruo nr_old_roots = old_roots->nnodes;
27245edfd9fdSQu Wenruo }
27255edfd9fdSQu Wenruo
27265edfd9fdSQu Wenruo /* Quick exit, either not fs tree roots, or won't affect any qgroup */
27275edfd9fdSQu Wenruo if (nr_old_roots == 0 && nr_new_roots == 0)
27285edfd9fdSQu Wenruo goto out_free;
2729550d7a2eSQu Wenruo
2730c9f6f3cdSQu Wenruo trace_btrfs_qgroup_account_extent(fs_info, trans->transid, bytenr,
2731c9f6f3cdSQu Wenruo num_bytes, nr_old_roots, nr_new_roots);
27320f5dcf8dSMark Fasheh
2733550d7a2eSQu Wenruo qgroups = ulist_alloc(GFP_NOFS);
2734550d7a2eSQu Wenruo if (!qgroups) {
2735550d7a2eSQu Wenruo ret = -ENOMEM;
2736550d7a2eSQu Wenruo goto out_free;
2737550d7a2eSQu Wenruo }
2738550d7a2eSQu Wenruo tmp = ulist_alloc(GFP_NOFS);
2739550d7a2eSQu Wenruo if (!tmp) {
2740550d7a2eSQu Wenruo ret = -ENOMEM;
2741550d7a2eSQu Wenruo goto out_free;
2742550d7a2eSQu Wenruo }
2743550d7a2eSQu Wenruo
2744550d7a2eSQu Wenruo mutex_lock(&fs_info->qgroup_rescan_lock);
2745550d7a2eSQu Wenruo if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
2746550d7a2eSQu Wenruo if (fs_info->qgroup_rescan_progress.objectid <= bytenr) {
2747550d7a2eSQu Wenruo mutex_unlock(&fs_info->qgroup_rescan_lock);
2748550d7a2eSQu Wenruo ret = 0;
2749550d7a2eSQu Wenruo goto out_free;
2750550d7a2eSQu Wenruo }
2751550d7a2eSQu Wenruo }
2752550d7a2eSQu Wenruo mutex_unlock(&fs_info->qgroup_rescan_lock);
2753550d7a2eSQu Wenruo
2754550d7a2eSQu Wenruo spin_lock(&fs_info->qgroup_lock);
2755550d7a2eSQu Wenruo seq = fs_info->qgroup_seq;
2756550d7a2eSQu Wenruo
2757550d7a2eSQu Wenruo /* Update old refcnts using old_roots */
2758550d7a2eSQu Wenruo ret = qgroup_update_refcnt(fs_info, old_roots, tmp, qgroups, seq,
2759550d7a2eSQu Wenruo UPDATE_OLD);
2760550d7a2eSQu Wenruo if (ret < 0)
2761550d7a2eSQu Wenruo goto out;
2762550d7a2eSQu Wenruo
2763550d7a2eSQu Wenruo /* Update new refcnts using new_roots */
2764550d7a2eSQu Wenruo ret = qgroup_update_refcnt(fs_info, new_roots, tmp, qgroups, seq,
2765550d7a2eSQu Wenruo UPDATE_NEW);
2766550d7a2eSQu Wenruo if (ret < 0)
2767550d7a2eSQu Wenruo goto out;
2768550d7a2eSQu Wenruo
2769550d7a2eSQu Wenruo qgroup_update_counters(fs_info, qgroups, nr_old_roots, nr_new_roots,
2770550d7a2eSQu Wenruo num_bytes, seq);
2771550d7a2eSQu Wenruo
2772550d7a2eSQu Wenruo /*
2773550d7a2eSQu Wenruo * Bump qgroup_seq to avoid seq overlap
2774550d7a2eSQu Wenruo */
2775550d7a2eSQu Wenruo fs_info->qgroup_seq += max(nr_old_roots, nr_new_roots) + 1;
2776550d7a2eSQu Wenruo out:
2777550d7a2eSQu Wenruo spin_unlock(&fs_info->qgroup_lock);
2778550d7a2eSQu Wenruo out_free:
2779550d7a2eSQu Wenruo ulist_free(tmp);
2780550d7a2eSQu Wenruo ulist_free(qgroups);
2781550d7a2eSQu Wenruo ulist_free(old_roots);
2782550d7a2eSQu Wenruo ulist_free(new_roots);
2783550d7a2eSQu Wenruo return ret;
2784550d7a2eSQu Wenruo }
2785550d7a2eSQu Wenruo
btrfs_qgroup_account_extents(struct btrfs_trans_handle * trans)2786460fb20aSNikolay Borisov int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans)
2787550d7a2eSQu Wenruo {
2788460fb20aSNikolay Borisov struct btrfs_fs_info *fs_info = trans->fs_info;
2789550d7a2eSQu Wenruo struct btrfs_qgroup_extent_record *record;
2790550d7a2eSQu Wenruo struct btrfs_delayed_ref_root *delayed_refs;
2791550d7a2eSQu Wenruo struct ulist *new_roots = NULL;
2792550d7a2eSQu Wenruo struct rb_node *node;
2793c337e7b0SQu Wenruo u64 num_dirty_extents = 0;
27949086db86SQu Wenruo u64 qgroup_to_skip;
2795550d7a2eSQu Wenruo int ret = 0;
2796550d7a2eSQu Wenruo
2797550d7a2eSQu Wenruo delayed_refs = &trans->transaction->delayed_refs;
27989086db86SQu Wenruo qgroup_to_skip = delayed_refs->qgroup_to_skip;
2799550d7a2eSQu Wenruo while ((node = rb_first(&delayed_refs->dirty_extent_root))) {
2800550d7a2eSQu Wenruo record = rb_entry(node, struct btrfs_qgroup_extent_record,
2801550d7a2eSQu Wenruo node);
2802550d7a2eSQu Wenruo
2803c337e7b0SQu Wenruo num_dirty_extents++;
2804bc074524SJeff Mahoney trace_btrfs_qgroup_account_extents(fs_info, record);
28050f5dcf8dSMark Fasheh
2806e15e9f43SQu Wenruo if (!ret && !(fs_info->qgroup_flags &
2807e15e9f43SQu Wenruo BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING)) {
2808a2c8d27eSFilipe Manana struct btrfs_backref_walk_ctx ctx = { 0 };
2809a2c8d27eSFilipe Manana
2810a2c8d27eSFilipe Manana ctx.bytenr = record->bytenr;
2811a2c8d27eSFilipe Manana ctx.fs_info = fs_info;
2812a2c8d27eSFilipe Manana
2813550d7a2eSQu Wenruo /*
2814d1b8b94aSQu Wenruo * Old roots should be searched when inserting qgroup
281575181406SQu Wenruo * extent record.
281675181406SQu Wenruo *
281775181406SQu Wenruo * But for INCONSISTENT (NO_ACCOUNTING) -> rescan case,
281875181406SQu Wenruo * we may have some record inserted during
281975181406SQu Wenruo * NO_ACCOUNTING (thus no old_roots populated), but
282075181406SQu Wenruo * later we start rescan, which clears NO_ACCOUNTING,
282175181406SQu Wenruo * leaving some inserted records without old_roots
282275181406SQu Wenruo * populated.
282375181406SQu Wenruo *
282475181406SQu Wenruo * Those cases are rare and should not cause too much
282575181406SQu Wenruo * time spent during commit_transaction().
2826d1b8b94aSQu Wenruo */
282775181406SQu Wenruo if (!record->old_roots) {
2828d1b8b94aSQu Wenruo /* Search commit root to find old_roots */
2829a2c8d27eSFilipe Manana ret = btrfs_find_all_roots(&ctx, false);
2830d1b8b94aSQu Wenruo if (ret < 0)
2831d1b8b94aSQu Wenruo goto cleanup;
2832a2c8d27eSFilipe Manana record->old_roots = ctx.roots;
2833a2c8d27eSFilipe Manana ctx.roots = NULL;
2834d1b8b94aSQu Wenruo }
2835d1b8b94aSQu Wenruo
2836d1b8b94aSQu Wenruo /*
2837f3a84ccdSFilipe Manana * Use BTRFS_SEQ_LAST as time_seq to do special search,
2838f3a84ccdSFilipe Manana * which doesn't lock tree or delayed_refs and search
2839f3a84ccdSFilipe Manana * current root. It's safe inside commit_transaction().
2840550d7a2eSQu Wenruo */
2841a2c8d27eSFilipe Manana ctx.trans = trans;
2842f1f0460cSJosef Bacik ctx.time_seq = BTRFS_SEQ_LAST;
2843a2c8d27eSFilipe Manana ret = btrfs_find_all_roots(&ctx, false);
2844550d7a2eSQu Wenruo if (ret < 0)
2845550d7a2eSQu Wenruo goto cleanup;
2846a2c8d27eSFilipe Manana new_roots = ctx.roots;
2847d1b8b94aSQu Wenruo if (qgroup_to_skip) {
28489086db86SQu Wenruo ulist_del(new_roots, qgroup_to_skip, 0);
2849d1b8b94aSQu Wenruo ulist_del(record->old_roots, qgroup_to_skip,
2850d1b8b94aSQu Wenruo 0);
2851d1b8b94aSQu Wenruo }
28528696d760SLu Fengqi ret = btrfs_qgroup_account_extent(trans, record->bytenr,
28538696d760SLu Fengqi record->num_bytes,
28548696d760SLu Fengqi record->old_roots,
28558696d760SLu Fengqi new_roots);
2856550d7a2eSQu Wenruo record->old_roots = NULL;
2857550d7a2eSQu Wenruo new_roots = NULL;
2858550d7a2eSQu Wenruo }
285940a24160SQu Wenruo /* Free the reserved data space */
286040a24160SQu Wenruo btrfs_qgroup_free_refroot(fs_info,
286140a24160SQu Wenruo record->data_rsv_refroot,
286240a24160SQu Wenruo record->data_rsv,
286340a24160SQu Wenruo BTRFS_QGROUP_RSV_DATA);
2864550d7a2eSQu Wenruo cleanup:
2865550d7a2eSQu Wenruo ulist_free(record->old_roots);
2866550d7a2eSQu Wenruo ulist_free(new_roots);
2867550d7a2eSQu Wenruo new_roots = NULL;
2868550d7a2eSQu Wenruo rb_erase(node, &delayed_refs->dirty_extent_root);
2869550d7a2eSQu Wenruo kfree(record);
2870550d7a2eSQu Wenruo
2871550d7a2eSQu Wenruo }
2872c337e7b0SQu Wenruo trace_qgroup_num_dirty_extents(fs_info, trans->transid,
2873c337e7b0SQu Wenruo num_dirty_extents);
2874550d7a2eSQu Wenruo return ret;
2875550d7a2eSQu Wenruo }
2876550d7a2eSQu Wenruo
2877bed92eaeSArne Jansen /*
28782f1a6be1SFilipe Manana * Writes all changed qgroups to disk.
28792f1a6be1SFilipe Manana * Called by the transaction commit path and the qgroup assign ioctl.
2880bed92eaeSArne Jansen */
btrfs_run_qgroups(struct btrfs_trans_handle * trans)2881280f8bd2SLu Fengqi int btrfs_run_qgroups(struct btrfs_trans_handle *trans)
2882bed92eaeSArne Jansen {
2883280f8bd2SLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
2884bed92eaeSArne Jansen int ret = 0;
2885bed92eaeSArne Jansen
28862f1a6be1SFilipe Manana /*
28872f1a6be1SFilipe Manana * In case we are called from the qgroup assign ioctl, assert that we
28882f1a6be1SFilipe Manana * are holding the qgroup_ioctl_lock, otherwise we can race with a quota
28892f1a6be1SFilipe Manana * disable operation (ioctl) and access a freed quota root.
28902f1a6be1SFilipe Manana */
28912f1a6be1SFilipe Manana if (trans->transaction->state != TRANS_STATE_COMMIT_DOING)
28922f1a6be1SFilipe Manana lockdep_assert_held(&fs_info->qgroup_ioctl_lock);
28932f1a6be1SFilipe Manana
2894e3b0edd2SMarcos Paulo de Souza if (!fs_info->quota_root)
28955d23515bSNikolay Borisov return ret;
2896bed92eaeSArne Jansen
2897bed92eaeSArne Jansen spin_lock(&fs_info->qgroup_lock);
2898bed92eaeSArne Jansen while (!list_empty(&fs_info->dirty_qgroups)) {
2899bed92eaeSArne Jansen struct btrfs_qgroup *qgroup;
2900bed92eaeSArne Jansen qgroup = list_first_entry(&fs_info->dirty_qgroups,
2901bed92eaeSArne Jansen struct btrfs_qgroup, dirty);
2902bed92eaeSArne Jansen list_del_init(&qgroup->dirty);
2903bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
29043e07e9a0SLu Fengqi ret = update_qgroup_info_item(trans, qgroup);
2905bed92eaeSArne Jansen if (ret)
2906e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
2907ac8a866aSLu Fengqi ret = update_qgroup_limit_item(trans, qgroup);
2908d3001ed3SDongsheng Yang if (ret)
2909e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
2910bed92eaeSArne Jansen spin_lock(&fs_info->qgroup_lock);
2911bed92eaeSArne Jansen }
2912afcdd129SJosef Bacik if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
2913bed92eaeSArne Jansen fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_ON;
2914bed92eaeSArne Jansen else
2915bed92eaeSArne Jansen fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
2916bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
2917bed92eaeSArne Jansen
29182e980acdSLu Fengqi ret = update_qgroup_status_item(trans);
2919bed92eaeSArne Jansen if (ret)
2920e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
2921bed92eaeSArne Jansen
2922bed92eaeSArne Jansen return ret;
2923bed92eaeSArne Jansen }
2924bed92eaeSArne Jansen
2925bed92eaeSArne Jansen /*
292601327610SNicholas D Steeves * Copy the accounting information between qgroups. This is necessary
2927918c2ee1SMark Fasheh * when a snapshot or a subvolume is created. Throwing an error will
2928918c2ee1SMark Fasheh * cause a transaction abort so we take extra care here to only error
2929918c2ee1SMark Fasheh * when a readonly fs is a reasonable outcome.
2930bed92eaeSArne Jansen */
btrfs_qgroup_inherit(struct btrfs_trans_handle * trans,u64 srcid,u64 objectid,struct btrfs_qgroup_inherit * inherit)2931a9377422SLu Fengqi int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
2932a9377422SLu Fengqi u64 objectid, struct btrfs_qgroup_inherit *inherit)
2933bed92eaeSArne Jansen {
2934bed92eaeSArne Jansen int ret = 0;
2935bed92eaeSArne Jansen int i;
2936bed92eaeSArne Jansen u64 *i_qgroups;
2937e88439deSQu Wenruo bool committing = false;
2938a9377422SLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
2939552f0329SFilipe Manana struct btrfs_root *quota_root;
2940bed92eaeSArne Jansen struct btrfs_qgroup *srcgroup;
2941bed92eaeSArne Jansen struct btrfs_qgroup *dstgroup;
2942cbab8adeSQu Wenruo bool need_rescan = false;
2943bed92eaeSArne Jansen u32 level_size = 0;
29443f5e2d3bSWang Shilong u64 nums;
2945bed92eaeSArne Jansen
2946e88439deSQu Wenruo /*
2947e88439deSQu Wenruo * There are only two callers of this function.
2948e88439deSQu Wenruo *
2949e88439deSQu Wenruo * One in create_subvol() in the ioctl context, which needs to hold
2950e88439deSQu Wenruo * the qgroup_ioctl_lock.
2951e88439deSQu Wenruo *
2952e88439deSQu Wenruo * The other one in create_pending_snapshot() where no other qgroup
2953e88439deSQu Wenruo * code can modify the fs as they all need to either start a new trans
2954e88439deSQu Wenruo * or hold a trans handler, thus we don't need to hold
2955e88439deSQu Wenruo * qgroup_ioctl_lock.
2956e88439deSQu Wenruo * This would avoid long and complex lock chain and make lockdep happy.
2957e88439deSQu Wenruo */
2958e88439deSQu Wenruo spin_lock(&fs_info->trans_lock);
2959e88439deSQu Wenruo if (trans->transaction->state == TRANS_STATE_COMMIT_DOING)
2960e88439deSQu Wenruo committing = true;
2961e88439deSQu Wenruo spin_unlock(&fs_info->trans_lock);
2962e88439deSQu Wenruo
2963e88439deSQu Wenruo if (!committing)
2964f2f6ed3dSWang Shilong mutex_lock(&fs_info->qgroup_ioctl_lock);
2965afcdd129SJosef Bacik if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
2966f2f6ed3dSWang Shilong goto out;
2967bed92eaeSArne Jansen
2968552f0329SFilipe Manana quota_root = fs_info->quota_root;
2969f2f6ed3dSWang Shilong if (!quota_root) {
2970f2f6ed3dSWang Shilong ret = -EINVAL;
2971f2f6ed3dSWang Shilong goto out;
2972f2f6ed3dSWang Shilong }
2973bed92eaeSArne Jansen
29743f5e2d3bSWang Shilong if (inherit) {
29753f5e2d3bSWang Shilong i_qgroups = (u64 *)(inherit + 1);
29763f5e2d3bSWang Shilong nums = inherit->num_qgroups + 2 * inherit->num_ref_copies +
29773f5e2d3bSWang Shilong 2 * inherit->num_excl_copies;
29783f5e2d3bSWang Shilong for (i = 0; i < nums; ++i) {
29793f5e2d3bSWang Shilong srcgroup = find_qgroup_rb(fs_info, *i_qgroups);
298009870d27SDongsheng Yang
2981918c2ee1SMark Fasheh /*
2982918c2ee1SMark Fasheh * Zero out invalid groups so we can ignore
2983918c2ee1SMark Fasheh * them later.
2984918c2ee1SMark Fasheh */
2985918c2ee1SMark Fasheh if (!srcgroup ||
2986918c2ee1SMark Fasheh ((srcgroup->qgroupid >> 48) <= (objectid >> 48)))
2987918c2ee1SMark Fasheh *i_qgroups = 0ULL;
2988918c2ee1SMark Fasheh
29893f5e2d3bSWang Shilong ++i_qgroups;
29903f5e2d3bSWang Shilong }
29913f5e2d3bSWang Shilong }
29923f5e2d3bSWang Shilong
2993bed92eaeSArne Jansen /*
2994bed92eaeSArne Jansen * create a tracking group for the subvol itself
2995bed92eaeSArne Jansen */
2996bed92eaeSArne Jansen ret = add_qgroup_item(trans, quota_root, objectid);
2997bed92eaeSArne Jansen if (ret)
2998bed92eaeSArne Jansen goto out;
2999bed92eaeSArne Jansen
3000bed92eaeSArne Jansen /*
3001bed92eaeSArne Jansen * add qgroup to all inherited groups
3002bed92eaeSArne Jansen */
3003bed92eaeSArne Jansen if (inherit) {
3004bed92eaeSArne Jansen i_qgroups = (u64 *)(inherit + 1);
3005918c2ee1SMark Fasheh for (i = 0; i < inherit->num_qgroups; ++i, ++i_qgroups) {
3006918c2ee1SMark Fasheh if (*i_qgroups == 0)
3007918c2ee1SMark Fasheh continue;
3008711169c4SLu Fengqi ret = add_qgroup_relation_item(trans, objectid,
3009711169c4SLu Fengqi *i_qgroups);
3010918c2ee1SMark Fasheh if (ret && ret != -EEXIST)
3011bed92eaeSArne Jansen goto out;
3012711169c4SLu Fengqi ret = add_qgroup_relation_item(trans, *i_qgroups,
3013711169c4SLu Fengqi objectid);
3014918c2ee1SMark Fasheh if (ret && ret != -EEXIST)
3015bed92eaeSArne Jansen goto out;
3016bed92eaeSArne Jansen }
3017918c2ee1SMark Fasheh ret = 0;
3018bed92eaeSArne Jansen }
3019bed92eaeSArne Jansen
3020bed92eaeSArne Jansen
3021bed92eaeSArne Jansen spin_lock(&fs_info->qgroup_lock);
3022bed92eaeSArne Jansen
3023bed92eaeSArne Jansen dstgroup = add_qgroup_rb(fs_info, objectid);
302457a5a882SDan Carpenter if (IS_ERR(dstgroup)) {
302557a5a882SDan Carpenter ret = PTR_ERR(dstgroup);
3026bed92eaeSArne Jansen goto unlock;
302757a5a882SDan Carpenter }
3028bed92eaeSArne Jansen
3029e8c8541aSDongsheng Yang if (inherit && inherit->flags & BTRFS_QGROUP_INHERIT_SET_LIMITS) {
3030e8c8541aSDongsheng Yang dstgroup->lim_flags = inherit->lim.flags;
3031e8c8541aSDongsheng Yang dstgroup->max_rfer = inherit->lim.max_rfer;
3032e8c8541aSDongsheng Yang dstgroup->max_excl = inherit->lim.max_excl;
3033e8c8541aSDongsheng Yang dstgroup->rsv_rfer = inherit->lim.rsv_rfer;
3034e8c8541aSDongsheng Yang dstgroup->rsv_excl = inherit->lim.rsv_excl;
30351510e71cSDongsheng Yang
3036f7e942b5SChenXiaoSong qgroup_dirty(fs_info, dstgroup);
3037e8c8541aSDongsheng Yang }
3038e8c8541aSDongsheng Yang
3039bed92eaeSArne Jansen if (srcid) {
3040bed92eaeSArne Jansen srcgroup = find_qgroup_rb(fs_info, srcid);
3041f3a87f1bSChris Mason if (!srcgroup)
3042bed92eaeSArne Jansen goto unlock;
3043fcebe456SJosef Bacik
3044fcebe456SJosef Bacik /*
3045fcebe456SJosef Bacik * We call inherit after we clone the root in order to make sure
3046fcebe456SJosef Bacik * our counts don't go crazy, so at this point the only
3047fcebe456SJosef Bacik * difference between the two roots should be the root node.
3048fcebe456SJosef Bacik */
3049c8389d4cSLu Fengqi level_size = fs_info->nodesize;
3050fcebe456SJosef Bacik dstgroup->rfer = srcgroup->rfer;
3051fcebe456SJosef Bacik dstgroup->rfer_cmpr = srcgroup->rfer_cmpr;
3052fcebe456SJosef Bacik dstgroup->excl = level_size;
3053fcebe456SJosef Bacik dstgroup->excl_cmpr = level_size;
3054bed92eaeSArne Jansen srcgroup->excl = level_size;
3055bed92eaeSArne Jansen srcgroup->excl_cmpr = level_size;
30563eeb4d59SDongsheng Yang
30573eeb4d59SDongsheng Yang /* inherit the limit info */
30583eeb4d59SDongsheng Yang dstgroup->lim_flags = srcgroup->lim_flags;
30593eeb4d59SDongsheng Yang dstgroup->max_rfer = srcgroup->max_rfer;
30603eeb4d59SDongsheng Yang dstgroup->max_excl = srcgroup->max_excl;
30613eeb4d59SDongsheng Yang dstgroup->rsv_rfer = srcgroup->rsv_rfer;
30623eeb4d59SDongsheng Yang dstgroup->rsv_excl = srcgroup->rsv_excl;
30633eeb4d59SDongsheng Yang
3064bed92eaeSArne Jansen qgroup_dirty(fs_info, dstgroup);
3065bed92eaeSArne Jansen qgroup_dirty(fs_info, srcgroup);
3066bed92eaeSArne Jansen }
3067bed92eaeSArne Jansen
3068f3a87f1bSChris Mason if (!inherit)
3069bed92eaeSArne Jansen goto unlock;
3070bed92eaeSArne Jansen
3071bed92eaeSArne Jansen i_qgroups = (u64 *)(inherit + 1);
3072bed92eaeSArne Jansen for (i = 0; i < inherit->num_qgroups; ++i) {
3073918c2ee1SMark Fasheh if (*i_qgroups) {
30740b246afaSJeff Mahoney ret = add_relation_rb(fs_info, objectid, *i_qgroups);
3075bed92eaeSArne Jansen if (ret)
3076bed92eaeSArne Jansen goto unlock;
3077918c2ee1SMark Fasheh }
3078bed92eaeSArne Jansen ++i_qgroups;
3079cbab8adeSQu Wenruo
3080cbab8adeSQu Wenruo /*
3081cbab8adeSQu Wenruo * If we're doing a snapshot, and adding the snapshot to a new
3082cbab8adeSQu Wenruo * qgroup, the numbers are guaranteed to be incorrect.
3083cbab8adeSQu Wenruo */
3084cbab8adeSQu Wenruo if (srcid)
3085cbab8adeSQu Wenruo need_rescan = true;
3086bed92eaeSArne Jansen }
3087bed92eaeSArne Jansen
3088918c2ee1SMark Fasheh for (i = 0; i < inherit->num_ref_copies; ++i, i_qgroups += 2) {
3089bed92eaeSArne Jansen struct btrfs_qgroup *src;
3090bed92eaeSArne Jansen struct btrfs_qgroup *dst;
3091bed92eaeSArne Jansen
3092918c2ee1SMark Fasheh if (!i_qgroups[0] || !i_qgroups[1])
3093918c2ee1SMark Fasheh continue;
3094918c2ee1SMark Fasheh
3095bed92eaeSArne Jansen src = find_qgroup_rb(fs_info, i_qgroups[0]);
3096bed92eaeSArne Jansen dst = find_qgroup_rb(fs_info, i_qgroups[1]);
3097bed92eaeSArne Jansen
3098bed92eaeSArne Jansen if (!src || !dst) {
3099bed92eaeSArne Jansen ret = -EINVAL;
3100bed92eaeSArne Jansen goto unlock;
3101bed92eaeSArne Jansen }
3102bed92eaeSArne Jansen
3103bed92eaeSArne Jansen dst->rfer = src->rfer - level_size;
3104bed92eaeSArne Jansen dst->rfer_cmpr = src->rfer_cmpr - level_size;
3105cbab8adeSQu Wenruo
3106cbab8adeSQu Wenruo /* Manually tweaking numbers certainly needs a rescan */
3107cbab8adeSQu Wenruo need_rescan = true;
3108bed92eaeSArne Jansen }
3109918c2ee1SMark Fasheh for (i = 0; i < inherit->num_excl_copies; ++i, i_qgroups += 2) {
3110bed92eaeSArne Jansen struct btrfs_qgroup *src;
3111bed92eaeSArne Jansen struct btrfs_qgroup *dst;
3112bed92eaeSArne Jansen
3113918c2ee1SMark Fasheh if (!i_qgroups[0] || !i_qgroups[1])
3114918c2ee1SMark Fasheh continue;
3115918c2ee1SMark Fasheh
3116bed92eaeSArne Jansen src = find_qgroup_rb(fs_info, i_qgroups[0]);
3117bed92eaeSArne Jansen dst = find_qgroup_rb(fs_info, i_qgroups[1]);
3118bed92eaeSArne Jansen
3119bed92eaeSArne Jansen if (!src || !dst) {
3120bed92eaeSArne Jansen ret = -EINVAL;
3121bed92eaeSArne Jansen goto unlock;
3122bed92eaeSArne Jansen }
3123bed92eaeSArne Jansen
3124bed92eaeSArne Jansen dst->excl = src->excl + level_size;
3125bed92eaeSArne Jansen dst->excl_cmpr = src->excl_cmpr + level_size;
3126cbab8adeSQu Wenruo need_rescan = true;
3127bed92eaeSArne Jansen }
3128bed92eaeSArne Jansen
3129bed92eaeSArne Jansen unlock:
3130bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
313149e5fb46SQu Wenruo if (!ret)
313249e5fb46SQu Wenruo ret = btrfs_sysfs_add_one_qgroup(fs_info, dstgroup);
3133bed92eaeSArne Jansen out:
3134e88439deSQu Wenruo if (!committing)
3135f2f6ed3dSWang Shilong mutex_unlock(&fs_info->qgroup_ioctl_lock);
3136cbab8adeSQu Wenruo if (need_rescan)
3137e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
3138bed92eaeSArne Jansen return ret;
3139bed92eaeSArne Jansen }
3140bed92eaeSArne Jansen
qgroup_check_limits(const struct btrfs_qgroup * qg,u64 num_bytes)3141adca4d94SQu Wenruo static bool qgroup_check_limits(const struct btrfs_qgroup *qg, u64 num_bytes)
3142003d7c59SJeff Mahoney {
3143003d7c59SJeff Mahoney if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
3144dba21324SQu Wenruo qgroup_rsv_total(qg) + (s64)qg->rfer + num_bytes > qg->max_rfer)
3145003d7c59SJeff Mahoney return false;
3146003d7c59SJeff Mahoney
3147003d7c59SJeff Mahoney if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
3148dba21324SQu Wenruo qgroup_rsv_total(qg) + (s64)qg->excl + num_bytes > qg->max_excl)
3149003d7c59SJeff Mahoney return false;
3150003d7c59SJeff Mahoney
3151003d7c59SJeff Mahoney return true;
3152003d7c59SJeff Mahoney }
3153003d7c59SJeff Mahoney
qgroup_reserve(struct btrfs_root * root,u64 num_bytes,bool enforce,enum btrfs_qgroup_rsv_type type)3154dba21324SQu Wenruo static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes, bool enforce,
3155dba21324SQu Wenruo enum btrfs_qgroup_rsv_type type)
3156bed92eaeSArne Jansen {
3157bed92eaeSArne Jansen struct btrfs_qgroup *qgroup;
3158bed92eaeSArne Jansen struct btrfs_fs_info *fs_info = root->fs_info;
3159bed92eaeSArne Jansen u64 ref_root = root->root_key.objectid;
3160bed92eaeSArne Jansen int ret = 0;
31611c9a5c49SQu Wenruo LIST_HEAD(qgroup_list);
3162bed92eaeSArne Jansen
3163bed92eaeSArne Jansen if (!is_fstree(ref_root))
3164bed92eaeSArne Jansen return 0;
3165bed92eaeSArne Jansen
3166bed92eaeSArne Jansen if (num_bytes == 0)
3167bed92eaeSArne Jansen return 0;
3168f29efe29SSargun Dhillon
3169f29efe29SSargun Dhillon if (test_bit(BTRFS_FS_QUOTA_OVERRIDE, &fs_info->flags) &&
3170f29efe29SSargun Dhillon capable(CAP_SYS_RESOURCE))
3171f29efe29SSargun Dhillon enforce = false;
3172f29efe29SSargun Dhillon
3173bed92eaeSArne Jansen spin_lock(&fs_info->qgroup_lock);
3174e3b0edd2SMarcos Paulo de Souza if (!fs_info->quota_root)
3175bed92eaeSArne Jansen goto out;
3176bed92eaeSArne Jansen
3177bed92eaeSArne Jansen qgroup = find_qgroup_rb(fs_info, ref_root);
3178bed92eaeSArne Jansen if (!qgroup)
3179bed92eaeSArne Jansen goto out;
3180bed92eaeSArne Jansen
31811c9a5c49SQu Wenruo qgroup_iterator_add(&qgroup_list, qgroup);
31821c9a5c49SQu Wenruo list_for_each_entry(qgroup, &qgroup_list, iterator) {
3183bed92eaeSArne Jansen struct btrfs_qgroup_list *glist;
3184bed92eaeSArne Jansen
31851c9a5c49SQu Wenruo if (enforce && !qgroup_check_limits(qgroup, num_bytes)) {
3186bed92eaeSArne Jansen ret = -EDQUOT;
3187720f1e20SWang Shilong goto out;
3188720f1e20SWang Shilong }
3189bed92eaeSArne Jansen
31901c9a5c49SQu Wenruo list_for_each_entry(glist, &qgroup->groups, next_group)
31911c9a5c49SQu Wenruo qgroup_iterator_add(&qgroup_list, glist->group);
3192bed92eaeSArne Jansen }
31931c9a5c49SQu Wenruo
31943c97185cSWang Shilong ret = 0;
3195bed92eaeSArne Jansen /*
3196bed92eaeSArne Jansen * no limits exceeded, now record the reservation into all qgroups
3197bed92eaeSArne Jansen */
31981c9a5c49SQu Wenruo list_for_each_entry(qgroup, &qgroup_list, iterator)
31991c9a5c49SQu Wenruo qgroup_rsv_add(fs_info, qgroup, num_bytes, type);
3200bed92eaeSArne Jansen
3201bed92eaeSArne Jansen out:
32021c9a5c49SQu Wenruo qgroup_iterator_clean(&qgroup_list);
3203bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
3204bed92eaeSArne Jansen return ret;
3205bed92eaeSArne Jansen }
3206bed92eaeSArne Jansen
3207e1211d0eSQu Wenruo /*
3208e1211d0eSQu Wenruo * Free @num_bytes of reserved space with @type for qgroup. (Normally level 0
3209e1211d0eSQu Wenruo * qgroup).
3210e1211d0eSQu Wenruo *
3211e1211d0eSQu Wenruo * Will handle all higher level qgroup too.
3212e1211d0eSQu Wenruo *
3213e1211d0eSQu Wenruo * NOTE: If @num_bytes is (u64)-1, this means to free all bytes of this qgroup.
3214e1211d0eSQu Wenruo * This special case is only used for META_PERTRANS type.
3215e1211d0eSQu Wenruo */
btrfs_qgroup_free_refroot(struct btrfs_fs_info * fs_info,u64 ref_root,u64 num_bytes,enum btrfs_qgroup_rsv_type type)3216297d750bSQu Wenruo void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info,
3217d4e5c920SQu Wenruo u64 ref_root, u64 num_bytes,
3218d4e5c920SQu Wenruo enum btrfs_qgroup_rsv_type type)
3219bed92eaeSArne Jansen {
3220bed92eaeSArne Jansen struct btrfs_qgroup *qgroup;
3221bed92eaeSArne Jansen struct ulist_node *unode;
3222bed92eaeSArne Jansen struct ulist_iterator uiter;
32233c97185cSWang Shilong int ret = 0;
3224bed92eaeSArne Jansen
3225bed92eaeSArne Jansen if (!is_fstree(ref_root))
3226bed92eaeSArne Jansen return;
3227bed92eaeSArne Jansen
3228bed92eaeSArne Jansen if (num_bytes == 0)
3229bed92eaeSArne Jansen return;
3230bed92eaeSArne Jansen
3231e1211d0eSQu Wenruo if (num_bytes == (u64)-1 && type != BTRFS_QGROUP_RSV_META_PERTRANS) {
3232e1211d0eSQu Wenruo WARN(1, "%s: Invalid type to free", __func__);
3233e1211d0eSQu Wenruo return;
3234e1211d0eSQu Wenruo }
3235bed92eaeSArne Jansen spin_lock(&fs_info->qgroup_lock);
3236bed92eaeSArne Jansen
3237e3b0edd2SMarcos Paulo de Souza if (!fs_info->quota_root)
3238bed92eaeSArne Jansen goto out;
3239bed92eaeSArne Jansen
3240bed92eaeSArne Jansen qgroup = find_qgroup_rb(fs_info, ref_root);
3241bed92eaeSArne Jansen if (!qgroup)
3242bed92eaeSArne Jansen goto out;
3243bed92eaeSArne Jansen
3244e1211d0eSQu Wenruo if (num_bytes == (u64)-1)
32458287475aSQu Wenruo /*
32468287475aSQu Wenruo * We're freeing all pertrans rsv, get reserved value from
32478287475aSQu Wenruo * level 0 qgroup as real num_bytes to free.
32488287475aSQu Wenruo */
3249e1211d0eSQu Wenruo num_bytes = qgroup->rsv.values[type];
3250e1211d0eSQu Wenruo
32511e8f9158SWang Shilong ulist_reinit(fs_info->qgroup_ulist);
32521e8f9158SWang Shilong ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
3253a1840b50SDavid Sterba qgroup_to_aux(qgroup), GFP_ATOMIC);
32543c97185cSWang Shilong if (ret < 0)
32553c97185cSWang Shilong goto out;
3256bed92eaeSArne Jansen ULIST_ITER_INIT(&uiter);
32571e8f9158SWang Shilong while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
3258bed92eaeSArne Jansen struct btrfs_qgroup *qg;
3259bed92eaeSArne Jansen struct btrfs_qgroup_list *glist;
3260bed92eaeSArne Jansen
3261ef2fff64SDavid Sterba qg = unode_aux_to_qgroup(unode);
3262bed92eaeSArne Jansen
326364ee4e75SQu Wenruo qgroup_rsv_release(fs_info, qg, num_bytes, type);
3264bed92eaeSArne Jansen
3265bed92eaeSArne Jansen list_for_each_entry(glist, &qg->groups, next_group) {
32661e8f9158SWang Shilong ret = ulist_add(fs_info->qgroup_ulist,
32671e8f9158SWang Shilong glist->group->qgroupid,
3268a1840b50SDavid Sterba qgroup_to_aux(glist->group), GFP_ATOMIC);
32693c97185cSWang Shilong if (ret < 0)
32703c97185cSWang Shilong goto out;
3271bed92eaeSArne Jansen }
3272bed92eaeSArne Jansen }
3273bed92eaeSArne Jansen
3274bed92eaeSArne Jansen out:
3275bed92eaeSArne Jansen spin_unlock(&fs_info->qgroup_lock);
3276bed92eaeSArne Jansen }
3277bed92eaeSArne Jansen
32782f232036SJan Schmidt /*
3279ff3d27a0SQu Wenruo * Check if the leaf is the last leaf. Which means all node pointers
3280ff3d27a0SQu Wenruo * are at their last position.
3281ff3d27a0SQu Wenruo */
is_last_leaf(struct btrfs_path * path)3282ff3d27a0SQu Wenruo static bool is_last_leaf(struct btrfs_path *path)
3283ff3d27a0SQu Wenruo {
3284ff3d27a0SQu Wenruo int i;
3285ff3d27a0SQu Wenruo
3286ff3d27a0SQu Wenruo for (i = 1; i < BTRFS_MAX_LEVEL && path->nodes[i]; i++) {
3287ff3d27a0SQu Wenruo if (path->slots[i] != btrfs_header_nritems(path->nodes[i]) - 1)
3288ff3d27a0SQu Wenruo return false;
3289ff3d27a0SQu Wenruo }
3290ff3d27a0SQu Wenruo return true;
3291ff3d27a0SQu Wenruo }
3292ff3d27a0SQu Wenruo
3293ff3d27a0SQu Wenruo /*
32942f232036SJan Schmidt * returns < 0 on error, 0 when more leafs are to be scanned.
32953393168dSQu Wenruo * returns 1 when done.
32962f232036SJan Schmidt */
qgroup_rescan_leaf(struct btrfs_trans_handle * trans,struct btrfs_path * path)329762088ca7SLu Fengqi static int qgroup_rescan_leaf(struct btrfs_trans_handle *trans,
329862088ca7SLu Fengqi struct btrfs_path *path)
32992f232036SJan Schmidt {
330062088ca7SLu Fengqi struct btrfs_fs_info *fs_info = trans->fs_info;
330129cbcf40SJosef Bacik struct btrfs_root *extent_root;
33022f232036SJan Schmidt struct btrfs_key found;
33030a0e8b89SQu Wenruo struct extent_buffer *scratch_leaf = NULL;
3304fcebe456SJosef Bacik u64 num_bytes;
3305ff3d27a0SQu Wenruo bool done;
33062f232036SJan Schmidt int slot;
33072f232036SJan Schmidt int ret;
33082f232036SJan Schmidt
33092f232036SJan Schmidt mutex_lock(&fs_info->qgroup_rescan_lock);
331029cbcf40SJosef Bacik extent_root = btrfs_extent_root(fs_info,
331129cbcf40SJosef Bacik fs_info->qgroup_rescan_progress.objectid);
331229cbcf40SJosef Bacik ret = btrfs_search_slot_for_read(extent_root,
33132f232036SJan Schmidt &fs_info->qgroup_rescan_progress,
33142f232036SJan Schmidt path, 1, 0);
33152f232036SJan Schmidt
3316ab8d0fc4SJeff Mahoney btrfs_debug(fs_info,
3317ab8d0fc4SJeff Mahoney "current progress key (%llu %u %llu), search_slot ret %d",
3318c1c9ff7cSGeert Uytterhoeven fs_info->qgroup_rescan_progress.objectid,
33192f232036SJan Schmidt fs_info->qgroup_rescan_progress.type,
3320c1c9ff7cSGeert Uytterhoeven fs_info->qgroup_rescan_progress.offset, ret);
33212f232036SJan Schmidt
33222f232036SJan Schmidt if (ret) {
33232f232036SJan Schmidt /*
33242f232036SJan Schmidt * The rescan is about to end, we will not be scanning any
33252f232036SJan Schmidt * further blocks. We cannot unset the RESCAN flag here, because
33262f232036SJan Schmidt * we want to commit the transaction if everything went well.
33272f232036SJan Schmidt * To make the live accounting work in this phase, we set our
33282f232036SJan Schmidt * scan progress pointer such that every real extent objectid
33292f232036SJan Schmidt * will be smaller.
33302f232036SJan Schmidt */
33312f232036SJan Schmidt fs_info->qgroup_rescan_progress.objectid = (u64)-1;
33322f232036SJan Schmidt btrfs_release_path(path);
33332f232036SJan Schmidt mutex_unlock(&fs_info->qgroup_rescan_lock);
33342f232036SJan Schmidt return ret;
33352f232036SJan Schmidt }
3336ff3d27a0SQu Wenruo done = is_last_leaf(path);
33372f232036SJan Schmidt
33382f232036SJan Schmidt btrfs_item_key_to_cpu(path->nodes[0], &found,
33392f232036SJan Schmidt btrfs_header_nritems(path->nodes[0]) - 1);
33402f232036SJan Schmidt fs_info->qgroup_rescan_progress.objectid = found.objectid + 1;
33412f232036SJan Schmidt
33420a0e8b89SQu Wenruo scratch_leaf = btrfs_clone_extent_buffer(path->nodes[0]);
33430a0e8b89SQu Wenruo if (!scratch_leaf) {
33440a0e8b89SQu Wenruo ret = -ENOMEM;
33450a0e8b89SQu Wenruo mutex_unlock(&fs_info->qgroup_rescan_lock);
33460a0e8b89SQu Wenruo goto out;
33470a0e8b89SQu Wenruo }
33482f232036SJan Schmidt slot = path->slots[0];
33492f232036SJan Schmidt btrfs_release_path(path);
33502f232036SJan Schmidt mutex_unlock(&fs_info->qgroup_rescan_lock);
33512f232036SJan Schmidt
33522f232036SJan Schmidt for (; slot < btrfs_header_nritems(scratch_leaf); ++slot) {
3353a2c8d27eSFilipe Manana struct btrfs_backref_walk_ctx ctx = { 0 };
3354a2c8d27eSFilipe Manana
33552f232036SJan Schmidt btrfs_item_key_to_cpu(scratch_leaf, &found, slot);
33563a6d75e8SJosef Bacik if (found.type != BTRFS_EXTENT_ITEM_KEY &&
33573a6d75e8SJosef Bacik found.type != BTRFS_METADATA_ITEM_KEY)
33582f232036SJan Schmidt continue;
33593a6d75e8SJosef Bacik if (found.type == BTRFS_METADATA_ITEM_KEY)
3360da17066cSJeff Mahoney num_bytes = fs_info->nodesize;
33613a6d75e8SJosef Bacik else
33623a6d75e8SJosef Bacik num_bytes = found.offset;
33633a6d75e8SJosef Bacik
3364a2c8d27eSFilipe Manana ctx.bytenr = found.objectid;
3365a2c8d27eSFilipe Manana ctx.fs_info = fs_info;
3366a2c8d27eSFilipe Manana
3367a2c8d27eSFilipe Manana ret = btrfs_find_all_roots(&ctx, false);
33682f232036SJan Schmidt if (ret < 0)
33692f232036SJan Schmidt goto out;
33709d220c95SQu Wenruo /* For rescan, just pass old_roots as NULL */
33718696d760SLu Fengqi ret = btrfs_qgroup_account_extent(trans, found.objectid,
3372a2c8d27eSFilipe Manana num_bytes, NULL, ctx.roots);
33739d220c95SQu Wenruo if (ret < 0)
33742f232036SJan Schmidt goto out;
33752f232036SJan Schmidt }
33762f232036SJan Schmidt out:
3377df449714SNikolay Borisov if (scratch_leaf)
33780a0e8b89SQu Wenruo free_extent_buffer(scratch_leaf);
33792f232036SJan Schmidt
33806f7de19eSQu Wenruo if (done && !ret) {
3381ff3d27a0SQu Wenruo ret = 1;
33826f7de19eSQu Wenruo fs_info->qgroup_rescan_progress.objectid = (u64)-1;
33836f7de19eSQu Wenruo }
33842f232036SJan Schmidt return ret;
33852f232036SJan Schmidt }
33862f232036SJan Schmidt
rescan_should_stop(struct btrfs_fs_info * fs_info)3387cb13eea3SFilipe Manana static bool rescan_should_stop(struct btrfs_fs_info *fs_info)
3388cb13eea3SFilipe Manana {
3389cb13eea3SFilipe Manana return btrfs_fs_closing(fs_info) ||
3390db5df254SNikolay Borisov test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state) ||
3391e562a8bdSQu Wenruo !test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
3392e562a8bdSQu Wenruo fs_info->qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN;
3393cb13eea3SFilipe Manana }
3394cb13eea3SFilipe Manana
btrfs_qgroup_rescan_worker(struct btrfs_work * work)3395d458b054SQu Wenruo static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
33962f232036SJan Schmidt {
3397b382a324SJan Schmidt struct btrfs_fs_info *fs_info = container_of(work, struct btrfs_fs_info,
3398b382a324SJan Schmidt qgroup_rescan_work);
33992f232036SJan Schmidt struct btrfs_path *path;
34002f232036SJan Schmidt struct btrfs_trans_handle *trans = NULL;
34012f232036SJan Schmidt int err = -ENOMEM;
340253b7cde9SQu Wenruo int ret = 0;
3403cb13eea3SFilipe Manana bool stopped = false;
3404b7adbf9aSFilipe Manana bool did_leaf_rescans = false;
34052f232036SJan Schmidt
34062f232036SJan Schmidt path = btrfs_alloc_path();
34072f232036SJan Schmidt if (!path)
34082f232036SJan Schmidt goto out;
3409b6debf15SQu Wenruo /*
3410b6debf15SQu Wenruo * Rescan should only search for commit root, and any later difference
3411b6debf15SQu Wenruo * should be recorded by qgroup
3412b6debf15SQu Wenruo */
3413b6debf15SQu Wenruo path->search_commit_root = 1;
3414b6debf15SQu Wenruo path->skip_locking = 1;
34152f232036SJan Schmidt
34162f232036SJan Schmidt err = 0;
3417cb13eea3SFilipe Manana while (!err && !(stopped = rescan_should_stop(fs_info))) {
34182f232036SJan Schmidt trans = btrfs_start_transaction(fs_info->fs_root, 0);
34192f232036SJan Schmidt if (IS_ERR(trans)) {
34202f232036SJan Schmidt err = PTR_ERR(trans);
34212f232036SJan Schmidt break;
34222f232036SJan Schmidt }
3423db5df254SNikolay Borisov
342462088ca7SLu Fengqi err = qgroup_rescan_leaf(trans, path);
3425b7adbf9aSFilipe Manana did_leaf_rescans = true;
3426db5df254SNikolay Borisov
34272f232036SJan Schmidt if (err > 0)
34283a45bb20SJeff Mahoney btrfs_commit_transaction(trans);
34292f232036SJan Schmidt else
34303a45bb20SJeff Mahoney btrfs_end_transaction(trans);
34312f232036SJan Schmidt }
34322f232036SJan Schmidt
34332f232036SJan Schmidt out:
34342f232036SJan Schmidt btrfs_free_path(path);
34352f232036SJan Schmidt
34362f232036SJan Schmidt mutex_lock(&fs_info->qgroup_rescan_lock);
34373393168dSQu Wenruo if (err > 0 &&
34382f232036SJan Schmidt fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) {
34392f232036SJan Schmidt fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
3440db5df254SNikolay Borisov } else if (err < 0 || stopped) {
34412f232036SJan Schmidt fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
34422f232036SJan Schmidt }
34432f232036SJan Schmidt mutex_unlock(&fs_info->qgroup_rescan_lock);
34442f232036SJan Schmidt
344553b7cde9SQu Wenruo /*
3446b7adbf9aSFilipe Manana * Only update status, since the previous part has already updated the
3447b7adbf9aSFilipe Manana * qgroup info, and only if we did any actual work. This also prevents
3448b7adbf9aSFilipe Manana * race with a concurrent quota disable, which has already set
3449b7adbf9aSFilipe Manana * fs_info->quota_root to NULL and cleared BTRFS_FS_QUOTA_ENABLED at
3450b7adbf9aSFilipe Manana * btrfs_quota_disable().
345153b7cde9SQu Wenruo */
3452b7adbf9aSFilipe Manana if (did_leaf_rescans) {
345353b7cde9SQu Wenruo trans = btrfs_start_transaction(fs_info->quota_root, 1);
345453b7cde9SQu Wenruo if (IS_ERR(trans)) {
345553b7cde9SQu Wenruo err = PTR_ERR(trans);
345613fc1d27SFilipe Manana trans = NULL;
345753b7cde9SQu Wenruo btrfs_err(fs_info,
3458913e1535SDavid Sterba "fail to start transaction for status update: %d",
345953b7cde9SQu Wenruo err);
346053b7cde9SQu Wenruo }
3461b7adbf9aSFilipe Manana } else {
3462b7adbf9aSFilipe Manana trans = NULL;
3463b7adbf9aSFilipe Manana }
346413fc1d27SFilipe Manana
346513fc1d27SFilipe Manana mutex_lock(&fs_info->qgroup_rescan_lock);
3466e562a8bdSQu Wenruo if (!stopped ||
3467e562a8bdSQu Wenruo fs_info->qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN)
346813fc1d27SFilipe Manana fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
346913fc1d27SFilipe Manana if (trans) {
34702e980acdSLu Fengqi ret = update_qgroup_status_item(trans);
347153b7cde9SQu Wenruo if (ret < 0) {
347253b7cde9SQu Wenruo err = ret;
347313fc1d27SFilipe Manana btrfs_err(fs_info, "fail to update qgroup status: %d",
347413fc1d27SFilipe Manana err);
347553b7cde9SQu Wenruo }
347613fc1d27SFilipe Manana }
347713fc1d27SFilipe Manana fs_info->qgroup_rescan_running = false;
3478e562a8bdSQu Wenruo fs_info->qgroup_flags &= ~BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN;
347913fc1d27SFilipe Manana complete_all(&fs_info->qgroup_rescan_completion);
348013fc1d27SFilipe Manana mutex_unlock(&fs_info->qgroup_rescan_lock);
348113fc1d27SFilipe Manana
348213fc1d27SFilipe Manana if (!trans)
348313fc1d27SFilipe Manana return;
348413fc1d27SFilipe Manana
34853a45bb20SJeff Mahoney btrfs_end_transaction(trans);
348653b7cde9SQu Wenruo
3487cb13eea3SFilipe Manana if (stopped) {
34887343dd61SJustin Maggard btrfs_info(fs_info, "qgroup scan paused");
3489e562a8bdSQu Wenruo } else if (fs_info->qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN) {
3490e562a8bdSQu Wenruo btrfs_info(fs_info, "qgroup scan cancelled");
34917343dd61SJustin Maggard } else if (err >= 0) {
3492efe120a0SFrank Holton btrfs_info(fs_info, "qgroup scan completed%s",
34933393168dSQu Wenruo err > 0 ? " (inconsistency flag cleared)" : "");
34942f232036SJan Schmidt } else {
3495efe120a0SFrank Holton btrfs_err(fs_info, "qgroup scan failed with %d", err);
34962f232036SJan Schmidt }
34972f232036SJan Schmidt }
34982f232036SJan Schmidt
3499b382a324SJan Schmidt /*
3500b382a324SJan Schmidt * Checks that (a) no rescan is running and (b) quota is enabled. Allocates all
3501b382a324SJan Schmidt * memory required for the rescan context.
3502b382a324SJan Schmidt */
3503b382a324SJan Schmidt static int
qgroup_rescan_init(struct btrfs_fs_info * fs_info,u64 progress_objectid,int init_flags)3504b382a324SJan Schmidt qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
3505b382a324SJan Schmidt int init_flags)
35062f232036SJan Schmidt {
35072f232036SJan Schmidt int ret = 0;
35082f232036SJan Schmidt
35099593bf49SQu Wenruo if (!init_flags) {
35109593bf49SQu Wenruo /* we're resuming qgroup rescan at mount time */
3511e4e7ede7SFilipe Manana if (!(fs_info->qgroup_flags &
3512e4e7ede7SFilipe Manana BTRFS_QGROUP_STATUS_FLAG_RESCAN)) {
35139593bf49SQu Wenruo btrfs_warn(fs_info,
351437d02592SNikolay Borisov "qgroup rescan init failed, qgroup rescan is not queued");
3515e4e7ede7SFilipe Manana ret = -EINVAL;
3516e4e7ede7SFilipe Manana } else if (!(fs_info->qgroup_flags &
3517e4e7ede7SFilipe Manana BTRFS_QGROUP_STATUS_FLAG_ON)) {
35189593bf49SQu Wenruo btrfs_warn(fs_info,
351937d02592SNikolay Borisov "qgroup rescan init failed, qgroup is not enabled");
3520e4e7ede7SFilipe Manana ret = -EINVAL;
3521e4e7ede7SFilipe Manana }
3522e4e7ede7SFilipe Manana
3523e4e7ede7SFilipe Manana if (ret)
3524e4e7ede7SFilipe Manana return ret;
3525b382a324SJan Schmidt }
35262f232036SJan Schmidt
35272f232036SJan Schmidt mutex_lock(&fs_info->qgroup_rescan_lock);
3528b382a324SJan Schmidt
3529b382a324SJan Schmidt if (init_flags) {
35309593bf49SQu Wenruo if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
35319593bf49SQu Wenruo btrfs_warn(fs_info,
35329593bf49SQu Wenruo "qgroup rescan is already in progress");
35332f232036SJan Schmidt ret = -EINPROGRESS;
35349593bf49SQu Wenruo } else if (!(fs_info->qgroup_flags &
35359593bf49SQu Wenruo BTRFS_QGROUP_STATUS_FLAG_ON)) {
35369593bf49SQu Wenruo btrfs_warn(fs_info,
35379593bf49SQu Wenruo "qgroup rescan init failed, qgroup is not enabled");
35382f232036SJan Schmidt ret = -EINVAL;
3539e804861bSShin'ichiro Kawasaki } else if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) {
3540e804861bSShin'ichiro Kawasaki /* Quota disable is in progress */
3541e804861bSShin'ichiro Kawasaki ret = -EBUSY;
35429593bf49SQu Wenruo }
3543b382a324SJan Schmidt
35442f232036SJan Schmidt if (ret) {
35452f232036SJan Schmidt mutex_unlock(&fs_info->qgroup_rescan_lock);
35469593bf49SQu Wenruo return ret;
35472f232036SJan Schmidt }
35482f232036SJan Schmidt fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_RESCAN;
3549b382a324SJan Schmidt }
3550b382a324SJan Schmidt
35512f232036SJan Schmidt memset(&fs_info->qgroup_rescan_progress, 0,
35522f232036SJan Schmidt sizeof(fs_info->qgroup_rescan_progress));
3553e15e9f43SQu Wenruo fs_info->qgroup_flags &= ~(BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN |
3554e15e9f43SQu Wenruo BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING);
3555b382a324SJan Schmidt fs_info->qgroup_rescan_progress.objectid = progress_objectid;
3556190631f1SFilipe Manana init_completion(&fs_info->qgroup_rescan_completion);
3557b382a324SJan Schmidt mutex_unlock(&fs_info->qgroup_rescan_lock);
3558b382a324SJan Schmidt
3559fc97fab0SQu Wenruo btrfs_init_work(&fs_info->qgroup_rescan_work,
3560fc97fab0SQu Wenruo btrfs_qgroup_rescan_worker, NULL, NULL);
3561b382a324SJan Schmidt return 0;
3562b382a324SJan Schmidt }
3563b382a324SJan Schmidt
3564b382a324SJan Schmidt static void
qgroup_rescan_zero_tracking(struct btrfs_fs_info * fs_info)3565b382a324SJan Schmidt qgroup_rescan_zero_tracking(struct btrfs_fs_info *fs_info)
3566b382a324SJan Schmidt {
3567b382a324SJan Schmidt struct rb_node *n;
3568b382a324SJan Schmidt struct btrfs_qgroup *qgroup;
3569b382a324SJan Schmidt
3570b382a324SJan Schmidt spin_lock(&fs_info->qgroup_lock);
35712f232036SJan Schmidt /* clear all current qgroup tracking information */
35722f232036SJan Schmidt for (n = rb_first(&fs_info->qgroup_tree); n; n = rb_next(n)) {
35732f232036SJan Schmidt qgroup = rb_entry(n, struct btrfs_qgroup, node);
35742f232036SJan Schmidt qgroup->rfer = 0;
35752f232036SJan Schmidt qgroup->rfer_cmpr = 0;
35762f232036SJan Schmidt qgroup->excl = 0;
35772f232036SJan Schmidt qgroup->excl_cmpr = 0;
35789c7b0c2eSQu Wenruo qgroup_dirty(fs_info, qgroup);
35792f232036SJan Schmidt }
35802f232036SJan Schmidt spin_unlock(&fs_info->qgroup_lock);
3581b382a324SJan Schmidt }
35822f232036SJan Schmidt
3583b382a324SJan Schmidt int
btrfs_qgroup_rescan(struct btrfs_fs_info * fs_info)3584b382a324SJan Schmidt btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
3585b382a324SJan Schmidt {
3586b382a324SJan Schmidt int ret = 0;
3587b382a324SJan Schmidt struct btrfs_trans_handle *trans;
3588b382a324SJan Schmidt
3589b382a324SJan Schmidt ret = qgroup_rescan_init(fs_info, 0, 1);
3590b382a324SJan Schmidt if (ret)
3591b382a324SJan Schmidt return ret;
3592b382a324SJan Schmidt
3593b382a324SJan Schmidt /*
3594b382a324SJan Schmidt * We have set the rescan_progress to 0, which means no more
3595b382a324SJan Schmidt * delayed refs will be accounted by btrfs_qgroup_account_ref.
3596b382a324SJan Schmidt * However, btrfs_qgroup_account_ref may be right after its call
3597b382a324SJan Schmidt * to btrfs_find_all_roots, in which case it would still do the
3598b382a324SJan Schmidt * accounting.
3599b382a324SJan Schmidt * To solve this, we're committing the transaction, which will
3600b382a324SJan Schmidt * ensure we run all delayed refs and only after that, we are
3601b382a324SJan Schmidt * going to clear all tracking information for a clean start.
3602b382a324SJan Schmidt */
3603b382a324SJan Schmidt
36046705b48aSFilipe Manana trans = btrfs_attach_transaction_barrier(fs_info->fs_root);
36056705b48aSFilipe Manana if (IS_ERR(trans) && trans != ERR_PTR(-ENOENT)) {
3606b382a324SJan Schmidt fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
3607b382a324SJan Schmidt return PTR_ERR(trans);
36086705b48aSFilipe Manana } else if (trans != ERR_PTR(-ENOENT)) {
36093a45bb20SJeff Mahoney ret = btrfs_commit_transaction(trans);
3610b382a324SJan Schmidt if (ret) {
3611b382a324SJan Schmidt fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
3612b382a324SJan Schmidt return ret;
3613b382a324SJan Schmidt }
36146705b48aSFilipe Manana }
3615b382a324SJan Schmidt
3616b382a324SJan Schmidt qgroup_rescan_zero_tracking(fs_info);
3617b382a324SJan Schmidt
3618d61acbbfSQu Wenruo mutex_lock(&fs_info->qgroup_rescan_lock);
3619d61acbbfSQu Wenruo fs_info->qgroup_rescan_running = true;
3620fc97fab0SQu Wenruo btrfs_queue_work(fs_info->qgroup_rescan_workers,
3621b382a324SJan Schmidt &fs_info->qgroup_rescan_work);
3622d61acbbfSQu Wenruo mutex_unlock(&fs_info->qgroup_rescan_lock);
36232f232036SJan Schmidt
36242f232036SJan Schmidt return 0;
36252f232036SJan Schmidt }
362657254b6eSJan Schmidt
btrfs_qgroup_wait_for_completion(struct btrfs_fs_info * fs_info,bool interruptible)3627d06f23d6SJeff Mahoney int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info,
3628d06f23d6SJeff Mahoney bool interruptible)
362957254b6eSJan Schmidt {
363057254b6eSJan Schmidt int running;
363157254b6eSJan Schmidt int ret = 0;
363257254b6eSJan Schmidt
363357254b6eSJan Schmidt mutex_lock(&fs_info->qgroup_rescan_lock);
3634d2c609b8SJeff Mahoney running = fs_info->qgroup_rescan_running;
363557254b6eSJan Schmidt mutex_unlock(&fs_info->qgroup_rescan_lock);
363657254b6eSJan Schmidt
3637d06f23d6SJeff Mahoney if (!running)
3638d06f23d6SJeff Mahoney return 0;
3639d06f23d6SJeff Mahoney
3640d06f23d6SJeff Mahoney if (interruptible)
364157254b6eSJan Schmidt ret = wait_for_completion_interruptible(
364257254b6eSJan Schmidt &fs_info->qgroup_rescan_completion);
3643d06f23d6SJeff Mahoney else
3644d06f23d6SJeff Mahoney wait_for_completion(&fs_info->qgroup_rescan_completion);
364557254b6eSJan Schmidt
364657254b6eSJan Schmidt return ret;
364757254b6eSJan Schmidt }
3648b382a324SJan Schmidt
3649b382a324SJan Schmidt /*
3650b382a324SJan Schmidt * this is only called from open_ctree where we're still single threaded, thus
3651b382a324SJan Schmidt * locking is omitted here.
3652b382a324SJan Schmidt */
3653b382a324SJan Schmidt void
btrfs_qgroup_rescan_resume(struct btrfs_fs_info * fs_info)3654b382a324SJan Schmidt btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info)
3655b382a324SJan Schmidt {
3656d61acbbfSQu Wenruo if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
3657d61acbbfSQu Wenruo mutex_lock(&fs_info->qgroup_rescan_lock);
3658d61acbbfSQu Wenruo fs_info->qgroup_rescan_running = true;
3659fc97fab0SQu Wenruo btrfs_queue_work(fs_info->qgroup_rescan_workers,
3660b382a324SJan Schmidt &fs_info->qgroup_rescan_work);
3661d61acbbfSQu Wenruo mutex_unlock(&fs_info->qgroup_rescan_lock);
3662d61acbbfSQu Wenruo }
3663b382a324SJan Schmidt }
366452472553SQu Wenruo
3665263da812SQu Wenruo #define rbtree_iterate_from_safe(node, next, start) \
3666263da812SQu Wenruo for (node = start; node && ({ next = rb_next(node); 1;}); node = next)
3667263da812SQu Wenruo
qgroup_unreserve_range(struct btrfs_inode * inode,struct extent_changeset * reserved,u64 start,u64 len)3668263da812SQu Wenruo static int qgroup_unreserve_range(struct btrfs_inode *inode,
3669263da812SQu Wenruo struct extent_changeset *reserved, u64 start,
3670263da812SQu Wenruo u64 len)
3671263da812SQu Wenruo {
3672263da812SQu Wenruo struct rb_node *node;
3673263da812SQu Wenruo struct rb_node *next;
3674f07728d5SDan Carpenter struct ulist_node *entry;
3675263da812SQu Wenruo int ret = 0;
3676263da812SQu Wenruo
3677263da812SQu Wenruo node = reserved->range_changed.root.rb_node;
3678f07728d5SDan Carpenter if (!node)
3679f07728d5SDan Carpenter return 0;
3680263da812SQu Wenruo while (node) {
3681263da812SQu Wenruo entry = rb_entry(node, struct ulist_node, rb_node);
3682263da812SQu Wenruo if (entry->val < start)
3683263da812SQu Wenruo node = node->rb_right;
3684263da812SQu Wenruo else
3685f07728d5SDan Carpenter node = node->rb_left;
3686263da812SQu Wenruo }
3687263da812SQu Wenruo
3688263da812SQu Wenruo if (entry->val > start && rb_prev(&entry->rb_node))
3689263da812SQu Wenruo entry = rb_entry(rb_prev(&entry->rb_node), struct ulist_node,
3690263da812SQu Wenruo rb_node);
3691263da812SQu Wenruo
3692263da812SQu Wenruo rbtree_iterate_from_safe(node, next, &entry->rb_node) {
3693263da812SQu Wenruo u64 entry_start;
3694263da812SQu Wenruo u64 entry_end;
3695263da812SQu Wenruo u64 entry_len;
3696263da812SQu Wenruo int clear_ret;
3697263da812SQu Wenruo
3698263da812SQu Wenruo entry = rb_entry(node, struct ulist_node, rb_node);
3699263da812SQu Wenruo entry_start = entry->val;
3700263da812SQu Wenruo entry_end = entry->aux;
3701263da812SQu Wenruo entry_len = entry_end - entry_start + 1;
3702263da812SQu Wenruo
3703263da812SQu Wenruo if (entry_start >= start + len)
3704263da812SQu Wenruo break;
3705263da812SQu Wenruo if (entry_start + entry_len <= start)
3706263da812SQu Wenruo continue;
3707263da812SQu Wenruo /*
3708263da812SQu Wenruo * Now the entry is in [start, start + len), revert the
3709263da812SQu Wenruo * EXTENT_QGROUP_RESERVED bit.
3710263da812SQu Wenruo */
3711263da812SQu Wenruo clear_ret = clear_extent_bits(&inode->io_tree, entry_start,
3712263da812SQu Wenruo entry_end, EXTENT_QGROUP_RESERVED);
3713263da812SQu Wenruo if (!ret && clear_ret < 0)
3714263da812SQu Wenruo ret = clear_ret;
3715263da812SQu Wenruo
3716263da812SQu Wenruo ulist_del(&reserved->range_changed, entry->val, entry->aux);
3717263da812SQu Wenruo if (likely(reserved->bytes_changed >= entry_len)) {
3718263da812SQu Wenruo reserved->bytes_changed -= entry_len;
3719263da812SQu Wenruo } else {
3720263da812SQu Wenruo WARN_ON(1);
3721263da812SQu Wenruo reserved->bytes_changed = 0;
3722263da812SQu Wenruo }
3723263da812SQu Wenruo }
3724263da812SQu Wenruo
3725263da812SQu Wenruo return ret;
3726263da812SQu Wenruo }
3727263da812SQu Wenruo
372852472553SQu Wenruo /*
3729c53e9653SQu Wenruo * Try to free some space for qgroup.
373052472553SQu Wenruo *
3731c53e9653SQu Wenruo * For qgroup, there are only 3 ways to free qgroup space:
3732c53e9653SQu Wenruo * - Flush nodatacow write
3733c53e9653SQu Wenruo * Any nodatacow write will free its reserved data space at run_delalloc_range().
3734c53e9653SQu Wenruo * In theory, we should only flush nodatacow inodes, but it's not yet
3735c53e9653SQu Wenruo * possible, so we need to flush the whole root.
373652472553SQu Wenruo *
3737c53e9653SQu Wenruo * - Wait for ordered extents
3738c53e9653SQu Wenruo * When ordered extents are finished, their reserved metadata is finally
3739c53e9653SQu Wenruo * converted to per_trans status, which can be freed by later commit
3740c53e9653SQu Wenruo * transaction.
374152472553SQu Wenruo *
3742c53e9653SQu Wenruo * - Commit transaction
3743c53e9653SQu Wenruo * This would free the meta_per_trans space.
3744c53e9653SQu Wenruo * In theory this shouldn't provide much space, but any more qgroup space
3745c53e9653SQu Wenruo * is needed.
374652472553SQu Wenruo */
try_flush_qgroup(struct btrfs_root * root)3747c53e9653SQu Wenruo static int try_flush_qgroup(struct btrfs_root *root)
3748c53e9653SQu Wenruo {
3749c53e9653SQu Wenruo struct btrfs_trans_handle *trans;
3750c53e9653SQu Wenruo int ret;
3751c53e9653SQu Wenruo
375235b22c19SFilipe Manana /* Can't hold an open transaction or we run the risk of deadlocking. */
3753ffb7c2e9SFilipe Manana ASSERT(current->journal_info == NULL);
3754ffb7c2e9SFilipe Manana if (WARN_ON(current->journal_info))
3755ae396a3bSNikolay Borisov return 0;
37566f23277aSQu Wenruo
3757ae5e070eSQu Wenruo /*
3758ae5e070eSQu Wenruo * We don't want to run flush again and again, so if there is a running
3759ae5e070eSQu Wenruo * one, we won't try to start a new flush, but exit directly.
3760ae5e070eSQu Wenruo */
3761ae5e070eSQu Wenruo if (test_and_set_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state)) {
3762ae5e070eSQu Wenruo wait_event(root->qgroup_flush_wait,
3763ae5e070eSQu Wenruo !test_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state));
3764ae5e070eSQu Wenruo return 0;
3765ae5e070eSQu Wenruo }
3766ae5e070eSQu Wenruo
376744013260SJosef Bacik btrfs_run_delayed_iputs(root->fs_info);
376844013260SJosef Bacik btrfs_wait_on_delayed_iputs(root->fs_info);
3769f9baa501SFilipe Manana ret = btrfs_start_delalloc_snapshot(root, true);
3770c53e9653SQu Wenruo if (ret < 0)
3771c53e9653SQu Wenruo goto out;
3772c53e9653SQu Wenruo btrfs_wait_ordered_extents(root, U64_MAX, 0, (u64)-1);
3773c53e9653SQu Wenruo
37749c93c238SFilipe Manana trans = btrfs_attach_transaction_barrier(root);
3775c53e9653SQu Wenruo if (IS_ERR(trans)) {
3776c53e9653SQu Wenruo ret = PTR_ERR(trans);
37779c93c238SFilipe Manana if (ret == -ENOENT)
37789c93c238SFilipe Manana ret = 0;
3779c53e9653SQu Wenruo goto out;
3780c53e9653SQu Wenruo }
3781c53e9653SQu Wenruo
3782c53e9653SQu Wenruo ret = btrfs_commit_transaction(trans);
3783c53e9653SQu Wenruo out:
3784c53e9653SQu Wenruo clear_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state);
3785c53e9653SQu Wenruo wake_up(&root->qgroup_flush_wait);
3786c53e9653SQu Wenruo return ret;
3787c53e9653SQu Wenruo }
3788c53e9653SQu Wenruo
qgroup_reserve_data(struct btrfs_inode * inode,struct extent_changeset ** reserved_ret,u64 start,u64 len)3789c53e9653SQu Wenruo static int qgroup_reserve_data(struct btrfs_inode *inode,
3790364ecf36SQu Wenruo struct extent_changeset **reserved_ret, u64 start,
3791364ecf36SQu Wenruo u64 len)
379252472553SQu Wenruo {
37937661a3e0SNikolay Borisov struct btrfs_root *root = inode->root;
3794364ecf36SQu Wenruo struct extent_changeset *reserved;
3795263da812SQu Wenruo bool new_reserved = false;
3796364ecf36SQu Wenruo u64 orig_reserved;
3797364ecf36SQu Wenruo u64 to_reserve;
379852472553SQu Wenruo int ret;
379952472553SQu Wenruo
3800afcdd129SJosef Bacik if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags) ||
38014fd786e6SMisono Tomohiro !is_fstree(root->root_key.objectid) || len == 0)
380252472553SQu Wenruo return 0;
380352472553SQu Wenruo
3804364ecf36SQu Wenruo /* @reserved parameter is mandatory for qgroup */
3805364ecf36SQu Wenruo if (WARN_ON(!reserved_ret))
3806364ecf36SQu Wenruo return -EINVAL;
3807364ecf36SQu Wenruo if (!*reserved_ret) {
3808263da812SQu Wenruo new_reserved = true;
3809364ecf36SQu Wenruo *reserved_ret = extent_changeset_alloc();
3810364ecf36SQu Wenruo if (!*reserved_ret)
3811364ecf36SQu Wenruo return -ENOMEM;
3812364ecf36SQu Wenruo }
3813364ecf36SQu Wenruo reserved = *reserved_ret;
3814364ecf36SQu Wenruo /* Record already reserved space */
3815364ecf36SQu Wenruo orig_reserved = reserved->bytes_changed;
38167661a3e0SNikolay Borisov ret = set_record_extent_bits(&inode->io_tree, start,
3817364ecf36SQu Wenruo start + len -1, EXTENT_QGROUP_RESERVED, reserved);
3818364ecf36SQu Wenruo
3819364ecf36SQu Wenruo /* Newly reserved space */
3820364ecf36SQu Wenruo to_reserve = reserved->bytes_changed - orig_reserved;
38217661a3e0SNikolay Borisov trace_btrfs_qgroup_reserve_data(&inode->vfs_inode, start, len,
3822364ecf36SQu Wenruo to_reserve, QGROUP_RESERVE);
382352472553SQu Wenruo if (ret < 0)
3824263da812SQu Wenruo goto out;
3825dba21324SQu Wenruo ret = qgroup_reserve(root, to_reserve, true, BTRFS_QGROUP_RSV_DATA);
382652472553SQu Wenruo if (ret < 0)
382752472553SQu Wenruo goto cleanup;
382852472553SQu Wenruo
382952472553SQu Wenruo return ret;
383052472553SQu Wenruo
383152472553SQu Wenruo cleanup:
3832263da812SQu Wenruo qgroup_unreserve_range(inode, reserved, start, len);
3833263da812SQu Wenruo out:
3834263da812SQu Wenruo if (new_reserved) {
3835d6ade689SNikolay Borisov extent_changeset_free(reserved);
3836263da812SQu Wenruo *reserved_ret = NULL;
3837263da812SQu Wenruo }
383852472553SQu Wenruo return ret;
383952472553SQu Wenruo }
3840f695fdceSQu Wenruo
3841c53e9653SQu Wenruo /*
3842c53e9653SQu Wenruo * Reserve qgroup space for range [start, start + len).
3843c53e9653SQu Wenruo *
3844c53e9653SQu Wenruo * This function will either reserve space from related qgroups or do nothing
3845c53e9653SQu Wenruo * if the range is already reserved.
3846c53e9653SQu Wenruo *
3847c53e9653SQu Wenruo * Return 0 for successful reservation
3848c53e9653SQu Wenruo * Return <0 for error (including -EQUOT)
3849c53e9653SQu Wenruo *
3850c53e9653SQu Wenruo * NOTE: This function may sleep for memory allocation, dirty page flushing and
3851c53e9653SQu Wenruo * commit transaction. So caller should not hold any dirty page locked.
3852c53e9653SQu Wenruo */
btrfs_qgroup_reserve_data(struct btrfs_inode * inode,struct extent_changeset ** reserved_ret,u64 start,u64 len)3853c53e9653SQu Wenruo int btrfs_qgroup_reserve_data(struct btrfs_inode *inode,
3854c53e9653SQu Wenruo struct extent_changeset **reserved_ret, u64 start,
3855c53e9653SQu Wenruo u64 len)
3856c53e9653SQu Wenruo {
3857c53e9653SQu Wenruo int ret;
3858c53e9653SQu Wenruo
3859c53e9653SQu Wenruo ret = qgroup_reserve_data(inode, reserved_ret, start, len);
3860c53e9653SQu Wenruo if (ret <= 0 && ret != -EDQUOT)
3861c53e9653SQu Wenruo return ret;
3862c53e9653SQu Wenruo
3863c53e9653SQu Wenruo ret = try_flush_qgroup(inode->root);
3864c53e9653SQu Wenruo if (ret < 0)
3865c53e9653SQu Wenruo return ret;
3866c53e9653SQu Wenruo return qgroup_reserve_data(inode, reserved_ret, start, len);
3867c53e9653SQu Wenruo }
3868c53e9653SQu Wenruo
3869bc42bda2SQu Wenruo /* Free ranges specified by @reserved, normally in error path */
qgroup_free_reserved_data(struct btrfs_inode * inode,struct extent_changeset * reserved,u64 start,u64 len,u64 * freed_ret)3870df2cfd13SNikolay Borisov static int qgroup_free_reserved_data(struct btrfs_inode *inode,
387118234915SBoris Burkov struct extent_changeset *reserved,
387218234915SBoris Burkov u64 start, u64 len, u64 *freed_ret)
3873bc42bda2SQu Wenruo {
3874df2cfd13SNikolay Borisov struct btrfs_root *root = inode->root;
3875bc42bda2SQu Wenruo struct ulist_node *unode;
3876bc42bda2SQu Wenruo struct ulist_iterator uiter;
3877bc42bda2SQu Wenruo struct extent_changeset changeset;
387818234915SBoris Burkov u64 freed = 0;
3879bc42bda2SQu Wenruo int ret;
3880bc42bda2SQu Wenruo
3881bc42bda2SQu Wenruo extent_changeset_init(&changeset);
3882bc42bda2SQu Wenruo len = round_up(start + len, root->fs_info->sectorsize);
3883bc42bda2SQu Wenruo start = round_down(start, root->fs_info->sectorsize);
3884bc42bda2SQu Wenruo
3885bc42bda2SQu Wenruo ULIST_ITER_INIT(&uiter);
3886bc42bda2SQu Wenruo while ((unode = ulist_next(&reserved->range_changed, &uiter))) {
3887bc42bda2SQu Wenruo u64 range_start = unode->val;
3888bc42bda2SQu Wenruo /* unode->aux is the inclusive end */
3889bc42bda2SQu Wenruo u64 range_len = unode->aux - range_start + 1;
3890bc42bda2SQu Wenruo u64 free_start;
3891bc42bda2SQu Wenruo u64 free_len;
3892bc42bda2SQu Wenruo
3893bc42bda2SQu Wenruo extent_changeset_release(&changeset);
3894bc42bda2SQu Wenruo
3895bc42bda2SQu Wenruo /* Only free range in range [start, start + len) */
3896bc42bda2SQu Wenruo if (range_start >= start + len ||
3897bc42bda2SQu Wenruo range_start + range_len <= start)
3898bc42bda2SQu Wenruo continue;
3899bc42bda2SQu Wenruo free_start = max(range_start, start);
3900bc42bda2SQu Wenruo free_len = min(start + len, range_start + range_len) -
3901bc42bda2SQu Wenruo free_start;
3902bc42bda2SQu Wenruo /*
3903bc42bda2SQu Wenruo * TODO: To also modify reserved->ranges_reserved to reflect
3904bc42bda2SQu Wenruo * the modification.
3905bc42bda2SQu Wenruo *
3906bc42bda2SQu Wenruo * However as long as we free qgroup reserved according to
3907bc42bda2SQu Wenruo * EXTENT_QGROUP_RESERVED, we won't double free.
3908bc42bda2SQu Wenruo * So not need to rush.
3909bc42bda2SQu Wenruo */
3910df2cfd13SNikolay Borisov ret = clear_record_extent_bits(&inode->io_tree, free_start,
3911df2cfd13SNikolay Borisov free_start + free_len - 1,
3912bc42bda2SQu Wenruo EXTENT_QGROUP_RESERVED, &changeset);
3913bc42bda2SQu Wenruo if (ret < 0)
3914bc42bda2SQu Wenruo goto out;
3915bc42bda2SQu Wenruo freed += changeset.bytes_changed;
3916bc42bda2SQu Wenruo }
39174fd786e6SMisono Tomohiro btrfs_qgroup_free_refroot(root->fs_info, root->root_key.objectid, freed,
3918d4e5c920SQu Wenruo BTRFS_QGROUP_RSV_DATA);
391918234915SBoris Burkov if (freed_ret)
392018234915SBoris Burkov *freed_ret = freed;
392118234915SBoris Burkov ret = 0;
3922bc42bda2SQu Wenruo out:
3923bc42bda2SQu Wenruo extent_changeset_release(&changeset);
3924bc42bda2SQu Wenruo return ret;
3925bc42bda2SQu Wenruo }
3926bc42bda2SQu Wenruo
__btrfs_qgroup_release_data(struct btrfs_inode * inode,struct extent_changeset * reserved,u64 start,u64 len,u64 * released,int free)39278769af96SNikolay Borisov static int __btrfs_qgroup_release_data(struct btrfs_inode *inode,
3928bc42bda2SQu Wenruo struct extent_changeset *reserved, u64 start, u64 len,
392918234915SBoris Burkov u64 *released, int free)
3930f695fdceSQu Wenruo {
3931f695fdceSQu Wenruo struct extent_changeset changeset;
393281fb6f77SQu Wenruo int trace_op = QGROUP_RELEASE;
3933f695fdceSQu Wenruo int ret;
3934f695fdceSQu Wenruo
39358769af96SNikolay Borisov if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &inode->root->fs_info->flags))
39363628b4caSQu Wenruo return 0;
39373628b4caSQu Wenruo
3938bc42bda2SQu Wenruo /* In release case, we shouldn't have @reserved */
3939bc42bda2SQu Wenruo WARN_ON(!free && reserved);
3940bc42bda2SQu Wenruo if (free && reserved)
394118234915SBoris Burkov return qgroup_free_reserved_data(inode, reserved, start, len, released);
3942364ecf36SQu Wenruo extent_changeset_init(&changeset);
39438769af96SNikolay Borisov ret = clear_record_extent_bits(&inode->io_tree, start, start + len -1,
39448769af96SNikolay Borisov EXTENT_QGROUP_RESERVED, &changeset);
3945f695fdceSQu Wenruo if (ret < 0)
3946f695fdceSQu Wenruo goto out;
3947f695fdceSQu Wenruo
3948d51ea5ddSQu Wenruo if (free)
3949d51ea5ddSQu Wenruo trace_op = QGROUP_FREE;
39508769af96SNikolay Borisov trace_btrfs_qgroup_release_data(&inode->vfs_inode, start, len,
3951d51ea5ddSQu Wenruo changeset.bytes_changed, trace_op);
3952d51ea5ddSQu Wenruo if (free)
39538769af96SNikolay Borisov btrfs_qgroup_free_refroot(inode->root->fs_info,
39548769af96SNikolay Borisov inode->root->root_key.objectid,
3955d4e5c920SQu Wenruo changeset.bytes_changed, BTRFS_QGROUP_RSV_DATA);
395618234915SBoris Burkov if (released)
395718234915SBoris Burkov *released = changeset.bytes_changed;
3958f695fdceSQu Wenruo out:
3959364ecf36SQu Wenruo extent_changeset_release(&changeset);
3960f695fdceSQu Wenruo return ret;
3961f695fdceSQu Wenruo }
3962f695fdceSQu Wenruo
3963f695fdceSQu Wenruo /*
3964f695fdceSQu Wenruo * Free a reserved space range from io_tree and related qgroups
3965f695fdceSQu Wenruo *
3966f695fdceSQu Wenruo * Should be called when a range of pages get invalidated before reaching disk.
3967f695fdceSQu Wenruo * Or for error cleanup case.
3968bc42bda2SQu Wenruo * if @reserved is given, only reserved range in [@start, @start + @len) will
3969bc42bda2SQu Wenruo * be freed.
3970f695fdceSQu Wenruo *
3971f695fdceSQu Wenruo * For data written to disk, use btrfs_qgroup_release_data().
3972f695fdceSQu Wenruo *
3973f695fdceSQu Wenruo * NOTE: This function may sleep for memory allocation.
3974f695fdceSQu Wenruo */
btrfs_qgroup_free_data(struct btrfs_inode * inode,struct extent_changeset * reserved,u64 start,u64 len,u64 * freed)39758b8a979fSNikolay Borisov int btrfs_qgroup_free_data(struct btrfs_inode *inode,
397618234915SBoris Burkov struct extent_changeset *reserved,
397718234915SBoris Burkov u64 start, u64 len, u64 *freed)
3978f695fdceSQu Wenruo {
397918234915SBoris Burkov return __btrfs_qgroup_release_data(inode, reserved, start, len, freed, 1);
3980f695fdceSQu Wenruo }
3981f695fdceSQu Wenruo
3982f695fdceSQu Wenruo /*
3983f695fdceSQu Wenruo * Release a reserved space range from io_tree only.
3984f695fdceSQu Wenruo *
3985f695fdceSQu Wenruo * Should be called when a range of pages get written to disk and corresponding
3986f695fdceSQu Wenruo * FILE_EXTENT is inserted into corresponding root.
3987f695fdceSQu Wenruo *
3988f695fdceSQu Wenruo * Since new qgroup accounting framework will only update qgroup numbers at
3989f695fdceSQu Wenruo * commit_transaction() time, its reserved space shouldn't be freed from
3990f695fdceSQu Wenruo * related qgroups.
3991f695fdceSQu Wenruo *
3992f695fdceSQu Wenruo * But we should release the range from io_tree, to allow further write to be
3993f695fdceSQu Wenruo * COWed.
3994f695fdceSQu Wenruo *
3995f695fdceSQu Wenruo * NOTE: This function may sleep for memory allocation.
3996f695fdceSQu Wenruo */
btrfs_qgroup_release_data(struct btrfs_inode * inode,u64 start,u64 len,u64 * released)399718234915SBoris Burkov int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len, u64 *released)
3998f695fdceSQu Wenruo {
399918234915SBoris Burkov return __btrfs_qgroup_release_data(inode, NULL, start, len, released, 0);
4000f695fdceSQu Wenruo }
400155eeaf05SQu Wenruo
add_root_meta_rsv(struct btrfs_root * root,int num_bytes,enum btrfs_qgroup_rsv_type type)40028287475aSQu Wenruo static void add_root_meta_rsv(struct btrfs_root *root, int num_bytes,
40038287475aSQu Wenruo enum btrfs_qgroup_rsv_type type)
40048287475aSQu Wenruo {
40058287475aSQu Wenruo if (type != BTRFS_QGROUP_RSV_META_PREALLOC &&
40068287475aSQu Wenruo type != BTRFS_QGROUP_RSV_META_PERTRANS)
40078287475aSQu Wenruo return;
40088287475aSQu Wenruo if (num_bytes == 0)
40098287475aSQu Wenruo return;
40108287475aSQu Wenruo
40118287475aSQu Wenruo spin_lock(&root->qgroup_meta_rsv_lock);
40128287475aSQu Wenruo if (type == BTRFS_QGROUP_RSV_META_PREALLOC)
40138287475aSQu Wenruo root->qgroup_meta_rsv_prealloc += num_bytes;
40148287475aSQu Wenruo else
40158287475aSQu Wenruo root->qgroup_meta_rsv_pertrans += num_bytes;
40168287475aSQu Wenruo spin_unlock(&root->qgroup_meta_rsv_lock);
40178287475aSQu Wenruo }
40188287475aSQu Wenruo
sub_root_meta_rsv(struct btrfs_root * root,int num_bytes,enum btrfs_qgroup_rsv_type type)40198287475aSQu Wenruo static int sub_root_meta_rsv(struct btrfs_root *root, int num_bytes,
40208287475aSQu Wenruo enum btrfs_qgroup_rsv_type type)
40218287475aSQu Wenruo {
40228287475aSQu Wenruo if (type != BTRFS_QGROUP_RSV_META_PREALLOC &&
40238287475aSQu Wenruo type != BTRFS_QGROUP_RSV_META_PERTRANS)
40248287475aSQu Wenruo return 0;
40258287475aSQu Wenruo if (num_bytes == 0)
40268287475aSQu Wenruo return 0;
40278287475aSQu Wenruo
40288287475aSQu Wenruo spin_lock(&root->qgroup_meta_rsv_lock);
40298287475aSQu Wenruo if (type == BTRFS_QGROUP_RSV_META_PREALLOC) {
40308287475aSQu Wenruo num_bytes = min_t(u64, root->qgroup_meta_rsv_prealloc,
40318287475aSQu Wenruo num_bytes);
40328287475aSQu Wenruo root->qgroup_meta_rsv_prealloc -= num_bytes;
40338287475aSQu Wenruo } else {
40348287475aSQu Wenruo num_bytes = min_t(u64, root->qgroup_meta_rsv_pertrans,
40358287475aSQu Wenruo num_bytes);
40368287475aSQu Wenruo root->qgroup_meta_rsv_pertrans -= num_bytes;
40378287475aSQu Wenruo }
40388287475aSQu Wenruo spin_unlock(&root->qgroup_meta_rsv_lock);
40398287475aSQu Wenruo return num_bytes;
40408287475aSQu Wenruo }
40418287475aSQu Wenruo
btrfs_qgroup_reserve_meta(struct btrfs_root * root,int num_bytes,enum btrfs_qgroup_rsv_type type,bool enforce)404280e9baedSNikolay Borisov int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
4043733e03a0SQu Wenruo enum btrfs_qgroup_rsv_type type, bool enforce)
404455eeaf05SQu Wenruo {
40450b246afaSJeff Mahoney struct btrfs_fs_info *fs_info = root->fs_info;
404655eeaf05SQu Wenruo int ret;
404755eeaf05SQu Wenruo
40480b246afaSJeff Mahoney if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
40494fd786e6SMisono Tomohiro !is_fstree(root->root_key.objectid) || num_bytes == 0)
405055eeaf05SQu Wenruo return 0;
405155eeaf05SQu Wenruo
40520b246afaSJeff Mahoney BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize));
4053fd2b007eSQu Wenruo trace_qgroup_meta_reserve(root, (s64)num_bytes, type);
4054733e03a0SQu Wenruo ret = qgroup_reserve(root, num_bytes, enforce, type);
405555eeaf05SQu Wenruo if (ret < 0)
405655eeaf05SQu Wenruo return ret;
40578287475aSQu Wenruo /*
40588287475aSQu Wenruo * Record what we have reserved into root.
40598287475aSQu Wenruo *
40608287475aSQu Wenruo * To avoid quota disabled->enabled underflow.
40618287475aSQu Wenruo * In that case, we may try to free space we haven't reserved
40628287475aSQu Wenruo * (since quota was disabled), so record what we reserved into root.
40638287475aSQu Wenruo * And ensure later release won't underflow this number.
40648287475aSQu Wenruo */
40658287475aSQu Wenruo add_root_meta_rsv(root, num_bytes, type);
406655eeaf05SQu Wenruo return ret;
406755eeaf05SQu Wenruo }
406855eeaf05SQu Wenruo
__btrfs_qgroup_reserve_meta(struct btrfs_root * root,int num_bytes,enum btrfs_qgroup_rsv_type type,bool enforce,bool noflush)4069c53e9653SQu Wenruo int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
4070d4135134SFilipe Manana enum btrfs_qgroup_rsv_type type, bool enforce,
4071d4135134SFilipe Manana bool noflush)
4072c53e9653SQu Wenruo {
4073c53e9653SQu Wenruo int ret;
4074c53e9653SQu Wenruo
407580e9baedSNikolay Borisov ret = btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce);
4076d4135134SFilipe Manana if ((ret <= 0 && ret != -EDQUOT) || noflush)
4077c53e9653SQu Wenruo return ret;
4078c53e9653SQu Wenruo
4079c53e9653SQu Wenruo ret = try_flush_qgroup(root);
4080c53e9653SQu Wenruo if (ret < 0)
4081c53e9653SQu Wenruo return ret;
408280e9baedSNikolay Borisov return btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce);
4083c53e9653SQu Wenruo }
4084c53e9653SQu Wenruo
btrfs_qgroup_free_meta_all_pertrans(struct btrfs_root * root)4085733e03a0SQu Wenruo void btrfs_qgroup_free_meta_all_pertrans(struct btrfs_root *root)
408655eeaf05SQu Wenruo {
40870b246afaSJeff Mahoney struct btrfs_fs_info *fs_info = root->fs_info;
408855eeaf05SQu Wenruo
40890b246afaSJeff Mahoney if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
40904fd786e6SMisono Tomohiro !is_fstree(root->root_key.objectid))
409155eeaf05SQu Wenruo return;
409255eeaf05SQu Wenruo
4093e1211d0eSQu Wenruo /* TODO: Update trace point to handle such free */
40944ee0d883SQu Wenruo trace_qgroup_meta_free_all_pertrans(root);
4095e1211d0eSQu Wenruo /* Special value -1 means to free all reserved space */
40964fd786e6SMisono Tomohiro btrfs_qgroup_free_refroot(fs_info, root->root_key.objectid, (u64)-1,
4097733e03a0SQu Wenruo BTRFS_QGROUP_RSV_META_PERTRANS);
409855eeaf05SQu Wenruo }
409955eeaf05SQu Wenruo
__btrfs_qgroup_free_meta(struct btrfs_root * root,int num_bytes,enum btrfs_qgroup_rsv_type type)4100733e03a0SQu Wenruo void __btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes,
4101733e03a0SQu Wenruo enum btrfs_qgroup_rsv_type type)
410255eeaf05SQu Wenruo {
41030b246afaSJeff Mahoney struct btrfs_fs_info *fs_info = root->fs_info;
41040b246afaSJeff Mahoney
41050b246afaSJeff Mahoney if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
41064fd786e6SMisono Tomohiro !is_fstree(root->root_key.objectid))
410755eeaf05SQu Wenruo return;
410855eeaf05SQu Wenruo
41098287475aSQu Wenruo /*
41108287475aSQu Wenruo * reservation for META_PREALLOC can happen before quota is enabled,
41118287475aSQu Wenruo * which can lead to underflow.
41128287475aSQu Wenruo * Here ensure we will only free what we really have reserved.
41138287475aSQu Wenruo */
41148287475aSQu Wenruo num_bytes = sub_root_meta_rsv(root, num_bytes, type);
41150b246afaSJeff Mahoney BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize));
4116fd2b007eSQu Wenruo trace_qgroup_meta_reserve(root, -(s64)num_bytes, type);
41174fd786e6SMisono Tomohiro btrfs_qgroup_free_refroot(fs_info, root->root_key.objectid,
41184fd786e6SMisono Tomohiro num_bytes, type);
411955eeaf05SQu Wenruo }
412056fa9d07SQu Wenruo
qgroup_convert_meta(struct btrfs_fs_info * fs_info,u64 ref_root,int num_bytes)412164cfaef6SQu Wenruo static void qgroup_convert_meta(struct btrfs_fs_info *fs_info, u64 ref_root,
412264cfaef6SQu Wenruo int num_bytes)
412364cfaef6SQu Wenruo {
412464cfaef6SQu Wenruo struct btrfs_qgroup *qgroup;
41251a80999bSQu Wenruo LIST_HEAD(qgroup_list);
412664cfaef6SQu Wenruo
412764cfaef6SQu Wenruo if (num_bytes == 0)
412864cfaef6SQu Wenruo return;
4129e3b0edd2SMarcos Paulo de Souza if (!fs_info->quota_root)
413064cfaef6SQu Wenruo return;
413164cfaef6SQu Wenruo
413264cfaef6SQu Wenruo spin_lock(&fs_info->qgroup_lock);
413364cfaef6SQu Wenruo qgroup = find_qgroup_rb(fs_info, ref_root);
413464cfaef6SQu Wenruo if (!qgroup)
413564cfaef6SQu Wenruo goto out;
41361a80999bSQu Wenruo
41371a80999bSQu Wenruo qgroup_iterator_add(&qgroup_list, qgroup);
41381a80999bSQu Wenruo list_for_each_entry(qgroup, &qgroup_list, iterator) {
413964cfaef6SQu Wenruo struct btrfs_qgroup_list *glist;
414064cfaef6SQu Wenruo
41411a80999bSQu Wenruo qgroup_rsv_release(fs_info, qgroup, num_bytes,
414264cfaef6SQu Wenruo BTRFS_QGROUP_RSV_META_PREALLOC);
4143624bc6f6SBoris Burkov if (!sb_rdonly(fs_info->sb))
41441a80999bSQu Wenruo qgroup_rsv_add(fs_info, qgroup, num_bytes,
414564cfaef6SQu Wenruo BTRFS_QGROUP_RSV_META_PERTRANS);
41461a80999bSQu Wenruo
41471a80999bSQu Wenruo list_for_each_entry(glist, &qgroup->groups, next_group)
41481a80999bSQu Wenruo qgroup_iterator_add(&qgroup_list, glist->group);
414964cfaef6SQu Wenruo }
415064cfaef6SQu Wenruo out:
41511a80999bSQu Wenruo qgroup_iterator_clean(&qgroup_list);
415264cfaef6SQu Wenruo spin_unlock(&fs_info->qgroup_lock);
415364cfaef6SQu Wenruo }
415464cfaef6SQu Wenruo
btrfs_qgroup_convert_reserved_meta(struct btrfs_root * root,int num_bytes)415564cfaef6SQu Wenruo void btrfs_qgroup_convert_reserved_meta(struct btrfs_root *root, int num_bytes)
415664cfaef6SQu Wenruo {
415764cfaef6SQu Wenruo struct btrfs_fs_info *fs_info = root->fs_info;
415864cfaef6SQu Wenruo
415964cfaef6SQu Wenruo if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
41604fd786e6SMisono Tomohiro !is_fstree(root->root_key.objectid))
416164cfaef6SQu Wenruo return;
41628287475aSQu Wenruo /* Same as btrfs_qgroup_free_meta_prealloc() */
41638287475aSQu Wenruo num_bytes = sub_root_meta_rsv(root, num_bytes,
41648287475aSQu Wenruo BTRFS_QGROUP_RSV_META_PREALLOC);
41654ee0d883SQu Wenruo trace_qgroup_meta_convert(root, num_bytes);
41664fd786e6SMisono Tomohiro qgroup_convert_meta(fs_info, root->root_key.objectid, num_bytes);
416703cca8feSBoris Burkov if (!sb_rdonly(fs_info->sb))
416803cca8feSBoris Burkov add_root_meta_rsv(root, num_bytes, BTRFS_QGROUP_RSV_META_PERTRANS);
416964cfaef6SQu Wenruo }
417064cfaef6SQu Wenruo
417156fa9d07SQu Wenruo /*
417201327610SNicholas D Steeves * Check qgroup reserved space leaking, normally at destroy inode
417356fa9d07SQu Wenruo * time
417456fa9d07SQu Wenruo */
btrfs_qgroup_check_reserved_leak(struct btrfs_inode * inode)4175cfdd4592SNikolay Borisov void btrfs_qgroup_check_reserved_leak(struct btrfs_inode *inode)
417656fa9d07SQu Wenruo {
417756fa9d07SQu Wenruo struct extent_changeset changeset;
417856fa9d07SQu Wenruo struct ulist_node *unode;
417956fa9d07SQu Wenruo struct ulist_iterator iter;
418056fa9d07SQu Wenruo int ret;
418156fa9d07SQu Wenruo
4182364ecf36SQu Wenruo extent_changeset_init(&changeset);
4183cfdd4592SNikolay Borisov ret = clear_record_extent_bits(&inode->io_tree, 0, (u64)-1,
4184f734c44aSDavid Sterba EXTENT_QGROUP_RESERVED, &changeset);
418556fa9d07SQu Wenruo
418656fa9d07SQu Wenruo WARN_ON(ret < 0);
418756fa9d07SQu Wenruo if (WARN_ON(changeset.bytes_changed)) {
418856fa9d07SQu Wenruo ULIST_ITER_INIT(&iter);
418953d32359SDavid Sterba while ((unode = ulist_next(&changeset.range_changed, &iter))) {
4190cfdd4592SNikolay Borisov btrfs_warn(inode->root->fs_info,
4191cfdd4592SNikolay Borisov "leaking qgroup reserved space, ino: %llu, start: %llu, end: %llu",
4192cfdd4592SNikolay Borisov btrfs_ino(inode), unode->val, unode->aux);
419356fa9d07SQu Wenruo }
4194cfdd4592SNikolay Borisov btrfs_qgroup_free_refroot(inode->root->fs_info,
4195cfdd4592SNikolay Borisov inode->root->root_key.objectid,
4196d4e5c920SQu Wenruo changeset.bytes_changed, BTRFS_QGROUP_RSV_DATA);
41970b08e1f4SDavid Sterba
419856fa9d07SQu Wenruo }
4199364ecf36SQu Wenruo extent_changeset_release(&changeset);
420056fa9d07SQu Wenruo }
4201370a11b8SQu Wenruo
btrfs_qgroup_init_swapped_blocks(struct btrfs_qgroup_swapped_blocks * swapped_blocks)4202370a11b8SQu Wenruo void btrfs_qgroup_init_swapped_blocks(
4203370a11b8SQu Wenruo struct btrfs_qgroup_swapped_blocks *swapped_blocks)
4204370a11b8SQu Wenruo {
4205370a11b8SQu Wenruo int i;
4206370a11b8SQu Wenruo
4207370a11b8SQu Wenruo spin_lock_init(&swapped_blocks->lock);
4208370a11b8SQu Wenruo for (i = 0; i < BTRFS_MAX_LEVEL; i++)
4209370a11b8SQu Wenruo swapped_blocks->blocks[i] = RB_ROOT;
4210370a11b8SQu Wenruo swapped_blocks->swapped = false;
4211370a11b8SQu Wenruo }
4212370a11b8SQu Wenruo
4213370a11b8SQu Wenruo /*
4214370a11b8SQu Wenruo * Delete all swapped blocks record of @root.
4215370a11b8SQu Wenruo * Every record here means we skipped a full subtree scan for qgroup.
4216370a11b8SQu Wenruo *
4217370a11b8SQu Wenruo * Gets called when committing one transaction.
4218370a11b8SQu Wenruo */
btrfs_qgroup_clean_swapped_blocks(struct btrfs_root * root)4219370a11b8SQu Wenruo void btrfs_qgroup_clean_swapped_blocks(struct btrfs_root *root)
4220370a11b8SQu Wenruo {
4221370a11b8SQu Wenruo struct btrfs_qgroup_swapped_blocks *swapped_blocks;
4222370a11b8SQu Wenruo int i;
4223370a11b8SQu Wenruo
4224370a11b8SQu Wenruo swapped_blocks = &root->swapped_blocks;
4225370a11b8SQu Wenruo
4226370a11b8SQu Wenruo spin_lock(&swapped_blocks->lock);
4227370a11b8SQu Wenruo if (!swapped_blocks->swapped)
4228370a11b8SQu Wenruo goto out;
4229370a11b8SQu Wenruo for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
4230370a11b8SQu Wenruo struct rb_root *cur_root = &swapped_blocks->blocks[i];
4231370a11b8SQu Wenruo struct btrfs_qgroup_swapped_block *entry;
4232370a11b8SQu Wenruo struct btrfs_qgroup_swapped_block *next;
4233370a11b8SQu Wenruo
4234370a11b8SQu Wenruo rbtree_postorder_for_each_entry_safe(entry, next, cur_root,
4235370a11b8SQu Wenruo node)
4236370a11b8SQu Wenruo kfree(entry);
4237370a11b8SQu Wenruo swapped_blocks->blocks[i] = RB_ROOT;
4238370a11b8SQu Wenruo }
4239370a11b8SQu Wenruo swapped_blocks->swapped = false;
4240370a11b8SQu Wenruo out:
4241370a11b8SQu Wenruo spin_unlock(&swapped_blocks->lock);
4242370a11b8SQu Wenruo }
4243370a11b8SQu Wenruo
4244370a11b8SQu Wenruo /*
4245370a11b8SQu Wenruo * Add subtree roots record into @subvol_root.
4246370a11b8SQu Wenruo *
4247370a11b8SQu Wenruo * @subvol_root: tree root of the subvolume tree get swapped
4248370a11b8SQu Wenruo * @bg: block group under balance
4249370a11b8SQu Wenruo * @subvol_parent/slot: pointer to the subtree root in subvolume tree
4250370a11b8SQu Wenruo * @reloc_parent/slot: pointer to the subtree root in reloc tree
4251370a11b8SQu Wenruo * BOTH POINTERS ARE BEFORE TREE SWAP
4252370a11b8SQu Wenruo * @last_snapshot: last snapshot generation of the subvolume tree
4253370a11b8SQu Wenruo */
btrfs_qgroup_add_swapped_blocks(struct btrfs_trans_handle * trans,struct btrfs_root * subvol_root,struct btrfs_block_group * bg,struct extent_buffer * subvol_parent,int subvol_slot,struct extent_buffer * reloc_parent,int reloc_slot,u64 last_snapshot)4254370a11b8SQu Wenruo int btrfs_qgroup_add_swapped_blocks(struct btrfs_trans_handle *trans,
4255370a11b8SQu Wenruo struct btrfs_root *subvol_root,
425632da5386SDavid Sterba struct btrfs_block_group *bg,
4257370a11b8SQu Wenruo struct extent_buffer *subvol_parent, int subvol_slot,
4258370a11b8SQu Wenruo struct extent_buffer *reloc_parent, int reloc_slot,
4259370a11b8SQu Wenruo u64 last_snapshot)
4260370a11b8SQu Wenruo {
4261370a11b8SQu Wenruo struct btrfs_fs_info *fs_info = subvol_root->fs_info;
4262370a11b8SQu Wenruo struct btrfs_qgroup_swapped_blocks *blocks = &subvol_root->swapped_blocks;
4263370a11b8SQu Wenruo struct btrfs_qgroup_swapped_block *block;
4264370a11b8SQu Wenruo struct rb_node **cur;
4265370a11b8SQu Wenruo struct rb_node *parent = NULL;
4266370a11b8SQu Wenruo int level = btrfs_header_level(subvol_parent) - 1;
4267370a11b8SQu Wenruo int ret = 0;
4268370a11b8SQu Wenruo
4269370a11b8SQu Wenruo if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
4270370a11b8SQu Wenruo return 0;
4271370a11b8SQu Wenruo
4272370a11b8SQu Wenruo if (btrfs_node_ptr_generation(subvol_parent, subvol_slot) >
4273370a11b8SQu Wenruo btrfs_node_ptr_generation(reloc_parent, reloc_slot)) {
4274370a11b8SQu Wenruo btrfs_err_rl(fs_info,
4275370a11b8SQu Wenruo "%s: bad parameter order, subvol_gen=%llu reloc_gen=%llu",
4276370a11b8SQu Wenruo __func__,
4277370a11b8SQu Wenruo btrfs_node_ptr_generation(subvol_parent, subvol_slot),
4278370a11b8SQu Wenruo btrfs_node_ptr_generation(reloc_parent, reloc_slot));
4279370a11b8SQu Wenruo return -EUCLEAN;
4280370a11b8SQu Wenruo }
4281370a11b8SQu Wenruo
4282370a11b8SQu Wenruo block = kmalloc(sizeof(*block), GFP_NOFS);
4283370a11b8SQu Wenruo if (!block) {
4284370a11b8SQu Wenruo ret = -ENOMEM;
4285370a11b8SQu Wenruo goto out;
4286370a11b8SQu Wenruo }
4287370a11b8SQu Wenruo
4288370a11b8SQu Wenruo /*
4289370a11b8SQu Wenruo * @reloc_parent/slot is still before swap, while @block is going to
4290370a11b8SQu Wenruo * record the bytenr after swap, so we do the swap here.
4291370a11b8SQu Wenruo */
4292370a11b8SQu Wenruo block->subvol_bytenr = btrfs_node_blockptr(reloc_parent, reloc_slot);
4293370a11b8SQu Wenruo block->subvol_generation = btrfs_node_ptr_generation(reloc_parent,
4294370a11b8SQu Wenruo reloc_slot);
4295370a11b8SQu Wenruo block->reloc_bytenr = btrfs_node_blockptr(subvol_parent, subvol_slot);
4296370a11b8SQu Wenruo block->reloc_generation = btrfs_node_ptr_generation(subvol_parent,
4297370a11b8SQu Wenruo subvol_slot);
4298370a11b8SQu Wenruo block->last_snapshot = last_snapshot;
4299370a11b8SQu Wenruo block->level = level;
430057949d03SQu Wenruo
430157949d03SQu Wenruo /*
430257949d03SQu Wenruo * If we have bg == NULL, we're called from btrfs_recover_relocation(),
430357949d03SQu Wenruo * no one else can modify tree blocks thus we qgroup will not change
430457949d03SQu Wenruo * no matter the value of trace_leaf.
430557949d03SQu Wenruo */
430657949d03SQu Wenruo if (bg && bg->flags & BTRFS_BLOCK_GROUP_DATA)
4307370a11b8SQu Wenruo block->trace_leaf = true;
4308370a11b8SQu Wenruo else
4309370a11b8SQu Wenruo block->trace_leaf = false;
4310370a11b8SQu Wenruo btrfs_node_key_to_cpu(reloc_parent, &block->first_key, reloc_slot);
4311370a11b8SQu Wenruo
4312370a11b8SQu Wenruo /* Insert @block into @blocks */
4313370a11b8SQu Wenruo spin_lock(&blocks->lock);
4314370a11b8SQu Wenruo cur = &blocks->blocks[level].rb_node;
4315370a11b8SQu Wenruo while (*cur) {
4316370a11b8SQu Wenruo struct btrfs_qgroup_swapped_block *entry;
4317370a11b8SQu Wenruo
4318370a11b8SQu Wenruo parent = *cur;
4319370a11b8SQu Wenruo entry = rb_entry(parent, struct btrfs_qgroup_swapped_block,
4320370a11b8SQu Wenruo node);
4321370a11b8SQu Wenruo
4322370a11b8SQu Wenruo if (entry->subvol_bytenr < block->subvol_bytenr) {
4323370a11b8SQu Wenruo cur = &(*cur)->rb_left;
4324370a11b8SQu Wenruo } else if (entry->subvol_bytenr > block->subvol_bytenr) {
4325370a11b8SQu Wenruo cur = &(*cur)->rb_right;
4326370a11b8SQu Wenruo } else {
4327370a11b8SQu Wenruo if (entry->subvol_generation !=
4328370a11b8SQu Wenruo block->subvol_generation ||
4329370a11b8SQu Wenruo entry->reloc_bytenr != block->reloc_bytenr ||
4330370a11b8SQu Wenruo entry->reloc_generation !=
4331370a11b8SQu Wenruo block->reloc_generation) {
4332370a11b8SQu Wenruo /*
4333370a11b8SQu Wenruo * Duplicated but mismatch entry found.
4334370a11b8SQu Wenruo * Shouldn't happen.
4335370a11b8SQu Wenruo *
4336370a11b8SQu Wenruo * Marking qgroup inconsistent should be enough
4337370a11b8SQu Wenruo * for end users.
4338370a11b8SQu Wenruo */
4339370a11b8SQu Wenruo WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG));
4340370a11b8SQu Wenruo ret = -EEXIST;
4341370a11b8SQu Wenruo }
4342370a11b8SQu Wenruo kfree(block);
4343370a11b8SQu Wenruo goto out_unlock;
4344370a11b8SQu Wenruo }
4345370a11b8SQu Wenruo }
4346370a11b8SQu Wenruo rb_link_node(&block->node, parent, cur);
4347370a11b8SQu Wenruo rb_insert_color(&block->node, &blocks->blocks[level]);
4348370a11b8SQu Wenruo blocks->swapped = true;
4349370a11b8SQu Wenruo out_unlock:
4350370a11b8SQu Wenruo spin_unlock(&blocks->lock);
4351370a11b8SQu Wenruo out:
4352370a11b8SQu Wenruo if (ret < 0)
4353e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
4354370a11b8SQu Wenruo return ret;
4355370a11b8SQu Wenruo }
4356f616f5cdSQu Wenruo
4357f616f5cdSQu Wenruo /*
4358f616f5cdSQu Wenruo * Check if the tree block is a subtree root, and if so do the needed
4359f616f5cdSQu Wenruo * delayed subtree trace for qgroup.
4360f616f5cdSQu Wenruo *
4361f616f5cdSQu Wenruo * This is called during btrfs_cow_block().
4362f616f5cdSQu Wenruo */
btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct extent_buffer * subvol_eb)4363f616f5cdSQu Wenruo int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
4364f616f5cdSQu Wenruo struct btrfs_root *root,
4365f616f5cdSQu Wenruo struct extent_buffer *subvol_eb)
4366f616f5cdSQu Wenruo {
4367f616f5cdSQu Wenruo struct btrfs_fs_info *fs_info = root->fs_info;
4368789d6a3aSQu Wenruo struct btrfs_tree_parent_check check = { 0 };
4369f616f5cdSQu Wenruo struct btrfs_qgroup_swapped_blocks *blocks = &root->swapped_blocks;
4370f616f5cdSQu Wenruo struct btrfs_qgroup_swapped_block *block;
4371f616f5cdSQu Wenruo struct extent_buffer *reloc_eb = NULL;
4372f616f5cdSQu Wenruo struct rb_node *node;
4373f616f5cdSQu Wenruo bool found = false;
4374f616f5cdSQu Wenruo bool swapped = false;
4375f616f5cdSQu Wenruo int level = btrfs_header_level(subvol_eb);
4376f616f5cdSQu Wenruo int ret = 0;
4377f616f5cdSQu Wenruo int i;
4378f616f5cdSQu Wenruo
4379f616f5cdSQu Wenruo if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
4380f616f5cdSQu Wenruo return 0;
4381f616f5cdSQu Wenruo if (!is_fstree(root->root_key.objectid) || !root->reloc_root)
4382f616f5cdSQu Wenruo return 0;
4383f616f5cdSQu Wenruo
4384f616f5cdSQu Wenruo spin_lock(&blocks->lock);
4385f616f5cdSQu Wenruo if (!blocks->swapped) {
4386f616f5cdSQu Wenruo spin_unlock(&blocks->lock);
4387f616f5cdSQu Wenruo return 0;
4388f616f5cdSQu Wenruo }
4389f616f5cdSQu Wenruo node = blocks->blocks[level].rb_node;
4390f616f5cdSQu Wenruo
4391f616f5cdSQu Wenruo while (node) {
4392f616f5cdSQu Wenruo block = rb_entry(node, struct btrfs_qgroup_swapped_block, node);
4393f616f5cdSQu Wenruo if (block->subvol_bytenr < subvol_eb->start) {
4394f616f5cdSQu Wenruo node = node->rb_left;
4395f616f5cdSQu Wenruo } else if (block->subvol_bytenr > subvol_eb->start) {
4396f616f5cdSQu Wenruo node = node->rb_right;
4397f616f5cdSQu Wenruo } else {
4398f616f5cdSQu Wenruo found = true;
4399f616f5cdSQu Wenruo break;
4400f616f5cdSQu Wenruo }
4401f616f5cdSQu Wenruo }
4402f616f5cdSQu Wenruo if (!found) {
4403f616f5cdSQu Wenruo spin_unlock(&blocks->lock);
4404f616f5cdSQu Wenruo goto out;
4405f616f5cdSQu Wenruo }
4406f616f5cdSQu Wenruo /* Found one, remove it from @blocks first and update blocks->swapped */
4407f616f5cdSQu Wenruo rb_erase(&block->node, &blocks->blocks[level]);
4408f616f5cdSQu Wenruo for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
4409f616f5cdSQu Wenruo if (RB_EMPTY_ROOT(&blocks->blocks[i])) {
4410f616f5cdSQu Wenruo swapped = true;
4411f616f5cdSQu Wenruo break;
4412f616f5cdSQu Wenruo }
4413f616f5cdSQu Wenruo }
4414f616f5cdSQu Wenruo blocks->swapped = swapped;
4415f616f5cdSQu Wenruo spin_unlock(&blocks->lock);
4416f616f5cdSQu Wenruo
4417789d6a3aSQu Wenruo check.level = block->level;
4418789d6a3aSQu Wenruo check.transid = block->reloc_generation;
4419789d6a3aSQu Wenruo check.has_first_key = true;
4420789d6a3aSQu Wenruo memcpy(&check.first_key, &block->first_key, sizeof(check.first_key));
4421789d6a3aSQu Wenruo
4422f616f5cdSQu Wenruo /* Read out reloc subtree root */
4423789d6a3aSQu Wenruo reloc_eb = read_tree_block(fs_info, block->reloc_bytenr, &check);
4424f616f5cdSQu Wenruo if (IS_ERR(reloc_eb)) {
4425f616f5cdSQu Wenruo ret = PTR_ERR(reloc_eb);
4426f616f5cdSQu Wenruo reloc_eb = NULL;
4427f616f5cdSQu Wenruo goto free_out;
4428f616f5cdSQu Wenruo }
4429f616f5cdSQu Wenruo if (!extent_buffer_uptodate(reloc_eb)) {
4430f616f5cdSQu Wenruo ret = -EIO;
4431f616f5cdSQu Wenruo goto free_out;
4432f616f5cdSQu Wenruo }
4433f616f5cdSQu Wenruo
4434f616f5cdSQu Wenruo ret = qgroup_trace_subtree_swap(trans, reloc_eb, subvol_eb,
4435f616f5cdSQu Wenruo block->last_snapshot, block->trace_leaf);
4436f616f5cdSQu Wenruo free_out:
4437f616f5cdSQu Wenruo kfree(block);
4438f616f5cdSQu Wenruo free_extent_buffer(reloc_eb);
4439f616f5cdSQu Wenruo out:
4440f616f5cdSQu Wenruo if (ret < 0) {
4441f616f5cdSQu Wenruo btrfs_err_rl(fs_info,
4442f616f5cdSQu Wenruo "failed to account subtree at bytenr %llu: %d",
4443f616f5cdSQu Wenruo subvol_eb->start, ret);
4444e562a8bdSQu Wenruo qgroup_mark_inconsistent(fs_info);
4445f616f5cdSQu Wenruo }
4446f616f5cdSQu Wenruo return ret;
4447f616f5cdSQu Wenruo }
444881f7eb00SJeff Mahoney
btrfs_qgroup_destroy_extent_records(struct btrfs_transaction * trans)444981f7eb00SJeff Mahoney void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans)
445081f7eb00SJeff Mahoney {
445181f7eb00SJeff Mahoney struct btrfs_qgroup_extent_record *entry;
445281f7eb00SJeff Mahoney struct btrfs_qgroup_extent_record *next;
445381f7eb00SJeff Mahoney struct rb_root *root;
445481f7eb00SJeff Mahoney
445581f7eb00SJeff Mahoney root = &trans->delayed_refs.dirty_extent_root;
445681f7eb00SJeff Mahoney rbtree_postorder_for_each_entry_safe(entry, next, root, node) {
445781f7eb00SJeff Mahoney ulist_free(entry->old_roots);
445881f7eb00SJeff Mahoney kfree(entry);
445981f7eb00SJeff Mahoney }
4460aa84ce8aSFilipe Manana *root = RB_ROOT;
446181f7eb00SJeff Mahoney }
4462