// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 */
#include "xfs_platform.h"
#include "xfs_fs.h"
#include "xfs_shared.h"
#include "xfs_format.h"
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
#include "xfs_bit.h"
#include "xfs_mount.h"
#include "xfs_inode.h"
#include "xfs_alloc.h"
#include "xfs_bmap.h"
#include "xfs_bmap_btree.h"
#include "xfs_bmap_util.h"
#include "xfs_trans.h"
#include "xfs_trans_space.h"
#include "xfs_icache.h"
#include "xfs_rtalloc.h"
#include "xfs_sb.h"
#include "xfs_rtbitmap.h"
#include "xfs_rtrmap_btree.h"
#include "xfs_quota.h"
#include "xfs_log_priv.h"
#include "xfs_health.h"
#include "xfs_da_format.h"
#include "xfs_metafile.h"
#include "xfs_rtgroup.h"
#include "xfs_error.h"
#include "xfs_trace.h"
#include "xfs_rtrefcount_btree.h"
#include "xfs_reflink.h"
#include "xfs_zone_alloc.h"

/*
 * Return whether there are any free extents in the size range given
 * by low and high, for the bitmap block bbno.
 */
STATIC int
xfs_rtany_summary(
	struct xfs_rtalloc_args	*args,
	int			low,	/* low log2 extent size */
	int			high,	/* high log2 extent size */
	xfs_fileoff_t		bbno,	/* bitmap block number */
	int			*maxlog) /* out: max log2 extent size free */
{
	uint8_t			*rsum_cache = args->rtg->rtg_rsum_cache;
	int			error;
	int			log;	/* loop counter, log2 of ext. size */
	xfs_suminfo_t		sum;	/* summary data */

	/* There are no extents at levels >= rsum_cache[bbno]. */
	if (rsum_cache) {
		high = min(high, rsum_cache[bbno] - 1);
		if (low > high) {
			*maxlog = -1;
			return 0;
		}
	}

	/*
	 * Loop over logs of extent sizes.
	 */
	for (log = high; log >= low; log--) {
		/*
		 * Get one summary datum.
		 */
		error = xfs_rtget_summary(args, log, bbno, &sum);
		if (error) {
			return error;
		}
		/*
		 * If there are any, return success.
		 */
		if (sum) {
			*maxlog = log;
			goto out;
		}
	}
	/*
	 * Found nothing, return failure.
	 */
	*maxlog = -1;
out:
	/* There were no extents at levels > log. */
	if (rsum_cache && log + 1 < rsum_cache[bbno])
		rsum_cache[bbno] = log + 1;
	return 0;
}

/*
 * Copy and transform the summary file, given the old and new
 * parameters in the mount structures.
 */
STATIC int
xfs_rtcopy_summary(
	struct xfs_rtalloc_args	*oargs,
	struct xfs_rtalloc_args	*nargs)
{
	xfs_fileoff_t		bbno;	/* bitmap block number */
	int			error;
	int			log;	/* summary level number (log length) */
	xfs_suminfo_t		sum;	/* summary data */

	for (log = oargs->mp->m_rsumlevels - 1; log >= 0; log--) {
		for (bbno = oargs->mp->m_sb.sb_rbmblocks - 1;
		     (xfs_srtblock_t)bbno >= 0;
		     bbno--) {
			error = xfs_rtget_summary(oargs, log, bbno, &sum);
			if (error)
				goto out;
			if (XFS_IS_CORRUPT(oargs->mp, sum < 0)) {
				error = -EFSCORRUPTED;
				goto out;
			}
			if (sum == 0)
				continue;
			error = xfs_rtmodify_summary(oargs, log, bbno, -sum);
			if (error)
				goto out;
			error = xfs_rtmodify_summary(nargs, log, bbno, sum);
			if (error)
				goto out;
		}
	}
	error = 0;
out:
	xfs_rtbuf_cache_relse(oargs);
	return error;
}
/*
 * Mark an extent specified by start and len allocated.
 * Updates all the summary information as well as the bitmap.
 */
STATIC int
xfs_rtallocate_range(
	struct xfs_rtalloc_args	*args,
	xfs_rtxnum_t		start,	/* start rtext to allocate */
	xfs_rtxlen_t		len)	/* in/out: summary block number */
{
	struct xfs_mount	*mp = args->mp;
	xfs_rtxnum_t		end;	/* end of the allocated rtext */
	int			error;
	xfs_rtxnum_t		postblock = 0; /* first rtext allocated > end */
	xfs_rtxnum_t		preblock = 0; /* first rtext allocated < start */

	end = start + len - 1;
	/*
	 * Assume we're allocating out of the middle of a free extent.
	 * We need to find the beginning and end of the extent so we can
	 * properly update the summary.
	 */
	error = xfs_rtfind_back(args, start, &preblock);
	if (error)
		return error;

	/*
	 * Find the next allocated block (end of free extent).
	 */
	error = xfs_rtfind_forw(args, end, args->rtg->rtg_extents - 1,
			&postblock);
	if (error)
		return error;

	/*
	 * Decrement the summary information corresponding to the entire
	 * (old) free extent.
	 */
	error = xfs_rtmodify_summary(args,
			xfs_highbit64(postblock + 1 - preblock),
			xfs_rtx_to_rbmblock(mp, preblock), -1);
	if (error)
		return error;

	/*
	 * If there are blocks not being allocated at the front of the
	 * old extent, add summary data for them to be free.
	 */
	if (preblock < start) {
		error = xfs_rtmodify_summary(args,
				xfs_highbit64(start - preblock),
				xfs_rtx_to_rbmblock(mp, preblock), 1);
		if (error)
			return error;
	}

	/*
	 * If there are blocks not being allocated at the end of the
	 * old extent, add summary data for them to be free.
	 */
	if (postblock > end) {
		error = xfs_rtmodify_summary(args,
				xfs_highbit64(postblock - end),
				xfs_rtx_to_rbmblock(mp, end + 1), 1);
		if (error)
			return error;
	}

	/*
	 * Modify the bitmap to mark this extent allocated.
	 */
	return xfs_rtmodify_range(args, start, len, 0);
}

/* Reduce @rtxlen until it is a multiple of @prod. */
static inline xfs_rtxlen_t
xfs_rtalloc_align_len(
	xfs_rtxlen_t	rtxlen,
	xfs_rtxlen_t	prod)
{
	if (unlikely(prod > 1))
		return rounddown(rtxlen, prod);
	return rtxlen;
}

/*
 * Make sure we don't run off the end of the rt volume.  Be careful that
 * adjusting maxlen downwards doesn't cause us to fail the alignment checks.
 */
static inline xfs_rtxlen_t
xfs_rtallocate_clamp_len(
	struct xfs_rtgroup	*rtg,
	xfs_rtxnum_t		startrtx,
	xfs_rtxlen_t		rtxlen,
	xfs_rtxlen_t		prod)
{
	xfs_rtxlen_t		ret;

	ret = min(rtg->rtg_extents, startrtx + rtxlen) - startrtx;
	return xfs_rtalloc_align_len(ret, prod);
}

/*
 * Attempt to allocate an extent minlen<=len<=maxlen starting from
 * bitmap block bbno.  If we don't get maxlen then use prod to trim
 * the length, if given.  Returns error; returns starting block in *rtx.
 * The lengths are all in rtextents.
 */
STATIC int
xfs_rtallocate_extent_block(
	struct xfs_rtalloc_args	*args,
	xfs_fileoff_t		bbno,	/* bitmap block number */
	xfs_rtxlen_t		minlen,	/* minimum length to allocate */
	xfs_rtxlen_t		maxlen,	/* maximum length to allocate */
	xfs_rtxlen_t		*len,	/* out: actual length allocated */
	xfs_rtxnum_t		*nextp,	/* out: next rtext to try */
	xfs_rtxlen_t		prod,	/* extent product factor */
	xfs_rtxnum_t		*rtx)	/* out: start rtext allocated */
{
	struct xfs_mount	*mp = args->mp;
	xfs_rtxnum_t		besti = -1; /* best rtext found so far */
	xfs_rtxnum_t		end;	/* last rtext in chunk */
	xfs_rtxnum_t		i;	/* current rtext trying */
	xfs_rtxnum_t		next;	/* next rtext to try */
	xfs_rtxlen_t		scanlen; /* number of free rtx to look for */
	xfs_rtxlen_t		bestlen = 0; /* best length found so far */
	int			stat;	/* status from internal calls */
	int			error;

	/*
	 * Loop over all the extents starting in this bitmap block up to the
	 * end of the rt volume, looking for one that's long enough.
	 */
	end = min(args->rtg->rtg_extents, xfs_rbmblock_to_rtx(mp, bbno + 1)) -
		1;
	for (i = xfs_rbmblock_to_rtx(mp, bbno); i <= end; i++) {
		/* Make sure we don't scan off the end of the rt volume. */
		scanlen = xfs_rtallocate_clamp_len(args->rtg, i, maxlen, prod);
		if (scanlen < minlen)
			break;

		/*
		 * See if there's a free extent of scanlen starting at i.
		 * If it's not so then next will contain the first non-free.
		 */
		error = xfs_rtcheck_range(args, i, scanlen, 1, &next, &stat);
		if (error)
			return error;
		if (stat) {
			/*
			 * i to scanlen is all free, allocate and return that.
			 */
			*len = scanlen;
			*rtx = i;
			return 0;
		}

		/*
		 * In the case where we have a variable-sized allocation
		 * request, figure out how big this free piece is,
		 * and if it's big enough for the minimum, and the best
		 * so far, remember it.
		 */
		if (minlen < maxlen) {
			xfs_rtxnum_t	thislen;	/* this extent size */

			thislen = next - i;
			if (thislen >= minlen && thislen > bestlen) {
				besti = i;
				bestlen = thislen;
			}
		}
		/*
		 * If not done yet, find the start of the next free space.
		 */
		if (next >= end)
			break;
		error = xfs_rtfind_forw(args, next, end, &i);
		if (error)
			return error;
	}

	/* Searched the whole thing & didn't find a maxlen free extent. */
	if (besti == -1)
		goto nospace;

	/*
	 * Ensure bestlen is a multiple of prod, but don't return a too-short
	 * extent.
	 */
	bestlen = xfs_rtalloc_align_len(bestlen, prod);
	if (bestlen < minlen)
		goto nospace;

	/*
	 * Pick besti for bestlen & return that.
	 */
	*len = bestlen;
	*rtx = besti;
	return 0;
nospace:
	/* Allocation failed.  Set *nextp to the next block to try. */
	*nextp = next;
	return -ENOSPC;
}

