| .. | .. |
|---|
| 79 | 79 | struct mutex mutex; |
|---|
| 80 | 80 | |
|---|
| 81 | 81 | spinlock_t lock; |
|---|
| 82 | | - struct rb_root ref_tree; |
|---|
| 82 | + struct rb_root_cached ref_tree; |
|---|
| 83 | 83 | /* accumulate add BTRFS_ADD_DELAYED_REF nodes to this ref_add_list. */ |
|---|
| 84 | 84 | struct list_head ref_add_list; |
|---|
| 85 | 85 | |
|---|
| .. | .. |
|---|
| 101 | 101 | * on disk reference count + ref_mod is accurate. |
|---|
| 102 | 102 | */ |
|---|
| 103 | 103 | int ref_mod; |
|---|
| 104 | | - |
|---|
| 105 | | - /* |
|---|
| 106 | | - * For qgroup reserved space freeing. |
|---|
| 107 | | - * |
|---|
| 108 | | - * ref_root and reserved will be recorded after |
|---|
| 109 | | - * BTRFS_ADD_DELAYED_EXTENT is called. |
|---|
| 110 | | - * And will be used to free reserved qgroup space at |
|---|
| 111 | | - * run_delayed_refs() time. |
|---|
| 112 | | - */ |
|---|
| 113 | | - u64 qgroup_ref_root; |
|---|
| 114 | | - u64 qgroup_reserved; |
|---|
| 115 | 104 | |
|---|
| 116 | 105 | /* |
|---|
| 117 | 106 | * when a new extent is allocated, it is just reserved in memory |
|---|
| .. | .. |
|---|
| 148 | 137 | |
|---|
| 149 | 138 | struct btrfs_delayed_ref_root { |
|---|
| 150 | 139 | /* head ref rbtree */ |
|---|
| 151 | | - struct rb_root href_root; |
|---|
| 140 | + struct rb_root_cached href_root; |
|---|
| 152 | 141 | |
|---|
| 153 | 142 | /* dirty extent records */ |
|---|
| 154 | 143 | struct rb_root dirty_extent_root; |
|---|
| .. | .. |
|---|
| 187 | 176 | u64 qgroup_to_skip; |
|---|
| 188 | 177 | }; |
|---|
| 189 | 178 | |
|---|
| 179 | +enum btrfs_ref_type { |
|---|
| 180 | + BTRFS_REF_NOT_SET, |
|---|
| 181 | + BTRFS_REF_DATA, |
|---|
| 182 | + BTRFS_REF_METADATA, |
|---|
| 183 | + BTRFS_REF_LAST, |
|---|
| 184 | +}; |
|---|
| 185 | + |
|---|
| 186 | +struct btrfs_data_ref { |
|---|
| 187 | + /* For EXTENT_DATA_REF */ |
|---|
| 188 | + |
|---|
| 189 | + /* Root which refers to this data extent */ |
|---|
| 190 | + u64 ref_root; |
|---|
| 191 | + |
|---|
| 192 | + /* Inode which refers to this data extent */ |
|---|
| 193 | + u64 ino; |
|---|
| 194 | + |
|---|
| 195 | + /* |
|---|
| 196 | + * file_offset - extent_offset |
|---|
| 197 | + * |
|---|
| 198 | + * file_offset is the key.offset of the EXTENT_DATA key. |
|---|
| 199 | + * extent_offset is btrfs_file_extent_offset() of the EXTENT_DATA data. |
|---|
| 200 | + */ |
|---|
| 201 | + u64 offset; |
|---|
| 202 | +}; |
|---|
| 203 | + |
|---|
| 204 | +struct btrfs_tree_ref { |
|---|
| 205 | + /* |
|---|
| 206 | + * Level of this tree block |
|---|
| 207 | + * |
|---|
| 208 | + * Shared for skinny (TREE_BLOCK_REF) and normal tree ref. |
|---|
| 209 | + */ |
|---|
| 210 | + int level; |
|---|
| 211 | + |
|---|
| 212 | + /* |
|---|
| 213 | + * Root which refers to this tree block. |
|---|
| 214 | + * |
|---|
| 215 | + * For TREE_BLOCK_REF (skinny metadata, either inline or keyed) |
|---|
| 216 | + */ |
|---|
| 217 | + u64 root; |
|---|
| 218 | + |
|---|
| 219 | + /* For non-skinny metadata, no special member needed */ |
|---|
| 220 | +}; |
|---|
| 221 | + |
|---|
| 222 | +struct btrfs_ref { |
|---|
| 223 | + enum btrfs_ref_type type; |
|---|
| 224 | + int action; |
|---|
| 225 | + |
|---|
| 226 | + /* |
|---|
| 227 | + * Whether this extent should go through qgroup record. |
|---|
| 228 | + * |
|---|
| 229 | + * Normally false, but for certain cases like delayed subtree scan, |
|---|
| 230 | + * setting this flag can hugely reduce qgroup overhead. |
|---|
| 231 | + */ |
|---|
| 232 | + bool skip_qgroup; |
|---|
| 233 | + |
|---|
| 234 | + /* |
|---|
| 235 | + * Optional. For which root is this modification. |
|---|
| 236 | + * Mostly used for qgroup optimization. |
|---|
| 237 | + * |
|---|
| 238 | + * When unset, data/tree ref init code will populate it. |
|---|
| 239 | + * In certain cases, we're modifying reference for a different root. |
|---|
| 240 | + * E.g. COW fs tree blocks for balance. |
|---|
| 241 | + * In that case, tree_ref::root will be fs tree, but we're doing this |
|---|
| 242 | + * for reloc tree, then we should set @real_root to reloc tree. |
|---|
| 243 | + */ |
|---|
| 244 | + u64 real_root; |
|---|
| 245 | + u64 bytenr; |
|---|
| 246 | + u64 len; |
|---|
| 247 | + |
|---|
| 248 | + /* Bytenr of the parent tree block */ |
|---|
| 249 | + u64 parent; |
|---|
| 250 | + union { |
|---|
| 251 | + struct btrfs_data_ref data_ref; |
|---|
| 252 | + struct btrfs_tree_ref tree_ref; |
|---|
| 253 | + }; |
|---|
| 254 | +}; |
|---|
| 255 | + |
|---|
| 190 | 256 | extern struct kmem_cache *btrfs_delayed_ref_head_cachep; |
|---|
| 191 | 257 | extern struct kmem_cache *btrfs_delayed_tree_ref_cachep; |
|---|
| 192 | 258 | extern struct kmem_cache *btrfs_delayed_data_ref_cachep; |
|---|
| .. | .. |
|---|
| 194 | 260 | |
|---|
| 195 | 261 | int __init btrfs_delayed_ref_init(void); |
|---|
| 196 | 262 | void __cold btrfs_delayed_ref_exit(void); |
|---|
| 263 | + |
|---|
| 264 | +static inline void btrfs_init_generic_ref(struct btrfs_ref *generic_ref, |
|---|
| 265 | + int action, u64 bytenr, u64 len, u64 parent) |
|---|
| 266 | +{ |
|---|
| 267 | + generic_ref->action = action; |
|---|
| 268 | + generic_ref->bytenr = bytenr; |
|---|
| 269 | + generic_ref->len = len; |
|---|
| 270 | + generic_ref->parent = parent; |
|---|
| 271 | +} |
|---|
| 272 | + |
|---|
| 273 | +static inline void btrfs_init_tree_ref(struct btrfs_ref *generic_ref, |
|---|
| 274 | + int level, u64 root) |
|---|
| 275 | +{ |
|---|
| 276 | + /* If @real_root not set, use @root as fallback */ |
|---|
| 277 | + if (!generic_ref->real_root) |
|---|
| 278 | + generic_ref->real_root = root; |
|---|
| 279 | + generic_ref->tree_ref.level = level; |
|---|
| 280 | + generic_ref->tree_ref.root = root; |
|---|
| 281 | + generic_ref->type = BTRFS_REF_METADATA; |
|---|
| 282 | +} |
|---|
| 283 | + |
|---|
| 284 | +static inline void btrfs_init_data_ref(struct btrfs_ref *generic_ref, |
|---|
| 285 | + u64 ref_root, u64 ino, u64 offset) |
|---|
| 286 | +{ |
|---|
| 287 | + /* If @real_root not set, use @root as fallback */ |
|---|
| 288 | + if (!generic_ref->real_root) |
|---|
| 289 | + generic_ref->real_root = ref_root; |
|---|
| 290 | + generic_ref->data_ref.ref_root = ref_root; |
|---|
| 291 | + generic_ref->data_ref.ino = ino; |
|---|
| 292 | + generic_ref->data_ref.offset = offset; |
|---|
| 293 | + generic_ref->type = BTRFS_REF_DATA; |
|---|
| 294 | +} |
|---|
| 197 | 295 | |
|---|
| 198 | 296 | static inline struct btrfs_delayed_extent_op * |
|---|
| 199 | 297 | btrfs_alloc_delayed_extent_op(void) |
|---|
| .. | .. |
|---|
| 228 | 326 | } |
|---|
| 229 | 327 | } |
|---|
| 230 | 328 | |
|---|
| 329 | +static inline u64 btrfs_ref_head_to_space_flags( |
|---|
| 330 | + struct btrfs_delayed_ref_head *head_ref) |
|---|
| 331 | +{ |
|---|
| 332 | + if (head_ref->is_data) |
|---|
| 333 | + return BTRFS_BLOCK_GROUP_DATA; |
|---|
| 334 | + else if (head_ref->is_system) |
|---|
| 335 | + return BTRFS_BLOCK_GROUP_SYSTEM; |
|---|
| 336 | + return BTRFS_BLOCK_GROUP_METADATA; |
|---|
| 337 | +} |
|---|
| 338 | + |
|---|
| 231 | 339 | static inline void btrfs_put_delayed_ref_head(struct btrfs_delayed_ref_head *head) |
|---|
| 232 | 340 | { |
|---|
| 233 | 341 | if (refcount_dec_and_test(&head->refs)) |
|---|
| .. | .. |
|---|
| 235 | 343 | } |
|---|
| 236 | 344 | |
|---|
| 237 | 345 | int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, |
|---|
| 238 | | - u64 bytenr, u64 num_bytes, u64 parent, |
|---|
| 239 | | - u64 ref_root, int level, int action, |
|---|
| 240 | | - struct btrfs_delayed_extent_op *extent_op, |
|---|
| 241 | | - int *old_ref_mod, int *new_ref_mod); |
|---|
| 346 | + struct btrfs_ref *generic_ref, |
|---|
| 347 | + struct btrfs_delayed_extent_op *extent_op); |
|---|
| 242 | 348 | int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, |
|---|
| 243 | | - u64 bytenr, u64 num_bytes, |
|---|
| 244 | | - u64 parent, u64 ref_root, |
|---|
| 245 | | - u64 owner, u64 offset, u64 reserved, int action, |
|---|
| 246 | | - int *old_ref_mod, int *new_ref_mod); |
|---|
| 247 | | -int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, |
|---|
| 248 | | - struct btrfs_trans_handle *trans, |
|---|
| 349 | + struct btrfs_ref *generic_ref, |
|---|
| 350 | + u64 reserved); |
|---|
| 351 | +int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, |
|---|
| 249 | 352 | u64 bytenr, u64 num_bytes, |
|---|
| 250 | 353 | struct btrfs_delayed_extent_op *extent_op); |
|---|
| 251 | 354 | void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans, |
|---|
| .. | .. |
|---|
| 255 | 358 | struct btrfs_delayed_ref_head * |
|---|
| 256 | 359 | btrfs_find_delayed_ref_head(struct btrfs_delayed_ref_root *delayed_refs, |
|---|
| 257 | 360 | u64 bytenr); |
|---|
| 258 | | -int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans, |
|---|
| 361 | +int btrfs_delayed_ref_lock(struct btrfs_delayed_ref_root *delayed_refs, |
|---|
| 259 | 362 | struct btrfs_delayed_ref_head *head); |
|---|
| 260 | 363 | static inline void btrfs_delayed_ref_unlock(struct btrfs_delayed_ref_head *head) |
|---|
| 261 | 364 | { |
|---|
| 262 | 365 | mutex_unlock(&head->mutex); |
|---|
| 263 | 366 | } |
|---|
| 367 | +void btrfs_delete_ref_head(struct btrfs_delayed_ref_root *delayed_refs, |
|---|
| 368 | + struct btrfs_delayed_ref_head *head); |
|---|
| 264 | 369 | |
|---|
| 265 | | - |
|---|
| 266 | | -struct btrfs_delayed_ref_head * |
|---|
| 267 | | -btrfs_select_ref_head(struct btrfs_trans_handle *trans); |
|---|
| 370 | +struct btrfs_delayed_ref_head *btrfs_select_ref_head( |
|---|
| 371 | + struct btrfs_delayed_ref_root *delayed_refs); |
|---|
| 268 | 372 | |
|---|
| 269 | 373 | int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, u64 seq); |
|---|
| 270 | 374 | |
|---|
| 375 | +void btrfs_delayed_refs_rsv_release(struct btrfs_fs_info *fs_info, int nr); |
|---|
| 376 | +void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans); |
|---|
| 377 | +int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, |
|---|
| 378 | + enum btrfs_reserve_flush_enum flush); |
|---|
| 379 | +void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, |
|---|
| 380 | + struct btrfs_block_rsv *src, |
|---|
| 381 | + u64 num_bytes); |
|---|
| 382 | +int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans); |
|---|
| 383 | +bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info); |
|---|
| 384 | + |
|---|
| 271 | 385 | /* |
|---|
| 272 | 386 | * helper functions to cast a node into its container |
|---|
| 273 | 387 | */ |
|---|