162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2014 Facebook. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef BTRFS_QGROUP_H 762306a36Sopenharmony_ci#define BTRFS_QGROUP_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/spinlock.h> 1062306a36Sopenharmony_ci#include <linux/rbtree.h> 1162306a36Sopenharmony_ci#include <linux/kobject.h> 1262306a36Sopenharmony_ci#include "ulist.h" 1362306a36Sopenharmony_ci#include "delayed-ref.h" 1462306a36Sopenharmony_ci#include "misc.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* 1762306a36Sopenharmony_ci * Btrfs qgroup overview 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * Btrfs qgroup splits into 3 main part: 2062306a36Sopenharmony_ci * 1) Reserve 2162306a36Sopenharmony_ci * Reserve metadata/data space for incoming operations 2262306a36Sopenharmony_ci * Affect how qgroup limit works 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * 2) Trace 2562306a36Sopenharmony_ci * Tell btrfs qgroup to trace dirty extents. 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * Dirty extents including: 2862306a36Sopenharmony_ci * - Newly allocated extents 2962306a36Sopenharmony_ci * - Extents going to be deleted (in this trans) 3062306a36Sopenharmony_ci * - Extents whose owner is going to be modified 3162306a36Sopenharmony_ci * 3262306a36Sopenharmony_ci * This is the main part affects whether qgroup numbers will stay 3362306a36Sopenharmony_ci * consistent. 3462306a36Sopenharmony_ci * Btrfs qgroup can trace clean extents and won't cause any problem, 3562306a36Sopenharmony_ci * but it will consume extra CPU time, it should be avoided if possible. 3662306a36Sopenharmony_ci * 3762306a36Sopenharmony_ci * 3) Account 3862306a36Sopenharmony_ci * Btrfs qgroup will updates its numbers, based on dirty extents traced 3962306a36Sopenharmony_ci * in previous step. 4062306a36Sopenharmony_ci * 4162306a36Sopenharmony_ci * Normally at qgroup rescan and transaction commit time. 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* 4562306a36Sopenharmony_ci * Special performance optimization for balance. 4662306a36Sopenharmony_ci * 4762306a36Sopenharmony_ci * For balance, we need to swap subtree of subvolume and reloc trees. 4862306a36Sopenharmony_ci * In theory, we need to trace all subtree blocks of both subvolume and reloc 4962306a36Sopenharmony_ci * trees, since their owner has changed during such swap. 5062306a36Sopenharmony_ci * 5162306a36Sopenharmony_ci * However since balance has ensured that both subtrees are containing the 5262306a36Sopenharmony_ci * same contents and have the same tree structures, such swap won't cause 5362306a36Sopenharmony_ci * qgroup number change. 5462306a36Sopenharmony_ci * 5562306a36Sopenharmony_ci * But there is a race window between subtree swap and transaction commit, 5662306a36Sopenharmony_ci * during that window, if we increase/decrease tree level or merge/split tree 5762306a36Sopenharmony_ci * blocks, we still need to trace the original subtrees. 5862306a36Sopenharmony_ci * 5962306a36Sopenharmony_ci * So for balance, we use a delayed subtree tracing, whose workflow is: 6062306a36Sopenharmony_ci * 6162306a36Sopenharmony_ci * 1) Record the subtree root block get swapped. 6262306a36Sopenharmony_ci * 6362306a36Sopenharmony_ci * During subtree swap: 6462306a36Sopenharmony_ci * O = Old tree blocks 6562306a36Sopenharmony_ci * N = New tree blocks 6662306a36Sopenharmony_ci * reloc tree subvolume tree X 6762306a36Sopenharmony_ci * Root Root 6862306a36Sopenharmony_ci * / \ / \ 6962306a36Sopenharmony_ci * NA OB OA OB 7062306a36Sopenharmony_ci * / | | \ / | | \ 7162306a36Sopenharmony_ci * NC ND OE OF OC OD OE OF 7262306a36Sopenharmony_ci * 7362306a36Sopenharmony_ci * In this case, NA and OA are going to be swapped, record (NA, OA) into 7462306a36Sopenharmony_ci * subvolume tree X. 7562306a36Sopenharmony_ci * 7662306a36Sopenharmony_ci * 2) After subtree swap. 7762306a36Sopenharmony_ci * reloc tree subvolume tree X 7862306a36Sopenharmony_ci * Root Root 7962306a36Sopenharmony_ci * / \ / \ 8062306a36Sopenharmony_ci * OA OB NA OB 8162306a36Sopenharmony_ci * / | | \ / | | \ 8262306a36Sopenharmony_ci * OC OD OE OF NC ND OE OF 8362306a36Sopenharmony_ci * 8462306a36Sopenharmony_ci * 3a) COW happens for OB 8562306a36Sopenharmony_ci * If we are going to COW tree block OB, we check OB's bytenr against 8662306a36Sopenharmony_ci * tree X's swapped_blocks structure. 8762306a36Sopenharmony_ci * If it doesn't fit any, nothing will happen. 8862306a36Sopenharmony_ci * 8962306a36Sopenharmony_ci * 3b) COW happens for NA 9062306a36Sopenharmony_ci * Check NA's bytenr against tree X's swapped_blocks, and get a hit. 9162306a36Sopenharmony_ci * Then we do subtree scan on both subtrees OA and NA. 9262306a36Sopenharmony_ci * Resulting 6 tree blocks to be scanned (OA, OC, OD, NA, NC, ND). 9362306a36Sopenharmony_ci * 9462306a36Sopenharmony_ci * Then no matter what we do to subvolume tree X, qgroup numbers will 9562306a36Sopenharmony_ci * still be correct. 9662306a36Sopenharmony_ci * Then NA's record gets removed from X's swapped_blocks. 9762306a36Sopenharmony_ci * 9862306a36Sopenharmony_ci * 4) Transaction commit 9962306a36Sopenharmony_ci * Any record in X's swapped_blocks gets removed, since there is no 10062306a36Sopenharmony_ci * modification to the swapped subtrees, no need to trigger heavy qgroup 10162306a36Sopenharmony_ci * subtree rescan for them. 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci#define BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN (1UL << 3) 10562306a36Sopenharmony_ci#define BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING (1UL << 4) 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/* 10862306a36Sopenharmony_ci * Record a dirty extent, and info qgroup to update quota on it 10962306a36Sopenharmony_ci * TODO: Use kmem cache to alloc it. 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_cistruct btrfs_qgroup_extent_record { 11262306a36Sopenharmony_ci struct rb_node node; 11362306a36Sopenharmony_ci u64 bytenr; 11462306a36Sopenharmony_ci u64 num_bytes; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci /* 11762306a36Sopenharmony_ci * For qgroup reserved data space freeing. 11862306a36Sopenharmony_ci * 11962306a36Sopenharmony_ci * @data_rsv_refroot and @data_rsv will be recorded after 12062306a36Sopenharmony_ci * BTRFS_ADD_DELAYED_EXTENT is called. 12162306a36Sopenharmony_ci * And will be used to free reserved qgroup space at 12262306a36Sopenharmony_ci * transaction commit time. 12362306a36Sopenharmony_ci */ 12462306a36Sopenharmony_ci u32 data_rsv; /* reserved data space needs to be freed */ 12562306a36Sopenharmony_ci u64 data_rsv_refroot; /* which root the reserved data belongs to */ 12662306a36Sopenharmony_ci struct ulist *old_roots; 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistruct btrfs_qgroup_swapped_block { 13062306a36Sopenharmony_ci struct rb_node node; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci int level; 13362306a36Sopenharmony_ci bool trace_leaf; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci /* bytenr/generation of the tree block in subvolume tree after swap */ 13662306a36Sopenharmony_ci u64 subvol_bytenr; 13762306a36Sopenharmony_ci u64 subvol_generation; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci /* bytenr/generation of the tree block in reloc tree after swap */ 14062306a36Sopenharmony_ci u64 reloc_bytenr; 14162306a36Sopenharmony_ci u64 reloc_generation; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci u64 last_snapshot; 14462306a36Sopenharmony_ci struct btrfs_key first_key; 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci/* 14862306a36Sopenharmony_ci * Qgroup reservation types: 14962306a36Sopenharmony_ci * 15062306a36Sopenharmony_ci * DATA: 15162306a36Sopenharmony_ci * space reserved for data 15262306a36Sopenharmony_ci * 15362306a36Sopenharmony_ci * META_PERTRANS: 15462306a36Sopenharmony_ci * Space reserved for metadata (per-transaction) 15562306a36Sopenharmony_ci * Due to the fact that qgroup data is only updated at transaction commit 15662306a36Sopenharmony_ci * time, reserved space for metadata must be kept until transaction 15762306a36Sopenharmony_ci * commits. 15862306a36Sopenharmony_ci * Any metadata reserved that are used in btrfs_start_transaction() should 15962306a36Sopenharmony_ci * be of this type. 16062306a36Sopenharmony_ci * 16162306a36Sopenharmony_ci * META_PREALLOC: 16262306a36Sopenharmony_ci * There are cases where metadata space is reserved before starting 16362306a36Sopenharmony_ci * transaction, and then btrfs_join_transaction() to get a trans handle. 16462306a36Sopenharmony_ci * Any metadata reserved for such usage should be of this type. 16562306a36Sopenharmony_ci * And after join_transaction() part (or all) of such reservation should 16662306a36Sopenharmony_ci * be converted into META_PERTRANS. 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_cienum btrfs_qgroup_rsv_type { 16962306a36Sopenharmony_ci BTRFS_QGROUP_RSV_DATA, 17062306a36Sopenharmony_ci BTRFS_QGROUP_RSV_META_PERTRANS, 17162306a36Sopenharmony_ci BTRFS_QGROUP_RSV_META_PREALLOC, 17262306a36Sopenharmony_ci BTRFS_QGROUP_RSV_LAST, 17362306a36Sopenharmony_ci}; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci/* 17662306a36Sopenharmony_ci * Represents how many bytes we have reserved for this qgroup. 17762306a36Sopenharmony_ci * 17862306a36Sopenharmony_ci * Each type should have different reservation behavior. 17962306a36Sopenharmony_ci * E.g, data follows its io_tree flag modification, while 18062306a36Sopenharmony_ci * *currently* meta is just reserve-and-clear during transaction. 18162306a36Sopenharmony_ci * 18262306a36Sopenharmony_ci * TODO: Add new type for reservation which can survive transaction commit. 18362306a36Sopenharmony_ci * Current metadata reservation behavior is not suitable for such case. 18462306a36Sopenharmony_ci */ 18562306a36Sopenharmony_cistruct btrfs_qgroup_rsv { 18662306a36Sopenharmony_ci u64 values[BTRFS_QGROUP_RSV_LAST]; 18762306a36Sopenharmony_ci}; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci/* 19062306a36Sopenharmony_ci * one struct for each qgroup, organized in fs_info->qgroup_tree. 19162306a36Sopenharmony_ci */ 19262306a36Sopenharmony_cistruct btrfs_qgroup { 19362306a36Sopenharmony_ci u64 qgroupid; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci /* 19662306a36Sopenharmony_ci * state 19762306a36Sopenharmony_ci */ 19862306a36Sopenharmony_ci u64 rfer; /* referenced */ 19962306a36Sopenharmony_ci u64 rfer_cmpr; /* referenced compressed */ 20062306a36Sopenharmony_ci u64 excl; /* exclusive */ 20162306a36Sopenharmony_ci u64 excl_cmpr; /* exclusive compressed */ 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci /* 20462306a36Sopenharmony_ci * limits 20562306a36Sopenharmony_ci */ 20662306a36Sopenharmony_ci u64 lim_flags; /* which limits are set */ 20762306a36Sopenharmony_ci u64 max_rfer; 20862306a36Sopenharmony_ci u64 max_excl; 20962306a36Sopenharmony_ci u64 rsv_rfer; 21062306a36Sopenharmony_ci u64 rsv_excl; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci /* 21362306a36Sopenharmony_ci * reservation tracking 21462306a36Sopenharmony_ci */ 21562306a36Sopenharmony_ci struct btrfs_qgroup_rsv rsv; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* 21862306a36Sopenharmony_ci * lists 21962306a36Sopenharmony_ci */ 22062306a36Sopenharmony_ci struct list_head groups; /* groups this group is member of */ 22162306a36Sopenharmony_ci struct list_head members; /* groups that are members of this group */ 22262306a36Sopenharmony_ci struct list_head dirty; /* dirty groups */ 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci /* 22562306a36Sopenharmony_ci * For qgroup iteration usage. 22662306a36Sopenharmony_ci * 22762306a36Sopenharmony_ci * The iteration list should always be empty until qgroup_iterator_add() 22862306a36Sopenharmony_ci * is called. And should be reset to empty after the iteration is 22962306a36Sopenharmony_ci * finished. 23062306a36Sopenharmony_ci */ 23162306a36Sopenharmony_ci struct list_head iterator; 23262306a36Sopenharmony_ci struct rb_node node; /* tree of qgroups */ 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci /* 23562306a36Sopenharmony_ci * temp variables for accounting operations 23662306a36Sopenharmony_ci * Refer to qgroup_shared_accounting() for details. 23762306a36Sopenharmony_ci */ 23862306a36Sopenharmony_ci u64 old_refcnt; 23962306a36Sopenharmony_ci u64 new_refcnt; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci /* 24262306a36Sopenharmony_ci * Sysfs kobjectid 24362306a36Sopenharmony_ci */ 24462306a36Sopenharmony_ci struct kobject kobj; 24562306a36Sopenharmony_ci}; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cistatic inline u64 btrfs_qgroup_subvolid(u64 qgroupid) 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci return (qgroupid & ((1ULL << BTRFS_QGROUP_LEVEL_SHIFT) - 1)); 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci/* 25362306a36Sopenharmony_ci * For qgroup event trace points only 25462306a36Sopenharmony_ci */ 25562306a36Sopenharmony_cienum { 25662306a36Sopenharmony_ci ENUM_BIT(QGROUP_RESERVE), 25762306a36Sopenharmony_ci ENUM_BIT(QGROUP_RELEASE), 25862306a36Sopenharmony_ci ENUM_BIT(QGROUP_FREE), 25962306a36Sopenharmony_ci}; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ciint btrfs_quota_enable(struct btrfs_fs_info *fs_info); 26262306a36Sopenharmony_ciint btrfs_quota_disable(struct btrfs_fs_info *fs_info); 26362306a36Sopenharmony_ciint btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); 26462306a36Sopenharmony_civoid btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info); 26562306a36Sopenharmony_ciint btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info, 26662306a36Sopenharmony_ci bool interruptible); 26762306a36Sopenharmony_ciint btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, 26862306a36Sopenharmony_ci u64 dst); 26962306a36Sopenharmony_ciint btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, 27062306a36Sopenharmony_ci u64 dst); 27162306a36Sopenharmony_ciint btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid); 27262306a36Sopenharmony_ciint btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid); 27362306a36Sopenharmony_ciint btrfs_limit_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid, 27462306a36Sopenharmony_ci struct btrfs_qgroup_limit *limit); 27562306a36Sopenharmony_ciint btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info); 27662306a36Sopenharmony_civoid btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info); 27762306a36Sopenharmony_cistruct btrfs_delayed_extent_op; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci/* 28062306a36Sopenharmony_ci * Inform qgroup to trace one dirty extent, its info is recorded in @record. 28162306a36Sopenharmony_ci * So qgroup can account it at transaction committing time. 28262306a36Sopenharmony_ci * 28362306a36Sopenharmony_ci * No lock version, caller must acquire delayed ref lock and allocated memory, 28462306a36Sopenharmony_ci * then call btrfs_qgroup_trace_extent_post() after exiting lock context. 28562306a36Sopenharmony_ci * 28662306a36Sopenharmony_ci * Return 0 for success insert 28762306a36Sopenharmony_ci * Return >0 for existing record, caller can free @record safely. 28862306a36Sopenharmony_ci * Error is not possible 28962306a36Sopenharmony_ci */ 29062306a36Sopenharmony_ciint btrfs_qgroup_trace_extent_nolock( 29162306a36Sopenharmony_ci struct btrfs_fs_info *fs_info, 29262306a36Sopenharmony_ci struct btrfs_delayed_ref_root *delayed_refs, 29362306a36Sopenharmony_ci struct btrfs_qgroup_extent_record *record); 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci/* 29662306a36Sopenharmony_ci * Post handler after qgroup_trace_extent_nolock(). 29762306a36Sopenharmony_ci * 29862306a36Sopenharmony_ci * NOTE: Current qgroup does the expensive backref walk at transaction 29962306a36Sopenharmony_ci * committing time with TRANS_STATE_COMMIT_DOING, this blocks incoming 30062306a36Sopenharmony_ci * new transaction. 30162306a36Sopenharmony_ci * This is designed to allow btrfs_find_all_roots() to get correct new_roots 30262306a36Sopenharmony_ci * result. 30362306a36Sopenharmony_ci * 30462306a36Sopenharmony_ci * However for old_roots there is no need to do backref walk at that time, 30562306a36Sopenharmony_ci * since we search commit roots to walk backref and result will always be 30662306a36Sopenharmony_ci * correct. 30762306a36Sopenharmony_ci * 30862306a36Sopenharmony_ci * Due to the nature of no lock version, we can't do backref there. 30962306a36Sopenharmony_ci * So we must call btrfs_qgroup_trace_extent_post() after exiting 31062306a36Sopenharmony_ci * spinlock context. 31162306a36Sopenharmony_ci * 31262306a36Sopenharmony_ci * TODO: If we can fix and prove btrfs_find_all_roots() can get correct result 31362306a36Sopenharmony_ci * using current root, then we can move all expensive backref walk out of 31462306a36Sopenharmony_ci * transaction committing, but not now as qgroup accounting will be wrong again. 31562306a36Sopenharmony_ci */ 31662306a36Sopenharmony_ciint btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle *trans, 31762306a36Sopenharmony_ci struct btrfs_qgroup_extent_record *qrecord); 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci/* 32062306a36Sopenharmony_ci * Inform qgroup to trace one dirty extent, specified by @bytenr and 32162306a36Sopenharmony_ci * @num_bytes. 32262306a36Sopenharmony_ci * So qgroup can account it at commit trans time. 32362306a36Sopenharmony_ci * 32462306a36Sopenharmony_ci * Better encapsulated version, with memory allocation and backref walk for 32562306a36Sopenharmony_ci * commit roots. 32662306a36Sopenharmony_ci * So this can sleep. 32762306a36Sopenharmony_ci * 32862306a36Sopenharmony_ci * Return 0 if the operation is done. 32962306a36Sopenharmony_ci * Return <0 for error, like memory allocation failure or invalid parameter 33062306a36Sopenharmony_ci * (NULL trans) 33162306a36Sopenharmony_ci */ 33262306a36Sopenharmony_ciint btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr, 33362306a36Sopenharmony_ci u64 num_bytes); 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci/* 33662306a36Sopenharmony_ci * Inform qgroup to trace all leaf items of data 33762306a36Sopenharmony_ci * 33862306a36Sopenharmony_ci * Return 0 for success 33962306a36Sopenharmony_ci * Return <0 for error(ENOMEM) 34062306a36Sopenharmony_ci */ 34162306a36Sopenharmony_ciint btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans, 34262306a36Sopenharmony_ci struct extent_buffer *eb); 34362306a36Sopenharmony_ci/* 34462306a36Sopenharmony_ci * Inform qgroup to trace a whole subtree, including all its child tree 34562306a36Sopenharmony_ci * blocks and data. 34662306a36Sopenharmony_ci * The root tree block is specified by @root_eb. 34762306a36Sopenharmony_ci * 34862306a36Sopenharmony_ci * Normally used by relocation(tree block swap) and subvolume deletion. 34962306a36Sopenharmony_ci * 35062306a36Sopenharmony_ci * Return 0 for success 35162306a36Sopenharmony_ci * Return <0 for error(ENOMEM or tree search error) 35262306a36Sopenharmony_ci */ 35362306a36Sopenharmony_ciint btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans, 35462306a36Sopenharmony_ci struct extent_buffer *root_eb, 35562306a36Sopenharmony_ci u64 root_gen, int root_level); 35662306a36Sopenharmony_ciint btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, u64 bytenr, 35762306a36Sopenharmony_ci u64 num_bytes, struct ulist *old_roots, 35862306a36Sopenharmony_ci struct ulist *new_roots); 35962306a36Sopenharmony_ciint btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans); 36062306a36Sopenharmony_ciint btrfs_run_qgroups(struct btrfs_trans_handle *trans); 36162306a36Sopenharmony_ciint btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, 36262306a36Sopenharmony_ci u64 objectid, struct btrfs_qgroup_inherit *inherit); 36362306a36Sopenharmony_civoid btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info, 36462306a36Sopenharmony_ci u64 ref_root, u64 num_bytes, 36562306a36Sopenharmony_ci enum btrfs_qgroup_rsv_type type); 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS 36862306a36Sopenharmony_ciint btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid, 36962306a36Sopenharmony_ci u64 rfer, u64 excl); 37062306a36Sopenharmony_ci#endif 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci/* New io_tree based accurate qgroup reserve API */ 37362306a36Sopenharmony_ciint btrfs_qgroup_reserve_data(struct btrfs_inode *inode, 37462306a36Sopenharmony_ci struct extent_changeset **reserved, u64 start, u64 len); 37562306a36Sopenharmony_ciint btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len, u64 *released); 37662306a36Sopenharmony_ciint btrfs_qgroup_free_data(struct btrfs_inode *inode, 37762306a36Sopenharmony_ci struct extent_changeset *reserved, u64 start, 37862306a36Sopenharmony_ci u64 len, u64 *freed); 37962306a36Sopenharmony_ciint btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, 38062306a36Sopenharmony_ci enum btrfs_qgroup_rsv_type type, bool enforce); 38162306a36Sopenharmony_ciint __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, 38262306a36Sopenharmony_ci enum btrfs_qgroup_rsv_type type, bool enforce, 38362306a36Sopenharmony_ci bool noflush); 38462306a36Sopenharmony_ci/* Reserve metadata space for pertrans and prealloc type */ 38562306a36Sopenharmony_cistatic inline int btrfs_qgroup_reserve_meta_pertrans(struct btrfs_root *root, 38662306a36Sopenharmony_ci int num_bytes, bool enforce) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci return __btrfs_qgroup_reserve_meta(root, num_bytes, 38962306a36Sopenharmony_ci BTRFS_QGROUP_RSV_META_PERTRANS, 39062306a36Sopenharmony_ci enforce, false); 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_cistatic inline int btrfs_qgroup_reserve_meta_prealloc(struct btrfs_root *root, 39362306a36Sopenharmony_ci int num_bytes, bool enforce, 39462306a36Sopenharmony_ci bool noflush) 39562306a36Sopenharmony_ci{ 39662306a36Sopenharmony_ci return __btrfs_qgroup_reserve_meta(root, num_bytes, 39762306a36Sopenharmony_ci BTRFS_QGROUP_RSV_META_PREALLOC, 39862306a36Sopenharmony_ci enforce, noflush); 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_civoid __btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes, 40262306a36Sopenharmony_ci enum btrfs_qgroup_rsv_type type); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci/* Free per-transaction meta reservation for error handling */ 40562306a36Sopenharmony_cistatic inline void btrfs_qgroup_free_meta_pertrans(struct btrfs_root *root, 40662306a36Sopenharmony_ci int num_bytes) 40762306a36Sopenharmony_ci{ 40862306a36Sopenharmony_ci __btrfs_qgroup_free_meta(root, num_bytes, 40962306a36Sopenharmony_ci BTRFS_QGROUP_RSV_META_PERTRANS); 41062306a36Sopenharmony_ci} 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci/* Pre-allocated meta reservation can be freed at need */ 41362306a36Sopenharmony_cistatic inline void btrfs_qgroup_free_meta_prealloc(struct btrfs_root *root, 41462306a36Sopenharmony_ci int num_bytes) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci __btrfs_qgroup_free_meta(root, num_bytes, 41762306a36Sopenharmony_ci BTRFS_QGROUP_RSV_META_PREALLOC); 41862306a36Sopenharmony_ci} 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci/* 42162306a36Sopenharmony_ci * Per-transaction meta reservation should be all freed at transaction commit 42262306a36Sopenharmony_ci * time 42362306a36Sopenharmony_ci */ 42462306a36Sopenharmony_civoid btrfs_qgroup_free_meta_all_pertrans(struct btrfs_root *root); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci/* 42762306a36Sopenharmony_ci * Convert @num_bytes of META_PREALLOCATED reservation to META_PERTRANS. 42862306a36Sopenharmony_ci * 42962306a36Sopenharmony_ci * This is called when preallocated meta reservation needs to be used. 43062306a36Sopenharmony_ci * Normally after btrfs_join_transaction() call. 43162306a36Sopenharmony_ci */ 43262306a36Sopenharmony_civoid btrfs_qgroup_convert_reserved_meta(struct btrfs_root *root, int num_bytes); 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_civoid btrfs_qgroup_check_reserved_leak(struct btrfs_inode *inode); 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci/* btrfs_qgroup_swapped_blocks related functions */ 43762306a36Sopenharmony_civoid btrfs_qgroup_init_swapped_blocks( 43862306a36Sopenharmony_ci struct btrfs_qgroup_swapped_blocks *swapped_blocks); 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_civoid btrfs_qgroup_clean_swapped_blocks(struct btrfs_root *root); 44162306a36Sopenharmony_ciint btrfs_qgroup_add_swapped_blocks(struct btrfs_trans_handle *trans, 44262306a36Sopenharmony_ci struct btrfs_root *subvol_root, 44362306a36Sopenharmony_ci struct btrfs_block_group *bg, 44462306a36Sopenharmony_ci struct extent_buffer *subvol_parent, int subvol_slot, 44562306a36Sopenharmony_ci struct extent_buffer *reloc_parent, int reloc_slot, 44662306a36Sopenharmony_ci u64 last_snapshot); 44762306a36Sopenharmony_ciint btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans, 44862306a36Sopenharmony_ci struct btrfs_root *root, struct extent_buffer *eb); 44962306a36Sopenharmony_civoid btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans); 45062306a36Sopenharmony_cibool btrfs_check_quota_leak(struct btrfs_fs_info *fs_info); 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci#endif 453