/*
 * Allocate an extent of length minlen<=len<=maxlen, starting at block
 * bno.  If we don't get maxlen then use prod to trim the length, if given.
 * Returns error; returns starting block in *rtx.
 * The lengths are all in rtextents.
 */
STATIC int
xfs_rtallocate_extent_exact(
	struct xfs_rtalloc_args	*args,
	xfs_rtxnum_t		start,	/* starting rtext number to allocate */
	xfs_rtxlen_t		minlen,	/* minimum length to allocate */
	xfs_rtxlen_t		maxlen,	/* maximum length to allocate */
	xfs_rtxlen_t		*len,	/* out: actual length allocated */
	xfs_rtxlen_t		prod,	/* extent product factor */
	xfs_rtxnum_t		*rtx)	/* out: start rtext allocated */
{
	xfs_rtxnum_t		next;	/* next rtext to try (dummy) */
	xfs_rtxlen_t		alloclen; /* candidate length */
	xfs_rtxlen_t		scanlen; /* number of free rtx to look for */
	int			isfree;	/* extent is free */
	int			error;

	ASSERT(minlen % prod == 0);
	ASSERT(maxlen % prod == 0);

	/* Make sure we don't run off the end of the rt volume. */
	scanlen = xfs_rtallocate_clamp_len(args->rtg, start, maxlen, prod);
	if (scanlen < minlen)
		return -ENOSPC;

	/* Check if the range in question (for scanlen) is free. */
	error = xfs_rtcheck_range(args, start, scanlen, 1, &next, &isfree);
	if (error)
		return error;

	if (isfree) {
		/* start to scanlen is all free; allocate it. */
		*len = scanlen;
		*rtx = start;
		return 0;
	}

	/*
	 * If not, allocate what there is, if it's at least minlen.
	 */
	alloclen = next - start;
	if (alloclen < minlen)
		return -ENOSPC;

	/* Ensure alloclen is a multiple of prod. */
	alloclen = xfs_rtalloc_align_len(alloclen, prod);
	if (alloclen < minlen)
		return -ENOSPC;

	*len = alloclen;
	*rtx = start;
	return 0;
}

/*
 * Allocate an extent of length minlen<=len<=maxlen, starting as near
 * to start as possible.  If we don't get maxlen then use prod to trim
 * the length, if given.  The lengths are all in rtextents.
 */
STATIC int
xfs_rtallocate_extent_near(
	struct xfs_rtalloc_args	*args,
	xfs_rtxnum_t		start,	/* starting rtext number to allocate */
	xfs_rtxlen_t		minlen,	/* minimum length to allocate */
	xfs_rtxlen_t		maxlen,	/* maximum length to allocate */
	xfs_rtxlen_t		*len,	/* out: actual length allocated */
	xfs_rtxlen_t		prod,	/* extent product factor */
	xfs_rtxnum_t		*rtx)	/* out: start rtext allocated */
{
	struct xfs_mount	*mp = args->mp;
	int			maxlog;	/* max useful extent from summary */
	xfs_fileoff_t		bbno;	/* bitmap block number */
	int			error;
	int			i;	/* bitmap block offset (loop control) */
	int			j;	/* secondary loop control */
	int			log2len; /* log2 of minlen */
	xfs_rtxnum_t		n;	/* next rtext to try */

	ASSERT(minlen % prod == 0);
	ASSERT(maxlen % prod == 0);

	/*
	 * If the block number given is off the end, silently set it to the last
	 * block.
	 */
	start = min(start, args->rtg->rtg_extents - 1);

	/*
	 * Try the exact allocation first.
	 */
	error = xfs_rtallocate_extent_exact(args, start, minlen, maxlen, len,
			prod, rtx);
	if (error != -ENOSPC)
		return error;

	bbno = xfs_rtx_to_rbmblock(mp, start);
	i = 0;
	j = -1;
	ASSERT(minlen != 0);
	log2len = xfs_highbit32(minlen);
	/*
	 * Loop over all bitmap blocks (bbno + i is current block).
	 */
	for (;;) {
		/*
		 * Get summary information of extents of all useful levels
		 * starting in this bitmap block.
		 */
		error = xfs_rtany_summary(args, log2len, mp->m_rsumlevels - 1,
				bbno + i, &maxlog);
		if (error)
			return error;

		/*
		 * If there are any useful extents starting here, try
		 * allocating one.
		 */
		if (maxlog >= 0) {
			xfs_extlen_t maxavail =
				min_t(xfs_rtblock_t, maxlen,
				      (1ULL << (maxlog + 1)) - 1);
			/*
			 * On the positive side of the starting location.
			 */
			if (i >= 0) {
				/*
				 * Try to allocate an extent starting in
				 * this block.
				 */
				error = xfs_rtallocate_extent_block(args,
						bbno + i, minlen, maxavail, len,
						&n, prod, rtx);
				if (error != -ENOSPC)
					return error;
			}
			/*
			 * On the negative side of the starting location.
			 */
			else {		/* i < 0 */
				int	maxblocks;

				/*
				 * Loop backwards to find the end of the extent
				 * we found in the realtime summary.
				 *
				 * maxblocks is the maximum possible number of
				 * bitmap blocks from the start of the extent
				 * to the end of the extent.
				 */
				if (maxlog == 0)
					maxblocks = 0;
				else if (maxlog < mp->m_blkbit_log)
					maxblocks = 1;
				else
					maxblocks = 2 << (maxlog - mp->m_blkbit_log);

				/*
				 * We need to check bbno + i + maxblocks down to
				 * bbno + i. We already checked bbno down to
				 * bbno + j + 1, so we don't need to check those
				 * again.
				 */
				j = min(i + maxblocks, j);
				for (; j >= i; j--) {
					error = xfs_rtallocate_extent_block(args,
							bbno + j, minlen,
							maxavail, len, &n, prod,
							rtx);
					if (error != -ENOSPC)
						return error;
				}
			}
		}
		/*
		 * Loop control.  If we were on the positive side, and there's
		 * still more blocks on the negative side, go there.
		 */
		if (i > 0 && (int)bbno - i >= 0)
			i = -i;
		/*
		 * If positive, and no more negative, but there are more
		 * positive, go there.
		 */
		else if (i > 0 && (int)bbno + i < mp->m_sb.sb_rbmblocks - 1)
			i++;
		/*
		 * If negative or 0 (just started), and there are positive
		 * blocks to go, go there.  The 0 case moves to block 1.
		 */
		else if (i <= 0 && (int)bbno - i < mp->m_sb.sb_rbmblocks - 1)
			i = 1 - i;
		/*
		 * If negative or 0 and there are more negative blocks,
		 * go there.
		 */
		else if (i <= 0 && (int)bbno + i > 0)
			i--;
		/*
		 * Must be done.  Return failure.
		 */
		else
			break;
	}
	return -ENOSPC;
}

static int
xfs_rtalloc_sumlevel(
	struct xfs_rtalloc_args	*args,
	int			l,	/* level number */
	xfs_rtxlen_t		minlen,	/* minimum length to allocate */
	xfs_rtxlen_t		maxlen,	/* maximum length to allocate */
	xfs_rtxlen_t		prod,	/* extent product factor */
	xfs_rtxlen_t		*len,	/* out: actual length allocated */
	xfs_rtxnum_t		*rtx)	/* out: start rtext allocated */
{
	xfs_fileoff_t		i;	/* bitmap block number */
	int			error;

	for (i = 0; i < args->mp->m_sb.sb_rbmblocks; i++) {
		xfs_suminfo_t	sum;	/* summary information for extents */
		xfs_rtxnum_t	n;	/* next rtext to be tried */

		error = xfs_rtget_summary(args, l, i, &sum);
		if (error)
			return error;

		/*
		 * Nothing there, on to the next block.
		 */
		if (!sum)
			continue;

		/*
		 * Try allocating the extent.
		 */
		error = xfs_rtallocate_extent_block(args, i, minlen, maxlen,
				len, &n, prod, rtx);
		if (error != -ENOSPC)
			return error;

		/*
		 * If the "next block to try" returned from the allocator is
		 * beyond the next bitmap block, skip to that bitmap block.
		 */
		if (xfs_rtx_to_rbmblock(args->mp, n) > i + 1)
			i = xfs_rtx_to_rbmblock(args->mp, n) - 1;
	}

	return -ENOSPC;
}

