xref: /openbmc/linux/fs/btrfs/block-rsv.h (revision 5ee9cd065836e5934710ca35653bce7905add20b)
1d12ffdd1SJosef Bacik /* SPDX-License-Identifier: GPL-2.0 */
2d12ffdd1SJosef Bacik 
3d12ffdd1SJosef Bacik #ifndef BTRFS_BLOCK_RSV_H
4d12ffdd1SJosef Bacik #define BTRFS_BLOCK_RSV_H
5d12ffdd1SJosef Bacik 
667f9c220SJosef Bacik struct btrfs_trans_handle;
73683fbbcSJosef Bacik struct btrfs_root;
8d12ffdd1SJosef Bacik enum btrfs_reserve_flush_enum;
9d12ffdd1SJosef Bacik 
10d12ffdd1SJosef Bacik /*
11d12ffdd1SJosef Bacik  * Types of block reserves
12d12ffdd1SJosef Bacik  */
138bfc9b2cSDavid Sterba enum btrfs_rsv_type {
14d12ffdd1SJosef Bacik 	BTRFS_BLOCK_RSV_GLOBAL,
15d12ffdd1SJosef Bacik 	BTRFS_BLOCK_RSV_DELALLOC,
16d12ffdd1SJosef Bacik 	BTRFS_BLOCK_RSV_TRANS,
17d12ffdd1SJosef Bacik 	BTRFS_BLOCK_RSV_CHUNK,
18d12ffdd1SJosef Bacik 	BTRFS_BLOCK_RSV_DELOPS,
19d12ffdd1SJosef Bacik 	BTRFS_BLOCK_RSV_DELREFS,
20d12ffdd1SJosef Bacik 	BTRFS_BLOCK_RSV_EMPTY,
21d12ffdd1SJosef Bacik 	BTRFS_BLOCK_RSV_TEMP,
22d12ffdd1SJosef Bacik };
23d12ffdd1SJosef Bacik 
24d12ffdd1SJosef Bacik struct btrfs_block_rsv {
25d12ffdd1SJosef Bacik 	u64 size;
26d12ffdd1SJosef Bacik 	u64 reserved;
27d12ffdd1SJosef Bacik 	struct btrfs_space_info *space_info;
28d12ffdd1SJosef Bacik 	spinlock_t lock;
29c70c2c5bSDavid Sterba 	bool full;
30710d5921SDavid Sterba 	bool failfast;
318bfc9b2cSDavid Sterba 	/* Block reserve type, one of BTRFS_BLOCK_RSV_* */
328bfc9b2cSDavid Sterba 	enum btrfs_rsv_type type:8;
33d12ffdd1SJosef Bacik 
34d12ffdd1SJosef Bacik 	/*
35d12ffdd1SJosef Bacik 	 * Qgroup equivalent for @size @reserved
36d12ffdd1SJosef Bacik 	 *
37d12ffdd1SJosef Bacik 	 * Unlike normal @size/@reserved for inode rsv, qgroup doesn't care
38d12ffdd1SJosef Bacik 	 * about things like csum size nor how many tree blocks it will need to
39d12ffdd1SJosef Bacik 	 * reserve.
40d12ffdd1SJosef Bacik 	 *
41d12ffdd1SJosef Bacik 	 * Qgroup cares more about net change of the extent usage.
42d12ffdd1SJosef Bacik 	 *
43d12ffdd1SJosef Bacik 	 * So for one newly inserted file extent, in worst case it will cause
44d12ffdd1SJosef Bacik 	 * leaf split and level increase, nodesize for each file extent is
45d12ffdd1SJosef Bacik 	 * already too much.
46d12ffdd1SJosef Bacik 	 *
47d12ffdd1SJosef Bacik 	 * In short, qgroup_size/reserved is the upper limit of possible needed
48d12ffdd1SJosef Bacik 	 * qgroup metadata reservation.
49d12ffdd1SJosef Bacik 	 */
50d12ffdd1SJosef Bacik 	u64 qgroup_rsv_size;
51d12ffdd1SJosef Bacik 	u64 qgroup_rsv_reserved;
52d12ffdd1SJosef Bacik };
53d12ffdd1SJosef Bacik 
548bfc9b2cSDavid Sterba void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, enum btrfs_rsv_type type);
552e608bd1SJosef Bacik void btrfs_init_root_block_rsv(struct btrfs_root *root);
56d12ffdd1SJosef Bacik struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_fs_info *fs_info,
578bfc9b2cSDavid Sterba 					      enum btrfs_rsv_type type);
58d12ffdd1SJosef Bacik void btrfs_init_metadata_block_rsv(struct btrfs_fs_info *fs_info,
59d12ffdd1SJosef Bacik 				   struct btrfs_block_rsv *rsv,
608bfc9b2cSDavid Sterba 				   enum btrfs_rsv_type type);
61d12ffdd1SJosef Bacik void btrfs_free_block_rsv(struct btrfs_fs_info *fs_info,
62d12ffdd1SJosef Bacik 			  struct btrfs_block_rsv *rsv);
639270501cSJosef Bacik int btrfs_block_rsv_add(struct btrfs_fs_info *fs_info,
64d12ffdd1SJosef Bacik 			struct btrfs_block_rsv *block_rsv, u64 num_bytes,
65d12ffdd1SJosef Bacik 			enum btrfs_reserve_flush_enum flush);
66428c8e03SDavid Sterba int btrfs_block_rsv_check(struct btrfs_block_rsv *block_rsv, int min_percent);
679270501cSJosef Bacik int btrfs_block_rsv_refill(struct btrfs_fs_info *fs_info,
684e8313e5SFilipe Manana 			   struct btrfs_block_rsv *block_rsv, u64 num_bytes,
69d12ffdd1SJosef Bacik 			   enum btrfs_reserve_flush_enum flush);
70d12ffdd1SJosef Bacik int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
71d12ffdd1SJosef Bacik 			    struct btrfs_block_rsv *dst_rsv, u64 num_bytes,
72d12ffdd1SJosef Bacik 			    bool update_size);
73d12ffdd1SJosef Bacik int btrfs_block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, u64 num_bytes);
740b50174aSJosef Bacik void btrfs_block_rsv_add_bytes(struct btrfs_block_rsv *block_rsv,
750b50174aSJosef Bacik 			       u64 num_bytes, bool update_size);
7663f018beSNikolay Borisov u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
77fed14b32SJosef Bacik 			      struct btrfs_block_rsv *block_rsv,
78fed14b32SJosef Bacik 			      u64 num_bytes, u64 *qgroup_to_release);
7967f9c220SJosef Bacik void btrfs_update_global_block_rsv(struct btrfs_fs_info *fs_info);
8067f9c220SJosef Bacik void btrfs_init_global_block_rsv(struct btrfs_fs_info *fs_info);
8167f9c220SJosef Bacik void btrfs_release_global_block_rsv(struct btrfs_fs_info *fs_info);
8267f9c220SJosef Bacik struct btrfs_block_rsv *btrfs_use_block_rsv(struct btrfs_trans_handle *trans,
8367f9c220SJosef Bacik 					    struct btrfs_root *root,
8467f9c220SJosef Bacik 					    u32 blocksize);
8554d687c1SJosef Bacik int btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info,
8654d687c1SJosef Bacik 				       struct btrfs_block_rsv *rsv);
btrfs_unuse_block_rsv(struct btrfs_fs_info * fs_info,struct btrfs_block_rsv * block_rsv,u32 blocksize)8767f9c220SJosef Bacik static inline void btrfs_unuse_block_rsv(struct btrfs_fs_info *fs_info,
8867f9c220SJosef Bacik 					 struct btrfs_block_rsv *block_rsv,
8967f9c220SJosef Bacik 					 u32 blocksize)
9067f9c220SJosef Bacik {
9167f9c220SJosef Bacik 	btrfs_block_rsv_add_bytes(block_rsv, blocksize, false);
9263f018beSNikolay Borisov 	btrfs_block_rsv_release(fs_info, block_rsv, 0, NULL);
9367f9c220SJosef Bacik }
9467f9c220SJosef Bacik 
95748f553cSDavid Sterba /*
96748f553cSDavid Sterba  * Fast path to check if the reserve is full, may be carefully used outside of
97748f553cSDavid Sterba  * locks.
98748f553cSDavid Sterba  */
btrfs_block_rsv_full(const struct btrfs_block_rsv * rsv)99748f553cSDavid Sterba static inline bool btrfs_block_rsv_full(const struct btrfs_block_rsv *rsv)
100748f553cSDavid Sterba {
101748f553cSDavid Sterba 	return data_race(rsv->full);
102748f553cSDavid Sterba }
103748f553cSDavid Sterba 
10482220b18SFilipe Manana /*
10582220b18SFilipe Manana  * Get the reserved mount of a block reserve in a context where getting a stale
10682220b18SFilipe Manana  * value is acceptable, instead of accessing it directly and trigger data race
10782220b18SFilipe Manana  * warning from KCSAN.
10882220b18SFilipe Manana  */
btrfs_block_rsv_reserved(struct btrfs_block_rsv * rsv)10982220b18SFilipe Manana static inline u64 btrfs_block_rsv_reserved(struct btrfs_block_rsv *rsv)
11082220b18SFilipe Manana {
11182220b18SFilipe Manana 	u64 ret;
11282220b18SFilipe Manana 
11382220b18SFilipe Manana 	spin_lock(&rsv->lock);
11482220b18SFilipe Manana 	ret = rsv->reserved;
11582220b18SFilipe Manana 	spin_unlock(&rsv->lock);
11682220b18SFilipe Manana 
11782220b18SFilipe Manana 	return ret;
11882220b18SFilipe Manana }
11982220b18SFilipe Manana 
120*f6d4d29aSFilipe Manana /*
121*f6d4d29aSFilipe Manana  * Get the size of a block reserve in a context where getting a stale value is
122*f6d4d29aSFilipe Manana  * acceptable, instead of accessing it directly and trigger data race warning
123*f6d4d29aSFilipe Manana  * from KCSAN.
124*f6d4d29aSFilipe Manana  */
btrfs_block_rsv_size(struct btrfs_block_rsv * rsv)125*f6d4d29aSFilipe Manana static inline u64 btrfs_block_rsv_size(struct btrfs_block_rsv *rsv)
126*f6d4d29aSFilipe Manana {
127*f6d4d29aSFilipe Manana 	u64 ret;
128*f6d4d29aSFilipe Manana 
129*f6d4d29aSFilipe Manana 	spin_lock(&rsv->lock);
130*f6d4d29aSFilipe Manana 	ret = rsv->size;
131*f6d4d29aSFilipe Manana 	spin_unlock(&rsv->lock);
132*f6d4d29aSFilipe Manana 
133*f6d4d29aSFilipe Manana 	return ret;
134*f6d4d29aSFilipe Manana }
135*f6d4d29aSFilipe Manana 
136d12ffdd1SJosef Bacik #endif /* BTRFS_BLOCK_RSV_H */
137