blob: 6bace8cb47dab11c88d82468895807e9c3937131 [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
Eric Sandeence748ea2015-07-29 11:53:31 +1000531 if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800532 return __this_address;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100533 if (be32_to_cpu(agfl->agfl_magicnum) != XFS_AGFL_MAGIC)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800534 return __this_address;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100535 /*
536 * during growfs operations, the perag is not fully initialised,
537 * so we can't use it for any useful checking. growfs ensures we can't
538 * use it by using uncached buffers that don't have the perag attached
539 * so we can detect and avoid this problem.
540 */
541 if (bp->b_pag && be32_to_cpu(agfl->agfl_seqno) != bp->b_pag->pag_agno)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800542 return __this_address;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100543
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100544 for (i = 0; i < XFS_AGFL_SIZE(mp); i++) {
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100545 if (be32_to_cpu(agfl->agfl_bno[i]) != NULLAGBLOCK &&
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100546 be32_to_cpu(agfl->agfl_bno[i]) >= mp->m_sb.sb_agblocks)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800547 return __this_address;
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100548 }
Brian Fostera45086e2015-10-12 15:59:25 +1100549
Darrick J. Wonga6a781a2018-01-08 10:51:03 -0800550 if (!xfs_log_check_lsn(mp, be64_to_cpu(XFS_BUF_TO_AGFL(bp)->agfl_lsn)))
551 return __this_address;
552 return NULL;
Dave Chinner612cfbf2012-11-14 17:52:32 +1100553}
554
Dave Chinnerb0f539d2012-11-14 17:53:49 +1100555static void
Dave Chinner612cfbf2012-11-14 17:52:32 +1100556xfs_agfl_read_verify(
557 struct xfs_buf *bp)
558{
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100559 struct xfs_mount *mp = bp->b_target->bt_mount;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800560 xfs_failaddr_t fa;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100561
562 /*
563 * There is no verification of non-crc AGFLs because mkfs does not
564 * initialise the AGFL to zero or NULL. Hence the only valid part of the
565 * AGFL is what the AGF says is active. We can't get to the AGF, so we
566 * can't verify just those entries are valid.
567 */
568 if (!xfs_sb_version_hascrc(&mp->m_sb))
569 return;
570
Eric Sandeence5028c2014-02-27 15:23:10 +1100571 if (!xfs_buf_verify_cksum(bp, XFS_AGFL_CRC_OFF))
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800572 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
573 else {
574 fa = xfs_agfl_verify(bp);
575 if (fa)
576 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
577 }
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100578}
579
580static void
581xfs_agfl_write_verify(
582 struct xfs_buf *bp)
583{
584 struct xfs_mount *mp = bp->b_target->bt_mount;
585 struct xfs_buf_log_item *bip = bp->b_fspriv;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800586 xfs_failaddr_t fa;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100587
588 /* no verification of non-crc AGFLs */
589 if (!xfs_sb_version_hascrc(&mp->m_sb))
590 return;
591
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -0800592 fa = xfs_agfl_verify(bp);
593 if (fa) {
594 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +1100595 return;
596 }
597
598 if (bip)
599 XFS_BUF_TO_AGFL(bp)->agfl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
600
Eric Sandeenf1dbcd72014-02-27 15:18:23 +1100601 xfs_buf_update_cksum(bp, XFS_AGFL_CRC_OFF);
Dave Chinnerbb80c6d2012-11-12 22:54:06 +1100602}
603
Dave Chinner1813dd62012-11-14 17:54:40 +1100604const struct xfs_buf_ops xfs_agfl_buf_ops = {
Eric Sandeen233135b2016-01-04 16:10:19 +1100605 .name = "xfs_agfl",
Dave Chinner1813dd62012-11-14 17:54:40 +1100606 .verify_read = xfs_agfl_read_verify,
607 .verify_write = xfs_agfl_write_verify,
608};
609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610/*
611 * Read in the allocation group free block array.
612 */
Darrick J. Wong26788092017-06-16 11:00:07 -0700613int /* error */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614xfs_alloc_read_agfl(
615 xfs_mount_t *mp, /* mount point structure */
616 xfs_trans_t *tp, /* transaction pointer */
617 xfs_agnumber_t agno, /* allocation group number */
618 xfs_buf_t **bpp) /* buffer for the ag free block array */
619{
620 xfs_buf_t *bp; /* return value */
621 int error;
622
623 ASSERT(agno != NULLAGNUMBER);
624 error = xfs_trans_read_buf(
625 mp, tp, mp->m_ddev_targp,
626 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
Dave Chinner1813dd62012-11-14 17:54:40 +1100627 XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 if (error)
629 return error;
Christoph Hellwig38f23232011-10-10 16:52:45 +0000630 xfs_buf_set_ref(bp, XFS_AGFL_REF);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 *bpp = bp;
632 return 0;
633}
634
Christoph Hellwigecb69282011-03-04 12:59:55 +0000635STATIC int
636xfs_alloc_update_counters(
637 struct xfs_trans *tp,
638 struct xfs_perag *pag,
639 struct xfs_buf *agbp,
640 long len)
641{
642 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
643
644 pag->pagf_freeblks += len;
645 be32_add_cpu(&agf->agf_freeblks, len);
646
647 xfs_trans_agblocks_delta(tp, len);
648 if (unlikely(be32_to_cpu(agf->agf_freeblks) >
649 be32_to_cpu(agf->agf_length)))
Dave Chinner24513372014-06-25 14:58:08 +1000650 return -EFSCORRUPTED;
Christoph Hellwigecb69282011-03-04 12:59:55 +0000651
652 xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
653 return 0;
654}
655
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656/*
657 * Allocation group level functions.
658 */
659
660/*
661 * Allocate a variable extent in the allocation group agno.
662 * Type and bno are used to determine where in the allocation group the
663 * extent will start.
664 * Extent's length (returned in *len) will be between minlen and maxlen,
665 * and of the form k * prod + mod unless there's nothing that large.
666 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
667 */
668STATIC int /* error */
669xfs_alloc_ag_vextent(
670 xfs_alloc_arg_t *args) /* argument structure for allocation */
671{
672 int error=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673
674 ASSERT(args->minlen > 0);
675 ASSERT(args->maxlen > 0);
676 ASSERT(args->minlen <= args->maxlen);
677 ASSERT(args->mod < args->prod);
678 ASSERT(args->alignment > 0);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +1000679
680 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 * Branch to correct routine based on the type.
682 */
683 args->wasfromfl = 0;
684 switch (args->type) {
685 case XFS_ALLOCTYPE_THIS_AG:
686 error = xfs_alloc_ag_vextent_size(args);
687 break;
688 case XFS_ALLOCTYPE_NEAR_BNO:
689 error = xfs_alloc_ag_vextent_near(args);
690 break;
691 case XFS_ALLOCTYPE_THIS_BNO:
692 error = xfs_alloc_ag_vextent_exact(args);
693 break;
694 default:
695 ASSERT(0);
696 /* NOTREACHED */
697 }
Christoph Hellwigecb69282011-03-04 12:59:55 +0000698
699 if (error || args->agbno == NULLAGBLOCK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701
Christoph Hellwigecb69282011-03-04 12:59:55 +0000702 ASSERT(args->len >= args->minlen);
703 ASSERT(args->len <= args->maxlen);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +1000704 ASSERT(!args->wasfromfl || args->resv != XFS_AG_RESV_AGFL);
Christoph Hellwigecb69282011-03-04 12:59:55 +0000705 ASSERT(args->agbno % args->alignment == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706
Darrick J. Wong673930c2016-08-03 11:33:43 +1000707 /* if not file data, insert new block into the reverse map btree */
Darrick J. Wong33df3a92017-12-07 19:07:27 -0800708 if (!xfs_rmap_should_skip_owner_update(&args->oinfo)) {
Darrick J. Wong673930c2016-08-03 11:33:43 +1000709 error = xfs_rmap_alloc(args->tp, args->agbp, args->agno,
710 args->agbno, args->len, &args->oinfo);
711 if (error)
712 return error;
713 }
714
Christoph Hellwigecb69282011-03-04 12:59:55 +0000715 if (!args->wasfromfl) {
716 error = xfs_alloc_update_counters(args->tp, args->pag,
717 args->agbp,
718 -((long)(args->len)));
719 if (error)
720 return error;
721
Dave Chinner4ecbfe62012-04-29 10:41:10 +0000722 ASSERT(!xfs_extent_busy_search(args->mp, args->agno,
Christoph Hellwige26f0502011-04-24 19:06:15 +0000723 args->agbno, args->len));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 }
Christoph Hellwigecb69282011-03-04 12:59:55 +0000725
Darrick J. Wong3fd129b2016-09-19 10:30:52 +1000726 xfs_ag_resv_alloc_extent(args->pag, args->resv, args);
Christoph Hellwigecb69282011-03-04 12:59:55 +0000727
Bill O'Donnellff6d6af2015-10-12 18:21:22 +1100728 XFS_STATS_INC(args->mp, xs_allocx);
729 XFS_STATS_ADD(args->mp, xs_allocb, args->len);
Christoph Hellwigecb69282011-03-04 12:59:55 +0000730 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731}
732
733/*
734 * Allocate a variable extent at exactly agno/bno.
735 * Extent's length (returned in *len) will be between minlen and maxlen,
736 * and of the form k * prod + mod unless there's nothing that large.
737 * Return the starting a.g. block (bno), or NULLAGBLOCK if we can't do it.
738 */
739STATIC int /* error */
740xfs_alloc_ag_vextent_exact(
741 xfs_alloc_arg_t *args) /* allocation argument structure */
742{
743 xfs_btree_cur_t *bno_cur;/* by block-number btree cursor */
744 xfs_btree_cur_t *cnt_cur;/* by count btree cursor */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 int error;
746 xfs_agblock_t fbno; /* start block of found extent */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 xfs_extlen_t flen; /* length of found extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800748 xfs_agblock_t tbno; /* start block of busy extent */
749 xfs_extlen_t tlen; /* length of busy extent */
750 xfs_agblock_t tend; /* end block of busy extent */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 int i; /* success/failure of operation */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800752 unsigned busy_gen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753
754 ASSERT(args->alignment == 1);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 /*
757 * Allocate/initialize a cursor for the by-number freespace btree.
758 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +1100759 bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000760 args->agno, XFS_BTNUM_BNO);
761
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 /*
763 * Lookup bno and minlen in the btree (minlen is irrelevant, really).
764 * Look for the closest free block <= bno, it must contain bno
765 * if any free block does.
766 */
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000767 error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i);
768 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 goto error0;
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000770 if (!i)
771 goto not_found;
772
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 /*
774 * Grab the freespace record.
775 */
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000776 error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i);
777 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +1100779 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 ASSERT(fbno <= args->agbno);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000781
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 /*
Christoph Hellwige26f0502011-04-24 19:06:15 +0000783 * Check for overlapping busy extents.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800785 tbno = fbno;
786 tlen = flen;
787 xfs_extent_busy_trim(args, &tbno, &tlen, &busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +0000788
789 /*
790 * Give up if the start of the extent is busy, or the freespace isn't
791 * long enough for the minimum request.
792 */
793 if (tbno > args->agbno)
794 goto not_found;
795 if (tlen < args->minlen)
796 goto not_found;
797 tend = tbno + tlen;
798 if (tend < args->agbno + args->minlen)
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000799 goto not_found;
800
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 /*
802 * End of extent will be smaller of the freespace end and the
803 * maximal requested end.
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000804 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 * Fix the length according to mod and prod if given.
806 */
Chandra Seetharaman81463b12011-06-09 16:47:49 +0000807 args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen)
808 - args->agbno;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 xfs_alloc_fix_len(args);
Chandra Seetharaman81463b12011-06-09 16:47:49 +0000810 ASSERT(args->agbno + args->len <= tend);
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000811
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 /*
Chandra Seetharaman81463b12011-06-09 16:47:49 +0000813 * We are allocating agbno for args->len
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 * Allocate/initialize a cursor for the by-size btree.
815 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +1100816 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
817 args->agno, XFS_BTNUM_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 ASSERT(args->agbno + args->len <=
Christoph Hellwig16259e72005-11-02 15:11:25 +1100819 be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000820 error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno,
821 args->len, XFSA_FIXUP_BNO_OK);
822 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
824 goto error0;
825 }
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000826
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
828 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +0000829
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 args->wasfromfl = 0;
Christoph Hellwig9f9baab2010-12-10 15:03:57 +0000831 trace_xfs_alloc_exact_done(args);
832 return 0;
833
834not_found:
835 /* Didn't find it, return null. */
836 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
837 args->agbno = NULLAGBLOCK;
838 trace_xfs_alloc_exact_notfound(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 return 0;
840
841error0:
842 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +0000843 trace_xfs_alloc_exact_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 return error;
845}
846
847/*
Christoph Hellwig489a1502010-12-10 15:04:11 +0000848 * Search the btree in a given direction via the search cursor and compare
849 * the records found against the good extent we've already found.
850 */
851STATIC int
852xfs_alloc_find_best_extent(
853 struct xfs_alloc_arg *args, /* allocation argument structure */
854 struct xfs_btree_cur **gcur, /* good cursor */
855 struct xfs_btree_cur **scur, /* searching cursor */
856 xfs_agblock_t gdiff, /* difference for search comparison */
857 xfs_agblock_t *sbno, /* extent found by search */
Christoph Hellwige26f0502011-04-24 19:06:15 +0000858 xfs_extlen_t *slen, /* extent length */
859 xfs_agblock_t *sbnoa, /* aligned extent found by search */
860 xfs_extlen_t *slena, /* aligned extent length */
Christoph Hellwig489a1502010-12-10 15:04:11 +0000861 int dir) /* 0 = search right, 1 = search left */
862{
Christoph Hellwig489a1502010-12-10 15:04:11 +0000863 xfs_agblock_t new;
864 xfs_agblock_t sdiff;
865 int error;
866 int i;
Christoph Hellwigebf55872017-02-07 14:06:57 -0800867 unsigned busy_gen;
Christoph Hellwig489a1502010-12-10 15:04:11 +0000868
869 /* The good extent is perfect, no need to search. */
870 if (!gdiff)
871 goto out_use_good;
872
873 /*
874 * Look until we find a better one, run out of space or run off the end.
875 */
876 do {
877 error = xfs_alloc_get_rec(*scur, sbno, slen, &i);
878 if (error)
879 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +1100880 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwigebf55872017-02-07 14:06:57 -0800881 xfs_alloc_compute_aligned(args, *sbno, *slen,
882 sbnoa, slena, &busy_gen);
Christoph Hellwig489a1502010-12-10 15:04:11 +0000883
884 /*
885 * The good extent is closer than this one.
886 */
887 if (!dir) {
Brian Fosterbfe46d42015-05-29 08:53:00 +1000888 if (*sbnoa > args->max_agbno)
889 goto out_use_good;
Christoph Hellwige26f0502011-04-24 19:06:15 +0000890 if (*sbnoa >= args->agbno + gdiff)
Christoph Hellwig489a1502010-12-10 15:04:11 +0000891 goto out_use_good;
892 } else {
Brian Fosterbfe46d42015-05-29 08:53:00 +1000893 if (*sbnoa < args->min_agbno)
894 goto out_use_good;
Christoph Hellwige26f0502011-04-24 19:06:15 +0000895 if (*sbnoa <= args->agbno - gdiff)
Christoph Hellwig489a1502010-12-10 15:04:11 +0000896 goto out_use_good;
897 }
898
899 /*
900 * Same distance, compare length and pick the best.
901 */
902 if (*slena >= args->minlen) {
903 args->len = XFS_EXTLEN_MIN(*slena, args->maxlen);
904 xfs_alloc_fix_len(args);
905
906 sdiff = xfs_alloc_compute_diff(args->agbno, args->len,
Jan Kara211d0222013-04-11 22:09:56 +0200907 args->alignment,
Dave Chinner292378e2016-09-26 08:21:28 +1000908 args->datatype, *sbnoa,
Christoph Hellwige26f0502011-04-24 19:06:15 +0000909 *slena, &new);
Christoph Hellwig489a1502010-12-10 15:04:11 +0000910
911 /*
912 * Choose closer size and invalidate other cursor.
913 */
914 if (sdiff < gdiff)
915 goto out_use_search;
916 goto out_use_good;
917 }
918
919 if (!dir)
920 error = xfs_btree_increment(*scur, 0, &i);
921 else
922 error = xfs_btree_decrement(*scur, 0, &i);
923 if (error)
924 goto error0;
925 } while (i);
926
927out_use_good:
928 xfs_btree_del_cursor(*scur, XFS_BTREE_NOERROR);
929 *scur = NULL;
930 return 0;
931
932out_use_search:
933 xfs_btree_del_cursor(*gcur, XFS_BTREE_NOERROR);
934 *gcur = NULL;
935 return 0;
936
937error0:
938 /* caller invalidates cursors */
939 return error;
940}
941
942/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 * Allocate a variable extent near bno in the allocation group agno.
944 * Extent's length (returned in len) will be between minlen and maxlen,
945 * and of the form k * prod + mod unless there's nothing that large.
946 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
947 */
948STATIC int /* error */
949xfs_alloc_ag_vextent_near(
950 xfs_alloc_arg_t *args) /* allocation argument structure */
951{
952 xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */
953 xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */
954 xfs_btree_cur_t *cnt_cur; /* cursor for count btree */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 xfs_agblock_t gtbno; /* start bno of right side entry */
956 xfs_agblock_t gtbnoa; /* aligned ... */
957 xfs_extlen_t gtdiff; /* difference to right side entry */
958 xfs_extlen_t gtlen; /* length of right side entry */
Christoph Hellwige26f0502011-04-24 19:06:15 +0000959 xfs_extlen_t gtlena; /* aligned ... */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 xfs_agblock_t gtnew; /* useful start bno of right side */
961 int error; /* error code */
962 int i; /* result code, temporary */
963 int j; /* result code, temporary */
964 xfs_agblock_t ltbno; /* start bno of left side entry */
965 xfs_agblock_t ltbnoa; /* aligned ... */
966 xfs_extlen_t ltdiff; /* difference to left side entry */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 xfs_extlen_t ltlen; /* length of left side entry */
Christoph Hellwige26f0502011-04-24 19:06:15 +0000968 xfs_extlen_t ltlena; /* aligned ... */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 xfs_agblock_t ltnew; /* useful start bno of left side */
970 xfs_extlen_t rlen; /* length of returned extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -0800971 bool busy;
972 unsigned busy_gen;
Dave Chinner63d20d62013-08-12 20:49:50 +1000973#ifdef DEBUG
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 /*
975 * Randomly don't execute the first algorithm.
976 */
977 int dofirst; /* set to do first algorithm */
978
Akinobu Mitaecb34032013-03-04 21:58:20 +0900979 dofirst = prandom_u32() & 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980#endif
Christoph Hellwige26f0502011-04-24 19:06:15 +0000981
Brian Fosterbfe46d42015-05-29 08:53:00 +1000982 /* handle unitialized agbno range so caller doesn't have to */
983 if (!args->min_agbno && !args->max_agbno)
984 args->max_agbno = args->mp->m_sb.sb_agblocks - 1;
985 ASSERT(args->min_agbno <= args->max_agbno);
986
987 /* clamp agbno to the range if it's outside */
988 if (args->agbno < args->min_agbno)
989 args->agbno = args->min_agbno;
990 if (args->agbno > args->max_agbno)
991 args->agbno = args->max_agbno;
992
Christoph Hellwige26f0502011-04-24 19:06:15 +0000993restart:
994 bno_cur_lt = NULL;
995 bno_cur_gt = NULL;
996 ltlen = 0;
997 gtlena = 0;
998 ltlena = 0;
Christoph Hellwigebf55872017-02-07 14:06:57 -0800999 busy = false;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001000
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 /*
1002 * Get a cursor for the by-size btree.
1003 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001004 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1005 args->agno, XFS_BTNUM_CNT);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001006
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 /*
1008 * See if there are any free extents as big as maxlen.
1009 */
1010 if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen, &i)))
1011 goto error0;
1012 /*
1013 * If none, then pick up the last entry in the tree unless the
1014 * tree is empty.
1015 */
1016 if (!i) {
1017 if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &ltbno,
1018 &ltlen, &i)))
1019 goto error0;
1020 if (i == 0 || ltlen == 0) {
1021 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001022 trace_xfs_alloc_near_noentry(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 return 0;
1024 }
1025 ASSERT(i == 1);
1026 }
1027 args->wasfromfl = 0;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001028
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 /*
1030 * First algorithm.
1031 * If the requested extent is large wrt the freespaces available
1032 * in this a.g., then the cursor will be pointing to a btree entry
1033 * near the right edge of the tree. If it's in the last btree leaf
1034 * block, then we just examine all the entries in that block
1035 * that are big enough, and pick the best one.
1036 * This is written as a while loop so we can break out of it,
1037 * but we never loop back to the top.
1038 */
1039 while (xfs_btree_islastblock(cnt_cur, 0)) {
1040 xfs_extlen_t bdiff;
1041 int besti=0;
1042 xfs_extlen_t blen=0;
1043 xfs_agblock_t bnew=0;
1044
Dave Chinner63d20d62013-08-12 20:49:50 +10001045#ifdef DEBUG
1046 if (dofirst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 break;
1048#endif
1049 /*
1050 * Start from the entry that lookup found, sequence through
1051 * all larger free blocks. If we're actually pointing at a
1052 * record smaller than maxlen, go to the start of this block,
1053 * and skip all those smaller than minlen.
1054 */
1055 if (ltlen || args->alignment > 1) {
1056 cnt_cur->bc_ptrs[0] = 1;
1057 do {
1058 if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno,
1059 &ltlen, &i)))
1060 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001061 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 if (ltlen >= args->minlen)
1063 break;
Christoph Hellwig637aa502008-10-30 16:55:45 +11001064 if ((error = xfs_btree_increment(cnt_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 goto error0;
1066 } while (i);
1067 ASSERT(ltlen >= args->minlen);
1068 if (!i)
1069 break;
1070 }
1071 i = cnt_cur->bc_ptrs[0];
1072 for (j = 1, blen = 0, bdiff = 0;
1073 !error && j && (blen < args->maxlen || bdiff > 0);
Christoph Hellwig637aa502008-10-30 16:55:45 +11001074 error = xfs_btree_increment(cnt_cur, 0, &j)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 /*
1076 * For each entry, decide if it's better than
1077 * the previous best entry.
1078 */
1079 if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
1080 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001081 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001082 busy = xfs_alloc_compute_aligned(args, ltbno, ltlen,
1083 &ltbnoa, &ltlena, &busy_gen);
David Chinnere6430032008-04-17 16:49:49 +10001084 if (ltlena < args->minlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 continue;
Brian Fosterbfe46d42015-05-29 08:53:00 +10001086 if (ltbnoa < args->min_agbno || ltbnoa > args->max_agbno)
1087 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1089 xfs_alloc_fix_len(args);
1090 ASSERT(args->len >= args->minlen);
1091 if (args->len < blen)
1092 continue;
1093 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
Dave Chinner292378e2016-09-26 08:21:28 +10001094 args->alignment, args->datatype, ltbnoa,
Jan Kara211d0222013-04-11 22:09:56 +02001095 ltlena, &ltnew);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 if (ltnew != NULLAGBLOCK &&
1097 (args->len > blen || ltdiff < bdiff)) {
1098 bdiff = ltdiff;
1099 bnew = ltnew;
1100 blen = args->len;
1101 besti = cnt_cur->bc_ptrs[0];
1102 }
1103 }
1104 /*
1105 * It didn't work. We COULD be in a case where
1106 * there's a good record somewhere, so try again.
1107 */
1108 if (blen == 0)
1109 break;
1110 /*
1111 * Point at the best entry, and retrieve it again.
1112 */
1113 cnt_cur->bc_ptrs[0] = besti;
1114 if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
1115 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001116 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwig73523a22010-07-20 17:54:45 +10001117 ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 args->len = blen;
Christoph Hellwig54fee132017-01-09 13:44:30 -08001119
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 /*
1121 * We are allocating starting at bnew for blen blocks.
1122 */
1123 args->agbno = bnew;
1124 ASSERT(bnew >= ltbno);
Christoph Hellwig73523a22010-07-20 17:54:45 +10001125 ASSERT(bnew + blen <= ltbno + ltlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 /*
1127 * Set up a cursor for the by-bno tree.
1128 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001129 bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp,
1130 args->agbp, args->agno, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 /*
1132 * Fix up the btree entries.
1133 */
1134 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno,
1135 ltlen, bnew, blen, XFSA_FIXUP_CNT_OK)))
1136 goto error0;
1137 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1138 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001139
1140 trace_xfs_alloc_near_first(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 return 0;
1142 }
1143 /*
1144 * Second algorithm.
1145 * Search in the by-bno tree to the left and to the right
1146 * simultaneously, until in each case we find a space big enough,
1147 * or run into the edge of the tree. When we run into the edge,
1148 * we deallocate that cursor.
1149 * If both searches succeed, we compare the two spaces and pick
1150 * the better one.
1151 * With alignment, it's possible for both to fail; the upper
1152 * level algorithm that picks allocation groups for allocations
1153 * is not supposed to do this.
1154 */
1155 /*
1156 * Allocate and initialize the cursor for the leftward search.
1157 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001158 bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1159 args->agno, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 /*
1161 * Lookup <= bno to find the leftward search's starting point.
1162 */
1163 if ((error = xfs_alloc_lookup_le(bno_cur_lt, args->agbno, args->maxlen, &i)))
1164 goto error0;
1165 if (!i) {
1166 /*
1167 * Didn't find anything; use this cursor for the rightward
1168 * search.
1169 */
1170 bno_cur_gt = bno_cur_lt;
1171 bno_cur_lt = NULL;
1172 }
1173 /*
1174 * Found something. Duplicate the cursor for the rightward search.
1175 */
1176 else if ((error = xfs_btree_dup_cursor(bno_cur_lt, &bno_cur_gt)))
1177 goto error0;
1178 /*
1179 * Increment the cursor, so we will point at the entry just right
1180 * of the leftward entry if any, or to the leftmost entry.
1181 */
Christoph Hellwig637aa502008-10-30 16:55:45 +11001182 if ((error = xfs_btree_increment(bno_cur_gt, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 goto error0;
1184 if (!i) {
1185 /*
1186 * It failed, there are no rightward entries.
1187 */
1188 xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_NOERROR);
1189 bno_cur_gt = NULL;
1190 }
1191 /*
1192 * Loop going left with the leftward cursor, right with the
1193 * rightward cursor, until either both directions give up or
1194 * we find an entry at least as big as minlen.
1195 */
1196 do {
1197 if (bno_cur_lt) {
1198 if ((error = xfs_alloc_get_rec(bno_cur_lt, &ltbno, &ltlen, &i)))
1199 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001200 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001201 busy |= xfs_alloc_compute_aligned(args, ltbno, ltlen,
1202 &ltbnoa, &ltlena, &busy_gen);
Brian Fosterbfe46d42015-05-29 08:53:00 +10001203 if (ltlena >= args->minlen && ltbnoa >= args->min_agbno)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 break;
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001205 if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 goto error0;
Brian Fosterbfe46d42015-05-29 08:53:00 +10001207 if (!i || ltbnoa < args->min_agbno) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 xfs_btree_del_cursor(bno_cur_lt,
1209 XFS_BTREE_NOERROR);
1210 bno_cur_lt = NULL;
1211 }
1212 }
1213 if (bno_cur_gt) {
1214 if ((error = xfs_alloc_get_rec(bno_cur_gt, &gtbno, &gtlen, &i)))
1215 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001216 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001217 busy |= xfs_alloc_compute_aligned(args, gtbno, gtlen,
1218 &gtbnoa, &gtlena, &busy_gen);
Brian Fosterbfe46d42015-05-29 08:53:00 +10001219 if (gtlena >= args->minlen && gtbnoa <= args->max_agbno)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 break;
Christoph Hellwig637aa502008-10-30 16:55:45 +11001221 if ((error = xfs_btree_increment(bno_cur_gt, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 goto error0;
Brian Fosterbfe46d42015-05-29 08:53:00 +10001223 if (!i || gtbnoa > args->max_agbno) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 xfs_btree_del_cursor(bno_cur_gt,
1225 XFS_BTREE_NOERROR);
1226 bno_cur_gt = NULL;
1227 }
1228 }
1229 } while (bno_cur_lt || bno_cur_gt);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001230
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 /*
1232 * Got both cursors still active, need to find better entry.
1233 */
1234 if (bno_cur_lt && bno_cur_gt) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 if (ltlena >= args->minlen) {
1236 /*
Christoph Hellwig489a1502010-12-10 15:04:11 +00001237 * Left side is good, look for a right side entry.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 */
1239 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1240 xfs_alloc_fix_len(args);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001241 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
Dave Chinner292378e2016-09-26 08:21:28 +10001242 args->alignment, args->datatype, ltbnoa,
Jan Kara211d0222013-04-11 22:09:56 +02001243 ltlena, &ltnew);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001244
1245 error = xfs_alloc_find_best_extent(args,
1246 &bno_cur_lt, &bno_cur_gt,
Christoph Hellwige26f0502011-04-24 19:06:15 +00001247 ltdiff, &gtbno, &gtlen,
1248 &gtbnoa, &gtlena,
Christoph Hellwig489a1502010-12-10 15:04:11 +00001249 0 /* search right */);
1250 } else {
1251 ASSERT(gtlena >= args->minlen);
1252
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 /*
Christoph Hellwig489a1502010-12-10 15:04:11 +00001254 * Right side is good, look for a left side entry.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 */
1256 args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
1257 xfs_alloc_fix_len(args);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001258 gtdiff = xfs_alloc_compute_diff(args->agbno, args->len,
Dave Chinner292378e2016-09-26 08:21:28 +10001259 args->alignment, args->datatype, gtbnoa,
Jan Kara211d0222013-04-11 22:09:56 +02001260 gtlena, &gtnew);
Christoph Hellwig489a1502010-12-10 15:04:11 +00001261
1262 error = xfs_alloc_find_best_extent(args,
1263 &bno_cur_gt, &bno_cur_lt,
Christoph Hellwige26f0502011-04-24 19:06:15 +00001264 gtdiff, &ltbno, &ltlen,
1265 &ltbnoa, &ltlena,
Christoph Hellwig489a1502010-12-10 15:04:11 +00001266 1 /* search left */);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 }
Christoph Hellwig489a1502010-12-10 15:04:11 +00001268
1269 if (error)
1270 goto error0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 }
Christoph Hellwig489a1502010-12-10 15:04:11 +00001272
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 /*
1274 * If we couldn't get anything, give up.
1275 */
1276 if (bno_cur_lt == NULL && bno_cur_gt == NULL) {
Dave Chinnere3a746f52012-07-12 07:40:42 +10001277 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1278
Christoph Hellwigebf55872017-02-07 14:06:57 -08001279 if (busy) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001280 trace_xfs_alloc_near_busy(args);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001281 xfs_extent_busy_flush(args->mp, args->pag, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001282 goto restart;
1283 }
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001284 trace_xfs_alloc_size_neither(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 args->agbno = NULLAGBLOCK;
1286 return 0;
1287 }
Christoph Hellwig489a1502010-12-10 15:04:11 +00001288
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 /*
1290 * At this point we have selected a freespace entry, either to the
1291 * left or to the right. If it's on the right, copy all the
1292 * useful variables to the "left" set so we only have one
1293 * copy of this code.
1294 */
1295 if (bno_cur_gt) {
1296 bno_cur_lt = bno_cur_gt;
1297 bno_cur_gt = NULL;
1298 ltbno = gtbno;
1299 ltbnoa = gtbnoa;
1300 ltlen = gtlen;
1301 ltlena = gtlena;
1302 j = 1;
1303 } else
1304 j = 0;
Christoph Hellwig489a1502010-12-10 15:04:11 +00001305
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 /*
1307 * Fix up the length and compute the useful address.
1308 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1310 xfs_alloc_fix_len(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311 rlen = args->len;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001312 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
Dave Chinner292378e2016-09-26 08:21:28 +10001313 args->datatype, ltbnoa, ltlena, &ltnew);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314 ASSERT(ltnew >= ltbno);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001315 ASSERT(ltnew + rlen <= ltbnoa + ltlena);
Christoph Hellwig16259e72005-11-02 15:11:25 +11001316 ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
Brian Fosterbfe46d42015-05-29 08:53:00 +10001317 ASSERT(ltnew >= args->min_agbno && ltnew <= args->max_agbno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 args->agbno = ltnew;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001319
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen,
1321 ltnew, rlen, XFSA_FIXUP_BNO_OK)))
1322 goto error0;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001323
1324 if (j)
1325 trace_xfs_alloc_near_greater(args);
1326 else
1327 trace_xfs_alloc_near_lesser(args);
1328
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1330 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
1331 return 0;
1332
1333 error0:
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001334 trace_xfs_alloc_near_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 if (cnt_cur != NULL)
1336 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1337 if (bno_cur_lt != NULL)
1338 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_ERROR);
1339 if (bno_cur_gt != NULL)
1340 xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_ERROR);
1341 return error;
1342}
1343
1344/*
1345 * Allocate a variable extent anywhere in the allocation group agno.
1346 * Extent's length (returned in len) will be between minlen and maxlen,
1347 * and of the form k * prod + mod unless there's nothing that large.
1348 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
1349 */
1350STATIC int /* error */
1351xfs_alloc_ag_vextent_size(
1352 xfs_alloc_arg_t *args) /* allocation argument structure */
1353{
1354 xfs_btree_cur_t *bno_cur; /* cursor for bno btree */
1355 xfs_btree_cur_t *cnt_cur; /* cursor for cnt btree */
1356 int error; /* error result */
1357 xfs_agblock_t fbno; /* start of found freespace */
1358 xfs_extlen_t flen; /* length of found freespace */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 int i; /* temp status variable */
1360 xfs_agblock_t rbno; /* returned block number */
1361 xfs_extlen_t rlen; /* length of returned extent */
Christoph Hellwigebf55872017-02-07 14:06:57 -08001362 bool busy;
1363 unsigned busy_gen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
Christoph Hellwige26f0502011-04-24 19:06:15 +00001365restart:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 /*
1367 * Allocate and initialize a cursor for the by-size btree.
1368 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001369 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1370 args->agno, XFS_BTNUM_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371 bno_cur = NULL;
Christoph Hellwigebf55872017-02-07 14:06:57 -08001372 busy = false;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001373
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 /*
1375 * Look for an entry >= maxlen+alignment-1 blocks.
1376 */
1377 if ((error = xfs_alloc_lookup_ge(cnt_cur, 0,
1378 args->maxlen + args->alignment - 1, &i)))
1379 goto error0;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001380
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 /*
Christoph Hellwigebf55872017-02-07 14:06:57 -08001382 * If none then we have to settle for a smaller extent. In the case that
1383 * there are no large extents, this will return the last entry in the
1384 * tree unless the tree is empty. In the case that there are only busy
1385 * large extents, this will return the largest small extent unless there
Christoph Hellwige26f0502011-04-24 19:06:15 +00001386 * are no smaller extents available.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 */
Christoph Hellwigebf55872017-02-07 14:06:57 -08001388 if (!i) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001389 error = xfs_alloc_ag_vextent_small(args, cnt_cur,
1390 &fbno, &flen, &i);
1391 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 goto error0;
1393 if (i == 0 || flen == 0) {
1394 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001395 trace_xfs_alloc_size_noentry(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 return 0;
1397 }
1398 ASSERT(i == 1);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001399 busy = xfs_alloc_compute_aligned(args, fbno, flen, &rbno,
1400 &rlen, &busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001401 } else {
1402 /*
1403 * Search for a non-busy extent that is large enough.
Christoph Hellwige26f0502011-04-24 19:06:15 +00001404 */
1405 for (;;) {
1406 error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i);
1407 if (error)
1408 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001409 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001410
Christoph Hellwigebf55872017-02-07 14:06:57 -08001411 busy = xfs_alloc_compute_aligned(args, fbno, flen,
1412 &rbno, &rlen, &busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001413
1414 if (rlen >= args->maxlen)
1415 break;
1416
1417 error = xfs_btree_increment(cnt_cur, 0, &i);
1418 if (error)
1419 goto error0;
1420 if (i == 0) {
1421 /*
1422 * Our only valid extents must have been busy.
1423 * Make it unbusy by forcing the log out and
Christoph Hellwigebf55872017-02-07 14:06:57 -08001424 * retrying.
Christoph Hellwige26f0502011-04-24 19:06:15 +00001425 */
1426 xfs_btree_del_cursor(cnt_cur,
1427 XFS_BTREE_NOERROR);
1428 trace_xfs_alloc_size_busy(args);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001429 xfs_extent_busy_flush(args->mp,
1430 args->pag, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001431 goto restart;
1432 }
1433 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 }
Christoph Hellwige26f0502011-04-24 19:06:15 +00001435
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 /*
1437 * In the first case above, we got the last entry in the
1438 * by-size btree. Now we check to see if the space hits maxlen
1439 * once aligned; if not, we search left for something better.
1440 * This can't happen in the second case above.
1441 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
Eric Sandeenc29aad42015-02-23 22:39:08 +11001443 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 (rlen <= flen && rbno + rlen <= fbno + flen), error0);
1445 if (rlen < args->maxlen) {
1446 xfs_agblock_t bestfbno;
1447 xfs_extlen_t bestflen;
1448 xfs_agblock_t bestrbno;
1449 xfs_extlen_t bestrlen;
1450
1451 bestrlen = rlen;
1452 bestrbno = rbno;
1453 bestflen = flen;
1454 bestfbno = fbno;
1455 for (;;) {
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001456 if ((error = xfs_btree_decrement(cnt_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457 goto error0;
1458 if (i == 0)
1459 break;
1460 if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen,
1461 &i)))
1462 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001463 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 if (flen < bestrlen)
1465 break;
Christoph Hellwigebf55872017-02-07 14:06:57 -08001466 busy = xfs_alloc_compute_aligned(args, fbno, flen,
1467 &rbno, &rlen, &busy_gen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
Eric Sandeenc29aad42015-02-23 22:39:08 +11001469 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 (rlen <= flen && rbno + rlen <= fbno + flen),
1471 error0);
1472 if (rlen > bestrlen) {
1473 bestrlen = rlen;
1474 bestrbno = rbno;
1475 bestflen = flen;
1476 bestfbno = fbno;
1477 if (rlen == args->maxlen)
1478 break;
1479 }
1480 }
1481 if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen,
1482 &i)))
1483 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001484 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 rlen = bestrlen;
1486 rbno = bestrbno;
1487 flen = bestflen;
1488 fbno = bestfbno;
1489 }
1490 args->wasfromfl = 0;
1491 /*
1492 * Fix up the length.
1493 */
1494 args->len = rlen;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001495 if (rlen < args->minlen) {
Christoph Hellwigebf55872017-02-07 14:06:57 -08001496 if (busy) {
Christoph Hellwige26f0502011-04-24 19:06:15 +00001497 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1498 trace_xfs_alloc_size_busy(args);
Christoph Hellwigebf55872017-02-07 14:06:57 -08001499 xfs_extent_busy_flush(args->mp, args->pag, busy_gen);
Christoph Hellwige26f0502011-04-24 19:06:15 +00001500 goto restart;
1501 }
1502 goto out_nominleft;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 }
Christoph Hellwige26f0502011-04-24 19:06:15 +00001504 xfs_alloc_fix_len(args);
1505
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 rlen = args->len;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001507 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 /*
1509 * Allocate and initialize a cursor for the by-block tree.
1510 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001511 bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1512 args->agno, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
1514 rbno, rlen, XFSA_FIXUP_CNT_OK)))
1515 goto error0;
1516 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1517 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
1518 cnt_cur = bno_cur = NULL;
1519 args->len = rlen;
1520 args->agbno = rbno;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001521 XFS_WANT_CORRUPTED_GOTO(args->mp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 args->agbno + args->len <=
Christoph Hellwig16259e72005-11-02 15:11:25 +11001523 be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 error0);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001525 trace_xfs_alloc_size_done(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 return 0;
1527
1528error0:
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001529 trace_xfs_alloc_size_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 if (cnt_cur)
1531 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1532 if (bno_cur)
1533 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
1534 return error;
Christoph Hellwige26f0502011-04-24 19:06:15 +00001535
1536out_nominleft:
1537 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1538 trace_xfs_alloc_size_nominleft(args);
1539 args->agbno = NULLAGBLOCK;
1540 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541}
1542
1543/*
1544 * Deal with the case where only small freespaces remain.
1545 * Either return the contents of the last freespace record,
1546 * or allocate space from the freelist if there is nothing in the tree.
1547 */
1548STATIC int /* error */
1549xfs_alloc_ag_vextent_small(
1550 xfs_alloc_arg_t *args, /* allocation argument structure */
1551 xfs_btree_cur_t *ccur, /* by-size cursor */
1552 xfs_agblock_t *fbnop, /* result block number */
1553 xfs_extlen_t *flenp, /* result length */
1554 int *stat) /* status: 0-freelist, 1-normal/none */
1555{
Darrick J. Wonga03f1a62016-08-17 11:12:57 +10001556 struct xfs_owner_info oinfo;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001557 struct xfs_perag *pag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558 int error;
1559 xfs_agblock_t fbno;
1560 xfs_extlen_t flen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 int i;
1562
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001563 if ((error = xfs_btree_decrement(ccur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 goto error0;
1565 if (i) {
1566 if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i)))
1567 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001568 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 }
1570 /*
1571 * Nothing in the btree, try the freelist. Make sure
1572 * to respect minleft even when pulling from the
1573 * freelist.
1574 */
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001575 else if (args->minlen == 1 && args->alignment == 1 &&
1576 args->resv != XFS_AG_RESV_AGFL &&
Christoph Hellwig16259e72005-11-02 15:11:25 +11001577 (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
1578 > args->minleft)) {
David Chinner92821e22007-05-24 15:26:31 +10001579 error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
1580 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 goto error0;
1582 if (fbno != NULLAGBLOCK) {
Dave Chinner4ecbfe62012-04-29 10:41:10 +00001583 xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1,
Dave Chinner292378e2016-09-26 08:21:28 +10001584 xfs_alloc_allow_busy_reuse(args->datatype));
Christoph Hellwig97d3ac72011-04-24 19:06:16 +00001585
Dave Chinner292378e2016-09-26 08:21:28 +10001586 if (xfs_alloc_is_userdata(args->datatype)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 xfs_buf_t *bp;
1588
1589 bp = xfs_btree_get_bufs(args->mp, args->tp,
1590 args->agno, fbno, 0);
Eric Sandeen93e8bef2017-10-09 21:08:06 -07001591 if (!bp) {
1592 error = -EFSCORRUPTED;
1593 goto error0;
1594 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 xfs_trans_binval(args->tp, bp);
1596 }
1597 args->len = 1;
1598 args->agbno = fbno;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001599 XFS_WANT_CORRUPTED_GOTO(args->mp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 args->agbno + args->len <=
Christoph Hellwig16259e72005-11-02 15:11:25 +11001601 be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 error0);
1603 args->wasfromfl = 1;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001604 trace_xfs_alloc_small_freelist(args);
Darrick J. Wonga03f1a62016-08-17 11:12:57 +10001605
1606 /*
1607 * If we're feeding an AGFL block to something that
1608 * doesn't live in the free space, we need to clear
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001609 * out the OWN_AG rmap and add the block back to
1610 * the AGFL per-AG reservation.
Darrick J. Wonga03f1a62016-08-17 11:12:57 +10001611 */
1612 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG);
1613 error = xfs_rmap_free(args->tp, args->agbp, args->agno,
1614 fbno, 1, &oinfo);
1615 if (error)
1616 goto error0;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001617 pag = xfs_perag_get(args->mp, args->agno);
1618 xfs_ag_resv_free_extent(pag, XFS_AG_RESV_AGFL,
1619 args->tp, 1);
1620 xfs_perag_put(pag);
Darrick J. Wonga03f1a62016-08-17 11:12:57 +10001621
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 *stat = 0;
1623 return 0;
1624 }
1625 /*
1626 * Nothing in the freelist.
1627 */
1628 else
1629 flen = 0;
1630 }
1631 /*
1632 * Can't allocate from the freelist for some reason.
1633 */
Nathan Scottd432c802006-09-28 11:03:44 +10001634 else {
1635 fbno = NULLAGBLOCK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 flen = 0;
Nathan Scottd432c802006-09-28 11:03:44 +10001637 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 /*
1639 * Can't do the allocation, give up.
1640 */
1641 if (flen < args->minlen) {
1642 args->agbno = NULLAGBLOCK;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001643 trace_xfs_alloc_small_notenough(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 flen = 0;
1645 }
1646 *fbnop = fbno;
1647 *flenp = flen;
1648 *stat = 1;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001649 trace_xfs_alloc_small_done(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 return 0;
1651
1652error0:
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001653 trace_xfs_alloc_small_error(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 return error;
1655}
1656
1657/*
1658 * Free the extent starting at agno/bno for length.
1659 */
Darrick J. Wong340785c2016-08-03 11:33:42 +10001660STATIC int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661xfs_free_ag_extent(
Darrick J. Wong340785c2016-08-03 11:33:42 +10001662 xfs_trans_t *tp,
1663 xfs_buf_t *agbp,
1664 xfs_agnumber_t agno,
1665 xfs_agblock_t bno,
1666 xfs_extlen_t len,
1667 struct xfs_owner_info *oinfo,
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001668 enum xfs_ag_resv_type type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669{
1670 xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */
1671 xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */
1672 int error; /* error return value */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 xfs_agblock_t gtbno; /* start of right neighbor block */
1674 xfs_extlen_t gtlen; /* length of right neighbor block */
1675 int haveleft; /* have a left neighbor block */
1676 int haveright; /* have a right neighbor block */
1677 int i; /* temp, result code */
1678 xfs_agblock_t ltbno; /* start of left neighbor block */
1679 xfs_extlen_t ltlen; /* length of left neighbor block */
1680 xfs_mount_t *mp; /* mount point struct for filesystem */
1681 xfs_agblock_t nbno; /* new starting block of freespace */
1682 xfs_extlen_t nlen; /* new length of freespace */
Christoph Hellwigecb69282011-03-04 12:59:55 +00001683 xfs_perag_t *pag; /* per allocation group data */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
Darrick J. Wong673930c2016-08-03 11:33:43 +10001685 bno_cur = cnt_cur = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 mp = tp->t_mountp;
Darrick J. Wong673930c2016-08-03 11:33:43 +10001687
Darrick J. Wong33df3a92017-12-07 19:07:27 -08001688 if (!xfs_rmap_should_skip_owner_update(oinfo)) {
Darrick J. Wong673930c2016-08-03 11:33:43 +10001689 error = xfs_rmap_free(tp, agbp, agno, bno, len, oinfo);
1690 if (error)
1691 goto error0;
1692 }
1693
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 /*
1695 * Allocate and initialize a cursor for the by-block btree.
1696 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001697 bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 /*
1699 * Look for a neighboring block on the left (lower block numbers)
1700 * that is contiguous with this space.
1701 */
1702 if ((error = xfs_alloc_lookup_le(bno_cur, bno, len, &haveleft)))
1703 goto error0;
1704 if (haveleft) {
1705 /*
1706 * There is a block to our left.
1707 */
1708 if ((error = xfs_alloc_get_rec(bno_cur, &ltbno, &ltlen, &i)))
1709 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001710 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 /*
1712 * It's not contiguous, though.
1713 */
1714 if (ltbno + ltlen < bno)
1715 haveleft = 0;
1716 else {
1717 /*
1718 * If this failure happens the request to free this
1719 * space was invalid, it's (partly) already free.
1720 * Very bad.
1721 */
Eric Sandeenc29aad42015-02-23 22:39:08 +11001722 XFS_WANT_CORRUPTED_GOTO(mp,
1723 ltbno + ltlen <= bno, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 }
1725 }
1726 /*
1727 * Look for a neighboring block on the right (higher block numbers)
1728 * that is contiguous with this space.
1729 */
Christoph Hellwig637aa502008-10-30 16:55:45 +11001730 if ((error = xfs_btree_increment(bno_cur, 0, &haveright)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 goto error0;
1732 if (haveright) {
1733 /*
1734 * There is a block to our right.
1735 */
1736 if ((error = xfs_alloc_get_rec(bno_cur, &gtbno, &gtlen, &i)))
1737 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001738 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 /*
1740 * It's not contiguous, though.
1741 */
1742 if (bno + len < gtbno)
1743 haveright = 0;
1744 else {
1745 /*
1746 * If this failure happens the request to free this
1747 * space was invalid, it's (partly) already free.
1748 * Very bad.
1749 */
Eric Sandeenc29aad42015-02-23 22:39:08 +11001750 XFS_WANT_CORRUPTED_GOTO(mp, gtbno >= bno + len, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 }
1752 }
1753 /*
1754 * Now allocate and initialize a cursor for the by-size tree.
1755 */
Christoph Hellwig561f7d12008-10-30 16:53:59 +11001756 cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 /*
1758 * Have both left and right contiguous neighbors.
1759 * Merge all three into a single free block.
1760 */
1761 if (haveleft && haveright) {
1762 /*
1763 * Delete the old by-size entry on the left.
1764 */
1765 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
1766 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001767 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001768 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001770 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 /*
1772 * Delete the old by-size entry on the right.
1773 */
1774 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
1775 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001776 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001777 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001779 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 /*
1781 * Delete the old by-block entry for the right block.
1782 */
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001783 if ((error = xfs_btree_delete(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001785 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 /*
1787 * Move the by-block cursor back to the left neighbor.
1788 */
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001789 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001791 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792#ifdef DEBUG
1793 /*
1794 * Check that this is the right record: delete didn't
1795 * mangle the cursor.
1796 */
1797 {
1798 xfs_agblock_t xxbno;
1799 xfs_extlen_t xxlen;
1800
1801 if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen,
1802 &i)))
1803 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001804 XFS_WANT_CORRUPTED_GOTO(mp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 i == 1 && xxbno == ltbno && xxlen == ltlen,
1806 error0);
1807 }
1808#endif
1809 /*
1810 * Update remaining by-block entry to the new, joined block.
1811 */
1812 nbno = ltbno;
1813 nlen = len + ltlen + gtlen;
1814 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
1815 goto error0;
1816 }
1817 /*
1818 * Have only a left contiguous neighbor.
1819 * Merge it together with the new freespace.
1820 */
1821 else if (haveleft) {
1822 /*
1823 * Delete the old by-size entry on the left.
1824 */
1825 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
1826 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001827 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001828 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001830 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 /*
1832 * Back up the by-block cursor to the left neighbor, and
1833 * update its length.
1834 */
Christoph Hellwig8df4da42008-10-30 16:55:58 +11001835 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001837 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 nbno = ltbno;
1839 nlen = len + ltlen;
1840 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
1841 goto error0;
1842 }
1843 /*
1844 * Have only a right contiguous neighbor.
1845 * Merge it together with the new freespace.
1846 */
1847 else if (haveright) {
1848 /*
1849 * Delete the old by-size entry on the right.
1850 */
1851 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
1852 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001853 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Christoph Hellwig91cca5df2008-10-30 16:58:01 +11001854 if ((error = xfs_btree_delete(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001856 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 /*
1858 * Update the starting block and length of the right
1859 * neighbor in the by-block tree.
1860 */
1861 nbno = bno;
1862 nlen = len + gtlen;
1863 if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
1864 goto error0;
1865 }
1866 /*
1867 * No contiguous neighbors.
1868 * Insert the new freespace into the by-block tree.
1869 */
1870 else {
1871 nbno = bno;
1872 nlen = len;
Christoph Hellwig4b22a572008-10-30 16:57:40 +11001873 if ((error = xfs_btree_insert(bno_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001875 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 }
1877 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
1878 bno_cur = NULL;
1879 /*
1880 * In all cases we need to insert the new freespace in the by-size tree.
1881 */
1882 if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i)))
1883 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001884 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, error0);
Christoph Hellwig4b22a572008-10-30 16:57:40 +11001885 if ((error = xfs_btree_insert(cnt_cur, &i)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 goto error0;
Eric Sandeenc29aad42015-02-23 22:39:08 +11001887 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1889 cnt_cur = NULL;
Christoph Hellwigecb69282011-03-04 12:59:55 +00001890
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 /*
1892 * Update the freespace totals in the ag and superblock.
1893 */
Christoph Hellwigecb69282011-03-04 12:59:55 +00001894 pag = xfs_perag_get(mp, agno);
1895 error = xfs_alloc_update_counters(tp, pag, agbp, len);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001896 xfs_ag_resv_free_extent(pag, type, tp, len);
Christoph Hellwigecb69282011-03-04 12:59:55 +00001897 xfs_perag_put(pag);
1898 if (error)
1899 goto error0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900
Bill O'Donnellff6d6af2015-10-12 18:21:22 +11001901 XFS_STATS_INC(mp, xs_freex);
1902 XFS_STATS_ADD(mp, xs_freeb, len);
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00001903
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001904 trace_xfs_free_extent(mp, agno, bno, len, type == XFS_AG_RESV_AGFL,
1905 haveleft, haveright);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 return 0;
1908
1909 error0:
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001910 trace_xfs_free_extent(mp, agno, bno, len, type == XFS_AG_RESV_AGFL,
1911 -1, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 if (bno_cur)
1913 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
1914 if (cnt_cur)
1915 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1916 return error;
1917}
1918
1919/*
1920 * Visible (exported) allocation/free functions.
1921 * Some of these are used just by xfs_alloc_btree.c and this file.
1922 */
1923
1924/*
1925 * Compute and fill in value of m_ag_maxlevels.
1926 */
1927void
1928xfs_alloc_compute_maxlevels(
1929 xfs_mount_t *mp) /* file system mount structure */
1930{
Darrick J. Wong19b54ee2016-06-21 11:53:28 +10001931 mp->m_ag_maxlevels = xfs_btree_compute_maxlevels(mp, mp->m_alloc_mnr,
1932 (mp->m_sb.sb_agblocks + 1) / 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933}
1934
1935/*
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001936 * Find the length of the longest extent in an AG. The 'need' parameter
1937 * specifies how much space we're going to need for the AGFL and the
1938 * 'reserved' parameter tells us how many blocks in this AG are reserved for
1939 * other callers.
Dave Chinner6cc87642009-03-16 08:29:46 +01001940 */
1941xfs_extlen_t
1942xfs_alloc_longest_free_extent(
1943 struct xfs_mount *mp,
Dave Chinner50adbcb2015-06-22 10:04:31 +10001944 struct xfs_perag *pag,
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001945 xfs_extlen_t need,
1946 xfs_extlen_t reserved)
Dave Chinner6cc87642009-03-16 08:29:46 +01001947{
Dave Chinner50adbcb2015-06-22 10:04:31 +10001948 xfs_extlen_t delta = 0;
Dave Chinner6cc87642009-03-16 08:29:46 +01001949
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001950 /*
1951 * If the AGFL needs a recharge, we'll have to subtract that from the
1952 * longest extent.
1953 */
Dave Chinner6cc87642009-03-16 08:29:46 +01001954 if (need > pag->pagf_flcount)
1955 delta = need - pag->pagf_flcount;
1956
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001957 /*
1958 * If we cannot maintain others' reservations with space from the
1959 * not-longest freesp extents, we'll have to subtract /that/ from
1960 * the longest extent too.
1961 */
1962 if (pag->pagf_freeblks - pag->pagf_longest < reserved)
1963 delta += reserved - (pag->pagf_freeblks - pag->pagf_longest);
1964
1965 /*
1966 * If the longest extent is long enough to satisfy all the
1967 * reservations and AGFL rules in place, we can return this extent.
1968 */
Dave Chinner6cc87642009-03-16 08:29:46 +01001969 if (pag->pagf_longest > delta)
1970 return pag->pagf_longest - delta;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10001971
1972 /* Otherwise, let the caller try for 1 block if there's space. */
Dave Chinner6cc87642009-03-16 08:29:46 +01001973 return pag->pagf_flcount > 0 || pag->pagf_longest > 0;
1974}
1975
Dave Chinner496817b2015-06-22 10:13:30 +10001976unsigned int
1977xfs_alloc_min_freelist(
1978 struct xfs_mount *mp,
1979 struct xfs_perag *pag)
1980{
1981 unsigned int min_free;
1982
1983 /* space needed by-bno freespace btree */
1984 min_free = min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_BNOi] + 1,
1985 mp->m_ag_maxlevels);
1986 /* space needed by-size freespace btree */
1987 min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1,
1988 mp->m_ag_maxlevels);
Darrick J. Wong52548852016-08-03 11:38:24 +10001989 /* space needed reverse mapping used space btree */
1990 if (xfs_sb_version_hasrmapbt(&mp->m_sb))
1991 min_free += min_t(unsigned int,
1992 pag->pagf_levels[XFS_BTNUM_RMAPi] + 1,
1993 mp->m_rmap_maxlevels);
Dave Chinner496817b2015-06-22 10:13:30 +10001994
1995 return min_free;
1996}
1997
Dave Chinner6cc87642009-03-16 08:29:46 +01001998/*
Dave Chinner72d55282015-06-22 10:04:42 +10001999 * Check if the operation we are fixing up the freelist for should go ahead or
2000 * not. If we are freeing blocks, we always allow it, otherwise the allocation
2001 * is dependent on whether the size and shape of free space available will
2002 * permit the requested allocation to take place.
2003 */
2004static bool
2005xfs_alloc_space_available(
2006 struct xfs_alloc_arg *args,
2007 xfs_extlen_t min_free,
2008 int flags)
2009{
2010 struct xfs_perag *pag = args->pag;
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002011 xfs_extlen_t alloc_len, longest;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002012 xfs_extlen_t reservation; /* blocks that are still reserved */
Dave Chinner72d55282015-06-22 10:04:42 +10002013 int available;
2014
2015 if (flags & XFS_ALLOC_FLAG_FREEING)
2016 return true;
2017
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002018 reservation = xfs_ag_resv_needed(pag, args->resv);
2019
Dave Chinner72d55282015-06-22 10:04:42 +10002020 /* do we have enough contiguous free space for the allocation? */
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002021 alloc_len = args->minlen + (args->alignment - 1) + args->minalignslop;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002022 longest = xfs_alloc_longest_free_extent(args->mp, pag, min_free,
2023 reservation);
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002024 if (longest < alloc_len)
Dave Chinner72d55282015-06-22 10:04:42 +10002025 return false;
2026
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002027 /* do we have enough free space remaining for the allocation? */
Dave Chinner72d55282015-06-22 10:04:42 +10002028 available = (int)(pag->pagf_freeblks + pag->pagf_flcount -
Christoph Hellwig54fee132017-01-09 13:44:30 -08002029 reservation - min_free - args->minleft);
Christoph Hellwig12ef8302017-01-09 13:39:35 -08002030 if (available < (int)max(args->total, alloc_len))
Dave Chinner72d55282015-06-22 10:04:42 +10002031 return false;
2032
Christoph Hellwig54fee132017-01-09 13:44:30 -08002033 /*
2034 * Clamp maxlen to the amount of free space available for the actual
2035 * extent allocation.
2036 */
2037 if (available < (int)args->maxlen && !(flags & XFS_ALLOC_FLAG_CHECK)) {
2038 args->maxlen = available;
2039 ASSERT(args->maxlen > 0);
2040 ASSERT(args->maxlen >= args->minlen);
2041 }
2042
Dave Chinner72d55282015-06-22 10:04:42 +10002043 return true;
2044}
2045
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046/*
2047 * Decide whether to use this allocation group for this allocation.
2048 * If so, fix up the btree freelist's size.
2049 */
Darrick J. Wong2e9101d2016-01-04 16:10:42 +11002050int /* error */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051xfs_alloc_fix_freelist(
Dave Chinner396503f2015-06-22 10:13:19 +10002052 struct xfs_alloc_arg *args, /* allocation argument structure */
2053 int flags) /* XFS_ALLOC_FLAG_... */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054{
Dave Chinner396503f2015-06-22 10:13:19 +10002055 struct xfs_mount *mp = args->mp;
2056 struct xfs_perag *pag = args->pag;
2057 struct xfs_trans *tp = args->tp;
2058 struct xfs_buf *agbp = NULL;
2059 struct xfs_buf *agflbp = NULL;
2060 struct xfs_alloc_arg targs; /* local allocation arguments */
2061 xfs_agblock_t bno; /* freelist block */
2062 xfs_extlen_t need; /* total blocks needed in freelist */
Jan Karac184f852015-08-25 10:05:13 +10002063 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065 if (!pag->pagf_init) {
Dave Chinner396503f2015-06-22 10:13:19 +10002066 error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
2067 if (error)
2068 goto out_no_agbp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069 if (!pag->pagf_init) {
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002070 ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
2071 ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
Dave Chinner396503f2015-06-22 10:13:19 +10002072 goto out_agbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 }
Dave Chinner396503f2015-06-22 10:13:19 +10002074 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002076 /*
Dave Chinner396503f2015-06-22 10:13:19 +10002077 * If this is a metadata preferred pag and we are user data then try
2078 * somewhere else if we are not being asked to try harder at this
2079 * point
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080 */
Dave Chinner292378e2016-09-26 08:21:28 +10002081 if (pag->pagf_metadata && xfs_alloc_is_userdata(args->datatype) &&
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002082 (flags & XFS_ALLOC_FLAG_TRYLOCK)) {
2083 ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
Dave Chinner396503f2015-06-22 10:13:19 +10002084 goto out_agbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 }
2086
Dave Chinner496817b2015-06-22 10:13:30 +10002087 need = xfs_alloc_min_freelist(mp, pag);
Christoph Hellwig54fee132017-01-09 13:44:30 -08002088 if (!xfs_alloc_space_available(args, need, flags |
2089 XFS_ALLOC_FLAG_CHECK))
Dave Chinner396503f2015-06-22 10:13:19 +10002090 goto out_agbp_relse;
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002091
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092 /*
2093 * Get the a.g. freespace buffer.
2094 * Can fail if we're not blocking on locks, and it's held.
2095 */
Dave Chinner396503f2015-06-22 10:13:19 +10002096 if (!agbp) {
2097 error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
2098 if (error)
2099 goto out_no_agbp;
2100 if (!agbp) {
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002101 ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
2102 ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
Dave Chinner396503f2015-06-22 10:13:19 +10002103 goto out_no_agbp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104 }
2105 }
Dave Chinner50adbcb2015-06-22 10:04:31 +10002106
Dave Chinner50adbcb2015-06-22 10:04:31 +10002107 /* If there isn't enough total space or single-extent, reject it. */
Dave Chinner496817b2015-06-22 10:13:30 +10002108 need = xfs_alloc_min_freelist(mp, pag);
Dave Chinner396503f2015-06-22 10:13:19 +10002109 if (!xfs_alloc_space_available(args, need, flags))
2110 goto out_agbp_relse;
Dave Chinner72d55282015-06-22 10:04:42 +10002111
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112 /*
2113 * Make the freelist shorter if it's too long.
Dave Chinner50adbcb2015-06-22 10:04:31 +10002114 *
Dave Chinner396503f2015-06-22 10:13:19 +10002115 * Note that from this point onwards, we will always release the agf and
2116 * agfl buffers on error. This handles the case where we error out and
2117 * the buffers are clean or may not have been joined to the transaction
2118 * and hence need to be released manually. If they have been joined to
2119 * the transaction, then xfs_trans_brelse() will handle them
2120 * appropriately based on the recursion count and dirty state of the
2121 * buffer.
2122 *
Dave Chinner50adbcb2015-06-22 10:04:31 +10002123 * XXX (dgc): When we have lots of free space, does this buy us
2124 * anything other than extra overhead when we need to put more blocks
2125 * back on the free list? Maybe we should only do this when space is
2126 * getting low or the AGFL is more than half full?
Darrick J. Wong04f13062016-08-03 12:19:53 +10002127 *
2128 * The NOSHRINK flag prevents the AGFL from being shrunk if it's too
2129 * big; the NORMAP flag prevents AGFL expand/shrink operations from
2130 * updating the rmapbt. Both flags are used in xfs_repair while we're
2131 * rebuilding the rmapbt, and neither are used by the kernel. They're
2132 * both required to ensure that rmaps are correctly recorded for the
2133 * regenerated AGFL, bnobt, and cntbt. See repair/phase5.c and
2134 * repair/rmap.c in xfsprogs for details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135 */
Darrick J. Wong04f13062016-08-03 12:19:53 +10002136 memset(&targs, 0, sizeof(targs));
2137 if (flags & XFS_ALLOC_FLAG_NORMAP)
2138 xfs_rmap_skip_owner_update(&targs.oinfo);
2139 else
2140 xfs_rmap_ag_owner(&targs.oinfo, XFS_RMAP_OWN_AG);
2141 while (!(flags & XFS_ALLOC_FLAG_NOSHRINK) && pag->pagf_flcount > need) {
Dave Chinner50adbcb2015-06-22 10:04:31 +10002142 struct xfs_buf *bp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143
David Chinner92821e22007-05-24 15:26:31 +10002144 error = xfs_alloc_get_freelist(tp, agbp, &bno, 0);
2145 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002146 goto out_agbp_relse;
Darrick J. Wong340785c2016-08-03 11:33:42 +10002147 error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1,
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002148 &targs.oinfo, XFS_AG_RESV_AGFL);
Dave Chinner50adbcb2015-06-22 10:04:31 +10002149 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002150 goto out_agbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002151 bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0);
Eric Sandeen93e8bef2017-10-09 21:08:06 -07002152 if (!bp) {
2153 error = -EFSCORRUPTED;
2154 goto out_agbp_relse;
2155 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 xfs_trans_binval(tp, bp);
2157 }
Dave Chinner50adbcb2015-06-22 10:04:31 +10002158
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159 targs.tp = tp;
2160 targs.mp = mp;
2161 targs.agbp = agbp;
2162 targs.agno = args->agno;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002163 targs.alignment = targs.minlen = targs.prod = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164 targs.type = XFS_ALLOCTYPE_THIS_AG;
2165 targs.pag = pag;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002166 error = xfs_alloc_read_agfl(mp, tp, targs.agno, &agflbp);
2167 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002168 goto out_agbp_relse;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002169
2170 /* Make the freelist longer if it's too short. */
2171 while (pag->pagf_flcount < need) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172 targs.agbno = 0;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002173 targs.maxlen = need - pag->pagf_flcount;
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002174 targs.resv = XFS_AG_RESV_AGFL;
Dave Chinner50adbcb2015-06-22 10:04:31 +10002175
2176 /* Allocate as many blocks as possible at once. */
2177 error = xfs_alloc_ag_vextent(&targs);
Dave Chinner396503f2015-06-22 10:13:19 +10002178 if (error)
2179 goto out_agflbp_relse;
2180
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181 /*
2182 * Stop if we run out. Won't happen if callers are obeying
2183 * the restrictions correctly. Can happen for free calls
2184 * on a completely full ag.
2185 */
Yingping Lud210a282006-06-09 14:55:18 +10002186 if (targs.agbno == NULLAGBLOCK) {
Nathan Scott0e1edbd2006-08-10 14:40:41 +10002187 if (flags & XFS_ALLOC_FLAG_FREEING)
2188 break;
Dave Chinner396503f2015-06-22 10:13:19 +10002189 goto out_agflbp_relse;
Yingping Lud210a282006-06-09 14:55:18 +10002190 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 /*
2192 * Put each allocated block on the list.
2193 */
2194 for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) {
David Chinner92821e22007-05-24 15:26:31 +10002195 error = xfs_alloc_put_freelist(tp, agbp,
2196 agflbp, bno, 0);
2197 if (error)
Dave Chinner396503f2015-06-22 10:13:19 +10002198 goto out_agflbp_relse;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 }
2200 }
Nathan Scotte63a3692006-05-08 19:51:58 +10002201 xfs_trans_brelse(tp, agflbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202 args->agbp = agbp;
2203 return 0;
Dave Chinner396503f2015-06-22 10:13:19 +10002204
2205out_agflbp_relse:
2206 xfs_trans_brelse(tp, agflbp);
2207out_agbp_relse:
2208 if (agbp)
2209 xfs_trans_brelse(tp, agbp);
2210out_no_agbp:
2211 args->agbp = NULL;
2212 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213}
2214
2215/*
2216 * Get a block from the freelist.
2217 * Returns with the buffer for the block gotten.
2218 */
2219int /* error */
2220xfs_alloc_get_freelist(
2221 xfs_trans_t *tp, /* transaction pointer */
2222 xfs_buf_t *agbp, /* buffer containing the agf structure */
David Chinner92821e22007-05-24 15:26:31 +10002223 xfs_agblock_t *bnop, /* block address retrieved from freelist */
2224 int btreeblk) /* destination is a AGF btree */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225{
2226 xfs_agf_t *agf; /* a.g. freespace structure */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */
2228 xfs_agblock_t bno; /* block number returned */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002229 __be32 *agfl_bno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 int error;
David Chinner92821e22007-05-24 15:26:31 +10002231 int logflags;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002232 xfs_mount_t *mp = tp->t_mountp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233 xfs_perag_t *pag; /* per allocation group data */
2234
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235 /*
2236 * Freelist is empty, give up.
2237 */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002238 agf = XFS_BUF_TO_AGF(agbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 if (!agf->agf_flcount) {
2240 *bnop = NULLAGBLOCK;
2241 return 0;
2242 }
2243 /*
2244 * Read the array of free blocks.
2245 */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002246 error = xfs_alloc_read_agfl(mp, tp, be32_to_cpu(agf->agf_seqno),
2247 &agflbp);
2248 if (error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249 return error;
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002250
2251
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 /*
2253 * Get the block number and update the data structures.
2254 */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002255 agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
2256 bno = be32_to_cpu(agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002257 be32_add_cpu(&agf->agf_flfirst, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 xfs_trans_brelse(tp, agflbp);
Christoph Hellwig16259e72005-11-02 15:11:25 +11002259 if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 agf->agf_flfirst = 0;
Dave Chinnera862e0f2010-01-11 11:47:41 +00002261
2262 pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002263 be32_add_cpu(&agf->agf_flcount, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264 xfs_trans_agflist_delta(tp, -1);
2265 pag->pagf_flcount--;
Dave Chinnera862e0f2010-01-11 11:47:41 +00002266 xfs_perag_put(pag);
David Chinner92821e22007-05-24 15:26:31 +10002267
2268 logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
2269 if (btreeblk) {
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002270 be32_add_cpu(&agf->agf_btreeblks, 1);
David Chinner92821e22007-05-24 15:26:31 +10002271 pag->pagf_btreeblks++;
2272 logflags |= XFS_AGF_BTREEBLKS;
2273 }
2274
David Chinner92821e22007-05-24 15:26:31 +10002275 xfs_alloc_log_agf(tp, agbp, logflags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276 *bnop = bno;
2277
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278 return 0;
2279}
2280
2281/*
2282 * Log the given fields from the agf structure.
2283 */
2284void
2285xfs_alloc_log_agf(
2286 xfs_trans_t *tp, /* transaction pointer */
2287 xfs_buf_t *bp, /* buffer for a.g. freelist header */
2288 int fields) /* mask of fields to be logged (XFS_AGF_...) */
2289{
2290 int first; /* first byte offset */
2291 int last; /* last byte offset */
2292 static const short offsets[] = {
2293 offsetof(xfs_agf_t, agf_magicnum),
2294 offsetof(xfs_agf_t, agf_versionnum),
2295 offsetof(xfs_agf_t, agf_seqno),
2296 offsetof(xfs_agf_t, agf_length),
2297 offsetof(xfs_agf_t, agf_roots[0]),
2298 offsetof(xfs_agf_t, agf_levels[0]),
2299 offsetof(xfs_agf_t, agf_flfirst),
2300 offsetof(xfs_agf_t, agf_fllast),
2301 offsetof(xfs_agf_t, agf_flcount),
2302 offsetof(xfs_agf_t, agf_freeblks),
2303 offsetof(xfs_agf_t, agf_longest),
David Chinner92821e22007-05-24 15:26:31 +10002304 offsetof(xfs_agf_t, agf_btreeblks),
Dave Chinner4e0e6042013-04-03 16:11:13 +11002305 offsetof(xfs_agf_t, agf_uuid),
Darrick J. Wongf32866fd2016-08-17 08:31:49 +10002306 offsetof(xfs_agf_t, agf_rmap_blocks),
Darrick J. Wongbdf28632016-10-03 09:11:19 -07002307 offsetof(xfs_agf_t, agf_refcount_blocks),
2308 offsetof(xfs_agf_t, agf_refcount_root),
2309 offsetof(xfs_agf_t, agf_refcount_level),
Darrick J. Wongda1f0392016-08-26 15:59:31 +10002310 /* needed so that we don't log the whole rest of the structure: */
2311 offsetof(xfs_agf_t, agf_spare64),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312 sizeof(xfs_agf_t)
2313 };
2314
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002315 trace_xfs_agf(tp->t_mountp, XFS_BUF_TO_AGF(bp), fields, _RET_IP_);
2316
Dave Chinner61fe1352013-04-03 16:11:30 +11002317 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGF_BUF);
Dave Chinner4e0e6042013-04-03 16:11:13 +11002318
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 xfs_btree_offsets(fields, offsets, XFS_AGF_NUM_BITS, &first, &last);
2320 xfs_trans_log_buf(tp, bp, (uint)first, (uint)last);
2321}
2322
2323/*
2324 * Interface for inode allocation to force the pag data to be initialized.
2325 */
2326int /* error */
2327xfs_alloc_pagf_init(
2328 xfs_mount_t *mp, /* file system mount structure */
2329 xfs_trans_t *tp, /* transaction pointer */
2330 xfs_agnumber_t agno, /* allocation group number */
2331 int flags) /* XFS_ALLOC_FLAGS_... */
2332{
2333 xfs_buf_t *bp;
2334 int error;
2335
2336 if ((error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp)))
2337 return error;
2338 if (bp)
2339 xfs_trans_brelse(tp, bp);
2340 return 0;
2341}
2342
2343/*
2344 * Put the block on the freelist for the allocation group.
2345 */
2346int /* error */
2347xfs_alloc_put_freelist(
2348 xfs_trans_t *tp, /* transaction pointer */
2349 xfs_buf_t *agbp, /* buffer for a.g. freelist header */
2350 xfs_buf_t *agflbp,/* buffer for a.g. free block array */
David Chinner92821e22007-05-24 15:26:31 +10002351 xfs_agblock_t bno, /* block being freed */
2352 int btreeblk) /* block came from a AGF btree */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353{
2354 xfs_agf_t *agf; /* a.g. freespace structure */
Christoph Hellwige2101002006-09-28 10:56:51 +10002355 __be32 *blockp;/* pointer to array entry */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002356 int error;
David Chinner92821e22007-05-24 15:26:31 +10002357 int logflags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358 xfs_mount_t *mp; /* mount structure */
2359 xfs_perag_t *pag; /* per allocation group data */
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002360 __be32 *agfl_bno;
2361 int startoff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362
2363 agf = XFS_BUF_TO_AGF(agbp);
2364 mp = tp->t_mountp;
2365
2366 if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp,
Christoph Hellwig16259e72005-11-02 15:11:25 +11002367 be32_to_cpu(agf->agf_seqno), &agflbp)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368 return error;
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002369 be32_add_cpu(&agf->agf_fllast, 1);
Christoph Hellwig16259e72005-11-02 15:11:25 +11002370 if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371 agf->agf_fllast = 0;
Dave Chinnera862e0f2010-01-11 11:47:41 +00002372
2373 pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002374 be32_add_cpu(&agf->agf_flcount, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375 xfs_trans_agflist_delta(tp, 1);
2376 pag->pagf_flcount++;
David Chinner92821e22007-05-24 15:26:31 +10002377
2378 logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
2379 if (btreeblk) {
Marcin Slusarz413d57c2008-02-13 15:03:29 -08002380 be32_add_cpu(&agf->agf_btreeblks, -1);
David Chinner92821e22007-05-24 15:26:31 +10002381 pag->pagf_btreeblks--;
2382 logflags |= XFS_AGF_BTREEBLKS;
2383 }
Dave Chinnera862e0f2010-01-11 11:47:41 +00002384 xfs_perag_put(pag);
David Chinner92821e22007-05-24 15:26:31 +10002385
David Chinner92821e22007-05-24 15:26:31 +10002386 xfs_alloc_log_agf(tp, agbp, logflags);
2387
Christoph Hellwig16259e72005-11-02 15:11:25 +11002388 ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002389
2390 agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
2391 blockp = &agfl_bno[be32_to_cpu(agf->agf_fllast)];
Christoph Hellwige2101002006-09-28 10:56:51 +10002392 *blockp = cpu_to_be32(bno);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002393 startoff = (char *)blockp - (char *)agflbp->b_addr;
2394
David Chinner92821e22007-05-24 15:26:31 +10002395 xfs_alloc_log_agf(tp, agbp, logflags);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002396
Dave Chinner61fe1352013-04-03 16:11:30 +11002397 xfs_trans_buf_set_type(tp, agflbp, XFS_BLFT_AGFL_BUF);
Christoph Hellwig77c95bb2013-04-03 16:11:14 +11002398 xfs_trans_log_buf(tp, agflbp, startoff,
2399 startoff + sizeof(xfs_agblock_t) - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400 return 0;
2401}
2402
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002403static xfs_failaddr_t
Dave Chinner612cfbf2012-11-14 17:52:32 +11002404xfs_agf_verify(
Dave Chinner4e0e6042013-04-03 16:11:13 +11002405 struct xfs_mount *mp,
Dave Chinner5d5f5272012-11-14 17:44:56 +11002406 struct xfs_buf *bp)
2407 {
Dave Chinner4e0e6042013-04-03 16:11:13 +11002408 struct xfs_agf *agf = XFS_BUF_TO_AGF(bp);
Dave Chinner5d5f5272012-11-14 17:44:56 +11002409
Brian Fostera45086e2015-10-12 15:59:25 +11002410 if (xfs_sb_version_hascrc(&mp->m_sb)) {
2411 if (!uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002412 return __this_address;
Brian Fostera45086e2015-10-12 15:59:25 +11002413 if (!xfs_log_check_lsn(mp,
2414 be64_to_cpu(XFS_BUF_TO_AGF(bp)->agf_lsn)))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002415 return __this_address;
Brian Fostera45086e2015-10-12 15:59:25 +11002416 }
Dave Chinner5d5f5272012-11-14 17:44:56 +11002417
Dave Chinner4e0e6042013-04-03 16:11:13 +11002418 if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
2419 XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
2420 be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
2421 be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) &&
2422 be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) &&
2423 be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002424 return __this_address;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002425
Darrick J. Wongd2a047f2016-12-05 12:32:50 +11002426 if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
2427 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
2428 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
Eric Sandeene1b05722014-09-09 11:47:24 +10002429 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002430 return __this_address;
Eric Sandeene1b05722014-09-09 11:47:24 +10002431
Darrick J. Wongb8704942016-08-03 11:30:32 +10002432 if (xfs_sb_version_hasrmapbt(&mp->m_sb) &&
Darrick J. Wongd2a047f2016-12-05 12:32:50 +11002433 (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 ||
2434 be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002435 return __this_address;
Darrick J. Wongb8704942016-08-03 11:30:32 +10002436
Dave Chinner5d5f5272012-11-14 17:44:56 +11002437 /*
2438 * during growfs operations, the perag is not fully initialised,
2439 * so we can't use it for any useful checking. growfs ensures we can't
2440 * use it by using uncached buffers that don't have the perag attached
2441 * so we can detect and avoid this problem.
2442 */
Dave Chinner4e0e6042013-04-03 16:11:13 +11002443 if (bp->b_pag && be32_to_cpu(agf->agf_seqno) != bp->b_pag->pag_agno)
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002444 return __this_address;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002445
Dave Chinner4e0e6042013-04-03 16:11:13 +11002446 if (xfs_sb_version_haslazysbcount(&mp->m_sb) &&
2447 be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002448 return __this_address;
Dave Chinner5d5f5272012-11-14 17:44:56 +11002449
Darrick J. Wong46eeb522016-10-03 09:11:16 -07002450 if (xfs_sb_version_hasreflink(&mp->m_sb) &&
Darrick J. Wongd2a047f2016-12-05 12:32:50 +11002451 (be32_to_cpu(agf->agf_refcount_level) < 1 ||
2452 be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS))
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002453 return __this_address;
Darrick J. Wong46eeb522016-10-03 09:11:16 -07002454
Darrick J. Wonga6a781a2018-01-08 10:51:03 -08002455 return NULL;
Dave Chinner4e0e6042013-04-03 16:11:13 +11002456
Dave Chinner612cfbf2012-11-14 17:52:32 +11002457}
Dave Chinner5d5f5272012-11-14 17:44:56 +11002458
Dave Chinner1813dd62012-11-14 17:54:40 +11002459static void
2460xfs_agf_read_verify(
Dave Chinner612cfbf2012-11-14 17:52:32 +11002461 struct xfs_buf *bp)
2462{
Dave Chinner4e0e6042013-04-03 16:11:13 +11002463 struct xfs_mount *mp = bp->b_target->bt_mount;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002464 xfs_failaddr_t fa;
Dave Chinner4e0e6042013-04-03 16:11:13 +11002465
Eric Sandeence5028c2014-02-27 15:23:10 +11002466 if (xfs_sb_version_hascrc(&mp->m_sb) &&
2467 !xfs_buf_verify_cksum(bp, XFS_AGF_CRC_OFF))
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002468 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
2469 else {
2470 fa = xfs_agf_verify(mp, bp);
2471 if (XFS_TEST_ERROR(fa, mp, XFS_ERRTAG_ALLOC_READ_AGF))
2472 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
2473 }
Dave Chinner612cfbf2012-11-14 17:52:32 +11002474}
2475
Dave Chinnerb0f539d2012-11-14 17:53:49 +11002476static void
Dave Chinner1813dd62012-11-14 17:54:40 +11002477xfs_agf_write_verify(
Dave Chinner612cfbf2012-11-14 17:52:32 +11002478 struct xfs_buf *bp)
2479{
Dave Chinner4e0e6042013-04-03 16:11:13 +11002480 struct xfs_mount *mp = bp->b_target->bt_mount;
2481 struct xfs_buf_log_item *bip = bp->b_fspriv;
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002482 xfs_failaddr_t fa;
Dave Chinner4e0e6042013-04-03 16:11:13 +11002483
Darrick J. Wongbc1a09b2018-01-08 10:51:03 -08002484 fa = xfs_agf_verify(mp, bp);
2485 if (fa) {
2486 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
Dave Chinner4e0e6042013-04-03 16:11:13 +11002487 return;
2488 }
2489
2490 if (!xfs_sb_version_hascrc(&mp->m_sb))
2491 return;
2492
2493 if (bip)
2494 XFS_BUF_TO_AGF(bp)->agf_lsn = cpu_to_be64(bip->bli_item.li_lsn);
2495
Eric Sandeenf1dbcd72014-02-27 15:18:23 +11002496 xfs_buf_update_cksum(bp, XFS_AGF_CRC_OFF);
Dave Chinner5d5f5272012-11-14 17:44:56 +11002497}
2498
Dave Chinner1813dd62012-11-14 17:54:40 +11002499const struct xfs_buf_ops xfs_agf_buf_ops = {
Eric Sandeen233135b2016-01-04 16:10:19 +11002500 .name = "xfs_agf",
Dave Chinner1813dd62012-11-14 17:54:40 +11002501 .verify_read = xfs_agf_read_verify,
2502 .verify_write = xfs_agf_write_verify,
2503};
2504
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505/*
2506 * Read in the allocation group header (free/alloc section).
2507 */
2508int /* error */
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002509xfs_read_agf(
2510 struct xfs_mount *mp, /* mount point structure */
2511 struct xfs_trans *tp, /* transaction pointer */
2512 xfs_agnumber_t agno, /* allocation group number */
2513 int flags, /* XFS_BUF_ */
2514 struct xfs_buf **bpp) /* buffer for the ag freelist header */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 int error;
2517
Dave Chinnerd1230312013-11-01 15:27:19 +11002518 trace_xfs_read_agf(mp, agno);
2519
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520 ASSERT(agno != NULLAGNUMBER);
2521 error = xfs_trans_read_buf(
2522 mp, tp, mp->m_ddev_targp,
2523 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
Dave Chinner1813dd62012-11-14 17:54:40 +11002524 XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 if (error)
2526 return error;
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002527 if (!*bpp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528 return 0;
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002529
Chandra Seetharaman5a52c2a582011-07-22 23:39:51 +00002530 ASSERT(!(*bpp)->b_error);
Christoph Hellwig38f23232011-10-10 16:52:45 +00002531 xfs_buf_set_ref(*bpp, XFS_AGF_REF);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002532 return 0;
2533}
2534
2535/*
2536 * Read in the allocation group header (free/alloc section).
2537 */
2538int /* error */
2539xfs_alloc_read_agf(
2540 struct xfs_mount *mp, /* mount point structure */
2541 struct xfs_trans *tp, /* transaction pointer */
2542 xfs_agnumber_t agno, /* allocation group number */
2543 int flags, /* XFS_ALLOC_FLAG_... */
2544 struct xfs_buf **bpp) /* buffer for the ag freelist header */
2545{
2546 struct xfs_agf *agf; /* ag freelist header */
2547 struct xfs_perag *pag; /* per allocation group data */
2548 int error;
2549
Dave Chinnerd1230312013-11-01 15:27:19 +11002550 trace_xfs_alloc_read_agf(mp, agno);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002551
Dave Chinnerd1230312013-11-01 15:27:19 +11002552 ASSERT(agno != NULLAGNUMBER);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002553 error = xfs_read_agf(mp, tp, agno,
Christoph Hellwig0cadda12010-01-19 09:56:44 +00002554 (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0,
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002555 bpp);
2556 if (error)
2557 return error;
2558 if (!*bpp)
2559 return 0;
Chandra Seetharaman5a52c2a582011-07-22 23:39:51 +00002560 ASSERT(!(*bpp)->b_error);
From: Christoph Hellwig48056212008-11-28 14:23:38 +11002561
2562 agf = XFS_BUF_TO_AGF(*bpp);
Dave Chinnera862e0f2010-01-11 11:47:41 +00002563 pag = xfs_perag_get(mp, agno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 if (!pag->pagf_init) {
Christoph Hellwig16259e72005-11-02 15:11:25 +11002565 pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
David Chinner92821e22007-05-24 15:26:31 +10002566 pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
Christoph Hellwig16259e72005-11-02 15:11:25 +11002567 pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
2568 pag->pagf_longest = be32_to_cpu(agf->agf_longest);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569 pag->pagf_levels[XFS_BTNUM_BNOi] =
Christoph Hellwig16259e72005-11-02 15:11:25 +11002570 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571 pag->pagf_levels[XFS_BTNUM_CNTi] =
Christoph Hellwig16259e72005-11-02 15:11:25 +11002572 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
Darrick J. Wongb8704942016-08-03 11:30:32 +10002573 pag->pagf_levels[XFS_BTNUM_RMAPi] =
2574 be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]);
Darrick J. Wong46eeb522016-10-03 09:11:16 -07002575 pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
Eric Sandeen007c61c2007-10-11 17:43:56 +10002576 spin_lock_init(&pag->pagb_lock);
Dave Chinnere57336f2010-01-11 11:47:49 +00002577 pag->pagb_count = 0;
Dave Chinnered3b4d62010-05-21 12:07:08 +10002578 pag->pagb_tree = RB_ROOT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579 pag->pagf_init = 1;
2580 }
2581#ifdef DEBUG
2582 else if (!XFS_FORCED_SHUTDOWN(mp)) {
Christoph Hellwig16259e72005-11-02 15:11:25 +11002583 ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks));
Barry Naujok89b28392008-10-30 17:05:49 +11002584 ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks));
Christoph Hellwig16259e72005-11-02 15:11:25 +11002585 ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
2586 ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587 ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] ==
Christoph Hellwig16259e72005-11-02 15:11:25 +11002588 be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589 ASSERT(pag->pagf_levels[XFS_BTNUM_CNTi] ==
Christoph Hellwig16259e72005-11-02 15:11:25 +11002590 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591 }
2592#endif
Dave Chinnera862e0f2010-01-11 11:47:41 +00002593 xfs_perag_put(pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594 return 0;
2595}
2596
2597/*
2598 * Allocate an extent (variable-size).
2599 * Depending on the allocation type, we either look in a single allocation
2600 * group or loop over the allocation groups to find the result.
2601 */
2602int /* error */
Dave Chinnere04426b2012-10-05 11:06:59 +10002603xfs_alloc_vextent(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604 xfs_alloc_arg_t *args) /* allocation argument structure */
2605{
2606 xfs_agblock_t agsize; /* allocation group size */
2607 int error;
2608 int flags; /* XFS_ALLOC_FLAG_... locking flags */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 xfs_mount_t *mp; /* mount structure pointer */
2610 xfs_agnumber_t sagno; /* starting allocation group number */
2611 xfs_alloctype_t type; /* input allocation type */
2612 int bump_rotor = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613 xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */
2614
2615 mp = args->mp;
2616 type = args->otype = args->type;
2617 args->agbno = NULLAGBLOCK;
2618 /*
2619 * Just fix this up, for the case where the last a.g. is shorter
2620 * (or there's only one a.g.) and the caller couldn't easily figure
2621 * that out (xfs_bmap_alloc).
2622 */
2623 agsize = mp->m_sb.sb_agblocks;
2624 if (args->maxlen > agsize)
2625 args->maxlen = agsize;
2626 if (args->alignment == 0)
2627 args->alignment = 1;
2628 ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_sb.sb_agcount);
2629 ASSERT(XFS_FSB_TO_AGBNO(mp, args->fsbno) < agsize);
2630 ASSERT(args->minlen <= args->maxlen);
2631 ASSERT(args->minlen <= agsize);
2632 ASSERT(args->mod < args->prod);
2633 if (XFS_FSB_TO_AGNO(mp, args->fsbno) >= mp->m_sb.sb_agcount ||
2634 XFS_FSB_TO_AGBNO(mp, args->fsbno) >= agsize ||
2635 args->minlen > args->maxlen || args->minlen > agsize ||
2636 args->mod >= args->prod) {
2637 args->fsbno = NULLFSBLOCK;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002638 trace_xfs_alloc_vextent_badargs(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639 return 0;
2640 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641
2642 switch (type) {
2643 case XFS_ALLOCTYPE_THIS_AG:
2644 case XFS_ALLOCTYPE_NEAR_BNO:
2645 case XFS_ALLOCTYPE_THIS_BNO:
2646 /*
2647 * These three force us into a single a.g.
2648 */
2649 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
Dave Chinnera862e0f2010-01-11 11:47:41 +00002650 args->pag = xfs_perag_get(mp, args->agno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651 error = xfs_alloc_fix_freelist(args, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652 if (error) {
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002653 trace_xfs_alloc_vextent_nofix(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 goto error0;
2655 }
2656 if (!args->agbp) {
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002657 trace_xfs_alloc_vextent_noagbp(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 break;
2659 }
2660 args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno);
2661 if ((error = xfs_alloc_ag_vextent(args)))
2662 goto error0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 break;
2664 case XFS_ALLOCTYPE_START_BNO:
2665 /*
2666 * Try near allocation first, then anywhere-in-ag after
2667 * the first a.g. fails.
2668 */
Dave Chinner292378e2016-09-26 08:21:28 +10002669 if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670 (mp->m_flags & XFS_MOUNT_32BITINODES)) {
2671 args->fsbno = XFS_AGB_TO_FSB(mp,
2672 ((mp->m_agfrotor / rotorstep) %
2673 mp->m_sb.sb_agcount), 0);
2674 bump_rotor = 1;
2675 }
2676 args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno);
2677 args->type = XFS_ALLOCTYPE_NEAR_BNO;
2678 /* FALLTHROUGH */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679 case XFS_ALLOCTYPE_FIRST_AG:
2680 /*
2681 * Rotate through the allocation groups looking for a winner.
2682 */
Christoph Hellwig8d242e92017-02-17 08:21:15 -08002683 if (type == XFS_ALLOCTYPE_FIRST_AG) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684 /*
2685 * Start with allocation group given by bno.
2686 */
2687 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
2688 args->type = XFS_ALLOCTYPE_THIS_AG;
2689 sagno = 0;
2690 flags = 0;
2691 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692 /*
2693 * Start with the given allocation group.
2694 */
2695 args->agno = sagno = XFS_FSB_TO_AGNO(mp, args->fsbno);
2696 flags = XFS_ALLOC_FLAG_TRYLOCK;
2697 }
2698 /*
2699 * Loop over allocation groups twice; first time with
2700 * trylock set, second time without.
2701 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702 for (;;) {
Dave Chinnera862e0f2010-01-11 11:47:41 +00002703 args->pag = xfs_perag_get(mp, args->agno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 error = xfs_alloc_fix_freelist(args, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705 if (error) {
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002706 trace_xfs_alloc_vextent_nofix(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707 goto error0;
2708 }
2709 /*
2710 * If we get a buffer back then the allocation will fly.
2711 */
2712 if (args->agbp) {
2713 if ((error = xfs_alloc_ag_vextent(args)))
2714 goto error0;
2715 break;
2716 }
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002717
2718 trace_xfs_alloc_vextent_loopfailed(args);
2719
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720 /*
2721 * Didn't work, figure out the next iteration.
2722 */
2723 if (args->agno == sagno &&
2724 type == XFS_ALLOCTYPE_START_BNO)
2725 args->type = XFS_ALLOCTYPE_THIS_AG;
Yingping Lud210a282006-06-09 14:55:18 +10002726 /*
2727 * For the first allocation, we can try any AG to get
2728 * space. However, if we already have allocated a
2729 * block, we don't want to try AGs whose number is below
2730 * sagno. Otherwise, we may end up with out-of-order
2731 * locking of AGF, which might cause deadlock.
2732 */
2733 if (++(args->agno) == mp->m_sb.sb_agcount) {
2734 if (args->firstblock != NULLFSBLOCK)
2735 args->agno = sagno;
2736 else
2737 args->agno = 0;
2738 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739 /*
2740 * Reached the starting a.g., must either be done
2741 * or switch to non-trylock mode.
2742 */
2743 if (args->agno == sagno) {
Christoph Hellwig255c5162017-01-09 13:36:19 -08002744 if (flags == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745 args->agbno = NULLAGBLOCK;
Christoph Hellwig0b1b2132009-12-14 23:14:59 +00002746 trace_xfs_alloc_vextent_allfailed(args);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747 break;
2748 }
Christoph Hellwig255c5162017-01-09 13:36:19 -08002749
2750 flags = 0;
2751 if (type == XFS_ALLOCTYPE_START_BNO) {
2752 args->agbno = XFS_FSB_TO_AGBNO(mp,
2753 args->fsbno);
2754 args->type = XFS_ALLOCTYPE_NEAR_BNO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755 }
2756 }
Dave Chinnera862e0f2010-01-11 11:47:41 +00002757 xfs_perag_put(args->pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758 }
Christoph Hellwig8d242e92017-02-17 08:21:15 -08002759 if (bump_rotor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760 if (args->agno == sagno)
2761 mp->m_agfrotor = (mp->m_agfrotor + 1) %
2762 (mp->m_sb.sb_agcount * rotorstep);
2763 else
2764 mp->m_agfrotor = (args->agno * rotorstep + 1) %
2765 (mp->m_sb.sb_agcount * rotorstep);
2766 }
2767 break;
2768 default:
2769 ASSERT(0);
2770 /* NOTREACHED */
2771 }
2772 if (args->agbno == NULLAGBLOCK)
2773 args->fsbno = NULLFSBLOCK;
2774 else {
2775 args->fsbno = XFS_AGB_TO_FSB(mp, args->agno, args->agbno);
2776#ifdef DEBUG
2777 ASSERT(args->len >= args->minlen);
2778 ASSERT(args->len <= args->maxlen);
2779 ASSERT(args->agbno % args->alignment == 0);
2780 XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno),
2781 args->len);
2782#endif
Dave Chinner3fbbbea2015-11-03 12:27:22 +11002783
2784 /* Zero the extent if we were asked to do so */
Dave Chinner292378e2016-09-26 08:21:28 +10002785 if (args->datatype & XFS_ALLOC_USERDATA_ZERO) {
Dave Chinner3fbbbea2015-11-03 12:27:22 +11002786 error = xfs_zero_extent(args->ip, args->fsbno, args->len);
2787 if (error)
2788 goto error0;
2789 }
2790
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791 }
Dave Chinnera862e0f2010-01-11 11:47:41 +00002792 xfs_perag_put(args->pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793 return 0;
2794error0:
Dave Chinnera862e0f2010-01-11 11:47:41 +00002795 xfs_perag_put(args->pag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796 return error;
2797}
2798
Dave Chinner4d89e202016-06-21 11:53:28 +10002799/* Ensure that the freelist is at full capacity. */
2800int
2801xfs_free_extent_fix_freelist(
2802 struct xfs_trans *tp,
2803 xfs_agnumber_t agno,
2804 struct xfs_buf **agbp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805{
Dave Chinner4d89e202016-06-21 11:53:28 +10002806 struct xfs_alloc_arg args;
2807 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808
Dave Chinner4d89e202016-06-21 11:53:28 +10002809 memset(&args, 0, sizeof(struct xfs_alloc_arg));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002810 args.tp = tp;
2811 args.mp = tp->t_mountp;
Dave Chinner4d89e202016-06-21 11:53:28 +10002812 args.agno = agno;
Dave Chinnerbe65b182011-04-08 12:45:07 +10002813
2814 /*
2815 * validate that the block number is legal - the enables us to detect
2816 * and handle a silent filesystem corruption rather than crashing.
2817 */
Dave Chinnerbe65b182011-04-08 12:45:07 +10002818 if (args.agno >= args.mp->m_sb.sb_agcount)
Dave Chinner24513372014-06-25 14:58:08 +10002819 return -EFSCORRUPTED;
Dave Chinnerbe65b182011-04-08 12:45:07 +10002820
Dave Chinnera862e0f2010-01-11 11:47:41 +00002821 args.pag = xfs_perag_get(args.mp, args.agno);
Dave Chinnerbe65b182011-04-08 12:45:07 +10002822 ASSERT(args.pag);
2823
2824 error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING);
2825 if (error)
Dave Chinner4d89e202016-06-21 11:53:28 +10002826 goto out;
2827
2828 *agbp = args.agbp;
2829out:
2830 xfs_perag_put(args.pag);
2831 return error;
2832}
2833
2834/*
2835 * Free an extent.
2836 * Just break up the extent address and hand off to xfs_free_ag_extent
2837 * after fixing up the freelist.
2838 */
2839int /* error */
2840xfs_free_extent(
2841 struct xfs_trans *tp, /* transaction pointer */
2842 xfs_fsblock_t bno, /* starting block number of extent */
Darrick J. Wong340785c2016-08-03 11:33:42 +10002843 xfs_extlen_t len, /* length of extent */
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002844 struct xfs_owner_info *oinfo, /* extent owner */
2845 enum xfs_ag_resv_type type) /* block reservation type */
Dave Chinner4d89e202016-06-21 11:53:28 +10002846{
2847 struct xfs_mount *mp = tp->t_mountp;
2848 struct xfs_buf *agbp;
2849 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno);
2850 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno);
2851 int error;
2852
2853 ASSERT(len != 0);
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002854 ASSERT(type != XFS_AG_RESV_AGFL);
Dave Chinner4d89e202016-06-21 11:53:28 +10002855
Darrick J. Wongba9e7802016-08-03 11:26:33 +10002856 if (XFS_TEST_ERROR(false, mp,
Darrick J. Wong9e24cfd2017-06-20 17:54:47 -07002857 XFS_ERRTAG_FREE_EXTENT))
Darrick J. Wongba9e7802016-08-03 11:26:33 +10002858 return -EIO;
2859
Dave Chinner4d89e202016-06-21 11:53:28 +10002860 error = xfs_free_extent_fix_freelist(tp, agno, &agbp);
2861 if (error)
2862 return error;
2863
2864 XFS_WANT_CORRUPTED_GOTO(mp, agbno < mp->m_sb.sb_agblocks, err);
Dave Chinnerbe65b182011-04-08 12:45:07 +10002865
2866 /* validate the extent size is legal now we have the agf locked */
Dave Chinner4d89e202016-06-21 11:53:28 +10002867 XFS_WANT_CORRUPTED_GOTO(mp,
2868 agbno + len <= be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_length),
2869 err);
Dave Chinnerbe65b182011-04-08 12:45:07 +10002870
Darrick J. Wong3fd129b2016-09-19 10:30:52 +10002871 error = xfs_free_ag_extent(tp, agbp, agno, agbno, len, oinfo, type);
Dave Chinner4d89e202016-06-21 11:53:28 +10002872 if (error)
2873 goto err;
2874
2875 xfs_extent_busy_insert(tp, agno, agbno, len, 0);
2876 return 0;
2877
2878err:
2879 xfs_trans_brelse(tp, agbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 return error;
2881}
Darrick J. Wong2d520bf2017-03-28 14:56:35 -07002882
2883struct xfs_alloc_query_range_info {
2884 xfs_alloc_query_range_fn fn;
2885 void *priv;
2886};
2887
2888/* Format btree record and pass to our callback. */
2889STATIC int
2890xfs_alloc_query_range_helper(
2891 struct xfs_btree_cur *cur,
2892 union xfs_btree_rec *rec,
2893 void *priv)
2894{
2895 struct xfs_alloc_query_range_info *query = priv;
2896 struct xfs_alloc_rec_incore irec;
2897
2898 irec.ar_startblock = be32_to_cpu(rec->alloc.ar_startblock);
2899 irec.ar_blockcount = be32_to_cpu(rec->alloc.ar_blockcount);
2900 return query->fn(cur, &irec, query->priv);
2901}
2902
2903/* Find all free space within a given range of blocks. */
2904int
2905xfs_alloc_query_range(
2906 struct xfs_btree_cur *cur,
2907 struct xfs_alloc_rec_incore *low_rec,
2908 struct xfs_alloc_rec_incore *high_rec,
2909 xfs_alloc_query_range_fn fn,
2910 void *priv)
2911{
2912 union xfs_btree_irec low_brec;
2913 union xfs_btree_irec high_brec;
2914 struct xfs_alloc_query_range_info query;
2915
2916 ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
2917 low_brec.a = *low_rec;
2918 high_brec.a = *high_rec;
2919 query.priv = priv;
2920 query.fn = fn;
2921 return xfs_btree_query_range(cur, &low_brec, &high_brec,
2922 xfs_alloc_query_range_helper, &query);
2923}
Darrick J. Wonge9a25992017-03-28 14:56:35 -07002924
2925/* Find all free space records. */
2926int
2927xfs_alloc_query_all(
2928 struct xfs_btree_cur *cur,
2929 xfs_alloc_query_range_fn fn,
2930 void *priv)
2931{
2932 struct xfs_alloc_query_range_info query;
2933
2934 ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
2935 query.priv = priv;
2936 query.fn = fn;
2937 return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query);
2938}
Darrick J. Wong21ec5412017-10-17 21:37:32 -07002939
2940/* Find the size of the AG, in blocks. */
2941xfs_agblock_t
2942xfs_ag_block_count(
2943 struct xfs_mount *mp,
2944 xfs_agnumber_t agno)
2945{
2946 ASSERT(agno < mp->m_sb.sb_agcount);
2947
2948 if (agno < mp->m_sb.sb_agcount - 1)
2949 return mp->m_sb.sb_agblocks;
2950 return mp->m_sb.sb_dblocks - (agno * mp->m_sb.sb_agblocks);
2951}
2952
2953/*
2954 * Verify that an AG block number pointer neither points outside the AG
2955 * nor points at static metadata.
2956 */
2957bool
2958xfs_verify_agbno(
2959 struct xfs_mount *mp,
2960 xfs_agnumber_t agno,
2961 xfs_agblock_t agbno)
2962{
2963 xfs_agblock_t eoag;
2964
2965 eoag = xfs_ag_block_count(mp, agno);
2966 if (agbno >= eoag)
2967 return false;
2968 if (agbno <= XFS_AGFL_BLOCK(mp))
2969 return false;
2970 return true;
2971}
2972
2973/*
2974 * Verify that an FS block number pointer neither points outside the
2975 * filesystem nor points at static AG metadata.
2976 */
2977bool
2978xfs_verify_fsbno(
2979 struct xfs_mount *mp,
2980 xfs_fsblock_t fsbno)
2981{
2982 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno);
2983
2984 if (agno >= mp->m_sb.sb_agcount)
2985 return false;
2986 return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno));
2987}