/*
 * Allocate an extent of length minlen<=len<=maxlen, with no position
 * specified.  If we don't get maxlen then use prod to trim
 * the length, if given.  The lengths are all in rtextents.
 */
static int
xfs_rtallocate_extent_size(
	struct xfs_rtalloc_args	*args,
	xfs_rtxlen_t		minlen,	/* minimum length to allocate */
	xfs_rtxlen_t		maxlen,	/* maximum length to allocate */
	xfs_rtxlen_t		*len,	/* out: actual length allocated */
	xfs_rtxlen_t		prod,	/* extent product factor */
	xfs_rtxnum_t		*rtx)	/* out: start rtext allocated */
{
	int			error;
	int			l;	/* level number (loop control) */

	ASSERT(minlen % prod == 0);
	ASSERT(maxlen % prod == 0);
	ASSERT(maxlen != 0);

	/*
	 * Loop over all the levels starting with maxlen.
	 *
	 * At each level, look at all the bitmap blocks, to see if there are
	 * extents starting there that are long enough (>= maxlen).
	 *
	 * Note, only on the initial level can the allocation fail if the
	 * summary says there's an extent.
	 */
	for (l = xfs_highbit32(maxlen); l < args->mp->m_rsumlevels; l++) {
		error = xfs_rtalloc_sumlevel(args, l, minlen, maxlen, prod, len,
				rtx);
		if (error != -ENOSPC)
			return error;
	}

	/*
	 * Didn't find any maxlen blocks.  Try smaller ones, unless we are
	 * looking for a fixed size extent.
	 */
	if (minlen > --maxlen)
		return -ENOSPC;
	ASSERT(minlen != 0);
	ASSERT(maxlen != 0);

	/*
	 * Loop over sizes, from maxlen down to minlen.
	 *
	 * This time, when we do the allocations, allow smaller ones to succeed,
	 * but make sure the specified minlen/maxlen are in the possible range
	 * for this summary level.
	 */
	for (l = xfs_highbit32(maxlen); l >= xfs_highbit32(minlen); l--) {
		error = xfs_rtalloc_sumlevel(args, l,
				max_t(xfs_rtxlen_t, minlen, 1 << l),
				min_t(xfs_rtxlen_t, maxlen, (1 << (l + 1)) - 1),
				prod, len, rtx);
		if (error != -ENOSPC)
			return error;
	}

	return -ENOSPC;
}

static void
xfs_rtunmount_rtg(
	struct xfs_rtgroup	*rtg)
{
	int			i;

	for (i = 0; i < XFS_RTGI_MAX; i++)
		xfs_rtginode_irele(&rtg->rtg_inodes[i]);
	if (!xfs_has_zoned(rtg_mount(rtg)))
		kvfree(rtg->rtg_rsum_cache);
}

static int
xfs_alloc_rsum_cache(
	struct xfs_rtgroup	*rtg,
	xfs_extlen_t		rbmblocks)
{
	/*
	 * The rsum cache is initialized to the maximum value, which is
	 * trivially an upper bound on the maximum level with any free extents.
	 */
	rtg->rtg_rsum_cache = kvmalloc(rbmblocks, GFP_KERNEL);
	if (!rtg->rtg_rsum_cache)
		return -ENOMEM;
	memset(rtg->rtg_rsum_cache, -1, rbmblocks);
	return 0;
}

/*
 * If we changed the rt extent size (meaning there was no rt volume previously)
 * and the root directory had EXTSZINHERIT and RTINHERIT set, it's possible
 * that the extent size hint on the root directory is no longer congruent with
 * the new rt extent size.  Log the rootdir inode to fix this.
 */
static int
xfs_growfs_rt_fixup_extsize(
	struct xfs_mount	*mp)
{
	struct xfs_inode	*ip = mp->m_rootip;
	struct xfs_trans	*tp;
	int			error = 0;

	xfs_ilock(ip, XFS_IOLOCK_EXCL);
	if (!(ip->i_diflags & XFS_DIFLAG_RTINHERIT) ||
	    !(ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT))
		goto out_iolock;

	error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_ichange, 0, 0, false,
			&tp);
	if (error)
		goto out_iolock;

	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
	error = xfs_trans_commit(tp);
	xfs_iunlock(ip, XFS_ILOCK_EXCL);

out_iolock:
	xfs_iunlock(ip, XFS_IOLOCK_EXCL);
	return error;
}

/* Ensure that the rtgroup metadata inode is loaded, creating it if neeeded. */
static int
xfs_rtginode_ensure(
	struct xfs_rtgroup	*rtg,
	enum xfs_rtg_inodes	type)
{
	struct xfs_trans	*tp;
	int			error;

	if (rtg->rtg_inodes[type])
		return 0;

	tp = xfs_trans_alloc_empty(rtg_mount(rtg));
	error = xfs_rtginode_load(rtg, type, tp);
	xfs_trans_cancel(tp);

	if (error != -ENOENT)
		return error;
	return xfs_rtginode_create(rtg, type, true);
}

static struct xfs_mount *
xfs_growfs_rt_alloc_fake_mount(
	const struct xfs_mount	*mp,
	xfs_rfsblock_t		rblocks,
	xfs_agblock_t		rextsize)
{
	struct xfs_mount	*nmp;

	nmp = kmemdup(mp, sizeof(*mp), GFP_KERNEL);
	if (!nmp)
		return NULL;
	xfs_mount_sb_set_rextsize(nmp, &nmp->m_sb, rextsize);
	nmp->m_sb.sb_rblocks = rblocks;
	nmp->m_sb.sb_rextents = xfs_blen_to_rtbxlen(nmp, nmp->m_sb.sb_rblocks);
	nmp->m_sb.sb_rbmblocks = xfs_rtbitmap_blockcount(nmp);
	nmp->m_sb.sb_rextslog = xfs_compute_rextslog(nmp->m_sb.sb_rextents);
	if (xfs_has_rtgroups(nmp))
		nmp->m_sb.sb_rgcount = howmany_64(nmp->m_sb.sb_rextents,
						  nmp->m_sb.sb_rgextents);
	else
		nmp->m_sb.sb_rgcount = 1;
	nmp->m_rsumblocks = xfs_rtsummary_blockcount(nmp, &nmp->m_rsumlevels);

	if (rblocks > 0)
		nmp->m_features |= XFS_FEAT_REALTIME;

	/* recompute growfsrt reservation from new rsumsize */
	xfs_trans_resv_calc(nmp, &nmp->m_resv);
	return nmp;
}

/* Free all the new space and return the number of extents actually freed. */
static int
xfs_growfs_rt_free_new(
	struct xfs_rtgroup	*rtg,
	struct xfs_rtalloc_args	*nargs,
	xfs_rtbxlen_t		*freed_rtx)
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	xfs_rgnumber_t		rgno = rtg_rgno(rtg);
	xfs_rtxnum_t		start_rtx = 0, end_rtx;

	if (rgno < mp->m_sb.sb_rgcount)
		start_rtx = xfs_rtgroup_extents(mp, rgno);
	end_rtx = xfs_rtgroup_extents(nargs->mp, rgno);

	/*
	 * Compute the first new extent that we want to free, being careful to
	 * skip past a realtime superblock at the start of the realtime volume.
	 */
	if (xfs_has_rtsb(nargs->mp) && rgno == 0 && start_rtx == 0)
		start_rtx++;
	*freed_rtx = end_rtx - start_rtx;
	return xfs_rtfree_range(nargs, start_rtx, *freed_rtx);
}

static xfs_rfsblock_t
xfs_growfs_rt_nrblocks(
	struct xfs_rtgroup	*rtg,
	xfs_rfsblock_t		nrblocks,
	xfs_agblock_t		rextsize,
	xfs_fileoff_t		bmbno)
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	xfs_rfsblock_t		step;

	step = (bmbno + 1) * mp->m_rtx_per_rbmblock * rextsize;
	if (xfs_has_rtgroups(mp)) {
		xfs_rfsblock_t	rgblocks = mp->m_sb.sb_rgextents * rextsize;

		step = min(rgblocks, step) + rgblocks * rtg_rgno(rtg);
	}

	return min(nrblocks, step);
}

/*
 * If the post-grow filesystem will have an rtsb; we're initializing the first
 * rtgroup; and the filesystem didn't have a realtime section, write the rtsb
 * now, and attach the rtsb buffer to the real mount.
 */
static int
xfs_growfs_rt_init_rtsb(
	const struct xfs_rtalloc_args	*nargs,
	const struct xfs_rtgroup	*rtg,
	const struct xfs_rtalloc_args	*args)
{
	struct xfs_mount		*mp = args->mp;
	struct xfs_buf			*rtsb_bp;
	int				error;

	if (!xfs_has_rtsb(nargs->mp))
		return 0;
	if (rtg_rgno(rtg) > 0)
		return 0;
	if (mp->m_sb.sb_rblocks)
		return 0;

	error = xfs_buf_get_uncached(mp->m_rtdev_targp, XFS_FSB_TO_BB(mp, 1),
			&rtsb_bp);
	if (error)
		return error;

	rtsb_bp->b_maps[0].bm_bn = XFS_RTSB_DADDR;
	rtsb_bp->b_ops = &xfs_rtsb_buf_ops;

	xfs_update_rtsb(rtsb_bp, mp->m_sb_bp);
	mp->m_rtsb_bp = rtsb_bp;
	error = xfs_bwrite(rtsb_bp);
	xfs_buf_unlock(rtsb_bp);
	if (error)
		return error;

	/* Initialize the rtrmap to reflect the rtsb. */
	if (rtg_rmap(args->rtg) != NULL)
		error = xfs_rtrmapbt_init_rtsb(nargs->mp, args->rtg, args->tp);

	return error;
}

