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 22 #include "ulist.h" 23 #include "delayed-ref.h" 24 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 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 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 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 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); 121 int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info, 122 bool interruptible); 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, 128 struct btrfs_fs_info *fs_info, u64 qgroupid); 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; 137 int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans, 138 struct btrfs_fs_info *fs_info); 139 /* 140 * Inform qgroup to trace one dirty extent, its info is recorded in @record. 141 * So qgroup can account it at transaction committing time. 142 * 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. 145 * 146 * Return 0 for success insert 147 * Return >0 for existing record, caller can free @record safely. 148 * Error is not possible 149 */ 150 int btrfs_qgroup_trace_extent_nolock( 151 struct btrfs_fs_info *fs_info, 152 struct btrfs_delayed_ref_root *delayed_refs, 153 struct btrfs_qgroup_extent_record *record); 154 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 179 /* 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. 183 * 184 * Better encapsulated version, with memory allocation and backref walk for 185 * commit roots. 186 * So this can sleep. 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 */ 192 int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, 193 struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, 194 gfp_t gfp_flag); 195 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, 203 struct btrfs_fs_info *fs_info, 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); 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); 224 int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans, 225 struct btrfs_fs_info *fs_info); 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); 231 void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info, 232 u64 ref_root, u64 num_bytes); 233 static inline void btrfs_qgroup_free_delayed_ref(struct btrfs_fs_info *fs_info, 234 u64 ref_root, u64 num_bytes) 235 { 236 trace_btrfs_qgroup_free_delayed_ref(fs_info, ref_root, num_bytes); 237 btrfs_qgroup_free_refroot(fs_info, ref_root, num_bytes); 238 } 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 245 /* New io_tree based accurate qgroup reserve API */ 246 int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len); 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); 249 250 int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, 251 bool enforce); 252 void btrfs_qgroup_free_meta_all(struct btrfs_root *root); 253 void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes); 254 void btrfs_qgroup_check_reserved_leak(struct inode *inode); 255 #endif /* __BTRFS_QGROUP__ */ 256