blob: 95157f5a5a6c0f7cf41ace1292dc34fd67eed725 [file] [log] [blame]
Dave Chinner0b61f8a2018-06-05 19:42:14 -07001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
Nathan Scott7b718762005-11-02 14:58:39 +11003 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006#include "xfs.h"
Nathan Scotta844f452005-11-02 14:38:42 +11007#include "xfs_fs.h"
Dave Chinner70a98832013-10-23 10:36:05 +11008#include "xfs_format.h"
Dave Chinner239880e2013-10-23 10:50:10 +11009#include "xfs_log_format.h"
Dave Chinner70a98832013-10-23 10:36:05 +110010#include "xfs_shared.h"
Dave Chinner239880e2013-10-23 10:50:10 +110011#include "xfs_trans_resv.h"
Nathan Scotta844f452005-11-02 14:38:42 +110012#include "xfs_bit.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include "xfs_mount.h"
Darrick J. Wong3ab78df2016-08-03 11:15:38 +100014#include "xfs_defer.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include "xfs_btree.h"
Darrick J. Wong673930c2016-08-03 11:33:43 +100016#include "xfs_rmap.h"
Dave Chinnera4fbe6a2013-10-23 10:51:50 +110017#include "xfs_alloc_btree.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include "xfs_alloc.h"
Dave Chinnerefc27b52012-04-29 10:39:43 +000019#include "xfs_extent_busy.h"
Darrick J. Wonge9e899a2017-10-31 12:04:49 -070020#include "xfs_errortag.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include "xfs_error.h"
Christoph Hellwig0b1b2132009-12-14 23:14:59 +000022#include "xfs_trace.h"
Dave Chinner239880e2013-10-23 10:50:10 +110023#include "xfs_trans.h"
Dave Chinner4e0e6042013-04-03 16:11:13 +110024#include "xfs_buf_item.h"
Dave Chinner239880e2013-10-23 10:50:10 +110025#include "xfs_log.h"
Dave Chinner9bbafc712021-06-02 10:48:24 +100026#include "xfs_ag.h"
Darrick J. Wong3fd129b2016-09-19 10:30:52 +100027#include "xfs_ag_resv.h"
Brian Fosterf8f28352018-05-07 17:38:47 -070028#include "xfs_bmap.h"
29
30extern kmem_zone_t *xfs_bmap_free_item_zone;
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Dave Chinnerc999a222012-03-22 05:15:07 +000032struct workqueue_struct *xfs_alloc_wq;
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
34#define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b)))
35
36#define XFSA_FIXUP_BNO_OK 1
37#define XFSA_FIXUP_CNT_OK 2
38
Linus Torvalds1da177e2005-04-16 15:20:36 -070039STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *);
40STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *);
41STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Dave Chinnera78ee252018-03-06 17:08:32 -080043/*
44 * Size of the AGFL. For CRC-enabled filesystes we steal a couple of slots in
45 * the beginning of the block for a proper header with the location information
46 * and CRC.
47 */
48unsigned int
49xfs_agfl_size(
50 struct xfs_mount *mp)
51{
52 unsigned int size = mp->m_sb.sb_sectsize;
53
Dave Chinner38c26bf2021-08-18 18:46:37 -070054 if (xfs_has_crc(mp))
Dave Chinnera78ee252018-03-06 17:08:32 -080055 size -= sizeof(struct xfs_agfl);
56
57 return size / sizeof(xfs_agblock_t);
58}
59
Darrick J. Wongaf30dfa2016-10-03 09:11:17 -070060unsigned int
61xfs_refc_block(
62 struct xfs_mount *mp)
63{
Dave Chinner38c26bf2021-08-18 18:46:37 -070064 if (xfs_has_rmapbt(mp))
Darrick J. Wongaf30dfa2016-10-03 09:11:17 -070065 return XFS_RMAP_BLOCK(mp) + 1;
Dave Chinner38c26bf2021-08-18 18:46:37 -070066 if (xfs_has_finobt(mp))
Darrick J. Wongaf30dfa2016-10-03 09:11:17 -070067 return XFS_FIBT_BLOCK(mp) + 1;
68 return XFS_IBT_BLOCK(mp) + 1;
69}
70
Darrick J. Wong80180262016-08-03 11:31:47 +100071xfs_extlen_t
72xfs_prealloc_blocks(
73 struct xfs_mount *mp)
74{
Dave Chinner38c26bf2021-08-18 18:46:37 -070075 if (xfs_has_reflink(mp))
Darrick J. Wongaf30dfa2016-10-03 09:11:17 -070076 return xfs_refc_block(mp) + 1;
Dave Chinner38c26bf2021-08-18 18:46:37 -070077 if (xfs_has_rmapbt(mp))
Darrick J. Wong80180262016-08-03 11:31:47 +100078 return XFS_RMAP_BLOCK(mp) + 1;
Dave Chinner38c26bf2021-08-18 18:46:37 -070079 if (xfs_has_finobt(mp))
Darrick J. Wong80180262016-08-03 11:31:47 +100080 return XFS_FIBT_BLOCK(mp) + 1;
81 return XFS_IBT_BLOCK(mp) + 1;
82}
83
Linus Torvalds1da177e2005-04-16 15:20:36 -070084/*
Darrick J. Wong52548852016-08-03 11:38:24 +100085 * In order to avoid ENOSPC-related deadlock caused by out-of-order locking of
86 * AGF buffer (PV 947395), we place constraints on the relationship among
87 * actual allocations for data blocks, freelist blocks, and potential file data
88 * bmap btree blocks. However, these restrictions may result in no actual space
89 * allocated for a delayed extent, for example, a data block in a certain AG is
90 * allocated but there is no additional block for the additional bmap btree
91 * block due to a split of the bmap btree of the file. The result of this may
92 * lead to an infinite loop when the file gets flushed to disk and all delayed
93 * extents need to be actually allocated. To get around this, we explicitly set
94 * aside a few blocks which will not be reserved in delayed allocation.
95 *
Darrick J. Wong3fd129b2016-09-19 10:30:52 +100096 * We need to reserve 4 fsbs _per AG_ for the freelist and 4 more to handle a
97 * potential split of the file's bmap btree.
Darrick J. Wong52548852016-08-03 11:38:24 +100098 */
99unsigned int
100xfs_alloc_set_aside(
101 struct xfs_mount *mp)
102{
Christoph Hellwig5149fd32017-01-09 13:36:30 -0800103 return mp->m_sb.sb_agcount * (XFS_ALLOC_AGFL_RESERVE + 4);
Darrick J. Wong52548852016-08-03 11:38:24 +1000104}
105
106/*
107 * When deciding how much space to allocate out of an AG, we limit the
108 * allocation maximum size to the size the AG. However, we cannot use all the
109 * blocks in the AG - some are permanently used by metadata. These
110 * blocks are generally:
111 * - the AG superblock, AGF, AGI and AGFL
112 * - the AGF (bno and cnt) and AGI btree root blocks, and optionally
113 * the AGI free inode and rmap btree root blocks.
114 * - blocks on the AGFL according to xfs_alloc_set_aside() limits
115 * - the rmapbt root block
116 *
117 * The AG headers are sector sized, so the amount of space they take up is
118 * dependent on filesystem geometry. The others are all single blocks.
119 */
120unsigned int
121xfs_alloc_ag_max_usable(
122 struct xfs_mount *mp)
123{
124 unsigned int blocks;
125
126 blocks = XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)); /* ag headers */
127 blocks += XFS_ALLOC_AGFL_RESERVE;
128 blocks += 3; /* AGF, AGI btree root blocks */
Dave Chinner38c26bf2021-08-18 18:46:37 -0700129 if (xfs_has_finobt(mp))
Darrick J. Wong52548852016-08-03 11:38:24 +1000130 blocks++; /* finobt root block */
Dave Chinner38c26bf2021-08-18 18:46:37 -0700131 if (xfs_has_rmapbt(mp))
Darrick J. Wong52548852016-08-03 11:38:24 +1000132 blocks++; /* rmap root block */
Dave Chinner38c26bf2021-08-18 18:46:37 -0700133 if (xfs_has_reflink(mp))
Darrick J. Wongd0e853f2016-10-03 09:11:24 -0700134 blocks++; /* refcount root block */
Darrick J. Wong52548852016-08-03 11:38:24 +1000135
136 return mp->m_sb.sb_agblocks - blocks;
137}
138
139/*
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100140 * Lookup the record equal to [bno, len] in the btree given by cur.
141 */
142STATIC int /* error */
143xfs_alloc_lookup_eq(
144 struct xfs_btree_cur *cur, /* btree cursor */
145 xfs_agblock_t bno, /* starting block of extent */
146 xfs_extlen_t len, /* length of extent */
147 int *stat) /* success/failure */
148{
Brian Fosterf6b428a2019-10-13 17:10:31 -0700149 int error;
150
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100151 cur->bc_rec.a.ar_startblock = bno;
152 cur->bc_rec.a.ar_blockcount = len;
Brian Fosterf6b428a2019-10-13 17:10:31 -0700153 error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
Dave Chinnerc4aa10d2020-03-10 17:57:51 -0700154 cur->bc_ag.abt.active = (*stat == 1);
Brian Fosterf6b428a2019-10-13 17:10:31 -0700155 return error;
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100156}
157
158/*
159 * Lookup the first record greater than or equal to [bno, len]
160 * in the btree given by cur.
161 */
Dave Chinnera66d6362012-03-22 05:15:12 +0000162int /* error */
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100163xfs_alloc_lookup_ge(
164 struct xfs_btree_cur *cur, /* btree cursor */
165 xfs_agblock_t bno, /* starting block of extent */
166 xfs_extlen_t len, /* length of extent */
167 int *stat) /* success/failure */
168{
Brian Fosterf6b428a2019-10-13 17:10:31 -0700169 int error;
170
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100171 cur->bc_rec.a.ar_startblock = bno;
172 cur->bc_rec.a.ar_blockcount = len;
Brian Fosterf6b428a2019-10-13 17:10:31 -0700173 error = xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
Dave Chinnerc4aa10d2020-03-10 17:57:51 -0700174 cur->bc_ag.abt.active = (*stat == 1);
Brian Fosterf6b428a2019-10-13 17:10:31 -0700175 return error;
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100176}
177
178/*
179 * Lookup the first record less than or equal to [bno, len]
180 * in the btree given by cur.
181 */
Darrick J. Wongce1d8022018-01-16 18:52:12 -0800182int /* error */
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100183xfs_alloc_lookup_le(
184 struct xfs_btree_cur *cur, /* btree cursor */
185 xfs_agblock_t bno, /* starting block of extent */
186 xfs_extlen_t len, /* length of extent */
187 int *stat) /* success/failure */
188{
Brian Fosterf6b428a2019-10-13 17:10:31 -0700189 int error;
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100190 cur->bc_rec.a.ar_startblock = bno;
191 cur->bc_rec.a.ar_blockcount = len;
Brian Fosterf6b428a2019-10-13 17:10:31 -0700192 error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
Dave Chinnerc4aa10d2020-03-10 17:57:51 -0700193 cur->bc_ag.abt.active = (*stat == 1);
Brian Fosterf6b428a2019-10-13 17:10:31 -0700194 return error;
195}
196
197static inline bool
198xfs_alloc_cur_active(
199 struct xfs_btree_cur *cur)
200{
Dave Chinnerc4aa10d2020-03-10 17:57:51 -0700201 return cur && cur->bc_ag.abt.active;
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100202}
203
Christoph Hellwig278d0ca2008-10-30 16:56:32 +1100204/*
205 * Update the record referred to by cur to the value given
206 * by [bno, len].
207 * This either works (return 0) or gets an EFSCORRUPTED error.
208 */
209STATIC int /* error */
210xfs_alloc_update(
211 struct xfs_btree_cur *cur, /* btree cursor */
212 xfs_agblock_t bno, /* starting block of extent */
213 xfs_extlen_t len) /* length of extent */
214{
215 union xfs_btree_rec rec;
216
217 rec.alloc.ar_startblock = cpu_to_be32(bno);
218 rec.alloc.ar_blockcount = cpu_to_be32(len);
219 return xfs_btree_update(cur, &rec);
220}
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100221
222/*
Christoph Hellwig8cc938f2008-10-30 16:58:11 +1100223 * Get the data from the pointed-to record.
224 */
Christoph Hellwiga46db602011-01-07 13:02:04 +0000225int /* error */
Christoph Hellwig8cc938f2008-10-30 16:58:11 +1100226xfs_alloc_get_rec(
227 struct xfs_btree_cur *cur, /* btree cursor */
228 xfs_agblock_t *bno, /* output: starting block of extent */
229 xfs_extlen_t *len, /* output: length of extent */
230 int *stat) /* output: success/failure */
231{
Dave Chinner9e6c08d2018-06-05 19:42:13 -0700232 struct xfs_mount *mp = cur->bc_mp;
Dave Chinner50f02fe2021-06-02 10:48:24 +1000233 xfs_agnumber_t agno = cur->bc_ag.pag->pag_agno;
Christoph Hellwig8cc938f2008-10-30 16:58:11 +1100234 union xfs_btree_rec *rec;
235 int error;
236
237 error = xfs_btree_get_rec(cur, &rec, stat);
Darrick J. Wonga37f7b12018-06-03 16:10:14 -0700238 if (error || !(*stat))
239 return error;
Darrick J. Wonga37f7b12018-06-03 16:10:14 -0700240
241 *bno = be32_to_cpu(rec->alloc.ar_startblock);
242 *len = be32_to_cpu(rec->alloc.ar_blockcount);
243
Carlos Maiolinoefe80322018-07-11 22:26:36 -0700244 if (*len == 0)
245 goto out_bad_rec;
246
Dave Chinner9e6c08d2018-06-05 19:42:13 -0700247 /* check for valid extent range, including overflow */
248 if (!xfs_verify_agbno(mp, agno, *bno))
249 goto out_bad_rec;
250 if (*bno > *bno + *len)
251 goto out_bad_rec;
252 if (!xfs_verify_agbno(mp, agno, *bno + *len - 1))
253 goto out_bad_rec;
254
255 return 0;
256
257out_bad_rec:
258 xfs_warn(mp,
259 "%s Freespace BTree record corruption in AG %d detected!",
260 cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size", agno);
261 xfs_warn(mp,
262 "start block 0x%x block count 0x%x", *bno, *len);
263 return -EFSCORRUPTED;
Christoph Hellwig8cc938f2008-10-30 16:58:11 +1100264}
265
266/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 * Compute aligned version of the found extent.
268 * Takes alignment and min length into account.
269 */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800270STATIC bool
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271xfs_alloc_compute_aligned(
Christoph Hellwig86fa8af2011-03-04 12:59:54 +0000272 xfs_alloc_arg_t *args, /* allocation argument structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 xfs_agblock_t foundbno, /* starting block in found extent */
274 xfs_extlen_t foundlen, /* length in found extent */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 xfs_agblock_t *resbno, /* result block number */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800276 xfs_extlen_t *reslen, /* result length */
277 unsigned *busy_gen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278{
Christoph Hellwigebf55872017-02-07 14:06:57 -0800279 xfs_agblock_t bno = foundbno;
280 xfs_extlen_t len = foundlen;
Brian Fosterbfe46d42015-05-29 08:53:00 +1000281 xfs_extlen_t diff;
Christoph Hellwigebf55872017-02-07 14:06:57 -0800282 bool busy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283
Christoph Hellwige26f0502011-04-24 19:06:15 +0000284 /* Trim busy sections out of found extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800285 busy = xfs_extent_busy_trim(args, &bno, &len, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +0000286
Brian Fosterbfe46d42015-05-29 08:53:00 +1000287 /*
288 * If we have a largish extent that happens to start before min_agbno,
289 * see if we can shift it into range...
290 */
291 if (bno < args->min_agbno && bno + len > args->min_agbno) {
292 diff = args->min_agbno - bno;
293 if (len > diff) {
294 bno += diff;
295 len -= diff;
296 }
297 }
298
Christoph Hellwige26f0502011-04-24 19:06:15 +0000299 if (args->alignment > 1 && len >= args->minlen) {
300 xfs_agblock_t aligned_bno = roundup(bno, args->alignment);
Brian Fosterbfe46d42015-05-29 08:53:00 +1000301
302 diff = aligned_bno - bno;
Christoph Hellwige26f0502011-04-24 19:06:15 +0000303
304 *resbno = aligned_bno;
305 *reslen = diff >= len ? 0 : len - diff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 } else {
Christoph Hellwige26f0502011-04-24 19:06:15 +0000307 *resbno = bno;
308 *reslen = len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 }
Christoph Hellwigebf55872017-02-07 14:06:57 -0800310
311 return busy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312}
313
314/*
315 * Compute best start block and diff for "near" allocations.
316 * freelen >= wantlen already checked by caller.
317 */
318STATIC xfs_extlen_t /* difference value (absolute) */
319xfs_alloc_compute_diff(
320 xfs_agblock_t wantbno, /* target starting block */
321 xfs_extlen_t wantlen, /* target length */
322 xfs_extlen_t alignment, /* target alignment */
Dave Chinner292378e2016-09-26 08:21:28 +1000323 int datatype, /* are we allocating data? */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 xfs_agblock_t freebno, /* freespace's starting block */
325 xfs_extlen_t freelen, /* freespace's length */
326 xfs_agblock_t *newbnop) /* result: best start block from free */
327{
328 xfs_agblock_t freeend; /* end of freespace extent */
329 xfs_agblock_t newbno1; /* return block number */
330 xfs_agblock_t newbno2; /* other new block number */
331 xfs_extlen_t newlen1=0; /* length with newbno1 */
332 xfs_extlen_t newlen2=0; /* length with newbno2 */
333 xfs_agblock_t wantend; /* end of target extent */
Christoph Hellwigc34d5702019-10-30 12:25:00 -0700334 bool userdata = datatype & XFS_ALLOC_USERDATA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335
336 ASSERT(freelen >= wantlen);
337 freeend = freebno + freelen;
338 wantend = wantbno + wantlen;
Jan Kara211d0222013-04-11 22:09:56 +0200339 /*
340 * We want to allocate from the start of a free extent if it is past
341 * the desired block or if we are allocating user data and the free
342 * extent is before desired block. The second case is there to allow
343 * for contiguous allocation from the remaining free space if the file
344 * grows in the short term.
345 */
346 if (freebno >= wantbno || (userdata && freeend < wantend)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 if ((newbno1 = roundup(freebno, alignment)) >= freeend)
348 newbno1 = NULLAGBLOCK;
349 } else if (freeend >= wantend && alignment > 1) {
350 newbno1 = roundup(wantbno, alignment);
351 newbno2 = newbno1 - alignment;
352 if (newbno1 >= freeend)
353 newbno1 = NULLAGBLOCK;
354 else
355 newlen1 = XFS_EXTLEN_MIN(wantlen, freeend - newbno1);
356 if (newbno2 < freebno)
357 newbno2 = NULLAGBLOCK;
358 else
359 newlen2 = XFS_EXTLEN_MIN(wantlen, freeend - newbno2);
360 if (newbno1 != NULLAGBLOCK && newbno2 != NULLAGBLOCK) {
361 if (newlen1 < newlen2 ||
362 (newlen1 == newlen2 &&
363 XFS_ABSDIFF(newbno1, wantbno) >
364 XFS_ABSDIFF(newbno2, wantbno)))
365 newbno1 = newbno2;
366 } else if (newbno2 != NULLAGBLOCK)
367 newbno1 = newbno2;
368 } else if (freeend >= wantend) {
369 newbno1 = wantbno;
370 } else if (alignment > 1) {
371 newbno1 = roundup(freeend - wantlen, alignment);
372 if (newbno1 > freeend - wantlen &&
373 newbno1 - alignment >= freebno)
374 newbno1 -= alignment;
375 else if (newbno1 >= freeend)
376 newbno1 = NULLAGBLOCK;
377 } else
378 newbno1 = freeend - wantlen;
379 *newbnop = newbno1;
380 return newbno1 == NULLAGBLOCK ? 0 : XFS_ABSDIFF(newbno1, wantbno);
381}
382
383/*
384 * Fix up the length, based on mod and prod.
385 * len should be k * prod + mod for some k.
386 * If len is too small it is returned unchanged.
387 * If len hits maxlen it is left alone.
388 */
389STATIC void
390xfs_alloc_fix_len(
391 xfs_alloc_arg_t *args) /* allocation argument structure */
392{
393 xfs_extlen_t k;
394 xfs_extlen_t rlen;
395
396 ASSERT(args->mod < args->prod);
397 rlen = args->len;
398 ASSERT(rlen >= args->minlen);
399 ASSERT(rlen <= args->maxlen);
400 if (args->prod <= 1 || rlen < args->mod || rlen == args->maxlen ||
401 (args->mod == 0 && rlen < args->prod))
402 return;
403 k = rlen % args->prod;
404 if (k == args->mod)
405 return;
Jan Kara30265112014-06-06 16:06:37 +1000406 if (k > args->mod)
407 rlen = rlen - (k - args->mod);
408 else
409 rlen = rlen - args->prod + (args->mod - k);
Dave Chinner3790a8c2015-02-24 10:16:04 +1100410 /* casts to (int) catch length underflows */
Jan Kara30265112014-06-06 16:06:37 +1000411 if ((int)rlen < (int)args->minlen)
412 return;
413 ASSERT(rlen >= args->minlen && rlen <= args->maxlen);
414 ASSERT(rlen % args->prod == args->mod);
Christoph Hellwig54fee132017-01-09 13:44:30 -0800415 ASSERT(args->pag->pagf_freeblks + args->pag->pagf_flcount >=
416 rlen + args->minleft);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 args->len = rlen;
418}
419
420/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 * Update the two btrees, logically removing from freespace the extent
422 * starting at rbno, rlen blocks. The extent is contained within the
423 * actual (current) free extent fbno for flen blocks.
424 * Flags are passed in indicating whether the cursors are set to the
425 * relevant records.
426 */
427STATIC int /* error code */
428xfs_alloc_fixup_trees(
429 xfs_btree_cur_t *cnt_cur, /* cursor for by-size btree */
430 xfs_btree_cur_t *bno_cur, /* cursor for by-block btree */
431 xfs_agblock_t fbno, /* starting block of free extent */
432 xfs_extlen_t flen, /* length of free extent */
433 xfs_agblock_t rbno, /* starting block of returned extent */
434 xfs_extlen_t rlen, /* length of returned extent */
435 int flags) /* flags, XFSA_FIXUP_... */
436{
437 int error; /* error code */
438 int i; /* operation results */
439 xfs_agblock_t nfbno1; /* first new free startblock */
440 xfs_agblock_t nfbno2; /* second new free startblock */
441 xfs_extlen_t nflen1=0; /* first new free length */
442 xfs_extlen_t nflen2=0; /* second new free length */
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100443 struct xfs_mount *mp;
444
445 mp = cnt_cur->bc_mp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446
447 /*
448 * Look up the record in the by-size tree if necessary.
449 */
450 if (flags & XFSA_FIXUP_CNT_OK) {
451#ifdef DEBUG
452 if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i)))
453 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800454 if (XFS_IS_CORRUPT(mp,
455 i != 1 ||
456 nfbno1 != fbno ||
457 nflen1 != flen))
458 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459#endif
460 } else {
461 if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i)))
462 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800463 if (XFS_IS_CORRUPT(mp, i != 1))
464 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 }
466 /*
467 * Look up the record in the by-block tree if necessary.
468 */
469 if (flags & XFSA_FIXUP_BNO_OK) {
470#ifdef DEBUG
471 if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i)))
472 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800473 if (XFS_IS_CORRUPT(mp,
474 i != 1 ||
475 nfbno1 != fbno ||
476 nflen1 != flen))
477 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478#endif
479 } else {
480 if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i)))
481 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800482 if (XFS_IS_CORRUPT(mp, i != 1))
483 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485
Christoph Hellwig7cc95a82008-10-30 17:14:34 +1100486#ifdef DEBUG
487 if (bno_cur->bc_nlevels == 1 && cnt_cur->bc_nlevels == 1) {
488 struct xfs_btree_block *bnoblock;
489 struct xfs_btree_block *cntblock;
490
491 bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]);
492 cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]);
493
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800494 if (XFS_IS_CORRUPT(mp,
495 bnoblock->bb_numrecs !=
496 cntblock->bb_numrecs))
497 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 }
499#endif
Christoph Hellwig7cc95a82008-10-30 17:14:34 +1100500
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 /*
502 * Deal with all four cases: the allocated record is contained
503 * within the freespace record, so we can have new freespace
504 * at either (or both) end, or no freespace remaining.
505 */
506 if (rbno == fbno && rlen == flen)
507 nfbno1 = nfbno2 = NULLAGBLOCK;
508 else if (rbno == fbno) {
509 nfbno1 = rbno + rlen;
510 nflen1 = flen - rlen;
511 nfbno2 = NULLAGBLOCK;
512 } else if (rbno + rlen == fbno + flen) {
513 nfbno1 = fbno;
514 nflen1 = flen - rlen;
515 nfbno2 = NULLAGBLOCK;
516 } else {
517 nfbno1 = fbno;
518 nflen1 = rbno - fbno;
519 nfbno2 = rbno + rlen;
520 nflen2 = (fbno + flen) - nfbno2;
521 }
522 /*
523 * Delete the entry from the by-size btree.
524 */
Christoph Hellwig91cca5df2008-10-30 16:58:01 +1100525 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800527 if (XFS_IS_CORRUPT(mp, i != 1))
528 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 /*
530 * Add new by-size btree entry(s).
531 */
532 if (nfbno1 != NULLAGBLOCK) {
533 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i)))
534 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800535 if (XFS_IS_CORRUPT(mp, i != 0))
536 return -EFSCORRUPTED;
Christoph Hellwig4b22a572008-10-30 16:57:40 +1100537 if ((error = xfs_btree_insert(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800539 if (XFS_IS_CORRUPT(mp, i != 1))
540 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 }
542 if (nfbno2 != NULLAGBLOCK) {
543 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i)))
544 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800545 if (XFS_IS_CORRUPT(mp, i != 0))
546 return -EFSCORRUPTED;
Christoph Hellwig4b22a572008-10-30 16:57:40 +1100547 if ((error = xfs_btree_insert(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800549 if (XFS_IS_CORRUPT(mp, i != 1))
550 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 }
552 /*
553 * Fix up the by-block btree entry(s).
554 */
555 if (nfbno1 == NULLAGBLOCK) {
556 /*
557 * No remaining freespace, just delete the by-block tree entry.
558 */
Christoph Hellwig91cca5df2008-10-30 16:58:01 +1100559 if ((error = xfs_btree_delete(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800561 if (XFS_IS_CORRUPT(mp, i != 1))
562 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 } else {
564 /*
565 * Update the by-block entry to start later|be shorter.
566 */
567 if ((error = xfs_alloc_update(bno_cur, nfbno1, nflen1)))
568 return error;
569 }
570 if (nfbno2 != NULLAGBLOCK) {
571 /*
572 * 2 resulting free entries, need to add one.
573 */
574 if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i)))
575 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800576 if (XFS_IS_CORRUPT(mp, i != 0))
577 return -EFSCORRUPTED;
Christoph Hellwig4b22a572008-10-30 16:57:40 +1100578 if ((error = xfs_btree_insert(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800580 if (XFS_IS_CORRUPT(mp, i != 1))
581 return -EFSCORRUPTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 }
583 return 0;
584}
585
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800586static xfs_failaddr_t
Dave Chinner612cfbf2012-11-14 17:52:32 +1100587xfs_agfl_verify(
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100588 struct xfs_buf *bp)
589{
Christoph Hellwigdbd329f12019-06-28 19:27:29 -0700590 struct xfs_mount *mp = bp->b_mount;
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100591 struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp);
Christoph Hellwig183606d2020-03-10 08:57:28 -0700592 __be32 *agfl_bno = xfs_buf_to_agfl_bno(bp);
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100593 int i;
594
Darrick J. Wongb5572592018-01-08 10:51:08 -0800595 /*
596 * There is no verification of non-crc AGFLs because mkfs does not
597 * initialise the AGFL to zero or NULL. Hence the only valid part of the
598 * AGFL is what the AGF says is active. We can't get to the AGF, so we
599 * can't verify just those entries are valid.
600 */
Dave Chinner38c26bf2021-08-18 18:46:37 -0700601 if (!xfs_has_crc(mp))
Darrick J. Wongb5572592018-01-08 10:51:08 -0800602 return NULL;
603
Brian Foster39708c22019-02-07 10:45:48 -0800604 if (!xfs_verify_magic(bp, agfl->agfl_magicnum))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800605 return __this_address;
Brian Foster39708c22019-02-07 10:45:48 -0800606 if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800607 return __this_address;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100608 /*
609 * during growfs operations, the perag is not fully initialised,
610 * so we can't use it for any useful checking. growfs ensures we can't
611 * use it by using uncached buffers that don't have the perag attached
612 * so we can detect and avoid this problem.
613 */
614 if (bp->b_pag && be32_to_cpu(agfl->agfl_seqno) != bp->b_pag->pag_agno)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800615 return __this_address;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100616
Dave Chinnera78ee252018-03-06 17:08:32 -0800617 for (i = 0; i < xfs_agfl_size(mp); i++) {
Christoph Hellwig183606d2020-03-10 08:57:28 -0700618 if (be32_to_cpu(agfl_bno[i]) != NULLAGBLOCK &&
619 be32_to_cpu(agfl_bno[i]) >= mp->m_sb.sb_agblocks)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800620 return __this_address;
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100621 }
Brian Fostera45086e2015-10-12 15:59:25 +1100622
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800623 if (!xfs_log_check_lsn(mp, be64_to_cpu(XFS_BUF_TO_AGFL(bp)->agfl_lsn)))
624 return __this_address;
625 return NULL;
Dave Chinner612cfbf2012-11-14 17:52:32 +1100626}
627
Dave Chinnerb0f539de2012-11-14 17:53:49 +1100628static void
Dave Chinner612cfbf2012-11-14 17:52:32 +1100629xfs_agfl_read_verify(
630 struct xfs_buf *bp)
631{
Christoph Hellwigdbd329f12019-06-28 19:27:29 -0700632 struct xfs_mount *mp = bp->b_mount;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800633 xfs_failaddr_t fa;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100634
635 /*
636 * There is no verification of non-crc AGFLs because mkfs does not
637 * initialise the AGFL to zero or NULL. Hence the only valid part of the
638 * AGFL is what the AGF says is active. We can't get to the AGF, so we
639 * can't verify just those entries are valid.
640 */
Dave Chinner38c26bf2021-08-18 18:46:37 -0700641 if (!xfs_has_crc(mp))
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100642 return;
643
Eric Sandeence5028c2014-02-27 15:23:10 +1100644 if (!xfs_buf_verify_cksum(bp, XFS_AGFL_CRC_OFF))
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800645 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
646 else {
647 fa = xfs_agfl_verify(bp);
648 if (fa)
649 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
650 }
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100651}
652
653static void
654xfs_agfl_write_verify(
655 struct xfs_buf *bp)
656{
Christoph Hellwigdbd329f12019-06-28 19:27:29 -0700657 struct xfs_mount *mp = bp->b_mount;
Carlos Maiolinofb1755a2018-01-24 13:38:48 -0800658 struct xfs_buf_log_item *bip = bp->b_log_item;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800659 xfs_failaddr_t fa;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100660
661 /* no verification of non-crc AGFLs */
Dave Chinner38c26bf2021-08-18 18:46:37 -0700662 if (!xfs_has_crc(mp))
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100663 return;
664
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800665 fa = xfs_agfl_verify(bp);
666 if (fa) {
667 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100668 return;
669 }
670
671 if (bip)
672 XFS_BUF_TO_AGFL(bp)->agfl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
673
Eric Sandeenf1dbcd72014-02-27 15:18:23 +1100674 xfs_buf_update_cksum(bp, XFS_AGFL_CRC_OFF);
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100675}
676
Dave Chinner1813dd62012-11-14 17:54:40 +1100677const struct xfs_buf_ops xfs_agfl_buf_ops = {
Eric Sandeen233135b2016-01-04 16:10:19 +1100678 .name = "xfs_agfl",
Brian Foster39708c22019-02-07 10:45:48 -0800679 .magic = { cpu_to_be32(XFS_AGFL_MAGIC), cpu_to_be32(XFS_AGFL_MAGIC) },
Dave Chinner1813dd62012-11-14 17:54:40 +1100680 .verify_read = xfs_agfl_read_verify,
681 .verify_write = xfs_agfl_write_verify,
Darrick J. Wongb5572592018-01-08 10:51:08 -0800682 .verify_struct = xfs_agfl_verify,
Dave Chinner1813dd62012-11-14 17:54:40 +1100683};
684
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685/*
686 * Read in the allocation group free block array.
687 */
Darrick J. Wong26788092017-06-16 11:00:07 -0700688int /* error */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689xfs_alloc_read_agfl(
690 xfs_mount_t *mp, /* mount point structure */
691 xfs_trans_t *tp, /* transaction pointer */
692 xfs_agnumber_t agno, /* allocation group number */
Dave Chinnere8222612020-12-16 16:07:34 -0800693 struct xfs_buf **bpp) /* buffer for the ag free block array */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694{
Dave Chinnere8222612020-12-16 16:07:34 -0800695 struct xfs_buf *bp; /* return value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 int error;
697
698 ASSERT(agno != NULLAGNUMBER);
699 error = xfs_trans_read_buf(
700 mp, tp, mp->m_ddev_targp,
701 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
Dave Chinner1813dd62012-11-14 17:54:40 +1100702 XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 if (error)
704 return error;
Christoph Hellwig38f23232011-10-10 16:52:45 +0000705 xfs_buf_set_ref(bp, XFS_AGFL_REF);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 *bpp = bp;
707 return 0;
708}
709
Christoph Hellwigecb69282011-03-04 12:59:55 +0000710STATIC int
711xfs_alloc_update_counters(
712 struct xfs_trans *tp,
Christoph Hellwigecb69282011-03-04 12:59:55 +0000713 struct xfs_buf *agbp,
714 long len)
715{
Christoph Hellwig9798f612020-03-10 08:57:29 -0700716 struct xfs_agf *agf = agbp->b_addr;
Christoph Hellwigecb69282011-03-04 12:59:55 +0000717
Gao Xiang92a00542020-07-13 09:13:00 -0700718 agbp->b_pag->pagf_freeblks += len;
Christoph Hellwigecb69282011-03-04 12:59:55 +0000719 be32_add_cpu(&agf->agf_freeblks, len);
720
Christoph Hellwigecb69282011-03-04 12:59:55 +0000721 if (unlikely(be32_to_cpu(agf->agf_freeblks) >
Darrick J. Wonga5155b82019-11-02 09:40:53 -0700722 be32_to_cpu(agf->agf_length))) {
Darrick J. Wong8d57c212020-03-11 10:37:54 -0700723 xfs_buf_mark_corrupt(agbp);
Dave Chinner24513372014-06-25 14:58:08 +1000724 return -EFSCORRUPTED;
Darrick J. Wonga5155b82019-11-02 09:40:53 -0700725 }
Christoph Hellwigecb69282011-03-04 12:59:55 +0000726
727 xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
728 return 0;
729}
730
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731/*
Brian Fosterf5e7dbe2019-10-13 17:10:31 -0700732 * Block allocation algorithm and data structures.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 */
Brian Fosterf5e7dbe2019-10-13 17:10:31 -0700734struct xfs_alloc_cur {
735 struct xfs_btree_cur *cnt; /* btree cursors */
736 struct xfs_btree_cur *bnolt;
737 struct xfs_btree_cur *bnogt;
Brian Fosterdc8e69b2019-10-13 17:10:36 -0700738 xfs_extlen_t cur_len;/* current search length */
Brian Fosterc62321a2019-10-13 17:10:32 -0700739 xfs_agblock_t rec_bno;/* extent startblock */
740 xfs_extlen_t rec_len;/* extent length */
741 xfs_agblock_t bno; /* alloc bno */
742 xfs_extlen_t len; /* alloc len */
743 xfs_extlen_t diff; /* diff from search bno */
Brian Fosterd6d3aff2019-10-13 17:10:32 -0700744 unsigned int busy_gen;/* busy state */
745 bool busy;
Brian Fosterf5e7dbe2019-10-13 17:10:31 -0700746};
747
748/*
749 * Set up cursors, etc. in the extent allocation cursor. This function can be
750 * called multiple times to reset an initialized structure without having to
751 * reallocate cursors.
752 */
753static int
754xfs_alloc_cur_setup(
755 struct xfs_alloc_arg *args,
756 struct xfs_alloc_cur *acur)
757{
758 int error;
759 int i;
760
761 ASSERT(args->alignment == 1 || args->type != XFS_ALLOCTYPE_THIS_BNO);
762
Brian Fosterdc8e69b2019-10-13 17:10:36 -0700763 acur->cur_len = args->maxlen;
Brian Fosterc62321a2019-10-13 17:10:32 -0700764 acur->rec_bno = 0;
765 acur->rec_len = 0;
766 acur->bno = 0;
767 acur->len = 0;
Brian Foster396bbf32019-10-13 17:10:33 -0700768 acur->diff = -1;
Brian Fosterd6d3aff2019-10-13 17:10:32 -0700769 acur->busy = false;
770 acur->busy_gen = 0;
771
Brian Fosterf5e7dbe2019-10-13 17:10:31 -0700772 /*
773 * Perform an initial cntbt lookup to check for availability of maxlen
774 * extents. If this fails, we'll return -ENOSPC to signal the caller to
775 * attempt a small allocation.
776 */
777 if (!acur->cnt)
778 acur->cnt = xfs_allocbt_init_cursor(args->mp, args->tp,
Dave Chinner289d38d2021-06-02 10:48:24 +1000779 args->agbp, args->pag, XFS_BTNUM_CNT);
Brian Fosterf5e7dbe2019-10-13 17:10:31 -0700780 error = xfs_alloc_lookup_ge(acur->cnt, 0, args->maxlen, &i);
781 if (error)
782 return error;
783
784 /*
785 * Allocate the bnobt left and right search cursors.
786 */
787 if (!acur->bnolt)
788 acur->bnolt = xfs_allocbt_init_cursor(args->mp, args->tp,
Dave Chinner289d38d2021-06-02 10:48:24 +1000789 args->agbp, args->pag, XFS_BTNUM_BNO);
Brian Fosterf5e7dbe2019-10-13 17:10:31 -0700790 if (!acur->bnogt)
791 acur->bnogt = xfs_allocbt_init_cursor(args->mp, args->tp,
Dave Chinner289d38d2021-06-02 10:48:24 +1000792 args->agbp, args->pag, XFS_BTNUM_BNO);
Brian Fosterf5e7dbe2019-10-13 17:10:31 -0700793 return i == 1 ? 0 : -ENOSPC;
794}
795
796static void
797xfs_alloc_cur_close(
798 struct xfs_alloc_cur *acur,
799 bool error)
800{
801 int cur_error = XFS_BTREE_NOERROR;
802
803 if (error)
804 cur_error = XFS_BTREE_ERROR;
805
806 if (acur->cnt)
807 xfs_btree_del_cursor(acur->cnt, cur_error);
808 if (acur->bnolt)
809 xfs_btree_del_cursor(acur->bnolt, cur_error);
810 if (acur->bnogt)
811 xfs_btree_del_cursor(acur->bnogt, cur_error);
812 acur->cnt = acur->bnolt = acur->bnogt = NULL;
813}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
815/*
Brian Foster396bbf32019-10-13 17:10:33 -0700816 * Check an extent for allocation and track the best available candidate in the
817 * allocation structure. The cursor is deactivated if it has entered an out of
818 * range state based on allocation arguments. Optionally return the extent
819 * extent geometry and allocation status if requested by the caller.
820 */
821static int
822xfs_alloc_cur_check(
823 struct xfs_alloc_arg *args,
824 struct xfs_alloc_cur *acur,
825 struct xfs_btree_cur *cur,
826 int *new)
827{
828 int error, i;
829 xfs_agblock_t bno, bnoa, bnew;
830 xfs_extlen_t len, lena, diff = -1;
831 bool busy;
832 unsigned busy_gen = 0;
833 bool deactivate = false;
Brian Fosterfec0afd2019-10-13 17:10:33 -0700834 bool isbnobt = cur->bc_btnum == XFS_BTNUM_BNO;
Brian Foster396bbf32019-10-13 17:10:33 -0700835
836 *new = 0;
837
838 error = xfs_alloc_get_rec(cur, &bno, &len, &i);
839 if (error)
840 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -0800841 if (XFS_IS_CORRUPT(args->mp, i != 1))
842 return -EFSCORRUPTED;
Brian Foster396bbf32019-10-13 17:10:33 -0700843
844 /*
845 * Check minlen and deactivate a cntbt cursor if out of acceptable size
846 * range (i.e., walking backwards looking for a minlen extent).
847 */
848 if (len < args->minlen) {
Brian Fosterfec0afd2019-10-13 17:10:33 -0700849 deactivate = !isbnobt;
Brian Foster396bbf32019-10-13 17:10:33 -0700850 goto out;
851 }
852
853 busy = xfs_alloc_compute_aligned(args, bno, len, &bnoa, &lena,
854 &busy_gen);
855 acur->busy |= busy;
856 if (busy)
857 acur->busy_gen = busy_gen;
858 /* deactivate a bnobt cursor outside of locality range */
Brian Fosterfec0afd2019-10-13 17:10:33 -0700859 if (bnoa < args->min_agbno || bnoa > args->max_agbno) {
860 deactivate = isbnobt;
Brian Foster396bbf32019-10-13 17:10:33 -0700861 goto out;
Brian Fosterfec0afd2019-10-13 17:10:33 -0700862 }
Brian Foster396bbf32019-10-13 17:10:33 -0700863 if (lena < args->minlen)
864 goto out;
865
866 args->len = XFS_EXTLEN_MIN(lena, args->maxlen);
867 xfs_alloc_fix_len(args);
868 ASSERT(args->len >= args->minlen);
869 if (args->len < acur->len)
870 goto out;
871
872 /*
873 * We have an aligned record that satisfies minlen and beats or matches
874 * the candidate extent size. Compare locality for near allocation mode.
875 */
876 ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO);
877 diff = xfs_alloc_compute_diff(args->agbno, args->len,
878 args->alignment, args->datatype,
879 bnoa, lena, &bnew);
880 if (bnew == NULLAGBLOCK)
881 goto out;
Brian Fosterfec0afd2019-10-13 17:10:33 -0700882
883 /*
884 * Deactivate a bnobt cursor with worse locality than the current best.
885 */
886 if (diff > acur->diff) {
887 deactivate = isbnobt;
Brian Foster396bbf32019-10-13 17:10:33 -0700888 goto out;
Brian Fosterfec0afd2019-10-13 17:10:33 -0700889 }
Brian Foster396bbf32019-10-13 17:10:33 -0700890
891 ASSERT(args->len > acur->len ||
892 (args->len == acur->len && diff <= acur->diff));
893 acur->rec_bno = bno;
894 acur->rec_len = len;
895 acur->bno = bnew;
896 acur->len = args->len;
897 acur->diff = diff;
898 *new = 1;
899
Brian Foster78d7aab2019-10-13 17:10:34 -0700900 /*
901 * We're done if we found a perfect allocation. This only deactivates
902 * the current cursor, but this is just an optimization to terminate a
903 * cntbt search that otherwise runs to the edge of the tree.
904 */
905 if (acur->diff == 0 && acur->len == args->maxlen)
906 deactivate = true;
Brian Foster396bbf32019-10-13 17:10:33 -0700907out:
908 if (deactivate)
Dave Chinnerc4aa10d2020-03-10 17:57:51 -0700909 cur->bc_ag.abt.active = false;
Brian Foster396bbf32019-10-13 17:10:33 -0700910 trace_xfs_alloc_cur_check(args->mp, cur->bc_btnum, bno, len, diff,
911 *new);
912 return 0;
913}
914
915/*
Brian Fosterd2968822019-10-13 17:10:35 -0700916 * Complete an allocation of a candidate extent. Remove the extent from both
917 * trees and update the args structure.
918 */
919STATIC int
920xfs_alloc_cur_finish(
921 struct xfs_alloc_arg *args,
922 struct xfs_alloc_cur *acur)
923{
Christoph Hellwig9798f612020-03-10 08:57:29 -0700924 struct xfs_agf __maybe_unused *agf = args->agbp->b_addr;
Brian Fosterd2968822019-10-13 17:10:35 -0700925 int error;
926
927 ASSERT(acur->cnt && acur->bnolt);
928 ASSERT(acur->bno >= acur->rec_bno);
929 ASSERT(acur->bno + acur->len <= acur->rec_bno + acur->rec_len);
Christoph Hellwig9798f612020-03-10 08:57:29 -0700930 ASSERT(acur->rec_bno + acur->rec_len <= be32_to_cpu(agf->agf_length));
Brian Fosterd2968822019-10-13 17:10:35 -0700931
932 error = xfs_alloc_fixup_trees(acur->cnt, acur->bnolt, acur->rec_bno,
933 acur->rec_len, acur->bno, acur->len, 0);
934 if (error)
935 return error;
936
937 args->agbno = acur->bno;
938 args->len = acur->len;
939 args->wasfromfl = 0;
940
941 trace_xfs_alloc_cur(args);
942 return 0;
943}
944
945/*
Brian Fosterdc8e69b2019-10-13 17:10:36 -0700946 * Locality allocation lookup algorithm. This expects a cntbt cursor and uses
947 * bno optimized lookup to search for extents with ideal size and locality.
948 */
949STATIC int
950xfs_alloc_cntbt_iter(
951 struct xfs_alloc_arg *args,
952 struct xfs_alloc_cur *acur)
953{
954 struct xfs_btree_cur *cur = acur->cnt;
955 xfs_agblock_t bno;
956 xfs_extlen_t len, cur_len;
957 int error;
958 int i;
959
960 if (!xfs_alloc_cur_active(cur))
961 return 0;
962
963 /* locality optimized lookup */
964 cur_len = acur->cur_len;
965 error = xfs_alloc_lookup_ge(cur, args->agbno, cur_len, &i);
966 if (error)
967 return error;
968 if (i == 0)
969 return 0;
970 error = xfs_alloc_get_rec(cur, &bno, &len, &i);
971 if (error)
972 return error;
973
974 /* check the current record and update search length from it */
975 error = xfs_alloc_cur_check(args, acur, cur, &i);
976 if (error)
977 return error;
978 ASSERT(len >= acur->cur_len);
979 acur->cur_len = len;
980
981 /*
982 * We looked up the first record >= [agbno, len] above. The agbno is a
983 * secondary key and so the current record may lie just before or after
984 * agbno. If it is past agbno, check the previous record too so long as
985 * the length matches as it may be closer. Don't check a smaller record
986 * because that could deactivate our cursor.
987 */
988 if (bno > args->agbno) {
989 error = xfs_btree_decrement(cur, 0, &i);
990 if (!error && i) {
991 error = xfs_alloc_get_rec(cur, &bno, &len, &i);
992 if (!error && i && len == acur->cur_len)
993 error = xfs_alloc_cur_check(args, acur, cur,
994 &i);
995 }
996 if (error)
997 return error;
998 }
999
1000 /*
1001 * Increment the search key until we find at least one allocation
1002 * candidate or if the extent we found was larger. Otherwise, double the
1003 * search key to optimize the search. Efficiency is more important here
1004 * than absolute best locality.
1005 */
1006 cur_len <<= 1;
1007 if (!acur->len || acur->cur_len >= cur_len)
1008 acur->cur_len++;
1009 else
1010 acur->cur_len = cur_len;
1011
1012 return error;
1013}
1014
1015/*
Brian Fosterc63cdd42019-06-28 19:30:19 -07001016 * Deal with the case where only small freespaces remain. Either return the
1017 * contents of the last freespace record, or allocate space from the freelist if
1018 * there is nothing in the tree.
1019 */
1020STATIC int /* error */
1021xfs_alloc_ag_vextent_small(
1022 struct xfs_alloc_arg *args, /* allocation argument structure */
1023 struct xfs_btree_cur *ccur, /* optional by-size cursor */
1024 xfs_agblock_t *fbnop, /* result block number */
1025 xfs_extlen_t *flenp, /* result length */
1026 int *stat) /* status: 0-freelist, 1-normal/none */
1027{
Christoph Hellwig9798f612020-03-10 08:57:29 -07001028 struct xfs_agf *agf = args->agbp->b_addr;
Brian Fosterc63cdd42019-06-28 19:30:19 -07001029 int error = 0;
1030 xfs_agblock_t fbno = NULLAGBLOCK;
1031 xfs_extlen_t flen = 0;
Brian Foster6691cd92019-06-28 19:30:20 -07001032 int i = 0;
Brian Fosterc63cdd42019-06-28 19:30:19 -07001033
Brian Foster6691cd92019-06-28 19:30:20 -07001034 /*
1035 * If a cntbt cursor is provided, try to allocate the largest record in
1036 * the tree. Try the AGFL if the cntbt is empty, otherwise fail the
1037 * allocation. Make sure to respect minleft even when pulling from the
1038 * freelist.
1039 */
1040 if (ccur)
1041 error = xfs_btree_decrement(ccur, 0, &i);
Brian Fosterc63cdd42019-06-28 19:30:19 -07001042 if (error)
1043 goto error;
1044 if (i) {
1045 error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i);
1046 if (error)
1047 goto error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001048 if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1049 error = -EFSCORRUPTED;
1050 goto error;
1051 }
Brian Fosterc63cdd42019-06-28 19:30:19 -07001052 goto out;
1053 }
1054
1055 if (args->minlen != 1 || args->alignment != 1 ||
1056 args->resv == XFS_AG_RESV_AGFL ||
Christoph Hellwig9798f612020-03-10 08:57:29 -07001057 be32_to_cpu(agf->agf_flcount) <= args->minleft)
Brian Fosterc63cdd42019-06-28 19:30:19 -07001058 goto out;
1059
1060 error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
1061 if (error)
1062 goto error;
1063 if (fbno == NULLAGBLOCK)
1064 goto out;
1065
Dave Chinner45d06622021-06-02 10:48:24 +10001066 xfs_extent_busy_reuse(args->mp, args->pag, fbno, 1,
Christoph Hellwigc34d5702019-10-30 12:25:00 -07001067 (args->datatype & XFS_ALLOC_NOBUSY));
Brian Fosterc63cdd42019-06-28 19:30:19 -07001068
Christoph Hellwigc34d5702019-10-30 12:25:00 -07001069 if (args->datatype & XFS_ALLOC_USERDATA) {
Brian Fosterc63cdd42019-06-28 19:30:19 -07001070 struct xfs_buf *bp;
1071
Darrick J. Wongee647f82020-01-23 17:01:19 -08001072 error = xfs_trans_get_buf(args->tp, args->mp->m_ddev_targp,
1073 XFS_AGB_TO_DADDR(args->mp, args->agno, fbno),
1074 args->mp->m_bsize, 0, &bp);
1075 if (error)
Brian Fosterc63cdd42019-06-28 19:30:19 -07001076 goto error;
Brian Fosterc63cdd42019-06-28 19:30:19 -07001077 xfs_trans_binval(args->tp, bp);
1078 }
Brian Foster7e36a3a2019-06-28 19:30:20 -07001079 *fbnop = args->agbno = fbno;
1080 *flenp = args->len = 1;
Christoph Hellwig9798f612020-03-10 08:57:29 -07001081 if (XFS_IS_CORRUPT(args->mp, fbno >= be32_to_cpu(agf->agf_length))) {
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001082 error = -EFSCORRUPTED;
1083 goto error;
1084 }
Brian Fosterc63cdd42019-06-28 19:30:19 -07001085 args->wasfromfl = 1;
1086 trace_xfs_alloc_small_freelist(args);
1087
1088 /*
1089 * If we're feeding an AGFL block to something that doesn't live in the
1090 * free space, we need to clear out the OWN_AG rmap.
1091 */
Dave Chinnerfa9c3c12021-06-02 10:48:24 +10001092 error = xfs_rmap_free(args->tp, args->agbp, args->pag, fbno, 1,
Brian Fosterc63cdd42019-06-28 19:30:19 -07001093 &XFS_RMAP_OINFO_AG);
1094 if (error)
1095 goto error;
1096
1097 *stat = 0;
1098 return 0;
1099
1100out:
1101 /*
1102 * Can't do the allocation, give up.
1103 */
1104 if (flen < args->minlen) {
1105 args->agbno = NULLAGBLOCK;
1106 trace_xfs_alloc_small_notenough(args);
1107 flen = 0;
1108 }
1109 *fbnop = fbno;
1110 *flenp = flen;
1111 *stat = 1;
1112 trace_xfs_alloc_small_done(args);
1113 return 0;
1114
1115error:
1116 trace_xfs_alloc_small_error(args);
1117 return error;
1118}
1119
1120/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 * Allocate a variable extent in the allocation group agno.
1122 * Type and bno are used to determine where in the allocation group the
1123 * extent will start.
1124 * Extent's length (returned in *len) will be between minlen and maxlen,
1125 * and of the form k * prod + mod unless there's nothing that large.
1126 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
1127 */
1128STATIC int /* error */
1129xfs_alloc_ag_vextent(
1130 xfs_alloc_arg_t *args) /* argument structure for allocation */
1131{
1132 int error=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133
1134 ASSERT(args->minlen > 0);
1135 ASSERT(args->maxlen > 0);
1136 ASSERT(args->minlen <= args->maxlen);
1137 ASSERT(args->mod < args->prod);
1138 ASSERT(args->alignment > 0);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001139
1140 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 * Branch to correct routine based on the type.
1142 */
1143 args->wasfromfl = 0;
1144 switch (args->type) {
1145 case XFS_ALLOCTYPE_THIS_AG:
1146 error = xfs_alloc_ag_vextent_size(args);
1147 break;
1148 case XFS_ALLOCTYPE_NEAR_BNO:
1149 error = xfs_alloc_ag_vextent_near(args);
1150 break;
1151 case XFS_ALLOCTYPE_THIS_BNO:
1152 error = xfs_alloc_ag_vextent_exact(args);
1153 break;
1154 default:
1155 ASSERT(0);
1156 /* NOTREACHED */
1157 }
Christoph Hellwigecb69282011-03-04 12:59:55 +00001158
1159 if (error || args->agbno == NULLAGBLOCK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161
Christoph Hellwigecb69282011-03-04 12:59:55 +00001162 ASSERT(args->len >= args->minlen);
1163 ASSERT(args->len <= args->maxlen);
Brian Foster0ab320862018-03-09 14:02:32 -08001164 ASSERT(!args->wasfromfl || args->resv != XFS_AG_RESV_AGFL);
Christoph Hellwigecb69282011-03-04 12:59:55 +00001165 ASSERT(args->agbno % args->alignment == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
Darrick J. Wong673930c2016-08-03 11:33:43 +10001167 /* if not file data, insert new block into the reverse map btree */
Darrick J. Wong33df3a92017-12-07 19:07:27 -08001168 if (!xfs_rmap_should_skip_owner_update(&args->oinfo)) {
Dave Chinnerfa9c3c12021-06-02 10:48:24 +10001169 error = xfs_rmap_alloc(args->tp, args->agbp, args->pag,
Darrick J. Wong673930c2016-08-03 11:33:43 +10001170 args->agbno, args->len, &args->oinfo);
1171 if (error)
1172 return error;
1173 }
1174
Christoph Hellwigecb69282011-03-04 12:59:55 +00001175 if (!args->wasfromfl) {
Gao Xiang92a00542020-07-13 09:13:00 -07001176 error = xfs_alloc_update_counters(args->tp, args->agbp,
Christoph Hellwigecb69282011-03-04 12:59:55 +00001177 -((long)(args->len)));
1178 if (error)
1179 return error;
1180
Dave Chinner45d06622021-06-02 10:48:24 +10001181 ASSERT(!xfs_extent_busy_search(args->mp, args->pag,
Christoph Hellwige26f0502011-04-24 19:06:15 +00001182 args->agbno, args->len));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 }
Christoph Hellwigecb69282011-03-04 12:59:55 +00001184
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001185 xfs_ag_resv_alloc_extent(args->pag, args->resv, args);
Christoph Hellwigecb69282011-03-04 12:59:55 +00001186
Bill O'Donnellff6d6af2015-10-12 18:21:22 +11001187 XFS_STATS_INC(args->mp, xs_allocx);
1188 XFS_STATS_ADD(args->mp, xs_allocb, args->len);
Christoph Hellwigecb69282011-03-04 12:59:55 +00001189 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190}
1191
1192/*
1193 * Allocate a variable extent at exactly agno/bno.
1194 * Extent's length (returned in *len) will be between minlen and maxlen,
1195 * and of the form k * prod + mod unless there's nothing that large.
1196 * Return the starting a.g. block (bno), or NULLAGBLOCK if we can't do it.
1197 */
1198STATIC int /* error */
1199xfs_alloc_ag_vextent_exact(
1200 xfs_alloc_arg_t *args) /* allocation argument structure */
1201{
Christoph Hellwig9798f612020-03-10 08:57:29 -07001202 struct xfs_agf __maybe_unused *agf = args->agbp->b_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 xfs_btree_cur_t *bno_cur;/* by block-number btree cursor */
1204 xfs_btree_cur_t *cnt_cur;/* by count btree cursor */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 int error;
1206 xfs_agblock_t fbno; /* start block of found extent */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 xfs_extlen_t flen; /* length of found extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -08001208 xfs_agblock_t tbno; /* start block of busy extent */
1209 xfs_extlen_t tlen; /* length of busy extent */
1210 xfs_agblock_t tend; /* end block of busy extent */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 int i; /* success/failure of operation */
Christoph Hellwigebf55872017-02-07 14:06:57 -08001212 unsigned busy_gen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213
1214 ASSERT(args->alignment == 1);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001215
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 /*
1217 * Allocate/initialize a cursor for the by-number freespace btree.
1218 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001219 bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
Dave Chinner289d38d2021-06-02 10:48:24 +10001220 args->pag, XFS_BTNUM_BNO);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001221
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 /*
1223 * Lookup bno and minlen in the btree (minlen is irrelevant, really).
1224 * Look for the closest free block <= bno, it must contain bno
1225 * if any free block does.
1226 */
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001227 error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i);
1228 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 goto error0;
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001230 if (!i)
1231 goto not_found;
1232
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 /*
1234 * Grab the freespace record.
1235 */
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001236 error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i);
1237 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001239 if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1240 error = -EFSCORRUPTED;
1241 goto error0;
1242 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 ASSERT(fbno <= args->agbno);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001244
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 /*
Christoph Hellwige26f0502011-04-24 19:06:15 +00001246 * Check for overlapping busy extents.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 */
Christoph Hellwigebf55872017-02-07 14:06:57 -08001248 tbno = fbno;
1249 tlen = flen;
1250 xfs_extent_busy_trim(args, &tbno, &tlen, &busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001251
1252 /*
1253 * Give up if the start of the extent is busy, or the freespace isn't
1254 * long enough for the minimum request.
1255 */
1256 if (tbno > args->agbno)
1257 goto not_found;
1258 if (tlen < args->minlen)
1259 goto not_found;
1260 tend = tbno + tlen;
1261 if (tend < args->agbno + args->minlen)
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001262 goto not_found;
1263
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 /*
1265 * End of extent will be smaller of the freespace end and the
1266 * maximal requested end.
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001267 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 * Fix the length according to mod and prod if given.
1269 */
Chandra Seetharaman81463b12011-06-09 16:47:49 +00001270 args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen)
1271 - args->agbno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272 xfs_alloc_fix_len(args);
Chandra Seetharaman81463b12011-06-09 16:47:49 +00001273 ASSERT(args->agbno + args->len <= tend);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001274
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 /*
Chandra Seetharaman81463b12011-06-09 16:47:49 +00001276 * We are allocating agbno for args->len
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 * Allocate/initialize a cursor for the by-size btree.
1278 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001279 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
Dave Chinner289d38d2021-06-02 10:48:24 +10001280 args->pag, XFS_BTNUM_CNT);
Christoph Hellwig9798f612020-03-10 08:57:29 -07001281 ASSERT(args->agbno + args->len <= be32_to_cpu(agf->agf_length));
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001282 error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno,
1283 args->len, XFSA_FIXUP_BNO_OK);
1284 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1286 goto error0;
1287 }
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001288
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
1290 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001291
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 args->wasfromfl = 0;
Christoph Hellwig9f9baab2010-12-10 15:03:57 +00001293 trace_xfs_alloc_exact_done(args);
1294 return 0;
1295
1296not_found:
1297 /* Didn't find it, return null. */
1298 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
1299 args->agbno = NULLAGBLOCK;
1300 trace_xfs_alloc_exact_notfound(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301 return 0;
1302
1303error0:
1304 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001305 trace_xfs_alloc_exact_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 return error;
1307}
1308
1309/*
Brian Foster78d7aab2019-10-13 17:10:34 -07001310 * Search a given number of btree records in a given direction. Check each
1311 * record against the good extent we've already found.
Christoph Hellwig489a1502010-12-10 15:04:11 +00001312 */
1313STATIC int
Brian Foster78d7aab2019-10-13 17:10:34 -07001314xfs_alloc_walk_iter(
Brian Fosterfec0afd2019-10-13 17:10:33 -07001315 struct xfs_alloc_arg *args,
1316 struct xfs_alloc_cur *acur,
1317 struct xfs_btree_cur *cur,
Brian Foster78d7aab2019-10-13 17:10:34 -07001318 bool increment,
1319 bool find_one, /* quit on first candidate */
1320 int count, /* rec count (-1 for infinite) */
1321 int *stat)
Christoph Hellwig489a1502010-12-10 15:04:11 +00001322{
Christoph Hellwig489a1502010-12-10 15:04:11 +00001323 int error;
1324 int i;
Christoph Hellwig489a1502010-12-10 15:04:11 +00001325
Brian Foster78d7aab2019-10-13 17:10:34 -07001326 *stat = 0;
1327
Christoph Hellwig489a1502010-12-10 15:04:11 +00001328 /*
Brian Fosterfec0afd2019-10-13 17:10:33 -07001329 * Search so long as the cursor is active or we find a better extent.
1330 * The cursor is deactivated if it extends beyond the range of the
1331 * current allocation candidate.
Christoph Hellwig489a1502010-12-10 15:04:11 +00001332 */
Brian Foster78d7aab2019-10-13 17:10:34 -07001333 while (xfs_alloc_cur_active(cur) && count) {
Brian Fosterfec0afd2019-10-13 17:10:33 -07001334 error = xfs_alloc_cur_check(args, acur, cur, &i);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001335 if (error)
Brian Fosterfec0afd2019-10-13 17:10:33 -07001336 return error;
Brian Foster78d7aab2019-10-13 17:10:34 -07001337 if (i == 1) {
1338 *stat = 1;
1339 if (find_one)
1340 break;
1341 }
Brian Fosterfec0afd2019-10-13 17:10:33 -07001342 if (!xfs_alloc_cur_active(cur))
1343 break;
Christoph Hellwig489a1502010-12-10 15:04:11 +00001344
Brian Fosterfec0afd2019-10-13 17:10:33 -07001345 if (increment)
1346 error = xfs_btree_increment(cur, 0, &i);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001347 else
Brian Fosterfec0afd2019-10-13 17:10:33 -07001348 error = xfs_btree_decrement(cur, 0, &i);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001349 if (error)
Brian Fosterfec0afd2019-10-13 17:10:33 -07001350 return error;
1351 if (i == 0)
Dave Chinnerc4aa10d2020-03-10 17:57:51 -07001352 cur->bc_ag.abt.active = false;
Brian Foster78d7aab2019-10-13 17:10:34 -07001353
1354 if (count > 0)
1355 count--;
Brian Fosterfec0afd2019-10-13 17:10:33 -07001356 }
Christoph Hellwig489a1502010-12-10 15:04:11 +00001357
Christoph Hellwig489a1502010-12-10 15:04:11 +00001358 return 0;
Christoph Hellwig489a1502010-12-10 15:04:11 +00001359}
1360
1361/*
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001362 * Search the by-bno and by-size btrees in parallel in search of an extent with
1363 * ideal locality based on the NEAR mode ->agbno locality hint.
Brian Foster0e26d5c2019-10-13 17:10:35 -07001364 */
1365STATIC int
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001366xfs_alloc_ag_vextent_locality(
Brian Foster0e26d5c2019-10-13 17:10:35 -07001367 struct xfs_alloc_arg *args,
1368 struct xfs_alloc_cur *acur,
1369 int *stat)
1370{
1371 struct xfs_btree_cur *fbcur = NULL;
1372 int error;
1373 int i;
1374 bool fbinc;
1375
1376 ASSERT(acur->len == 0);
1377 ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO);
1378
1379 *stat = 0;
1380
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001381 error = xfs_alloc_lookup_ge(acur->cnt, args->agbno, acur->cur_len, &i);
1382 if (error)
1383 return error;
Brian Foster0e26d5c2019-10-13 17:10:35 -07001384 error = xfs_alloc_lookup_le(acur->bnolt, args->agbno, 0, &i);
1385 if (error)
1386 return error;
1387 error = xfs_alloc_lookup_ge(acur->bnogt, args->agbno, 0, &i);
1388 if (error)
1389 return error;
1390
1391 /*
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001392 * Search the bnobt and cntbt in parallel. Search the bnobt left and
1393 * right and lookup the closest extent to the locality hint for each
1394 * extent size key in the cntbt. The entire search terminates
1395 * immediately on a bnobt hit because that means we've found best case
1396 * locality. Otherwise the search continues until the cntbt cursor runs
1397 * off the end of the tree. If no allocation candidate is found at this
1398 * point, give up on locality, walk backwards from the end of the cntbt
1399 * and take the first available extent.
1400 *
1401 * The parallel tree searches balance each other out to provide fairly
1402 * consistent performance for various situations. The bnobt search can
1403 * have pathological behavior in the worst case scenario of larger
1404 * allocation requests and fragmented free space. On the other hand, the
1405 * bnobt is able to satisfy most smaller allocation requests much more
1406 * quickly than the cntbt. The cntbt search can sift through fragmented
1407 * free space and sets of free extents for larger allocation requests
1408 * more quickly than the bnobt. Since the locality hint is just a hint
1409 * and we don't want to scan the entire bnobt for perfect locality, the
1410 * cntbt search essentially bounds the bnobt search such that we can
1411 * find good enough locality at reasonable performance in most cases.
Brian Foster0e26d5c2019-10-13 17:10:35 -07001412 */
1413 while (xfs_alloc_cur_active(acur->bnolt) ||
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001414 xfs_alloc_cur_active(acur->bnogt) ||
1415 xfs_alloc_cur_active(acur->cnt)) {
1416
1417 trace_xfs_alloc_cur_lookup(args);
1418
1419 /*
1420 * Search the bnobt left and right. In the case of a hit, finish
1421 * the search in the opposite direction and we're done.
1422 */
Brian Foster0e26d5c2019-10-13 17:10:35 -07001423 error = xfs_alloc_walk_iter(args, acur, acur->bnolt, false,
1424 true, 1, &i);
1425 if (error)
1426 return error;
1427 if (i == 1) {
1428 trace_xfs_alloc_cur_left(args);
1429 fbcur = acur->bnogt;
1430 fbinc = true;
1431 break;
1432 }
Brian Foster0e26d5c2019-10-13 17:10:35 -07001433 error = xfs_alloc_walk_iter(args, acur, acur->bnogt, true, true,
1434 1, &i);
1435 if (error)
1436 return error;
1437 if (i == 1) {
1438 trace_xfs_alloc_cur_right(args);
1439 fbcur = acur->bnolt;
1440 fbinc = false;
1441 break;
1442 }
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001443
1444 /*
1445 * Check the extent with best locality based on the current
1446 * extent size search key and keep track of the best candidate.
1447 */
1448 error = xfs_alloc_cntbt_iter(args, acur);
1449 if (error)
1450 return error;
1451 if (!xfs_alloc_cur_active(acur->cnt)) {
1452 trace_xfs_alloc_cur_lookup_done(args);
1453 break;
1454 }
Brian Foster0e26d5c2019-10-13 17:10:35 -07001455 }
1456
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001457 /*
1458 * If we failed to find anything due to busy extents, return empty
1459 * handed so the caller can flush and retry. If no busy extents were
1460 * found, walk backwards from the end of the cntbt as a last resort.
1461 */
1462 if (!xfs_alloc_cur_active(acur->cnt) && !acur->len && !acur->busy) {
1463 error = xfs_btree_decrement(acur->cnt, 0, &i);
1464 if (error)
1465 return error;
1466 if (i) {
Dave Chinnerc4aa10d2020-03-10 17:57:51 -07001467 acur->cnt->bc_ag.abt.active = true;
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001468 fbcur = acur->cnt;
1469 fbinc = false;
1470 }
1471 }
1472
1473 /*
1474 * Search in the opposite direction for a better entry in the case of
1475 * a bnobt hit or walk backwards from the end of the cntbt.
1476 */
Brian Foster0e26d5c2019-10-13 17:10:35 -07001477 if (fbcur) {
1478 error = xfs_alloc_walk_iter(args, acur, fbcur, fbinc, true, -1,
1479 &i);
1480 if (error)
1481 return error;
1482 }
1483
1484 if (acur->len)
1485 *stat = 1;
1486
1487 return 0;
1488}
1489
Darrick J. Wong5113f8e2019-11-07 12:29:00 -08001490/* Check the last block of the cnt btree for allocations. */
1491static int
1492xfs_alloc_ag_vextent_lastblock(
1493 struct xfs_alloc_arg *args,
1494 struct xfs_alloc_cur *acur,
1495 xfs_agblock_t *bno,
1496 xfs_extlen_t *len,
1497 bool *allocated)
1498{
1499 int error;
1500 int i;
1501
1502#ifdef DEBUG
1503 /* Randomly don't execute the first algorithm. */
1504 if (prandom_u32() & 1)
1505 return 0;
1506#endif
1507
1508 /*
1509 * Start from the entry that lookup found, sequence through all larger
1510 * free blocks. If we're actually pointing at a record smaller than
1511 * maxlen, go to the start of this block, and skip all those smaller
1512 * than minlen.
1513 */
Darrick J. Wong77ca1ee2020-03-13 13:57:58 -07001514 if (*len || args->alignment > 1) {
Darrick J. Wong5113f8e2019-11-07 12:29:00 -08001515 acur->cnt->bc_ptrs[0] = 1;
1516 do {
1517 error = xfs_alloc_get_rec(acur->cnt, bno, len, &i);
1518 if (error)
1519 return error;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001520 if (XFS_IS_CORRUPT(args->mp, i != 1))
1521 return -EFSCORRUPTED;
Darrick J. Wong5113f8e2019-11-07 12:29:00 -08001522 if (*len >= args->minlen)
1523 break;
1524 error = xfs_btree_increment(acur->cnt, 0, &i);
1525 if (error)
1526 return error;
1527 } while (i);
1528 ASSERT(*len >= args->minlen);
1529 if (!i)
1530 return 0;
1531 }
1532
1533 error = xfs_alloc_walk_iter(args, acur, acur->cnt, true, false, -1, &i);
1534 if (error)
1535 return error;
1536
1537 /*
1538 * It didn't work. We COULD be in a case where there's a good record
1539 * somewhere, so try again.
1540 */
1541 if (acur->len == 0)
1542 return 0;
1543
1544 trace_xfs_alloc_near_first(args);
1545 *allocated = true;
1546 return 0;
1547}
1548
Brian Foster0e26d5c2019-10-13 17:10:35 -07001549/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 * Allocate a variable extent near bno in the allocation group agno.
1551 * Extent's length (returned in len) will be between minlen and maxlen,
1552 * and of the form k * prod + mod unless there's nothing that large.
1553 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
1554 */
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001555STATIC int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556xfs_alloc_ag_vextent_near(
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001557 struct xfs_alloc_arg *args)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558{
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001559 struct xfs_alloc_cur acur = {};
Brian Fosterfec0afd2019-10-13 17:10:33 -07001560 int error; /* error code */
1561 int i; /* result code, temporary */
Brian Fosterfec0afd2019-10-13 17:10:33 -07001562 xfs_agblock_t bno;
1563 xfs_extlen_t len;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001564
Joe Perchescf085a12019-11-07 13:24:52 -08001565 /* handle uninitialized agbno range so caller doesn't have to */
Brian Fosterbfe46d42015-05-29 08:53:00 +10001566 if (!args->min_agbno && !args->max_agbno)
1567 args->max_agbno = args->mp->m_sb.sb_agblocks - 1;
1568 ASSERT(args->min_agbno <= args->max_agbno);
1569
1570 /* clamp agbno to the range if it's outside */
1571 if (args->agbno < args->min_agbno)
1572 args->agbno = args->min_agbno;
1573 if (args->agbno > args->max_agbno)
1574 args->agbno = args->max_agbno;
1575
Christoph Hellwige26f0502011-04-24 19:06:15 +00001576restart:
Brian Fosterfec0afd2019-10-13 17:10:33 -07001577 len = 0;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001578
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 /*
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001580 * Set up cursors and see if there are any free extents as big as
1581 * maxlen. If not, pick the last entry in the tree unless the tree is
1582 * empty.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 */
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001584 error = xfs_alloc_cur_setup(args, &acur);
1585 if (error == -ENOSPC) {
Brian Fosterfec0afd2019-10-13 17:10:33 -07001586 error = xfs_alloc_ag_vextent_small(args, acur.cnt, &bno,
1587 &len, &i);
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001588 if (error)
1589 goto out;
Brian Fosterfec0afd2019-10-13 17:10:33 -07001590 if (i == 0 || len == 0) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001591 trace_xfs_alloc_near_noentry(args);
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001592 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 }
1594 ASSERT(i == 1);
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001595 } else if (error) {
1596 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 }
Christoph Hellwige26f0502011-04-24 19:06:15 +00001598
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 /*
1600 * First algorithm.
1601 * If the requested extent is large wrt the freespaces available
1602 * in this a.g., then the cursor will be pointing to a btree entry
1603 * near the right edge of the tree. If it's in the last btree leaf
1604 * block, then we just examine all the entries in that block
1605 * that are big enough, and pick the best one.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 */
Darrick J. Wong5113f8e2019-11-07 12:29:00 -08001607 if (xfs_btree_islastblock(acur.cnt, 0)) {
1608 bool allocated = false;
Brian Foster78d7aab2019-10-13 17:10:34 -07001609
Darrick J. Wong5113f8e2019-11-07 12:29:00 -08001610 error = xfs_alloc_ag_vextent_lastblock(args, &acur, &bno, &len,
1611 &allocated);
Brian Foster78d7aab2019-10-13 17:10:34 -07001612 if (error)
1613 goto out;
Darrick J. Wong5113f8e2019-11-07 12:29:00 -08001614 if (allocated)
1615 goto alloc_finish;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 }
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001617
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 /*
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001619 * Second algorithm. Combined cntbt and bnobt search to find ideal
1620 * locality.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 */
Brian Fosterdc8e69b2019-10-13 17:10:36 -07001622 error = xfs_alloc_ag_vextent_locality(args, &acur, &i);
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001623 if (error)
1624 goto out;
Christoph Hellwig489a1502010-12-10 15:04:11 +00001625
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 /*
1627 * If we couldn't get anything, give up.
1628 */
Brian Fosterfec0afd2019-10-13 17:10:33 -07001629 if (!acur.len) {
Brian Fosterd6d3aff2019-10-13 17:10:32 -07001630 if (acur.busy) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001631 trace_xfs_alloc_near_busy(args);
Brian Fosterd6d3aff2019-10-13 17:10:32 -07001632 xfs_extent_busy_flush(args->mp, args->pag,
1633 acur.busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001634 goto restart;
1635 }
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001636 trace_xfs_alloc_size_neither(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 args->agbno = NULLAGBLOCK;
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001638 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 }
Christoph Hellwig489a1502010-12-10 15:04:11 +00001640
Darrick J. Wong5113f8e2019-11-07 12:29:00 -08001641alloc_finish:
Brian Fosterd2968822019-10-13 17:10:35 -07001642 /* fix up btrees on a successful allocation */
1643 error = xfs_alloc_cur_finish(args, &acur);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001644
Brian Fosterf5e7dbe2019-10-13 17:10:31 -07001645out:
1646 xfs_alloc_cur_close(&acur, error);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 return error;
1648}
1649
1650/*
1651 * Allocate a variable extent anywhere in the allocation group agno.
1652 * Extent's length (returned in len) will be between minlen and maxlen,
1653 * and of the form k * prod + mod unless there's nothing that large.
1654 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
1655 */
1656STATIC int /* error */
1657xfs_alloc_ag_vextent_size(
1658 xfs_alloc_arg_t *args) /* allocation argument structure */
1659{
Christoph Hellwig9798f612020-03-10 08:57:29 -07001660 struct xfs_agf *agf = args->agbp->b_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 xfs_btree_cur_t *bno_cur; /* cursor for bno btree */
1662 xfs_btree_cur_t *cnt_cur; /* cursor for cnt btree */
1663 int error; /* error result */
1664 xfs_agblock_t fbno; /* start of found freespace */
1665 xfs_extlen_t flen; /* length of found freespace */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 int i; /* temp status variable */
1667 xfs_agblock_t rbno; /* returned block number */
1668 xfs_extlen_t rlen; /* length of returned extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -08001669 bool busy;
1670 unsigned busy_gen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671
Christoph Hellwige26f0502011-04-24 19:06:15 +00001672restart:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 /*
1674 * Allocate and initialize a cursor for the by-size btree.
1675 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001676 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
Dave Chinner289d38d2021-06-02 10:48:24 +10001677 args->pag, XFS_BTNUM_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678 bno_cur = NULL;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001679
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 /*
1681 * Look for an entry >= maxlen+alignment-1 blocks.
1682 */
1683 if ((error = xfs_alloc_lookup_ge(cnt_cur, 0,
1684 args->maxlen + args->alignment - 1, &i)))
1685 goto error0;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001686
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 /*
Christoph Hellwigebf55872017-02-07 14:06:57 -08001688 * If none then we have to settle for a smaller extent. In the case that
1689 * there are no large extents, this will return the last entry in the
1690 * tree unless the tree is empty. In the case that there are only busy
1691 * large extents, this will return the largest small extent unless there
Christoph Hellwige26f0502011-04-24 19:06:15 +00001692 * are no smaller extents available.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 */
Christoph Hellwigebf55872017-02-07 14:06:57 -08001694 if (!i) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001695 error = xfs_alloc_ag_vextent_small(args, cnt_cur,
1696 &fbno, &flen, &i);
1697 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 goto error0;
1699 if (i == 0 || flen == 0) {
1700 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001701 trace_xfs_alloc_size_noentry(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 return 0;
1703 }
1704 ASSERT(i == 1);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001705 busy = xfs_alloc_compute_aligned(args, fbno, flen, &rbno,
1706 &rlen, &busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001707 } else {
1708 /*
1709 * Search for a non-busy extent that is large enough.
Christoph Hellwige26f0502011-04-24 19:06:15 +00001710 */
1711 for (;;) {
1712 error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i);
1713 if (error)
1714 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001715 if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1716 error = -EFSCORRUPTED;
1717 goto error0;
1718 }
Christoph Hellwige26f0502011-04-24 19:06:15 +00001719
Christoph Hellwigebf55872017-02-07 14:06:57 -08001720 busy = xfs_alloc_compute_aligned(args, fbno, flen,
1721 &rbno, &rlen, &busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001722
1723 if (rlen >= args->maxlen)
1724 break;
1725
1726 error = xfs_btree_increment(cnt_cur, 0, &i);
1727 if (error)
1728 goto error0;
1729 if (i == 0) {
1730 /*
1731 * Our only valid extents must have been busy.
1732 * Make it unbusy by forcing the log out and
Christoph Hellwigebf55872017-02-07 14:06:57 -08001733 * retrying.
Christoph Hellwige26f0502011-04-24 19:06:15 +00001734 */
1735 xfs_btree_del_cursor(cnt_cur,
1736 XFS_BTREE_NOERROR);
1737 trace_xfs_alloc_size_busy(args);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001738 xfs_extent_busy_flush(args->mp,
1739 args->pag, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001740 goto restart;
1741 }
1742 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 }
Christoph Hellwige26f0502011-04-24 19:06:15 +00001744
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 /*
1746 * In the first case above, we got the last entry in the
1747 * by-size btree. Now we check to see if the space hits maxlen
1748 * once aligned; if not, we search left for something better.
1749 * This can't happen in the second case above.
1750 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001752 if (XFS_IS_CORRUPT(args->mp,
1753 rlen != 0 &&
1754 (rlen > flen ||
1755 rbno + rlen > fbno + flen))) {
1756 error = -EFSCORRUPTED;
1757 goto error0;
1758 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 if (rlen < args->maxlen) {
1760 xfs_agblock_t bestfbno;
1761 xfs_extlen_t bestflen;
1762 xfs_agblock_t bestrbno;
1763 xfs_extlen_t bestrlen;
1764
1765 bestrlen = rlen;
1766 bestrbno = rbno;
1767 bestflen = flen;
1768 bestfbno = fbno;
1769 for (;;) {
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001770 if ((error = xfs_btree_decrement(cnt_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 goto error0;
1772 if (i == 0)
1773 break;
1774 if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen,
1775 &i)))
1776 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001777 if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1778 error = -EFSCORRUPTED;
1779 goto error0;
1780 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 if (flen < bestrlen)
1782 break;
Christoph Hellwigebf55872017-02-07 14:06:57 -08001783 busy = xfs_alloc_compute_aligned(args, fbno, flen,
1784 &rbno, &rlen, &busy_gen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001786 if (XFS_IS_CORRUPT(args->mp,
1787 rlen != 0 &&
1788 (rlen > flen ||
1789 rbno + rlen > fbno + flen))) {
1790 error = -EFSCORRUPTED;
1791 goto error0;
1792 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 if (rlen > bestrlen) {
1794 bestrlen = rlen;
1795 bestrbno = rbno;
1796 bestflen = flen;
1797 bestfbno = fbno;
1798 if (rlen == args->maxlen)
1799 break;
1800 }
1801 }
1802 if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen,
1803 &i)))
1804 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001805 if (XFS_IS_CORRUPT(args->mp, i != 1)) {
1806 error = -EFSCORRUPTED;
1807 goto error0;
1808 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 rlen = bestrlen;
1810 rbno = bestrbno;
1811 flen = bestflen;
1812 fbno = bestfbno;
1813 }
1814 args->wasfromfl = 0;
1815 /*
1816 * Fix up the length.
1817 */
1818 args->len = rlen;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001819 if (rlen < args->minlen) {
Christoph Hellwigebf55872017-02-07 14:06:57 -08001820 if (busy) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001821 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1822 trace_xfs_alloc_size_busy(args);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001823 xfs_extent_busy_flush(args->mp, args->pag, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001824 goto restart;
1825 }
1826 goto out_nominleft;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 }
Christoph Hellwige26f0502011-04-24 19:06:15 +00001828 xfs_alloc_fix_len(args);
1829
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 rlen = args->len;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001831 if (XFS_IS_CORRUPT(args->mp, rlen > flen)) {
1832 error = -EFSCORRUPTED;
1833 goto error0;
1834 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 /*
1836 * Allocate and initialize a cursor for the by-block tree.
1837 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001838 bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
Dave Chinner289d38d2021-06-02 10:48:24 +10001839 args->pag, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
1841 rbno, rlen, XFSA_FIXUP_CNT_OK)))
1842 goto error0;
1843 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1844 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
1845 cnt_cur = bno_cur = NULL;
1846 args->len = rlen;
1847 args->agbno = rbno;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001848 if (XFS_IS_CORRUPT(args->mp,
1849 args->agbno + args->len >
Christoph Hellwig9798f612020-03-10 08:57:29 -07001850 be32_to_cpu(agf->agf_length))) {
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001851 error = -EFSCORRUPTED;
1852 goto error0;
1853 }
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001854 trace_xfs_alloc_size_done(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 return 0;
1856
1857error0:
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001858 trace_xfs_alloc_size_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 if (cnt_cur)
1860 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1861 if (bno_cur)
1862 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
1863 return error;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001864
1865out_nominleft:
1866 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1867 trace_xfs_alloc_size_nominleft(args);
1868 args->agbno = NULLAGBLOCK;
1869 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870}
1871
1872/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 * Free the extent starting at agno/bno for length.
1874 */
Darrick J. Wong340785c2016-08-03 11:33:42 +10001875STATIC int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876xfs_free_ag_extent(
Darrick J. Wong66e32372018-12-12 08:46:23 -08001877 struct xfs_trans *tp,
1878 struct xfs_buf *agbp,
1879 xfs_agnumber_t agno,
1880 xfs_agblock_t bno,
1881 xfs_extlen_t len,
1882 const struct xfs_owner_info *oinfo,
1883 enum xfs_ag_resv_type type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884{
Darrick J. Wong66e32372018-12-12 08:46:23 -08001885 struct xfs_mount *mp;
Darrick J. Wong66e32372018-12-12 08:46:23 -08001886 struct xfs_btree_cur *bno_cur;
1887 struct xfs_btree_cur *cnt_cur;
1888 xfs_agblock_t gtbno; /* start of right neighbor */
1889 xfs_extlen_t gtlen; /* length of right neighbor */
1890 xfs_agblock_t ltbno; /* start of left neighbor */
1891 xfs_extlen_t ltlen; /* length of left neighbor */
1892 xfs_agblock_t nbno; /* new starting block of freesp */
1893 xfs_extlen_t nlen; /* new length of freespace */
1894 int haveleft; /* have a left neighbor */
1895 int haveright; /* have a right neighbor */
1896 int i;
1897 int error;
Dave Chinnerfa9c3c12021-06-02 10:48:24 +10001898 struct xfs_perag *pag = agbp->b_pag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
Darrick J. Wong673930c2016-08-03 11:33:43 +10001900 bno_cur = cnt_cur = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 mp = tp->t_mountp;
Darrick J. Wong673930c2016-08-03 11:33:43 +10001902
Darrick J. Wong33df3a92017-12-07 19:07:27 -08001903 if (!xfs_rmap_should_skip_owner_update(oinfo)) {
Dave Chinnerfa9c3c12021-06-02 10:48:24 +10001904 error = xfs_rmap_free(tp, agbp, pag, bno, len, oinfo);
Darrick J. Wong673930c2016-08-03 11:33:43 +10001905 if (error)
1906 goto error0;
1907 }
1908
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 /*
1910 * Allocate and initialize a cursor for the by-block btree.
1911 */
Dave Chinner289d38d2021-06-02 10:48:24 +10001912 bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 /*
1914 * Look for a neighboring block on the left (lower block numbers)
1915 * that is contiguous with this space.
1916 */
1917 if ((error = xfs_alloc_lookup_le(bno_cur, bno, len, &haveleft)))
1918 goto error0;
1919 if (haveleft) {
1920 /*
1921 * There is a block to our left.
1922 */
1923 if ((error = xfs_alloc_get_rec(bno_cur, &ltbno, &ltlen, &i)))
1924 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001925 if (XFS_IS_CORRUPT(mp, i != 1)) {
1926 error = -EFSCORRUPTED;
1927 goto error0;
1928 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 /*
1930 * It's not contiguous, though.
1931 */
1932 if (ltbno + ltlen < bno)
1933 haveleft = 0;
1934 else {
1935 /*
1936 * If this failure happens the request to free this
1937 * space was invalid, it's (partly) already free.
1938 * Very bad.
1939 */
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001940 if (XFS_IS_CORRUPT(mp, ltbno + ltlen > bno)) {
1941 error = -EFSCORRUPTED;
1942 goto error0;
1943 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 }
1945 }
1946 /*
1947 * Look for a neighboring block on the right (higher block numbers)
1948 * that is contiguous with this space.
1949 */
Christoph Hellwig637aa502008-10-30 16:55:45 +11001950 if ((error = xfs_btree_increment(bno_cur, 0, &haveright)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 goto error0;
1952 if (haveright) {
1953 /*
1954 * There is a block to our right.
1955 */
1956 if ((error = xfs_alloc_get_rec(bno_cur, &gtbno, &gtlen, &i)))
1957 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001958 if (XFS_IS_CORRUPT(mp, i != 1)) {
1959 error = -EFSCORRUPTED;
1960 goto error0;
1961 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 /*
1963 * It's not contiguous, though.
1964 */
1965 if (bno + len < gtbno)
1966 haveright = 0;
1967 else {
1968 /*
1969 * If this failure happens the request to free this
1970 * space was invalid, it's (partly) already free.
1971 * Very bad.
1972 */
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001973 if (XFS_IS_CORRUPT(mp, bno + len > gtbno)) {
1974 error = -EFSCORRUPTED;
1975 goto error0;
1976 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 }
1978 }
1979 /*
1980 * Now allocate and initialize a cursor for the by-size tree.
1981 */
Dave Chinner289d38d2021-06-02 10:48:24 +10001982 cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983 /*
1984 * Have both left and right contiguous neighbors.
1985 * Merge all three into a single free block.
1986 */
1987 if (haveleft && haveright) {
1988 /*
1989 * Delete the old by-size entry on the left.
1990 */
1991 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
1992 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001993 if (XFS_IS_CORRUPT(mp, i != 1)) {
1994 error = -EFSCORRUPTED;
1995 goto error0;
1996 }
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001997 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08001999 if (XFS_IS_CORRUPT(mp, i != 1)) {
2000 error = -EFSCORRUPTED;
2001 goto error0;
2002 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003 /*
2004 * Delete the old by-size entry on the right.
2005 */
2006 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
2007 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002008 if (XFS_IS_CORRUPT(mp, i != 1)) {
2009 error = -EFSCORRUPTED;
2010 goto error0;
2011 }
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11002012 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002014 if (XFS_IS_CORRUPT(mp, i != 1)) {
2015 error = -EFSCORRUPTED;
2016 goto error0;
2017 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018 /*
2019 * Delete the old by-block entry for the right block.
2020 */
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11002021 if ((error = xfs_btree_delete(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002023 if (XFS_IS_CORRUPT(mp, i != 1)) {
2024 error = -EFSCORRUPTED;
2025 goto error0;
2026 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 /*
2028 * Move the by-block cursor back to the left neighbor.
2029 */
Christoph Hellwig8df4da42008-10-30 16:55:58 +11002030 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002032 if (XFS_IS_CORRUPT(mp, i != 1)) {
2033 error = -EFSCORRUPTED;
2034 goto error0;
2035 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036#ifdef DEBUG
2037 /*
2038 * Check that this is the right record: delete didn't
2039 * mangle the cursor.
2040 */
2041 {
2042 xfs_agblock_t xxbno;
2043 xfs_extlen_t xxlen;
2044
2045 if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen,
2046 &i)))
2047 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002048 if (XFS_IS_CORRUPT(mp,
2049 i != 1 ||
2050 xxbno != ltbno ||
2051 xxlen != ltlen)) {
2052 error = -EFSCORRUPTED;
2053 goto error0;
2054 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055 }
2056#endif
2057 /*
2058 * Update remaining by-block entry to the new, joined block.
2059 */
2060 nbno = ltbno;
2061 nlen = len + ltlen + gtlen;
2062 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
2063 goto error0;
2064 }
2065 /*
2066 * Have only a left contiguous neighbor.
2067 * Merge it together with the new freespace.
2068 */
2069 else if (haveleft) {
2070 /*
2071 * Delete the old by-size entry on the left.
2072 */
2073 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
2074 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002075 if (XFS_IS_CORRUPT(mp, i != 1)) {
2076 error = -EFSCORRUPTED;
2077 goto error0;
2078 }
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11002079 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002081 if (XFS_IS_CORRUPT(mp, i != 1)) {
2082 error = -EFSCORRUPTED;
2083 goto error0;
2084 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 /*
2086 * Back up the by-block cursor to the left neighbor, and
2087 * update its length.
2088 */
Christoph Hellwig8df4da42008-10-30 16:55:58 +11002089 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002091 if (XFS_IS_CORRUPT(mp, i != 1)) {
2092 error = -EFSCORRUPTED;
2093 goto error0;
2094 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095 nbno = ltbno;
2096 nlen = len + ltlen;
2097 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
2098 goto error0;
2099 }
2100 /*
2101 * Have only a right contiguous neighbor.
2102 * Merge it together with the new freespace.
2103 */
2104 else if (haveright) {
2105 /*
2106 * Delete the old by-size entry on the right.
2107 */
2108 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
2109 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002110 if (XFS_IS_CORRUPT(mp, i != 1)) {
2111 error = -EFSCORRUPTED;
2112 goto error0;
2113 }
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11002114 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002116 if (XFS_IS_CORRUPT(mp, i != 1)) {
2117 error = -EFSCORRUPTED;
2118 goto error0;
2119 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 /*
2121 * Update the starting block and length of the right
2122 * neighbor in the by-block tree.
2123 */
2124 nbno = bno;
2125 nlen = len + gtlen;
2126 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
2127 goto error0;
2128 }
2129 /*
2130 * No contiguous neighbors.
2131 * Insert the new freespace into the by-block tree.
2132 */
2133 else {
2134 nbno = bno;
2135 nlen = len;
Christoph Hellwig4b22a572008-10-30 16:57:40 +11002136 if ((error = xfs_btree_insert(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002138 if (XFS_IS_CORRUPT(mp, i != 1)) {
2139 error = -EFSCORRUPTED;
2140 goto error0;
2141 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142 }
2143 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
2144 bno_cur = NULL;
2145 /*
2146 * In all cases we need to insert the new freespace in the by-size tree.
2147 */
2148 if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i)))
2149 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002150 if (XFS_IS_CORRUPT(mp, i != 0)) {
2151 error = -EFSCORRUPTED;
2152 goto error0;
2153 }
Christoph Hellwig4b22a572008-10-30 16:57:40 +11002154 if ((error = xfs_btree_insert(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 goto error0;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08002156 if (XFS_IS_CORRUPT(mp, i != 1)) {
2157 error = -EFSCORRUPTED;
2158 goto error0;
2159 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002160 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
2161 cnt_cur = NULL;
Christoph Hellwigecb69282011-03-04 12:59:55 +00002162
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163 /*
2164 * Update the freespace totals in the ag and superblock.
2165 */
Gao Xiang92a00542020-07-13 09:13:00 -07002166 error = xfs_alloc_update_counters(tp, agbp, len);
2167 xfs_ag_resv_free_extent(agbp->b_pag, type, tp, len);
Christoph Hellwigecb69282011-03-04 12:59:55 +00002168 if (error)
2169 goto error0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170
Bill O'Donnellff6d6af2015-10-12 18:21:22 +11002171 XFS_STATS_INC(mp, xs_freex);
2172 XFS_STATS_ADD(mp, xs_freeb, len);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002173
Brian Foster21592862018-03-09 14:01:59 -08002174 trace_xfs_free_extent(mp, agno, bno, len, type, haveleft, haveright);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 return 0;
2177
2178 error0:
Brian Foster21592862018-03-09 14:01:59 -08002179 trace_xfs_free_extent(mp, agno, bno, len, type, -1, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180 if (bno_cur)
2181 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
2182 if (cnt_cur)
2183 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
2184 return error;
2185}
2186
2187/*
2188 * Visible (exported) allocation/free functions.
2189 * Some of these are used just by xfs_alloc_btree.c and this file.
2190 */
2191
2192/*
2193 * Compute and fill in value of m_ag_maxlevels.
2194 */
2195void
2196xfs_alloc_compute_maxlevels(
2197 xfs_mount_t *mp) /* file system mount structure */
2198{
Eric Sandeena1f69412018-04-06 10:09:42 -07002199 mp->m_ag_maxlevels = xfs_btree_compute_maxlevels(mp->m_alloc_mnr,
Darrick J. Wong19b54ee2016-06-21 11:53:28 +10002200 (mp->m_sb.sb_agblocks + 1) / 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201}
2202
2203/*
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002204 * Find the length of the longest extent in an AG. The 'need' parameter
2205 * specifies how much space we're going to need for the AGFL and the
2206 * 'reserved' parameter tells us how many blocks in this AG are reserved for
2207 * other callers.
Dave Chinner6cc87642009-03-16 08:29:46 +01002208 */
2209xfs_extlen_t
2210xfs_alloc_longest_free_extent(
Dave Chinner50adbcb2015-06-22 10:04:31 +10002211 struct xfs_perag *pag,
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002212 xfs_extlen_t need,
2213 xfs_extlen_t reserved)
Dave Chinner6cc87642009-03-16 08:29:46 +01002214{
Dave Chinner50adbcb2015-06-22 10:04:31 +10002215 xfs_extlen_t delta = 0;
Dave Chinner6cc87642009-03-16 08:29:46 +01002216
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002217 /*
2218 * If the AGFL needs a recharge, we'll have to subtract that from the
2219 * longest extent.
2220 */
Dave Chinner6cc87642009-03-16 08:29:46 +01002221 if (need > pag->pagf_flcount)
2222 delta = need - pag->pagf_flcount;
2223
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002224 /*
2225 * If we cannot maintain others' reservations with space from the
2226 * not-longest freesp extents, we'll have to subtract /that/ from
2227 * the longest extent too.
2228 */
2229 if (pag->pagf_freeblks - pag->pagf_longest < reserved)
2230 delta += reserved - (pag->pagf_freeblks - pag->pagf_longest);
2231
2232 /*
2233 * If the longest extent is long enough to satisfy all the
2234 * reservations and AGFL rules in place, we can return this extent.
2235 */
Dave Chinner6cc87642009-03-16 08:29:46 +01002236 if (pag->pagf_longest > delta)
Dave Chinner1c743572019-10-21 09:26:34 -07002237 return min_t(xfs_extlen_t, pag->pag_mount->m_ag_max_usable,
2238 pag->pagf_longest - delta);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002239
2240 /* Otherwise, let the caller try for 1 block if there's space. */
Dave Chinner6cc87642009-03-16 08:29:46 +01002241 return pag->pagf_flcount > 0 || pag->pagf_longest > 0;
2242}
2243
Darrick J. Wong1cac2332019-12-18 11:09:55 -08002244/*
2245 * Compute the minimum length of the AGFL in the given AG. If @pag is NULL,
2246 * return the largest possible minimum length.
2247 */
Dave Chinner496817b2015-06-22 10:13:30 +10002248unsigned int
2249xfs_alloc_min_freelist(
2250 struct xfs_mount *mp,
2251 struct xfs_perag *pag)
2252{
Darrick J. Wong1cac2332019-12-18 11:09:55 -08002253 /* AG btrees have at least 1 level. */
2254 static const uint8_t fake_levels[XFS_BTNUM_AGF] = {1, 1, 1};
2255 const uint8_t *levels = pag ? pag->pagf_levels : fake_levels;
Dave Chinner496817b2015-06-22 10:13:30 +10002256 unsigned int min_free;
2257
Darrick J. Wong1cac2332019-12-18 11:09:55 -08002258 ASSERT(mp->m_ag_maxlevels > 0);
2259
Dave Chinner496817b2015-06-22 10:13:30 +10002260 /* space needed by-bno freespace btree */
Darrick J. Wong1cac2332019-12-18 11:09:55 -08002261 min_free = min_t(unsigned int, levels[XFS_BTNUM_BNOi] + 1,
Dave Chinner496817b2015-06-22 10:13:30 +10002262 mp->m_ag_maxlevels);
2263 /* space needed by-size freespace btree */
Darrick J. Wong1cac2332019-12-18 11:09:55 -08002264 min_free += min_t(unsigned int, levels[XFS_BTNUM_CNTi] + 1,
Dave Chinner496817b2015-06-22 10:13:30 +10002265 mp->m_ag_maxlevels);
Darrick J. Wong52548852016-08-03 11:38:24 +10002266 /* space needed reverse mapping used space btree */
Dave Chinnerebd90272021-08-18 18:46:55 -07002267 if (xfs_has_rmapbt(mp))
Darrick J. Wong1cac2332019-12-18 11:09:55 -08002268 min_free += min_t(unsigned int, levels[XFS_BTNUM_RMAPi] + 1,
2269 mp->m_rmap_maxlevels);
Dave Chinner496817b2015-06-22 10:13:30 +10002270
2271 return min_free;
2272}
2273
Dave Chinner6cc87642009-03-16 08:29:46 +01002274/*
Dave Chinner72d55282015-06-22 10:04:42 +10002275 * Check if the operation we are fixing up the freelist for should go ahead or
2276 * not. If we are freeing blocks, we always allow it, otherwise the allocation
2277 * is dependent on whether the size and shape of free space available will
2278 * permit the requested allocation to take place.
2279 */
2280static bool
2281xfs_alloc_space_available(
2282 struct xfs_alloc_arg *args,
2283 xfs_extlen_t min_free,
2284 int flags)
2285{
2286 struct xfs_perag *pag = args->pag;
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002287 xfs_extlen_t alloc_len, longest;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002288 xfs_extlen_t reservation; /* blocks that are still reserved */
Dave Chinner72d55282015-06-22 10:04:42 +10002289 int available;
Brian Foster1ca89fb2019-04-12 07:39:21 -07002290 xfs_extlen_t agflcount;
Dave Chinner72d55282015-06-22 10:04:42 +10002291
2292 if (flags & XFS_ALLOC_FLAG_FREEING)
2293 return true;
2294
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002295 reservation = xfs_ag_resv_needed(pag, args->resv);
2296
Dave Chinner72d55282015-06-22 10:04:42 +10002297 /* do we have enough contiguous free space for the allocation? */
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002298 alloc_len = args->minlen + (args->alignment - 1) + args->minalignslop;
Eric Sandeena1f69412018-04-06 10:09:42 -07002299 longest = xfs_alloc_longest_free_extent(pag, min_free, reservation);
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002300 if (longest < alloc_len)
Dave Chinner72d55282015-06-22 10:04:42 +10002301 return false;
2302
Brian Foster1ca89fb2019-04-12 07:39:21 -07002303 /*
2304 * Do we have enough free space remaining for the allocation? Don't
2305 * account extra agfl blocks because we are about to defer free them,
2306 * making them unavailable until the current transaction commits.
2307 */
2308 agflcount = min_t(xfs_extlen_t, pag->pagf_flcount, min_free);
2309 available = (int)(pag->pagf_freeblks + agflcount -
Christoph Hellwig54fee132017-01-09 13:44:30 -08002310 reservation - min_free - args->minleft);
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002311 if (available < (int)max(args->total, alloc_len))
Dave Chinner72d55282015-06-22 10:04:42 +10002312 return false;
2313
Christoph Hellwig54fee132017-01-09 13:44:30 -08002314 /*
2315 * Clamp maxlen to the amount of free space available for the actual
2316 * extent allocation.
2317 */
2318 if (available < (int)args->maxlen && !(flags & XFS_ALLOC_FLAG_CHECK)) {
2319 args->maxlen = available;
2320 ASSERT(args->maxlen > 0);
2321 ASSERT(args->maxlen >= args->minlen);
2322 }
2323
Dave Chinner72d55282015-06-22 10:04:42 +10002324 return true;
2325}
2326
Brian Foster4223f652018-05-07 17:38:46 -07002327int
2328xfs_free_agfl_block(
2329 struct xfs_trans *tp,
2330 xfs_agnumber_t agno,
2331 xfs_agblock_t agbno,
2332 struct xfs_buf *agbp,
2333 struct xfs_owner_info *oinfo)
2334{
2335 int error;
2336 struct xfs_buf *bp;
2337
2338 error = xfs_free_ag_extent(tp, agbp, agno, agbno, 1, oinfo,
2339 XFS_AG_RESV_AGFL);
2340 if (error)
2341 return error;
2342
Darrick J. Wongee647f82020-01-23 17:01:19 -08002343 error = xfs_trans_get_buf(tp, tp->t_mountp->m_ddev_targp,
2344 XFS_AGB_TO_DADDR(tp->t_mountp, agno, agbno),
2345 tp->t_mountp->m_bsize, 0, &bp);
2346 if (error)
2347 return error;
Brian Foster4223f652018-05-07 17:38:46 -07002348 xfs_trans_binval(tp, bp);
2349
2350 return 0;
2351}
2352
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353/*
Brian Fostera27ba262018-03-15 10:51:58 -07002354 * Check the agfl fields of the agf for inconsistency or corruption. The purpose
2355 * is to detect an agfl header padding mismatch between current and early v5
2356 * kernels. This problem manifests as a 1-slot size difference between the
2357 * on-disk flcount and the active [first, last] range of a wrapped agfl. This
2358 * may also catch variants of agfl count corruption unrelated to padding. Either
2359 * way, we'll reset the agfl and warn the user.
2360 *
2361 * Return true if a reset is required before the agfl can be used, false
2362 * otherwise.
2363 */
2364static bool
2365xfs_agfl_needs_reset(
2366 struct xfs_mount *mp,
2367 struct xfs_agf *agf)
2368{
2369 uint32_t f = be32_to_cpu(agf->agf_flfirst);
2370 uint32_t l = be32_to_cpu(agf->agf_fllast);
2371 uint32_t c = be32_to_cpu(agf->agf_flcount);
2372 int agfl_size = xfs_agfl_size(mp);
2373 int active;
2374
2375 /* no agfl header on v4 supers */
Dave Chinner38c26bf2021-08-18 18:46:37 -07002376 if (!xfs_has_crc(mp))
Brian Fostera27ba262018-03-15 10:51:58 -07002377 return false;
2378
2379 /*
2380 * The agf read verifier catches severe corruption of these fields.
2381 * Repeat some sanity checks to cover a packed -> unpacked mismatch if
2382 * the verifier allows it.
2383 */
2384 if (f >= agfl_size || l >= agfl_size)
2385 return true;
2386 if (c > agfl_size)
2387 return true;
2388
2389 /*
2390 * Check consistency between the on-disk count and the active range. An
2391 * agfl padding mismatch manifests as an inconsistent flcount.
2392 */
2393 if (c && l >= f)
2394 active = l - f + 1;
2395 else if (c)
2396 active = agfl_size - f + l + 1;
2397 else
2398 active = 0;
2399
2400 return active != c;
2401}
2402
2403/*
2404 * Reset the agfl to an empty state. Ignore/drop any existing blocks since the
2405 * agfl content cannot be trusted. Warn the user that a repair is required to
2406 * recover leaked blocks.
2407 *
2408 * The purpose of this mechanism is to handle filesystems affected by the agfl
2409 * header padding mismatch problem. A reset keeps the filesystem online with a
2410 * relatively minor free space accounting inconsistency rather than suffer the
2411 * inevitable crash from use of an invalid agfl block.
2412 */
2413static void
2414xfs_agfl_reset(
2415 struct xfs_trans *tp,
2416 struct xfs_buf *agbp,
2417 struct xfs_perag *pag)
2418{
2419 struct xfs_mount *mp = tp->t_mountp;
Christoph Hellwig9798f612020-03-10 08:57:29 -07002420 struct xfs_agf *agf = agbp->b_addr;
Brian Fostera27ba262018-03-15 10:51:58 -07002421
2422 ASSERT(pag->pagf_agflreset);
2423 trace_xfs_agfl_reset(mp, agf, 0, _RET_IP_);
2424
2425 xfs_warn(mp,
2426 "WARNING: Reset corrupted AGFL on AG %u. %d blocks leaked. "
2427 "Please unmount and run xfs_repair.",
2428 pag->pag_agno, pag->pagf_flcount);
2429
2430 agf->agf_flfirst = 0;
2431 agf->agf_fllast = cpu_to_be32(xfs_agfl_size(mp) - 1);
2432 agf->agf_flcount = 0;
2433 xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLLAST |
2434 XFS_AGF_FLCOUNT);
2435
2436 pag->pagf_flcount = 0;
2437 pag->pagf_agflreset = false;
2438}
2439
2440/*
Brian Fosterf8f28352018-05-07 17:38:47 -07002441 * Defer an AGFL block free. This is effectively equivalent to
2442 * xfs_bmap_add_free() with some special handling particular to AGFL blocks.
2443 *
2444 * Deferring AGFL frees helps prevent log reservation overruns due to too many
2445 * allocation operations in a transaction. AGFL frees are prone to this problem
2446 * because for one they are always freed one at a time. Further, an immediate
2447 * AGFL block free can cause a btree join and require another block free before
2448 * the real allocation can proceed. Deferring the free disconnects freeing up
2449 * the AGFL slot from freeing the block.
2450 */
2451STATIC void
2452xfs_defer_agfl_block(
Brian Foster0f37d172018-08-01 07:20:34 -07002453 struct xfs_trans *tp,
Brian Fosterf8f28352018-05-07 17:38:47 -07002454 xfs_agnumber_t agno,
2455 xfs_fsblock_t agbno,
2456 struct xfs_owner_info *oinfo)
2457{
Brian Foster0f37d172018-08-01 07:20:34 -07002458 struct xfs_mount *mp = tp->t_mountp;
Brian Fosterf8f28352018-05-07 17:38:47 -07002459 struct xfs_extent_free_item *new; /* new element */
2460
2461 ASSERT(xfs_bmap_free_item_zone != NULL);
2462 ASSERT(oinfo != NULL);
2463
Carlos Maiolino3050bd02020-07-22 09:23:04 -07002464 new = kmem_cache_alloc(xfs_bmap_free_item_zone,
2465 GFP_KERNEL | __GFP_NOFAIL);
Brian Fosterf8f28352018-05-07 17:38:47 -07002466 new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
2467 new->xefi_blockcount = 1;
2468 new->xefi_oinfo = *oinfo;
Darrick J. Wong2c334e12020-10-26 15:19:38 -07002469 new->xefi_skip_discard = false;
Brian Fosterf8f28352018-05-07 17:38:47 -07002470
2471 trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
2472
Brian Foster0f37d172018-08-01 07:20:34 -07002473 xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &new->xefi_list);
Brian Fosterf8f28352018-05-07 17:38:47 -07002474}
2475
Chandan Babu R30151962021-01-22 16:48:17 -08002476#ifdef DEBUG
2477/*
2478 * Check if an AGF has a free extent record whose length is equal to
2479 * args->minlen.
2480 */
2481STATIC int
2482xfs_exact_minlen_extent_available(
2483 struct xfs_alloc_arg *args,
2484 struct xfs_buf *agbp,
2485 int *stat)
2486{
2487 struct xfs_btree_cur *cnt_cur;
2488 xfs_agblock_t fbno;
2489 xfs_extlen_t flen;
2490 int error = 0;
2491
2492 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, agbp,
Dave Chinner289d38d2021-06-02 10:48:24 +10002493 args->pag, XFS_BTNUM_CNT);
Chandan Babu R30151962021-01-22 16:48:17 -08002494 error = xfs_alloc_lookup_ge(cnt_cur, 0, args->minlen, stat);
2495 if (error)
2496 goto out;
2497
2498 if (*stat == 0) {
2499 error = -EFSCORRUPTED;
2500 goto out;
2501 }
2502
2503 error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, stat);
2504 if (error)
2505 goto out;
2506
2507 if (*stat == 1 && flen != args->minlen)
2508 *stat = 0;
2509
2510out:
2511 xfs_btree_del_cursor(cnt_cur, error);
2512
2513 return error;
2514}
2515#endif
2516
Brian Fosterf8f28352018-05-07 17:38:47 -07002517/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518 * Decide whether to use this allocation group for this allocation.
2519 * If so, fix up the btree freelist's size.
2520 */
Darrick J. Wong2e9101d2016-01-04 16:10:42 +11002521int /* error */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522xfs_alloc_fix_freelist(
Dave Chinner396503f2015-06-22 10:13:19 +10002523 struct xfs_alloc_arg *args, /* allocation argument structure */
2524 int flags) /* XFS_ALLOC_FLAG_... */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525{
Dave Chinner396503f2015-06-22 10:13:19 +10002526 struct xfs_mount *mp = args->mp;
2527 struct xfs_perag *pag = args->pag;
2528 struct xfs_trans *tp = args->tp;
2529 struct xfs_buf *agbp = NULL;
2530 struct xfs_buf *agflbp = NULL;
2531 struct xfs_alloc_arg targs; /* local allocation arguments */
2532 xfs_agblock_t bno; /* freelist block */
2533 xfs_extlen_t need; /* total blocks needed in freelist */
Jan Karac184f852015-08-25 10:05:13 +10002534 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535
Brian Foster362f5e72019-04-23 07:54:06 -07002536 /* deferred ops (AGFL block frees) require permanent transactions */
2537 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
2538
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 if (!pag->pagf_init) {
Dave Chinner396503f2015-06-22 10:13:19 +10002540 error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
Darrick J. Wongf48e2df2020-01-23 17:01:19 -08002541 if (error) {
2542 /* Couldn't lock the AGF so skip this AG. */
2543 if (error == -EAGAIN)
2544 error = 0;
Dave Chinner396503f2015-06-22 10:13:19 +10002545 goto out_no_agbp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546 }
Dave Chinner396503f2015-06-22 10:13:19 +10002547 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002549 /*
Dave Chinner396503f2015-06-22 10:13:19 +10002550 * If this is a metadata preferred pag and we are user data then try
2551 * somewhere else if we are not being asked to try harder at this
2552 * point
Linus Torvalds1da177e2005-04-16 15:20:36 -07002553 */
Christoph Hellwigc34d5702019-10-30 12:25:00 -07002554 if (pag->pagf_metadata && (args->datatype & XFS_ALLOC_USERDATA) &&
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002555 (flags & XFS_ALLOC_FLAG_TRYLOCK)) {
2556 ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
Dave Chinner396503f2015-06-22 10:13:19 +10002557 goto out_agbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558 }
2559
Dave Chinner496817b2015-06-22 10:13:30 +10002560 need = xfs_alloc_min_freelist(mp, pag);
Christoph Hellwig54fee132017-01-09 13:44:30 -08002561 if (!xfs_alloc_space_available(args, need, flags |
2562 XFS_ALLOC_FLAG_CHECK))
Dave Chinner396503f2015-06-22 10:13:19 +10002563 goto out_agbp_relse;
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002564
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565 /*
2566 * Get the a.g. freespace buffer.
2567 * Can fail if we're not blocking on locks, and it's held.
2568 */
Dave Chinner396503f2015-06-22 10:13:19 +10002569 if (!agbp) {
2570 error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
Darrick J. Wongf48e2df2020-01-23 17:01:19 -08002571 if (error) {
2572 /* Couldn't lock the AGF so skip this AG. */
2573 if (error == -EAGAIN)
2574 error = 0;
Dave Chinner396503f2015-06-22 10:13:19 +10002575 goto out_no_agbp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 }
2577 }
Dave Chinner50adbcb2015-06-22 10:04:31 +10002578
Brian Fostera27ba262018-03-15 10:51:58 -07002579 /* reset a padding mismatched agfl before final free space check */
2580 if (pag->pagf_agflreset)
2581 xfs_agfl_reset(tp, agbp, pag);
2582
Dave Chinner50adbcb2015-06-22 10:04:31 +10002583 /* If there isn't enough total space or single-extent, reject it. */
Dave Chinner496817b2015-06-22 10:13:30 +10002584 need = xfs_alloc_min_freelist(mp, pag);
Dave Chinner396503f2015-06-22 10:13:19 +10002585 if (!xfs_alloc_space_available(args, need, flags))
2586 goto out_agbp_relse;
Dave Chinner72d55282015-06-22 10:04:42 +10002587
Chandan Babu R30151962021-01-22 16:48:17 -08002588#ifdef DEBUG
2589 if (args->alloc_minlen_only) {
2590 int stat;
2591
2592 error = xfs_exact_minlen_extent_available(args, agbp, &stat);
2593 if (error || !stat)
2594 goto out_agbp_relse;
2595 }
2596#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597 /*
2598 * Make the freelist shorter if it's too long.
Dave Chinner50adbcb2015-06-22 10:04:31 +10002599 *
Dave Chinner396503f2015-06-22 10:13:19 +10002600 * Note that from this point onwards, we will always release the agf and
2601 * agfl buffers on error. This handles the case where we error out and
2602 * the buffers are clean or may not have been joined to the transaction
2603 * and hence need to be released manually. If they have been joined to
2604 * the transaction, then xfs_trans_brelse() will handle them
2605 * appropriately based on the recursion count and dirty state of the
2606 * buffer.
2607 *
Dave Chinner50adbcb2015-06-22 10:04:31 +10002608 * XXX (dgc): When we have lots of free space, does this buy us
2609 * anything other than extra overhead when we need to put more blocks
2610 * back on the free list? Maybe we should only do this when space is
2611 * getting low or the AGFL is more than half full?
Darrick J. Wong04f13062016-08-03 12:19:53 +10002612 *
2613 * The NOSHRINK flag prevents the AGFL from being shrunk if it's too
2614 * big; the NORMAP flag prevents AGFL expand/shrink operations from
2615 * updating the rmapbt. Both flags are used in xfs_repair while we're
2616 * rebuilding the rmapbt, and neither are used by the kernel. They're
2617 * both required to ensure that rmaps are correctly recorded for the
2618 * regenerated AGFL, bnobt, and cntbt. See repair/phase5.c and
2619 * repair/rmap.c in xfsprogs for details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620 */
Darrick J. Wong04f13062016-08-03 12:19:53 +10002621 memset(&targs, 0, sizeof(targs));
Darrick J. Wong7280fed2018-12-12 08:46:23 -08002622 /* struct copy below */
Darrick J. Wong04f13062016-08-03 12:19:53 +10002623 if (flags & XFS_ALLOC_FLAG_NORMAP)
Darrick J. Wong7280fed2018-12-12 08:46:23 -08002624 targs.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
Darrick J. Wong04f13062016-08-03 12:19:53 +10002625 else
Darrick J. Wong7280fed2018-12-12 08:46:23 -08002626 targs.oinfo = XFS_RMAP_OINFO_AG;
Darrick J. Wong04f13062016-08-03 12:19:53 +10002627 while (!(flags & XFS_ALLOC_FLAG_NOSHRINK) && pag->pagf_flcount > need) {
David Chinner92821e22007-05-24 15:26:31 +10002628 error = xfs_alloc_get_freelist(tp, agbp, &bno, 0);
2629 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002630 goto out_agbp_relse;
Brian Foster4223f652018-05-07 17:38:46 -07002631
Brian Fosterc03edc92018-08-01 07:20:35 -07002632 /* defer agfl frees */
2633 xfs_defer_agfl_block(tp, args->agno, bno, &targs.oinfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 }
Dave Chinner50adbcb2015-06-22 10:04:31 +10002635
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 targs.tp = tp;
2637 targs.mp = mp;
2638 targs.agbp = agbp;
2639 targs.agno = args->agno;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002640 targs.alignment = targs.minlen = targs.prod = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641 targs.type = XFS_ALLOCTYPE_THIS_AG;
2642 targs.pag = pag;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002643 error = xfs_alloc_read_agfl(mp, tp, targs.agno, &agflbp);
2644 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002645 goto out_agbp_relse;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002646
2647 /* Make the freelist longer if it's too short. */
2648 while (pag->pagf_flcount < need) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 targs.agbno = 0;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002650 targs.maxlen = need - pag->pagf_flcount;
Brian Foster0ab320862018-03-09 14:02:32 -08002651 targs.resv = XFS_AG_RESV_AGFL;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002652
2653 /* Allocate as many blocks as possible at once. */
2654 error = xfs_alloc_ag_vextent(&targs);
Dave Chinner396503f2015-06-22 10:13:19 +10002655 if (error)
2656 goto out_agflbp_relse;
2657
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 /*
2659 * Stop if we run out. Won't happen if callers are obeying
2660 * the restrictions correctly. Can happen for free calls
2661 * on a completely full ag.
2662 */
Yingping Lud210a282006-06-09 14:55:18 +10002663 if (targs.agbno == NULLAGBLOCK) {
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002664 if (flags & XFS_ALLOC_FLAG_FREEING)
2665 break;
Dave Chinner396503f2015-06-22 10:13:19 +10002666 goto out_agflbp_relse;
Yingping Lud210a282006-06-09 14:55:18 +10002667 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668 /*
2669 * Put each allocated block on the list.
2670 */
2671 for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) {
David Chinner92821e22007-05-24 15:26:31 +10002672 error = xfs_alloc_put_freelist(tp, agbp,
2673 agflbp, bno, 0);
2674 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002675 goto out_agflbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002676 }
2677 }
Nathan Scotte63a3692006-05-08 19:51:58 +10002678 xfs_trans_brelse(tp, agflbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679 args->agbp = agbp;
2680 return 0;
Dave Chinner396503f2015-06-22 10:13:19 +10002681
2682out_agflbp_relse:
2683 xfs_trans_brelse(tp, agflbp);
2684out_agbp_relse:
2685 if (agbp)
2686 xfs_trans_brelse(tp, agbp);
2687out_no_agbp:
2688 args->agbp = NULL;
2689 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690}
2691
2692/*
2693 * Get a block from the freelist.
2694 * Returns with the buffer for the block gotten.
2695 */
Dave Chinner50920112021-06-02 10:48:51 +10002696int
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697xfs_alloc_get_freelist(
Dave Chinner50920112021-06-02 10:48:51 +10002698 struct xfs_trans *tp,
2699 struct xfs_buf *agbp,
2700 xfs_agblock_t *bnop,
2701 int btreeblk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702{
Dave Chinner50920112021-06-02 10:48:51 +10002703 struct xfs_agf *agf = agbp->b_addr;
2704 struct xfs_buf *agflbp;
2705 xfs_agblock_t bno;
2706 __be32 *agfl_bno;
2707 int error;
2708 int logflags;
2709 struct xfs_mount *mp = tp->t_mountp;
2710 struct xfs_perag *pag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712 /*
2713 * Freelist is empty, give up.
2714 */
2715 if (!agf->agf_flcount) {
2716 *bnop = NULLAGBLOCK;
2717 return 0;
2718 }
2719 /*
2720 * Read the array of free blocks.
2721 */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002722 error = xfs_alloc_read_agfl(mp, tp, be32_to_cpu(agf->agf_seqno),
2723 &agflbp);
2724 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725 return error;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002726
2727
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 /*
2729 * Get the block number and update the data structures.
2730 */
Christoph Hellwig183606d2020-03-10 08:57:28 -07002731 agfl_bno = xfs_buf_to_agfl_bno(agflbp);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002732 bno = be32_to_cpu(agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002733 be32_add_cpu(&agf->agf_flfirst, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734 xfs_trans_brelse(tp, agflbp);
Dave Chinnera78ee252018-03-06 17:08:32 -08002735 if (be32_to_cpu(agf->agf_flfirst) == xfs_agfl_size(mp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736 agf->agf_flfirst = 0;
Dave Chinnera862e0f2010-01-11 11:47:41 +00002737
Gao Xiang92a00542020-07-13 09:13:00 -07002738 pag = agbp->b_pag;
Brian Fostera27ba262018-03-15 10:51:58 -07002739 ASSERT(!pag->pagf_agflreset);
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002740 be32_add_cpu(&agf->agf_flcount, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 pag->pagf_flcount--;
David Chinner92821e22007-05-24 15:26:31 +10002742
2743 logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
2744 if (btreeblk) {
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002745 be32_add_cpu(&agf->agf_btreeblks, 1);
David Chinner92821e22007-05-24 15:26:31 +10002746 pag->pagf_btreeblks++;
2747 logflags |= XFS_AGF_BTREEBLKS;
2748 }
2749
David Chinner92821e22007-05-24 15:26:31 +10002750 xfs_alloc_log_agf(tp, agbp, logflags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751 *bnop = bno;
2752
Linus Torvalds1da177e2005-04-16 15:20:36 -07002753 return 0;
2754}
2755
2756/*
2757 * Log the given fields from the agf structure.
2758 */
2759void
2760xfs_alloc_log_agf(
2761 xfs_trans_t *tp, /* transaction pointer */
Dave Chinnere8222612020-12-16 16:07:34 -08002762 struct xfs_buf *bp, /* buffer for a.g. freelist header */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763 int fields) /* mask of fields to be logged (XFS_AGF_...) */
2764{
2765 int first; /* first byte offset */
2766 int last; /* last byte offset */
2767 static const short offsets[] = {
2768 offsetof(xfs_agf_t, agf_magicnum),
2769 offsetof(xfs_agf_t, agf_versionnum),
2770 offsetof(xfs_agf_t, agf_seqno),
2771 offsetof(xfs_agf_t, agf_length),
2772 offsetof(xfs_agf_t, agf_roots[0]),
2773 offsetof(xfs_agf_t, agf_levels[0]),
2774 offsetof(xfs_agf_t, agf_flfirst),
2775 offsetof(xfs_agf_t, agf_fllast),
2776 offsetof(xfs_agf_t, agf_flcount),
2777 offsetof(xfs_agf_t, agf_freeblks),
2778 offsetof(xfs_agf_t, agf_longest),
David Chinner92821e22007-05-24 15:26:31 +10002779 offsetof(xfs_agf_t, agf_btreeblks),
Dave Chinner4e0e6042013-04-03 16:11:13 +11002780 offsetof(xfs_agf_t, agf_uuid),
Darrick J. Wongf32866fd2016-08-17 08:31:49 +10002781 offsetof(xfs_agf_t, agf_rmap_blocks),
Darrick J. Wongbdf28632016-10-03 09:11:19 -07002782 offsetof(xfs_agf_t, agf_refcount_blocks),
2783 offsetof(xfs_agf_t, agf_refcount_root),
2784 offsetof(xfs_agf_t, agf_refcount_level),
Darrick J. Wongda1f0392016-08-26 15:59:31 +10002785 /* needed so that we don't log the whole rest of the structure: */
2786 offsetof(xfs_agf_t, agf_spare64),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787 sizeof(xfs_agf_t)
2788 };
2789
Christoph Hellwig9798f612020-03-10 08:57:29 -07002790 trace_xfs_agf(tp->t_mountp, bp->b_addr, fields, _RET_IP_);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002791
Dave Chinner61fe1352013-04-03 16:11:30 +11002792 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGF_BUF);
Dave Chinner4e0e6042013-04-03 16:11:13 +11002793
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 xfs_btree_offsets(fields, offsets, XFS_AGF_NUM_BITS, &first, &last);
2795 xfs_trans_log_buf(tp, bp, (uint)first, (uint)last);
2796}
2797
2798/*
2799 * Interface for inode allocation to force the pag data to be initialized.
2800 */
2801int /* error */
2802xfs_alloc_pagf_init(
2803 xfs_mount_t *mp, /* file system mount structure */
2804 xfs_trans_t *tp, /* transaction pointer */
2805 xfs_agnumber_t agno, /* allocation group number */
2806 int flags) /* XFS_ALLOC_FLAGS_... */
2807{
Dave Chinnere8222612020-12-16 16:07:34 -08002808 struct xfs_buf *bp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809 int error;
2810
Darrick J. Wongf48e2df2020-01-23 17:01:19 -08002811 error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp);
2812 if (!error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813 xfs_trans_brelse(tp, bp);
Darrick J. Wongf48e2df2020-01-23 17:01:19 -08002814 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815}
2816
2817/*
2818 * Put the block on the freelist for the allocation group.
2819 */
Dave Chinner50920112021-06-02 10:48:51 +10002820int
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821xfs_alloc_put_freelist(
Dave Chinner50920112021-06-02 10:48:51 +10002822 struct xfs_trans *tp,
2823 struct xfs_buf *agbp,
2824 struct xfs_buf *agflbp,
2825 xfs_agblock_t bno,
2826 int btreeblk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827{
Christoph Hellwig9798f612020-03-10 08:57:29 -07002828 struct xfs_mount *mp = tp->t_mountp;
2829 struct xfs_agf *agf = agbp->b_addr;
Dave Chinner50920112021-06-02 10:48:51 +10002830 struct xfs_perag *pag;
2831 __be32 *blockp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 int error;
David Chinner92821e22007-05-24 15:26:31 +10002833 int logflags;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002834 __be32 *agfl_bno;
2835 int startoff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837 if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp,
Christoph Hellwig16259e72005-11-02 15:11:25 +11002838 be32_to_cpu(agf->agf_seqno), &agflbp)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839 return error;
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002840 be32_add_cpu(&agf->agf_fllast, 1);
Dave Chinnera78ee252018-03-06 17:08:32 -08002841 if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842 agf->agf_fllast = 0;
Dave Chinnera862e0f2010-01-11 11:47:41 +00002843
Gao Xiang92a00542020-07-13 09:13:00 -07002844 pag = agbp->b_pag;
Brian Fostera27ba262018-03-15 10:51:58 -07002845 ASSERT(!pag->pagf_agflreset);
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002846 be32_add_cpu(&agf->agf_flcount, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 pag->pagf_flcount++;
David Chinner92821e22007-05-24 15:26:31 +10002848
2849 logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
2850 if (btreeblk) {
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002851 be32_add_cpu(&agf->agf_btreeblks, -1);
David Chinner92821e22007-05-24 15:26:31 +10002852 pag->pagf_btreeblks--;
2853 logflags |= XFS_AGF_BTREEBLKS;
2854 }
2855
David Chinner92821e22007-05-24 15:26:31 +10002856 xfs_alloc_log_agf(tp, agbp, logflags);
2857
Dave Chinnera78ee252018-03-06 17:08:32 -08002858 ASSERT(be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp));
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002859
Christoph Hellwig183606d2020-03-10 08:57:28 -07002860 agfl_bno = xfs_buf_to_agfl_bno(agflbp);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002861 blockp = &agfl_bno[be32_to_cpu(agf->agf_fllast)];
Christoph Hellwige2101002006-09-28 10:56:51 +10002862 *blockp = cpu_to_be32(bno);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002863 startoff = (char *)blockp - (char *)agflbp->b_addr;
2864
David Chinner92821e22007-05-24 15:26:31 +10002865 xfs_alloc_log_agf(tp, agbp, logflags);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002866
Dave Chinner61fe1352013-04-03 16:11:30 +11002867 xfs_trans_buf_set_type(tp, agflbp, XFS_BLFT_AGFL_BUF);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002868 xfs_trans_log_buf(tp, agflbp, startoff,
2869 startoff + sizeof(xfs_agblock_t) - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870 return 0;
2871}
2872
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002873static xfs_failaddr_t
Dave Chinner612cfbf2012-11-14 17:52:32 +11002874xfs_agf_verify(
Darrick J. Wongb5572592018-01-08 10:51:08 -08002875 struct xfs_buf *bp)
2876{
Christoph Hellwigdbd329f12019-06-28 19:27:29 -07002877 struct xfs_mount *mp = bp->b_mount;
Christoph Hellwig9798f612020-03-10 08:57:29 -07002878 struct xfs_agf *agf = bp->b_addr;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002879
Dave Chinner38c26bf2021-08-18 18:46:37 -07002880 if (xfs_has_crc(mp)) {
Brian Fostera45086e2015-10-12 15:59:25 +11002881 if (!uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002882 return __this_address;
Christoph Hellwig9798f612020-03-10 08:57:29 -07002883 if (!xfs_log_check_lsn(mp, be64_to_cpu(agf->agf_lsn)))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002884 return __this_address;
Brian Fostera45086e2015-10-12 15:59:25 +11002885 }
Dave Chinner5d5f5272012-11-14 17:44:56 +11002886
Brian Foster39708c22019-02-07 10:45:48 -08002887 if (!xfs_verify_magic(bp, agf->agf_magicnum))
2888 return __this_address;
2889
2890 if (!(XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
Dave Chinner4e0e6042013-04-03 16:11:13 +11002891 be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
Dave Chinnera78ee252018-03-06 17:08:32 -08002892 be32_to_cpu(agf->agf_flfirst) < xfs_agfl_size(mp) &&
2893 be32_to_cpu(agf->agf_fllast) < xfs_agfl_size(mp) &&
2894 be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp)))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002895 return __this_address;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002896
Zheng Bind0c7fea2020-02-21 07:38:20 -08002897 if (be32_to_cpu(agf->agf_length) > mp->m_sb.sb_dblocks)
2898 return __this_address;
2899
2900 if (be32_to_cpu(agf->agf_freeblks) < be32_to_cpu(agf->agf_longest) ||
2901 be32_to_cpu(agf->agf_freeblks) > be32_to_cpu(agf->agf_length))
2902 return __this_address;
2903
Darrick J. Wongd2a047f2016-12-05 12:32:50 +11002904 if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
2905 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
Darrick J. Wong973975b2021-03-22 09:51:54 -07002906 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > mp->m_ag_maxlevels ||
2907 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > mp->m_ag_maxlevels)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002908 return __this_address;
Eric Sandeene1b05722014-09-09 11:47:24 +10002909
Dave Chinner38c26bf2021-08-18 18:46:37 -07002910 if (xfs_has_rmapbt(mp) &&
Darrick J. Wongd2a047f2016-12-05 12:32:50 +11002911 (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 ||
Darrick J. Wong973975b2021-03-22 09:51:54 -07002912 be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > mp->m_rmap_maxlevels))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002913 return __this_address;
Darrick J. Wongb8704942016-08-03 11:30:32 +10002914
Dave Chinnerebd90272021-08-18 18:46:55 -07002915 if (xfs_has_rmapbt(mp) &&
Zheng Bind0c7fea2020-02-21 07:38:20 -08002916 be32_to_cpu(agf->agf_rmap_blocks) > be32_to_cpu(agf->agf_length))
2917 return __this_address;
2918
Dave Chinner5d5f5272012-11-14 17:44:56 +11002919 /*
2920 * during growfs operations, the perag is not fully initialised,
2921 * so we can't use it for any useful checking. growfs ensures we can't
2922 * use it by using uncached buffers that don't have the perag attached
2923 * so we can detect and avoid this problem.
2924 */
Dave Chinner4e0e6042013-04-03 16:11:13 +11002925 if (bp->b_pag && be32_to_cpu(agf->agf_seqno) != bp->b_pag->pag_agno)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002926 return __this_address;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002927
Dave Chinnerebd90272021-08-18 18:46:55 -07002928 if (xfs_has_lazysbcount(mp) &&
Dave Chinner4e0e6042013-04-03 16:11:13 +11002929 be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002930 return __this_address;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002931
Dave Chinnerebd90272021-08-18 18:46:55 -07002932 if (xfs_has_reflink(mp) &&
Zheng Bind0c7fea2020-02-21 07:38:20 -08002933 be32_to_cpu(agf->agf_refcount_blocks) >
2934 be32_to_cpu(agf->agf_length))
2935 return __this_address;
2936
Dave Chinnerebd90272021-08-18 18:46:55 -07002937 if (xfs_has_reflink(mp) &&
Darrick J. Wongd2a047f2016-12-05 12:32:50 +11002938 (be32_to_cpu(agf->agf_refcount_level) < 1 ||
Darrick J. Wong973975b2021-03-22 09:51:54 -07002939 be32_to_cpu(agf->agf_refcount_level) > mp->m_refc_maxlevels))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002940 return __this_address;
Darrick J. Wong46eeb522016-10-03 09:11:16 -07002941
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002942 return NULL;
Dave Chinner4e0e6042013-04-03 16:11:13 +11002943
Dave Chinner612cfbf2012-11-14 17:52:32 +11002944}
Dave Chinner5d5f5272012-11-14 17:44:56 +11002945
Dave Chinner1813dd62012-11-14 17:54:40 +11002946static void
2947xfs_agf_read_verify(
Dave Chinner612cfbf2012-11-14 17:52:32 +11002948 struct xfs_buf *bp)
2949{
Christoph Hellwigdbd329f12019-06-28 19:27:29 -07002950 struct xfs_mount *mp = bp->b_mount;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002951 xfs_failaddr_t fa;
Dave Chinner4e0e6042013-04-03 16:11:13 +11002952
Dave Chinner38c26bf2021-08-18 18:46:37 -07002953 if (xfs_has_crc(mp) &&
Eric Sandeence5028c2014-02-27 15:23:10 +11002954 !xfs_buf_verify_cksum(bp, XFS_AGF_CRC_OFF))
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002955 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
2956 else {
Darrick J. Wongb5572592018-01-08 10:51:08 -08002957 fa = xfs_agf_verify(bp);
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002958 if (XFS_TEST_ERROR(fa, mp, XFS_ERRTAG_ALLOC_READ_AGF))
2959 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
2960 }
Dave Chinner612cfbf2012-11-14 17:52:32 +11002961}
2962
Dave Chinnerb0f539de2012-11-14 17:53:49 +11002963static void
Dave Chinner1813dd62012-11-14 17:54:40 +11002964xfs_agf_write_verify(
Dave Chinner612cfbf2012-11-14 17:52:32 +11002965 struct xfs_buf *bp)
2966{
Christoph Hellwigdbd329f12019-06-28 19:27:29 -07002967 struct xfs_mount *mp = bp->b_mount;
Carlos Maiolinofb1755a2018-01-24 13:38:48 -08002968 struct xfs_buf_log_item *bip = bp->b_log_item;
Christoph Hellwig9798f612020-03-10 08:57:29 -07002969 struct xfs_agf *agf = bp->b_addr;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002970 xfs_failaddr_t fa;
Dave Chinner4e0e6042013-04-03 16:11:13 +11002971
Darrick J. Wongb5572592018-01-08 10:51:08 -08002972 fa = xfs_agf_verify(bp);
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002973 if (fa) {
2974 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
Dave Chinner4e0e6042013-04-03 16:11:13 +11002975 return;
2976 }
2977
Dave Chinner38c26bf2021-08-18 18:46:37 -07002978 if (!xfs_has_crc(mp))
Dave Chinner4e0e6042013-04-03 16:11:13 +11002979 return;
2980
2981 if (bip)
Christoph Hellwig9798f612020-03-10 08:57:29 -07002982 agf->agf_lsn = cpu_to_be64(bip->bli_item.li_lsn);
Dave Chinner4e0e6042013-04-03 16:11:13 +11002983
Eric Sandeenf1dbcd72014-02-27 15:18:23 +11002984 xfs_buf_update_cksum(bp, XFS_AGF_CRC_OFF);
Dave Chinner5d5f5272012-11-14 17:44:56 +11002985}
2986
Dave Chinner1813dd62012-11-14 17:54:40 +11002987const struct xfs_buf_ops xfs_agf_buf_ops = {
Eric Sandeen233135b2016-01-04 16:10:19 +11002988 .name = "xfs_agf",
Brian Foster39708c22019-02-07 10:45:48 -08002989 .magic = { cpu_to_be32(XFS_AGF_MAGIC), cpu_to_be32(XFS_AGF_MAGIC) },
Dave Chinner1813dd62012-11-14 17:54:40 +11002990 .verify_read = xfs_agf_read_verify,
2991 .verify_write = xfs_agf_write_verify,
Darrick J. Wongb5572592018-01-08 10:51:08 -08002992 .verify_struct = xfs_agf_verify,
Dave Chinner1813dd62012-11-14 17:54:40 +11002993};
2994
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995/*
2996 * Read in the allocation group header (free/alloc section).
2997 */
2998int /* error */
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002999xfs_read_agf(
3000 struct xfs_mount *mp, /* mount point structure */
3001 struct xfs_trans *tp, /* transaction pointer */
3002 xfs_agnumber_t agno, /* allocation group number */
3003 int flags, /* XFS_BUF_ */
3004 struct xfs_buf **bpp) /* buffer for the ag freelist header */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006 int error;
3007
Dave Chinnerd1230312013-11-01 15:27:19 +11003008 trace_xfs_read_agf(mp, agno);
3009
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010 ASSERT(agno != NULLAGNUMBER);
Darrick J. Wong4ed8e272020-01-23 17:01:16 -08003011 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
Dave Chinner1813dd62012-11-14 17:54:40 +11003013 XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003014 if (error)
3015 return error;
From: Christoph Hellwig48056212008-11-28 14:23:38 +11003016
Chandra Seetharaman5a52c2a582011-07-22 23:39:51 +00003017 ASSERT(!(*bpp)->b_error);
Christoph Hellwig38f23232011-10-10 16:52:45 +00003018 xfs_buf_set_ref(*bpp, XFS_AGF_REF);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11003019 return 0;
3020}
3021
3022/*
3023 * Read in the allocation group header (free/alloc section).
3024 */
3025int /* error */
3026xfs_alloc_read_agf(
3027 struct xfs_mount *mp, /* mount point structure */
3028 struct xfs_trans *tp, /* transaction pointer */
3029 xfs_agnumber_t agno, /* allocation group number */
3030 int flags, /* XFS_ALLOC_FLAG_... */
3031 struct xfs_buf **bpp) /* buffer for the ag freelist header */
3032{
3033 struct xfs_agf *agf; /* ag freelist header */
3034 struct xfs_perag *pag; /* per allocation group data */
3035 int error;
Brian Foster16eaab82021-04-28 15:05:50 -07003036 int allocbt_blks;
From: Christoph Hellwig48056212008-11-28 14:23:38 +11003037
Dave Chinnerd1230312013-11-01 15:27:19 +11003038 trace_xfs_alloc_read_agf(mp, agno);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11003039
Darrick J. Wongf48e2df2020-01-23 17:01:19 -08003040 /* We don't support trylock when freeing. */
3041 ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) !=
3042 (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK));
Dave Chinnerd1230312013-11-01 15:27:19 +11003043 ASSERT(agno != NULLAGNUMBER);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11003044 error = xfs_read_agf(mp, tp, agno,
Christoph Hellwig0cadda12010-01-19 09:56:44 +00003045 (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0,
From: Christoph Hellwig48056212008-11-28 14:23:38 +11003046 bpp);
3047 if (error)
3048 return error;
Chandra Seetharaman5a52c2a582011-07-22 23:39:51 +00003049 ASSERT(!(*bpp)->b_error);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11003050
Christoph Hellwig9798f612020-03-10 08:57:29 -07003051 agf = (*bpp)->b_addr;
Gao Xiang92a00542020-07-13 09:13:00 -07003052 pag = (*bpp)->b_pag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003053 if (!pag->pagf_init) {
Christoph Hellwig16259e72005-11-02 15:11:25 +11003054 pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
David Chinner92821e22007-05-24 15:26:31 +10003055 pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
Christoph Hellwig16259e72005-11-02 15:11:25 +11003056 pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
3057 pag->pagf_longest = be32_to_cpu(agf->agf_longest);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058 pag->pagf_levels[XFS_BTNUM_BNOi] =
Christoph Hellwig16259e72005-11-02 15:11:25 +11003059 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003060 pag->pagf_levels[XFS_BTNUM_CNTi] =
Christoph Hellwig16259e72005-11-02 15:11:25 +11003061 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
Darrick J. Wongb8704942016-08-03 11:30:32 +10003062 pag->pagf_levels[XFS_BTNUM_RMAPi] =
3063 be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]);
Darrick J. Wong46eeb522016-10-03 09:11:16 -07003064 pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065 pag->pagf_init = 1;
Brian Fostera27ba262018-03-15 10:51:58 -07003066 pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf);
Brian Foster16eaab82021-04-28 15:05:50 -07003067
3068 /*
3069 * Update the in-core allocbt counter. Filter out the rmapbt
3070 * subset of the btreeblks counter because the rmapbt is managed
3071 * by perag reservation. Subtract one for the rmapbt root block
3072 * because the rmap counter includes it while the btreeblks
3073 * counter only tracks non-root blocks.
3074 */
3075 allocbt_blks = pag->pagf_btreeblks;
Dave Chinnerebd90272021-08-18 18:46:55 -07003076 if (xfs_has_rmapbt(mp))
Brian Foster16eaab82021-04-28 15:05:50 -07003077 allocbt_blks -= be32_to_cpu(agf->agf_rmap_blocks) - 1;
3078 if (allocbt_blks > 0)
3079 atomic64_add(allocbt_blks, &mp->m_allocbt_blks);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003080 }
3081#ifdef DEBUG
Dave Chinner75c8c50f2021-08-18 18:46:53 -07003082 else if (!xfs_is_shutdown(mp)) {
Christoph Hellwig16259e72005-11-02 15:11:25 +11003083 ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks));
Barry Naujok89b28392008-10-30 17:05:49 +11003084 ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks));
Christoph Hellwig16259e72005-11-02 15:11:25 +11003085 ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
3086 ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003087 ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] ==
Christoph Hellwig16259e72005-11-02 15:11:25 +11003088 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003089 ASSERT(pag->pagf_levels[XFS_BTNUM_CNTi] ==
Christoph Hellwig16259e72005-11-02 15:11:25 +11003090 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091 }
3092#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003093 return 0;
3094}
3095
3096/*
3097 * Allocate an extent (variable-size).
3098 * Depending on the allocation type, we either look in a single allocation
3099 * group or loop over the allocation groups to find the result.
3100 */
3101int /* error */
Dave Chinnere04426b2012-10-05 11:06:59 +10003102xfs_alloc_vextent(
Brian Foster64396ff2018-07-11 22:26:30 -07003103 struct xfs_alloc_arg *args) /* allocation argument structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104{
Brian Foster64396ff2018-07-11 22:26:30 -07003105 xfs_agblock_t agsize; /* allocation group size */
3106 int error;
3107 int flags; /* XFS_ALLOC_FLAG_... locking flags */
3108 struct xfs_mount *mp; /* mount structure pointer */
3109 xfs_agnumber_t sagno; /* starting allocation group number */
3110 xfs_alloctype_t type; /* input allocation type */
3111 int bump_rotor = 0;
3112 xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003113
3114 mp = args->mp;
3115 type = args->otype = args->type;
3116 args->agbno = NULLAGBLOCK;
3117 /*
3118 * Just fix this up, for the case where the last a.g. is shorter
3119 * (or there's only one a.g.) and the caller couldn't easily figure
3120 * that out (xfs_bmap_alloc).
3121 */
3122 agsize = mp->m_sb.sb_agblocks;
3123 if (args->maxlen > agsize)
3124 args->maxlen = agsize;
3125 if (args->alignment == 0)
3126 args->alignment = 1;
3127 ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_sb.sb_agcount);
3128 ASSERT(XFS_FSB_TO_AGBNO(mp, args->fsbno) < agsize);
3129 ASSERT(args->minlen <= args->maxlen);
3130 ASSERT(args->minlen <= agsize);
3131 ASSERT(args->mod < args->prod);
3132 if (XFS_FSB_TO_AGNO(mp, args->fsbno) >= mp->m_sb.sb_agcount ||
3133 XFS_FSB_TO_AGBNO(mp, args->fsbno) >= agsize ||
3134 args->minlen > args->maxlen || args->minlen > agsize ||
3135 args->mod >= args->prod) {
3136 args->fsbno = NULLFSBLOCK;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00003137 trace_xfs_alloc_vextent_badargs(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138 return 0;
3139 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140
3141 switch (type) {
3142 case XFS_ALLOCTYPE_THIS_AG:
3143 case XFS_ALLOCTYPE_NEAR_BNO:
3144 case XFS_ALLOCTYPE_THIS_BNO:
3145 /*
3146 * These three force us into a single a.g.
3147 */
3148 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
Dave Chinnera862e0f2010-01-11 11:47:41 +00003149 args->pag = xfs_perag_get(mp, args->agno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150 error = xfs_alloc_fix_freelist(args, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151 if (error) {
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00003152 trace_xfs_alloc_vextent_nofix(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153 goto error0;
3154 }
3155 if (!args->agbp) {
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00003156 trace_xfs_alloc_vextent_noagbp(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 break;
3158 }
3159 args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno);
3160 if ((error = xfs_alloc_ag_vextent(args)))
3161 goto error0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003162 break;
3163 case XFS_ALLOCTYPE_START_BNO:
3164 /*
3165 * Try near allocation first, then anywhere-in-ag after
3166 * the first a.g. fails.
3167 */
Dave Chinner292378e2016-09-26 08:21:28 +10003168 if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) &&
Dave Chinner2e973b22021-08-18 18:46:52 -07003169 xfs_is_inode32(mp)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170 args->fsbno = XFS_AGB_TO_FSB(mp,
3171 ((mp->m_agfrotor / rotorstep) %
3172 mp->m_sb.sb_agcount), 0);
3173 bump_rotor = 1;
3174 }
3175 args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno);
3176 args->type = XFS_ALLOCTYPE_NEAR_BNO;
Gustavo A. R. Silva53004ee2021-04-20 17:54:36 -05003177 fallthrough;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178 case XFS_ALLOCTYPE_FIRST_AG:
3179 /*
3180 * Rotate through the allocation groups looking for a winner.
3181 */
Christoph Hellwig8d242e92017-02-17 08:21:15 -08003182 if (type == XFS_ALLOCTYPE_FIRST_AG) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183 /*
3184 * Start with allocation group given by bno.
3185 */
3186 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
3187 args->type = XFS_ALLOCTYPE_THIS_AG;
3188 sagno = 0;
3189 flags = 0;
3190 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191 /*
3192 * Start with the given allocation group.
3193 */
3194 args->agno = sagno = XFS_FSB_TO_AGNO(mp, args->fsbno);
3195 flags = XFS_ALLOC_FLAG_TRYLOCK;
3196 }
3197 /*
3198 * Loop over allocation groups twice; first time with
3199 * trylock set, second time without.
3200 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003201 for (;;) {
Dave Chinnera862e0f2010-01-11 11:47:41 +00003202 args->pag = xfs_perag_get(mp, args->agno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203 error = xfs_alloc_fix_freelist(args, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003204 if (error) {
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00003205 trace_xfs_alloc_vextent_nofix(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003206 goto error0;
3207 }
3208 /*
3209 * If we get a buffer back then the allocation will fly.
3210 */
3211 if (args->agbp) {
3212 if ((error = xfs_alloc_ag_vextent(args)))
3213 goto error0;
3214 break;
3215 }
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00003216
3217 trace_xfs_alloc_vextent_loopfailed(args);
3218
Linus Torvalds1da177e2005-04-16 15:20:36 -07003219 /*
3220 * Didn't work, figure out the next iteration.
3221 */
3222 if (args->agno == sagno &&
3223 type == XFS_ALLOCTYPE_START_BNO)
3224 args->type = XFS_ALLOCTYPE_THIS_AG;
Yingping Lud210a282006-06-09 14:55:18 +10003225 /*
3226 * For the first allocation, we can try any AG to get
3227 * space. However, if we already have allocated a
3228 * block, we don't want to try AGs whose number is below
3229 * sagno. Otherwise, we may end up with out-of-order
3230 * locking of AGF, which might cause deadlock.
3231 */
3232 if (++(args->agno) == mp->m_sb.sb_agcount) {
Brian Foster64396ff2018-07-11 22:26:30 -07003233 if (args->tp->t_firstblock != NULLFSBLOCK)
Yingping Lud210a282006-06-09 14:55:18 +10003234 args->agno = sagno;
3235 else
3236 args->agno = 0;
3237 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238 /*
3239 * Reached the starting a.g., must either be done
3240 * or switch to non-trylock mode.
3241 */
3242 if (args->agno == sagno) {
Christoph Hellwig255c5162017-01-09 13:36:19 -08003243 if (flags == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003244 args->agbno = NULLAGBLOCK;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00003245 trace_xfs_alloc_vextent_allfailed(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003246 break;
3247 }
Christoph Hellwig255c5162017-01-09 13:36:19 -08003248
3249 flags = 0;
3250 if (type == XFS_ALLOCTYPE_START_BNO) {
3251 args->agbno = XFS_FSB_TO_AGBNO(mp,
3252 args->fsbno);
3253 args->type = XFS_ALLOCTYPE_NEAR_BNO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003254 }
3255 }
Dave Chinnera862e0f2010-01-11 11:47:41 +00003256 xfs_perag_put(args->pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003257 }
Christoph Hellwig8d242e92017-02-17 08:21:15 -08003258 if (bump_rotor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003259 if (args->agno == sagno)
3260 mp->m_agfrotor = (mp->m_agfrotor + 1) %
3261 (mp->m_sb.sb_agcount * rotorstep);
3262 else
3263 mp->m_agfrotor = (args->agno * rotorstep + 1) %
3264 (mp->m_sb.sb_agcount * rotorstep);
3265 }
3266 break;
3267 default:
3268 ASSERT(0);
3269 /* NOTREACHED */
3270 }
3271 if (args->agbno == NULLAGBLOCK)
3272 args->fsbno = NULLFSBLOCK;
3273 else {
3274 args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno);
3275#ifdef DEBUG
3276 ASSERT(args->len >= args->minlen);
3277 ASSERT(args->len <= args->maxlen);
3278 ASSERT(args->agbno % args->alignment == 0);
3279 XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno),
3280 args->len);
3281#endif
Dave Chinner3fbbbea2015-11-03 12:27:22 +11003282
Linus Torvalds1da177e2005-04-16 15:20:36 -07003283 }
Dave Chinnera862e0f2010-01-11 11:47:41 +00003284 xfs_perag_put(args->pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003285 return 0;
3286error0:
Dave Chinnera862e0f2010-01-11 11:47:41 +00003287 xfs_perag_put(args->pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003288 return error;
3289}
3290
Dave Chinner4d89e202016-06-21 11:53:28 +10003291/* Ensure that the freelist is at full capacity. */
3292int
3293xfs_free_extent_fix_freelist(
3294 struct xfs_trans *tp,
Dave Chinner45d06622021-06-02 10:48:24 +10003295 struct xfs_perag *pag,
Dave Chinner4d89e202016-06-21 11:53:28 +10003296 struct xfs_buf **agbp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003297{
Dave Chinner4d89e202016-06-21 11:53:28 +10003298 struct xfs_alloc_arg args;
3299 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003300
Dave Chinner4d89e202016-06-21 11:53:28 +10003301 memset(&args, 0, sizeof(struct xfs_alloc_arg));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302 args.tp = tp;
3303 args.mp = tp->t_mountp;
Dave Chinner45d06622021-06-02 10:48:24 +10003304 args.agno = pag->pag_agno;
3305 args.pag = pag;
Dave Chinnerbe65b182011-04-08 12:45:07 +10003306
3307 /*
3308 * validate that the block number is legal - the enables us to detect
3309 * and handle a silent filesystem corruption rather than crashing.
3310 */
Dave Chinnerbe65b182011-04-08 12:45:07 +10003311 if (args.agno >= args.mp->m_sb.sb_agcount)
Dave Chinner24513372014-06-25 14:58:08 +10003312 return -EFSCORRUPTED;
Dave Chinnerbe65b182011-04-08 12:45:07 +10003313
Dave Chinnerbe65b182011-04-08 12:45:07 +10003314 error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING);
3315 if (error)
Dave Chinner45d06622021-06-02 10:48:24 +10003316 return error;
Dave Chinner4d89e202016-06-21 11:53:28 +10003317
3318 *agbp = args.agbp;
Dave Chinner45d06622021-06-02 10:48:24 +10003319 return 0;
Dave Chinner4d89e202016-06-21 11:53:28 +10003320}
3321
3322/*
3323 * Free an extent.
3324 * Just break up the extent address and hand off to xfs_free_ag_extent
3325 * after fixing up the freelist.
3326 */
Darrick J. Wong66e32372018-12-12 08:46:23 -08003327int
Brian Fosterfcb762f2018-05-09 08:45:04 -07003328__xfs_free_extent(
Darrick J. Wong66e32372018-12-12 08:46:23 -08003329 struct xfs_trans *tp,
3330 xfs_fsblock_t bno,
3331 xfs_extlen_t len,
3332 const struct xfs_owner_info *oinfo,
3333 enum xfs_ag_resv_type type,
3334 bool skip_discard)
Dave Chinner4d89e202016-06-21 11:53:28 +10003335{
Darrick J. Wong66e32372018-12-12 08:46:23 -08003336 struct xfs_mount *mp = tp->t_mountp;
3337 struct xfs_buf *agbp;
3338 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno);
3339 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno);
Christoph Hellwig9798f612020-03-10 08:57:29 -07003340 struct xfs_agf *agf;
Darrick J. Wong66e32372018-12-12 08:46:23 -08003341 int error;
3342 unsigned int busy_flags = 0;
Dave Chinner45d06622021-06-02 10:48:24 +10003343 struct xfs_perag *pag;
Dave Chinner4d89e202016-06-21 11:53:28 +10003344
3345 ASSERT(len != 0);
Brian Foster0ab320862018-03-09 14:02:32 -08003346 ASSERT(type != XFS_AG_RESV_AGFL);
Dave Chinner4d89e202016-06-21 11:53:28 +10003347
Darrick J. Wongba9e7802016-08-03 11:26:33 +10003348 if (XFS_TEST_ERROR(false, mp,
Darrick J. Wong9e24cfd2017-06-20 17:54:47 -07003349 XFS_ERRTAG_FREE_EXTENT))
Darrick J. Wongba9e7802016-08-03 11:26:33 +10003350 return -EIO;
3351
Dave Chinner45d06622021-06-02 10:48:24 +10003352 pag = xfs_perag_get(mp, agno);
3353 error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
Dave Chinner4d89e202016-06-21 11:53:28 +10003354 if (error)
Dave Chinner45d06622021-06-02 10:48:24 +10003355 goto err;
Christoph Hellwig9798f612020-03-10 08:57:29 -07003356 agf = agbp->b_addr;
Dave Chinner4d89e202016-06-21 11:53:28 +10003357
Darrick J. Wongf9e03702019-11-11 12:52:18 -08003358 if (XFS_IS_CORRUPT(mp, agbno >= mp->m_sb.sb_agblocks)) {
3359 error = -EFSCORRUPTED;
Dave Chinner45d06622021-06-02 10:48:24 +10003360 goto err_release;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08003361 }
Dave Chinnerbe65b182011-04-08 12:45:07 +10003362
3363 /* validate the extent size is legal now we have the agf locked */
Christoph Hellwig9798f612020-03-10 08:57:29 -07003364 if (XFS_IS_CORRUPT(mp, agbno + len > be32_to_cpu(agf->agf_length))) {
Darrick J. Wongf9e03702019-11-11 12:52:18 -08003365 error = -EFSCORRUPTED;
Dave Chinner45d06622021-06-02 10:48:24 +10003366 goto err_release;
Darrick J. Wongf9e03702019-11-11 12:52:18 -08003367 }
Dave Chinnerbe65b182011-04-08 12:45:07 +10003368
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10003369 error = xfs_free_ag_extent(tp, agbp, agno, agbno, len, oinfo, type);
Dave Chinner4d89e202016-06-21 11:53:28 +10003370 if (error)
Dave Chinner45d06622021-06-02 10:48:24 +10003371 goto err_release;
Dave Chinner4d89e202016-06-21 11:53:28 +10003372
Brian Fosterfcb762f2018-05-09 08:45:04 -07003373 if (skip_discard)
3374 busy_flags |= XFS_EXTENT_BUSY_SKIP_DISCARD;
Dave Chinner45d06622021-06-02 10:48:24 +10003375 xfs_extent_busy_insert(tp, pag, agbno, len, busy_flags);
3376 xfs_perag_put(pag);
Dave Chinner4d89e202016-06-21 11:53:28 +10003377 return 0;
3378
Dave Chinner45d06622021-06-02 10:48:24 +10003379err_release:
Dave Chinner4d89e202016-06-21 11:53:28 +10003380 xfs_trans_brelse(tp, agbp);
Dave Chinner45d06622021-06-02 10:48:24 +10003381err:
3382 xfs_perag_put(pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383 return error;
3384}
Darrick J. Wong2d520bf2017-03-28 14:56:35 -07003385
3386struct xfs_alloc_query_range_info {
3387 xfs_alloc_query_range_fn fn;
3388 void *priv;
3389};
3390
3391/* Format btree record and pass to our callback. */
3392STATIC int
3393xfs_alloc_query_range_helper(
3394 struct xfs_btree_cur *cur,
Darrick J. Wong159eb692021-08-10 17:02:16 -07003395 const union xfs_btree_rec *rec,
Darrick J. Wong2d520bf2017-03-28 14:56:35 -07003396 void *priv)
3397{
3398 struct xfs_alloc_query_range_info *query = priv;
3399 struct xfs_alloc_rec_incore irec;
3400
3401 irec.ar_startblock = be32_to_cpu(rec->alloc.ar_startblock);
3402 irec.ar_blockcount = be32_to_cpu(rec->alloc.ar_blockcount);
3403 return query->fn(cur, &irec, query->priv);
3404}
3405
3406/* Find all free space within a given range of blocks. */
3407int
3408xfs_alloc_query_range(
3409 struct xfs_btree_cur *cur,
Darrick J. Wong04dcb472021-08-10 17:02:15 -07003410 const struct xfs_alloc_rec_incore *low_rec,
3411 const struct xfs_alloc_rec_incore *high_rec,
Darrick J. Wong2d520bf2017-03-28 14:56:35 -07003412 xfs_alloc_query_range_fn fn,
3413 void *priv)
3414{
3415 union xfs_btree_irec low_brec;
3416 union xfs_btree_irec high_brec;
3417 struct xfs_alloc_query_range_info query;
3418
3419 ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
3420 low_brec.a = *low_rec;
3421 high_brec.a = *high_rec;
3422 query.priv = priv;
3423 query.fn = fn;
3424 return xfs_btree_query_range(cur, &low_brec, &high_brec,
3425 xfs_alloc_query_range_helper, &query);
3426}
Darrick J. Wonge9a25992017-03-28 14:56:35 -07003427
3428/* Find all free space records. */
3429int
3430xfs_alloc_query_all(
3431 struct xfs_btree_cur *cur,
3432 xfs_alloc_query_range_fn fn,
3433 void *priv)
3434{
3435 struct xfs_alloc_query_range_info query;
3436
3437 ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
3438 query.priv = priv;
3439 query.fn = fn;
3440 return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query);
3441}
Darrick J. Wong21ec5412017-10-17 21:37:32 -07003442
Darrick J. Wongce1d8022018-01-16 18:52:12 -08003443/* Is there a record covering a given extent? */
3444int
3445xfs_alloc_has_record(
3446 struct xfs_btree_cur *cur,
3447 xfs_agblock_t bno,
3448 xfs_extlen_t len,
3449 bool *exists)
3450{
3451 union xfs_btree_irec low;
3452 union xfs_btree_irec high;
3453
3454 memset(&low, 0, sizeof(low));
3455 low.a.ar_startblock = bno;
3456 memset(&high, 0xFF, sizeof(high));
3457 high.a.ar_startblock = bno + len - 1;
3458
3459 return xfs_btree_has_record(cur, &low, &high, exists);
3460}
Darrick J. Wong9f3a0802018-05-14 06:34:34 -07003461
3462/*
3463 * Walk all the blocks in the AGFL. The @walk_fn can return any negative
Darrick J. Wong5bb46e32019-07-02 09:39:38 -07003464 * error code or XFS_ITER_*.
Darrick J. Wong9f3a0802018-05-14 06:34:34 -07003465 */
3466int
3467xfs_agfl_walk(
3468 struct xfs_mount *mp,
3469 struct xfs_agf *agf,
3470 struct xfs_buf *agflbp,
3471 xfs_agfl_walk_fn walk_fn,
3472 void *priv)
3473{
3474 __be32 *agfl_bno;
3475 unsigned int i;
3476 int error;
3477
Christoph Hellwig183606d2020-03-10 08:57:28 -07003478 agfl_bno = xfs_buf_to_agfl_bno(agflbp);
Darrick J. Wong9f3a0802018-05-14 06:34:34 -07003479 i = be32_to_cpu(agf->agf_flfirst);
3480
3481 /* Nothing to walk in an empty AGFL. */
3482 if (agf->agf_flcount == cpu_to_be32(0))
3483 return 0;
3484
3485 /* Otherwise, walk from first to last, wrapping as needed. */
3486 for (;;) {
3487 error = walk_fn(mp, be32_to_cpu(agfl_bno[i]), priv);
3488 if (error)
3489 return error;
3490 if (i == be32_to_cpu(agf->agf_fllast))
3491 break;
3492 if (++i == xfs_agfl_size(mp))
3493 i = 0;
3494 }
3495
3496 return 0;
3497}