static void
xfs_growfs_rt_sb_fields(
	struct xfs_trans	*tp,
	const struct xfs_mount	*nmp)
{
	struct xfs_mount	*mp = tp->t_mountp;

	if (nmp->m_sb.sb_rextsize != mp->m_sb.sb_rextsize)
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSIZE,
			nmp->m_sb.sb_rextsize - mp->m_sb.sb_rextsize);
	if (nmp->m_sb.sb_rbmblocks != mp->m_sb.sb_rbmblocks)
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBMBLOCKS,
			nmp->m_sb.sb_rbmblocks - mp->m_sb.sb_rbmblocks);
	if (nmp->m_sb.sb_rblocks != mp->m_sb.sb_rblocks)
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBLOCKS,
			nmp->m_sb.sb_rblocks - mp->m_sb.sb_rblocks);
	if (nmp->m_sb.sb_rextents != mp->m_sb.sb_rextents)
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTENTS,
			nmp->m_sb.sb_rextents - mp->m_sb.sb_rextents);
	if (nmp->m_sb.sb_rextslog != mp->m_sb.sb_rextslog)
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSLOG,
			nmp->m_sb.sb_rextslog - mp->m_sb.sb_rextslog);
	if (nmp->m_sb.sb_rgcount != mp->m_sb.sb_rgcount)
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_RGCOUNT,
			nmp->m_sb.sb_rgcount - mp->m_sb.sb_rgcount);
}

static int
xfs_growfs_rt_zoned(
	struct xfs_rtgroup	*rtg)
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	struct xfs_mount	*nmp;
	struct xfs_trans	*tp;
	xfs_rtbxlen_t		freed_rtx;
	int			error;

	/*
	 * Calculate new sb and mount fields for this round.  Also ensure the
	 * rtg_extents value is uptodate as the rtbitmap code relies on it.
	 */
	nmp = xfs_growfs_rt_alloc_fake_mount(mp,
			xfs_rtgs_to_rfsbs(mp, rtg_rgno(rtg) + 1),
			mp->m_sb.sb_rextsize);
	if (!nmp)
		return -ENOMEM;
	freed_rtx = nmp->m_sb.sb_rextents - mp->m_sb.sb_rextents;

	xfs_rtgroup_calc_geometry(nmp, rtg, rtg_rgno(rtg),
			nmp->m_sb.sb_rgcount, nmp->m_sb.sb_rextents);

	error = xfs_trans_alloc(mp, &M_RES(nmp)->tr_growrtfree, 0, 0, 0, &tp);
	if (error)
		goto out_free;

	xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
	xfs_rtgroup_trans_join(tp, rtg, XFS_RTGLOCK_RMAP);

	xfs_growfs_rt_sb_fields(tp, nmp);
	xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, freed_rtx);

	error = xfs_trans_commit(tp);
	if (error)
		goto out_free;

	/*
	 * Ensure the mount RT feature flag is now set, and compute new
	 * maxlevels for rt btrees.
	 */
	mp->m_features |= XFS_FEAT_REALTIME;
	xfs_rtrmapbt_compute_maxlevels(mp);
	xfs_rtrefcountbt_compute_maxlevels(mp);

	/*
	 * Finally add the newly added zone to the freelist and add the space
	 * to the available counter.  The order is important here: only add
	 * the available space after the zones, as available space guarantees
	 * that zones to back it are available.
	 */
	xfs_zone_mark_free(rtg);
	xfs_zoned_add_available(mp, freed_rtx);
out_free:
	kfree(nmp);
	return error;
}

static int
xfs_growfs_rt_bmblock(
	struct xfs_rtgroup	*rtg,
	xfs_rfsblock_t		nrblocks,
	xfs_agblock_t		rextsize,
	xfs_fileoff_t		bmbno)
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	struct xfs_inode	*rbmip = rtg_bitmap(rtg);
	struct xfs_inode	*rsumip = rtg_summary(rtg);
	struct xfs_rtalloc_args	args = {
		.mp		= mp,
		.rtg		= rtg,
	};
	struct xfs_rtalloc_args	nargs = {
		.rtg		= rtg,
	};
	struct xfs_mount	*nmp;
	xfs_rtbxlen_t		freed_rtx;
	int			error;

	/*
	 * Calculate new sb and mount fields for this round.  Also ensure the
	 * rtg_extents value is uptodate as the rtbitmap code relies on it.
	 */
	nmp = nargs.mp = xfs_growfs_rt_alloc_fake_mount(mp,
			xfs_growfs_rt_nrblocks(rtg, nrblocks, rextsize, bmbno),
			rextsize);
	if (!nmp)
		return -ENOMEM;

	xfs_rtgroup_calc_geometry(nmp, rtg, rtg_rgno(rtg),
			nmp->m_sb.sb_rgcount, nmp->m_sb.sb_rextents);

	/*
	 * Recompute the growfsrt reservation from the new rsumsize, so that the
	 * transaction below use the new, potentially larger value.
	 * */
	xfs_trans_resv_calc(nmp, &nmp->m_resv);
	error = xfs_trans_alloc(mp, &M_RES(nmp)->tr_growrtfree, 0, 0, 0,
			&args.tp);
	if (error)
		goto out_free;
	nargs.tp = args.tp;

	xfs_rtgroup_lock(args.rtg, XFS_RTGLOCK_BITMAP | XFS_RTGLOCK_RMAP);
	xfs_rtgroup_trans_join(args.tp, args.rtg,
			XFS_RTGLOCK_BITMAP | XFS_RTGLOCK_RMAP);

	/*
	 * Update the bitmap inode's size ondisk and incore.  We need to update
	 * the incore size so that inode inactivation won't punch what it thinks
	 * are "posteof" blocks.
	 */
	rbmip->i_disk_size = nmp->m_sb.sb_rbmblocks * nmp->m_sb.sb_blocksize;
	i_size_write(VFS_I(rbmip), rbmip->i_disk_size);
	xfs_trans_log_inode(args.tp, rbmip, XFS_ILOG_CORE);

	/*
	 * Update the summary inode's size.  We need to update the incore size
	 * so that inode inactivation won't punch what it thinks are "posteof"
	 * blocks.
	 */
	rsumip->i_disk_size = nmp->m_rsumblocks * nmp->m_sb.sb_blocksize;
	i_size_write(VFS_I(rsumip), rsumip->i_disk_size);
	xfs_trans_log_inode(args.tp, rsumip, XFS_ILOG_CORE);

	/*
	 * Copy summary data from old to new sizes when the real size (not
	 * block-aligned) changes.
	 */
	if (mp->m_sb.sb_rbmblocks != nmp->m_sb.sb_rbmblocks ||
	    mp->m_rsumlevels != nmp->m_rsumlevels) {
		error = xfs_rtcopy_summary(&args, &nargs);
		if (error)
			goto out_cancel;
	}

	error = xfs_growfs_rt_init_rtsb(&nargs, rtg, &args);
	if (error)
		goto out_cancel;

	/*
	 * Update superblock fields.
	 */
	xfs_growfs_rt_sb_fields(args.tp, nmp);

	/*
	 * Free the new extent.
	 */
	error = xfs_growfs_rt_free_new(rtg, &nargs, &freed_rtx);
	xfs_rtbuf_cache_relse(&nargs);
	if (error)
		goto out_cancel;

	/*
	 * Mark more blocks free in the superblock.
	 */
	xfs_trans_mod_sb(args.tp, XFS_TRANS_SB_FREXTENTS, freed_rtx);

	/*
	 * Update the calculated values in the real mount structure.
	 */
	mp->m_rsumlevels = nmp->m_rsumlevels;
	mp->m_rsumblocks = nmp->m_rsumblocks;

	/*
	 * Recompute the growfsrt reservation from the new rsumsize.
	 */
	xfs_trans_resv_calc(mp, &mp->m_resv);

	/*
	 * Sync sb counters now to reflect the updated values. Lazy counters are
	 * not always updated and in order to avoid inconsistencies between
	 * frextents and rtextents, it is better to sync the counters.
	 */

	if (xfs_has_lazysbcount(mp))
		xfs_log_sb(args.tp);

	error = xfs_trans_commit(args.tp);
	if (error)
		goto out_free;

	/*
	 * Ensure the mount RT feature flag is now set, and compute new
	 * maxlevels for rt btrees.
	 */
	mp->m_features |= XFS_FEAT_REALTIME;
	xfs_rtrmapbt_compute_maxlevels(mp);
	xfs_rtrefcountbt_compute_maxlevels(mp);

	kfree(nmp);
	return 0;

out_cancel:
	xfs_trans_cancel(args.tp);
out_free:
	kfree(nmp);
	return error;
}

static xfs_rtxnum_t
xfs_last_rtgroup_extents(
	struct xfs_mount	*mp)
{
	return mp->m_sb.sb_rextents -
		((xfs_rtxnum_t)(mp->m_sb.sb_rgcount - 1) *
		 mp->m_sb.sb_rgextents);
}

