Commit | Line | Data |
---|---|---|
508578f2 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1da177e4 | 2 | /* |
7b718769 NS |
3 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. |
4 | * All Rights Reserved. | |
1da177e4 LT |
5 | */ |
6 | #ifndef __XFS_ALLOC_H__ | |
7 | #define __XFS_ALLOC_H__ | |
8 | ||
9 | struct xfs_buf; | |
a46db608 | 10 | struct xfs_btree_cur; |
1da177e4 LT |
11 | struct xfs_mount; |
12 | struct xfs_perag; | |
13 | struct xfs_trans; | |
14 | ||
c999a223 DC |
15 | extern struct workqueue_struct *xfs_alloc_wq; |
16 | ||
a78ee256 DC |
17 | unsigned int xfs_agfl_size(struct xfs_mount *mp); |
18 | ||
1da177e4 LT |
19 | /* |
20 | * Flags for xfs_alloc_fix_freelist. | |
21 | */ | |
8ebbf262 DC |
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 */ | |
1da177e4 LT |
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 */ | |
bfe46d4e BF |
50 | xfs_agblock_t min_agbno; /* set an agbno range for NEAR allocs */ |
51 | xfs_agblock_t max_agbno; /* ... */ | |
1da177e4 | 52 | xfs_extlen_t len; /* output: actual size of extent */ |
292378ed | 53 | int datatype; /* mask defining data type treatment */ |
1da177e4 LT |
54 | char wasdel; /* set if allocation was prev delayed */ |
55 | char wasfromfl; /* set if allocation is from freelist */ | |
340785cc | 56 | struct xfs_owner_info oinfo; /* owner of blocks being allocated */ |
3fd129b6 | 57 | enum xfs_ag_resv_type resv; /* block reservation to use */ |
30151967 CB |
58 | #ifdef DEBUG |
59 | bool alloc_minlen_only; /* allocate exact minlen extent */ | |
60 | #endif | |
1da177e4 LT |
61 | } xfs_alloc_arg_t; |
62 | ||
63 | /* | |
292378ed | 64 | * Defines for datatype |
1da177e4 | 65 | */ |
ce840429 DW |
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 */ | |
fd638f1d | 68 | #define XFS_ALLOC_NOBUSY (1 << 2)/* Busy extents not allowed */ |
292378ed | 69 | |
52548852 | 70 | /* freespace limit calculations */ |
52548852 DW |
71 | unsigned int xfs_alloc_set_aside(struct xfs_mount *mp); |
72 | unsigned int xfs_alloc_ag_max_usable(struct xfs_mount *mp); | |
73 | ||
a1f69417 ES |
74 | xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_perag *pag, |
75 | xfs_extlen_t need, xfs_extlen_t reserved); | |
496817b4 | 76 | unsigned int xfs_alloc_min_freelist(struct xfs_mount *mp, |
6cc87645 | 77 | struct xfs_perag *pag); |
49f0d84e DC |
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); | |
8c392eb2 DC |
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); | |
1da177e4 | 83 | |
1da177e4 | 84 | /* |
7cb3efb4 | 85 | * Compute and fill in value of m_alloc_maxlevels. |
1da177e4 LT |
86 | */ |
87 | void | |
88 | xfs_alloc_compute_maxlevels( | |
89 | struct xfs_mount *mp); /* file system mount structure */ | |
90 | ||
1da177e4 LT |
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 */ | |
f53dde11 | 98 | uint32_t fields);/* mask of fields to be logged (XFS_AGF_...) */ |
1da177e4 | 99 | |
74c36a86 | 100 | /* |
5f36b2ce DC |
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. | |
74c36a86 | 103 | */ |
5f36b2ce | 104 | int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args, xfs_agnumber_t agno); |
74c36a86 | 105 | |
db4710fd DC |
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 | ||
5f36b2ce DC |
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 | ||
2a7f6d41 DC |
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 | ||
319c9e87 DC |
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 | ||
1da177e4 LT |
139 | /* |
140 | * Free an extent. | |
141 | */ | |
142 | int /* error */ | |
fcb762f5 | 143 | __xfs_free_extent( |
340785cc | 144 | struct xfs_trans *tp, /* transaction pointer */ |
b2ccab31 DW |
145 | struct xfs_perag *pag, |
146 | xfs_agblock_t agbno, | |
340785cc | 147 | xfs_extlen_t len, /* length of extent */ |
66e3237e | 148 | const struct xfs_owner_info *oinfo, /* extent owner */ |
fcb762f5 BF |
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, | |
b2ccab31 DW |
155 | struct xfs_perag *pag, |
156 | xfs_agblock_t agbno, | |
fcb762f5 | 157 | xfs_extlen_t len, |
66e3237e | 158 | const struct xfs_owner_info *oinfo, |
fcb762f5 BF |
159 | enum xfs_ag_resv_type type) |
160 | { | |
b2ccab31 | 161 | return __xfs_free_extent(tp, pag, agbno, len, oinfo, type, false); |
fcb762f5 BF |
162 | } |
163 | ||
ce1d802e DW |
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 | ||
a66d6363 DC |
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 | ||
a46db608 CH |
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 | ||
35e3b9a1 DW |
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_btree_cur *cur, | |
189 | const struct xfs_alloc_rec_incore *irec); | |
190 | ||
fa044ae7 DC |
191 | int xfs_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, |
192 | struct xfs_buf **agfbpp); | |
08d3e84f DC |
193 | int xfs_alloc_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, |
194 | struct xfs_buf **agfbpp); | |
cec7bb7d DC |
195 | int xfs_alloc_read_agfl(struct xfs_perag *pag, struct xfs_trans *tp, |
196 | struct xfs_buf **bpp); | |
4223f659 BF |
197 | int xfs_free_agfl_block(struct xfs_trans *, xfs_agnumber_t, xfs_agblock_t, |
198 | struct xfs_buf *, struct xfs_owner_info *); | |
6a2a9d77 | 199 | int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args, uint32_t alloc_flags); |
45d06621 | 200 | int xfs_free_extent_fix_freelist(struct xfs_trans *tp, struct xfs_perag *pag, |
4d89e20b | 201 | struct xfs_buf **agbp); |
4fb6e8ad | 202 | |
8018026e DW |
203 | xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp); |
204 | ||
2d520bfa | 205 | typedef int (*xfs_alloc_query_range_fn)( |
159eb69d DW |
206 | struct xfs_btree_cur *cur, |
207 | const struct xfs_alloc_rec_incore *rec, | |
208 | void *priv); | |
2d520bfa DW |
209 | |
210 | int xfs_alloc_query_range(struct xfs_btree_cur *cur, | |
04dcb474 DW |
211 | const struct xfs_alloc_rec_incore *low_rec, |
212 | const struct xfs_alloc_rec_incore *high_rec, | |
2d520bfa | 213 | xfs_alloc_query_range_fn fn, void *priv); |
e9a2599a DW |
214 | int xfs_alloc_query_all(struct xfs_btree_cur *cur, xfs_alloc_query_range_fn fn, |
215 | void *priv); | |
2d520bfa | 216 | |
6abc7aef DW |
217 | int xfs_alloc_has_records(struct xfs_btree_cur *cur, xfs_agblock_t bno, |
218 | xfs_extlen_t len, enum xbtree_recpacking *outcome); | |
ce1d802e | 219 | |
9f3a080e DW |
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 | ||
183606d8 CH |
225 | static inline __be32 * |
226 | xfs_buf_to_agfl_bno( | |
227 | struct xfs_buf *bp) | |
228 | { | |
ebd9027d | 229 | if (xfs_has_crc(bp->b_mount)) |
183606d8 CH |
230 | return bp->b_addr + sizeof(struct xfs_agfl); |
231 | return bp->b_addr; | |
232 | } | |
233 | ||
7dfee17b | 234 | int __xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno, |
c201d9ca | 235 | xfs_filblks_t len, const struct xfs_owner_info *oinfo, |
b742d7b4 | 236 | enum xfs_ag_resv_type type, bool skip_discard); |
c201d9ca DW |
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; | |
b3b5ff41 | 244 | uint64_t xefi_owner; |
c201d9ca DW |
245 | xfs_fsblock_t xefi_startblock;/* starting fs block number */ |
246 | xfs_extlen_t xefi_blockcount;/* number of blocks in extent */ | |
f6b38463 | 247 | struct xfs_perag *xefi_pag; |
b3b5ff41 | 248 | unsigned int xefi_flags; |
b742d7b4 | 249 | enum xfs_ag_resv_type xefi_agresv; |
c201d9ca DW |
250 | }; |
251 | ||
f6b38463 DW |
252 | void xfs_extent_free_get_group(struct xfs_mount *mp, |
253 | struct xfs_extent_free_item *xefi); | |
254 | ||
b3b5ff41 DW |
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 | ||
7dfee17b | 259 | static inline int |
c201d9ca DW |
260 | xfs_free_extent_later( |
261 | struct xfs_trans *tp, | |
262 | xfs_fsblock_t bno, | |
263 | xfs_filblks_t len, | |
b742d7b4 DC |
264 | const struct xfs_owner_info *oinfo, |
265 | enum xfs_ag_resv_type type) | |
c201d9ca | 266 | { |
b742d7b4 | 267 | return __xfs_free_extent_later(tp, bno, len, oinfo, type, false); |
c201d9ca DW |
268 | } |
269 | ||
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 | ||
1da177e4 | 276 | #endif /* __XFS_ALLOC_H__ */ |