Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-or-later */
2 : /*
3 : * Copyright (C) 2021-2023 Oracle. All Rights Reserved.
4 : * Author: Darrick J. Wong <djwong@kernel.org>
5 : */
6 : #ifndef __XFS_RTREFCOUNT_BTREE_H__
7 : #define __XFS_RTREFCOUNT_BTREE_H__
8 :
9 : struct xfs_buf;
10 : struct xfs_btree_cur;
11 : struct xfs_mount;
12 : struct xbtree_ifakeroot;
13 : struct xfs_rtgroup;
14 : struct xfs_imeta_path;
15 :
16 : /* refcounts only exist on crc enabled filesystems */
17 : #define XFS_RTREFCOUNT_BLOCK_LEN XFS_BTREE_LBLOCK_CRC_LEN
18 :
19 : struct xfs_btree_cur *xfs_rtrefcountbt_init_cursor(struct xfs_mount *mp,
20 : struct xfs_trans *tp, struct xfs_rtgroup *rtg,
21 : struct xfs_inode *ip);
22 : struct xfs_btree_cur *xfs_rtrefcountbt_stage_cursor(struct xfs_mount *mp,
23 : struct xfs_rtgroup *rtg, struct xfs_inode *ip,
24 : struct xbtree_ifakeroot *ifake);
25 : void xfs_rtrefcountbt_commit_staged_btree(struct xfs_btree_cur *cur,
26 : struct xfs_trans *tp);
27 : unsigned int xfs_rtrefcountbt_maxrecs(struct xfs_mount *mp,
28 : unsigned int blocklen, bool leaf);
29 : void xfs_rtrefcountbt_compute_maxlevels(struct xfs_mount *mp);
30 : unsigned int xfs_rtrefcountbt_droot_maxrecs(unsigned int blocklen, bool leaf);
31 :
32 : /*
33 : * Addresses of records, keys, and pointers within an incore rtrefcountbt block.
34 : *
35 : * (note that some of these may appear unused, but they are used in userspace)
36 : */
37 : static inline struct xfs_refcount_rec *
38 : xfs_rtrefcount_rec_addr(
39 : struct xfs_btree_block *block,
40 : unsigned int index)
41 : {
42 3121793 : return (struct xfs_refcount_rec *)
43 : ((char *)block + XFS_RTREFCOUNT_BLOCK_LEN +
44 : (index - 1) * sizeof(struct xfs_refcount_rec));
45 : }
46 :
47 : static inline struct xfs_refcount_key *
48 : xfs_rtrefcount_key_addr(
49 : struct xfs_btree_block *block,
50 : unsigned int index)
51 : {
52 26474 : return (struct xfs_refcount_key *)
53 : ((char *)block + XFS_RTREFCOUNT_BLOCK_LEN +
54 : (index - 1) * sizeof(struct xfs_refcount_key));
55 : }
56 :
57 : static inline xfs_rtrefcount_ptr_t *
58 : xfs_rtrefcount_ptr_addr(
59 : struct xfs_btree_block *block,
60 : unsigned int index,
61 : unsigned int maxrecs)
62 : {
63 29541 : return (xfs_rtrefcount_ptr_t *)
64 29541 : ((char *)block + XFS_RTREFCOUNT_BLOCK_LEN +
65 29541 : maxrecs * sizeof(struct xfs_refcount_key) +
66 : (index - 1) * sizeof(xfs_rtrefcount_ptr_t));
67 : }
68 :
69 : unsigned int xfs_rtrefcountbt_maxlevels_ondisk(void);
70 : int __init xfs_rtrefcountbt_init_cur_cache(void);
71 : void xfs_rtrefcountbt_destroy_cur_cache(void);
72 :
73 : int xfs_rtrefcountbt_create_path(struct xfs_mount *mp, xfs_rgnumber_t rgno,
74 : struct xfs_imeta_path **pathp);
75 :
76 : xfs_filblks_t xfs_rtrefcountbt_calc_reserves(struct xfs_mount *mp);
77 : unsigned long long xfs_rtrefcountbt_calc_size(struct xfs_mount *mp,
78 : unsigned long long len);
79 :
80 : /* Addresses of key, pointers, and records within an ondisk rtrefcount block. */
81 :
82 : static inline struct xfs_refcount_rec *
83 : xfs_rtrefcount_droot_rec_addr(
84 : struct xfs_rtrefcount_root *block,
85 : unsigned int index)
86 : {
87 117645 : return (struct xfs_refcount_rec *)
88 : ((char *)(block + 1) +
89 : (index - 1) * sizeof(struct xfs_refcount_rec));
90 : }
91 :
92 : static inline struct xfs_refcount_key *
93 : xfs_rtrefcount_droot_key_addr(
94 : struct xfs_rtrefcount_root *block,
95 : unsigned int index)
96 : {
97 24893 : return (struct xfs_refcount_key *)
98 : ((char *)(block + 1) +
99 : (index - 1) * sizeof(struct xfs_refcount_key));
100 : }
101 :
102 : static inline xfs_rtrefcount_ptr_t *
103 : xfs_rtrefcount_droot_ptr_addr(
104 : struct xfs_rtrefcount_root *block,
105 : unsigned int index,
106 : unsigned int maxrecs)
107 : {
108 24893 : return (xfs_rtrefcount_ptr_t *)
109 24893 : ((char *)(block + 1) +
110 24893 : maxrecs * sizeof(struct xfs_refcount_key) +
111 : (index - 1) * sizeof(xfs_rtrefcount_ptr_t));
112 : }
113 :
114 : /*
115 : * Address of pointers within the incore btree root.
116 : *
117 : * These are to be used when we know the size of the block and
118 : * we don't have a cursor.
119 : */
120 : static inline xfs_rtrefcount_ptr_t *
121 : xfs_rtrefcount_broot_ptr_addr(
122 : struct xfs_mount *mp,
123 : struct xfs_btree_block *bb,
124 : unsigned int index,
125 : unsigned int block_size)
126 : {
127 29541 : return xfs_rtrefcount_ptr_addr(bb, index,
128 : xfs_rtrefcountbt_maxrecs(mp, block_size, false));
129 : }
130 :
131 : /*
132 : * Compute the space required for the incore btree root containing the given
133 : * number of records.
134 : */
135 : static inline size_t
136 6388294 : xfs_rtrefcount_broot_space_calc(
137 : struct xfs_mount *mp,
138 : unsigned int level,
139 : unsigned int nrecs)
140 : {
141 6611262 : size_t sz = XFS_RTREFCOUNT_BLOCK_LEN;
142 :
143 6513961 : if (level > 0)
144 28848 : return sz + nrecs * (sizeof(struct xfs_refcount_key) +
145 : sizeof(xfs_rtrefcount_ptr_t));
146 6582414 : return sz + nrecs * sizeof(struct xfs_refcount_rec);
147 : }
148 :
149 : /*
150 : * Compute the space required for the incore btree root given the ondisk
151 : * btree root block.
152 : */
153 : static inline size_t
154 : xfs_rtrefcount_broot_space(struct xfs_mount *mp, struct xfs_rtrefcount_root *bb)
155 : {
156 97301 : return xfs_rtrefcount_broot_space_calc(mp, be16_to_cpu(bb->bb_level),
157 97301 : be16_to_cpu(bb->bb_numrecs));
158 : }
159 :
160 : /* Compute the space required for the ondisk root block. */
161 : static inline size_t
162 : xfs_rtrefcount_droot_space_calc(
163 : unsigned int level,
164 : unsigned int nrecs)
165 : {
166 6512466 : size_t sz = sizeof(struct xfs_rtrefcount_root);
167 :
168 97301 : if (level > 0)
169 29484 : return sz + nrecs * (sizeof(struct xfs_refcount_key) +
170 : sizeof(xfs_rtrefcount_ptr_t));
171 6482982 : return sz + nrecs * sizeof(struct xfs_refcount_rec);
172 : }
173 :
174 : /*
175 : * Compute the space required for the ondisk root block given an incore root
176 : * block.
177 : */
178 : static inline size_t
179 : xfs_rtrefcount_droot_space(struct xfs_btree_block *bb)
180 : {
181 6415165 : return xfs_rtrefcount_droot_space_calc(be16_to_cpu(bb->bb_level),
182 6415165 : be16_to_cpu(bb->bb_numrecs));
183 : }
184 :
185 : int xfs_iformat_rtrefcount(struct xfs_inode *ip, struct xfs_dinode *dip);
186 : void xfs_rtrefcountbt_to_disk(struct xfs_mount *mp,
187 : struct xfs_btree_block *rblock, int rblocklen,
188 : struct xfs_rtrefcount_root *dblock, int dblocklen);
189 : void xfs_iflush_rtrefcount(struct xfs_inode *ip, struct xfs_dinode *dip);
190 :
191 : struct xfs_imeta_update;
192 :
193 : int xfs_rtrefcountbt_create(struct xfs_imeta_update *upd,
194 : struct xfs_inode **ipp);
195 :
196 : #endif /* __XFS_RTREFCOUNT_BTREE_H__ */
|