/*
 * This will return the bitmap block number (indexed at 0) that will be
 * extended/modified. There are 2 cases here:
 * 1. The size of the rtg is such that it is a multiple of
 *    xfs_rtbitmap_rtx_per_rbmblock() i.e, an integral number of bitmap blocks
 *    are completely filled up. In this case, we should return
 *    1 + (the last used bitmap block number).
 * 2. The size of the rtg is not an multiple of xfs_rtbitmap_rtx_per_rbmblock().
 *    Here we will return the block number of last used block number. In this
 *    case, we will modify the last used bitmap block to extend the size of the
 *    rtgroup.
 *
 * This also deals with the case where there were no rtextents before.
 */
static xfs_fileoff_t
xfs_last_rt_bmblock_to_extend(
	struct xfs_rtgroup	*rtg)
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	xfs_rgnumber_t		rgno = rtg_rgno(rtg);
	xfs_fileoff_t		bmbno = 0;
	unsigned int		mod = 0;

	ASSERT(!mp->m_sb.sb_rgcount || rgno >= mp->m_sb.sb_rgcount - 1);

	if (mp->m_sb.sb_rgcount && rgno == mp->m_sb.sb_rgcount - 1) {
		xfs_rtxnum_t	nrext = xfs_last_rtgroup_extents(mp);

		/* Also fill up the previous block if not entirely full. */
		/* We are doing a -1 to convert it to a 0 based index */
		bmbno = xfs_rtbitmap_blockcount_len(mp, nrext) - 1;
		div_u64_rem(nrext, xfs_rtbitmap_rtx_per_rbmblock(mp), &mod);
		/*
		 * mod = 0 means that all the current blocks are full. So
		 * return the next block number to be used for the rtgroup
		 * growth.
		 */
		if (mod == 0)
			bmbno++;
	}

	return bmbno;
}

/*
 * Allocate space to the bitmap and summary files, as necessary.
 */
static int
xfs_growfs_rt_alloc_blocks(
	struct xfs_rtgroup	*rtg,
	xfs_rfsblock_t		nrblocks,
	xfs_agblock_t		rextsize,
	xfs_extlen_t		*nrbmblocks)
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	struct xfs_inode	*rbmip = rtg_bitmap(rtg);
	struct xfs_inode	*rsumip = rtg_summary(rtg);
	xfs_extlen_t		orbmblocks = 0;
	xfs_extlen_t		orsumblocks = 0;
	struct xfs_mount	*nmp;
	int			error = 0;

	nmp = xfs_growfs_rt_alloc_fake_mount(mp, nrblocks, rextsize);
	if (!nmp)
		return -ENOMEM;
	*nrbmblocks = nmp->m_sb.sb_rbmblocks;

	if (xfs_has_rtgroups(mp)) {
		/*
		 * For file systems with the rtgroups feature, the RT bitmap and
		 * summary are always fully allocated, which means that we never
		 * need to grow the existing files.
		 *
		 * But we have to be careful to only fill the bitmap until the
		 * end of the actually used range.
		 */
		if (rtg_rgno(rtg) == nmp->m_sb.sb_rgcount - 1)
			*nrbmblocks = xfs_rtbitmap_blockcount_len(nmp,
					xfs_last_rtgroup_extents(nmp));

		if (mp->m_sb.sb_rgcount &&
		    rtg_rgno(rtg) == mp->m_sb.sb_rgcount - 1)
			goto out_free;
	} else {
		/*
		 * Get the old block counts for bitmap and summary inodes.
		 * These can't change since other growfs callers are locked out.
		 */
		orbmblocks = XFS_B_TO_FSB(mp, rbmip->i_disk_size);
		orsumblocks = XFS_B_TO_FSB(mp, rsumip->i_disk_size);
	}

	error = xfs_rtfile_initialize_blocks(rtg, XFS_RTGI_BITMAP, orbmblocks,
			nmp->m_sb.sb_rbmblocks, NULL);
	if (error)
		goto out_free;
	error = xfs_rtfile_initialize_blocks(rtg, XFS_RTGI_SUMMARY, orsumblocks,
			nmp->m_rsumblocks, NULL);
out_free:
	kfree(nmp);
	return error;
}

static int
xfs_growfs_rtg(
	struct xfs_mount	*mp,
	xfs_rgnumber_t		rgno,
	xfs_rfsblock_t		nrblocks,
	xfs_agblock_t		rextsize)
{
	uint8_t			*old_rsum_cache = NULL;
	xfs_extlen_t		bmblocks;
	xfs_fileoff_t		bmbno;
	struct xfs_rtgroup	*rtg;
	unsigned int		i;
	int			error;

	rtg = xfs_rtgroup_grab(mp, rgno);
	if (!rtg)
		return -EINVAL;

	for (i = 0; i < XFS_RTGI_MAX; i++) {
		error = xfs_rtginode_ensure(rtg, i);
		if (error)
			goto out_rele;
	}

	if (xfs_has_zoned(mp)) {
		error = xfs_growfs_rt_zoned(rtg);
		goto out_rele;
	}

	error = xfs_growfs_rt_alloc_blocks(rtg, nrblocks, rextsize, &bmblocks);
	if (error)
		goto out_rele;

	if (bmblocks != rtg_mount(rtg)->m_sb.sb_rbmblocks) {
		old_rsum_cache = rtg->rtg_rsum_cache;
		error = xfs_alloc_rsum_cache(rtg, bmblocks);
		if (error)
			goto out_rele;
	}

	for (bmbno = xfs_last_rt_bmblock_to_extend(rtg); bmbno < bmblocks;
			bmbno++) {
		error = xfs_growfs_rt_bmblock(rtg, nrblocks, rextsize, bmbno);
		if (error)
			goto out_error;
	}

	kvfree(old_rsum_cache);
	goto out_rele;

out_error:
	/*
	 * Reset rtg_extents to the old value if adding more blocks failed.
	 */
	xfs_rtgroup_calc_geometry(mp, rtg, rtg_rgno(rtg), mp->m_sb.sb_rgcount,
			mp->m_sb.sb_rextents);
	if (old_rsum_cache) {
		kvfree(rtg->rtg_rsum_cache);
		rtg->rtg_rsum_cache = old_rsum_cache;
	}
out_rele:
	xfs_rtgroup_rele(rtg);
	return error;
}

int
xfs_growfs_check_rtgeom(
	const struct xfs_mount	*mp,
	xfs_rfsblock_t		dblocks,
	xfs_rfsblock_t		rblocks,
	xfs_extlen_t		rextsize)
{
	xfs_extlen_t		min_logfsbs;
	struct xfs_mount	*nmp;

	nmp = xfs_growfs_rt_alloc_fake_mount(mp, rblocks, rextsize);
	if (!nmp)
		return -ENOMEM;
	nmp->m_sb.sb_dblocks = dblocks;

	xfs_rtrmapbt_compute_maxlevels(nmp);
	xfs_rtrefcountbt_compute_maxlevels(nmp);
	xfs_trans_resv_calc(nmp, M_RES(nmp));

	/*
	 * New summary size can't be more than half the size of the log.  This
	 * prevents us from getting a log overflow, since we'll log basically
	 * the whole summary file at once.
	 */
	min_logfsbs = min_t(xfs_extlen_t, xfs_log_calc_minimum_size(nmp),
			nmp->m_rsumblocks * 2);

	trace_xfs_growfs_check_rtgeom(mp, min_logfsbs);

	if (min_logfsbs > mp->m_sb.sb_logblocks)
		goto out_inval;

	if (xfs_has_zoned(mp)) {
		uint32_t	gblocks = mp->m_groups[XG_TYPE_RTG].blocks;
		uint32_t	rem;

		if (rextsize != 1)
			goto out_inval;
		div_u64_rem(nmp->m_sb.sb_rblocks, gblocks, &rem);
		if (rem) {
			xfs_warn(mp,
"new RT volume size (%lld) not aligned to RT group size (%d)",
				nmp->m_sb.sb_rblocks, gblocks);
			goto out_inval;
		}
	}

	kfree(nmp);
	return 0;
out_inval:
	kfree(nmp);
	return -EINVAL;
}

/*
 * Compute the new number of rt groups and ensure that /rtgroups exists.
 *
 * Changing the rtgroup size is not allowed (even if the rt volume hasn't yet
 * been initialized) because the userspace ABI doesn't support it.
 */
static int
xfs_growfs_rt_prep_groups(
	struct xfs_mount	*mp,
	xfs_rfsblock_t		rblocks,
	xfs_extlen_t		rextsize,
	xfs_rgnumber_t		*new_rgcount)
{
	int			error;

	*new_rgcount = howmany_64(rblocks, mp->m_sb.sb_rgextents * rextsize);
	if (*new_rgcount > XFS_MAX_RGNUMBER)
		return -EINVAL;

	/* Make sure the /rtgroups dir has been created */
	if (!mp->m_rtdirip) {
		struct xfs_trans	*tp;

		tp = xfs_trans_alloc_empty(mp);
		error = xfs_rtginode_load_parent(tp);
		xfs_trans_cancel(tp);

		if (error == -ENOENT)
			error = xfs_rtginode_mkdir_parent(mp);
		if (error)
			return error;
	}

	return 0;
}

static bool
xfs_grow_last_rtg(
	struct xfs_mount	*mp)
{
	if (!xfs_has_rtgroups(mp))
		return true;
	if (mp->m_sb.sb_rgcount == 0)
		return false;
	return xfs_rtgroup_extents(mp, mp->m_sb.sb_rgcount - 1) <
			mp->m_sb.sb_rgextents;
}

/*
 * Read in the last block of the RT device to make sure it is accessible.
 */
