Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */
2 : /*
3 : * Copyright (c) 2018 Red Hat, Inc.
4 : * All rights reserved.
5 : */
6 :
7 : #ifndef __LIBXFS_AG_H
8 : #define __LIBXFS_AG_H 1
9 :
10 : struct xfs_mount;
11 : struct xfs_trans;
12 : struct xfs_perag;
13 :
14 : /*
15 : * Per-ag infrastructure
16 : */
17 :
18 : /* per-AG block reservation data structures*/
19 : struct xfs_ag_resv {
20 : /* number of blocks originally reserved here */
21 : xfs_extlen_t ar_orig_reserved;
22 : /* number of blocks reserved here */
23 : xfs_extlen_t ar_reserved;
24 : /* number of blocks originally asked for */
25 : xfs_extlen_t ar_asked;
26 : };
27 :
28 : /*
29 : * Per-ag incore structure, copies of information in agf and agi, to improve the
30 : * performance of allocation group selection.
31 : */
32 : struct xfs_perag {
33 : struct xfs_mount *pag_mount; /* owner filesystem */
34 : xfs_agnumber_t pag_agno; /* AG this structure belongs to */
35 : atomic_t pag_ref; /* passive reference count */
36 : atomic_t pag_active_ref; /* active reference count */
37 : wait_queue_head_t pag_active_wq;/* woken active_ref falls to zero */
38 : unsigned long pag_opstate;
39 : uint8_t pagf_levels[XFS_BTNUM_AGF];
40 : /* # of levels in bno & cnt btree */
41 : uint32_t pagf_flcount; /* count of blocks in freelist */
42 : xfs_extlen_t pagf_freeblks; /* total free blocks */
43 : xfs_extlen_t pagf_longest; /* longest free space */
44 : uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */
45 : xfs_agino_t pagi_freecount; /* number of free inodes */
46 : xfs_agino_t pagi_count; /* number of allocated inodes */
47 :
48 : /*
49 : * Inode allocation search lookup optimisation.
50 : * If the pagino matches, the search for new inodes
51 : * doesn't need to search the near ones again straight away
52 : */
53 : xfs_agino_t pagl_pagino;
54 : xfs_agino_t pagl_leftrec;
55 : xfs_agino_t pagl_rightrec;
56 :
57 : int pagb_count; /* pagb slots in use */
58 : uint8_t pagf_refcount_level; /* recount btree height */
59 :
60 : /* Blocks reserved for all kinds of metadata. */
61 : struct xfs_ag_resv pag_meta_resv;
62 : /* Blocks reserved for the reverse mapping btree. */
63 : struct xfs_ag_resv pag_rmapbt_resv;
64 :
65 : /* for rcu-safe freeing */
66 : struct rcu_head rcu_head;
67 :
68 : /* Precalculated geometry info */
69 : xfs_agblock_t block_count;
70 : xfs_agblock_t min_block;
71 : xfs_agino_t agino_min;
72 : xfs_agino_t agino_max;
73 :
74 : #ifdef __KERNEL__
75 : /* -- kernel only structures below this line -- */
76 :
77 : /*
78 : * Bitsets of per-ag metadata that have been checked and/or are sick.
79 : * Callers should hold pag_state_lock before accessing this field.
80 : */
81 : uint16_t pag_checked;
82 : uint16_t pag_sick;
83 : spinlock_t pag_state_lock;
84 :
85 : spinlock_t pagb_lock; /* lock for pagb_tree */
86 : struct rb_root pagb_tree; /* ordered tree of busy extents */
87 : unsigned int pagb_gen; /* generation count for pagb_tree */
88 : wait_queue_head_t pagb_wait; /* woken when pagb_gen changes */
89 :
90 : atomic_t pagf_fstrms; /* # of filestreams active in this AG */
91 :
92 : spinlock_t pag_ici_lock; /* incore inode cache lock */
93 : struct radix_tree_root pag_ici_root; /* incore inode cache root */
94 : int pag_ici_reclaimable; /* reclaimable inodes */
95 : unsigned long pag_ici_reclaim_cursor; /* reclaim restart point */
96 :
97 : /* buffer cache index */
98 : spinlock_t pag_buf_lock; /* lock for pag_buf_hash */
99 : struct rhashtable pag_buf_hash;
100 :
101 : /* background prealloc block trimming */
102 : struct delayed_work pag_blockgc_work;
103 :
104 : /*
105 : * We use xfs_drain to track the number of deferred log intent items
106 : * that have been queued (but not yet processed) so that waiters (e.g.
107 : * scrub) will not lock resources when other threads are in the middle
108 : * of processing a chain of intent items only to find momentary
109 : * inconsistencies.
110 : */
111 : struct xfs_defer_drain pag_intents_drain;
112 : #endif /* __KERNEL__ */
113 : };
114 :
115 : /*
116 : * Per-AG operational state. These are atomic flag bits.
117 : */
118 : #define XFS_AGSTATE_AGF_INIT 0
119 : #define XFS_AGSTATE_AGI_INIT 1
120 : #define XFS_AGSTATE_PREFERS_METADATA 2
121 : #define XFS_AGSTATE_ALLOWS_INODES 3
122 : #define XFS_AGSTATE_AGFL_NEEDS_RESET 4
123 :
124 : #define __XFS_AG_OPSTATE(name, NAME) \
125 : static inline bool xfs_perag_ ## name (struct xfs_perag *pag) \
126 : { \
127 : return test_bit(XFS_AGSTATE_ ## NAME, &pag->pag_opstate); \
128 : }
129 :
130 2402644949 : __XFS_AG_OPSTATE(initialised_agf, AGF_INIT)
131 1795642124 : __XFS_AG_OPSTATE(initialised_agi, AGI_INIT)
132 671310075 : __XFS_AG_OPSTATE(prefers_metadata, PREFERS_METADATA)
133 88479084 : __XFS_AG_OPSTATE(allows_inodes, ALLOWS_INODES)
134 493983972 : __XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET)
135 :
136 : int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount,
137 : xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi);
138 : int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno);
139 : void xfs_free_perag(struct xfs_mount *mp);
140 :
141 : /* Passive AG references */
142 : struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno);
143 : struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno,
144 : unsigned int tag);
145 : struct xfs_perag *xfs_perag_hold(struct xfs_perag *pag);
146 : void xfs_perag_put(struct xfs_perag *pag);
147 :
148 : /* Active AG references */
149 : struct xfs_perag *xfs_perag_grab(struct xfs_mount *, xfs_agnumber_t);
150 : struct xfs_perag *xfs_perag_grab_tag(struct xfs_mount *, xfs_agnumber_t,
151 : int tag);
152 : void xfs_perag_rele(struct xfs_perag *pag);
153 :
154 : /*
155 : * Per-ag geometry infomation and validation
156 : */
157 : xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno);
158 : void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
159 : xfs_agino_t *first, xfs_agino_t *last);
160 :
161 : static inline bool
162 : xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno)
163 : {
164 >36913*10^7 : if (agbno >= pag->block_count)
165 : return false;
166 >38505*10^7 : if (agbno <= pag->min_block)
167 0 : return false;
168 : return true;
169 : }
170 :
171 : static inline bool
172 61118001714 : xfs_verify_agbext(
173 : struct xfs_perag *pag,
174 : xfs_agblock_t agbno,
175 : xfs_agblock_t len)
176 : {
177 61118001714 : if (agbno + len <= agbno)
178 : return false;
179 :
180 61118001714 : if (!xfs_verify_agbno(pag, agbno))
181 : return false;
182 :
183 61118001704 : return xfs_verify_agbno(pag, agbno + len - 1);
184 : }
185 :
186 : /*
187 : * Verify that an AG inode number pointer neither points outside the AG
188 : * nor points at static metadata.
189 : */
190 : static inline bool
191 : xfs_verify_agino(struct xfs_perag *pag, xfs_agino_t agino)
192 : {
193 40196665176 : if (agino < pag->agino_min)
194 : return false;
195 40285598660 : if (agino > pag->agino_max)
196 0 : return false;
197 : return true;
198 : }
199 :
200 : /*
201 : * Verify that an AG inode number pointer neither points outside the AG
202 : * nor points at static metadata, or is NULLAGINO.
203 : */
204 : static inline bool
205 : xfs_verify_agino_or_null(struct xfs_perag *pag, xfs_agino_t agino)
206 : {
207 1730510278 : if (agino == NULLAGINO)
208 : return true;
209 168014172 : return xfs_verify_agino(pag, agino);
210 : }
211 :
212 : static inline bool
213 2853480 : xfs_ag_contains_log(struct xfs_mount *mp, xfs_agnumber_t agno)
214 : {
215 2853480 : return mp->m_sb.sb_logstart > 0 &&
216 2483516 : agno == XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart);
217 : }
218 :
219 : /*
220 : * Perag iteration APIs
221 : */
222 : static inline struct xfs_perag *
223 21987217 : xfs_perag_next(
224 : struct xfs_perag *pag,
225 : xfs_agnumber_t *agno,
226 : xfs_agnumber_t end_agno)
227 : {
228 21987217 : struct xfs_mount *mp = pag->pag_mount;
229 :
230 21987217 : *agno = pag->pag_agno + 1;
231 21987217 : xfs_perag_rele(pag);
232 21987217 : while (*agno <= end_agno) {
233 15964120 : pag = xfs_perag_grab(mp, *agno);
234 15963607 : if (pag)
235 15963607 : return pag;
236 0 : (*agno)++;
237 : }
238 : return NULL;
239 : }
240 :
241 : #define for_each_perag_range(mp, agno, end_agno, pag) \
242 : for ((pag) = xfs_perag_grab((mp), (agno)); \
243 : (pag) != NULL; \
244 : (pag) = xfs_perag_next((pag), &(agno), (end_agno)))
245 :
246 : #define for_each_perag_from(mp, agno, pag) \
247 : for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount - 1, (pag))
248 :
249 : #define for_each_perag(mp, agno, pag) \
250 : (agno) = 0; \
251 : for_each_perag_from((mp), (agno), (pag))
252 :
253 : #define for_each_perag_tag(mp, agno, pag, tag) \
254 : for ((agno) = 0, (pag) = xfs_perag_grab_tag((mp), 0, (tag)); \
255 : (pag) != NULL; \
256 : (agno) = (pag)->pag_agno + 1, \
257 : xfs_perag_rele(pag), \
258 : (pag) = xfs_perag_grab_tag((mp), (agno), (tag)))
259 :
260 : static inline struct xfs_perag *
261 183180193 : xfs_perag_next_wrap(
262 : struct xfs_perag *pag,
263 : xfs_agnumber_t *agno,
264 : xfs_agnumber_t stop_agno,
265 : xfs_agnumber_t restart_agno,
266 : xfs_agnumber_t wrap_agno)
267 : {
268 183180193 : struct xfs_mount *mp = pag->pag_mount;
269 :
270 183180193 : *agno = pag->pag_agno + 1;
271 183180193 : xfs_perag_rele(pag);
272 183206032 : while (*agno != stop_agno) {
273 182102279 : if (*agno >= wrap_agno) {
274 2427927 : if (restart_agno >= stop_agno)
275 : break;
276 2056144 : *agno = restart_agno;
277 : }
278 :
279 181730496 : pag = xfs_perag_grab(mp, *agno);
280 181739304 : if (pag)
281 181713465 : return pag;
282 25839 : (*agno)++;
283 : }
284 : return NULL;
285 : }
286 :
287 : /*
288 : * Iterate all AGs from start_agno through wrap_agno, then restart_agno through
289 : * (start_agno - 1).
290 : */
291 : #define for_each_perag_wrap_range(mp, start_agno, restart_agno, wrap_agno, agno, pag) \
292 : for ((agno) = (start_agno), (pag) = xfs_perag_grab((mp), (agno)); \
293 : (pag) != NULL; \
294 : (pag) = xfs_perag_next_wrap((pag), &(agno), (start_agno), \
295 : (restart_agno), (wrap_agno)))
296 : /*
297 : * Iterate all AGs from start_agno through wrap_agno, then 0 through
298 : * (start_agno - 1).
299 : */
300 : #define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \
301 : for_each_perag_wrap_range((mp), (start_agno), 0, (wrap_agno), (agno), (pag))
302 :
303 : /*
304 : * Iterate all AGs from start_agno through to the end of the filesystem, then 0
305 : * through (start_agno - 1).
306 : */
307 : #define for_each_perag_wrap(mp, start_agno, agno, pag) \
308 : for_each_perag_wrap_at((mp), (start_agno), (mp)->m_sb.sb_agcount, \
309 : (agno), (pag))
310 :
311 :
312 : struct aghdr_init_data {
313 : /* per ag data */
314 : xfs_agblock_t agno; /* ag to init */
315 : xfs_extlen_t agsize; /* new AG size */
316 : struct list_head buffer_list; /* buffer writeback list */
317 : xfs_rfsblock_t nfree; /* cumulative new free space */
318 :
319 : /* per header data */
320 : xfs_daddr_t daddr; /* header location */
321 : size_t numblks; /* size of header */
322 : xfs_btnum_t type; /* type of btree root block */
323 : };
324 :
325 : int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
326 : int xfs_ag_shrink_space(struct xfs_perag *pag, struct xfs_trans **tpp,
327 : xfs_extlen_t delta);
328 : int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp,
329 : xfs_extlen_t len);
330 : int xfs_ag_get_geometry(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
331 :
332 : #endif /* __LIBXFS_AG_H */
|