1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (c) 2018 Red Hat, Inc.
8 #define __LIBXFS_AG_H 1
10 #include "xfs_group.h"
17 * Per-ag infrastructure
20 /* per-AG block reservation data structures*/
22 /* number of blocks originally reserved here */
23 xfs_extlen_t ar_orig_reserved
;
24 /* number of blocks reserved here */
25 xfs_extlen_t ar_reserved
;
26 /* number of blocks originally asked for */
27 xfs_extlen_t ar_asked
;
31 * Per-ag incore structure, copies of information in agf and agi, to improve the
32 * performance of allocation group selection.
35 struct xfs_group pag_group
;
36 unsigned long pag_opstate
;
37 uint8_t pagf_bno_level
; /* # of levels in bno btree */
38 uint8_t pagf_cnt_level
; /* # of levels in cnt btree */
39 uint8_t pagf_rmap_level
;/* # of levels in rmap btree */
40 uint32_t pagf_flcount
; /* count of blocks in freelist */
41 xfs_extlen_t pagf_freeblks
; /* total free blocks */
42 xfs_extlen_t pagf_longest
; /* longest free space */
43 uint32_t pagf_btreeblks
; /* # of blocks held in AGF btrees */
44 xfs_agino_t pagi_freecount
; /* number of free inodes */
45 xfs_agino_t pagi_count
; /* number of allocated inodes */
48 * Inode allocation search lookup optimisation.
49 * If the pagino matches, the search for new inodes
50 * doesn't need to search the near ones again straight away
52 xfs_agino_t pagl_pagino
;
53 xfs_agino_t pagl_leftrec
;
54 xfs_agino_t pagl_rightrec
;
56 uint8_t pagf_refcount_level
; /* recount btree height */
58 /* Blocks reserved for all kinds of metadata. */
59 struct xfs_ag_resv pag_meta_resv
;
60 /* Blocks reserved for the reverse mapping btree. */
61 struct xfs_ag_resv pag_rmapbt_resv
;
63 /* Precalculated geometry info */
64 xfs_agino_t agino_min
;
65 xfs_agino_t agino_max
;
68 /* -- kernel only structures below this line -- */
70 #ifdef CONFIG_XFS_ONLINE_REPAIR
72 * Alternate btree heights so that online repair won't trip the write
73 * verifiers while rebuilding the AG btrees.
75 uint8_t pagf_repair_bno_level
;
76 uint8_t pagf_repair_cnt_level
;
77 uint8_t pagf_repair_refcount_level
;
78 uint8_t pagf_repair_rmap_level
;
81 atomic_t pagf_fstrms
; /* # of filestreams active in this AG */
83 spinlock_t pag_ici_lock
; /* incore inode cache lock */
84 struct radix_tree_root pag_ici_root
; /* incore inode cache root */
85 int pag_ici_reclaimable
; /* reclaimable inodes */
86 unsigned long pag_ici_reclaim_cursor
; /* reclaim restart point */
88 struct xfs_buf_cache pag_bcache
;
90 /* background prealloc block trimming */
91 struct delayed_work pag_blockgc_work
;
92 #endif /* __KERNEL__ */
95 static inline struct xfs_perag
*to_perag(struct xfs_group
*xg
)
97 return container_of(xg
, struct xfs_perag
, pag_group
);
100 static inline struct xfs_group
*pag_group(struct xfs_perag
*pag
)
102 return &pag
->pag_group
;
105 static inline struct xfs_mount
*pag_mount(const struct xfs_perag
*pag
)
107 return pag
->pag_group
.xg_mount
;
110 static inline xfs_agnumber_t
pag_agno(const struct xfs_perag
*pag
)
112 return pag
->pag_group
.xg_gno
;
116 * Per-AG operational state. These are atomic flag bits.
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
124 #define __XFS_AG_OPSTATE(name, NAME) \
125 static inline bool xfs_perag_ ## name (struct xfs_perag *pag) \
127 return test_bit(XFS_AGSTATE_ ## NAME, &pag->pag_opstate); \
130 __XFS_AG_OPSTATE(initialised_agf
, AGF_INIT
)
131 __XFS_AG_OPSTATE(initialised_agi
, AGI_INIT
)
132 __XFS_AG_OPSTATE(prefers_metadata
, PREFERS_METADATA
)
133 __XFS_AG_OPSTATE(allows_inodes
, ALLOWS_INODES
)
134 __XFS_AG_OPSTATE(agfl_needs_reset
, AGFL_NEEDS_RESET
)
136 int xfs_initialize_perag(struct xfs_mount
*mp
, xfs_agnumber_t orig_agcount
,
137 xfs_agnumber_t new_agcount
, xfs_rfsblock_t dcount
,
138 xfs_agnumber_t
*maxagi
);
139 void xfs_free_perag_range(struct xfs_mount
*mp
, xfs_agnumber_t first_agno
,
140 xfs_agnumber_t end_agno
);
141 int xfs_initialize_perag_data(struct xfs_mount
*mp
, xfs_agnumber_t agno
);
142 int xfs_update_last_ag_size(struct xfs_mount
*mp
, xfs_agnumber_t prev_agcount
);
144 /* Passive AG references */
145 static inline struct xfs_perag
*
147 struct xfs_mount
*mp
,
150 return to_perag(xfs_group_get(mp
, agno
, XG_TYPE_AG
));
153 static inline struct xfs_perag
*
155 struct xfs_perag
*pag
)
157 return to_perag(xfs_group_hold(pag_group(pag
)));
162 struct xfs_perag
*pag
)
164 xfs_group_put(pag_group(pag
));
167 /* Active AG references */
168 static inline struct xfs_perag
*
170 struct xfs_mount
*mp
,
173 return to_perag(xfs_group_grab(mp
, agno
, XG_TYPE_AG
));
178 struct xfs_perag
*pag
)
180 xfs_group_rele(pag_group(pag
));
183 static inline struct xfs_perag
*
184 xfs_perag_next_range(
185 struct xfs_mount
*mp
,
186 struct xfs_perag
*pag
,
187 xfs_agnumber_t start_agno
,
188 xfs_agnumber_t end_agno
)
190 return to_perag(xfs_group_next_range(mp
, pag
? pag_group(pag
) : NULL
,
191 start_agno
, end_agno
, XG_TYPE_AG
));
194 static inline struct xfs_perag
*
196 struct xfs_mount
*mp
,
197 struct xfs_perag
*pag
,
198 xfs_agnumber_t start_agno
)
200 return xfs_perag_next_range(mp
, pag
, start_agno
, mp
->m_sb
.sb_agcount
- 1);
203 static inline struct xfs_perag
*
205 struct xfs_mount
*mp
,
206 struct xfs_perag
*pag
)
208 return xfs_perag_next_from(mp
, pag
, 0);
212 * Per-ag geometry infomation and validation
214 xfs_agblock_t
xfs_ag_block_count(struct xfs_mount
*mp
, xfs_agnumber_t agno
);
215 void xfs_agino_range(struct xfs_mount
*mp
, xfs_agnumber_t agno
,
216 xfs_agino_t
*first
, xfs_agino_t
*last
);
219 xfs_verify_agbno(struct xfs_perag
*pag
, xfs_agblock_t agbno
)
221 return xfs_verify_gbno(pag_group(pag
), agbno
);
226 struct xfs_perag
*pag
,
230 return xfs_verify_gbext(pag_group(pag
), agbno
, len
);
234 * Verify that an AG inode number pointer neither points outside the AG
235 * nor points at static metadata.
238 xfs_verify_agino(struct xfs_perag
*pag
, xfs_agino_t agino
)
240 if (agino
< pag
->agino_min
)
242 if (agino
> pag
->agino_max
)
248 * Verify that an AG inode number pointer neither points outside the AG
249 * nor points at static metadata, or is NULLAGINO.
252 xfs_verify_agino_or_null(struct xfs_perag
*pag
, xfs_agino_t agino
)
254 if (agino
== NULLAGINO
)
256 return xfs_verify_agino(pag
, agino
);
260 xfs_ag_contains_log(struct xfs_mount
*mp
, xfs_agnumber_t agno
)
262 return mp
->m_sb
.sb_logstart
> 0 &&
263 agno
== XFS_FSB_TO_AGNO(mp
, mp
->m_sb
.sb_logstart
);
266 static inline struct xfs_perag
*
268 struct xfs_perag
*pag
,
269 xfs_agnumber_t
*agno
,
270 xfs_agnumber_t stop_agno
,
271 xfs_agnumber_t restart_agno
,
272 xfs_agnumber_t wrap_agno
)
274 struct xfs_mount
*mp
= pag_mount(pag
);
276 *agno
= pag_agno(pag
) + 1;
278 while (*agno
!= stop_agno
) {
279 if (*agno
>= wrap_agno
) {
280 if (restart_agno
>= stop_agno
)
282 *agno
= restart_agno
;
285 pag
= xfs_perag_grab(mp
, *agno
);
294 * Iterate all AGs from start_agno through wrap_agno, then restart_agno through
297 #define for_each_perag_wrap_range(mp, start_agno, restart_agno, wrap_agno, agno, pag) \
298 for ((agno) = (start_agno), (pag) = xfs_perag_grab((mp), (agno)); \
300 (pag) = xfs_perag_next_wrap((pag), &(agno), (start_agno), \
301 (restart_agno), (wrap_agno)))
303 * Iterate all AGs from start_agno through wrap_agno, then 0 through
306 #define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \
307 for_each_perag_wrap_range((mp), (start_agno), 0, (wrap_agno), (agno), (pag))
310 * Iterate all AGs from start_agno through to the end of the filesystem, then 0
311 * through (start_agno - 1).
313 #define for_each_perag_wrap(mp, start_agno, agno, pag) \
314 for_each_perag_wrap_at((mp), (start_agno), (mp)->m_sb.sb_agcount, \
318 struct aghdr_init_data
{
320 xfs_agblock_t agno
; /* ag to init */
321 xfs_extlen_t agsize
; /* new AG size */
322 struct list_head buffer_list
; /* buffer writeback list */
323 xfs_rfsblock_t nfree
; /* cumulative new free space */
325 /* per header data */
326 xfs_daddr_t daddr
; /* header location */
327 size_t numblks
; /* size of header */
328 const struct xfs_btree_ops
*bc_ops
; /* btree ops */
331 int xfs_ag_init_headers(struct xfs_mount
*mp
, struct aghdr_init_data
*id
);
332 int xfs_ag_shrink_space(struct xfs_perag
*pag
, struct xfs_trans
**tpp
,
334 int xfs_ag_extend_space(struct xfs_perag
*pag
, struct xfs_trans
*tp
,
336 int xfs_ag_get_geometry(struct xfs_perag
*pag
, struct xfs_ag_geometry
*ageo
);
338 static inline xfs_fsblock_t
340 struct xfs_perag
*pag
,
343 return XFS_AGB_TO_FSB(pag_mount(pag
), pag_agno(pag
), agbno
);
346 static inline xfs_daddr_t
348 struct xfs_perag
*pag
,
351 return XFS_AGB_TO_DADDR(pag_mount(pag
), pag_agno(pag
), agbno
);
354 static inline xfs_ino_t
356 struct xfs_perag
*pag
,
359 return XFS_AGINO_TO_INO(pag_mount(pag
), pag_agno(pag
), agino
);
362 #endif /* __LIBXFS_AG_H */