static int
xfs_rt_check_size(
	struct xfs_mount	*mp,
	xfs_rfsblock_t		last_block)
{
	xfs_daddr_t		daddr = XFS_FSB_TO_BB(mp, last_block);
	struct xfs_buf		*bp;
	int			error;

	if (XFS_BB_TO_FSB(mp, daddr) != last_block) {
		xfs_warn(mp, "RT device size overflow: %llu != %llu",
			XFS_BB_TO_FSB(mp, daddr), last_block);
		return -EFBIG;
	}

	error = xfs_buf_read_uncached(mp->m_rtdev_targp,
			XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart) + daddr,
			XFS_FSB_TO_BB(mp, 1), &bp, NULL);
	if (error)
		xfs_warn(mp, "cannot read last RT device sector (%lld)",
				last_block);
	else
		xfs_buf_relse(bp);
	return error;
}

/*
 * Grow the realtime area of the filesystem.
 */
int
xfs_growfs_rt(
	struct xfs_mount	*mp,
	struct xfs_growfs_rt	*in)
{
	xfs_rgnumber_t		old_rgcount = mp->m_sb.sb_rgcount;
	xfs_rgnumber_t		new_rgcount = 1;
	xfs_rgnumber_t		rgno;
	xfs_agblock_t		old_rextsize = mp->m_sb.sb_rextsize;
	int			error;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	/* Needs to have been mounted with an rt device. */
	if (!XFS_IS_REALTIME_MOUNT(mp))
		return -EINVAL;

	if (!mutex_trylock(&mp->m_growlock))
		return -EWOULDBLOCK;

	/* Shrink not supported. */
	error = -EINVAL;
	if (in->newblocks <= mp->m_sb.sb_rblocks)
		goto out_unlock;
	/* Can only change rt extent size when adding rt volume. */
	if (mp->m_sb.sb_rblocks > 0 && in->extsize != mp->m_sb.sb_rextsize)
		goto out_unlock;

	/* Range check the extent size. */
	if (XFS_FSB_TO_B(mp, in->extsize) > XFS_MAX_RTEXTSIZE ||
	    XFS_FSB_TO_B(mp, in->extsize) < XFS_MIN_RTEXTSIZE)
		goto out_unlock;

	/* Check for features supported only on rtgroups filesystems. */
	error = -EOPNOTSUPP;
	if (!xfs_has_rtgroups(mp)) {
		if (xfs_has_rmapbt(mp))
			goto out_unlock;
		if (xfs_has_quota(mp))
			goto out_unlock;
		if (xfs_has_reflink(mp))
			goto out_unlock;
	} else if (xfs_has_reflink(mp) &&
		   !xfs_reflink_supports_rextsize(mp, in->extsize))
		goto out_unlock;

	error = xfs_sb_validate_fsb_count(&mp->m_sb, in->newblocks);
	if (error)
		goto out_unlock;

	error = xfs_rt_check_size(mp, in->newblocks - 1);
	if (error)
		goto out_unlock;

	/*
	 * Calculate new parameters.  These are the final values to be reached.
	 */
	error = -EINVAL;
	if (in->newblocks < in->extsize)
		goto out_unlock;

	/* Make sure the new fs size won't cause problems with the log. */
	error = xfs_growfs_check_rtgeom(mp, mp->m_sb.sb_dblocks, in->newblocks,
			in->extsize);
	if (error)
		goto out_unlock;

	if (xfs_has_rtgroups(mp)) {
		error = xfs_growfs_rt_prep_groups(mp, in->newblocks,
				in->extsize, &new_rgcount);
		if (error)
			goto out_unlock;
	}

	if (xfs_grow_last_rtg(mp)) {
		error = xfs_growfs_rtg(mp, old_rgcount - 1, in->newblocks,
				in->extsize);
		if (error)
			goto out_unlock;
	}

	for (rgno = old_rgcount; rgno < new_rgcount; rgno++) {
		xfs_rtbxlen_t	rextents = div_u64(in->newblocks, in->extsize);

		error = xfs_rtgroup_alloc(mp, rgno, new_rgcount, rextents);
		if (error)
			goto out_unlock;

		error = xfs_growfs_rtg(mp, rgno, in->newblocks, in->extsize);
		if (error) {
			struct xfs_rtgroup	*rtg;

			rtg = xfs_rtgroup_grab(mp, rgno);
			if (!WARN_ON_ONCE(!rtg)) {
				xfs_rtunmount_rtg(rtg);
				xfs_rtgroup_rele(rtg);
				xfs_rtgroup_free(mp, rgno);
			}
			break;
		}
	}

	if (!error && old_rextsize != in->extsize)
		error = xfs_growfs_rt_fixup_extsize(mp);

	/*
	 * Update secondary superblocks now the physical grow has completed.
	 *
	 * Also do this in case of an error as we might have already
	 * successfully updated one or more RTGs and incremented sb_rgcount.
	 */
	if (!xfs_is_shutdown(mp)) {
		int error2 = xfs_update_secondary_sbs(mp);

		if (!error)
			error = error2;

		/* Reset the rt metadata btree space reservations. */
		error2 = xfs_metafile_resv_init(mp);
		if (error2 && error2 != -ENOSPC)
			error = error2;
	}

out_unlock:
	mutex_unlock(&mp->m_growlock);
	return error;
}

/* Read the realtime superblock and attach it to the mount. */
int
xfs_rtmount_readsb(
	struct xfs_mount	*mp)
{
	struct xfs_buf		*bp;
	int			error;

	if (!xfs_has_rtsb(mp))
		return 0;
	if (mp->m_sb.sb_rblocks == 0)
		return 0;
	if (mp->m_rtdev_targp == NULL) {
		xfs_warn(mp,
	"Filesystem has a realtime volume, use rtdev=device option");
		return -ENODEV;
	}

	/* m_blkbb_log is not set up yet */
	error = xfs_buf_read_uncached(mp->m_rtdev_targp, XFS_RTSB_DADDR,
			mp->m_sb.sb_blocksize >> BBSHIFT, &bp,
			&xfs_rtsb_buf_ops);
	if (error) {
		xfs_warn(mp, "rt sb validate failed with error %d.", error);
		/* bad CRC means corrupted metadata */
		if (error == -EFSBADCRC)
			error = -EFSCORRUPTED;
		return error;
	}

	mp->m_rtsb_bp = bp;
	xfs_buf_unlock(bp);
	return 0;
}

/* Detach the realtime superblock from the mount and free it. */
void
xfs_rtmount_freesb(
	struct xfs_mount	*mp)
{
	struct xfs_buf		*bp = mp->m_rtsb_bp;

	if (!bp)
		return;

	xfs_buf_lock(bp);
	mp->m_rtsb_bp = NULL;
	xfs_buf_relse(bp);
}

/*
 * Initialize realtime fields in the mount structure.
 */
int				/* error */
xfs_rtmount_init(
	struct xfs_mount	*mp)	/* file system mount structure */
{
	if (mp->m_sb.sb_rblocks == 0)
		return 0;
	if (mp->m_rtdev_targp == NULL) {
		xfs_warn(mp,
	"Filesystem has a realtime volume, use rtdev=device option");
		return -ENODEV;
	}

	mp->m_rsumblocks = xfs_rtsummary_blockcount(mp, &mp->m_rsumlevels);

	return xfs_rt_check_size(mp, mp->m_sb.sb_rblocks - 1);
}

static int
xfs_rtalloc_count_frextent(
	struct xfs_rtgroup		*rtg,
	struct xfs_trans		*tp,
	const struct xfs_rtalloc_rec	*rec,
	void				*priv)
{
	uint64_t			*valp = priv;

	*valp += rec->ar_extcount;
	return 0;
}

/*
 * Reinitialize the number of free realtime extents from the realtime bitmap.
 * Callers must ensure that there is no other activity in the filesystem.
 */
int
xfs_rtalloc_reinit_frextents(
	struct xfs_mount	*mp)
{
	uint64_t		val = 0;
	int			error;

	struct xfs_rtgroup	*rtg = NULL;

	while ((rtg = xfs_rtgroup_next(mp, rtg))) {
		xfs_rtgroup_lock(rtg, XFS_RTGLOCK_BITMAP_SHARED);
		error = xfs_rtalloc_query_all(rtg, NULL,
				xfs_rtalloc_count_frextent, &val);
		xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_BITMAP_SHARED);
		if (error) {
			xfs_rtgroup_rele(rtg);
			return error;
		}
	}

	spin_lock(&mp->m_sb_lock);
	mp->m_sb.sb_frextents = val;
	spin_unlock(&mp->m_sb_lock);
	xfs_set_freecounter(mp, XC_FREE_RTEXTENTS, mp->m_sb.sb_frextents);
	return 0;
}

/*
 * Read in the bmbt of an rt metadata inode so that we never have to load them
 * at runtime.  This enables the use of shared ILOCKs for rtbitmap scans.  Use
 * an empty transaction to avoid deadlocking on loops in the bmbt.
 */
static inline int
xfs_rtmount_iread_extents(
	struct xfs_trans	*tp,
	struct xfs_inode	*ip)
{
	int			error;

	xfs_ilock(ip, XFS_ILOCK_EXCL);

	error = xfs_iread_extents(tp, ip, XFS_DATA_FORK);
	if (error)
		goto out_unlock;

