1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | |
3 | #ifndef BTRFS_BLOCK_RSV_H |
4 | #define BTRFS_BLOCK_RSV_H |
5 | |
6 | #include <linux/types.h> |
7 | #include <linux/compiler.h> |
8 | #include <linux/spinlock.h> |
9 | |
10 | struct btrfs_trans_handle; |
11 | struct btrfs_root; |
12 | struct btrfs_space_info; |
13 | struct btrfs_block_rsv; |
14 | struct btrfs_fs_info; |
15 | enum btrfs_reserve_flush_enum; |
16 | |
17 | /* |
18 | * Types of block reserves |
19 | */ |
20 | enum btrfs_rsv_type { |
21 | BTRFS_BLOCK_RSV_GLOBAL, |
22 | BTRFS_BLOCK_RSV_DELALLOC, |
23 | BTRFS_BLOCK_RSV_TRANS, |
24 | BTRFS_BLOCK_RSV_CHUNK, |
25 | BTRFS_BLOCK_RSV_DELOPS, |
26 | BTRFS_BLOCK_RSV_DELREFS, |
27 | BTRFS_BLOCK_RSV_EMPTY, |
28 | BTRFS_BLOCK_RSV_TEMP, |
29 | }; |
30 | |
31 | struct btrfs_block_rsv { |
32 | u64 size; |
33 | u64 reserved; |
34 | struct btrfs_space_info *space_info; |
35 | spinlock_t lock; |
36 | bool full; |
37 | bool failfast; |
38 | /* Block reserve type, one of BTRFS_BLOCK_RSV_* */ |
39 | enum btrfs_rsv_type type:8; |
40 | |
41 | /* |
42 | * Qgroup equivalent for @size @reserved |
43 | * |
44 | * Unlike normal @size/@reserved for inode rsv, qgroup doesn't care |
45 | * about things like csum size nor how many tree blocks it will need to |
46 | * reserve. |
47 | * |
48 | * Qgroup cares more about net change of the extent usage. |
49 | * |
50 | * So for one newly inserted file extent, in worst case it will cause |
51 | * leaf split and level increase, nodesize for each file extent is |
52 | * already too much. |
53 | * |
54 | * In short, qgroup_size/reserved is the upper limit of possible needed |
55 | * qgroup metadata reservation. |
56 | */ |
57 | u64 qgroup_rsv_size; |
58 | u64 qgroup_rsv_reserved; |
59 | }; |
60 | |
61 | void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, enum btrfs_rsv_type type); |
62 | void btrfs_init_root_block_rsv(struct btrfs_root *root); |
63 | struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_fs_info *fs_info, |
64 | enum btrfs_rsv_type type); |
65 | void btrfs_init_metadata_block_rsv(struct btrfs_fs_info *fs_info, |
66 | struct btrfs_block_rsv *rsv, |
67 | enum btrfs_rsv_type type); |
68 | void btrfs_free_block_rsv(struct btrfs_fs_info *fs_info, |
69 | struct btrfs_block_rsv *rsv); |
70 | int btrfs_block_rsv_add(struct btrfs_fs_info *fs_info, |
71 | struct btrfs_block_rsv *block_rsv, u64 num_bytes, |
72 | enum btrfs_reserve_flush_enum flush); |
73 | int btrfs_block_rsv_check(struct btrfs_block_rsv *block_rsv, int min_percent); |
74 | int btrfs_block_rsv_refill(struct btrfs_fs_info *fs_info, |
75 | struct btrfs_block_rsv *block_rsv, u64 num_bytes, |
76 | enum btrfs_reserve_flush_enum flush); |
77 | int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, |
78 | struct btrfs_block_rsv *dst_rsv, u64 num_bytes, |
79 | bool update_size); |
80 | int btrfs_block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, u64 num_bytes); |
81 | void btrfs_block_rsv_add_bytes(struct btrfs_block_rsv *block_rsv, |
82 | u64 num_bytes, bool update_size); |
83 | u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info, |
84 | struct btrfs_block_rsv *block_rsv, |
85 | u64 num_bytes, u64 *qgroup_to_release); |
86 | void btrfs_update_global_block_rsv(struct btrfs_fs_info *fs_info); |
87 | void btrfs_init_global_block_rsv(struct btrfs_fs_info *fs_info); |
88 | void btrfs_release_global_block_rsv(struct btrfs_fs_info *fs_info); |
89 | struct btrfs_block_rsv *btrfs_use_block_rsv(struct btrfs_trans_handle *trans, |
90 | struct btrfs_root *root, |
91 | u32 blocksize); |
92 | int btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info, |
93 | struct btrfs_block_rsv *rsv); |
94 | static inline void btrfs_unuse_block_rsv(struct btrfs_fs_info *fs_info, |
95 | struct btrfs_block_rsv *block_rsv, |
96 | u32 blocksize) |
97 | { |
98 | btrfs_block_rsv_add_bytes(block_rsv, num_bytes: blocksize, update_size: false); |
99 | btrfs_block_rsv_release(fs_info, block_rsv, num_bytes: 0, NULL); |
100 | } |
101 | |
102 | /* |
103 | * Fast path to check if the reserve is full, may be carefully used outside of |
104 | * locks. |
105 | */ |
106 | static inline bool btrfs_block_rsv_full(const struct btrfs_block_rsv *rsv) |
107 | { |
108 | return data_race(rsv->full); |
109 | } |
110 | |
111 | /* |
112 | * Get the reserved mount of a block reserve in a context where getting a stale |
113 | * value is acceptable, instead of accessing it directly and trigger data race |
114 | * warning from KCSAN. |
115 | */ |
116 | static inline u64 btrfs_block_rsv_reserved(struct btrfs_block_rsv *rsv) |
117 | { |
118 | u64 ret; |
119 | |
120 | spin_lock(lock: &rsv->lock); |
121 | ret = rsv->reserved; |
122 | spin_unlock(lock: &rsv->lock); |
123 | |
124 | return ret; |
125 | } |
126 | |
127 | /* |
128 | * Get the size of a block reserve in a context where getting a stale value is |
129 | * acceptable, instead of accessing it directly and trigger data race warning |
130 | * from KCSAN. |
131 | */ |
132 | static inline u64 btrfs_block_rsv_size(struct btrfs_block_rsv *rsv) |
133 | { |
134 | u64 ret; |
135 | |
136 | spin_lock(lock: &rsv->lock); |
137 | ret = rsv->size; |
138 | spin_unlock(lock: &rsv->lock); |
139 | |
140 | return ret; |
141 | } |
142 | |
143 | #endif /* BTRFS_BLOCK_RSV_H */ |
144 | |