1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. |
4 | * All Rights Reserved. |
5 | */ |
6 | #ifndef __XFS_ALLOC_H__ |
7 | #define __XFS_ALLOC_H__ |
8 | |
9 | struct xfs_buf; |
10 | struct xfs_btree_cur; |
11 | struct xfs_mount; |
12 | struct xfs_perag; |
13 | struct xfs_trans; |
14 | |
15 | extern struct workqueue_struct *xfs_alloc_wq; |
16 | |
17 | unsigned int xfs_agfl_size(struct xfs_mount *mp); |
18 | |
19 | /* |
20 | * Flags for xfs_alloc_fix_freelist. |
21 | */ |
22 | #define XFS_ALLOC_FLAG_TRYLOCK (1U << 0) /* use trylock for buffer locking */ |
23 | #define XFS_ALLOC_FLAG_FREEING (1U << 1) /* indicate caller is freeing extents*/ |
24 | #define XFS_ALLOC_FLAG_NORMAP (1U << 2) /* don't modify the rmapbt */ |
25 | #define XFS_ALLOC_FLAG_NOSHRINK (1U << 3) /* don't shrink the freelist */ |
26 | #define XFS_ALLOC_FLAG_CHECK (1U << 4) /* test only, don't modify args */ |
27 | #define XFS_ALLOC_FLAG_TRYFLUSH (1U << 5) /* don't wait in busy extent flush */ |
28 | |
29 | /* |
30 | * Argument structure for xfs_alloc routines. |
31 | * This is turned into a structure to avoid having 20 arguments passed |
32 | * down several levels of the stack. |
33 | */ |
34 | typedef struct xfs_alloc_arg { |
35 | struct xfs_trans *tp; /* transaction pointer */ |
36 | struct xfs_mount *mp; /* file system mount point */ |
37 | struct xfs_buf *agbp; /* buffer for a.g. freelist header */ |
38 | struct xfs_perag *pag; /* per-ag struct for this agno */ |
39 | xfs_fsblock_t fsbno; /* file system block number */ |
40 | xfs_agnumber_t agno; /* allocation group number */ |
41 | xfs_agblock_t agbno; /* allocation group-relative block # */ |
42 | xfs_extlen_t minlen; /* minimum size of extent */ |
43 | xfs_extlen_t maxlen; /* maximum size of extent */ |
44 | xfs_extlen_t mod; /* mod value for extent size */ |
45 | xfs_extlen_t prod; /* prod value for extent size */ |
46 | xfs_extlen_t minleft; /* min blocks must be left after us */ |
47 | xfs_extlen_t total; /* total blocks needed in xaction */ |
48 | xfs_extlen_t alignment; /* align answer to multiple of this */ |
49 | xfs_extlen_t minalignslop; /* slop for minlen+alignment calcs */ |
50 | xfs_agblock_t min_agbno; /* set an agbno range for NEAR allocs */ |
51 | xfs_agblock_t max_agbno; /* ... */ |
52 | xfs_extlen_t len; /* output: actual size of extent */ |
53 | int datatype; /* mask defining data type treatment */ |
54 | char wasdel; /* set if allocation was prev delayed */ |
55 | char wasfromfl; /* set if allocation is from freelist */ |
56 | struct xfs_owner_info oinfo; /* owner of blocks being allocated */ |
57 | enum xfs_ag_resv_type resv; /* block reservation to use */ |
58 | #ifdef DEBUG |
59 | bool alloc_minlen_only; /* allocate exact minlen extent */ |
60 | #endif |
61 | } xfs_alloc_arg_t; |
62 | |
63 | /* |
64 | * Defines for datatype |
65 | */ |
66 | #define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/ |
67 | #define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */ |
68 | #define XFS_ALLOC_NOBUSY (1 << 2)/* Busy extents not allowed */ |
69 | |
70 | /* freespace limit calculations */ |
71 | unsigned int xfs_alloc_set_aside(struct xfs_mount *mp); |
72 | unsigned int xfs_alloc_ag_max_usable(struct xfs_mount *mp); |
73 | |
74 | xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_perag *pag, |
75 | xfs_extlen_t need, xfs_extlen_t reserved); |
76 | unsigned int xfs_alloc_min_freelist(struct xfs_mount *mp, |
77 | struct xfs_perag *pag); |
78 | int xfs_alloc_get_freelist(struct xfs_perag *pag, struct xfs_trans *tp, |
79 | struct xfs_buf *agfbp, xfs_agblock_t *bnop, int btreeblk); |
80 | int xfs_alloc_put_freelist(struct xfs_perag *pag, struct xfs_trans *tp, |
81 | struct xfs_buf *agfbp, struct xfs_buf *agflbp, |
82 | xfs_agblock_t bno, int btreeblk); |
83 | |
84 | /* |
85 | * Compute and fill in value of m_alloc_maxlevels. |
86 | */ |
87 | void |
88 | xfs_alloc_compute_maxlevels( |
89 | struct xfs_mount *mp); /* file system mount structure */ |
90 | |
91 | /* |
92 | * Log the given fields from the agf structure. |
93 | */ |
94 | void |
95 | xfs_alloc_log_agf( |
96 | struct xfs_trans *tp, /* transaction pointer */ |
97 | struct xfs_buf *bp, /* buffer for a.g. freelist header */ |
98 | uint32_t fields);/* mask of fields to be logged (XFS_AGF_...) */ |
99 | |
100 | /* |
101 | * Allocate an extent anywhere in the specific AG given. If there is no |
102 | * space matching the requirements in that AG, then the allocation will fail. |
103 | */ |
104 | int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args, xfs_agnumber_t agno); |
105 | |
106 | /* |
107 | * Allocate an extent as close to the target as possible. If there are not |
108 | * viable candidates in the AG, then fail the allocation. |
109 | */ |
110 | int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args, |
111 | xfs_fsblock_t target); |
112 | |
113 | /* |
114 | * Allocate an extent exactly at the target given. If this is not possible |
115 | * then the allocation fails. |
116 | */ |
117 | int xfs_alloc_vextent_exact_bno(struct xfs_alloc_arg *args, |
118 | xfs_fsblock_t target); |
119 | |
120 | /* |
121 | * Best effort full filesystem allocation scan. |
122 | * |
123 | * Locality aware allocation will be attempted in the initial AG, but on failure |
124 | * non-localised attempts will be made. The AGs are constrained by previous |
125 | * allocations in the current transaction. Two passes will be made - the first |
126 | * non-blocking, the second blocking. |
127 | */ |
128 | int xfs_alloc_vextent_start_ag(struct xfs_alloc_arg *args, |
129 | xfs_fsblock_t target); |
130 | |
131 | /* |
132 | * Iterate from the AG indicated from args->fsbno through to the end of the |
133 | * filesystem attempting blocking allocation. This is for use in last |
134 | * resort allocation attempts when everything else has failed. |
135 | */ |
136 | int xfs_alloc_vextent_first_ag(struct xfs_alloc_arg *args, |
137 | xfs_fsblock_t target); |
138 | |
139 | /* |
140 | * Free an extent. |
141 | */ |
142 | int /* error */ |
143 | __xfs_free_extent( |
144 | struct xfs_trans *tp, /* transaction pointer */ |
145 | struct xfs_perag *pag, |
146 | xfs_agblock_t agbno, |
147 | xfs_extlen_t len, /* length of extent */ |
148 | const struct xfs_owner_info *oinfo, /* extent owner */ |
149 | enum xfs_ag_resv_type type, /* block reservation type */ |
150 | bool skip_discard); |
151 | |
152 | static inline int |
153 | xfs_free_extent( |
154 | struct xfs_trans *tp, |
155 | struct xfs_perag *pag, |
156 | xfs_agblock_t agbno, |
157 | xfs_extlen_t len, |
158 | const struct xfs_owner_info *oinfo, |
159 | enum xfs_ag_resv_type type) |
160 | { |
161 | return __xfs_free_extent(tp, pag, agbno, len, oinfo, type, false); |
162 | } |
163 | |
164 | int /* error */ |
165 | xfs_alloc_lookup_le( |
166 | struct xfs_btree_cur *cur, /* btree cursor */ |
167 | xfs_agblock_t bno, /* starting block of extent */ |
168 | xfs_extlen_t len, /* length of extent */ |
169 | int *stat); /* success/failure */ |
170 | |
171 | int /* error */ |
172 | xfs_alloc_lookup_ge( |
173 | struct xfs_btree_cur *cur, /* btree cursor */ |
174 | xfs_agblock_t bno, /* starting block of extent */ |
175 | xfs_extlen_t len, /* length of extent */ |
176 | int *stat); /* success/failure */ |
177 | |
178 | int /* error */ |
179 | xfs_alloc_get_rec( |
180 | struct xfs_btree_cur *cur, /* btree cursor */ |
181 | xfs_agblock_t *bno, /* output: starting block of extent */ |
182 | xfs_extlen_t *len, /* output: length of extent */ |
183 | int *stat); /* output: success/failure */ |
184 | |
185 | union xfs_btree_rec; |
186 | void xfs_alloc_btrec_to_irec(const union xfs_btree_rec *rec, |
187 | struct xfs_alloc_rec_incore *irec); |
188 | xfs_failaddr_t xfs_alloc_check_irec(struct xfs_perag *pag, |
189 | const struct xfs_alloc_rec_incore *irec); |
190 | |
191 | int xfs_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, |
192 | struct xfs_buf **agfbpp); |
193 | int xfs_alloc_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, |
194 | struct xfs_buf **agfbpp); |
195 | int xfs_alloc_read_agfl(struct xfs_perag *pag, struct xfs_trans *tp, |
196 | struct xfs_buf **bpp); |
197 | int xfs_free_agfl_block(struct xfs_trans *, xfs_agnumber_t, xfs_agblock_t, |
198 | struct xfs_buf *, struct xfs_owner_info *); |
199 | int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args, uint32_t alloc_flags); |
200 | int xfs_free_extent_fix_freelist(struct xfs_trans *tp, struct xfs_perag *pag, |
201 | struct xfs_buf **agbp); |
202 | |
203 | xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp); |
204 | |
205 | typedef int (*xfs_alloc_query_range_fn)( |
206 | struct xfs_btree_cur *cur, |
207 | const struct xfs_alloc_rec_incore *rec, |
208 | void *priv); |
209 | |
210 | int xfs_alloc_query_range(struct xfs_btree_cur *cur, |
211 | const struct xfs_alloc_rec_incore *low_rec, |
212 | const struct xfs_alloc_rec_incore *high_rec, |
213 | xfs_alloc_query_range_fn fn, void *priv); |
214 | int xfs_alloc_query_all(struct xfs_btree_cur *cur, xfs_alloc_query_range_fn fn, |
215 | void *priv); |
216 | |
217 | int xfs_alloc_has_records(struct xfs_btree_cur *cur, xfs_agblock_t bno, |
218 | xfs_extlen_t len, enum xbtree_recpacking *outcome); |
219 | |
220 | typedef int (*xfs_agfl_walk_fn)(struct xfs_mount *mp, xfs_agblock_t bno, |
221 | void *priv); |
222 | int xfs_agfl_walk(struct xfs_mount *mp, struct xfs_agf *agf, |
223 | struct xfs_buf *agflbp, xfs_agfl_walk_fn walk_fn, void *priv); |
224 | |
225 | static inline __be32 * |
226 | xfs_buf_to_agfl_bno( |
227 | struct xfs_buf *bp) |
228 | { |
229 | if (xfs_has_crc(bp->b_mount)) |
230 | return bp->b_addr + sizeof(struct xfs_agfl); |
231 | return bp->b_addr; |
232 | } |
233 | |
234 | int xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno, |
235 | xfs_filblks_t len, const struct xfs_owner_info *oinfo, |
236 | enum xfs_ag_resv_type type, bool skip_discard); |
237 | |
238 | /* |
239 | * List of extents to be free "later". |
240 | * The list is kept sorted on xbf_startblock. |
241 | */ |
242 | struct xfs_extent_free_item { |
243 | struct list_head xefi_list; |
244 | uint64_t xefi_owner; |
245 | xfs_fsblock_t xefi_startblock;/* starting fs block number */ |
246 | xfs_extlen_t xefi_blockcount;/* number of blocks in extent */ |
247 | struct xfs_perag *xefi_pag; |
248 | unsigned int xefi_flags; |
249 | enum xfs_ag_resv_type xefi_agresv; |
250 | }; |
251 | |
252 | void xfs_extent_free_get_group(struct xfs_mount *mp, |
253 | struct xfs_extent_free_item *xefi); |
254 | |
255 | #define XFS_EFI_SKIP_DISCARD (1U << 0) /* don't issue discard */ |
256 | #define XFS_EFI_ATTR_FORK (1U << 1) /* freeing attr fork block */ |
257 | #define XFS_EFI_BMBT_BLOCK (1U << 2) /* freeing bmap btree block */ |
258 | #define XFS_EFI_CANCELLED (1U << 3) /* dont actually free the space */ |
259 | |
260 | struct xfs_alloc_autoreap { |
261 | struct xfs_defer_pending *dfp; |
262 | }; |
263 | |
264 | int xfs_alloc_schedule_autoreap(const struct xfs_alloc_arg *args, |
265 | bool skip_discard, struct xfs_alloc_autoreap *aarp); |
266 | void xfs_alloc_cancel_autoreap(struct xfs_trans *tp, |
267 | struct xfs_alloc_autoreap *aarp); |
268 | void xfs_alloc_commit_autoreap(struct xfs_trans *tp, |
269 | struct xfs_alloc_autoreap *aarp); |
270 | |
271 | extern struct kmem_cache *xfs_extfree_item_cache; |
272 | |
273 | int __init xfs_extfree_intent_init_cache(void); |
274 | void xfs_extfree_intent_destroy_cache(void); |
275 | |
276 | xfs_failaddr_t xfs_validate_ag_length(struct xfs_buf *bp, uint32_t seqno, |
277 | uint32_t length); |
278 | |
279 | #endif /* __XFS_ALLOC_H__ */ |
280 | |