	if (xfs_inode_has_attr_fork(ip)) {
		error = xfs_iread_extents(tp, ip, XFS_ATTR_FORK);
		if (error)
			goto out_unlock;
	}

out_unlock:
	xfs_iunlock(ip, XFS_ILOCK_EXCL);
	return error;
}

static int
xfs_rtmount_rtg(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	struct xfs_rtgroup	*rtg)
{
	int			error, i;

	for (i = 0; i < XFS_RTGI_MAX; i++) {
		error = xfs_rtginode_load(rtg, i, tp);
		if (error)
			return error;

		if (rtg->rtg_inodes[i]) {
			error = xfs_rtmount_iread_extents(tp,
					rtg->rtg_inodes[i]);
			if (error)
				return error;
		}
	}

	if (xfs_has_zoned(mp))
		return 0;
	return xfs_alloc_rsum_cache(rtg, mp->m_sb.sb_rbmblocks);
}

/*
 * Get the bitmap and summary inodes and the summary cache into the mount
 * structure at mount time.
 */
int
xfs_rtmount_inodes(
	struct xfs_mount	*mp)
{
	struct xfs_trans	*tp;
	struct xfs_rtgroup	*rtg = NULL;
	int			error;

	tp = xfs_trans_alloc_empty(mp);
	if (xfs_has_rtgroups(mp) && mp->m_sb.sb_rgcount > 0) {
		error = xfs_rtginode_load_parent(tp);
		if (error)
			goto out_cancel;
	}

	while ((rtg = xfs_rtgroup_next(mp, rtg))) {
		error = xfs_rtmount_rtg(mp, tp, rtg);
		if (error) {
			xfs_rtgroup_rele(rtg);
			xfs_rtunmount_inodes(mp);
			break;
		}
	}

out_cancel:
	xfs_trans_cancel(tp);
	return error;
}

void
xfs_rtunmount_inodes(
	struct xfs_mount	*mp)
{
	struct xfs_rtgroup	*rtg = NULL;

	while ((rtg = xfs_rtgroup_next(mp, rtg)))
		xfs_rtunmount_rtg(rtg);
	xfs_rtginode_irele(&mp->m_rtdirip);
}

/*
 * Pick an extent for allocation at the start of a new realtime file.
 * Use the sequence number stored in the atime field of the bitmap inode.
 * Translate this to a fraction of the rtextents, and return the product
 * of rtextents and the fraction.
 * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ...
 */
static xfs_rtxnum_t
xfs_rtpick_extent(
	struct xfs_rtgroup	*rtg,
	struct xfs_trans	*tp,
	xfs_rtxlen_t		len)		/* allocation length (rtextents) */
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	struct xfs_inode	*rbmip = rtg_bitmap(rtg);
	xfs_rtxnum_t		b = 0;		/* result rtext */
	int			log2;		/* log of sequence number */
	uint64_t		resid;		/* residual after log removed */
	uint64_t		seq;		/* sequence number of file creation */
	struct timespec64	ts;		/* timespec in inode */

	xfs_assert_ilocked(rbmip, XFS_ILOCK_EXCL);

	ts = inode_get_atime(VFS_I(rbmip));
	if (!(rbmip->i_diflags & XFS_DIFLAG_NEWRTBM)) {
		rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
		seq = 0;
	} else {
		seq = ts.tv_sec;
	}
	log2 = xfs_highbit64(seq);
	if (log2 != -1) {
		resid = seq - (1ULL << log2);
		b = (mp->m_sb.sb_rextents * ((resid << 1) + 1ULL)) >>
		    (log2 + 1);
		if (b >= mp->m_sb.sb_rextents)
			div64_u64_rem(b, mp->m_sb.sb_rextents, &b);
		if (b + len > mp->m_sb.sb_rextents)
			b = mp->m_sb.sb_rextents - len;
	}
	ts.tv_sec = seq + 1;
	inode_set_atime_to_ts(VFS_I(rbmip), ts);
	xfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE);
	return b;
}

static void
xfs_rtalloc_align_minmax(
	xfs_rtxlen_t		*raminlen,
	xfs_rtxlen_t		*ramaxlen,
	xfs_rtxlen_t		*prod)
{
	xfs_rtxlen_t		newmaxlen = *ramaxlen;
	xfs_rtxlen_t		newminlen = *raminlen;
	xfs_rtxlen_t		slack;

	slack = newmaxlen % *prod;
	if (slack)
		newmaxlen -= slack;
	slack = newminlen % *prod;
	if (slack)
		newminlen += *prod - slack;

	/*
	 * If adjusting for extent size hint alignment produces an invalid
	 * min/max len combination, go ahead without it.
	 */
	if (newmaxlen < newminlen) {
		*prod = 1;
		return;
	}
	*ramaxlen = newmaxlen;
	*raminlen = newminlen;
}

/* Given a free extent, find any part of it that isn't busy, if possible. */
STATIC bool
xfs_rtalloc_check_busy(
	struct xfs_rtalloc_args	*args,
	xfs_rtxnum_t		start,
	xfs_rtxlen_t		minlen_rtx,
	xfs_rtxlen_t		maxlen_rtx,
	xfs_rtxlen_t		len_rtx,
	xfs_rtxlen_t		prod,
	xfs_rtxnum_t		rtx,
	xfs_rtxlen_t		*reslen,
	xfs_rtxnum_t		*resrtx,
	unsigned		*busy_gen)
{
	struct xfs_rtgroup	*rtg = args->rtg;
	struct xfs_mount	*mp = rtg_mount(rtg);
	xfs_agblock_t		rgbno = xfs_rtx_to_rgbno(rtg, rtx);
	xfs_rgblock_t		min_rgbno = xfs_rtx_to_rgbno(rtg, start);
	xfs_extlen_t		minlen = xfs_rtxlen_to_extlen(mp, minlen_rtx);
	xfs_extlen_t		len = xfs_rtxlen_to_extlen(mp, len_rtx);
	xfs_extlen_t		diff;
	bool			busy;

	busy = xfs_extent_busy_trim(rtg_group(rtg), minlen,
			xfs_rtxlen_to_extlen(mp, maxlen_rtx), &rgbno, &len,
			busy_gen);

	/*
	 * If we have a largish extent that happens to start before min_rgbno,
	 * see if we can shift it into range...
	 */
	if (rgbno < min_rgbno && rgbno + len > min_rgbno) {
		diff = min_rgbno - rgbno;
		if (len > diff) {
			rgbno += diff;
			len -= diff;
		}
	}

	if (prod > 1 && len >= minlen) {
		xfs_rgblock_t	aligned_rgbno = roundup(rgbno, prod);

		diff = aligned_rgbno - rgbno;

		*resrtx = xfs_rgbno_to_rtx(mp, aligned_rgbno);
		*reslen = xfs_extlen_to_rtxlen(mp,
				diff >= len ? 0 : len - diff);
	} else {
		*resrtx = xfs_rgbno_to_rtx(mp, rgbno);
		*reslen = xfs_extlen_to_rtxlen(mp, len);
	}

	return busy;
}

/*
 * Adjust the given free extent so that it isn't busy, or flush the log and
 * wait for the space to become unbusy.  Only needed for rtgroups.
 */
STATIC int
xfs_rtallocate_adjust_for_busy(
	struct xfs_rtalloc_args	*args,
	xfs_rtxnum_t		start,
	xfs_rtxlen_t		minlen,
	xfs_rtxlen_t		maxlen,
	xfs_rtxlen_t		*len,
	xfs_rtxlen_t		prod,
	xfs_rtxnum_t		*rtx)
{
	xfs_rtxnum_t		resrtx;
	xfs_rtxlen_t		reslen;
	unsigned		busy_gen;
	bool			busy;
	int			error;

again:
	busy = xfs_rtalloc_check_busy(args, start, minlen, maxlen, *len, prod,
			*rtx, &reslen, &resrtx, &busy_gen);
	if (!busy)
		return 0;

	if (reslen < minlen || (start != 0 && resrtx != *rtx)) {
		/*
		 * Enough of the extent was busy that we cannot satisfy the
		 * allocation, or this is a near allocation and the start of
		 * the extent is busy.  Flush the log and wait for the busy
		 * situation to resolve.
		 */
		trace_xfs_rtalloc_extent_busy(args->rtg, start, minlen, maxlen,
				*len, prod, *rtx, busy_gen);

		error = xfs_extent_busy_flush(args->tp, rtg_group(args->rtg),
				busy_gen, 0);
		if (error)
			return error;

		goto again;
	}

	/* Some of the free space wasn't busy, hand that back to the caller. */
	trace_xfs_rtalloc_extent_busy_trim(args->rtg, *rtx, *len, resrtx,
			reslen);
	*len = reslen;
	*rtx = resrtx;

	return 0;
}

