xref: /linux/fs/xfs/libxfs/xfs_rtrefcount_btree.h (revision b477ff98d903618a1ab8247861f2ea6e70c0f0f8)
19abe03a0SDarrick J. Wong /* SPDX-License-Identifier: GPL-2.0-or-later */
29abe03a0SDarrick J. Wong /*
39abe03a0SDarrick J. Wong  * Copyright (c) 2021-2024 Oracle.  All Rights Reserved.
49abe03a0SDarrick J. Wong  * Author: Darrick J. Wong <djwong@kernel.org>
59abe03a0SDarrick J. Wong  */
69abe03a0SDarrick J. Wong #ifndef __XFS_RTREFCOUNT_BTREE_H__
79abe03a0SDarrick J. Wong #define __XFS_RTREFCOUNT_BTREE_H__
89abe03a0SDarrick J. Wong 
99abe03a0SDarrick J. Wong struct xfs_buf;
109abe03a0SDarrick J. Wong struct xfs_btree_cur;
119abe03a0SDarrick J. Wong struct xfs_mount;
129abe03a0SDarrick J. Wong struct xbtree_ifakeroot;
139abe03a0SDarrick J. Wong struct xfs_rtgroup;
149abe03a0SDarrick J. Wong 
159abe03a0SDarrick J. Wong /* refcounts only exist on crc enabled filesystems */
169abe03a0SDarrick J. Wong #define XFS_RTREFCOUNT_BLOCK_LEN	XFS_BTREE_LBLOCK_CRC_LEN
179abe03a0SDarrick J. Wong 
189abe03a0SDarrick J. Wong struct xfs_btree_cur *xfs_rtrefcountbt_init_cursor(struct xfs_trans *tp,
199abe03a0SDarrick J. Wong 		struct xfs_rtgroup *rtg);
209abe03a0SDarrick J. Wong struct xfs_btree_cur *xfs_rtrefcountbt_stage_cursor(struct xfs_mount *mp,
219abe03a0SDarrick J. Wong 		struct xfs_rtgroup *rtg, struct xfs_inode *ip,
229abe03a0SDarrick J. Wong 		struct xbtree_ifakeroot *ifake);
239abe03a0SDarrick J. Wong void xfs_rtrefcountbt_commit_staged_btree(struct xfs_btree_cur *cur,
249abe03a0SDarrick J. Wong 		struct xfs_trans *tp);
259abe03a0SDarrick J. Wong unsigned int xfs_rtrefcountbt_maxrecs(struct xfs_mount *mp,
269abe03a0SDarrick J. Wong 		unsigned int blocklen, bool leaf);
279abe03a0SDarrick J. Wong void xfs_rtrefcountbt_compute_maxlevels(struct xfs_mount *mp);
28f0415af6SDarrick J. Wong unsigned int xfs_rtrefcountbt_droot_maxrecs(unsigned int blocklen, bool leaf);
299abe03a0SDarrick J. Wong 
309abe03a0SDarrick J. Wong /*
319abe03a0SDarrick J. Wong  * Addresses of records, keys, and pointers within an incore rtrefcountbt block.
329abe03a0SDarrick J. Wong  *
339abe03a0SDarrick J. Wong  * (note that some of these may appear unused, but they are used in userspace)
349abe03a0SDarrick J. Wong  */
359abe03a0SDarrick J. Wong static inline struct xfs_refcount_rec *
xfs_rtrefcount_rec_addr(struct xfs_btree_block * block,unsigned int index)369abe03a0SDarrick J. Wong xfs_rtrefcount_rec_addr(
379abe03a0SDarrick J. Wong 	struct xfs_btree_block	*block,
389abe03a0SDarrick J. Wong 	unsigned int		index)
399abe03a0SDarrick J. Wong {
409abe03a0SDarrick J. Wong 	return (struct xfs_refcount_rec *)
419abe03a0SDarrick J. Wong 		((char *)block + XFS_RTREFCOUNT_BLOCK_LEN +
429abe03a0SDarrick J. Wong 		 (index - 1) * sizeof(struct xfs_refcount_rec));
439abe03a0SDarrick J. Wong }
449abe03a0SDarrick J. Wong 
459abe03a0SDarrick J. Wong static inline struct xfs_refcount_key *
xfs_rtrefcount_key_addr(struct xfs_btree_block * block,unsigned int index)469abe03a0SDarrick J. Wong xfs_rtrefcount_key_addr(
479abe03a0SDarrick J. Wong 	struct xfs_btree_block	*block,
489abe03a0SDarrick J. Wong 	unsigned int		index)
499abe03a0SDarrick J. Wong {
509abe03a0SDarrick J. Wong 	return (struct xfs_refcount_key *)
519abe03a0SDarrick J. Wong 		((char *)block + XFS_RTREFCOUNT_BLOCK_LEN +
529abe03a0SDarrick J. Wong 		 (index - 1) * sizeof(struct xfs_refcount_key));
539abe03a0SDarrick J. Wong }
549abe03a0SDarrick J. Wong 
559abe03a0SDarrick J. Wong static inline xfs_rtrefcount_ptr_t *
xfs_rtrefcount_ptr_addr(struct xfs_btree_block * block,unsigned int index,unsigned int maxrecs)569abe03a0SDarrick J. Wong xfs_rtrefcount_ptr_addr(
579abe03a0SDarrick J. Wong 	struct xfs_btree_block	*block,
589abe03a0SDarrick J. Wong 	unsigned int		index,
599abe03a0SDarrick J. Wong 	unsigned int		maxrecs)
609abe03a0SDarrick J. Wong {
619abe03a0SDarrick J. Wong 	return (xfs_rtrefcount_ptr_t *)
629abe03a0SDarrick J. Wong 		((char *)block + XFS_RTREFCOUNT_BLOCK_LEN +
639abe03a0SDarrick J. Wong 		 maxrecs * sizeof(struct xfs_refcount_key) +
649abe03a0SDarrick J. Wong 		 (index - 1) * sizeof(xfs_rtrefcount_ptr_t));
659abe03a0SDarrick J. Wong }
669abe03a0SDarrick J. Wong 
679abe03a0SDarrick J. Wong unsigned int xfs_rtrefcountbt_maxlevels_ondisk(void);
689abe03a0SDarrick J. Wong int __init xfs_rtrefcountbt_init_cur_cache(void);
699abe03a0SDarrick J. Wong void xfs_rtrefcountbt_destroy_cur_cache(void);
709abe03a0SDarrick J. Wong 
71bf0b9941SDarrick J. Wong xfs_filblks_t xfs_rtrefcountbt_calc_reserves(struct xfs_mount *mp);
72bf0b9941SDarrick J. Wong unsigned long long xfs_rtrefcountbt_calc_size(struct xfs_mount *mp,
73bf0b9941SDarrick J. Wong 		unsigned long long len);
74bf0b9941SDarrick J. Wong 
75f0415af6SDarrick J. Wong /* Addresses of key, pointers, and records within an ondisk rtrefcount block. */
76f0415af6SDarrick J. Wong 
77f0415af6SDarrick J. Wong static inline struct xfs_refcount_rec *
xfs_rtrefcount_droot_rec_addr(struct xfs_rtrefcount_root * block,unsigned int index)78f0415af6SDarrick J. Wong xfs_rtrefcount_droot_rec_addr(
79f0415af6SDarrick J. Wong 	struct xfs_rtrefcount_root	*block,
80f0415af6SDarrick J. Wong 	unsigned int			index)
81f0415af6SDarrick J. Wong {
82f0415af6SDarrick J. Wong 	return (struct xfs_refcount_rec *)
83f0415af6SDarrick J. Wong 		((char *)(block + 1) +
84f0415af6SDarrick J. Wong 		 (index - 1) * sizeof(struct xfs_refcount_rec));
85f0415af6SDarrick J. Wong }
86f0415af6SDarrick J. Wong 
87f0415af6SDarrick J. Wong static inline struct xfs_refcount_key *
xfs_rtrefcount_droot_key_addr(struct xfs_rtrefcount_root * block,unsigned int index)88f0415af6SDarrick J. Wong xfs_rtrefcount_droot_key_addr(
89f0415af6SDarrick J. Wong 	struct xfs_rtrefcount_root	*block,
90f0415af6SDarrick J. Wong 	unsigned int			index)
91f0415af6SDarrick J. Wong {
92f0415af6SDarrick J. Wong 	return (struct xfs_refcount_key *)
93f0415af6SDarrick J. Wong 		((char *)(block + 1) +
94f0415af6SDarrick J. Wong 		 (index - 1) * sizeof(struct xfs_refcount_key));
95f0415af6SDarrick J. Wong }
96f0415af6SDarrick J. Wong 
97f0415af6SDarrick J. Wong static inline xfs_rtrefcount_ptr_t *
xfs_rtrefcount_droot_ptr_addr(struct xfs_rtrefcount_root * block,unsigned int index,unsigned int maxrecs)98f0415af6SDarrick J. Wong xfs_rtrefcount_droot_ptr_addr(
99f0415af6SDarrick J. Wong 	struct xfs_rtrefcount_root	*block,
100f0415af6SDarrick J. Wong 	unsigned int			index,
101f0415af6SDarrick J. Wong 	unsigned int			maxrecs)
102f0415af6SDarrick J. Wong {
103f0415af6SDarrick J. Wong 	return (xfs_rtrefcount_ptr_t *)
104f0415af6SDarrick J. Wong 		((char *)(block + 1) +
105f0415af6SDarrick J. Wong 		 maxrecs * sizeof(struct xfs_refcount_key) +
106f0415af6SDarrick J. Wong 		 (index - 1) * sizeof(xfs_rtrefcount_ptr_t));
107f0415af6SDarrick J. Wong }
108f0415af6SDarrick J. Wong 
109f0415af6SDarrick J. Wong /*
110f0415af6SDarrick J. Wong  * Address of pointers within the incore btree root.
111f0415af6SDarrick J. Wong  *
112f0415af6SDarrick J. Wong  * These are to be used when we know the size of the block and
113f0415af6SDarrick J. Wong  * we don't have a cursor.
114f0415af6SDarrick J. Wong  */
115f0415af6SDarrick J. Wong static inline xfs_rtrefcount_ptr_t *
xfs_rtrefcount_broot_ptr_addr(struct xfs_mount * mp,struct xfs_btree_block * bb,unsigned int index,unsigned int block_size)116f0415af6SDarrick J. Wong xfs_rtrefcount_broot_ptr_addr(
117f0415af6SDarrick J. Wong 	struct xfs_mount	*mp,
118f0415af6SDarrick J. Wong 	struct xfs_btree_block	*bb,
119f0415af6SDarrick J. Wong 	unsigned int		index,
120f0415af6SDarrick J. Wong 	unsigned int		block_size)
121f0415af6SDarrick J. Wong {
122f0415af6SDarrick J. Wong 	return xfs_rtrefcount_ptr_addr(bb, index,
123f0415af6SDarrick J. Wong 			xfs_rtrefcountbt_maxrecs(mp, block_size, false));
124f0415af6SDarrick J. Wong }
125f0415af6SDarrick J. Wong 
126f0415af6SDarrick J. Wong /*
127f0415af6SDarrick J. Wong  * Compute the space required for the incore btree root containing the given
128f0415af6SDarrick J. Wong  * number of records.
129f0415af6SDarrick J. Wong  */
130f0415af6SDarrick J. Wong static inline size_t
xfs_rtrefcount_broot_space_calc(struct xfs_mount * mp,unsigned int level,unsigned int nrecs)131f0415af6SDarrick J. Wong xfs_rtrefcount_broot_space_calc(
132f0415af6SDarrick J. Wong 	struct xfs_mount	*mp,
133f0415af6SDarrick J. Wong 	unsigned int		level,
134f0415af6SDarrick J. Wong 	unsigned int		nrecs)
135f0415af6SDarrick J. Wong {
136f0415af6SDarrick J. Wong 	size_t			sz = XFS_RTREFCOUNT_BLOCK_LEN;
137f0415af6SDarrick J. Wong 
138f0415af6SDarrick J. Wong 	if (level > 0)
139f0415af6SDarrick J. Wong 		return sz + nrecs * (sizeof(struct xfs_refcount_key) +
140f0415af6SDarrick J. Wong 				     sizeof(xfs_rtrefcount_ptr_t));
141f0415af6SDarrick J. Wong 	return sz + nrecs * sizeof(struct xfs_refcount_rec);
142f0415af6SDarrick J. Wong }
143f0415af6SDarrick J. Wong 
144f0415af6SDarrick J. Wong /*
145f0415af6SDarrick J. Wong  * Compute the space required for the incore btree root given the ondisk
146f0415af6SDarrick J. Wong  * btree root block.
147f0415af6SDarrick J. Wong  */
148f0415af6SDarrick J. Wong static inline size_t
xfs_rtrefcount_broot_space(struct xfs_mount * mp,struct xfs_rtrefcount_root * bb)149f0415af6SDarrick J. Wong xfs_rtrefcount_broot_space(struct xfs_mount *mp, struct xfs_rtrefcount_root *bb)
150f0415af6SDarrick J. Wong {
151f0415af6SDarrick J. Wong 	return xfs_rtrefcount_broot_space_calc(mp, be16_to_cpu(bb->bb_level),
152f0415af6SDarrick J. Wong 			be16_to_cpu(bb->bb_numrecs));
153f0415af6SDarrick J. Wong }
154f0415af6SDarrick J. Wong 
155f0415af6SDarrick J. Wong /* Compute the space required for the ondisk root block. */
156f0415af6SDarrick J. Wong static inline size_t
xfs_rtrefcount_droot_space_calc(unsigned int level,unsigned int nrecs)157f0415af6SDarrick J. Wong xfs_rtrefcount_droot_space_calc(
158f0415af6SDarrick J. Wong 	unsigned int		level,
159f0415af6SDarrick J. Wong 	unsigned int		nrecs)
160f0415af6SDarrick J. Wong {
161f0415af6SDarrick J. Wong 	size_t			sz = sizeof(struct xfs_rtrefcount_root);
162f0415af6SDarrick J. Wong 
163f0415af6SDarrick J. Wong 	if (level > 0)
164f0415af6SDarrick J. Wong 		return sz + nrecs * (sizeof(struct xfs_refcount_key) +
165f0415af6SDarrick J. Wong 				     sizeof(xfs_rtrefcount_ptr_t));
166f0415af6SDarrick J. Wong 	return sz + nrecs * sizeof(struct xfs_refcount_rec);
167f0415af6SDarrick J. Wong }
168f0415af6SDarrick J. Wong 
169f0415af6SDarrick J. Wong /*
170f0415af6SDarrick J. Wong  * Compute the space required for the ondisk root block given an incore root
171f0415af6SDarrick J. Wong  * block.
172f0415af6SDarrick J. Wong  */
173f0415af6SDarrick J. Wong static inline size_t
xfs_rtrefcount_droot_space(struct xfs_btree_block * bb)174f0415af6SDarrick J. Wong xfs_rtrefcount_droot_space(struct xfs_btree_block *bb)
175f0415af6SDarrick J. Wong {
176f0415af6SDarrick J. Wong 	return xfs_rtrefcount_droot_space_calc(be16_to_cpu(bb->bb_level),
177f0415af6SDarrick J. Wong 			be16_to_cpu(bb->bb_numrecs));
178f0415af6SDarrick J. Wong }
179f0415af6SDarrick J. Wong 
180f0415af6SDarrick J. Wong int xfs_iformat_rtrefcount(struct xfs_inode *ip, struct xfs_dinode *dip);
181f0415af6SDarrick J. Wong void xfs_rtrefcountbt_to_disk(struct xfs_mount *mp,
182f0415af6SDarrick J. Wong 		struct xfs_btree_block *rblock, int rblocklen,
183f0415af6SDarrick J. Wong 		struct xfs_rtrefcount_root *dblock, int dblocklen);
184f0415af6SDarrick J. Wong void xfs_iflush_rtrefcount(struct xfs_inode *ip, struct xfs_dinode *dip);
185f0415af6SDarrick J. Wong 
186*4ee3113aSDarrick J. Wong int xfs_rtrefcountbt_create(struct xfs_rtgroup *rtg, struct xfs_inode *ip,
187*4ee3113aSDarrick J. Wong 		struct xfs_trans *tp, bool init);
188*4ee3113aSDarrick J. Wong 
1899abe03a0SDarrick J. Wong #endif	/* __XFS_RTREFCOUNT_BTREE_H__ */
190