xfs: active perag reference counting
[platform/kernel/linux-starfive.git] / fs / xfs / libxfs / xfs_ag.h
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         char            pagf_init;      /* this agf's entry is initialized */
39         char            pagi_init;      /* this agi's entry is initialized */
40         char            pagf_metadata;  /* the agf is preferred to be metadata */
41         char            pagi_inodeok;   /* The agi is ok for inodes */
42         uint8_t         pagf_levels[XFS_BTNUM_AGF];
43                                         /* # of levels in bno & cnt btree */
44         bool            pagf_agflreset; /* agfl requires reset before use */
45         uint32_t        pagf_flcount;   /* count of blocks in freelist */
46         xfs_extlen_t    pagf_freeblks;  /* total free blocks */
47         xfs_extlen_t    pagf_longest;   /* longest free space */
48         uint32_t        pagf_btreeblks; /* # of blocks held in AGF btrees */
49         xfs_agino_t     pagi_freecount; /* number of free inodes */
50         xfs_agino_t     pagi_count;     /* number of allocated inodes */
51
52         /*
53          * Inode allocation search lookup optimisation.
54          * If the pagino matches, the search for new inodes
55          * doesn't need to search the near ones again straight away
56          */
57         xfs_agino_t     pagl_pagino;
58         xfs_agino_t     pagl_leftrec;
59         xfs_agino_t     pagl_rightrec;
60
61         int             pagb_count;     /* pagb slots in use */
62         uint8_t         pagf_refcount_level; /* recount btree height */
63
64         /* Blocks reserved for all kinds of metadata. */
65         struct xfs_ag_resv      pag_meta_resv;
66         /* Blocks reserved for the reverse mapping btree. */
67         struct xfs_ag_resv      pag_rmapbt_resv;
68
69         /* for rcu-safe freeing */
70         struct rcu_head rcu_head;
71
72         /* Precalculated geometry info */
73         xfs_agblock_t           block_count;
74         xfs_agblock_t           min_block;
75         xfs_agino_t             agino_min;
76         xfs_agino_t             agino_max;
77
78 #ifdef __KERNEL__
79         /* -- kernel only structures below this line -- */
80
81         /*
82          * Bitsets of per-ag metadata that have been checked and/or are sick.
83          * Callers should hold pag_state_lock before accessing this field.
84          */
85         uint16_t        pag_checked;
86         uint16_t        pag_sick;
87         spinlock_t      pag_state_lock;
88
89         spinlock_t      pagb_lock;      /* lock for pagb_tree */
90         struct rb_root  pagb_tree;      /* ordered tree of busy extents */
91         unsigned int    pagb_gen;       /* generation count for pagb_tree */
92         wait_queue_head_t pagb_wait;    /* woken when pagb_gen changes */
93
94         atomic_t        pagf_fstrms;    /* # of filestreams active in this AG */
95
96         spinlock_t      pag_ici_lock;   /* incore inode cache lock */
97         struct radix_tree_root pag_ici_root;    /* incore inode cache root */
98         int             pag_ici_reclaimable;    /* reclaimable inodes */
99         unsigned long   pag_ici_reclaim_cursor; /* reclaim restart point */
100
101         /* buffer cache index */
102         spinlock_t      pag_buf_lock;   /* lock for pag_buf_hash */
103         struct rhashtable pag_buf_hash;
104
105         /* background prealloc block trimming */
106         struct delayed_work     pag_blockgc_work;
107
108 #endif /* __KERNEL__ */
109 };
110
111 int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount,
112                         xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi);
113 int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno);
114 void xfs_free_perag(struct xfs_mount *mp);
115
116 /* Passive AG references */
117 struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno);
118 struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno,
119                 unsigned int tag);
120 void xfs_perag_put(struct xfs_perag *pag);
121
122 /* Active AG references */
123 struct xfs_perag *xfs_perag_grab(struct xfs_mount *, xfs_agnumber_t);
124 struct xfs_perag *xfs_perag_grab_tag(struct xfs_mount *, xfs_agnumber_t,
125                                    int tag);
126 void xfs_perag_rele(struct xfs_perag *pag);
127
128 /*
129  * Per-ag geometry infomation and validation
130  */
131 xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno);
132 void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
133                 xfs_agino_t *first, xfs_agino_t *last);
134
135 static inline bool
136 xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno)
137 {
138         if (agbno >= pag->block_count)
139                 return false;
140         if (agbno <= pag->min_block)
141                 return false;
142         return true;
143 }
144
145 static inline bool
146 xfs_verify_agbext(
147         struct xfs_perag        *pag,
148         xfs_agblock_t           agbno,
149         xfs_agblock_t           len)
150 {
151         if (agbno + len <= agbno)
152                 return false;
153
154         if (!xfs_verify_agbno(pag, agbno))
155                 return false;
156
157         return xfs_verify_agbno(pag, agbno + len - 1);
158 }
159
160 /*
161  * Verify that an AG inode number pointer neither points outside the AG
162  * nor points at static metadata.
163  */
164 static inline bool
165 xfs_verify_agino(struct xfs_perag *pag, xfs_agino_t agino)
166 {
167         if (agino < pag->agino_min)
168                 return false;
169         if (agino > pag->agino_max)
170                 return false;
171         return true;
172 }
173
174 /*
175  * Verify that an AG inode number pointer neither points outside the AG
176  * nor points at static metadata, or is NULLAGINO.
177  */
178 static inline bool
179 xfs_verify_agino_or_null(struct xfs_perag *pag, xfs_agino_t agino)
180 {
181         if (agino == NULLAGINO)
182                 return true;
183         return xfs_verify_agino(pag, agino);
184 }
185
186 static inline bool
187 xfs_ag_contains_log(struct xfs_mount *mp, xfs_agnumber_t agno)
188 {
189         return mp->m_sb.sb_logstart > 0 &&
190                agno == XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart);
191 }
192
193 /*
194  * Perag iteration APIs
195  */
196 static inline struct xfs_perag *
197 xfs_perag_next(
198         struct xfs_perag        *pag,
199         xfs_agnumber_t          *agno,
200         xfs_agnumber_t          end_agno)
201 {
202         struct xfs_mount        *mp = pag->pag_mount;
203
204         *agno = pag->pag_agno + 1;
205         xfs_perag_rele(pag);
206         while (*agno <= end_agno) {
207                 pag = xfs_perag_grab(mp, *agno);
208                 if (pag)
209                         return pag;
210                 (*agno)++;
211         }
212         return NULL;
213 }
214
215 #define for_each_perag_range(mp, agno, end_agno, pag) \
216         for ((pag) = xfs_perag_grab((mp), (agno)); \
217                 (pag) != NULL; \
218                 (pag) = xfs_perag_next((pag), &(agno), (end_agno)))
219
220 #define for_each_perag_from(mp, agno, pag) \
221         for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount - 1, (pag))
222
223
224 #define for_each_perag(mp, agno, pag) \
225         (agno) = 0; \
226         for_each_perag_from((mp), (agno), (pag))
227
228 #define for_each_perag_tag(mp, agno, pag, tag) \
229         for ((agno) = 0, (pag) = xfs_perag_grab_tag((mp), 0, (tag)); \
230                 (pag) != NULL; \
231                 (agno) = (pag)->pag_agno + 1, \
232                 xfs_perag_rele(pag), \
233                 (pag) = xfs_perag_grab_tag((mp), (agno), (tag)))
234
235 struct aghdr_init_data {
236         /* per ag data */
237         xfs_agblock_t           agno;           /* ag to init */
238         xfs_extlen_t            agsize;         /* new AG size */
239         struct list_head        buffer_list;    /* buffer writeback list */
240         xfs_rfsblock_t          nfree;          /* cumulative new free space */
241
242         /* per header data */
243         xfs_daddr_t             daddr;          /* header location */
244         size_t                  numblks;        /* size of header */
245         xfs_btnum_t             type;           /* type of btree root block */
246 };
247
248 int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
249 int xfs_ag_shrink_space(struct xfs_perag *pag, struct xfs_trans **tpp,
250                         xfs_extlen_t delta);
251 int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp,
252                         xfs_extlen_t len);
253 int xfs_ag_get_geometry(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
254
255 #endif /* __LIBXFS_AG_H */