static int
xfs_rtallocate_rtg(
	struct xfs_trans	*tp,
	xfs_rgnumber_t		rgno,
	xfs_rtblock_t		bno_hint,
	xfs_rtxlen_t		minlen,
	xfs_rtxlen_t		maxlen,
	xfs_rtxlen_t		prod,
	bool			wasdel,
	bool			initial_user_data,
	bool			*rtlocked,
	xfs_rtblock_t		*bno,
	xfs_extlen_t		*blen)
{
	struct xfs_rtalloc_args	args = {
		.mp		= tp->t_mountp,
		.tp		= tp,
	};
	xfs_rtxnum_t		start = 0;
	xfs_rtxnum_t		rtx;
	xfs_rtxlen_t		len = 0;
	int			error = 0;

	args.rtg = xfs_rtgroup_grab(args.mp, rgno);
	if (!args.rtg)
		return -ENOSPC;

	/*
	 * We need to lock out modifications to both the RT bitmap and summary
	 * inodes for finding free space in xfs_rtallocate_extent_{near,size}
	 * and join the bitmap and summary inodes for the actual allocation
	 * down in xfs_rtallocate_range.
	 *
	 * For RTG-enabled file system we don't want to join the inodes to the
	 * transaction until we are committed to allocate to allocate from this
	 * RTG so that only one inode of each type is locked at a time.
	 *
	 * But for pre-RTG file systems we need to already to join the bitmap
	 * inode to the transaction for xfs_rtpick_extent, which bumps the
	 * sequence number in it, so we'll have to join the inode to the
	 * transaction early here.
	 *
	 * This is all a bit messy, but at least the mess is contained in
	 * this function.
	 */
	if (!*rtlocked) {
		xfs_rtgroup_lock(args.rtg, XFS_RTGLOCK_BITMAP);
		if (!xfs_has_rtgroups(args.mp))
			xfs_rtgroup_trans_join(tp, args.rtg,
					XFS_RTGLOCK_BITMAP);
		*rtlocked = true;
	}

	/*
	 * For an allocation to an empty file at offset 0, pick an extent that
	 * will space things out in the rt area.
	 */
	if (bno_hint != NULLFSBLOCK)
		start = xfs_rtb_to_rtx(args.mp, bno_hint);
	else if (!xfs_has_rtgroups(args.mp) && initial_user_data)
		start = xfs_rtpick_extent(args.rtg, tp, maxlen);

	if (start) {
		error = xfs_rtallocate_extent_near(&args, start, minlen, maxlen,
				&len, prod, &rtx);
		/*
		 * If we can't allocate near a specific rt extent, try again
		 * without locality criteria.
		 */
		if (error == -ENOSPC) {
			xfs_rtbuf_cache_relse(&args);
			error = 0;
		}
	}

	if (!error) {
		error = xfs_rtallocate_extent_size(&args, minlen, maxlen, &len,
				prod, &rtx);
	}

	if (error) {
		if (xfs_has_rtgroups(args.mp))
			goto out_unlock;
		goto out_release;
	}

	if (xfs_has_rtgroups(args.mp)) {
		error = xfs_rtallocate_adjust_for_busy(&args, start, minlen,
				maxlen, &len, prod, &rtx);
		if (error)
			goto out_unlock;

		xfs_rtgroup_trans_join(tp, args.rtg, XFS_RTGLOCK_BITMAP);
	}

	error = xfs_rtallocate_range(&args, rtx, len);
	if (error)
		goto out_release;

	xfs_trans_mod_sb(tp, wasdel ?
			XFS_TRANS_SB_RES_FREXTENTS : XFS_TRANS_SB_FREXTENTS,
			-(long)len);
	*bno = xfs_rtx_to_rtb(args.rtg, rtx);
	*blen = xfs_rtxlen_to_extlen(args.mp, len);

out_release:
	xfs_rtgroup_rele(args.rtg);
	xfs_rtbuf_cache_relse(&args);
	return error;
out_unlock:
	xfs_rtgroup_unlock(args.rtg, XFS_RTGLOCK_BITMAP);
	*rtlocked = false;
	goto out_release;
}

int
xfs_rtallocate_rtgs(
	struct xfs_trans	*tp,
	xfs_fsblock_t		bno_hint,
	xfs_rtxlen_t		minlen,
	xfs_rtxlen_t		maxlen,
	xfs_rtxlen_t		prod,
	bool			wasdel,
	bool			initial_user_data,
	xfs_rtblock_t		*bno,
	xfs_extlen_t		*blen)
{
	struct xfs_mount	*mp = tp->t_mountp;
	xfs_rgnumber_t		start_rgno, rgno;
	int			error;

	/*
	 * For now this just blindly iterates over the RTGs for an initial
	 * allocation.  We could try to keep an in-memory rtg_longest member
	 * to avoid the locking when just looking for big enough free space,
	 * but for now this keeps things simple.
	 */
	if (bno_hint != NULLFSBLOCK)
		start_rgno = xfs_rtb_to_rgno(mp, bno_hint);
	else
		start_rgno = (atomic_inc_return(&mp->m_rtgrotor) - 1) %
				mp->m_sb.sb_rgcount;

	rgno = start_rgno;
	do {
		bool		rtlocked = false;

		error = xfs_rtallocate_rtg(tp, rgno, bno_hint, minlen, maxlen,
				prod, wasdel, initial_user_data, &rtlocked,
				bno, blen);
		if (error != -ENOSPC)
			return error;
		ASSERT(!rtlocked);

		if (++rgno == mp->m_sb.sb_rgcount)
			rgno = 0;
		bno_hint = NULLFSBLOCK;
	} while (rgno != start_rgno);

	return -ENOSPC;
}

static int
xfs_rtallocate_align(
	struct xfs_bmalloca	*ap,
	xfs_rtxlen_t		*ralen,
	xfs_rtxlen_t		*raminlen,
	xfs_rtxlen_t		*prod,
	bool			*noalign)
{
	struct xfs_mount	*mp = ap->ip->i_mount;
	xfs_fileoff_t		orig_offset = ap->offset;
	xfs_extlen_t		minlen = mp->m_sb.sb_rextsize;
	xfs_extlen_t            align;	/* minimum allocation alignment */
	xfs_extlen_t		mod;	/* product factor for allocators */
	int			error;

	if (*noalign) {
		align = mp->m_sb.sb_rextsize;
	} else {
		if (ap->flags & XFS_BMAPI_COWFORK)
			align = xfs_get_cowextsz_hint(ap->ip);
		else
			align = xfs_get_extsz_hint(ap->ip);
		if (!align)
			align = 1;
		if (align == mp->m_sb.sb_rextsize)
			*noalign = true;
	}

	error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, align, 1,
			ap->eof, 0, ap->conv, &ap->offset, &ap->length);
	if (error)
		return error;
	ASSERT(ap->length);
	ASSERT(xfs_extlen_to_rtxmod(mp, ap->length) == 0);

	/*
	 * If we shifted the file offset downward to satisfy an extent size
	 * hint, increase minlen by that amount so that the allocator won't
	 * give us an allocation that's too short to cover at least one of the
	 * blocks that the caller asked for.
	 */
	if (ap->offset != orig_offset)
		minlen += orig_offset - ap->offset;

	/*
	 * Set ralen to be the actual requested length in rtextents.
	 *
	 * If the old value was close enough to XFS_BMBT_MAX_EXTLEN that
	 * we rounded up to it, cut it back so it's valid again.
	 * Note that if it's a really large request (bigger than
	 * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't
	 * adjust the starting point to match it.
	 */
	*ralen = xfs_extlen_to_rtxlen(mp, min(ap->length, XFS_MAX_BMBT_EXTLEN));
	*raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen));
	ASSERT(*raminlen > 0);
	ASSERT(*raminlen <= *ralen);

	/*
	 * Only bother calculating a real prod factor if offset & length are
	 * perfectly aligned, otherwise it will just get us in trouble.
	 */
	div_u64_rem(ap->offset, align, &mod);
	if (mod || ap->length % align)
		*prod = 1;
	else
		*prod = xfs_extlen_to_rtxlen(mp, align);

	if (*prod > 1)
		xfs_rtalloc_align_minmax(raminlen, ralen, prod);
	return 0;
}

int
xfs_bmap_rtalloc(
	struct xfs_bmalloca	*ap)
{
	xfs_fileoff_t		orig_offset = ap->offset;
	xfs_rtxlen_t		prod = 0;  /* product factor for allocators */
	xfs_rtxlen_t		ralen = 0; /* realtime allocation length */
	xfs_rtblock_t		bno_hint = NULLRTBLOCK;
	xfs_extlen_t		orig_length = ap->length;
	xfs_rtxlen_t		raminlen;
	bool			rtlocked = false;
	bool			noalign = false;
	bool			initial_user_data =
		ap->datatype & XFS_ALLOC_INITIAL_USER_DATA;
	int			error;

	ASSERT(!xfs_has_zoned(ap->tp->t_mountp));

retry:
	error = xfs_rtallocate_align(ap, &ralen, &raminlen, &prod, &noalign);
	if (error)
		return error;

	if (xfs_bmap_adjacent(ap))
		bno_hint = ap->blkno;

	if (xfs_has_rtgroups(ap->ip->i_mount)) {
		error = xfs_rtallocate_rtgs(ap->tp, bno_hint, raminlen, ralen,
				prod, ap->wasdel, initial_user_data,
				&ap->blkno, &ap->length);
	} else {
		error = xfs_rtallocate_rtg(ap->tp, 0, bno_hint, raminlen, ralen,
				prod, ap->wasdel, initial_user_data,
				&rtlocked, &ap->blkno, &ap->length);
	}

	if (error == -ENOSPC) {
		if (!noalign) {
			/*
			 * We previously enlarged the request length to try to
			 * satisfy an extent size hint.  The allocator didn't
			 * return anything, so reset the parameters to the
			 * original values and try again without alignment
			 * criteria.
			 */
			ap->offset = orig_offset;
			ap->length = orig_length;
			noalign = true;
			goto retry;
		}

		ap->blkno = NULLFSBLOCK;
		ap->length = 0;
		return 0;
	}
	if (error)
		return error;

	xfs_bmap_alloc_account(ap);
	return 0;
}
