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