]>
Commit | Line | Data |
---|---|---|
fcebe456 JB |
1 | /* |
2 | * Copyright (C) 2014 Facebook. All rights reserved. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public | |
6 | * License v2 as published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
11 | * General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public | |
14 | * License along with this program; if not, write to the | |
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
16 | * Boston, MA 021110-1307, USA. | |
17 | */ | |
18 | ||
19 | #ifndef __BTRFS_QGROUP__ | |
20 | #define __BTRFS_QGROUP__ | |
21 | ||
3368d001 QW |
22 | #include "ulist.h" |
23 | #include "delayed-ref.h" | |
24 | ||
1d2beaa9 QW |
25 | /* |
26 | * Btrfs qgroup overview | |
27 | * | |
28 | * Btrfs qgroup splits into 3 main part: | |
29 | * 1) Reserve | |
30 | * Reserve metadata/data space for incoming operations | |
31 | * Affect how qgroup limit works | |
32 | * | |
33 | * 2) Trace | |
34 | * Tell btrfs qgroup to trace dirty extents. | |
35 | * | |
36 | * Dirty extents including: | |
37 | * - Newly allocated extents | |
38 | * - Extents going to be deleted (in this trans) | |
39 | * - Extents whose owner is going to be modified | |
40 | * | |
41 | * This is the main part affects whether qgroup numbers will stay | |
42 | * consistent. | |
43 | * Btrfs qgroup can trace clean extents and won't cause any problem, | |
44 | * but it will consume extra CPU time, it should be avoided if possible. | |
45 | * | |
46 | * 3) Account | |
47 | * Btrfs qgroup will updates its numbers, based on dirty extents traced | |
48 | * in previous step. | |
49 | * | |
50 | * Normally at qgroup rescan and transaction commit time. | |
51 | */ | |
52 | ||
3368d001 QW |
53 | /* |
54 | * Record a dirty extent, and info qgroup to update quota on it | |
55 | * TODO: Use kmem cache to alloc it. | |
56 | */ | |
57 | struct btrfs_qgroup_extent_record { | |
58 | struct rb_node node; | |
59 | u64 bytenr; | |
60 | u64 num_bytes; | |
61 | struct ulist *old_roots; | |
62 | }; | |
63 | ||
3159fe7b QW |
64 | /* |
65 | * one struct for each qgroup, organized in fs_info->qgroup_tree. | |
66 | */ | |
67 | struct btrfs_qgroup { | |
68 | u64 qgroupid; | |
69 | ||
70 | /* | |
71 | * state | |
72 | */ | |
73 | u64 rfer; /* referenced */ | |
74 | u64 rfer_cmpr; /* referenced compressed */ | |
75 | u64 excl; /* exclusive */ | |
76 | u64 excl_cmpr; /* exclusive compressed */ | |
77 | ||
78 | /* | |
79 | * limits | |
80 | */ | |
81 | u64 lim_flags; /* which limits are set */ | |
82 | u64 max_rfer; | |
83 | u64 max_excl; | |
84 | u64 rsv_rfer; | |
85 | u64 rsv_excl; | |
86 | ||
87 | /* | |
88 | * reservation tracking | |
89 | */ | |
90 | u64 reserved; | |
91 | ||
92 | /* | |
93 | * lists | |
94 | */ | |
95 | struct list_head groups; /* groups this group is member of */ | |
96 | struct list_head members; /* groups that are members of this group */ | |
97 | struct list_head dirty; /* dirty groups */ | |
98 | struct rb_node node; /* tree of qgroups */ | |
99 | ||
100 | /* | |
101 | * temp variables for accounting operations | |
102 | * Refer to qgroup_shared_accounting() for details. | |
103 | */ | |
104 | u64 old_refcnt; | |
105 | u64 new_refcnt; | |
106 | }; | |
107 | ||
81fb6f77 QW |
108 | /* |
109 | * For qgroup event trace points only | |
110 | */ | |
111 | #define QGROUP_RESERVE (1<<0) | |
112 | #define QGROUP_RELEASE (1<<1) | |
113 | #define QGROUP_FREE (1<<2) | |
114 | ||
fcebe456 JB |
115 | int btrfs_quota_enable(struct btrfs_trans_handle *trans, |
116 | struct btrfs_fs_info *fs_info); | |
117 | int btrfs_quota_disable(struct btrfs_trans_handle *trans, | |
118 | struct btrfs_fs_info *fs_info); | |
119 | int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); | |
120 | void btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info); | |
d06f23d6 JM |
121 | int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info, |
122 | bool interruptible); | |
fcebe456 JB |
123 | int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, |
124 | struct btrfs_fs_info *fs_info, u64 src, u64 dst); | |
125 | int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, | |
126 | struct btrfs_fs_info *fs_info, u64 src, u64 dst); | |
127 | int btrfs_create_qgroup(struct btrfs_trans_handle *trans, | |
4087cf24 | 128 | struct btrfs_fs_info *fs_info, u64 qgroupid); |
fcebe456 JB |
129 | int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, |
130 | struct btrfs_fs_info *fs_info, u64 qgroupid); | |
131 | int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, | |
132 | struct btrfs_fs_info *fs_info, u64 qgroupid, | |
133 | struct btrfs_qgroup_limit *limit); | |
134 | int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info); | |
135 | void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info); | |
136 | struct btrfs_delayed_extent_op; | |
3b7d00f9 QW |
137 | int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans, |
138 | struct btrfs_fs_info *fs_info); | |
cb93b52c | 139 | /* |
50b3e040 | 140 | * Inform qgroup to trace one dirty extent, its info is recorded in @record. |
fb235dc0 | 141 | * So qgroup can account it at transaction committing time. |
cb93b52c | 142 | * |
fb235dc0 QW |
143 | * No lock version, caller must acquire delayed ref lock and allocated memory, |
144 | * then call btrfs_qgroup_trace_extent_post() after exiting lock context. | |
cb93b52c QW |
145 | * |
146 | * Return 0 for success insert | |
147 | * Return >0 for existing record, caller can free @record safely. | |
148 | * Error is not possible | |
149 | */ | |
50b3e040 | 150 | int btrfs_qgroup_trace_extent_nolock( |
cb93b52c QW |
151 | struct btrfs_fs_info *fs_info, |
152 | struct btrfs_delayed_ref_root *delayed_refs, | |
153 | struct btrfs_qgroup_extent_record *record); | |
154 | ||
fb235dc0 QW |
155 | /* |
156 | * Post handler after qgroup_trace_extent_nolock(). | |
157 | * | |
158 | * NOTE: Current qgroup does the expensive backref walk at transaction | |
159 | * committing time with TRANS_STATE_COMMIT_DOING, this blocks incoming | |
160 | * new transaction. | |
161 | * This is designed to allow btrfs_find_all_roots() to get correct new_roots | |
162 | * result. | |
163 | * | |
164 | * However for old_roots there is no need to do backref walk at that time, | |
165 | * since we search commit roots to walk backref and result will always be | |
166 | * correct. | |
167 | * | |
168 | * Due to the nature of no lock version, we can't do backref there. | |
169 | * So we must call btrfs_qgroup_trace_extent_post() after exiting | |
170 | * spinlock context. | |
171 | * | |
172 | * TODO: If we can fix and prove btrfs_find_all_roots() can get correct result | |
173 | * using current root, then we can move all expensive backref walk out of | |
174 | * transaction committing, but not now as qgroup accounting will be wrong again. | |
175 | */ | |
176 | int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info, | |
177 | struct btrfs_qgroup_extent_record *qrecord); | |
178 | ||
cb93b52c | 179 | /* |
50b3e040 QW |
180 | * Inform qgroup to trace one dirty extent, specified by @bytenr and |
181 | * @num_bytes. | |
182 | * So qgroup can account it at commit trans time. | |
cb93b52c | 183 | * |
fb235dc0 QW |
184 | * Better encapsulated version, with memory allocation and backref walk for |
185 | * commit roots. | |
186 | * So this can sleep. | |
cb93b52c QW |
187 | * |
188 | * Return 0 if the operation is done. | |
189 | * Return <0 for error, like memory allocation failure or invalid parameter | |
190 | * (NULL trans) | |
191 | */ | |
50b3e040 | 192 | int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, |
cb93b52c QW |
193 | struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, |
194 | gfp_t gfp_flag); | |
195 | ||
33d1f05c QW |
196 | /* |
197 | * Inform qgroup to trace all leaf items of data | |
198 | * | |
199 | * Return 0 for success | |
200 | * Return <0 for error(ENOMEM) | |
201 | */ | |
202 | int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans, | |
2ff7e61e | 203 | struct btrfs_fs_info *fs_info, |
33d1f05c QW |
204 | struct extent_buffer *eb); |
205 | /* | |
206 | * Inform qgroup to trace a whole subtree, including all its child tree | |
207 | * blocks and data. | |
208 | * The root tree block is specified by @root_eb. | |
209 | * | |
210 | * Normally used by relocation(tree block swap) and subvolume deletion. | |
211 | * | |
212 | * Return 0 for success | |
213 | * Return <0 for error(ENOMEM or tree search error) | |
214 | */ | |
215 | int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans, | |
216 | struct btrfs_root *root, | |
217 | struct extent_buffer *root_eb, | |
218 | u64 root_gen, int root_level); | |
442244c9 QW |
219 | int |
220 | btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, | |
221 | struct btrfs_fs_info *fs_info, | |
222 | u64 bytenr, u64 num_bytes, | |
223 | struct ulist *old_roots, struct ulist *new_roots); | |
550d7a2e QW |
224 | int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans, |
225 | struct btrfs_fs_info *fs_info); | |
fcebe456 JB |
226 | int btrfs_run_qgroups(struct btrfs_trans_handle *trans, |
227 | struct btrfs_fs_info *fs_info); | |
228 | int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, | |
229 | struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid, | |
230 | struct btrfs_qgroup_inherit *inherit); | |
297d750b QW |
231 | void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info, |
232 | u64 ref_root, u64 num_bytes); | |
297d750b QW |
233 | static inline void btrfs_qgroup_free_delayed_ref(struct btrfs_fs_info *fs_info, |
234 | u64 ref_root, u64 num_bytes) | |
235 | { | |
bc074524 | 236 | trace_btrfs_qgroup_free_delayed_ref(fs_info, ref_root, num_bytes); |
d51ea5dd | 237 | btrfs_qgroup_free_refroot(fs_info, ref_root, num_bytes); |
297d750b | 238 | } |
fcebe456 JB |
239 | |
240 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | |
241 | int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid, | |
242 | u64 rfer, u64 excl); | |
243 | #endif | |
244 | ||
52472553 QW |
245 | /* New io_tree based accurate qgroup reserve API */ |
246 | int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len); | |
f695fdce QW |
247 | int btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len); |
248 | int btrfs_qgroup_free_data(struct inode *inode, u64 start, u64 len); | |
55eeaf05 | 249 | |
003d7c59 JM |
250 | int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, |
251 | bool enforce); | |
55eeaf05 QW |
252 | void btrfs_qgroup_free_meta_all(struct btrfs_root *root); |
253 | void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes); | |
56fa9d07 | 254 | void btrfs_qgroup_check_reserved_leak(struct inode *inode); |
fcebe456 | 255 | #endif /* __BTRFS_QGROUP__ */ |