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 * For qgroup event trace points only 66 */ 67 #define QGROUP_RESERVE (1<<0) 68 #define QGROUP_RELEASE (1<<1) 69 #define QGROUP_FREE (1<<2) 70 71 int btrfs_quota_enable(struct btrfs_trans_handle *trans, 72 struct btrfs_fs_info *fs_info); 73 int btrfs_quota_disable(struct btrfs_trans_handle *trans, 74 struct btrfs_fs_info *fs_info); 75 int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); 76 void btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info); 77 int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info, 78 bool interruptible); 79 int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, 80 struct btrfs_fs_info *fs_info, u64 src, u64 dst); 81 int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, 82 struct btrfs_fs_info *fs_info, u64 src, u64 dst); 83 int btrfs_create_qgroup(struct btrfs_trans_handle *trans, 84 struct btrfs_fs_info *fs_info, u64 qgroupid); 85 int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, 86 struct btrfs_fs_info *fs_info, u64 qgroupid); 87 int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, 88 struct btrfs_fs_info *fs_info, u64 qgroupid, 89 struct btrfs_qgroup_limit *limit); 90 int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info); 91 void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info); 92 struct btrfs_delayed_extent_op; 93 int btrfs_qgroup_prepare_account_extents(struct btrfs_trans_handle *trans, 94 struct btrfs_fs_info *fs_info); 95 /* 96 * Inform qgroup to trace one dirty extent, its info is recorded in @record. 97 * So qgroup can account it at transaction committing time. 98 * 99 * No lock version, caller must acquire delayed ref lock and allocated memory, 100 * then call btrfs_qgroup_trace_extent_post() after exiting lock context. 101 * 102 * Return 0 for success insert 103 * Return >0 for existing record, caller can free @record safely. 104 * Error is not possible 105 */ 106 int btrfs_qgroup_trace_extent_nolock( 107 struct btrfs_fs_info *fs_info, 108 struct btrfs_delayed_ref_root *delayed_refs, 109 struct btrfs_qgroup_extent_record *record); 110 111 /* 112 * Post handler after qgroup_trace_extent_nolock(). 113 * 114 * NOTE: Current qgroup does the expensive backref walk at transaction 115 * committing time with TRANS_STATE_COMMIT_DOING, this blocks incoming 116 * new transaction. 117 * This is designed to allow btrfs_find_all_roots() to get correct new_roots 118 * result. 119 * 120 * However for old_roots there is no need to do backref walk at that time, 121 * since we search commit roots to walk backref and result will always be 122 * correct. 123 * 124 * Due to the nature of no lock version, we can't do backref there. 125 * So we must call btrfs_qgroup_trace_extent_post() after exiting 126 * spinlock context. 127 * 128 * TODO: If we can fix and prove btrfs_find_all_roots() can get correct result 129 * using current root, then we can move all expensive backref walk out of 130 * transaction committing, but not now as qgroup accounting will be wrong again. 131 */ 132 int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info, 133 struct btrfs_qgroup_extent_record *qrecord); 134 135 /* 136 * Inform qgroup to trace one dirty extent, specified by @bytenr and 137 * @num_bytes. 138 * So qgroup can account it at commit trans time. 139 * 140 * Better encapsulated version, with memory allocation and backref walk for 141 * commit roots. 142 * So this can sleep. 143 * 144 * Return 0 if the operation is done. 145 * Return <0 for error, like memory allocation failure or invalid parameter 146 * (NULL trans) 147 */ 148 int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, 149 struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, 150 gfp_t gfp_flag); 151 152 /* 153 * Inform qgroup to trace all leaf items of data 154 * 155 * Return 0 for success 156 * Return <0 for error(ENOMEM) 157 */ 158 int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans, 159 struct btrfs_fs_info *fs_info, 160 struct extent_buffer *eb); 161 /* 162 * Inform qgroup to trace a whole subtree, including all its child tree 163 * blocks and data. 164 * The root tree block is specified by @root_eb. 165 * 166 * Normally used by relocation(tree block swap) and subvolume deletion. 167 * 168 * Return 0 for success 169 * Return <0 for error(ENOMEM or tree search error) 170 */ 171 int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans, 172 struct btrfs_root *root, 173 struct extent_buffer *root_eb, 174 u64 root_gen, int root_level); 175 int 176 btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, 177 struct btrfs_fs_info *fs_info, 178 u64 bytenr, u64 num_bytes, 179 struct ulist *old_roots, struct ulist *new_roots); 180 int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans, 181 struct btrfs_fs_info *fs_info); 182 int btrfs_run_qgroups(struct btrfs_trans_handle *trans, 183 struct btrfs_fs_info *fs_info); 184 int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, 185 struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid, 186 struct btrfs_qgroup_inherit *inherit); 187 void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info, 188 u64 ref_root, u64 num_bytes); 189 /* 190 * TODO: Add proper trace point for it, as btrfs_qgroup_free() is 191 * called by everywhere, can't provide good trace for delayed ref case. 192 */ 193 static inline void btrfs_qgroup_free_delayed_ref(struct btrfs_fs_info *fs_info, 194 u64 ref_root, u64 num_bytes) 195 { 196 btrfs_qgroup_free_refroot(fs_info, ref_root, num_bytes); 197 trace_btrfs_qgroup_free_delayed_ref(fs_info, ref_root, num_bytes); 198 } 199 void assert_qgroups_uptodate(struct btrfs_trans_handle *trans); 200 201 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS 202 int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid, 203 u64 rfer, u64 excl); 204 #endif 205 206 /* New io_tree based accurate qgroup reserve API */ 207 int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len); 208 int btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len); 209 int btrfs_qgroup_free_data(struct inode *inode, u64 start, u64 len); 210 211 int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, 212 bool enforce); 213 void btrfs_qgroup_free_meta_all(struct btrfs_root *root); 214 void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes); 215 void btrfs_qgroup_check_reserved_leak(struct inode *inode); 216 #endif /* __BTRFS_QGROUP__ */ 217