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  #endif /* __KERNEL__ */
105  };
106  
107  /*
108   * Per-AG operational state. These are atomic flag bits.
109   */
110  #define XFS_AGSTATE_AGF_INIT		0
111  #define XFS_AGSTATE_AGI_INIT		1
112  #define XFS_AGSTATE_PREFERS_METADATA	2
113  #define XFS_AGSTATE_ALLOWS_INODES	3
114  #define XFS_AGSTATE_AGFL_NEEDS_RESET	4
115  
116  #define __XFS_AG_OPSTATE(name, NAME) \
117  static inline bool xfs_perag_ ## name (struct xfs_perag *pag) \
118  { \
119  	return test_bit(XFS_AGSTATE_ ## NAME, &pag->pag_opstate); \
120  }
121  
122  __XFS_AG_OPSTATE(initialised_agf, AGF_INIT)
123  __XFS_AG_OPSTATE(initialised_agi, AGI_INIT)
124  __XFS_AG_OPSTATE(prefers_metadata, PREFERS_METADATA)
125  __XFS_AG_OPSTATE(allows_inodes, ALLOWS_INODES)
126  __XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET)
127  
128  int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount,
129  			xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi);
130  int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno);
131  void xfs_free_perag(struct xfs_mount *mp);
132  
133  /* Passive AG references */
134  struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno);
135  struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno,
136  		unsigned int tag);
137  void xfs_perag_put(struct xfs_perag *pag);
138  
139  /* Active AG references */
140  struct xfs_perag *xfs_perag_grab(struct xfs_mount *, xfs_agnumber_t);
141  struct xfs_perag *xfs_perag_grab_tag(struct xfs_mount *, xfs_agnumber_t,
142  				   int tag);
143  void xfs_perag_rele(struct xfs_perag *pag);
144  
145  /*
146   * Per-ag geometry infomation and validation
147   */
148  xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno);
149  void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
150  		xfs_agino_t *first, xfs_agino_t *last);
151  
152  static inline bool
xfs_verify_agbno(struct xfs_perag * pag,xfs_agblock_t agbno)153  xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno)
154  {
155  	if (agbno >= pag->block_count)
156  		return false;
157  	if (agbno <= pag->min_block)
158  		return false;
159  	return true;
160  }
161  
162  static inline bool
xfs_verify_agbext(struct xfs_perag * pag,xfs_agblock_t agbno,xfs_agblock_t len)163  xfs_verify_agbext(
164  	struct xfs_perag	*pag,
165  	xfs_agblock_t		agbno,
166  	xfs_agblock_t		len)
167  {
168  	if (agbno + len <= agbno)
169  		return false;
170  
171  	if (!xfs_verify_agbno(pag, agbno))
172  		return false;
173  
174  	return xfs_verify_agbno(pag, agbno + len - 1);
175  }
176  
177  /*
178   * Verify that an AG inode number pointer neither points outside the AG
179   * nor points at static metadata.
180   */
181  static inline bool
xfs_verify_agino(struct xfs_perag * pag,xfs_agino_t agino)182  xfs_verify_agino(struct xfs_perag *pag, xfs_agino_t agino)
183  {
184  	if (agino < pag->agino_min)
185  		return false;
186  	if (agino > pag->agino_max)
187  		return false;
188  	return true;
189  }
190  
191  /*
192   * Verify that an AG inode number pointer neither points outside the AG
193   * nor points at static metadata, or is NULLAGINO.
194   */
195  static inline bool
xfs_verify_agino_or_null(struct xfs_perag * pag,xfs_agino_t agino)196  xfs_verify_agino_or_null(struct xfs_perag *pag, xfs_agino_t agino)
197  {
198  	if (agino == NULLAGINO)
199  		return true;
200  	return xfs_verify_agino(pag, agino);
201  }
202  
203  static inline bool
xfs_ag_contains_log(struct xfs_mount * mp,xfs_agnumber_t agno)204  xfs_ag_contains_log(struct xfs_mount *mp, xfs_agnumber_t agno)
205  {
206  	return mp->m_sb.sb_logstart > 0 &&
207  	       agno == XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart);
208  }
209  
210  /*
211   * Perag iteration APIs
212   */
213  static inline struct xfs_perag *
xfs_perag_next(struct xfs_perag * pag,xfs_agnumber_t * agno,xfs_agnumber_t end_agno)214  xfs_perag_next(
215  	struct xfs_perag	*pag,
216  	xfs_agnumber_t		*agno,
217  	xfs_agnumber_t		end_agno)
218  {
219  	struct xfs_mount	*mp = pag->pag_mount;
220  
221  	*agno = pag->pag_agno + 1;
222  	xfs_perag_rele(pag);
223  	while (*agno <= end_agno) {
224  		pag = xfs_perag_grab(mp, *agno);
225  		if (pag)
226  			return pag;
227  		(*agno)++;
228  	}
229  	return NULL;
230  }
231  
232  #define for_each_perag_range(mp, agno, end_agno, pag) \
233  	for ((pag) = xfs_perag_grab((mp), (agno)); \
234  		(pag) != NULL; \
235  		(pag) = xfs_perag_next((pag), &(agno), (end_agno)))
236  
237  #define for_each_perag_from(mp, agno, pag) \
238  	for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount - 1, (pag))
239  
240  #define for_each_perag(mp, agno, pag) \
241  	(agno) = 0; \
242  	for_each_perag_from((mp), (agno), (pag))
243  
244  #define for_each_perag_tag(mp, agno, pag, tag) \
245  	for ((agno) = 0, (pag) = xfs_perag_grab_tag((mp), 0, (tag)); \
246  		(pag) != NULL; \
247  		(agno) = (pag)->pag_agno + 1, \
248  		xfs_perag_rele(pag), \
249  		(pag) = xfs_perag_grab_tag((mp), (agno), (tag)))
250  
251  static inline struct xfs_perag *
xfs_perag_next_wrap(struct xfs_perag * pag,xfs_agnumber_t * agno,xfs_agnumber_t stop_agno,xfs_agnumber_t restart_agno,xfs_agnumber_t wrap_agno)252  xfs_perag_next_wrap(
253  	struct xfs_perag	*pag,
254  	xfs_agnumber_t		*agno,
255  	xfs_agnumber_t		stop_agno,
256  	xfs_agnumber_t		restart_agno,
257  	xfs_agnumber_t		wrap_agno)
258  {
259  	struct xfs_mount	*mp = pag->pag_mount;
260  
261  	*agno = pag->pag_agno + 1;
262  	xfs_perag_rele(pag);
263  	while (*agno != stop_agno) {
264  		if (*agno >= wrap_agno) {
265  			if (restart_agno >= stop_agno)
266  				break;
267  			*agno = restart_agno;
268  		}
269  
270  		pag = xfs_perag_grab(mp, *agno);
271  		if (pag)
272  			return pag;
273  		(*agno)++;
274  	}
275  	return NULL;
276  }
277  
278  /*
279   * Iterate all AGs from start_agno through wrap_agno, then restart_agno through
280   * (start_agno - 1).
281   */
282  #define for_each_perag_wrap_range(mp, start_agno, restart_agno, wrap_agno, agno, pag) \
283  	for ((agno) = (start_agno), (pag) = xfs_perag_grab((mp), (agno)); \
284  		(pag) != NULL; \
285  		(pag) = xfs_perag_next_wrap((pag), &(agno), (start_agno), \
286  				(restart_agno), (wrap_agno)))
287  /*
288   * Iterate all AGs from start_agno through wrap_agno, then 0 through
289   * (start_agno - 1).
290   */
291  #define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \
292  	for_each_perag_wrap_range((mp), (start_agno), 0, (wrap_agno), (agno), (pag))
293  
294  /*
295   * Iterate all AGs from start_agno through to the end of the filesystem, then 0
296   * through (start_agno - 1).
297   */
298  #define for_each_perag_wrap(mp, start_agno, agno, pag) \
299  	for_each_perag_wrap_at((mp), (start_agno), (mp)->m_sb.sb_agcount, \
300  				(agno), (pag))
301  
302  
303  struct aghdr_init_data {
304  	/* per ag data */
305  	xfs_agblock_t		agno;		/* ag to init */
306  	xfs_extlen_t		agsize;		/* new AG size */
307  	struct list_head	buffer_list;	/* buffer writeback list */
308  	xfs_rfsblock_t		nfree;		/* cumulative new free space */
309  
310  	/* per header data */
311  	xfs_daddr_t		daddr;		/* header location */
312  	size_t			numblks;	/* size of header */
313  	xfs_btnum_t		type;		/* type of btree root block */
314  };
315  
316  int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
317  int xfs_ag_shrink_space(struct xfs_perag *pag, struct xfs_trans **tpp,
318  			xfs_extlen_t delta);
319  int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp,
320  			xfs_extlen_t len);
321  int xfs_ag_get_geometry(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
322  
323  #endif /* __LIBXFS_AG_H */
324