blob: 50ba989481cc9904ff74eef2646ef4a0d8448ca5 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Nathan Scott7b718762005-11-02 14:58:39 +11002 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Nathan Scott7b718762005-11-02 14:58:39 +11005 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 * published by the Free Software Foundation.
8 *
Nathan Scott7b718762005-11-02 14:58:39 +11009 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 *
Nathan Scott7b718762005-11-02 14:58:39 +110014 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include "xfs.h"
Nathan Scotta844f452005-11-02 14:38:42 +110019#include "xfs_fs.h"
Dave Chinner70a98832013-10-23 10:36:05 +110020#include "xfs_format.h"
Dave Chinner239880e2013-10-23 10:50:10 +110021#include "xfs_log_format.h"
Dave Chinner70a98832013-10-23 10:36:05 +110022#include "xfs_shared.h"
Dave Chinner239880e2013-10-23 10:50:10 +110023#include "xfs_trans_resv.h"
Nathan Scotta844f452005-11-02 14:38:42 +110024#include "xfs_bit.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include "xfs_sb.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include "xfs_mount.h"
Darrick J. Wong3ab78df2016-08-03 11:15:38 +100027#include "xfs_defer.h"
Nathan Scotta844f452005-11-02 14:38:42 +110028#include "xfs_inode.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include "xfs_btree.h"
Darrick J. Wong673930c2016-08-03 11:33:43 +100030#include "xfs_rmap.h"
Dave Chinnera4fbe6a2013-10-23 10:51:50 +110031#include "xfs_alloc_btree.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include "xfs_alloc.h"
Dave Chinnerefc27b52012-04-29 10:39:43 +000033#include "xfs_extent_busy.h"
Darrick J. Wonge9e899a2017-10-31 12:04:49 -070034#include "xfs_errortag.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include "xfs_error.h"
Dave Chinner4e0e6042013-04-03 16:11:13 +110036#include "xfs_cksum.h"
Christoph Hellwig0b1b2132009-12-14 23:14:59 +000037#include "xfs_trace.h"
Dave Chinner239880e2013-10-23 10:50:10 +110038#include "xfs_trans.h"
Dave Chinner4e0e6042013-04-03 16:11:13 +110039#include "xfs_buf_item.h"
Dave Chinner239880e2013-10-23 10:50:10 +110040#include "xfs_log.h"
Darrick J. Wong3fd129b2016-09-19 10:30:52 +100041#include "xfs_ag_resv.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Dave Chinnerc999a222012-03-22 05:15:07 +000043struct workqueue_struct *xfs_alloc_wq;
Linus Torvalds1da177e2005-04-16 15:20:36 -070044
45#define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b)))
46
47#define XFSA_FIXUP_BNO_OK 1
48#define XFSA_FIXUP_CNT_OK 2
49
Linus Torvalds1da177e2005-04-16 15:20:36 -070050STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *);
51STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *);
52STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *);
53STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *,
Christoph Hellwige26f0502011-04-24 19:06:15 +000054 xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Darrick J. Wongaf30dfa2016-10-03 09:11:17 -070056unsigned int
57xfs_refc_block(
58 struct xfs_mount *mp)
59{
60 if (xfs_sb_version_hasrmapbt(&mp->m_sb))
61 return XFS_RMAP_BLOCK(mp) + 1;
62 if (xfs_sb_version_hasfinobt(&mp->m_sb))
63 return XFS_FIBT_BLOCK(mp) + 1;
64 return XFS_IBT_BLOCK(mp) + 1;
65}
66
Darrick J. Wong80180262016-08-03 11:31:47 +100067xfs_extlen_t
68xfs_prealloc_blocks(
69 struct xfs_mount *mp)
70{
Darrick J. Wongaf30dfa2016-10-03 09:11:17 -070071 if (xfs_sb_version_hasreflink(&mp->m_sb))
72 return xfs_refc_block(mp) + 1;
Darrick J. Wong80180262016-08-03 11:31:47 +100073 if (xfs_sb_version_hasrmapbt(&mp->m_sb))
74 return XFS_RMAP_BLOCK(mp) + 1;
75 if (xfs_sb_version_hasfinobt(&mp->m_sb))
76 return XFS_FIBT_BLOCK(mp) + 1;
77 return XFS_IBT_BLOCK(mp) + 1;
78}
79
Linus Torvalds1da177e2005-04-16 15:20:36 -070080/*
Darrick J. Wong52548852016-08-03 11:38:24 +100081 * In order to avoid ENOSPC-related deadlock caused by out-of-order locking of
82 * AGF buffer (PV 947395), we place constraints on the relationship among
83 * actual allocations for data blocks, freelist blocks, and potential file data
84 * bmap btree blocks. However, these restrictions may result in no actual space
85 * allocated for a delayed extent, for example, a data block in a certain AG is
86 * allocated but there is no additional block for the additional bmap btree
87 * block due to a split of the bmap btree of the file. The result of this may
88 * lead to an infinite loop when the file gets flushed to disk and all delayed
89 * extents need to be actually allocated. To get around this, we explicitly set
90 * aside a few blocks which will not be reserved in delayed allocation.
91 *
Darrick J. Wong3fd129b2016-09-19 10:30:52 +100092 * We need to reserve 4 fsbs _per AG_ for the freelist and 4 more to handle a
93 * potential split of the file's bmap btree.
Darrick J. Wong52548852016-08-03 11:38:24 +100094 */
95unsigned int
96xfs_alloc_set_aside(
97 struct xfs_mount *mp)
98{
Christoph Hellwig5149fd32017-01-09 13:36:30 -080099 return mp->m_sb.sb_agcount * (XFS_ALLOC_AGFL_RESERVE + 4);
Darrick J. Wong52548852016-08-03 11:38:24 +1000100}
101
102/*
103 * When deciding how much space to allocate out of an AG, we limit the
104 * allocation maximum size to the size the AG. However, we cannot use all the
105 * blocks in the AG - some are permanently used by metadata. These
106 * blocks are generally:
107 * - the AG superblock, AGF, AGI and AGFL
108 * - the AGF (bno and cnt) and AGI btree root blocks, and optionally
109 * the AGI free inode and rmap btree root blocks.
110 * - blocks on the AGFL according to xfs_alloc_set_aside() limits
111 * - the rmapbt root block
112 *
113 * The AG headers are sector sized, so the amount of space they take up is
114 * dependent on filesystem geometry. The others are all single blocks.
115 */
116unsigned int
117xfs_alloc_ag_max_usable(
118 struct xfs_mount *mp)
119{
120 unsigned int blocks;
121
122 blocks = XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)); /* ag headers */
123 blocks += XFS_ALLOC_AGFL_RESERVE;
124 blocks += 3; /* AGF, AGI btree root blocks */
125 if (xfs_sb_version_hasfinobt(&mp->m_sb))
126 blocks++; /* finobt root block */
127 if (xfs_sb_version_hasrmapbt(&mp->m_sb))
128 blocks++; /* rmap root block */
Darrick J. Wongd0e853f2016-10-03 09:11:24 -0700129 if (xfs_sb_version_hasreflink(&mp->m_sb))
130 blocks++; /* refcount root block */
Darrick J. Wong52548852016-08-03 11:38:24 +1000131
132 return mp->m_sb.sb_agblocks - blocks;
133}
134
135/*
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100136 * Lookup the record equal to [bno, len] in the btree given by cur.
137 */
138STATIC int /* error */
139xfs_alloc_lookup_eq(
140 struct xfs_btree_cur *cur, /* btree cursor */
141 xfs_agblock_t bno, /* starting block of extent */
142 xfs_extlen_t len, /* length of extent */
143 int *stat) /* success/failure */
144{
145 cur->bc_rec.a.ar_startblock = bno;
146 cur->bc_rec.a.ar_blockcount = len;
147 return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
148}
149
150/*
151 * Lookup the first record greater than or equal to [bno, len]
152 * in the btree given by cur.
153 */
Dave Chinnera66d6362012-03-22 05:15:12 +0000154int /* error */
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100155xfs_alloc_lookup_ge(
156 struct xfs_btree_cur *cur, /* btree cursor */
157 xfs_agblock_t bno, /* starting block of extent */
158 xfs_extlen_t len, /* length of extent */
159 int *stat) /* success/failure */
160{
161 cur->bc_rec.a.ar_startblock = bno;
162 cur->bc_rec.a.ar_blockcount = len;
163 return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
164}
165
166/*
167 * Lookup the first record less than or equal to [bno, len]
168 * in the btree given by cur.
169 */
Eric Sandeen0d5a75e2016-06-01 17:38:15 +1000170static int /* error */
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100171xfs_alloc_lookup_le(
172 struct xfs_btree_cur *cur, /* btree cursor */
173 xfs_agblock_t bno, /* starting block of extent */
174 xfs_extlen_t len, /* length of extent */
175 int *stat) /* success/failure */
176{
177 cur->bc_rec.a.ar_startblock = bno;
178 cur->bc_rec.a.ar_blockcount = len;
179 return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
180}
181
Christoph Hellwig278d0ca2008-10-30 16:56:32 +1100182/*
183 * Update the record referred to by cur to the value given
184 * by [bno, len].
185 * This either works (return 0) or gets an EFSCORRUPTED error.
186 */
187STATIC int /* error */
188xfs_alloc_update(
189 struct xfs_btree_cur *cur, /* btree cursor */
190 xfs_agblock_t bno, /* starting block of extent */
191 xfs_extlen_t len) /* length of extent */
192{
193 union xfs_btree_rec rec;
194
195 rec.alloc.ar_startblock = cpu_to_be32(bno);
196 rec.alloc.ar_blockcount = cpu_to_be32(len);
197 return xfs_btree_update(cur, &rec);
198}
Christoph Hellwigfe033cc2008-10-30 16:56:09 +1100199
200/*
Christoph Hellwig8cc938f2008-10-30 16:58:11 +1100201 * Get the data from the pointed-to record.
202 */
Christoph Hellwiga46db602011-01-07 13:02:04 +0000203int /* error */
Christoph Hellwig8cc938f2008-10-30 16:58:11 +1100204xfs_alloc_get_rec(
205 struct xfs_btree_cur *cur, /* btree cursor */
206 xfs_agblock_t *bno, /* output: starting block of extent */
207 xfs_extlen_t *len, /* output: length of extent */
208 int *stat) /* output: success/failure */
209{
210 union xfs_btree_rec *rec;
211 int error;
212
213 error = xfs_btree_get_rec(cur, &rec, stat);
214 if (!error && *stat == 1) {
215 *bno = be32_to_cpu(rec->alloc.ar_startblock);
216 *len = be32_to_cpu(rec->alloc.ar_blockcount);
217 }
218 return error;
219}
220
221/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 * Compute aligned version of the found extent.
223 * Takes alignment and min length into account.
224 */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800225STATIC bool
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226xfs_alloc_compute_aligned(
Christoph Hellwig86fa8af2011-03-04 12:59:54 +0000227 xfs_alloc_arg_t *args, /* allocation argument structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 xfs_agblock_t foundbno, /* starting block in found extent */
229 xfs_extlen_t foundlen, /* length in found extent */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 xfs_agblock_t *resbno, /* result block number */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800231 xfs_extlen_t *reslen, /* result length */
232 unsigned *busy_gen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233{
Christoph Hellwigebf55872017-02-07 14:06:57 -0800234 xfs_agblock_t bno = foundbno;
235 xfs_extlen_t len = foundlen;
Brian Fosterbfe46d42015-05-29 08:53:00 +1000236 xfs_extlen_t diff;
Christoph Hellwigebf55872017-02-07 14:06:57 -0800237 bool busy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
Christoph Hellwige26f0502011-04-24 19:06:15 +0000239 /* Trim busy sections out of found extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800240 busy = xfs_extent_busy_trim(args, &bno, &len, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +0000241
Brian Fosterbfe46d42015-05-29 08:53:00 +1000242 /*
243 * If we have a largish extent that happens to start before min_agbno,
244 * see if we can shift it into range...
245 */
246 if (bno < args->min_agbno && bno + len > args->min_agbno) {
247 diff = args->min_agbno - bno;
248 if (len > diff) {
249 bno += diff;
250 len -= diff;
251 }
252 }
253
Christoph Hellwige26f0502011-04-24 19:06:15 +0000254 if (args->alignment > 1 && len >= args->minlen) {
255 xfs_agblock_t aligned_bno = roundup(bno, args->alignment);
Brian Fosterbfe46d42015-05-29 08:53:00 +1000256
257 diff = aligned_bno - bno;
Christoph Hellwige26f0502011-04-24 19:06:15 +0000258
259 *resbno = aligned_bno;
260 *reslen = diff >= len ? 0 : len - diff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 } else {
Christoph Hellwige26f0502011-04-24 19:06:15 +0000262 *resbno = bno;
263 *reslen = len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 }
Christoph Hellwigebf55872017-02-07 14:06:57 -0800265
266 return busy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267}
268
269/*
270 * Compute best start block and diff for "near" allocations.
271 * freelen >= wantlen already checked by caller.
272 */
273STATIC xfs_extlen_t /* difference value (absolute) */
274xfs_alloc_compute_diff(
275 xfs_agblock_t wantbno, /* target starting block */
276 xfs_extlen_t wantlen, /* target length */
277 xfs_extlen_t alignment, /* target alignment */
Dave Chinner292378e2016-09-26 08:21:28 +1000278 int datatype, /* are we allocating data? */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 xfs_agblock_t freebno, /* freespace's starting block */
280 xfs_extlen_t freelen, /* freespace's length */
281 xfs_agblock_t *newbnop) /* result: best start block from free */
282{
283 xfs_agblock_t freeend; /* end of freespace extent */
284 xfs_agblock_t newbno1; /* return block number */
285 xfs_agblock_t newbno2; /* other new block number */
286 xfs_extlen_t newlen1=0; /* length with newbno1 */
287 xfs_extlen_t newlen2=0; /* length with newbno2 */
288 xfs_agblock_t wantend; /* end of target extent */
Dave Chinner292378e2016-09-26 08:21:28 +1000289 bool userdata = xfs_alloc_is_userdata(datatype);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290
291 ASSERT(freelen >= wantlen);
292 freeend = freebno + freelen;
293 wantend = wantbno + wantlen;
Jan Kara211d0222013-04-11 22:09:56 +0200294 /*
295 * We want to allocate from the start of a free extent if it is past
296 * the desired block or if we are allocating user data and the free
297 * extent is before desired block. The second case is there to allow
298 * for contiguous allocation from the remaining free space if the file
299 * grows in the short term.
300 */
301 if (freebno >= wantbno || (userdata && freeend < wantend)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 if ((newbno1 = roundup(freebno, alignment)) >= freeend)
303 newbno1 = NULLAGBLOCK;
304 } else if (freeend >= wantend && alignment > 1) {
305 newbno1 = roundup(wantbno, alignment);
306 newbno2 = newbno1 - alignment;
307 if (newbno1 >= freeend)
308 newbno1 = NULLAGBLOCK;
309 else
310 newlen1 = XFS_EXTLEN_MIN(wantlen, freeend - newbno1);
311 if (newbno2 < freebno)
312 newbno2 = NULLAGBLOCK;
313 else
314 newlen2 = XFS_EXTLEN_MIN(wantlen, freeend - newbno2);
315 if (newbno1 != NULLAGBLOCK && newbno2 != NULLAGBLOCK) {
316 if (newlen1 < newlen2 ||
317 (newlen1 == newlen2 &&
318 XFS_ABSDIFF(newbno1, wantbno) >
319 XFS_ABSDIFF(newbno2, wantbno)))
320 newbno1 = newbno2;
321 } else if (newbno2 != NULLAGBLOCK)
322 newbno1 = newbno2;
323 } else if (freeend >= wantend) {
324 newbno1 = wantbno;
325 } else if (alignment > 1) {
326 newbno1 = roundup(freeend - wantlen, alignment);
327 if (newbno1 > freeend - wantlen &&
328 newbno1 - alignment >= freebno)
329 newbno1 -= alignment;
330 else if (newbno1 >= freeend)
331 newbno1 = NULLAGBLOCK;
332 } else
333 newbno1 = freeend - wantlen;
334 *newbnop = newbno1;
335 return newbno1 == NULLAGBLOCK ? 0 : XFS_ABSDIFF(newbno1, wantbno);
336}
337
338/*
339 * Fix up the length, based on mod and prod.
340 * len should be k * prod + mod for some k.
341 * If len is too small it is returned unchanged.
342 * If len hits maxlen it is left alone.
343 */
344STATIC void
345xfs_alloc_fix_len(
346 xfs_alloc_arg_t *args) /* allocation argument structure */
347{
348 xfs_extlen_t k;
349 xfs_extlen_t rlen;
350
351 ASSERT(args->mod < args->prod);
352 rlen = args->len;
353 ASSERT(rlen >= args->minlen);
354 ASSERT(rlen <= args->maxlen);
355 if (args->prod <= 1 || rlen < args->mod || rlen == args->maxlen ||
356 (args->mod == 0 && rlen < args->prod))
357 return;
358 k = rlen % args->prod;
359 if (k == args->mod)
360 return;
Jan Kara30265112014-06-06 16:06:37 +1000361 if (k > args->mod)
362 rlen = rlen - (k - args->mod);
363 else
364 rlen = rlen - args->prod + (args->mod - k);
Dave Chinner3790a8c2015-02-24 10:16:04 +1100365 /* casts to (int) catch length underflows */
Jan Kara30265112014-06-06 16:06:37 +1000366 if ((int)rlen < (int)args->minlen)
367 return;
368 ASSERT(rlen >= args->minlen && rlen <= args->maxlen);
369 ASSERT(rlen % args->prod == args->mod);
Christoph Hellwig54fee132017-01-09 13:44:30 -0800370 ASSERT(args->pag->pagf_freeblks + args->pag->pagf_flcount >=
371 rlen + args->minleft);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 args->len = rlen;
373}
374
375/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 * Update the two btrees, logically removing from freespace the extent
377 * starting at rbno, rlen blocks. The extent is contained within the
378 * actual (current) free extent fbno for flen blocks.
379 * Flags are passed in indicating whether the cursors are set to the
380 * relevant records.
381 */
382STATIC int /* error code */
383xfs_alloc_fixup_trees(
384 xfs_btree_cur_t *cnt_cur, /* cursor for by-size btree */
385 xfs_btree_cur_t *bno_cur, /* cursor for by-block btree */
386 xfs_agblock_t fbno, /* starting block of free extent */
387 xfs_extlen_t flen, /* length of free extent */
388 xfs_agblock_t rbno, /* starting block of returned extent */
389 xfs_extlen_t rlen, /* length of returned extent */
390 int flags) /* flags, XFSA_FIXUP_... */
391{
392 int error; /* error code */
393 int i; /* operation results */
394 xfs_agblock_t nfbno1; /* first new free startblock */
395 xfs_agblock_t nfbno2; /* second new free startblock */
396 xfs_extlen_t nflen1=0; /* first new free length */
397 xfs_extlen_t nflen2=0; /* second new free length */
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100398 struct xfs_mount *mp;
399
400 mp = cnt_cur->bc_mp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
402 /*
403 * Look up the record in the by-size tree if necessary.
404 */
405 if (flags & XFSA_FIXUP_CNT_OK) {
406#ifdef DEBUG
407 if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i)))
408 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100409 XFS_WANT_CORRUPTED_RETURN(mp,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 i == 1 && nfbno1 == fbno && nflen1 == flen);
411#endif
412 } else {
413 if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i)))
414 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100415 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 }
417 /*
418 * Look up the record in the by-block tree if necessary.
419 */
420 if (flags & XFSA_FIXUP_BNO_OK) {
421#ifdef DEBUG
422 if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i)))
423 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100424 XFS_WANT_CORRUPTED_RETURN(mp,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 i == 1 && nfbno1 == fbno && nflen1 == flen);
426#endif
427 } else {
428 if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i)))
429 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100430 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
Christoph Hellwig7cc95a82008-10-30 17:14:34 +1100433#ifdef DEBUG
434 if (bno_cur->bc_nlevels == 1 && cnt_cur->bc_nlevels == 1) {
435 struct xfs_btree_block *bnoblock;
436 struct xfs_btree_block *cntblock;
437
438 bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]);
439 cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]);
440
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100441 XFS_WANT_CORRUPTED_RETURN(mp,
Christoph Hellwig7cc95a82008-10-30 17:14:34 +1100442 bnoblock->bb_numrecs == cntblock->bb_numrecs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 }
444#endif
Christoph Hellwig7cc95a82008-10-30 17:14:34 +1100445
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 /*
447 * Deal with all four cases: the allocated record is contained
448 * within the freespace record, so we can have new freespace
449 * at either (or both) end, or no freespace remaining.
450 */
451 if (rbno == fbno && rlen == flen)
452 nfbno1 = nfbno2 = NULLAGBLOCK;
453 else if (rbno == fbno) {
454 nfbno1 = rbno + rlen;
455 nflen1 = flen - rlen;
456 nfbno2 = NULLAGBLOCK;
457 } else if (rbno + rlen == fbno + flen) {
458 nfbno1 = fbno;
459 nflen1 = flen - rlen;
460 nfbno2 = NULLAGBLOCK;
461 } else {
462 nfbno1 = fbno;
463 nflen1 = rbno - fbno;
464 nfbno2 = rbno + rlen;
465 nflen2 = (fbno + flen) - nfbno2;
466 }
467 /*
468 * Delete the entry from the by-size btree.
469 */
Christoph Hellwig91cca5df2008-10-30 16:58:01 +1100470 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100472 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 /*
474 * Add new by-size btree entry(s).
475 */
476 if (nfbno1 != NULLAGBLOCK) {
477 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i)))
478 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100479 XFS_WANT_CORRUPTED_RETURN(mp, i == 0);
Christoph Hellwig4b22a572008-10-30 16:57:40 +1100480 if ((error = xfs_btree_insert(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100482 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 }
484 if (nfbno2 != NULLAGBLOCK) {
485 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i)))
486 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100487 XFS_WANT_CORRUPTED_RETURN(mp, i == 0);
Christoph Hellwig4b22a572008-10-30 16:57:40 +1100488 if ((error = xfs_btree_insert(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100490 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 }
492 /*
493 * Fix up the by-block btree entry(s).
494 */
495 if (nfbno1 == NULLAGBLOCK) {
496 /*
497 * No remaining freespace, just delete the by-block tree entry.
498 */
Christoph Hellwig91cca5df2008-10-30 16:58:01 +1100499 if ((error = xfs_btree_delete(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100501 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 } else {
503 /*
504 * Update the by-block entry to start later|be shorter.
505 */
506 if ((error = xfs_alloc_update(bno_cur, nfbno1, nflen1)))
507 return error;
508 }
509 if (nfbno2 != NULLAGBLOCK) {
510 /*
511 * 2 resulting free entries, need to add one.
512 */
513 if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i)))
514 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100515 XFS_WANT_CORRUPTED_RETURN(mp, i == 0);
Christoph Hellwig4b22a572008-10-30 16:57:40 +1100516 if ((error = xfs_btree_insert(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 return error;
Eric Sandeen5fb5aee2015-02-23 22:39:13 +1100518 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 }
520 return 0;
521}
522
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800523static xfs_failaddr_t
Dave Chinner612cfbf2012-11-14 17:52:32 +1100524xfs_agfl_verify(
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100525 struct xfs_buf *bp)
526{
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100527 struct xfs_mount *mp = bp->b_target->bt_mount;
528 struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp);
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100529 int i;
530
Darrick J. Wongb5572592018-01-08 10:51:08 -0800531 /*
532 * There is no verification of non-crc AGFLs because mkfs does not
533 * initialise the AGFL to zero or NULL. Hence the only valid part of the
534 * AGFL is what the AGF says is active. We can't get to the AGF, so we
535 * can't verify just those entries are valid.
536 */
537 if (!xfs_sb_version_hascrc(&mp->m_sb))
538 return NULL;
539
Eric Sandeence748ea2015-07-29 11:53:31 +1000540 if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800541 return __this_address;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100542 if (be32_to_cpu(agfl->agfl_magicnum) != XFS_AGFL_MAGIC)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800543 return __this_address;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100544 /*
545 * during growfs operations, the perag is not fully initialised,
546 * so we can't use it for any useful checking. growfs ensures we can't
547 * use it by using uncached buffers that don't have the perag attached
548 * so we can detect and avoid this problem.
549 */
550 if (bp->b_pag && be32_to_cpu(agfl->agfl_seqno) != bp->b_pag->pag_agno)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800551 return __this_address;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100552
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100553 for (i = 0; i < XFS_AGFL_SIZE(mp); i++) {
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100554 if (be32_to_cpu(agfl->agfl_bno[i]) != NULLAGBLOCK &&
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100555 be32_to_cpu(agfl->agfl_bno[i]) >= mp->m_sb.sb_agblocks)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800556 return __this_address;
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100557 }
Brian Fostera45086e2015-10-12 15:59:25 +1100558
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800559 if (!xfs_log_check_lsn(mp, be64_to_cpu(XFS_BUF_TO_AGFL(bp)->agfl_lsn)))
560 return __this_address;
561 return NULL;
Dave Chinner612cfbf2012-11-14 17:52:32 +1100562}
563
Dave Chinnerb0f539d2012-11-14 17:53:49 +1100564static void
Dave Chinner612cfbf2012-11-14 17:52:32 +1100565xfs_agfl_read_verify(
566 struct xfs_buf *bp)
567{
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100568 struct xfs_mount *mp = bp->b_target->bt_mount;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800569 xfs_failaddr_t fa;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100570
571 /*
572 * There is no verification of non-crc AGFLs because mkfs does not
573 * initialise the AGFL to zero or NULL. Hence the only valid part of the
574 * AGFL is what the AGF says is active. We can't get to the AGF, so we
575 * can't verify just those entries are valid.
576 */
577 if (!xfs_sb_version_hascrc(&mp->m_sb))
578 return;
579
Eric Sandeence5028c2014-02-27 15:23:10 +1100580 if (!xfs_buf_verify_cksum(bp, XFS_AGFL_CRC_OFF))
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800581 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
582 else {
583 fa = xfs_agfl_verify(bp);
584 if (fa)
585 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
586 }
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100587}
588
589static void
590xfs_agfl_write_verify(
591 struct xfs_buf *bp)
592{
593 struct xfs_mount *mp = bp->b_target->bt_mount;
594 struct xfs_buf_log_item *bip = bp->b_fspriv;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800595 xfs_failaddr_t fa;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100596
597 /* no verification of non-crc AGFLs */
598 if (!xfs_sb_version_hascrc(&mp->m_sb))
599 return;
600
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800601 fa = xfs_agfl_verify(bp);
602 if (fa) {
603 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100604 return;
605 }
606
607 if (bip)
608 XFS_BUF_TO_AGFL(bp)->agfl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
609
Eric Sandeenf1dbcd72014-02-27 15:18:23 +1100610 xfs_buf_update_cksum(bp, XFS_AGFL_CRC_OFF);
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100611}
612
Dave Chinner1813dd62012-11-14 17:54:40 +1100613const struct xfs_buf_ops xfs_agfl_buf_ops = {
Eric Sandeen233135b2016-01-04 16:10:19 +1100614 .name = "xfs_agfl",
Dave Chinner1813dd62012-11-14 17:54:40 +1100615 .verify_read = xfs_agfl_read_verify,
616 .verify_write = xfs_agfl_write_verify,
Darrick J. Wongb5572592018-01-08 10:51:08 -0800617 .verify_struct = xfs_agfl_verify,
Dave Chinner1813dd62012-11-14 17:54:40 +1100618};
619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620/*
621 * Read in the allocation group free block array.
622 */
Darrick J. Wong26788092017-06-16 11:00:07 -0700623int /* error */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624xfs_alloc_read_agfl(
625 xfs_mount_t *mp, /* mount point structure */
626 xfs_trans_t *tp, /* transaction pointer */
627 xfs_agnumber_t agno, /* allocation group number */
628 xfs_buf_t **bpp) /* buffer for the ag free block array */
629{
630 xfs_buf_t *bp; /* return value */
631 int error;
632
633 ASSERT(agno != NULLAGNUMBER);
634 error = xfs_trans_read_buf(
635 mp, tp, mp->m_ddev_targp,
636 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
Dave Chinner1813dd62012-11-14 17:54:40 +1100637 XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 if (error)
639 return error;
Christoph Hellwig38f23232011-10-10 16:52:45 +0000640 xfs_buf_set_ref(bp, XFS_AGFL_REF);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 *bpp = bp;
642 return 0;
643}
644
Christoph Hellwigecb69282011-03-04 12:59:55 +0000645STATIC int
646xfs_alloc_update_counters(
647 struct xfs_trans *tp,
648 struct xfs_perag *pag,
649 struct xfs_buf *agbp,
650 long len)
651{
652 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
653
654 pag->pagf_freeblks += len;
655 be32_add_cpu(&agf->agf_freeblks, len);
656
657 xfs_trans_agblocks_delta(tp, len);
658 if (unlikely(be32_to_cpu(agf->agf_freeblks) >
659 be32_to_cpu(agf->agf_length)))
Dave Chinner24513372014-06-25 14:58:08 +1000660 return -EFSCORRUPTED;
Christoph Hellwigecb69282011-03-04 12:59:55 +0000661
662 xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
663 return 0;
664}
665
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666/*
667 * Allocation group level functions.
668 */
669
670/*
671 * Allocate a variable extent in the allocation group agno.
672 * Type and bno are used to determine where in the allocation group the
673 * extent will start.
674 * Extent's length (returned in *len) will be between minlen and maxlen,
675 * and of the form k * prod + mod unless there's nothing that large.
676 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
677 */
678STATIC int /* error */
679xfs_alloc_ag_vextent(
680 xfs_alloc_arg_t *args) /* argument structure for allocation */
681{
682 int error=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683
684 ASSERT(args->minlen > 0);
685 ASSERT(args->maxlen > 0);
686 ASSERT(args->minlen <= args->maxlen);
687 ASSERT(args->mod < args->prod);
688 ASSERT(args->alignment > 0);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +1000689
690 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 * Branch to correct routine based on the type.
692 */
693 args->wasfromfl = 0;
694 switch (args->type) {
695 case XFS_ALLOCTYPE_THIS_AG:
696 error = xfs_alloc_ag_vextent_size(args);
697 break;
698 case XFS_ALLOCTYPE_NEAR_BNO:
699 error = xfs_alloc_ag_vextent_near(args);
700 break;
701 case XFS_ALLOCTYPE_THIS_BNO:
702 error = xfs_alloc_ag_vextent_exact(args);
703 break;
704 default:
705 ASSERT(0);
706 /* NOTREACHED */
707 }
Christoph Hellwigecb69282011-03-04 12:59:55 +0000708
709 if (error || args->agbno == NULLAGBLOCK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711
Christoph Hellwigecb69282011-03-04 12:59:55 +0000712 ASSERT(args->len >= args->minlen);
713 ASSERT(args->len <= args->maxlen);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +1000714 ASSERT(!args->wasfromfl || args->resv != XFS_AG_RESV_AGFL);
Christoph Hellwigecb69282011-03-04 12:59:55 +0000715 ASSERT(args->agbno % args->alignment == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716
Darrick J. Wong673930c2016-08-03 11:33:43 +1000717 /* if not file data, insert new block into the reverse map btree */
Darrick J. Wong33df3a92017-12-07 19:07:27 -0800718 if (!xfs_rmap_should_skip_owner_update(&args->oinfo)) {
Darrick J. Wong673930c2016-08-03 11:33:43 +1000719 error = xfs_rmap_alloc(args->tp, args->agbp, args->agno,
720 args->agbno, args->len, &args->oinfo);
721 if (error)
722 return error;
723 }
724
Christoph Hellwigecb69282011-03-04 12:59:55 +0000725 if (!args->wasfromfl) {
726 error = xfs_alloc_update_counters(args->tp, args->pag,
727 args->agbp,
728 -((long)(args->len)));
729 if (error)
730 return error;
731
Dave Chinner4ecbfe62012-04-29 10:41:10 +0000732 ASSERT(!xfs_extent_busy_search(args->mp, args->agno,
Christoph Hellwige26f0502011-04-24 19:06:15 +0000733 args->agbno, args->len));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 }
Christoph Hellwigecb69282011-03-04 12:59:55 +0000735
Darrick J. Wong3fd129b2016-09-19 10:30:52 +1000736 xfs_ag_resv_alloc_extent(args->pag, args->resv, args);
Christoph Hellwigecb69282011-03-04 12:59:55 +0000737
Bill O'Donnellff6d6af2015-10-12 18:21:22 +1100738 XFS_STATS_INC(args->mp, xs_allocx);
739 XFS_STATS_ADD(args->mp, xs_allocb, args->len);
Christoph Hellwigecb69282011-03-04 12:59:55 +0000740 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741}
742
743/*
744 * Allocate a variable extent at exactly agno/bno.
745 * Extent's length (returned in *len) will be between minlen and maxlen,
746 * and of the form k * prod + mod unless there's nothing that large.
747 * Return the starting a.g. block (bno), or NULLAGBLOCK if we can't do it.
748 */
749STATIC int /* error */
750xfs_alloc_ag_vextent_exact(
751 xfs_alloc_arg_t *args) /* allocation argument structure */
752{
753 xfs_btree_cur_t *bno_cur;/* by block-number btree cursor */
754 xfs_btree_cur_t *cnt_cur;/* by count btree cursor */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 int error;
756 xfs_agblock_t fbno; /* start block of found extent */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 xfs_extlen_t flen; /* length of found extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800758 xfs_agblock_t tbno; /* start block of busy extent */
759 xfs_extlen_t tlen; /* length of busy extent */
760 xfs_agblock_t tend; /* end block of busy extent */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 int i; /* success/failure of operation */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800762 unsigned busy_gen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763
764 ASSERT(args->alignment == 1);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 /*
767 * Allocate/initialize a cursor for the by-number freespace btree.
768 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +1100769 bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000770 args->agno, XFS_BTNUM_BNO);
771
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 /*
773 * Lookup bno and minlen in the btree (minlen is irrelevant, really).
774 * Look for the closest free block <= bno, it must contain bno
775 * if any free block does.
776 */
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000777 error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i);
778 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 goto error0;
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000780 if (!i)
781 goto not_found;
782
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 /*
784 * Grab the freespace record.
785 */
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000786 error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i);
787 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +1100789 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 ASSERT(fbno <= args->agbno);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000791
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 /*
Christoph Hellwige26f0502011-04-24 19:06:15 +0000793 * Check for overlapping busy extents.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800795 tbno = fbno;
796 tlen = flen;
797 xfs_extent_busy_trim(args, &tbno, &tlen, &busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +0000798
799 /*
800 * Give up if the start of the extent is busy, or the freespace isn't
801 * long enough for the minimum request.
802 */
803 if (tbno > args->agbno)
804 goto not_found;
805 if (tlen < args->minlen)
806 goto not_found;
807 tend = tbno + tlen;
808 if (tend < args->agbno + args->minlen)
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000809 goto not_found;
810
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 /*
812 * End of extent will be smaller of the freespace end and the
813 * maximal requested end.
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000814 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 * Fix the length according to mod and prod if given.
816 */
Chandra Seetharaman81463b12011-06-09 16:47:49 +0000817 args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen)
818 - args->agbno;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 xfs_alloc_fix_len(args);
Chandra Seetharaman81463b12011-06-09 16:47:49 +0000820 ASSERT(args->agbno + args->len <= tend);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000821
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 /*
Chandra Seetharaman81463b12011-06-09 16:47:49 +0000823 * We are allocating agbno for args->len
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 * Allocate/initialize a cursor for the by-size btree.
825 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +1100826 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
827 args->agno, XFS_BTNUM_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 ASSERT(args->agbno + args->len <=
Christoph Hellwig16259e72005-11-02 15:11:25 +1100829 be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000830 error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno,
831 args->len, XFSA_FIXUP_BNO_OK);
832 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
834 goto error0;
835 }
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000836
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
838 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +0000839
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 args->wasfromfl = 0;
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000841 trace_xfs_alloc_exact_done(args);
842 return 0;
843
844not_found:
845 /* Didn't find it, return null. */
846 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
847 args->agbno = NULLAGBLOCK;
848 trace_xfs_alloc_exact_notfound(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 return 0;
850
851error0:
852 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +0000853 trace_xfs_alloc_exact_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 return error;
855}
856
857/*
Christoph Hellwig489a1502010-12-10 15:04:11 +0000858 * Search the btree in a given direction via the search cursor and compare
859 * the records found against the good extent we've already found.
860 */
861STATIC int
862xfs_alloc_find_best_extent(
863 struct xfs_alloc_arg *args, /* allocation argument structure */
864 struct xfs_btree_cur **gcur, /* good cursor */
865 struct xfs_btree_cur **scur, /* searching cursor */
866 xfs_agblock_t gdiff, /* difference for search comparison */
867 xfs_agblock_t *sbno, /* extent found by search */
Christoph Hellwige26f0502011-04-24 19:06:15 +0000868 xfs_extlen_t *slen, /* extent length */
869 xfs_agblock_t *sbnoa, /* aligned extent found by search */
870 xfs_extlen_t *slena, /* aligned extent length */
Christoph Hellwig489a1502010-12-10 15:04:11 +0000871 int dir) /* 0 = search right, 1 = search left */
872{
Christoph Hellwig489a1502010-12-10 15:04:11 +0000873 xfs_agblock_t new;
874 xfs_agblock_t sdiff;
875 int error;
876 int i;
Christoph Hellwigebf55872017-02-07 14:06:57 -0800877 unsigned busy_gen;
Christoph Hellwig489a1502010-12-10 15:04:11 +0000878
879 /* The good extent is perfect, no need to search. */
880 if (!gdiff)
881 goto out_use_good;
882
883 /*
884 * Look until we find a better one, run out of space or run off the end.
885 */
886 do {
887 error = xfs_alloc_get_rec(*scur, sbno, slen, &i);
888 if (error)
889 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +1100890 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwigebf55872017-02-07 14:06:57 -0800891 xfs_alloc_compute_aligned(args, *sbno, *slen,
892 sbnoa, slena, &busy_gen);
Christoph Hellwig489a1502010-12-10 15:04:11 +0000893
894 /*
895 * The good extent is closer than this one.
896 */
897 if (!dir) {
Brian Fosterbfe46d42015-05-29 08:53:00 +1000898 if (*sbnoa > args->max_agbno)
899 goto out_use_good;
Christoph Hellwige26f0502011-04-24 19:06:15 +0000900 if (*sbnoa >= args->agbno + gdiff)
Christoph Hellwig489a1502010-12-10 15:04:11 +0000901 goto out_use_good;
902 } else {
Brian Fosterbfe46d42015-05-29 08:53:00 +1000903 if (*sbnoa < args->min_agbno)
904 goto out_use_good;
Christoph Hellwige26f0502011-04-24 19:06:15 +0000905 if (*sbnoa <= args->agbno - gdiff)
Christoph Hellwig489a1502010-12-10 15:04:11 +0000906 goto out_use_good;
907 }
908
909 /*
910 * Same distance, compare length and pick the best.
911 */
912 if (*slena >= args->minlen) {
913 args->len = XFS_EXTLEN_MIN(*slena, args->maxlen);
914 xfs_alloc_fix_len(args);
915
916 sdiff = xfs_alloc_compute_diff(args->agbno, args->len,
Jan Kara211d0222013-04-11 22:09:56 +0200917 args->alignment,
Dave Chinner292378e2016-09-26 08:21:28 +1000918 args->datatype, *sbnoa,
Christoph Hellwige26f0502011-04-24 19:06:15 +0000919 *slena, &new);
Christoph Hellwig489a1502010-12-10 15:04:11 +0000920
921 /*
922 * Choose closer size and invalidate other cursor.
923 */
924 if (sdiff < gdiff)
925 goto out_use_search;
926 goto out_use_good;
927 }
928
929 if (!dir)
930 error = xfs_btree_increment(*scur, 0, &i);
931 else
932 error = xfs_btree_decrement(*scur, 0, &i);
933 if (error)
934 goto error0;
935 } while (i);
936
937out_use_good:
938 xfs_btree_del_cursor(*scur, XFS_BTREE_NOERROR);
939 *scur = NULL;
940 return 0;
941
942out_use_search:
943 xfs_btree_del_cursor(*gcur, XFS_BTREE_NOERROR);
944 *gcur = NULL;
945 return 0;
946
947error0:
948 /* caller invalidates cursors */
949 return error;
950}
951
952/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 * Allocate a variable extent near bno in the allocation group agno.
954 * Extent's length (returned in len) will be between minlen and maxlen,
955 * and of the form k * prod + mod unless there's nothing that large.
956 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
957 */
958STATIC int /* error */
959xfs_alloc_ag_vextent_near(
960 xfs_alloc_arg_t *args) /* allocation argument structure */
961{
962 xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */
963 xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */
964 xfs_btree_cur_t *cnt_cur; /* cursor for count btree */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 xfs_agblock_t gtbno; /* start bno of right side entry */
966 xfs_agblock_t gtbnoa; /* aligned ... */
967 xfs_extlen_t gtdiff; /* difference to right side entry */
968 xfs_extlen_t gtlen; /* length of right side entry */
Christoph Hellwige26f0502011-04-24 19:06:15 +0000969 xfs_extlen_t gtlena; /* aligned ... */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 xfs_agblock_t gtnew; /* useful start bno of right side */
971 int error; /* error code */
972 int i; /* result code, temporary */
973 int j; /* result code, temporary */
974 xfs_agblock_t ltbno; /* start bno of left side entry */
975 xfs_agblock_t ltbnoa; /* aligned ... */
976 xfs_extlen_t ltdiff; /* difference to left side entry */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 xfs_extlen_t ltlen; /* length of left side entry */
Christoph Hellwige26f0502011-04-24 19:06:15 +0000978 xfs_extlen_t ltlena; /* aligned ... */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 xfs_agblock_t ltnew; /* useful start bno of left side */
980 xfs_extlen_t rlen; /* length of returned extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800981 bool busy;
982 unsigned busy_gen;
Dave Chinner63d20d62013-08-12 20:49:50 +1000983#ifdef DEBUG
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 /*
985 * Randomly don't execute the first algorithm.
986 */
987 int dofirst; /* set to do first algorithm */
988
Akinobu Mitaecb34032013-03-04 21:58:20 +0900989 dofirst = prandom_u32() & 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990#endif
Christoph Hellwige26f0502011-04-24 19:06:15 +0000991
Brian Fosterbfe46d42015-05-29 08:53:00 +1000992 /* handle unitialized agbno range so caller doesn't have to */
993 if (!args->min_agbno && !args->max_agbno)
994 args->max_agbno = args->mp->m_sb.sb_agblocks - 1;
995 ASSERT(args->min_agbno <= args->max_agbno);
996
997 /* clamp agbno to the range if it's outside */
998 if (args->agbno < args->min_agbno)
999 args->agbno = args->min_agbno;
1000 if (args->agbno > args->max_agbno)
1001 args->agbno = args->max_agbno;
1002
Christoph Hellwige26f0502011-04-24 19:06:15 +00001003restart:
1004 bno_cur_lt = NULL;
1005 bno_cur_gt = NULL;
1006 ltlen = 0;
1007 gtlena = 0;
1008 ltlena = 0;
Christoph Hellwigebf55872017-02-07 14:06:57 -08001009 busy = false;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001010
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 /*
1012 * Get a cursor for the by-size btree.
1013 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001014 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1015 args->agno, XFS_BTNUM_CNT);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001016
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 /*
1018 * See if there are any free extents as big as maxlen.
1019 */
1020 if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen, &i)))
1021 goto error0;
1022 /*
1023 * If none, then pick up the last entry in the tree unless the
1024 * tree is empty.
1025 */
1026 if (!i) {
1027 if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &ltbno,
1028 &ltlen, &i)))
1029 goto error0;
1030 if (i == 0 || ltlen == 0) {
1031 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001032 trace_xfs_alloc_near_noentry(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 return 0;
1034 }
1035 ASSERT(i == 1);
1036 }
1037 args->wasfromfl = 0;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001038
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 /*
1040 * First algorithm.
1041 * If the requested extent is large wrt the freespaces available
1042 * in this a.g., then the cursor will be pointing to a btree entry
1043 * near the right edge of the tree. If it's in the last btree leaf
1044 * block, then we just examine all the entries in that block
1045 * that are big enough, and pick the best one.
1046 * This is written as a while loop so we can break out of it,
1047 * but we never loop back to the top.
1048 */
1049 while (xfs_btree_islastblock(cnt_cur, 0)) {
1050 xfs_extlen_t bdiff;
1051 int besti=0;
1052 xfs_extlen_t blen=0;
1053 xfs_agblock_t bnew=0;
1054
Dave Chinner63d20d62013-08-12 20:49:50 +10001055#ifdef DEBUG
1056 if (dofirst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 break;
1058#endif
1059 /*
1060 * Start from the entry that lookup found, sequence through
1061 * all larger free blocks. If we're actually pointing at a
1062 * record smaller than maxlen, go to the start of this block,
1063 * and skip all those smaller than minlen.
1064 */
1065 if (ltlen || args->alignment > 1) {
1066 cnt_cur->bc_ptrs[0] = 1;
1067 do {
1068 if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno,
1069 &ltlen, &i)))
1070 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001071 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 if (ltlen >= args->minlen)
1073 break;
Christoph Hellwig637aa502008-10-30 16:55:45 +11001074 if ((error = xfs_btree_increment(cnt_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 goto error0;
1076 } while (i);
1077 ASSERT(ltlen >= args->minlen);
1078 if (!i)
1079 break;
1080 }
1081 i = cnt_cur->bc_ptrs[0];
1082 for (j = 1, blen = 0, bdiff = 0;
1083 !error && j && (blen < args->maxlen || bdiff > 0);
Christoph Hellwig637aa502008-10-30 16:55:45 +11001084 error = xfs_btree_increment(cnt_cur, 0, &j)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 /*
1086 * For each entry, decide if it's better than
1087 * the previous best entry.
1088 */
1089 if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
1090 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001091 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001092 busy = xfs_alloc_compute_aligned(args, ltbno, ltlen,
1093 &ltbnoa, &ltlena, &busy_gen);
David Chinnere6430032008-04-17 16:49:49 +10001094 if (ltlena < args->minlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 continue;
Brian Fosterbfe46d42015-05-29 08:53:00 +10001096 if (ltbnoa < args->min_agbno || ltbnoa > args->max_agbno)
1097 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1099 xfs_alloc_fix_len(args);
1100 ASSERT(args->len >= args->minlen);
1101 if (args->len < blen)
1102 continue;
1103 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
Dave Chinner292378e2016-09-26 08:21:28 +10001104 args->alignment, args->datatype, ltbnoa,
Jan Kara211d0222013-04-11 22:09:56 +02001105 ltlena, &ltnew);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 if (ltnew != NULLAGBLOCK &&
1107 (args->len > blen || ltdiff < bdiff)) {
1108 bdiff = ltdiff;
1109 bnew = ltnew;
1110 blen = args->len;
1111 besti = cnt_cur->bc_ptrs[0];
1112 }
1113 }
1114 /*
1115 * It didn't work. We COULD be in a case where
1116 * there's a good record somewhere, so try again.
1117 */
1118 if (blen == 0)
1119 break;
1120 /*
1121 * Point at the best entry, and retrieve it again.
1122 */
1123 cnt_cur->bc_ptrs[0] = besti;
1124 if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
1125 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001126 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwig73523a22010-07-20 17:54:45 +10001127 ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 args->len = blen;
Christoph Hellwig54fee132017-01-09 13:44:30 -08001129
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 /*
1131 * We are allocating starting at bnew for blen blocks.
1132 */
1133 args->agbno = bnew;
1134 ASSERT(bnew >= ltbno);
Christoph Hellwig73523a22010-07-20 17:54:45 +10001135 ASSERT(bnew + blen <= ltbno + ltlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 /*
1137 * Set up a cursor for the by-bno tree.
1138 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001139 bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp,
1140 args->agbp, args->agno, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 /*
1142 * Fix up the btree entries.
1143 */
1144 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno,
1145 ltlen, bnew, blen, XFSA_FIXUP_CNT_OK)))
1146 goto error0;
1147 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1148 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001149
1150 trace_xfs_alloc_near_first(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 return 0;
1152 }
1153 /*
1154 * Second algorithm.
1155 * Search in the by-bno tree to the left and to the right
1156 * simultaneously, until in each case we find a space big enough,
1157 * or run into the edge of the tree. When we run into the edge,
1158 * we deallocate that cursor.
1159 * If both searches succeed, we compare the two spaces and pick
1160 * the better one.
1161 * With alignment, it's possible for both to fail; the upper
1162 * level algorithm that picks allocation groups for allocations
1163 * is not supposed to do this.
1164 */
1165 /*
1166 * Allocate and initialize the cursor for the leftward search.
1167 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001168 bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1169 args->agno, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 /*
1171 * Lookup <= bno to find the leftward search's starting point.
1172 */
1173 if ((error = xfs_alloc_lookup_le(bno_cur_lt, args->agbno, args->maxlen, &i)))
1174 goto error0;
1175 if (!i) {
1176 /*
1177 * Didn't find anything; use this cursor for the rightward
1178 * search.
1179 */
1180 bno_cur_gt = bno_cur_lt;
1181 bno_cur_lt = NULL;
1182 }
1183 /*
1184 * Found something. Duplicate the cursor for the rightward search.
1185 */
1186 else if ((error = xfs_btree_dup_cursor(bno_cur_lt, &bno_cur_gt)))
1187 goto error0;
1188 /*
1189 * Increment the cursor, so we will point at the entry just right
1190 * of the leftward entry if any, or to the leftmost entry.
1191 */
Christoph Hellwig637aa502008-10-30 16:55:45 +11001192 if ((error = xfs_btree_increment(bno_cur_gt, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 goto error0;
1194 if (!i) {
1195 /*
1196 * It failed, there are no rightward entries.
1197 */
1198 xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_NOERROR);
1199 bno_cur_gt = NULL;
1200 }
1201 /*
1202 * Loop going left with the leftward cursor, right with the
1203 * rightward cursor, until either both directions give up or
1204 * we find an entry at least as big as minlen.
1205 */
1206 do {
1207 if (bno_cur_lt) {
1208 if ((error = xfs_alloc_get_rec(bno_cur_lt, &ltbno, &ltlen, &i)))
1209 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001210 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001211 busy |= xfs_alloc_compute_aligned(args, ltbno, ltlen,
1212 &ltbnoa, &ltlena, &busy_gen);
Brian Fosterbfe46d42015-05-29 08:53:00 +10001213 if (ltlena >= args->minlen && ltbnoa >= args->min_agbno)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 break;
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001215 if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 goto error0;
Brian Fosterbfe46d42015-05-29 08:53:00 +10001217 if (!i || ltbnoa < args->min_agbno) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 xfs_btree_del_cursor(bno_cur_lt,
1219 XFS_BTREE_NOERROR);
1220 bno_cur_lt = NULL;
1221 }
1222 }
1223 if (bno_cur_gt) {
1224 if ((error = xfs_alloc_get_rec(bno_cur_gt, &gtbno, &gtlen, &i)))
1225 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001226 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001227 busy |= xfs_alloc_compute_aligned(args, gtbno, gtlen,
1228 &gtbnoa, &gtlena, &busy_gen);
Brian Fosterbfe46d42015-05-29 08:53:00 +10001229 if (gtlena >= args->minlen && gtbnoa <= args->max_agbno)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 break;
Christoph Hellwig637aa502008-10-30 16:55:45 +11001231 if ((error = xfs_btree_increment(bno_cur_gt, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 goto error0;
Brian Fosterbfe46d42015-05-29 08:53:00 +10001233 if (!i || gtbnoa > args->max_agbno) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234 xfs_btree_del_cursor(bno_cur_gt,
1235 XFS_BTREE_NOERROR);
1236 bno_cur_gt = NULL;
1237 }
1238 }
1239 } while (bno_cur_lt || bno_cur_gt);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001240
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 /*
1242 * Got both cursors still active, need to find better entry.
1243 */
1244 if (bno_cur_lt && bno_cur_gt) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 if (ltlena >= args->minlen) {
1246 /*
Christoph Hellwig489a1502010-12-10 15:04:11 +00001247 * Left side is good, look for a right side entry.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 */
1249 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1250 xfs_alloc_fix_len(args);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001251 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
Dave Chinner292378e2016-09-26 08:21:28 +10001252 args->alignment, args->datatype, ltbnoa,
Jan Kara211d0222013-04-11 22:09:56 +02001253 ltlena, &ltnew);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001254
1255 error = xfs_alloc_find_best_extent(args,
1256 &bno_cur_lt, &bno_cur_gt,
Christoph Hellwige26f0502011-04-24 19:06:15 +00001257 ltdiff, &gtbno, &gtlen,
1258 &gtbnoa, &gtlena,
Christoph Hellwig489a1502010-12-10 15:04:11 +00001259 0 /* search right */);
1260 } else {
1261 ASSERT(gtlena >= args->minlen);
1262
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 /*
Christoph Hellwig489a1502010-12-10 15:04:11 +00001264 * Right side is good, look for a left side entry.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265 */
1266 args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
1267 xfs_alloc_fix_len(args);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001268 gtdiff = xfs_alloc_compute_diff(args->agbno, args->len,
Dave Chinner292378e2016-09-26 08:21:28 +10001269 args->alignment, args->datatype, gtbnoa,
Jan Kara211d0222013-04-11 22:09:56 +02001270 gtlena, &gtnew);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001271
1272 error = xfs_alloc_find_best_extent(args,
1273 &bno_cur_gt, &bno_cur_lt,
Christoph Hellwige26f0502011-04-24 19:06:15 +00001274 gtdiff, &ltbno, &ltlen,
1275 &ltbnoa, &ltlena,
Christoph Hellwig489a1502010-12-10 15:04:11 +00001276 1 /* search left */);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 }
Christoph Hellwig489a1502010-12-10 15:04:11 +00001278
1279 if (error)
1280 goto error0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 }
Christoph Hellwig489a1502010-12-10 15:04:11 +00001282
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283 /*
1284 * If we couldn't get anything, give up.
1285 */
1286 if (bno_cur_lt == NULL && bno_cur_gt == NULL) {
Dave Chinnere3a746f52012-07-12 07:40:42 +10001287 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1288
Christoph Hellwigebf55872017-02-07 14:06:57 -08001289 if (busy) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001290 trace_xfs_alloc_near_busy(args);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001291 xfs_extent_busy_flush(args->mp, args->pag, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001292 goto restart;
1293 }
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001294 trace_xfs_alloc_size_neither(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 args->agbno = NULLAGBLOCK;
1296 return 0;
1297 }
Christoph Hellwig489a1502010-12-10 15:04:11 +00001298
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 /*
1300 * At this point we have selected a freespace entry, either to the
1301 * left or to the right. If it's on the right, copy all the
1302 * useful variables to the "left" set so we only have one
1303 * copy of this code.
1304 */
1305 if (bno_cur_gt) {
1306 bno_cur_lt = bno_cur_gt;
1307 bno_cur_gt = NULL;
1308 ltbno = gtbno;
1309 ltbnoa = gtbnoa;
1310 ltlen = gtlen;
1311 ltlena = gtlena;
1312 j = 1;
1313 } else
1314 j = 0;
Christoph Hellwig489a1502010-12-10 15:04:11 +00001315
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 /*
1317 * Fix up the length and compute the useful address.
1318 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1320 xfs_alloc_fix_len(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 rlen = args->len;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001322 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
Dave Chinner292378e2016-09-26 08:21:28 +10001323 args->datatype, ltbnoa, ltlena, &ltnew);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 ASSERT(ltnew >= ltbno);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001325 ASSERT(ltnew + rlen <= ltbnoa + ltlena);
Christoph Hellwig16259e72005-11-02 15:11:25 +11001326 ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
Brian Fosterbfe46d42015-05-29 08:53:00 +10001327 ASSERT(ltnew >= args->min_agbno && ltnew <= args->max_agbno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 args->agbno = ltnew;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001329
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen,
1331 ltnew, rlen, XFSA_FIXUP_BNO_OK)))
1332 goto error0;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001333
1334 if (j)
1335 trace_xfs_alloc_near_greater(args);
1336 else
1337 trace_xfs_alloc_near_lesser(args);
1338
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1340 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
1341 return 0;
1342
1343 error0:
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001344 trace_xfs_alloc_near_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 if (cnt_cur != NULL)
1346 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1347 if (bno_cur_lt != NULL)
1348 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_ERROR);
1349 if (bno_cur_gt != NULL)
1350 xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_ERROR);
1351 return error;
1352}
1353
1354/*
1355 * Allocate a variable extent anywhere in the allocation group agno.
1356 * Extent's length (returned in len) will be between minlen and maxlen,
1357 * and of the form k * prod + mod unless there's nothing that large.
1358 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
1359 */
1360STATIC int /* error */
1361xfs_alloc_ag_vextent_size(
1362 xfs_alloc_arg_t *args) /* allocation argument structure */
1363{
1364 xfs_btree_cur_t *bno_cur; /* cursor for bno btree */
1365 xfs_btree_cur_t *cnt_cur; /* cursor for cnt btree */
1366 int error; /* error result */
1367 xfs_agblock_t fbno; /* start of found freespace */
1368 xfs_extlen_t flen; /* length of found freespace */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 int i; /* temp status variable */
1370 xfs_agblock_t rbno; /* returned block number */
1371 xfs_extlen_t rlen; /* length of returned extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -08001372 bool busy;
1373 unsigned busy_gen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374
Christoph Hellwige26f0502011-04-24 19:06:15 +00001375restart:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 /*
1377 * Allocate and initialize a cursor for the by-size btree.
1378 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001379 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1380 args->agno, XFS_BTNUM_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 bno_cur = NULL;
Christoph Hellwigebf55872017-02-07 14:06:57 -08001382 busy = false;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001383
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 /*
1385 * Look for an entry >= maxlen+alignment-1 blocks.
1386 */
1387 if ((error = xfs_alloc_lookup_ge(cnt_cur, 0,
1388 args->maxlen + args->alignment - 1, &i)))
1389 goto error0;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001390
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 /*
Christoph Hellwigebf55872017-02-07 14:06:57 -08001392 * If none then we have to settle for a smaller extent. In the case that
1393 * there are no large extents, this will return the last entry in the
1394 * tree unless the tree is empty. In the case that there are only busy
1395 * large extents, this will return the largest small extent unless there
Christoph Hellwige26f0502011-04-24 19:06:15 +00001396 * are no smaller extents available.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 */
Christoph Hellwigebf55872017-02-07 14:06:57 -08001398 if (!i) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001399 error = xfs_alloc_ag_vextent_small(args, cnt_cur,
1400 &fbno, &flen, &i);
1401 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 goto error0;
1403 if (i == 0 || flen == 0) {
1404 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001405 trace_xfs_alloc_size_noentry(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 return 0;
1407 }
1408 ASSERT(i == 1);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001409 busy = xfs_alloc_compute_aligned(args, fbno, flen, &rbno,
1410 &rlen, &busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001411 } else {
1412 /*
1413 * Search for a non-busy extent that is large enough.
Christoph Hellwige26f0502011-04-24 19:06:15 +00001414 */
1415 for (;;) {
1416 error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i);
1417 if (error)
1418 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001419 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001420
Christoph Hellwigebf55872017-02-07 14:06:57 -08001421 busy = xfs_alloc_compute_aligned(args, fbno, flen,
1422 &rbno, &rlen, &busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001423
1424 if (rlen >= args->maxlen)
1425 break;
1426
1427 error = xfs_btree_increment(cnt_cur, 0, &i);
1428 if (error)
1429 goto error0;
1430 if (i == 0) {
1431 /*
1432 * Our only valid extents must have been busy.
1433 * Make it unbusy by forcing the log out and
Christoph Hellwigebf55872017-02-07 14:06:57 -08001434 * retrying.
Christoph Hellwige26f0502011-04-24 19:06:15 +00001435 */
1436 xfs_btree_del_cursor(cnt_cur,
1437 XFS_BTREE_NOERROR);
1438 trace_xfs_alloc_size_busy(args);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001439 xfs_extent_busy_flush(args->mp,
1440 args->pag, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001441 goto restart;
1442 }
1443 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 }
Christoph Hellwige26f0502011-04-24 19:06:15 +00001445
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 /*
1447 * In the first case above, we got the last entry in the
1448 * by-size btree. Now we check to see if the space hits maxlen
1449 * once aligned; if not, we search left for something better.
1450 * This can't happen in the second case above.
1451 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
Eric Sandeenc29aad42015-02-23 22:39:08 +11001453 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 (rlen <= flen && rbno + rlen <= fbno + flen), error0);
1455 if (rlen < args->maxlen) {
1456 xfs_agblock_t bestfbno;
1457 xfs_extlen_t bestflen;
1458 xfs_agblock_t bestrbno;
1459 xfs_extlen_t bestrlen;
1460
1461 bestrlen = rlen;
1462 bestrbno = rbno;
1463 bestflen = flen;
1464 bestfbno = fbno;
1465 for (;;) {
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001466 if ((error = xfs_btree_decrement(cnt_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 goto error0;
1468 if (i == 0)
1469 break;
1470 if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen,
1471 &i)))
1472 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001473 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 if (flen < bestrlen)
1475 break;
Christoph Hellwigebf55872017-02-07 14:06:57 -08001476 busy = xfs_alloc_compute_aligned(args, fbno, flen,
1477 &rbno, &rlen, &busy_gen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
Eric Sandeenc29aad42015-02-23 22:39:08 +11001479 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 (rlen <= flen && rbno + rlen <= fbno + flen),
1481 error0);
1482 if (rlen > bestrlen) {
1483 bestrlen = rlen;
1484 bestrbno = rbno;
1485 bestflen = flen;
1486 bestfbno = fbno;
1487 if (rlen == args->maxlen)
1488 break;
1489 }
1490 }
1491 if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen,
1492 &i)))
1493 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001494 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 rlen = bestrlen;
1496 rbno = bestrbno;
1497 flen = bestflen;
1498 fbno = bestfbno;
1499 }
1500 args->wasfromfl = 0;
1501 /*
1502 * Fix up the length.
1503 */
1504 args->len = rlen;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001505 if (rlen < args->minlen) {
Christoph Hellwigebf55872017-02-07 14:06:57 -08001506 if (busy) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001507 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1508 trace_xfs_alloc_size_busy(args);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001509 xfs_extent_busy_flush(args->mp, args->pag, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001510 goto restart;
1511 }
1512 goto out_nominleft;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 }
Christoph Hellwige26f0502011-04-24 19:06:15 +00001514 xfs_alloc_fix_len(args);
1515
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 rlen = args->len;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001517 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 /*
1519 * Allocate and initialize a cursor for the by-block tree.
1520 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001521 bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1522 args->agno, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
1524 rbno, rlen, XFSA_FIXUP_CNT_OK)))
1525 goto error0;
1526 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1527 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
1528 cnt_cur = bno_cur = NULL;
1529 args->len = rlen;
1530 args->agbno = rbno;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001531 XFS_WANT_CORRUPTED_GOTO(args->mp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 args->agbno + args->len <=
Christoph Hellwig16259e72005-11-02 15:11:25 +11001533 be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 error0);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001535 trace_xfs_alloc_size_done(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 return 0;
1537
1538error0:
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001539 trace_xfs_alloc_size_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 if (cnt_cur)
1541 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1542 if (bno_cur)
1543 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
1544 return error;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001545
1546out_nominleft:
1547 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1548 trace_xfs_alloc_size_nominleft(args);
1549 args->agbno = NULLAGBLOCK;
1550 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551}
1552
1553/*
1554 * Deal with the case where only small freespaces remain.
1555 * Either return the contents of the last freespace record,
1556 * or allocate space from the freelist if there is nothing in the tree.
1557 */
1558STATIC int /* error */
1559xfs_alloc_ag_vextent_small(
1560 xfs_alloc_arg_t *args, /* allocation argument structure */
1561 xfs_btree_cur_t *ccur, /* by-size cursor */
1562 xfs_agblock_t *fbnop, /* result block number */
1563 xfs_extlen_t *flenp, /* result length */
1564 int *stat) /* status: 0-freelist, 1-normal/none */
1565{
Darrick J. Wonga03f1a62016-08-17 11:12:57 +10001566 struct xfs_owner_info oinfo;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001567 struct xfs_perag *pag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 int error;
1569 xfs_agblock_t fbno;
1570 xfs_extlen_t flen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 int i;
1572
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001573 if ((error = xfs_btree_decrement(ccur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 goto error0;
1575 if (i) {
1576 if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i)))
1577 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001578 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 }
1580 /*
1581 * Nothing in the btree, try the freelist. Make sure
1582 * to respect minleft even when pulling from the
1583 * freelist.
1584 */
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001585 else if (args->minlen == 1 && args->alignment == 1 &&
1586 args->resv != XFS_AG_RESV_AGFL &&
Christoph Hellwig16259e72005-11-02 15:11:25 +11001587 (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
1588 > args->minleft)) {
David Chinner92821e22007-05-24 15:26:31 +10001589 error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
1590 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 goto error0;
1592 if (fbno != NULLAGBLOCK) {
Dave Chinner4ecbfe62012-04-29 10:41:10 +00001593 xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1,
Dave Chinner292378e2016-09-26 08:21:28 +10001594 xfs_alloc_allow_busy_reuse(args->datatype));
Christoph Hellwig97d3ac72011-04-24 19:06:16 +00001595
Dave Chinner292378e2016-09-26 08:21:28 +10001596 if (xfs_alloc_is_userdata(args->datatype)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 xfs_buf_t *bp;
1598
1599 bp = xfs_btree_get_bufs(args->mp, args->tp,
1600 args->agno, fbno, 0);
Eric Sandeen93e8bef2017-10-09 21:08:06 -07001601 if (!bp) {
1602 error = -EFSCORRUPTED;
1603 goto error0;
1604 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 xfs_trans_binval(args->tp, bp);
1606 }
1607 args->len = 1;
1608 args->agbno = fbno;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001609 XFS_WANT_CORRUPTED_GOTO(args->mp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 args->agbno + args->len <=
Christoph Hellwig16259e72005-11-02 15:11:25 +11001611 be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 error0);
1613 args->wasfromfl = 1;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001614 trace_xfs_alloc_small_freelist(args);
Darrick J. Wonga03f1a62016-08-17 11:12:57 +10001615
1616 /*
1617 * If we're feeding an AGFL block to something that
1618 * doesn't live in the free space, we need to clear
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001619 * out the OWN_AG rmap and add the block back to
1620 * the AGFL per-AG reservation.
Darrick J. Wonga03f1a62016-08-17 11:12:57 +10001621 */
1622 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG);
1623 error = xfs_rmap_free(args->tp, args->agbp, args->agno,
1624 fbno, 1, &oinfo);
1625 if (error)
1626 goto error0;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001627 pag = xfs_perag_get(args->mp, args->agno);
1628 xfs_ag_resv_free_extent(pag, XFS_AG_RESV_AGFL,
1629 args->tp, 1);
1630 xfs_perag_put(pag);
Darrick J. Wonga03f1a62016-08-17 11:12:57 +10001631
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 *stat = 0;
1633 return 0;
1634 }
1635 /*
1636 * Nothing in the freelist.
1637 */
1638 else
1639 flen = 0;
1640 }
1641 /*
1642 * Can't allocate from the freelist for some reason.
1643 */
Nathan Scottd432c802006-09-28 11:03:44 +10001644 else {
1645 fbno = NULLAGBLOCK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646 flen = 0;
Nathan Scottd432c802006-09-28 11:03:44 +10001647 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 /*
1649 * Can't do the allocation, give up.
1650 */
1651 if (flen < args->minlen) {
1652 args->agbno = NULLAGBLOCK;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001653 trace_xfs_alloc_small_notenough(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 flen = 0;
1655 }
1656 *fbnop = fbno;
1657 *flenp = flen;
1658 *stat = 1;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001659 trace_xfs_alloc_small_done(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 return 0;
1661
1662error0:
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001663 trace_xfs_alloc_small_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 return error;
1665}
1666
1667/*
1668 * Free the extent starting at agno/bno for length.
1669 */
Darrick J. Wong340785c2016-08-03 11:33:42 +10001670STATIC int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671xfs_free_ag_extent(
Darrick J. Wong340785c2016-08-03 11:33:42 +10001672 xfs_trans_t *tp,
1673 xfs_buf_t *agbp,
1674 xfs_agnumber_t agno,
1675 xfs_agblock_t bno,
1676 xfs_extlen_t len,
1677 struct xfs_owner_info *oinfo,
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001678 enum xfs_ag_resv_type type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679{
1680 xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */
1681 xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */
1682 int error; /* error return value */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 xfs_agblock_t gtbno; /* start of right neighbor block */
1684 xfs_extlen_t gtlen; /* length of right neighbor block */
1685 int haveleft; /* have a left neighbor block */
1686 int haveright; /* have a right neighbor block */
1687 int i; /* temp, result code */
1688 xfs_agblock_t ltbno; /* start of left neighbor block */
1689 xfs_extlen_t ltlen; /* length of left neighbor block */
1690 xfs_mount_t *mp; /* mount point struct for filesystem */
1691 xfs_agblock_t nbno; /* new starting block of freespace */
1692 xfs_extlen_t nlen; /* new length of freespace */
Christoph Hellwigecb69282011-03-04 12:59:55 +00001693 xfs_perag_t *pag; /* per allocation group data */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
Darrick J. Wong673930c2016-08-03 11:33:43 +10001695 bno_cur = cnt_cur = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 mp = tp->t_mountp;
Darrick J. Wong673930c2016-08-03 11:33:43 +10001697
Darrick J. Wong33df3a92017-12-07 19:07:27 -08001698 if (!xfs_rmap_should_skip_owner_update(oinfo)) {
Darrick J. Wong673930c2016-08-03 11:33:43 +10001699 error = xfs_rmap_free(tp, agbp, agno, bno, len, oinfo);
1700 if (error)
1701 goto error0;
1702 }
1703
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 /*
1705 * Allocate and initialize a cursor for the by-block btree.
1706 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001707 bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 /*
1709 * Look for a neighboring block on the left (lower block numbers)
1710 * that is contiguous with this space.
1711 */
1712 if ((error = xfs_alloc_lookup_le(bno_cur, bno, len, &haveleft)))
1713 goto error0;
1714 if (haveleft) {
1715 /*
1716 * There is a block to our left.
1717 */
1718 if ((error = xfs_alloc_get_rec(bno_cur, &ltbno, &ltlen, &i)))
1719 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001720 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 /*
1722 * It's not contiguous, though.
1723 */
1724 if (ltbno + ltlen < bno)
1725 haveleft = 0;
1726 else {
1727 /*
1728 * If this failure happens the request to free this
1729 * space was invalid, it's (partly) already free.
1730 * Very bad.
1731 */
Eric Sandeenc29aad42015-02-23 22:39:08 +11001732 XFS_WANT_CORRUPTED_GOTO(mp,
1733 ltbno + ltlen <= bno, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 }
1735 }
1736 /*
1737 * Look for a neighboring block on the right (higher block numbers)
1738 * that is contiguous with this space.
1739 */
Christoph Hellwig637aa502008-10-30 16:55:45 +11001740 if ((error = xfs_btree_increment(bno_cur, 0, &haveright)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 goto error0;
1742 if (haveright) {
1743 /*
1744 * There is a block to our right.
1745 */
1746 if ((error = xfs_alloc_get_rec(bno_cur, &gtbno, &gtlen, &i)))
1747 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001748 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 /*
1750 * It's not contiguous, though.
1751 */
1752 if (bno + len < gtbno)
1753 haveright = 0;
1754 else {
1755 /*
1756 * If this failure happens the request to free this
1757 * space was invalid, it's (partly) already free.
1758 * Very bad.
1759 */
Eric Sandeenc29aad42015-02-23 22:39:08 +11001760 XFS_WANT_CORRUPTED_GOTO(mp, gtbno >= bno + len, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 }
1762 }
1763 /*
1764 * Now allocate and initialize a cursor for the by-size tree.
1765 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001766 cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 /*
1768 * Have both left and right contiguous neighbors.
1769 * Merge all three into a single free block.
1770 */
1771 if (haveleft && haveright) {
1772 /*
1773 * Delete the old by-size entry on the left.
1774 */
1775 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
1776 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001777 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001778 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001780 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 /*
1782 * Delete the old by-size entry on the right.
1783 */
1784 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
1785 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001786 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001787 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001789 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 /*
1791 * Delete the old by-block entry for the right block.
1792 */
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001793 if ((error = xfs_btree_delete(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001795 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 /*
1797 * Move the by-block cursor back to the left neighbor.
1798 */
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001799 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001801 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802#ifdef DEBUG
1803 /*
1804 * Check that this is the right record: delete didn't
1805 * mangle the cursor.
1806 */
1807 {
1808 xfs_agblock_t xxbno;
1809 xfs_extlen_t xxlen;
1810
1811 if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen,
1812 &i)))
1813 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001814 XFS_WANT_CORRUPTED_GOTO(mp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 i == 1 && xxbno == ltbno && xxlen == ltlen,
1816 error0);
1817 }
1818#endif
1819 /*
1820 * Update remaining by-block entry to the new, joined block.
1821 */
1822 nbno = ltbno;
1823 nlen = len + ltlen + gtlen;
1824 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
1825 goto error0;
1826 }
1827 /*
1828 * Have only a left contiguous neighbor.
1829 * Merge it together with the new freespace.
1830 */
1831 else if (haveleft) {
1832 /*
1833 * Delete the old by-size entry on the left.
1834 */
1835 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
1836 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001837 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001838 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001840 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 /*
1842 * Back up the by-block cursor to the left neighbor, and
1843 * update its length.
1844 */
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001845 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001847 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 nbno = ltbno;
1849 nlen = len + ltlen;
1850 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
1851 goto error0;
1852 }
1853 /*
1854 * Have only a right contiguous neighbor.
1855 * Merge it together with the new freespace.
1856 */
1857 else if (haveright) {
1858 /*
1859 * Delete the old by-size entry on the right.
1860 */
1861 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
1862 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001863 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001864 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001866 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 /*
1868 * Update the starting block and length of the right
1869 * neighbor in the by-block tree.
1870 */
1871 nbno = bno;
1872 nlen = len + gtlen;
1873 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
1874 goto error0;
1875 }
1876 /*
1877 * No contiguous neighbors.
1878 * Insert the new freespace into the by-block tree.
1879 */
1880 else {
1881 nbno = bno;
1882 nlen = len;
Christoph Hellwig4b22a572008-10-30 16:57:40 +11001883 if ((error = xfs_btree_insert(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001885 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 }
1887 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
1888 bno_cur = NULL;
1889 /*
1890 * In all cases we need to insert the new freespace in the by-size tree.
1891 */
1892 if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i)))
1893 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001894 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, error0);
Christoph Hellwig4b22a572008-10-30 16:57:40 +11001895 if ((error = xfs_btree_insert(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001897 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1899 cnt_cur = NULL;
Christoph Hellwigecb69282011-03-04 12:59:55 +00001900
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 /*
1902 * Update the freespace totals in the ag and superblock.
1903 */
Christoph Hellwigecb69282011-03-04 12:59:55 +00001904 pag = xfs_perag_get(mp, agno);
1905 error = xfs_alloc_update_counters(tp, pag, agbp, len);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001906 xfs_ag_resv_free_extent(pag, type, tp, len);
Christoph Hellwigecb69282011-03-04 12:59:55 +00001907 xfs_perag_put(pag);
1908 if (error)
1909 goto error0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
Bill O'Donnellff6d6af2015-10-12 18:21:22 +11001911 XFS_STATS_INC(mp, xs_freex);
1912 XFS_STATS_ADD(mp, xs_freeb, len);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001913
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001914 trace_xfs_free_extent(mp, agno, bno, len, type == XFS_AG_RESV_AGFL,
1915 haveleft, haveright);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917 return 0;
1918
1919 error0:
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001920 trace_xfs_free_extent(mp, agno, bno, len, type == XFS_AG_RESV_AGFL,
1921 -1, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 if (bno_cur)
1923 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
1924 if (cnt_cur)
1925 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1926 return error;
1927}
1928
1929/*
1930 * Visible (exported) allocation/free functions.
1931 * Some of these are used just by xfs_alloc_btree.c and this file.
1932 */
1933
1934/*
1935 * Compute and fill in value of m_ag_maxlevels.
1936 */
1937void
1938xfs_alloc_compute_maxlevels(
1939 xfs_mount_t *mp) /* file system mount structure */
1940{
Darrick J. Wong19b54ee2016-06-21 11:53:28 +10001941 mp->m_ag_maxlevels = xfs_btree_compute_maxlevels(mp, mp->m_alloc_mnr,
1942 (mp->m_sb.sb_agblocks + 1) / 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943}
1944
1945/*
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001946 * Find the length of the longest extent in an AG. The 'need' parameter
1947 * specifies how much space we're going to need for the AGFL and the
1948 * 'reserved' parameter tells us how many blocks in this AG are reserved for
1949 * other callers.
Dave Chinner6cc87642009-03-16 08:29:46 +01001950 */
1951xfs_extlen_t
1952xfs_alloc_longest_free_extent(
1953 struct xfs_mount *mp,
Dave Chinner50adbcb2015-06-22 10:04:31 +10001954 struct xfs_perag *pag,
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001955 xfs_extlen_t need,
1956 xfs_extlen_t reserved)
Dave Chinner6cc87642009-03-16 08:29:46 +01001957{
Dave Chinner50adbcb2015-06-22 10:04:31 +10001958 xfs_extlen_t delta = 0;
Dave Chinner6cc87642009-03-16 08:29:46 +01001959
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001960 /*
1961 * If the AGFL needs a recharge, we'll have to subtract that from the
1962 * longest extent.
1963 */
Dave Chinner6cc87642009-03-16 08:29:46 +01001964 if (need > pag->pagf_flcount)
1965 delta = need - pag->pagf_flcount;
1966
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001967 /*
1968 * If we cannot maintain others' reservations with space from the
1969 * not-longest freesp extents, we'll have to subtract /that/ from
1970 * the longest extent too.
1971 */
1972 if (pag->pagf_freeblks - pag->pagf_longest < reserved)
1973 delta += reserved - (pag->pagf_freeblks - pag->pagf_longest);
1974
1975 /*
1976 * If the longest extent is long enough to satisfy all the
1977 * reservations and AGFL rules in place, we can return this extent.
1978 */
Dave Chinner6cc87642009-03-16 08:29:46 +01001979 if (pag->pagf_longest > delta)
1980 return pag->pagf_longest - delta;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001981
1982 /* Otherwise, let the caller try for 1 block if there's space. */
Dave Chinner6cc87642009-03-16 08:29:46 +01001983 return pag->pagf_flcount > 0 || pag->pagf_longest > 0;
1984}
1985
Dave Chinner496817b2015-06-22 10:13:30 +10001986unsigned int
1987xfs_alloc_min_freelist(
1988 struct xfs_mount *mp,
1989 struct xfs_perag *pag)
1990{
1991 unsigned int min_free;
1992
1993 /* space needed by-bno freespace btree */
1994 min_free = min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_BNOi] + 1,
1995 mp->m_ag_maxlevels);
1996 /* space needed by-size freespace btree */
1997 min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1,
1998 mp->m_ag_maxlevels);
Darrick J. Wong52548852016-08-03 11:38:24 +10001999 /* space needed reverse mapping used space btree */
2000 if (xfs_sb_version_hasrmapbt(&mp->m_sb))
2001 min_free += min_t(unsigned int,
2002 pag->pagf_levels[XFS_BTNUM_RMAPi] + 1,
2003 mp->m_rmap_maxlevels);
Dave Chinner496817b2015-06-22 10:13:30 +10002004
2005 return min_free;
2006}
2007
Dave Chinner6cc87642009-03-16 08:29:46 +01002008/*
Dave Chinner72d55282015-06-22 10:04:42 +10002009 * Check if the operation we are fixing up the freelist for should go ahead or
2010 * not. If we are freeing blocks, we always allow it, otherwise the allocation
2011 * is dependent on whether the size and shape of free space available will
2012 * permit the requested allocation to take place.
2013 */
2014static bool
2015xfs_alloc_space_available(
2016 struct xfs_alloc_arg *args,
2017 xfs_extlen_t min_free,
2018 int flags)
2019{
2020 struct xfs_perag *pag = args->pag;
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002021 xfs_extlen_t alloc_len, longest;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002022 xfs_extlen_t reservation; /* blocks that are still reserved */
Dave Chinner72d55282015-06-22 10:04:42 +10002023 int available;
2024
2025 if (flags & XFS_ALLOC_FLAG_FREEING)
2026 return true;
2027
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002028 reservation = xfs_ag_resv_needed(pag, args->resv);
2029
Dave Chinner72d55282015-06-22 10:04:42 +10002030 /* do we have enough contiguous free space for the allocation? */
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002031 alloc_len = args->minlen + (args->alignment - 1) + args->minalignslop;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002032 longest = xfs_alloc_longest_free_extent(args->mp, pag, min_free,
2033 reservation);
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002034 if (longest < alloc_len)
Dave Chinner72d55282015-06-22 10:04:42 +10002035 return false;
2036
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002037 /* do we have enough free space remaining for the allocation? */
Dave Chinner72d55282015-06-22 10:04:42 +10002038 available = (int)(pag->pagf_freeblks + pag->pagf_flcount -
Christoph Hellwig54fee132017-01-09 13:44:30 -08002039 reservation - min_free - args->minleft);
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002040 if (available < (int)max(args->total, alloc_len))
Dave Chinner72d55282015-06-22 10:04:42 +10002041 return false;
2042
Christoph Hellwig54fee132017-01-09 13:44:30 -08002043 /*
2044 * Clamp maxlen to the amount of free space available for the actual
2045 * extent allocation.
2046 */
2047 if (available < (int)args->maxlen && !(flags & XFS_ALLOC_FLAG_CHECK)) {
2048 args->maxlen = available;
2049 ASSERT(args->maxlen > 0);
2050 ASSERT(args->maxlen >= args->minlen);
2051 }
2052
Dave Chinner72d55282015-06-22 10:04:42 +10002053 return true;
2054}
2055
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056/*
2057 * Decide whether to use this allocation group for this allocation.
2058 * If so, fix up the btree freelist's size.
2059 */
Darrick J. Wong2e9101d2016-01-04 16:10:42 +11002060int /* error */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061xfs_alloc_fix_freelist(
Dave Chinner396503f2015-06-22 10:13:19 +10002062 struct xfs_alloc_arg *args, /* allocation argument structure */
2063 int flags) /* XFS_ALLOC_FLAG_... */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064{
Dave Chinner396503f2015-06-22 10:13:19 +10002065 struct xfs_mount *mp = args->mp;
2066 struct xfs_perag *pag = args->pag;
2067 struct xfs_trans *tp = args->tp;
2068 struct xfs_buf *agbp = NULL;
2069 struct xfs_buf *agflbp = NULL;
2070 struct xfs_alloc_arg targs; /* local allocation arguments */
2071 xfs_agblock_t bno; /* freelist block */
2072 xfs_extlen_t need; /* total blocks needed in freelist */
Jan Karac184f852015-08-25 10:05:13 +10002073 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 if (!pag->pagf_init) {
Dave Chinner396503f2015-06-22 10:13:19 +10002076 error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
2077 if (error)
2078 goto out_no_agbp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 if (!pag->pagf_init) {
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002080 ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
2081 ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
Dave Chinner396503f2015-06-22 10:13:19 +10002082 goto out_agbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083 }
Dave Chinner396503f2015-06-22 10:13:19 +10002084 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002086 /*
Dave Chinner396503f2015-06-22 10:13:19 +10002087 * If this is a metadata preferred pag and we are user data then try
2088 * somewhere else if we are not being asked to try harder at this
2089 * point
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 */
Dave Chinner292378e2016-09-26 08:21:28 +10002091 if (pag->pagf_metadata && xfs_alloc_is_userdata(args->datatype) &&
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002092 (flags & XFS_ALLOC_FLAG_TRYLOCK)) {
2093 ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
Dave Chinner396503f2015-06-22 10:13:19 +10002094 goto out_agbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095 }
2096
Dave Chinner496817b2015-06-22 10:13:30 +10002097 need = xfs_alloc_min_freelist(mp, pag);
Christoph Hellwig54fee132017-01-09 13:44:30 -08002098 if (!xfs_alloc_space_available(args, need, flags |
2099 XFS_ALLOC_FLAG_CHECK))
Dave Chinner396503f2015-06-22 10:13:19 +10002100 goto out_agbp_relse;
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002101
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102 /*
2103 * Get the a.g. freespace buffer.
2104 * Can fail if we're not blocking on locks, and it's held.
2105 */
Dave Chinner396503f2015-06-22 10:13:19 +10002106 if (!agbp) {
2107 error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
2108 if (error)
2109 goto out_no_agbp;
2110 if (!agbp) {
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002111 ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
2112 ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
Dave Chinner396503f2015-06-22 10:13:19 +10002113 goto out_no_agbp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114 }
2115 }
Dave Chinner50adbcb2015-06-22 10:04:31 +10002116
Dave Chinner50adbcb2015-06-22 10:04:31 +10002117 /* If there isn't enough total space or single-extent, reject it. */
Dave Chinner496817b2015-06-22 10:13:30 +10002118 need = xfs_alloc_min_freelist(mp, pag);
Dave Chinner396503f2015-06-22 10:13:19 +10002119 if (!xfs_alloc_space_available(args, need, flags))
2120 goto out_agbp_relse;
Dave Chinner72d55282015-06-22 10:04:42 +10002121
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 /*
2123 * Make the freelist shorter if it's too long.
Dave Chinner50adbcb2015-06-22 10:04:31 +10002124 *
Dave Chinner396503f2015-06-22 10:13:19 +10002125 * Note that from this point onwards, we will always release the agf and
2126 * agfl buffers on error. This handles the case where we error out and
2127 * the buffers are clean or may not have been joined to the transaction
2128 * and hence need to be released manually. If they have been joined to
2129 * the transaction, then xfs_trans_brelse() will handle them
2130 * appropriately based on the recursion count and dirty state of the
2131 * buffer.
2132 *
Dave Chinner50adbcb2015-06-22 10:04:31 +10002133 * XXX (dgc): When we have lots of free space, does this buy us
2134 * anything other than extra overhead when we need to put more blocks
2135 * back on the free list? Maybe we should only do this when space is
2136 * getting low or the AGFL is more than half full?
Darrick J. Wong04f13062016-08-03 12:19:53 +10002137 *
2138 * The NOSHRINK flag prevents the AGFL from being shrunk if it's too
2139 * big; the NORMAP flag prevents AGFL expand/shrink operations from
2140 * updating the rmapbt. Both flags are used in xfs_repair while we're
2141 * rebuilding the rmapbt, and neither are used by the kernel. They're
2142 * both required to ensure that rmaps are correctly recorded for the
2143 * regenerated AGFL, bnobt, and cntbt. See repair/phase5.c and
2144 * repair/rmap.c in xfsprogs for details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 */
Darrick J. Wong04f13062016-08-03 12:19:53 +10002146 memset(&targs, 0, sizeof(targs));
2147 if (flags & XFS_ALLOC_FLAG_NORMAP)
2148 xfs_rmap_skip_owner_update(&targs.oinfo);
2149 else
2150 xfs_rmap_ag_owner(&targs.oinfo, XFS_RMAP_OWN_AG);
2151 while (!(flags & XFS_ALLOC_FLAG_NOSHRINK) && pag->pagf_flcount > need) {
Dave Chinner50adbcb2015-06-22 10:04:31 +10002152 struct xfs_buf *bp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153
David Chinner92821e22007-05-24 15:26:31 +10002154 error = xfs_alloc_get_freelist(tp, agbp, &bno, 0);
2155 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002156 goto out_agbp_relse;
Darrick J. Wong340785c2016-08-03 11:33:42 +10002157 error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1,
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002158 &targs.oinfo, XFS_AG_RESV_AGFL);
Dave Chinner50adbcb2015-06-22 10:04:31 +10002159 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002160 goto out_agbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161 bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0);
Eric Sandeen93e8bef2017-10-09 21:08:06 -07002162 if (!bp) {
2163 error = -EFSCORRUPTED;
2164 goto out_agbp_relse;
2165 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166 xfs_trans_binval(tp, bp);
2167 }
Dave Chinner50adbcb2015-06-22 10:04:31 +10002168
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169 targs.tp = tp;
2170 targs.mp = mp;
2171 targs.agbp = agbp;
2172 targs.agno = args->agno;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002173 targs.alignment = targs.minlen = targs.prod = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 targs.type = XFS_ALLOCTYPE_THIS_AG;
2175 targs.pag = pag;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002176 error = xfs_alloc_read_agfl(mp, tp, targs.agno, &agflbp);
2177 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002178 goto out_agbp_relse;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002179
2180 /* Make the freelist longer if it's too short. */
2181 while (pag->pagf_flcount < need) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182 targs.agbno = 0;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002183 targs.maxlen = need - pag->pagf_flcount;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002184 targs.resv = XFS_AG_RESV_AGFL;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002185
2186 /* Allocate as many blocks as possible at once. */
2187 error = xfs_alloc_ag_vextent(&targs);
Dave Chinner396503f2015-06-22 10:13:19 +10002188 if (error)
2189 goto out_agflbp_relse;
2190
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 /*
2192 * Stop if we run out. Won't happen if callers are obeying
2193 * the restrictions correctly. Can happen for free calls
2194 * on a completely full ag.
2195 */
Yingping Lud210a282006-06-09 14:55:18 +10002196 if (targs.agbno == NULLAGBLOCK) {
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002197 if (flags & XFS_ALLOC_FLAG_FREEING)
2198 break;
Dave Chinner396503f2015-06-22 10:13:19 +10002199 goto out_agflbp_relse;
Yingping Lud210a282006-06-09 14:55:18 +10002200 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201 /*
2202 * Put each allocated block on the list.
2203 */
2204 for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) {
David Chinner92821e22007-05-24 15:26:31 +10002205 error = xfs_alloc_put_freelist(tp, agbp,
2206 agflbp, bno, 0);
2207 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002208 goto out_agflbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 }
2210 }
Nathan Scotte63a3692006-05-08 19:51:58 +10002211 xfs_trans_brelse(tp, agflbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212 args->agbp = agbp;
2213 return 0;
Dave Chinner396503f2015-06-22 10:13:19 +10002214
2215out_agflbp_relse:
2216 xfs_trans_brelse(tp, agflbp);
2217out_agbp_relse:
2218 if (agbp)
2219 xfs_trans_brelse(tp, agbp);
2220out_no_agbp:
2221 args->agbp = NULL;
2222 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223}
2224
2225/*
2226 * Get a block from the freelist.
2227 * Returns with the buffer for the block gotten.
2228 */
2229int /* error */
2230xfs_alloc_get_freelist(
2231 xfs_trans_t *tp, /* transaction pointer */
2232 xfs_buf_t *agbp, /* buffer containing the agf structure */
David Chinner92821e22007-05-24 15:26:31 +10002233 xfs_agblock_t *bnop, /* block address retrieved from freelist */
2234 int btreeblk) /* destination is a AGF btree */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235{
2236 xfs_agf_t *agf; /* a.g. freespace structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */
2238 xfs_agblock_t bno; /* block number returned */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002239 __be32 *agfl_bno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240 int error;
David Chinner92821e22007-05-24 15:26:31 +10002241 int logflags;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002242 xfs_mount_t *mp = tp->t_mountp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 xfs_perag_t *pag; /* per allocation group data */
2244
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 /*
2246 * Freelist is empty, give up.
2247 */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002248 agf = XFS_BUF_TO_AGF(agbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249 if (!agf->agf_flcount) {
2250 *bnop = NULLAGBLOCK;
2251 return 0;
2252 }
2253 /*
2254 * Read the array of free blocks.
2255 */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002256 error = xfs_alloc_read_agfl(mp, tp, be32_to_cpu(agf->agf_seqno),
2257 &agflbp);
2258 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 return error;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002260
2261
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262 /*
2263 * Get the block number and update the data structures.
2264 */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002265 agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
2266 bno = be32_to_cpu(agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002267 be32_add_cpu(&agf->agf_flfirst, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268 xfs_trans_brelse(tp, agflbp);
Christoph Hellwig16259e72005-11-02 15:11:25 +11002269 if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270 agf->agf_flfirst = 0;
Dave Chinnera862e0f2010-01-11 11:47:41 +00002271
2272 pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002273 be32_add_cpu(&agf->agf_flcount, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274 xfs_trans_agflist_delta(tp, -1);
2275 pag->pagf_flcount--;
Dave Chinnera862e0f2010-01-11 11:47:41 +00002276 xfs_perag_put(pag);
David Chinner92821e22007-05-24 15:26:31 +10002277
2278 logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
2279 if (btreeblk) {
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002280 be32_add_cpu(&agf->agf_btreeblks, 1);
David Chinner92821e22007-05-24 15:26:31 +10002281 pag->pagf_btreeblks++;
2282 logflags |= XFS_AGF_BTREEBLKS;
2283 }
2284
David Chinner92821e22007-05-24 15:26:31 +10002285 xfs_alloc_log_agf(tp, agbp, logflags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286 *bnop = bno;
2287
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 return 0;
2289}
2290
2291/*
2292 * Log the given fields from the agf structure.
2293 */
2294void
2295xfs_alloc_log_agf(
2296 xfs_trans_t *tp, /* transaction pointer */
2297 xfs_buf_t *bp, /* buffer for a.g. freelist header */
2298 int fields) /* mask of fields to be logged (XFS_AGF_...) */
2299{
2300 int first; /* first byte offset */
2301 int last; /* last byte offset */
2302 static const short offsets[] = {
2303 offsetof(xfs_agf_t, agf_magicnum),
2304 offsetof(xfs_agf_t, agf_versionnum),
2305 offsetof(xfs_agf_t, agf_seqno),
2306 offsetof(xfs_agf_t, agf_length),
2307 offsetof(xfs_agf_t, agf_roots[0]),
2308 offsetof(xfs_agf_t, agf_levels[0]),
2309 offsetof(xfs_agf_t, agf_flfirst),
2310 offsetof(xfs_agf_t, agf_fllast),
2311 offsetof(xfs_agf_t, agf_flcount),
2312 offsetof(xfs_agf_t, agf_freeblks),
2313 offsetof(xfs_agf_t, agf_longest),
David Chinner92821e22007-05-24 15:26:31 +10002314 offsetof(xfs_agf_t, agf_btreeblks),
Dave Chinner4e0e6042013-04-03 16:11:13 +11002315 offsetof(xfs_agf_t, agf_uuid),
Darrick J. Wongf32866fd2016-08-17 08:31:49 +10002316 offsetof(xfs_agf_t, agf_rmap_blocks),
Darrick J. Wongbdf28632016-10-03 09:11:19 -07002317 offsetof(xfs_agf_t, agf_refcount_blocks),
2318 offsetof(xfs_agf_t, agf_refcount_root),
2319 offsetof(xfs_agf_t, agf_refcount_level),
Darrick J. Wongda1f0392016-08-26 15:59:31 +10002320 /* needed so that we don't log the whole rest of the structure: */
2321 offsetof(xfs_agf_t, agf_spare64),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 sizeof(xfs_agf_t)
2323 };
2324
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002325 trace_xfs_agf(tp->t_mountp, XFS_BUF_TO_AGF(bp), fields, _RET_IP_);
2326
Dave Chinner61fe1352013-04-03 16:11:30 +11002327 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGF_BUF);
Dave Chinner4e0e6042013-04-03 16:11:13 +11002328
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 xfs_btree_offsets(fields, offsets, XFS_AGF_NUM_BITS, &first, &last);
2330 xfs_trans_log_buf(tp, bp, (uint)first, (uint)last);
2331}
2332
2333/*
2334 * Interface for inode allocation to force the pag data to be initialized.
2335 */
2336int /* error */
2337xfs_alloc_pagf_init(
2338 xfs_mount_t *mp, /* file system mount structure */
2339 xfs_trans_t *tp, /* transaction pointer */
2340 xfs_agnumber_t agno, /* allocation group number */
2341 int flags) /* XFS_ALLOC_FLAGS_... */
2342{
2343 xfs_buf_t *bp;
2344 int error;
2345
2346 if ((error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp)))
2347 return error;
2348 if (bp)
2349 xfs_trans_brelse(tp, bp);
2350 return 0;
2351}
2352
2353/*
2354 * Put the block on the freelist for the allocation group.
2355 */
2356int /* error */
2357xfs_alloc_put_freelist(
2358 xfs_trans_t *tp, /* transaction pointer */
2359 xfs_buf_t *agbp, /* buffer for a.g. freelist header */
2360 xfs_buf_t *agflbp,/* buffer for a.g. free block array */
David Chinner92821e22007-05-24 15:26:31 +10002361 xfs_agblock_t bno, /* block being freed */
2362 int btreeblk) /* block came from a AGF btree */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363{
2364 xfs_agf_t *agf; /* a.g. freespace structure */
Christoph Hellwige2101002006-09-28 10:56:51 +10002365 __be32 *blockp;/* pointer to array entry */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366 int error;
David Chinner92821e22007-05-24 15:26:31 +10002367 int logflags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368 xfs_mount_t *mp; /* mount structure */
2369 xfs_perag_t *pag; /* per allocation group data */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002370 __be32 *agfl_bno;
2371 int startoff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372
2373 agf = XFS_BUF_TO_AGF(agbp);
2374 mp = tp->t_mountp;
2375
2376 if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp,
Christoph Hellwig16259e72005-11-02 15:11:25 +11002377 be32_to_cpu(agf->agf_seqno), &agflbp)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378 return error;
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002379 be32_add_cpu(&agf->agf_fllast, 1);
Christoph Hellwig16259e72005-11-02 15:11:25 +11002380 if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002381 agf->agf_fllast = 0;
Dave Chinnera862e0f2010-01-11 11:47:41 +00002382
2383 pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002384 be32_add_cpu(&agf->agf_flcount, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385 xfs_trans_agflist_delta(tp, 1);
2386 pag->pagf_flcount++;
David Chinner92821e22007-05-24 15:26:31 +10002387
2388 logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
2389 if (btreeblk) {
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002390 be32_add_cpu(&agf->agf_btreeblks, -1);
David Chinner92821e22007-05-24 15:26:31 +10002391 pag->pagf_btreeblks--;
2392 logflags |= XFS_AGF_BTREEBLKS;
2393 }
Dave Chinnera862e0f2010-01-11 11:47:41 +00002394 xfs_perag_put(pag);
David Chinner92821e22007-05-24 15:26:31 +10002395
David Chinner92821e22007-05-24 15:26:31 +10002396 xfs_alloc_log_agf(tp, agbp, logflags);
2397
Christoph Hellwig16259e72005-11-02 15:11:25 +11002398 ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002399
2400 agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
2401 blockp = &agfl_bno[be32_to_cpu(agf->agf_fllast)];
Christoph Hellwige2101002006-09-28 10:56:51 +10002402 *blockp = cpu_to_be32(bno);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002403 startoff = (char *)blockp - (char *)agflbp->b_addr;
2404
David Chinner92821e22007-05-24 15:26:31 +10002405 xfs_alloc_log_agf(tp, agbp, logflags);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002406
Dave Chinner61fe1352013-04-03 16:11:30 +11002407 xfs_trans_buf_set_type(tp, agflbp, XFS_BLFT_AGFL_BUF);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002408 xfs_trans_log_buf(tp, agflbp, startoff,
2409 startoff + sizeof(xfs_agblock_t) - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410 return 0;
2411}
2412
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002413static xfs_failaddr_t
Dave Chinner612cfbf2012-11-14 17:52:32 +11002414xfs_agf_verify(
Darrick J. Wongb5572592018-01-08 10:51:08 -08002415 struct xfs_buf *bp)
2416{
2417 struct xfs_mount *mp = bp->b_target->bt_mount;
2418 struct xfs_agf *agf = XFS_BUF_TO_AGF(bp);
Dave Chinner5d5f5272012-11-14 17:44:56 +11002419
Brian Fostera45086e2015-10-12 15:59:25 +11002420 if (xfs_sb_version_hascrc(&mp->m_sb)) {
2421 if (!uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002422 return __this_address;
Brian Fostera45086e2015-10-12 15:59:25 +11002423 if (!xfs_log_check_lsn(mp,
2424 be64_to_cpu(XFS_BUF_TO_AGF(bp)->agf_lsn)))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002425 return __this_address;
Brian Fostera45086e2015-10-12 15:59:25 +11002426 }
Dave Chinner5d5f5272012-11-14 17:44:56 +11002427
Dave Chinner4e0e6042013-04-03 16:11:13 +11002428 if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
2429 XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
2430 be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
2431 be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) &&
2432 be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) &&
2433 be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002434 return __this_address;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002435
Darrick J. Wongd2a047f2016-12-05 12:32:50 +11002436 if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
2437 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
2438 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
Eric Sandeene1b05722014-09-09 11:47:24 +10002439 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002440 return __this_address;
Eric Sandeene1b05722014-09-09 11:47:24 +10002441
Darrick J. Wongb8704942016-08-03 11:30:32 +10002442 if (xfs_sb_version_hasrmapbt(&mp->m_sb) &&
Darrick J. Wongd2a047f2016-12-05 12:32:50 +11002443 (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 ||
2444 be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002445 return __this_address;
Darrick J. Wongb8704942016-08-03 11:30:32 +10002446
Dave Chinner5d5f5272012-11-14 17:44:56 +11002447 /*
2448 * during growfs operations, the perag is not fully initialised,
2449 * so we can't use it for any useful checking. growfs ensures we can't
2450 * use it by using uncached buffers that don't have the perag attached
2451 * so we can detect and avoid this problem.
2452 */
Dave Chinner4e0e6042013-04-03 16:11:13 +11002453 if (bp->b_pag && be32_to_cpu(agf->agf_seqno) != bp->b_pag->pag_agno)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002454 return __this_address;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002455
Dave Chinner4e0e6042013-04-03 16:11:13 +11002456 if (xfs_sb_version_haslazysbcount(&mp->m_sb) &&
2457 be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002458 return __this_address;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002459
Darrick J. Wong46eeb522016-10-03 09:11:16 -07002460 if (xfs_sb_version_hasreflink(&mp->m_sb) &&
Darrick J. Wongd2a047f2016-12-05 12:32:50 +11002461 (be32_to_cpu(agf->agf_refcount_level) < 1 ||
2462 be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002463 return __this_address;
Darrick J. Wong46eeb522016-10-03 09:11:16 -07002464
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002465 return NULL;
Dave Chinner4e0e6042013-04-03 16:11:13 +11002466
Dave Chinner612cfbf2012-11-14 17:52:32 +11002467}
Dave Chinner5d5f5272012-11-14 17:44:56 +11002468
Dave Chinner1813dd62012-11-14 17:54:40 +11002469static void
2470xfs_agf_read_verify(
Dave Chinner612cfbf2012-11-14 17:52:32 +11002471 struct xfs_buf *bp)
2472{
Dave Chinner4e0e6042013-04-03 16:11:13 +11002473 struct xfs_mount *mp = bp->b_target->bt_mount;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002474 xfs_failaddr_t fa;
Dave Chinner4e0e6042013-04-03 16:11:13 +11002475
Eric Sandeence5028c2014-02-27 15:23:10 +11002476 if (xfs_sb_version_hascrc(&mp->m_sb) &&
2477 !xfs_buf_verify_cksum(bp, XFS_AGF_CRC_OFF))
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002478 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
2479 else {
Darrick J. Wongb5572592018-01-08 10:51:08 -08002480 fa = xfs_agf_verify(bp);
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002481 if (XFS_TEST_ERROR(fa, mp, XFS_ERRTAG_ALLOC_READ_AGF))
2482 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
2483 }
Dave Chinner612cfbf2012-11-14 17:52:32 +11002484}
2485
Dave Chinnerb0f539d2012-11-14 17:53:49 +11002486static void
Dave Chinner1813dd62012-11-14 17:54:40 +11002487xfs_agf_write_verify(
Dave Chinner612cfbf2012-11-14 17:52:32 +11002488 struct xfs_buf *bp)
2489{
Dave Chinner4e0e6042013-04-03 16:11:13 +11002490 struct xfs_mount *mp = bp->b_target->bt_mount;
2491 struct xfs_buf_log_item *bip = bp->b_fspriv;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002492 xfs_failaddr_t fa;
Dave Chinner4e0e6042013-04-03 16:11:13 +11002493
Darrick J. Wongb5572592018-01-08 10:51:08 -08002494 fa = xfs_agf_verify(bp);
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002495 if (fa) {
2496 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
Dave Chinner4e0e6042013-04-03 16:11:13 +11002497 return;
2498 }
2499
2500 if (!xfs_sb_version_hascrc(&mp->m_sb))
2501 return;
2502
2503 if (bip)
2504 XFS_BUF_TO_AGF(bp)->agf_lsn = cpu_to_be64(bip->bli_item.li_lsn);
2505
Eric Sandeenf1dbcd72014-02-27 15:18:23 +11002506 xfs_buf_update_cksum(bp, XFS_AGF_CRC_OFF);
Dave Chinner5d5f5272012-11-14 17:44:56 +11002507}
2508
Dave Chinner1813dd62012-11-14 17:54:40 +11002509const struct xfs_buf_ops xfs_agf_buf_ops = {
Eric Sandeen233135b2016-01-04 16:10:19 +11002510 .name = "xfs_agf",
Dave Chinner1813dd62012-11-14 17:54:40 +11002511 .verify_read = xfs_agf_read_verify,
2512 .verify_write = xfs_agf_write_verify,
Darrick J. Wongb5572592018-01-08 10:51:08 -08002513 .verify_struct = xfs_agf_verify,
Dave Chinner1813dd62012-11-14 17:54:40 +11002514};
2515
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516/*
2517 * Read in the allocation group header (free/alloc section).
2518 */
2519int /* error */
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002520xfs_read_agf(
2521 struct xfs_mount *mp, /* mount point structure */
2522 struct xfs_trans *tp, /* transaction pointer */
2523 xfs_agnumber_t agno, /* allocation group number */
2524 int flags, /* XFS_BUF_ */
2525 struct xfs_buf **bpp) /* buffer for the ag freelist header */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527 int error;
2528
Dave Chinnerd1230312013-11-01 15:27:19 +11002529 trace_xfs_read_agf(mp, agno);
2530
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531 ASSERT(agno != NULLAGNUMBER);
2532 error = xfs_trans_read_buf(
2533 mp, tp, mp->m_ddev_targp,
2534 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
Dave Chinner1813dd62012-11-14 17:54:40 +11002535 XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 if (error)
2537 return error;
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002538 if (!*bpp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 return 0;
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002540
Chandra Seetharaman5a52c2a582011-07-22 23:39:51 +00002541 ASSERT(!(*bpp)->b_error);
Christoph Hellwig38f23232011-10-10 16:52:45 +00002542 xfs_buf_set_ref(*bpp, XFS_AGF_REF);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002543 return 0;
2544}
2545
2546/*
2547 * Read in the allocation group header (free/alloc section).
2548 */
2549int /* error */
2550xfs_alloc_read_agf(
2551 struct xfs_mount *mp, /* mount point structure */
2552 struct xfs_trans *tp, /* transaction pointer */
2553 xfs_agnumber_t agno, /* allocation group number */
2554 int flags, /* XFS_ALLOC_FLAG_... */
2555 struct xfs_buf **bpp) /* buffer for the ag freelist header */
2556{
2557 struct xfs_agf *agf; /* ag freelist header */
2558 struct xfs_perag *pag; /* per allocation group data */
2559 int error;
2560
Dave Chinnerd1230312013-11-01 15:27:19 +11002561 trace_xfs_alloc_read_agf(mp, agno);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002562
Dave Chinnerd1230312013-11-01 15:27:19 +11002563 ASSERT(agno != NULLAGNUMBER);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002564 error = xfs_read_agf(mp, tp, agno,
Christoph Hellwig0cadda12010-01-19 09:56:44 +00002565 (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0,
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002566 bpp);
2567 if (error)
2568 return error;
2569 if (!*bpp)
2570 return 0;
Chandra Seetharaman5a52c2a582011-07-22 23:39:51 +00002571 ASSERT(!(*bpp)->b_error);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002572
2573 agf = XFS_BUF_TO_AGF(*bpp);
Dave Chinnera862e0f2010-01-11 11:47:41 +00002574 pag = xfs_perag_get(mp, agno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575 if (!pag->pagf_init) {
Christoph Hellwig16259e72005-11-02 15:11:25 +11002576 pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
David Chinner92821e22007-05-24 15:26:31 +10002577 pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
Christoph Hellwig16259e72005-11-02 15:11:25 +11002578 pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
2579 pag->pagf_longest = be32_to_cpu(agf->agf_longest);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580 pag->pagf_levels[XFS_BTNUM_BNOi] =
Christoph Hellwig16259e72005-11-02 15:11:25 +11002581 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582 pag->pagf_levels[XFS_BTNUM_CNTi] =
Christoph Hellwig16259e72005-11-02 15:11:25 +11002583 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
Darrick J. Wongb8704942016-08-03 11:30:32 +10002584 pag->pagf_levels[XFS_BTNUM_RMAPi] =
2585 be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]);
Darrick J. Wong46eeb522016-10-03 09:11:16 -07002586 pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
Eric Sandeen007c61c2007-10-11 17:43:56 +10002587 spin_lock_init(&pag->pagb_lock);
Dave Chinnere57336f2010-01-11 11:47:49 +00002588 pag->pagb_count = 0;
Dave Chinnered3b4d62010-05-21 12:07:08 +10002589 pag->pagb_tree = RB_ROOT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590 pag->pagf_init = 1;
2591 }
2592#ifdef DEBUG
2593 else if (!XFS_FORCED_SHUTDOWN(mp)) {
Christoph Hellwig16259e72005-11-02 15:11:25 +11002594 ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks));
Barry Naujok89b28392008-10-30 17:05:49 +11002595 ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks));
Christoph Hellwig16259e72005-11-02 15:11:25 +11002596 ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
2597 ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598 ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] ==
Christoph Hellwig16259e72005-11-02 15:11:25 +11002599 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 ASSERT(pag->pagf_levels[XFS_BTNUM_CNTi] ==
Christoph Hellwig16259e72005-11-02 15:11:25 +11002601 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602 }
2603#endif
Dave Chinnera862e0f2010-01-11 11:47:41 +00002604 xfs_perag_put(pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605 return 0;
2606}
2607
2608/*
2609 * Allocate an extent (variable-size).
2610 * Depending on the allocation type, we either look in a single allocation
2611 * group or loop over the allocation groups to find the result.
2612 */
2613int /* error */
Dave Chinnere04426b2012-10-05 11:06:59 +10002614xfs_alloc_vextent(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615 xfs_alloc_arg_t *args) /* allocation argument structure */
2616{
2617 xfs_agblock_t agsize; /* allocation group size */
2618 int error;
2619 int flags; /* XFS_ALLOC_FLAG_... locking flags */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620 xfs_mount_t *mp; /* mount structure pointer */
2621 xfs_agnumber_t sagno; /* starting allocation group number */
2622 xfs_alloctype_t type; /* input allocation type */
2623 int bump_rotor = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624 xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */
2625
2626 mp = args->mp;
2627 type = args->otype = args->type;
2628 args->agbno = NULLAGBLOCK;
2629 /*
2630 * Just fix this up, for the case where the last a.g. is shorter
2631 * (or there's only one a.g.) and the caller couldn't easily figure
2632 * that out (xfs_bmap_alloc).
2633 */
2634 agsize = mp->m_sb.sb_agblocks;
2635 if (args->maxlen > agsize)
2636 args->maxlen = agsize;
2637 if (args->alignment == 0)
2638 args->alignment = 1;
2639 ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_sb.sb_agcount);
2640 ASSERT(XFS_FSB_TO_AGBNO(mp, args->fsbno) < agsize);
2641 ASSERT(args->minlen <= args->maxlen);
2642 ASSERT(args->minlen <= agsize);
2643 ASSERT(args->mod < args->prod);
2644 if (XFS_FSB_TO_AGNO(mp, args->fsbno) >= mp->m_sb.sb_agcount ||
2645 XFS_FSB_TO_AGBNO(mp, args->fsbno) >= agsize ||
2646 args->minlen > args->maxlen || args->minlen > agsize ||
2647 args->mod >= args->prod) {
2648 args->fsbno = NULLFSBLOCK;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002649 trace_xfs_alloc_vextent_badargs(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 return 0;
2651 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652
2653 switch (type) {
2654 case XFS_ALLOCTYPE_THIS_AG:
2655 case XFS_ALLOCTYPE_NEAR_BNO:
2656 case XFS_ALLOCTYPE_THIS_BNO:
2657 /*
2658 * These three force us into a single a.g.
2659 */
2660 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
Dave Chinnera862e0f2010-01-11 11:47:41 +00002661 args->pag = xfs_perag_get(mp, args->agno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 error = xfs_alloc_fix_freelist(args, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 if (error) {
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002664 trace_xfs_alloc_vextent_nofix(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665 goto error0;
2666 }
2667 if (!args->agbp) {
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002668 trace_xfs_alloc_vextent_noagbp(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 break;
2670 }
2671 args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno);
2672 if ((error = xfs_alloc_ag_vextent(args)))
2673 goto error0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 break;
2675 case XFS_ALLOCTYPE_START_BNO:
2676 /*
2677 * Try near allocation first, then anywhere-in-ag after
2678 * the first a.g. fails.
2679 */
Dave Chinner292378e2016-09-26 08:21:28 +10002680 if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681 (mp->m_flags & XFS_MOUNT_32BITINODES)) {
2682 args->fsbno = XFS_AGB_TO_FSB(mp,
2683 ((mp->m_agfrotor / rotorstep) %
2684 mp->m_sb.sb_agcount), 0);
2685 bump_rotor = 1;
2686 }
2687 args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno);
2688 args->type = XFS_ALLOCTYPE_NEAR_BNO;
2689 /* FALLTHROUGH */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690 case XFS_ALLOCTYPE_FIRST_AG:
2691 /*
2692 * Rotate through the allocation groups looking for a winner.
2693 */
Christoph Hellwig8d242e92017-02-17 08:21:15 -08002694 if (type == XFS_ALLOCTYPE_FIRST_AG) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002695 /*
2696 * Start with allocation group given by bno.
2697 */
2698 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
2699 args->type = XFS_ALLOCTYPE_THIS_AG;
2700 sagno = 0;
2701 flags = 0;
2702 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703 /*
2704 * Start with the given allocation group.
2705 */
2706 args->agno = sagno = XFS_FSB_TO_AGNO(mp, args->fsbno);
2707 flags = XFS_ALLOC_FLAG_TRYLOCK;
2708 }
2709 /*
2710 * Loop over allocation groups twice; first time with
2711 * trylock set, second time without.
2712 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713 for (;;) {
Dave Chinnera862e0f2010-01-11 11:47:41 +00002714 args->pag = xfs_perag_get(mp, args->agno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715 error = xfs_alloc_fix_freelist(args, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716 if (error) {
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002717 trace_xfs_alloc_vextent_nofix(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002718 goto error0;
2719 }
2720 /*
2721 * If we get a buffer back then the allocation will fly.
2722 */
2723 if (args->agbp) {
2724 if ((error = xfs_alloc_ag_vextent(args)))
2725 goto error0;
2726 break;
2727 }
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002728
2729 trace_xfs_alloc_vextent_loopfailed(args);
2730
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731 /*
2732 * Didn't work, figure out the next iteration.
2733 */
2734 if (args->agno == sagno &&
2735 type == XFS_ALLOCTYPE_START_BNO)
2736 args->type = XFS_ALLOCTYPE_THIS_AG;
Yingping Lud210a282006-06-09 14:55:18 +10002737 /*
2738 * For the first allocation, we can try any AG to get
2739 * space. However, if we already have allocated a
2740 * block, we don't want to try AGs whose number is below
2741 * sagno. Otherwise, we may end up with out-of-order
2742 * locking of AGF, which might cause deadlock.
2743 */
2744 if (++(args->agno) == mp->m_sb.sb_agcount) {
2745 if (args->firstblock != NULLFSBLOCK)
2746 args->agno = sagno;
2747 else
2748 args->agno = 0;
2749 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750 /*
2751 * Reached the starting a.g., must either be done
2752 * or switch to non-trylock mode.
2753 */
2754 if (args->agno == sagno) {
Christoph Hellwig255c5162017-01-09 13:36:19 -08002755 if (flags == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 args->agbno = NULLAGBLOCK;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002757 trace_xfs_alloc_vextent_allfailed(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758 break;
2759 }
Christoph Hellwig255c5162017-01-09 13:36:19 -08002760
2761 flags = 0;
2762 if (type == XFS_ALLOCTYPE_START_BNO) {
2763 args->agbno = XFS_FSB_TO_AGBNO(mp,
2764 args->fsbno);
2765 args->type = XFS_ALLOCTYPE_NEAR_BNO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766 }
2767 }
Dave Chinnera862e0f2010-01-11 11:47:41 +00002768 xfs_perag_put(args->pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002769 }
Christoph Hellwig8d242e92017-02-17 08:21:15 -08002770 if (bump_rotor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771 if (args->agno == sagno)
2772 mp->m_agfrotor = (mp->m_agfrotor + 1) %
2773 (mp->m_sb.sb_agcount * rotorstep);
2774 else
2775 mp->m_agfrotor = (args->agno * rotorstep + 1) %
2776 (mp->m_sb.sb_agcount * rotorstep);
2777 }
2778 break;
2779 default:
2780 ASSERT(0);
2781 /* NOTREACHED */
2782 }
2783 if (args->agbno == NULLAGBLOCK)
2784 args->fsbno = NULLFSBLOCK;
2785 else {
2786 args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno);
2787#ifdef DEBUG
2788 ASSERT(args->len >= args->minlen);
2789 ASSERT(args->len <= args->maxlen);
2790 ASSERT(args->agbno % args->alignment == 0);
2791 XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno),
2792 args->len);
2793#endif
Dave Chinner3fbbbea2015-11-03 12:27:22 +11002794
2795 /* Zero the extent if we were asked to do so */
Dave Chinner292378e2016-09-26 08:21:28 +10002796 if (args->datatype & XFS_ALLOC_USERDATA_ZERO) {
Dave Chinner3fbbbea2015-11-03 12:27:22 +11002797 error = xfs_zero_extent(args->ip, args->fsbno, args->len);
2798 if (error)
2799 goto error0;
2800 }
2801
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802 }
Dave Chinnera862e0f2010-01-11 11:47:41 +00002803 xfs_perag_put(args->pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002804 return 0;
2805error0:
Dave Chinnera862e0f2010-01-11 11:47:41 +00002806 xfs_perag_put(args->pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807 return error;
2808}
2809
Dave Chinner4d89e202016-06-21 11:53:28 +10002810/* Ensure that the freelist is at full capacity. */
2811int
2812xfs_free_extent_fix_freelist(
2813 struct xfs_trans *tp,
2814 xfs_agnumber_t agno,
2815 struct xfs_buf **agbp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816{
Dave Chinner4d89e202016-06-21 11:53:28 +10002817 struct xfs_alloc_arg args;
2818 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819
Dave Chinner4d89e202016-06-21 11:53:28 +10002820 memset(&args, 0, sizeof(struct xfs_alloc_arg));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 args.tp = tp;
2822 args.mp = tp->t_mountp;
Dave Chinner4d89e202016-06-21 11:53:28 +10002823 args.agno = agno;
Dave Chinnerbe65b182011-04-08 12:45:07 +10002824
2825 /*
2826 * validate that the block number is legal - the enables us to detect
2827 * and handle a silent filesystem corruption rather than crashing.
2828 */
Dave Chinnerbe65b182011-04-08 12:45:07 +10002829 if (args.agno >= args.mp->m_sb.sb_agcount)
Dave Chinner24513372014-06-25 14:58:08 +10002830 return -EFSCORRUPTED;
Dave Chinnerbe65b182011-04-08 12:45:07 +10002831
Dave Chinnera862e0f2010-01-11 11:47:41 +00002832 args.pag = xfs_perag_get(args.mp, args.agno);
Dave Chinnerbe65b182011-04-08 12:45:07 +10002833 ASSERT(args.pag);
2834
2835 error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING);
2836 if (error)
Dave Chinner4d89e202016-06-21 11:53:28 +10002837 goto out;
2838
2839 *agbp = args.agbp;
2840out:
2841 xfs_perag_put(args.pag);
2842 return error;
2843}
2844
2845/*
2846 * Free an extent.
2847 * Just break up the extent address and hand off to xfs_free_ag_extent
2848 * after fixing up the freelist.
2849 */
2850int /* error */
2851xfs_free_extent(
2852 struct xfs_trans *tp, /* transaction pointer */
2853 xfs_fsblock_t bno, /* starting block number of extent */
Darrick J. Wong340785c2016-08-03 11:33:42 +10002854 xfs_extlen_t len, /* length of extent */
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002855 struct xfs_owner_info *oinfo, /* extent owner */
2856 enum xfs_ag_resv_type type) /* block reservation type */
Dave Chinner4d89e202016-06-21 11:53:28 +10002857{
2858 struct xfs_mount *mp = tp->t_mountp;
2859 struct xfs_buf *agbp;
2860 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno);
2861 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno);
2862 int error;
2863
2864 ASSERT(len != 0);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002865 ASSERT(type != XFS_AG_RESV_AGFL);
Dave Chinner4d89e202016-06-21 11:53:28 +10002866
Darrick J. Wongba9e7802016-08-03 11:26:33 +10002867 if (XFS_TEST_ERROR(false, mp,
Darrick J. Wong9e24cfd2017-06-20 17:54:47 -07002868 XFS_ERRTAG_FREE_EXTENT))
Darrick J. Wongba9e7802016-08-03 11:26:33 +10002869 return -EIO;
2870
Dave Chinner4d89e202016-06-21 11:53:28 +10002871 error = xfs_free_extent_fix_freelist(tp, agno, &agbp);
2872 if (error)
2873 return error;
2874
2875 XFS_WANT_CORRUPTED_GOTO(mp, agbno < mp->m_sb.sb_agblocks, err);
Dave Chinnerbe65b182011-04-08 12:45:07 +10002876
2877 /* validate the extent size is legal now we have the agf locked */
Dave Chinner4d89e202016-06-21 11:53:28 +10002878 XFS_WANT_CORRUPTED_GOTO(mp,
2879 agbno + len <= be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_length),
2880 err);
Dave Chinnerbe65b182011-04-08 12:45:07 +10002881
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002882 error = xfs_free_ag_extent(tp, agbp, agno, agbno, len, oinfo, type);
Dave Chinner4d89e202016-06-21 11:53:28 +10002883 if (error)
2884 goto err;
2885
2886 xfs_extent_busy_insert(tp, agno, agbno, len, 0);
2887 return 0;
2888
2889err:
2890 xfs_trans_brelse(tp, agbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891 return error;
2892}
Darrick J. Wong2d520bf2017-03-28 14:56:35 -07002893
2894struct xfs_alloc_query_range_info {
2895 xfs_alloc_query_range_fn fn;
2896 void *priv;
2897};
2898
2899/* Format btree record and pass to our callback. */
2900STATIC int
2901xfs_alloc_query_range_helper(
2902 struct xfs_btree_cur *cur,
2903 union xfs_btree_rec *rec,
2904 void *priv)
2905{
2906 struct xfs_alloc_query_range_info *query = priv;
2907 struct xfs_alloc_rec_incore irec;
2908
2909 irec.ar_startblock = be32_to_cpu(rec->alloc.ar_startblock);
2910 irec.ar_blockcount = be32_to_cpu(rec->alloc.ar_blockcount);
2911 return query->fn(cur, &irec, query->priv);
2912}
2913
2914/* Find all free space within a given range of blocks. */
2915int
2916xfs_alloc_query_range(
2917 struct xfs_btree_cur *cur,
2918 struct xfs_alloc_rec_incore *low_rec,
2919 struct xfs_alloc_rec_incore *high_rec,
2920 xfs_alloc_query_range_fn fn,
2921 void *priv)
2922{
2923 union xfs_btree_irec low_brec;
2924 union xfs_btree_irec high_brec;
2925 struct xfs_alloc_query_range_info query;
2926
2927 ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
2928 low_brec.a = *low_rec;
2929 high_brec.a = *high_rec;
2930 query.priv = priv;
2931 query.fn = fn;
2932 return xfs_btree_query_range(cur, &low_brec, &high_brec,
2933 xfs_alloc_query_range_helper, &query);
2934}
Darrick J. Wonge9a25992017-03-28 14:56:35 -07002935
2936/* Find all free space records. */
2937int
2938xfs_alloc_query_all(
2939 struct xfs_btree_cur *cur,
2940 xfs_alloc_query_range_fn fn,
2941 void *priv)
2942{
2943 struct xfs_alloc_query_range_info query;
2944
2945 ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
2946 query.priv = priv;
2947 query.fn = fn;
2948 return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query);
2949}
Darrick J. Wong21ec5412017-10-17 21:37:32 -07002950
2951/* Find the size of the AG, in blocks. */
2952xfs_agblock_t
2953xfs_ag_block_count(
2954 struct xfs_mount *mp,
2955 xfs_agnumber_t agno)
2956{
2957 ASSERT(agno < mp->m_sb.sb_agcount);
2958
2959 if (agno < mp->m_sb.sb_agcount - 1)
2960 return mp->m_sb.sb_agblocks;
2961 return mp->m_sb.sb_dblocks - (agno * mp->m_sb.sb_agblocks);
2962}
2963
2964/*
2965 * Verify that an AG block number pointer neither points outside the AG
2966 * nor points at static metadata.
2967 */
2968bool
2969xfs_verify_agbno(
2970 struct xfs_mount *mp,
2971 xfs_agnumber_t agno,
2972 xfs_agblock_t agbno)
2973{
2974 xfs_agblock_t eoag;
2975
2976 eoag = xfs_ag_block_count(mp, agno);
2977 if (agbno >= eoag)
2978 return false;
2979 if (agbno <= XFS_AGFL_BLOCK(mp))
2980 return false;
2981 return true;
2982}
2983
2984/*
2985 * Verify that an FS block number pointer neither points outside the
2986 * filesystem nor points at static AG metadata.
2987 */
2988bool
2989xfs_verify_fsbno(
2990 struct xfs_mount *mp,
2991 xfs_fsblock_t fsbno)
2992{
2993 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno);
2994
2995 if (agno >= mp->m_sb.sb_agcount)
2996 return false;
2997 return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno));
2998}