PageRenderTime 99ms CodeModel.GetById 3ms app.highlight 83ms RepoModel.GetById 1ms app.codeStats 0ms

/linux-2.6.33/kernel/linux-2.6.33/fs/xfs/xfs_alloc.c

https://bitbucket.org/microcreat/cortexm_uclinux
C | 2603 lines | 1813 code | 129 blank | 661 comment | 461 complexity | b4fb12d2c36e8ce1ccae689878f96e90 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
   3 * All Rights Reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * 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.
  13 *
  14 * 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
  17 */
  18#include "xfs.h"
  19#include "xfs_fs.h"
  20#include "xfs_types.h"
  21#include "xfs_bit.h"
  22#include "xfs_log.h"
  23#include "xfs_inum.h"
  24#include "xfs_trans.h"
  25#include "xfs_sb.h"
  26#include "xfs_ag.h"
  27#include "xfs_dir2.h"
  28#include "xfs_dmapi.h"
  29#include "xfs_mount.h"
  30#include "xfs_bmap_btree.h"
  31#include "xfs_alloc_btree.h"
  32#include "xfs_ialloc_btree.h"
  33#include "xfs_dir2_sf.h"
  34#include "xfs_attr_sf.h"
  35#include "xfs_dinode.h"
  36#include "xfs_inode.h"
  37#include "xfs_btree.h"
  38#include "xfs_ialloc.h"
  39#include "xfs_alloc.h"
  40#include "xfs_error.h"
  41#include "xfs_trace.h"
  42
  43
  44#define XFS_ABSDIFF(a,b)	(((a) <= (b)) ? ((b) - (a)) : ((a) - (b)))
  45
  46#define	XFSA_FIXUP_BNO_OK	1
  47#define	XFSA_FIXUP_CNT_OK	2
  48
  49STATIC void
  50xfs_alloc_search_busy(xfs_trans_t *tp,
  51		    xfs_agnumber_t agno,
  52		    xfs_agblock_t bno,
  53		    xfs_extlen_t len);
  54
  55/*
  56 * Prototypes for per-ag allocation routines
  57 */
  58
  59STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *);
  60STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *);
  61STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *);
  62STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *,
  63	xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *);
  64
  65/*
  66 * Internal functions.
  67 */
  68
  69/*
  70 * Lookup the record equal to [bno, len] in the btree given by cur.
  71 */
  72STATIC int				/* error */
  73xfs_alloc_lookup_eq(
  74	struct xfs_btree_cur	*cur,	/* btree cursor */
  75	xfs_agblock_t		bno,	/* starting block of extent */
  76	xfs_extlen_t		len,	/* length of extent */
  77	int			*stat)	/* success/failure */
  78{
  79	cur->bc_rec.a.ar_startblock = bno;
  80	cur->bc_rec.a.ar_blockcount = len;
  81	return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
  82}
  83
  84/*
  85 * Lookup the first record greater than or equal to [bno, len]
  86 * in the btree given by cur.
  87 */
  88STATIC int				/* error */
  89xfs_alloc_lookup_ge(
  90	struct xfs_btree_cur	*cur,	/* btree cursor */
  91	xfs_agblock_t		bno,	/* starting block of extent */
  92	xfs_extlen_t		len,	/* length of extent */
  93	int			*stat)	/* success/failure */
  94{
  95	cur->bc_rec.a.ar_startblock = bno;
  96	cur->bc_rec.a.ar_blockcount = len;
  97	return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
  98}
  99
 100/*
 101 * Lookup the first record less than or equal to [bno, len]
 102 * in the btree given by cur.
 103 */
 104STATIC int				/* error */
 105xfs_alloc_lookup_le(
 106	struct xfs_btree_cur	*cur,	/* btree cursor */
 107	xfs_agblock_t		bno,	/* starting block of extent */
 108	xfs_extlen_t		len,	/* length of extent */
 109	int			*stat)	/* success/failure */
 110{
 111	cur->bc_rec.a.ar_startblock = bno;
 112	cur->bc_rec.a.ar_blockcount = len;
 113	return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
 114}
 115
 116/*
 117 * Update the record referred to by cur to the value given
 118 * by [bno, len].
 119 * This either works (return 0) or gets an EFSCORRUPTED error.
 120 */
 121STATIC int				/* error */
 122xfs_alloc_update(
 123	struct xfs_btree_cur	*cur,	/* btree cursor */
 124	xfs_agblock_t		bno,	/* starting block of extent */
 125	xfs_extlen_t		len)	/* length of extent */
 126{
 127	union xfs_btree_rec	rec;
 128
 129	rec.alloc.ar_startblock = cpu_to_be32(bno);
 130	rec.alloc.ar_blockcount = cpu_to_be32(len);
 131	return xfs_btree_update(cur, &rec);
 132}
 133
 134/*
 135 * Get the data from the pointed-to record.
 136 */
 137STATIC int				/* error */
 138xfs_alloc_get_rec(
 139	struct xfs_btree_cur	*cur,	/* btree cursor */
 140	xfs_agblock_t		*bno,	/* output: starting block of extent */
 141	xfs_extlen_t		*len,	/* output: length of extent */
 142	int			*stat)	/* output: success/failure */
 143{
 144	union xfs_btree_rec	*rec;
 145	int			error;
 146
 147	error = xfs_btree_get_rec(cur, &rec, stat);
 148	if (!error && *stat == 1) {
 149		*bno = be32_to_cpu(rec->alloc.ar_startblock);
 150		*len = be32_to_cpu(rec->alloc.ar_blockcount);
 151	}
 152	return error;
 153}
 154
 155/*
 156 * Compute aligned version of the found extent.
 157 * Takes alignment and min length into account.
 158 */
 159STATIC void
 160xfs_alloc_compute_aligned(
 161	xfs_agblock_t	foundbno,	/* starting block in found extent */
 162	xfs_extlen_t	foundlen,	/* length in found extent */
 163	xfs_extlen_t	alignment,	/* alignment for allocation */
 164	xfs_extlen_t	minlen,		/* minimum length for allocation */
 165	xfs_agblock_t	*resbno,	/* result block number */
 166	xfs_extlen_t	*reslen)	/* result length */
 167{
 168	xfs_agblock_t	bno;
 169	xfs_extlen_t	diff;
 170	xfs_extlen_t	len;
 171
 172	if (alignment > 1 && foundlen >= minlen) {
 173		bno = roundup(foundbno, alignment);
 174		diff = bno - foundbno;
 175		len = diff >= foundlen ? 0 : foundlen - diff;
 176	} else {
 177		bno = foundbno;
 178		len = foundlen;
 179	}
 180	*resbno = bno;
 181	*reslen = len;
 182}
 183
 184/*
 185 * Compute best start block and diff for "near" allocations.
 186 * freelen >= wantlen already checked by caller.
 187 */
 188STATIC xfs_extlen_t			/* difference value (absolute) */
 189xfs_alloc_compute_diff(
 190	xfs_agblock_t	wantbno,	/* target starting block */
 191	xfs_extlen_t	wantlen,	/* target length */
 192	xfs_extlen_t	alignment,	/* target alignment */
 193	xfs_agblock_t	freebno,	/* freespace's starting block */
 194	xfs_extlen_t	freelen,	/* freespace's length */
 195	xfs_agblock_t	*newbnop)	/* result: best start block from free */
 196{
 197	xfs_agblock_t	freeend;	/* end of freespace extent */
 198	xfs_agblock_t	newbno1;	/* return block number */
 199	xfs_agblock_t	newbno2;	/* other new block number */
 200	xfs_extlen_t	newlen1=0;	/* length with newbno1 */
 201	xfs_extlen_t	newlen2=0;	/* length with newbno2 */
 202	xfs_agblock_t	wantend;	/* end of target extent */
 203
 204	ASSERT(freelen >= wantlen);
 205	freeend = freebno + freelen;
 206	wantend = wantbno + wantlen;
 207	if (freebno >= wantbno) {
 208		if ((newbno1 = roundup(freebno, alignment)) >= freeend)
 209			newbno1 = NULLAGBLOCK;
 210	} else if (freeend >= wantend && alignment > 1) {
 211		newbno1 = roundup(wantbno, alignment);
 212		newbno2 = newbno1 - alignment;
 213		if (newbno1 >= freeend)
 214			newbno1 = NULLAGBLOCK;
 215		else
 216			newlen1 = XFS_EXTLEN_MIN(wantlen, freeend - newbno1);
 217		if (newbno2 < freebno)
 218			newbno2 = NULLAGBLOCK;
 219		else
 220			newlen2 = XFS_EXTLEN_MIN(wantlen, freeend - newbno2);
 221		if (newbno1 != NULLAGBLOCK && newbno2 != NULLAGBLOCK) {
 222			if (newlen1 < newlen2 ||
 223			    (newlen1 == newlen2 &&
 224			     XFS_ABSDIFF(newbno1, wantbno) >
 225			     XFS_ABSDIFF(newbno2, wantbno)))
 226				newbno1 = newbno2;
 227		} else if (newbno2 != NULLAGBLOCK)
 228			newbno1 = newbno2;
 229	} else if (freeend >= wantend) {
 230		newbno1 = wantbno;
 231	} else if (alignment > 1) {
 232		newbno1 = roundup(freeend - wantlen, alignment);
 233		if (newbno1 > freeend - wantlen &&
 234		    newbno1 - alignment >= freebno)
 235			newbno1 -= alignment;
 236		else if (newbno1 >= freeend)
 237			newbno1 = NULLAGBLOCK;
 238	} else
 239		newbno1 = freeend - wantlen;
 240	*newbnop = newbno1;
 241	return newbno1 == NULLAGBLOCK ? 0 : XFS_ABSDIFF(newbno1, wantbno);
 242}
 243
 244/*
 245 * Fix up the length, based on mod and prod.
 246 * len should be k * prod + mod for some k.
 247 * If len is too small it is returned unchanged.
 248 * If len hits maxlen it is left alone.
 249 */
 250STATIC void
 251xfs_alloc_fix_len(
 252	xfs_alloc_arg_t	*args)		/* allocation argument structure */
 253{
 254	xfs_extlen_t	k;
 255	xfs_extlen_t	rlen;
 256
 257	ASSERT(args->mod < args->prod);
 258	rlen = args->len;
 259	ASSERT(rlen >= args->minlen);
 260	ASSERT(rlen <= args->maxlen);
 261	if (args->prod <= 1 || rlen < args->mod || rlen == args->maxlen ||
 262	    (args->mod == 0 && rlen < args->prod))
 263		return;
 264	k = rlen % args->prod;
 265	if (k == args->mod)
 266		return;
 267	if (k > args->mod) {
 268		if ((int)(rlen = rlen - k - args->mod) < (int)args->minlen)
 269			return;
 270	} else {
 271		if ((int)(rlen = rlen - args->prod - (args->mod - k)) <
 272		    (int)args->minlen)
 273			return;
 274	}
 275	ASSERT(rlen >= args->minlen);
 276	ASSERT(rlen <= args->maxlen);
 277	args->len = rlen;
 278}
 279
 280/*
 281 * Fix up length if there is too little space left in the a.g.
 282 * Return 1 if ok, 0 if too little, should give up.
 283 */
 284STATIC int
 285xfs_alloc_fix_minleft(
 286	xfs_alloc_arg_t	*args)		/* allocation argument structure */
 287{
 288	xfs_agf_t	*agf;		/* a.g. freelist header */
 289	int		diff;		/* free space difference */
 290
 291	if (args->minleft == 0)
 292		return 1;
 293	agf = XFS_BUF_TO_AGF(args->agbp);
 294	diff = be32_to_cpu(agf->agf_freeblks)
 295		+ be32_to_cpu(agf->agf_flcount)
 296		- args->len - args->minleft;
 297	if (diff >= 0)
 298		return 1;
 299	args->len += diff;		/* shrink the allocated space */
 300	if (args->len >= args->minlen)
 301		return 1;
 302	args->agbno = NULLAGBLOCK;
 303	return 0;
 304}
 305
 306/*
 307 * Update the two btrees, logically removing from freespace the extent
 308 * starting at rbno, rlen blocks.  The extent is contained within the
 309 * actual (current) free extent fbno for flen blocks.
 310 * Flags are passed in indicating whether the cursors are set to the
 311 * relevant records.
 312 */
 313STATIC int				/* error code */
 314xfs_alloc_fixup_trees(
 315	xfs_btree_cur_t	*cnt_cur,	/* cursor for by-size btree */
 316	xfs_btree_cur_t	*bno_cur,	/* cursor for by-block btree */
 317	xfs_agblock_t	fbno,		/* starting block of free extent */
 318	xfs_extlen_t	flen,		/* length of free extent */
 319	xfs_agblock_t	rbno,		/* starting block of returned extent */
 320	xfs_extlen_t	rlen,		/* length of returned extent */
 321	int		flags)		/* flags, XFSA_FIXUP_... */
 322{
 323	int		error;		/* error code */
 324	int		i;		/* operation results */
 325	xfs_agblock_t	nfbno1;		/* first new free startblock */
 326	xfs_agblock_t	nfbno2;		/* second new free startblock */
 327	xfs_extlen_t	nflen1=0;	/* first new free length */
 328	xfs_extlen_t	nflen2=0;	/* second new free length */
 329
 330	/*
 331	 * Look up the record in the by-size tree if necessary.
 332	 */
 333	if (flags & XFSA_FIXUP_CNT_OK) {
 334#ifdef DEBUG
 335		if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i)))
 336			return error;
 337		XFS_WANT_CORRUPTED_RETURN(
 338			i == 1 && nfbno1 == fbno && nflen1 == flen);
 339#endif
 340	} else {
 341		if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i)))
 342			return error;
 343		XFS_WANT_CORRUPTED_RETURN(i == 1);
 344	}
 345	/*
 346	 * Look up the record in the by-block tree if necessary.
 347	 */
 348	if (flags & XFSA_FIXUP_BNO_OK) {
 349#ifdef DEBUG
 350		if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i)))
 351			return error;
 352		XFS_WANT_CORRUPTED_RETURN(
 353			i == 1 && nfbno1 == fbno && nflen1 == flen);
 354#endif
 355	} else {
 356		if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i)))
 357			return error;
 358		XFS_WANT_CORRUPTED_RETURN(i == 1);
 359	}
 360
 361#ifdef DEBUG
 362	if (bno_cur->bc_nlevels == 1 && cnt_cur->bc_nlevels == 1) {
 363		struct xfs_btree_block	*bnoblock;
 364		struct xfs_btree_block	*cntblock;
 365
 366		bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]);
 367		cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]);
 368
 369		XFS_WANT_CORRUPTED_RETURN(
 370			bnoblock->bb_numrecs == cntblock->bb_numrecs);
 371	}
 372#endif
 373
 374	/*
 375	 * Deal with all four cases: the allocated record is contained
 376	 * within the freespace record, so we can have new freespace
 377	 * at either (or both) end, or no freespace remaining.
 378	 */
 379	if (rbno == fbno && rlen == flen)
 380		nfbno1 = nfbno2 = NULLAGBLOCK;
 381	else if (rbno == fbno) {
 382		nfbno1 = rbno + rlen;
 383		nflen1 = flen - rlen;
 384		nfbno2 = NULLAGBLOCK;
 385	} else if (rbno + rlen == fbno + flen) {
 386		nfbno1 = fbno;
 387		nflen1 = flen - rlen;
 388		nfbno2 = NULLAGBLOCK;
 389	} else {
 390		nfbno1 = fbno;
 391		nflen1 = rbno - fbno;
 392		nfbno2 = rbno + rlen;
 393		nflen2 = (fbno + flen) - nfbno2;
 394	}
 395	/*
 396	 * Delete the entry from the by-size btree.
 397	 */
 398	if ((error = xfs_btree_delete(cnt_cur, &i)))
 399		return error;
 400	XFS_WANT_CORRUPTED_RETURN(i == 1);
 401	/*
 402	 * Add new by-size btree entry(s).
 403	 */
 404	if (nfbno1 != NULLAGBLOCK) {
 405		if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i)))
 406			return error;
 407		XFS_WANT_CORRUPTED_RETURN(i == 0);
 408		if ((error = xfs_btree_insert(cnt_cur, &i)))
 409			return error;
 410		XFS_WANT_CORRUPTED_RETURN(i == 1);
 411	}
 412	if (nfbno2 != NULLAGBLOCK) {
 413		if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i)))
 414			return error;
 415		XFS_WANT_CORRUPTED_RETURN(i == 0);
 416		if ((error = xfs_btree_insert(cnt_cur, &i)))
 417			return error;
 418		XFS_WANT_CORRUPTED_RETURN(i == 1);
 419	}
 420	/*
 421	 * Fix up the by-block btree entry(s).
 422	 */
 423	if (nfbno1 == NULLAGBLOCK) {
 424		/*
 425		 * No remaining freespace, just delete the by-block tree entry.
 426		 */
 427		if ((error = xfs_btree_delete(bno_cur, &i)))
 428			return error;
 429		XFS_WANT_CORRUPTED_RETURN(i == 1);
 430	} else {
 431		/*
 432		 * Update the by-block entry to start later|be shorter.
 433		 */
 434		if ((error = xfs_alloc_update(bno_cur, nfbno1, nflen1)))
 435			return error;
 436	}
 437	if (nfbno2 != NULLAGBLOCK) {
 438		/*
 439		 * 2 resulting free entries, need to add one.
 440		 */
 441		if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i)))
 442			return error;
 443		XFS_WANT_CORRUPTED_RETURN(i == 0);
 444		if ((error = xfs_btree_insert(bno_cur, &i)))
 445			return error;
 446		XFS_WANT_CORRUPTED_RETURN(i == 1);
 447	}
 448	return 0;
 449}
 450
 451/*
 452 * Read in the allocation group free block array.
 453 */
 454STATIC int				/* error */
 455xfs_alloc_read_agfl(
 456	xfs_mount_t	*mp,		/* mount point structure */
 457	xfs_trans_t	*tp,		/* transaction pointer */
 458	xfs_agnumber_t	agno,		/* allocation group number */
 459	xfs_buf_t	**bpp)		/* buffer for the ag free block array */
 460{
 461	xfs_buf_t	*bp;		/* return value */
 462	int		error;
 463
 464	ASSERT(agno != NULLAGNUMBER);
 465	error = xfs_trans_read_buf(
 466			mp, tp, mp->m_ddev_targp,
 467			XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
 468			XFS_FSS_TO_BB(mp, 1), 0, &bp);
 469	if (error)
 470		return error;
 471	ASSERT(bp);
 472	ASSERT(!XFS_BUF_GETERROR(bp));
 473	XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGFL, XFS_AGFL_REF);
 474	*bpp = bp;
 475	return 0;
 476}
 477
 478/*
 479 * Allocation group level functions.
 480 */
 481
 482/*
 483 * Allocate a variable extent in the allocation group agno.
 484 * Type and bno are used to determine where in the allocation group the
 485 * extent will start.
 486 * Extent's length (returned in *len) will be between minlen and maxlen,
 487 * and of the form k * prod + mod unless there's nothing that large.
 488 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
 489 */
 490STATIC int			/* error */
 491xfs_alloc_ag_vextent(
 492	xfs_alloc_arg_t	*args)	/* argument structure for allocation */
 493{
 494	int		error=0;
 495
 496	ASSERT(args->minlen > 0);
 497	ASSERT(args->maxlen > 0);
 498	ASSERT(args->minlen <= args->maxlen);
 499	ASSERT(args->mod < args->prod);
 500	ASSERT(args->alignment > 0);
 501	/*
 502	 * Branch to correct routine based on the type.
 503	 */
 504	args->wasfromfl = 0;
 505	switch (args->type) {
 506	case XFS_ALLOCTYPE_THIS_AG:
 507		error = xfs_alloc_ag_vextent_size(args);
 508		break;
 509	case XFS_ALLOCTYPE_NEAR_BNO:
 510		error = xfs_alloc_ag_vextent_near(args);
 511		break;
 512	case XFS_ALLOCTYPE_THIS_BNO:
 513		error = xfs_alloc_ag_vextent_exact(args);
 514		break;
 515	default:
 516		ASSERT(0);
 517		/* NOTREACHED */
 518	}
 519	if (error)
 520		return error;
 521	/*
 522	 * If the allocation worked, need to change the agf structure
 523	 * (and log it), and the superblock.
 524	 */
 525	if (args->agbno != NULLAGBLOCK) {
 526		xfs_agf_t	*agf;	/* allocation group freelist header */
 527		long		slen = (long)args->len;
 528
 529		ASSERT(args->len >= args->minlen && args->len <= args->maxlen);
 530		ASSERT(!(args->wasfromfl) || !args->isfl);
 531		ASSERT(args->agbno % args->alignment == 0);
 532		if (!(args->wasfromfl)) {
 533
 534			agf = XFS_BUF_TO_AGF(args->agbp);
 535			be32_add_cpu(&agf->agf_freeblks, -(args->len));
 536			xfs_trans_agblocks_delta(args->tp,
 537						 -((long)(args->len)));
 538			args->pag->pagf_freeblks -= args->len;
 539			ASSERT(be32_to_cpu(agf->agf_freeblks) <=
 540				be32_to_cpu(agf->agf_length));
 541			xfs_alloc_log_agf(args->tp, args->agbp,
 542						XFS_AGF_FREEBLKS);
 543			/* search the busylist for these blocks */
 544			xfs_alloc_search_busy(args->tp, args->agno,
 545					args->agbno, args->len);
 546		}
 547		if (!args->isfl)
 548			xfs_trans_mod_sb(args->tp,
 549				args->wasdel ? XFS_TRANS_SB_RES_FDBLOCKS :
 550					XFS_TRANS_SB_FDBLOCKS, -slen);
 551		XFS_STATS_INC(xs_allocx);
 552		XFS_STATS_ADD(xs_allocb, args->len);
 553	}
 554	return 0;
 555}
 556
 557/*
 558 * Allocate a variable extent at exactly agno/bno.
 559 * Extent's length (returned in *len) will be between minlen and maxlen,
 560 * and of the form k * prod + mod unless there's nothing that large.
 561 * Return the starting a.g. block (bno), or NULLAGBLOCK if we can't do it.
 562 */
 563STATIC int			/* error */
 564xfs_alloc_ag_vextent_exact(
 565	xfs_alloc_arg_t	*args)	/* allocation argument structure */
 566{
 567	xfs_btree_cur_t	*bno_cur;/* by block-number btree cursor */
 568	xfs_btree_cur_t	*cnt_cur;/* by count btree cursor */
 569	xfs_agblock_t	end;	/* end of allocated extent */
 570	int		error;
 571	xfs_agblock_t	fbno;	/* start block of found extent */
 572	xfs_agblock_t	fend;	/* end block of found extent */
 573	xfs_extlen_t	flen;	/* length of found extent */
 574	int		i;	/* success/failure of operation */
 575	xfs_agblock_t	maxend;	/* end of maximal extent */
 576	xfs_agblock_t	minend;	/* end of minimal extent */
 577	xfs_extlen_t	rlen;	/* length of returned extent */
 578
 579	ASSERT(args->alignment == 1);
 580	/*
 581	 * Allocate/initialize a cursor for the by-number freespace btree.
 582	 */
 583	bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
 584		args->agno, XFS_BTNUM_BNO);
 585	/*
 586	 * Lookup bno and minlen in the btree (minlen is irrelevant, really).
 587	 * Look for the closest free block <= bno, it must contain bno
 588	 * if any free block does.
 589	 */
 590	if ((error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i)))
 591		goto error0;
 592	if (!i) {
 593		/*
 594		 * Didn't find it, return null.
 595		 */
 596		xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
 597		args->agbno = NULLAGBLOCK;
 598		return 0;
 599	}
 600	/*
 601	 * Grab the freespace record.
 602	 */
 603	if ((error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i)))
 604		goto error0;
 605	XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
 606	ASSERT(fbno <= args->agbno);
 607	minend = args->agbno + args->minlen;
 608	maxend = args->agbno + args->maxlen;
 609	fend = fbno + flen;
 610	/*
 611	 * Give up if the freespace isn't long enough for the minimum request.
 612	 */
 613	if (fend < minend) {
 614		xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
 615		args->agbno = NULLAGBLOCK;
 616		return 0;
 617	}
 618	/*
 619	 * End of extent will be smaller of the freespace end and the
 620	 * maximal requested end.
 621	 */
 622	end = XFS_AGBLOCK_MIN(fend, maxend);
 623	/*
 624	 * Fix the length according to mod and prod if given.
 625	 */
 626	args->len = end - args->agbno;
 627	xfs_alloc_fix_len(args);
 628	if (!xfs_alloc_fix_minleft(args)) {
 629		xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
 630		return 0;
 631	}
 632	rlen = args->len;
 633	ASSERT(args->agbno + rlen <= fend);
 634	end = args->agbno + rlen;
 635	/*
 636	 * We are allocating agbno for rlen [agbno .. end]
 637	 * Allocate/initialize a cursor for the by-size btree.
 638	 */
 639	cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
 640		args->agno, XFS_BTNUM_CNT);
 641	ASSERT(args->agbno + args->len <=
 642		be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
 643	if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
 644			args->agbno, args->len, XFSA_FIXUP_BNO_OK))) {
 645		xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
 646		goto error0;
 647	}
 648	xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
 649	xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
 650
 651	trace_xfs_alloc_exact_done(args);
 652	args->wasfromfl = 0;
 653	return 0;
 654
 655error0:
 656	xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
 657	trace_xfs_alloc_exact_error(args);
 658	return error;
 659}
 660
 661/*
 662 * Allocate a variable extent near bno in the allocation group agno.
 663 * Extent's length (returned in len) will be between minlen and maxlen,
 664 * and of the form k * prod + mod unless there's nothing that large.
 665 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
 666 */
 667STATIC int				/* error */
 668xfs_alloc_ag_vextent_near(
 669	xfs_alloc_arg_t	*args)		/* allocation argument structure */
 670{
 671	xfs_btree_cur_t	*bno_cur_gt;	/* cursor for bno btree, right side */
 672	xfs_btree_cur_t	*bno_cur_lt;	/* cursor for bno btree, left side */
 673	xfs_btree_cur_t	*cnt_cur;	/* cursor for count btree */
 674	xfs_agblock_t	gtbno;		/* start bno of right side entry */
 675	xfs_agblock_t	gtbnoa;		/* aligned ... */
 676	xfs_extlen_t	gtdiff;		/* difference to right side entry */
 677	xfs_extlen_t	gtlen;		/* length of right side entry */
 678	xfs_extlen_t	gtlena;		/* aligned ... */
 679	xfs_agblock_t	gtnew;		/* useful start bno of right side */
 680	int		error;		/* error code */
 681	int		i;		/* result code, temporary */
 682	int		j;		/* result code, temporary */
 683	xfs_agblock_t	ltbno;		/* start bno of left side entry */
 684	xfs_agblock_t	ltbnoa;		/* aligned ... */
 685	xfs_extlen_t	ltdiff;		/* difference to left side entry */
 686	/*REFERENCED*/
 687	xfs_agblock_t	ltend;		/* end bno of left side entry */
 688	xfs_extlen_t	ltlen;		/* length of left side entry */
 689	xfs_extlen_t	ltlena;		/* aligned ... */
 690	xfs_agblock_t	ltnew;		/* useful start bno of left side */
 691	xfs_extlen_t	rlen;		/* length of returned extent */
 692#if defined(DEBUG) && defined(__KERNEL__)
 693	/*
 694	 * Randomly don't execute the first algorithm.
 695	 */
 696	int		dofirst;	/* set to do first algorithm */
 697
 698	dofirst = random32() & 1;
 699#endif
 700	/*
 701	 * Get a cursor for the by-size btree.
 702	 */
 703	cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
 704		args->agno, XFS_BTNUM_CNT);
 705	ltlen = 0;
 706	bno_cur_lt = bno_cur_gt = NULL;
 707	/*
 708	 * See if there are any free extents as big as maxlen.
 709	 */
 710	if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen, &i)))
 711		goto error0;
 712	/*
 713	 * If none, then pick up the last entry in the tree unless the
 714	 * tree is empty.
 715	 */
 716	if (!i) {
 717		if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &ltbno,
 718				&ltlen, &i)))
 719			goto error0;
 720		if (i == 0 || ltlen == 0) {
 721			xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
 722			return 0;
 723		}
 724		ASSERT(i == 1);
 725	}
 726	args->wasfromfl = 0;
 727	/*
 728	 * First algorithm.
 729	 * If the requested extent is large wrt the freespaces available
 730	 * in this a.g., then the cursor will be pointing to a btree entry
 731	 * near the right edge of the tree.  If it's in the last btree leaf
 732	 * block, then we just examine all the entries in that block
 733	 * that are big enough, and pick the best one.
 734	 * This is written as a while loop so we can break out of it,
 735	 * but we never loop back to the top.
 736	 */
 737	while (xfs_btree_islastblock(cnt_cur, 0)) {
 738		xfs_extlen_t	bdiff;
 739		int		besti=0;
 740		xfs_extlen_t	blen=0;
 741		xfs_agblock_t	bnew=0;
 742
 743#if defined(DEBUG) && defined(__KERNEL__)
 744		if (!dofirst)
 745			break;
 746#endif
 747		/*
 748		 * Start from the entry that lookup found, sequence through
 749		 * all larger free blocks.  If we're actually pointing at a
 750		 * record smaller than maxlen, go to the start of this block,
 751		 * and skip all those smaller than minlen.
 752		 */
 753		if (ltlen || args->alignment > 1) {
 754			cnt_cur->bc_ptrs[0] = 1;
 755			do {
 756				if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno,
 757						&ltlen, &i)))
 758					goto error0;
 759				XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
 760				if (ltlen >= args->minlen)
 761					break;
 762				if ((error = xfs_btree_increment(cnt_cur, 0, &i)))
 763					goto error0;
 764			} while (i);
 765			ASSERT(ltlen >= args->minlen);
 766			if (!i)
 767				break;
 768		}
 769		i = cnt_cur->bc_ptrs[0];
 770		for (j = 1, blen = 0, bdiff = 0;
 771		     !error && j && (blen < args->maxlen || bdiff > 0);
 772		     error = xfs_btree_increment(cnt_cur, 0, &j)) {
 773			/*
 774			 * For each entry, decide if it's better than
 775			 * the previous best entry.
 776			 */
 777			if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
 778				goto error0;
 779			XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
 780			xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment,
 781					args->minlen, &ltbnoa, &ltlena);
 782			if (ltlena < args->minlen)
 783				continue;
 784			args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
 785			xfs_alloc_fix_len(args);
 786			ASSERT(args->len >= args->minlen);
 787			if (args->len < blen)
 788				continue;
 789			ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
 790				args->alignment, ltbno, ltlen, &ltnew);
 791			if (ltnew != NULLAGBLOCK &&
 792			    (args->len > blen || ltdiff < bdiff)) {
 793				bdiff = ltdiff;
 794				bnew = ltnew;
 795				blen = args->len;
 796				besti = cnt_cur->bc_ptrs[0];
 797			}
 798		}
 799		/*
 800		 * It didn't work.  We COULD be in a case where
 801		 * there's a good record somewhere, so try again.
 802		 */
 803		if (blen == 0)
 804			break;
 805		/*
 806		 * Point at the best entry, and retrieve it again.
 807		 */
 808		cnt_cur->bc_ptrs[0] = besti;
 809		if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i)))
 810			goto error0;
 811		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
 812		ltend = ltbno + ltlen;
 813		ASSERT(ltend <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
 814		args->len = blen;
 815		if (!xfs_alloc_fix_minleft(args)) {
 816			xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
 817			trace_xfs_alloc_near_nominleft(args);
 818			return 0;
 819		}
 820		blen = args->len;
 821		/*
 822		 * We are allocating starting at bnew for blen blocks.
 823		 */
 824		args->agbno = bnew;
 825		ASSERT(bnew >= ltbno);
 826		ASSERT(bnew + blen <= ltend);
 827		/*
 828		 * Set up a cursor for the by-bno tree.
 829		 */
 830		bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp,
 831			args->agbp, args->agno, XFS_BTNUM_BNO);
 832		/*
 833		 * Fix up the btree entries.
 834		 */
 835		if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno,
 836				ltlen, bnew, blen, XFSA_FIXUP_CNT_OK)))
 837			goto error0;
 838		xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
 839		xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
 840
 841		trace_xfs_alloc_near_first(args);
 842		return 0;
 843	}
 844	/*
 845	 * Second algorithm.
 846	 * Search in the by-bno tree to the left and to the right
 847	 * simultaneously, until in each case we find a space big enough,
 848	 * or run into the edge of the tree.  When we run into the edge,
 849	 * we deallocate that cursor.
 850	 * If both searches succeed, we compare the two spaces and pick
 851	 * the better one.
 852	 * With alignment, it's possible for both to fail; the upper
 853	 * level algorithm that picks allocation groups for allocations
 854	 * is not supposed to do this.
 855	 */
 856	/*
 857	 * Allocate and initialize the cursor for the leftward search.
 858	 */
 859	bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
 860		args->agno, XFS_BTNUM_BNO);
 861	/*
 862	 * Lookup <= bno to find the leftward search's starting point.
 863	 */
 864	if ((error = xfs_alloc_lookup_le(bno_cur_lt, args->agbno, args->maxlen, &i)))
 865		goto error0;
 866	if (!i) {
 867		/*
 868		 * Didn't find anything; use this cursor for the rightward
 869		 * search.
 870		 */
 871		bno_cur_gt = bno_cur_lt;
 872		bno_cur_lt = NULL;
 873	}
 874	/*
 875	 * Found something.  Duplicate the cursor for the rightward search.
 876	 */
 877	else if ((error = xfs_btree_dup_cursor(bno_cur_lt, &bno_cur_gt)))
 878		goto error0;
 879	/*
 880	 * Increment the cursor, so we will point at the entry just right
 881	 * of the leftward entry if any, or to the leftmost entry.
 882	 */
 883	if ((error = xfs_btree_increment(bno_cur_gt, 0, &i)))
 884		goto error0;
 885	if (!i) {
 886		/*
 887		 * It failed, there are no rightward entries.
 888		 */
 889		xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_NOERROR);
 890		bno_cur_gt = NULL;
 891	}
 892	/*
 893	 * Loop going left with the leftward cursor, right with the
 894	 * rightward cursor, until either both directions give up or
 895	 * we find an entry at least as big as minlen.
 896	 */
 897	do {
 898		if (bno_cur_lt) {
 899			if ((error = xfs_alloc_get_rec(bno_cur_lt, &ltbno, &ltlen, &i)))
 900				goto error0;
 901			XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
 902			xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment,
 903					args->minlen, &ltbnoa, &ltlena);
 904			if (ltlena >= args->minlen)
 905				break;
 906			if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i)))
 907				goto error0;
 908			if (!i) {
 909				xfs_btree_del_cursor(bno_cur_lt,
 910						     XFS_BTREE_NOERROR);
 911				bno_cur_lt = NULL;
 912			}
 913		}
 914		if (bno_cur_gt) {
 915			if ((error = xfs_alloc_get_rec(bno_cur_gt, &gtbno, &gtlen, &i)))
 916				goto error0;
 917			XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
 918			xfs_alloc_compute_aligned(gtbno, gtlen, args->alignment,
 919					args->minlen, &gtbnoa, &gtlena);
 920			if (gtlena >= args->minlen)
 921				break;
 922			if ((error = xfs_btree_increment(bno_cur_gt, 0, &i)))
 923				goto error0;
 924			if (!i) {
 925				xfs_btree_del_cursor(bno_cur_gt,
 926						     XFS_BTREE_NOERROR);
 927				bno_cur_gt = NULL;
 928			}
 929		}
 930	} while (bno_cur_lt || bno_cur_gt);
 931	/*
 932	 * Got both cursors still active, need to find better entry.
 933	 */
 934	if (bno_cur_lt && bno_cur_gt) {
 935		/*
 936		 * Left side is long enough, look for a right side entry.
 937		 */
 938		if (ltlena >= args->minlen) {
 939			/*
 940			 * Fix up the length.
 941			 */
 942			args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
 943			xfs_alloc_fix_len(args);
 944			rlen = args->len;
 945			ltdiff = xfs_alloc_compute_diff(args->agbno, rlen,
 946				args->alignment, ltbno, ltlen, &ltnew);
 947			/*
 948			 * Not perfect.
 949			 */
 950			if (ltdiff) {
 951				/*
 952				 * Look until we find a better one, run out of
 953				 * space, or run off the end.
 954				 */
 955				while (bno_cur_lt && bno_cur_gt) {
 956					if ((error = xfs_alloc_get_rec(
 957							bno_cur_gt, &gtbno,
 958							&gtlen, &i)))
 959						goto error0;
 960					XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
 961					xfs_alloc_compute_aligned(gtbno, gtlen,
 962						args->alignment, args->minlen,
 963						&gtbnoa, &gtlena);
 964					/*
 965					 * The left one is clearly better.
 966					 */
 967					if (gtbnoa >= args->agbno + ltdiff) {
 968						xfs_btree_del_cursor(
 969							bno_cur_gt,
 970							XFS_BTREE_NOERROR);
 971						bno_cur_gt = NULL;
 972						break;
 973					}
 974					/*
 975					 * If we reach a big enough entry,
 976					 * compare the two and pick the best.
 977					 */
 978					if (gtlena >= args->minlen) {
 979						args->len =
 980							XFS_EXTLEN_MIN(gtlena,
 981								args->maxlen);
 982						xfs_alloc_fix_len(args);
 983						rlen = args->len;
 984						gtdiff = xfs_alloc_compute_diff(
 985							args->agbno, rlen,
 986							args->alignment,
 987							gtbno, gtlen, &gtnew);
 988						/*
 989						 * Right side is better.
 990						 */
 991						if (gtdiff < ltdiff) {
 992							xfs_btree_del_cursor(
 993								bno_cur_lt,
 994								XFS_BTREE_NOERROR);
 995							bno_cur_lt = NULL;
 996						}
 997						/*
 998						 * Left side is better.
 999						 */
1000						else {
1001							xfs_btree_del_cursor(
1002								bno_cur_gt,
1003								XFS_BTREE_NOERROR);
1004							bno_cur_gt = NULL;
1005						}
1006						break;
1007					}
1008					/*
1009					 * Fell off the right end.
1010					 */
1011					if ((error = xfs_btree_increment(
1012							bno_cur_gt, 0, &i)))
1013						goto error0;
1014					if (!i) {
1015						xfs_btree_del_cursor(
1016							bno_cur_gt,
1017							XFS_BTREE_NOERROR);
1018						bno_cur_gt = NULL;
1019						break;
1020					}
1021				}
1022			}
1023			/*
1024			 * The left side is perfect, trash the right side.
1025			 */
1026			else {
1027				xfs_btree_del_cursor(bno_cur_gt,
1028						     XFS_BTREE_NOERROR);
1029				bno_cur_gt = NULL;
1030			}
1031		}
1032		/*
1033		 * It's the right side that was found first, look left.
1034		 */
1035		else {
1036			/*
1037			 * Fix up the length.
1038			 */
1039			args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
1040			xfs_alloc_fix_len(args);
1041			rlen = args->len;
1042			gtdiff = xfs_alloc_compute_diff(args->agbno, rlen,
1043				args->alignment, gtbno, gtlen, &gtnew);
1044			/*
1045			 * Right side entry isn't perfect.
1046			 */
1047			if (gtdiff) {
1048				/*
1049				 * Look until we find a better one, run out of
1050				 * space, or run off the end.
1051				 */
1052				while (bno_cur_lt && bno_cur_gt) {
1053					if ((error = xfs_alloc_get_rec(
1054							bno_cur_lt, &ltbno,
1055							&ltlen, &i)))
1056						goto error0;
1057					XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1058					xfs_alloc_compute_aligned(ltbno, ltlen,
1059						args->alignment, args->minlen,
1060						&ltbnoa, &ltlena);
1061					/*
1062					 * The right one is clearly better.
1063					 */
1064					if (ltbnoa <= args->agbno - gtdiff) {
1065						xfs_btree_del_cursor(
1066							bno_cur_lt,
1067							XFS_BTREE_NOERROR);
1068						bno_cur_lt = NULL;
1069						break;
1070					}
1071					/*
1072					 * If we reach a big enough entry,
1073					 * compare the two and pick the best.
1074					 */
1075					if (ltlena >= args->minlen) {
1076						args->len = XFS_EXTLEN_MIN(
1077							ltlena, args->maxlen);
1078						xfs_alloc_fix_len(args);
1079						rlen = args->len;
1080						ltdiff = xfs_alloc_compute_diff(
1081							args->agbno, rlen,
1082							args->alignment,
1083							ltbno, ltlen, &ltnew);
1084						/*
1085						 * Left side is better.
1086						 */
1087						if (ltdiff < gtdiff) {
1088							xfs_btree_del_cursor(
1089								bno_cur_gt,
1090								XFS_BTREE_NOERROR);
1091							bno_cur_gt = NULL;
1092						}
1093						/*
1094						 * Right side is better.
1095						 */
1096						else {
1097							xfs_btree_del_cursor(
1098								bno_cur_lt,
1099								XFS_BTREE_NOERROR);
1100							bno_cur_lt = NULL;
1101						}
1102						break;
1103					}
1104					/*
1105					 * Fell off the left end.
1106					 */
1107					if ((error = xfs_btree_decrement(
1108							bno_cur_lt, 0, &i)))
1109						goto error0;
1110					if (!i) {
1111						xfs_btree_del_cursor(bno_cur_lt,
1112							XFS_BTREE_NOERROR);
1113						bno_cur_lt = NULL;
1114						break;
1115					}
1116				}
1117			}
1118			/*
1119			 * The right side is perfect, trash the left side.
1120			 */
1121			else {
1122				xfs_btree_del_cursor(bno_cur_lt,
1123					XFS_BTREE_NOERROR);
1124				bno_cur_lt = NULL;
1125			}
1126		}
1127	}
1128	/*
1129	 * If we couldn't get anything, give up.
1130	 */
1131	if (bno_cur_lt == NULL && bno_cur_gt == NULL) {
1132		trace_xfs_alloc_size_neither(args);
1133		args->agbno = NULLAGBLOCK;
1134		return 0;
1135	}
1136	/*
1137	 * At this point we have selected a freespace entry, either to the
1138	 * left or to the right.  If it's on the right, copy all the
1139	 * useful variables to the "left" set so we only have one
1140	 * copy of this code.
1141	 */
1142	if (bno_cur_gt) {
1143		bno_cur_lt = bno_cur_gt;
1144		bno_cur_gt = NULL;
1145		ltbno = gtbno;
1146		ltbnoa = gtbnoa;
1147		ltlen = gtlen;
1148		ltlena = gtlena;
1149		j = 1;
1150	} else
1151		j = 0;
1152	/*
1153	 * Fix up the length and compute the useful address.
1154	 */
1155	ltend = ltbno + ltlen;
1156	args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1157	xfs_alloc_fix_len(args);
1158	if (!xfs_alloc_fix_minleft(args)) {
1159		trace_xfs_alloc_near_nominleft(args);
1160		xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
1161		xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1162		return 0;
1163	}
1164	rlen = args->len;
1165	(void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, ltbno,
1166		ltlen, &ltnew);
1167	ASSERT(ltnew >= ltbno);
1168	ASSERT(ltnew + rlen <= ltend);
1169	ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
1170	args->agbno = ltnew;
1171	if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen,
1172			ltnew, rlen, XFSA_FIXUP_BNO_OK)))
1173		goto error0;
1174
1175	if (j)
1176		trace_xfs_alloc_near_greater(args);
1177	else
1178		trace_xfs_alloc_near_lesser(args);
1179
1180	xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1181	xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
1182	return 0;
1183
1184 error0:
1185	trace_xfs_alloc_near_error(args);
1186	if (cnt_cur != NULL)
1187		xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1188	if (bno_cur_lt != NULL)
1189		xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_ERROR);
1190	if (bno_cur_gt != NULL)
1191		xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_ERROR);
1192	return error;
1193}
1194
1195/*
1196 * Allocate a variable extent anywhere in the allocation group agno.
1197 * Extent's length (returned in len) will be between minlen and maxlen,
1198 * and of the form k * prod + mod unless there's nothing that large.
1199 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.
1200 */
1201STATIC int				/* error */
1202xfs_alloc_ag_vextent_size(
1203	xfs_alloc_arg_t	*args)		/* allocation argument structure */
1204{
1205	xfs_btree_cur_t	*bno_cur;	/* cursor for bno btree */
1206	xfs_btree_cur_t	*cnt_cur;	/* cursor for cnt btree */
1207	int		error;		/* error result */
1208	xfs_agblock_t	fbno;		/* start of found freespace */
1209	xfs_extlen_t	flen;		/* length of found freespace */
1210	int		i;		/* temp status variable */
1211	xfs_agblock_t	rbno;		/* returned block number */
1212	xfs_extlen_t	rlen;		/* length of returned extent */
1213
1214	/*
1215	 * Allocate and initialize a cursor for the by-size btree.
1216	 */
1217	cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1218		args->agno, XFS_BTNUM_CNT);
1219	bno_cur = NULL;
1220	/*
1221	 * Look for an entry >= maxlen+alignment-1 blocks.
1222	 */
1223	if ((error = xfs_alloc_lookup_ge(cnt_cur, 0,
1224			args->maxlen + args->alignment - 1, &i)))
1225		goto error0;
1226	/*
1227	 * If none, then pick up the last entry in the tree unless the
1228	 * tree is empty.
1229	 */
1230	if (!i) {
1231		if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &fbno,
1232				&flen, &i)))
1233			goto error0;
1234		if (i == 0 || flen == 0) {
1235			xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1236			trace_xfs_alloc_size_noentry(args);
1237			return 0;
1238		}
1239		ASSERT(i == 1);
1240	}
1241	/*
1242	 * There's a freespace as big as maxlen+alignment-1, get it.
1243	 */
1244	else {
1245		if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i)))
1246			goto error0;
1247		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1248	}
1249	/*
1250	 * In the first case above, we got the last entry in the
1251	 * by-size btree.  Now we check to see if the space hits maxlen
1252	 * once aligned; if not, we search left for something better.
1253	 * This can't happen in the second case above.
1254	 */
1255	xfs_alloc_compute_aligned(fbno, flen, args->alignment, args->minlen,
1256		&rbno, &rlen);
1257	rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
1258	XFS_WANT_CORRUPTED_GOTO(rlen == 0 ||
1259			(rlen <= flen && rbno + rlen <= fbno + flen), error0);
1260	if (rlen < args->maxlen) {
1261		xfs_agblock_t	bestfbno;
1262		xfs_extlen_t	bestflen;
1263		xfs_agblock_t	bestrbno;
1264		xfs_extlen_t	bestrlen;
1265
1266		bestrlen = rlen;
1267		bestrbno = rbno;
1268		bestflen = flen;
1269		bestfbno = fbno;
1270		for (;;) {
1271			if ((error = xfs_btree_decrement(cnt_cur, 0, &i)))
1272				goto error0;
1273			if (i == 0)
1274				break;
1275			if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen,
1276					&i)))
1277				goto error0;
1278			XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1279			if (flen < bestrlen)
1280				break;
1281			xfs_alloc_compute_aligned(fbno, flen, args->alignment,
1282				args->minlen, &rbno, &rlen);
1283			rlen = XFS_EXTLEN_MIN(args->maxlen, rlen);
1284			XFS_WANT_CORRUPTED_GOTO(rlen == 0 ||
1285				(rlen <= flen && rbno + rlen <= fbno + flen),
1286				error0);
1287			if (rlen > bestrlen) {
1288				bestrlen = rlen;
1289				bestrbno = rbno;
1290				bestflen = flen;
1291				bestfbno = fbno;
1292				if (rlen == args->maxlen)
1293					break;
1294			}
1295		}
1296		if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen,
1297				&i)))
1298			goto error0;
1299		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1300		rlen = bestrlen;
1301		rbno = bestrbno;
1302		flen = bestflen;
1303		fbno = bestfbno;
1304	}
1305	args->wasfromfl = 0;
1306	/*
1307	 * Fix up the length.
1308	 */
1309	args->len = rlen;
1310	xfs_alloc_fix_len(args);
1311	if (rlen < args->minlen || !xfs_alloc_fix_minleft(args)) {
1312		xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1313		trace_xfs_alloc_size_nominleft(args);
1314		args->agbno = NULLAGBLOCK;
1315		return 0;
1316	}
1317	rlen = args->len;
1318	XFS_WANT_CORRUPTED_GOTO(rlen <= flen, error0);
1319	/*
1320	 * Allocate and initialize a cursor for the by-block tree.
1321	 */
1322	bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
1323		args->agno, XFS_BTNUM_BNO);
1324	if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
1325			rbno, rlen, XFSA_FIXUP_CNT_OK)))
1326		goto error0;
1327	xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1328	xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
1329	cnt_cur = bno_cur = NULL;
1330	args->len = rlen;
1331	args->agbno = rbno;
1332	XFS_WANT_CORRUPTED_GOTO(
1333		args->agbno + args->len <=
1334			be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
1335		error0);
1336	trace_xfs_alloc_size_done(args);
1337	return 0;
1338
1339error0:
1340	trace_xfs_alloc_size_error(args);
1341	if (cnt_cur)
1342		xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1343	if (bno_cur)
1344		xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
1345	return error;
1346}
1347
1348/*
1349 * Deal with the case where only small freespaces remain.
1350 * Either return the contents of the last freespace record,
1351 * or allocate space from the freelist if there is nothing in the tree.
1352 */
1353STATIC int			/* error */
1354xfs_alloc_ag_vextent_small(
1355	xfs_alloc_arg_t	*args,	/* allocation argument structure */
1356	xfs_btree_cur_t	*ccur,	/* by-size cursor */
1357	xfs_agblock_t	*fbnop,	/* result block number */
1358	xfs_extlen_t	*flenp,	/* result length */
1359	int		*stat)	/* status: 0-freelist, 1-normal/none */
1360{
1361	int		error;
1362	xfs_agblock_t	fbno;
1363	xfs_extlen_t	flen;
1364	int		i;
1365
1366	if ((error = xfs_btree_decrement(ccur, 0, &i)))
1367		goto error0;
1368	if (i) {
1369		if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i)))
1370			goto error0;
1371		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1372	}
1373	/*
1374	 * Nothing in the btree, try the freelist.  Make sure
1375	 * to respect minleft even when pulling from the
1376	 * freelist.
1377	 */
1378	else if (args->minlen == 1 && args->alignment == 1 && !args->isfl &&
1379		 (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
1380		  > args->minleft)) {
1381		error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
1382		if (error)
1383			goto error0;
1384		if (fbno != NULLAGBLOCK) {
1385			if (args->userdata) {
1386				xfs_buf_t	*bp;
1387
1388				bp = xfs_btree_get_bufs(args->mp, args->tp,
1389					args->agno, fbno, 0);
1390				xfs_trans_binval(args->tp, bp);
1391			}
1392			args->len = 1;
1393			args->agbno = fbno;
1394			XFS_WANT_CORRUPTED_GOTO(
1395				args->agbno + args->len <=
1396				be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
1397				error0);
1398			args->wasfromfl = 1;
1399			trace_xfs_alloc_small_freelist(args);
1400			*stat = 0;
1401			return 0;
1402		}
1403		/*
1404		 * Nothing in the freelist.
1405		 */
1406		else
1407			flen = 0;
1408	}
1409	/*
1410	 * Can't allocate from the freelist for some reason.
1411	 */
1412	else {
1413		fbno = NULLAGBLOCK;
1414		flen = 0;
1415	}
1416	/*
1417	 * Can't do the allocation, give up.
1418	 */
1419	if (flen < args->minlen) {
1420		args->agbno = NULLAGBLOCK;
1421		trace_xfs_alloc_small_notenough(args);
1422		flen = 0;
1423	}
1424	*fbnop = fbno;
1425	*flenp = flen;
1426	*stat = 1;
1427	trace_xfs_alloc_small_done(args);
1428	return 0;
1429
1430error0:
1431	trace_xfs_alloc_small_error(args);
1432	return error;
1433}
1434
1435/*
1436 * Free the extent starting at agno/bno for length.
1437 */
1438STATIC int			/* error */
1439xfs_free_ag_extent(
1440	xfs_trans_t	*tp,	/* transaction pointer */
1441	xfs_buf_t	*agbp,	/* buffer for a.g. freelist header */
1442	xfs_agnumber_t	agno,	/* allocation group number */
1443	xfs_agblock_t	bno,	/* starting block number */
1444	xfs_extlen_t	len,	/* length of extent */
1445	int		isfl)	/* set if is freelist blocks - no sb acctg */
1446{
1447	xfs_btree_cur_t	*bno_cur;	/* cursor for by-block btree */
1448	xfs_btree_cur_t	*cnt_cur;	/* cursor for by-size btree */
1449	int		error;		/* error return value */
1450	xfs_agblock_t	gtbno;		/* start of right neighbor block */
1451	xfs_extlen_t	gtlen;		/* length of right neighbor block */
1452	int		haveleft;	/* have a left neighbor block */
1453	int		haveright;	/* have a right neighbor block */
1454	int		i;		/* temp, result code */
1455	xfs_agblock_t	ltbno;		/* start of left neighbor block */
1456	xfs_extlen_t	ltlen;		/* length of left neighbor block */
1457	xfs_mount_t	*mp;		/* mount point struct for filesystem */
1458	xfs_agblock_t	nbno;		/* new starting block of freespace */
1459	xfs_extlen_t	nlen;		/* new length of freespace */
1460
1461	mp = tp->t_mountp;
1462	/*
1463	 * Allocate and initialize a cursor for the by-block btree.
1464	 */
1465	bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO);
1466	cnt_cur = NULL;
1467	/*
1468	 * Look for a neighboring block on the left (lower block numbers)
1469	 * that is contiguous with this space.
1470	 */
1471	if ((error = xfs_alloc_lookup_le(bno_cur, bno, len, &haveleft)))
1472		goto error0;
1473	if (haveleft) {
1474		/*
1475		 * There is a block to our left.
1476		 */
1477		if ((error = xfs_alloc_get_rec(bno_cur, &ltbno, &ltlen, &i)))
1478			goto error0;
1479		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1480		/*
1481		 * It's not contiguous, though.
1482		 */
1483		if (ltbno + ltlen < bno)
1484			haveleft = 0;
1485		else {
1486			/*
1487			 * If this failure happens the request to free this
1488			 * space was invalid, it's (partly) already free.
1489			 * Very bad.
1490			 */
1491			XFS_WANT_CORRUPTED_GOTO(ltbno + ltlen <= bno, error0);
1492		}
1493	}
1494	/*
1495	 * Look for a neighboring block on the right (higher block numbers)
1496	 * that is contiguous with this space.
1497	 */
1498	if ((error = xfs_btree_increment(bno_cur, 0, &haveright)))
1499		goto error0;
1500	if (haveright) {
1501		/*
1502		 * There is a block to our right.
1503		 */
1504		if ((error = xfs_alloc_get_rec(bno_cur, &gtbno, &gtlen, &i)))
1505			goto error0;
1506		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1507		/*
1508		 * It's not contiguous, though.
1509		 */
1510		if (bno + len < gtbno)
1511			haveright = 0;
1512		else {
1513			/*
1514			 * If this failure happens the request to free this
1515			 * space was invalid, it's (partly) already free.
1516			 * Very bad.
1517			 */
1518			XFS_WANT_CORRUPTED_GOTO(gtbno >= bno + len, error0);
1519		}
1520	}
1521	/*
1522	 * Now allocate and initialize a cursor for the by-size tree.
1523	 */
1524	cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT);
1525	/*
1526	 * Have both left and right contiguous neighbors.
1527	 * Merge all three into a single free block.
1528	 */
1529	if (haveleft && haveright) {
1530		/*
1531		 * Delete the old by-size entry on the left.
1532		 */
1533		if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
1534			goto error0;
1535		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1536		if ((error = xfs_btree_delete(cnt_cur, &i)))
1537			goto error0;
1538		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1539		/*
1540		 * Delete the old by-size entry on the right.
1541		 */
1542		if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
1543			goto error0;
1544		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1545		if ((error = xfs_btree_delete(cnt_cur, &i)))
1546			goto error0;
1547		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1548		/*
1549		 * Delete the old by-block entry for the right block.
1550		 */
1551		if ((error = xfs_btree_delete(bno_cur, &i)))
1552			goto error0;
1553		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1554		/*
1555		 * Move the by-block cursor back to the left neighbor.
1556		 */
1557		if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
1558			goto error0;
1559		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1560#ifdef DEBUG
1561		/*
1562		 * Check that this is the right record: delete didn't
1563		 * mangle the cursor.
1564		 */
1565		{
1566			xfs_agblock_t	xxbno;
1567			xfs_extlen_t	xxlen;
1568
1569			if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen,
1570					&i)))
1571				goto error0;
1572			XFS_WANT_CORRUPTED_GOTO(
1573				i == 1 && xxbno == ltbno && xxlen == ltlen,
1574				error0);
1575		}
1576#endif
1577		/*
1578		 * Update remaining by-block entry to the new, joined block.
1579		 */
1580		nbno = ltbno;
1581		nlen = len + ltlen + gtlen;
1582		if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
1583			goto error0;
1584	}
1585	/*
1586	 * Have only a left contiguous neighbor.
1587	 * Merge it together with the new freespace.
1588	 */
1589	else if (haveleft) {
1590		/*
1591		 * Delete the old by-size entry on the left.
1592		 */
1593		if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
1594			goto error0;
1595		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1596		if ((error = xfs_btree_delete(cnt_cur, &i)))
1597			goto error0;
1598		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1599		/*
1600		 * Back up the by-block cursor to the left neighbor, and
1601		 * update its length.
1602		 */
1603		if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
1604			goto error0;
1605		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1606		nbno = ltbno;
1607		nlen = len + ltlen;
1608		if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
1609			goto error0;
1610	}
1611	/*
1612	 * Have only a right contiguous neighbor.
1613	 * Merge it together with the new freespace.
1614	 */
1615	else if (haveright) {
1616		/*
1617		 * Delete the old by-size entry on the right.
1618		 */
1619		if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
1620			goto error0;
1621		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1622		if ((error = xfs_btree_delete(cnt_cur, &i)))
1623			goto error0;
1624		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1625		/*
1626		 * Update the starting block and length of the right
1627		 * neighbor in the by-block tree.
1628		 */
1629		nbno = bno;
1630		nlen = len + gtlen;
1631		if ((error = xfs_alloc_update(bno_cur, nbno, nlen)))
1632			goto error0;
1633	}
1634	/*
1635	 * No contiguous neighbors.
1636	 * Insert the new freespace into the by-block tree.
1637	 */
1638	else {
1639		nbno = bno;
1640		nlen = len;
1641		if ((error = xfs_btree_insert(bno_cur, &i)))
1642			goto error0;
1643		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1644	}
1645	xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR);
1646	bno_cur = NULL;
1647	/*
1648	 * In all cases we need to insert the new freespace in the by-size tree.
1649	 */
1650	if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i)))
1651		goto error0;
1652	XFS_WANT_CORRUPTED_GOTO(i == 0, error0);
1653	if ((error = xfs_btree_insert(cnt_cur, &i)))
1654		goto error0;
1655	XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1656	xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1657	cnt_cur = NULL;
1658	/*
1659	 * Update the freespace totals in the ag and superblock.
1660	 */
1661	{
1662		xfs_agf_t	*agf;
1663		xfs_perag_t	*pag;		/* per allocation group data */
1664
1665		agf = XFS_BUF_TO_AGF(agbp);
1666		pag = &mp->m_perag[agno];
1667		be32_add_cpu(&agf->agf_freeblks, len);
1668		xfs_trans_agblocks_delta(tp, len);
1669		pag->pagf_freeblks += len;
1670		XFS_WANT_CORRUPTED_GOTO(
1671			be32_to_cpu(agf->agf_freeblks) <=
1672			be32_to_cpu(agf->agf_length),
1673			error0);
1674		xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
1675		if (!isfl)
1676			xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len);
1677		XFS_STATS_INC(xs_freex);
1678		XFS_STATS_ADD(xs_freeb, len);
1679	}
1680
1681	trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright);
1682
1683	/*
1684	 * Since blocks move to the free list without the coordination
1685	 * used in xfs_bmap_finish, we can't allow block to be available
1686	 * for reallocation and non-transaction writing (user data)
1687	 * until we know that the transaction that moved it to the free
1688	 * list is permanently on disk.  We track the blocks by declaring
1689	 * these blocks as "busy"; the busy list is maintained on a per-ag
1690	 * basis and each transaction records which entries should be removed
1691	 * when the iclog commits to disk.  If a busy block is allocated,
1692	 * the iclog is pushed up to the LSN that freed the block.
1693	 */
1694	xfs_alloc_mark_busy(tp, agno, bno, len);
1695	return 0;
1696
1697 error0:
1698	trace_xfs_free_extent(mp, agno, bno, len, isfl, -1, -1);
1699	if (bno_cur)
1700		xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR);
1701	if (cnt_cur)
1702		xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
1703	return error;
1704}
1705
1706/*
1707 * Visible (exported) allocation/free functions.
1708 * Some of these are used just by xfs_alloc_btree.c and this file.
1709 */
1710
1711/*
1712 * Compute and fill in value of m_ag_maxlevels.
1713 */
1714void
1715xfs_alloc_compute_maxlevels(
1716	xfs_mount_t	*mp)	/* file system mount structure */
1717{
1718	int		level;
1719	uint		maxblocks;
1720	uint		maxleafents;
1721	int		minleafrecs;
1722	int		minnoderecs;
1723
1724	maxleafents = (mp->m_sb.sb_agblocks + 1) / 2;
1725	minleafrecs = mp->m_alloc_mnr[0];
1726	minnoderecs = mp->m_alloc_mnr[1];
1727	maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
1728	for (level = 1; maxblocks > 1; level++)
1729		maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
1730	mp->m_ag_maxlevels = level;
1731}
1732
1733/*
1734 * Find the length of the longest extent in an AG.
1735 */
1736xfs_extlen_t
1737xfs_alloc_longest_free_extent(
1738	struct xfs_mount	*mp,
1739	struct xfs_perag	*pag)
1740{
1741	xfs_extlen_t		need, delta = 0;
1742
1743	need = XFS_MIN_FREELIST_PAG(pag, mp);
1744	if (need > pag->pagf_flcount)
1745		delta = need - pag->pagf_flcount;
1746
1747	if (pag->pagf_longest > delta)
1748		return pag->pagf_longest - delta;
1749	return pag->pagf_flcount > 0 || pag->pagf_longest > 0;
1750}
1751
1752/*
1753 * Decide whether to use this allocation group for this allocation.
1754 * If so, fix up the btree freelist's size.
1755 */
1756STATIC int			/* error */
1757xfs_alloc_fix_freelist(
1758	xfs_alloc_arg_t	*args,	/* allocation argument structure */
1759	int		flags)	/* XFS_ALLOC_FLAG_... */
1760{
1761	xfs_buf_t	*agbp;	/* agf buffer pointer */
1762	xfs_agf_t	*agf;	/* a.g. freespace structure pointer */
1763	xfs_buf_t	*agflbp;/* agfl buffer pointer */
1764	xfs_agblock_t	bno;	/* freelist block */
1765	xfs_extlen_t	delta;	/* new blocks needed in freelist */
1766	int		error;	/* error result code *…

Large files files are truncated, but you can click here to view the full file