// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2023-2025 Christoph Hellwig.
 * Copyright (c) 2024-2025, Western Digital Corporation or its affiliates.
 */
#include "xfs_platform.h"
#include "xfs_shared.h"
#include "xfs_format.h"
#include "xfs_log_format.h"
#include "xfs_error.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
#include "xfs_inode.h"
#include "xfs_iomap.h"
#include "xfs_trans.h"
#include "xfs_alloc.h"
#include "xfs_bmap.h"
#include "xfs_bmap_btree.h"
#include "xfs_trans_space.h"
#include "xfs_refcount.h"
#include "xfs_rtbitmap.h"
#include "xfs_rtrmap_btree.h"
#include "xfs_zone_alloc.h"
#include "xfs_sysfs.h"
#include "xfs_zone_priv.h"
#include "xfs_zones.h"
#include "xfs_trace.h"
#include "xfs_mru_cache.h"

static void
xfs_open_zone_free_rcu(
	struct callback_head	*cb)
{
	struct xfs_open_zone	*oz = container_of(cb, typeof(*oz), oz_rcu);

	xfs_rtgroup_rele(oz->oz_rtg);
	kfree(oz);
}

void
xfs_open_zone_put(
	struct xfs_open_zone	*oz)
{
	if (atomic_dec_and_test(&oz->oz_ref))
		call_rcu(&oz->oz_rcu, xfs_open_zone_free_rcu);
}

static inline uint32_t
xfs_zone_bucket(
	struct xfs_mount	*mp,
	uint32_t		used_blocks)
{
	return XFS_ZONE_USED_BUCKETS * used_blocks /
			mp->m_groups[XG_TYPE_RTG].blocks;
}

static inline void
xfs_zone_add_to_bucket(
	struct xfs_zone_info	*zi,
	xfs_rgnumber_t		rgno,
	uint32_t		to_bucket)
{
	__set_bit(rgno, zi->zi_used_bucket_bitmap[to_bucket]);
	zi->zi_used_bucket_entries[to_bucket]++;
}

static inline void
xfs_zone_remove_from_bucket(
	struct xfs_zone_info	*zi,
	xfs_rgnumber_t		rgno,
	uint32_t		from_bucket)
{
	__clear_bit(rgno, zi->zi_used_bucket_bitmap[from_bucket]);
	zi->zi_used_bucket_entries[from_bucket]--;
}

static void
xfs_zone_account_reclaimable(
	struct xfs_rtgroup	*rtg,
	uint32_t		freed)
{
	struct xfs_group	*xg = rtg_group(rtg);
	struct xfs_mount	*mp = rtg_mount(rtg);
	struct xfs_zone_info	*zi = mp->m_zone_info;
	uint32_t		used = rtg_rmap(rtg)->i_used_blocks;
	xfs_rgnumber_t		rgno = rtg_rgno(rtg);
	uint32_t		from_bucket = xfs_zone_bucket(mp, used + freed);
	uint32_t		to_bucket = xfs_zone_bucket(mp, used);
	bool			was_full = (used + freed == rtg_blocks(rtg));

	/*
	 * This can be called from log recovery, where the zone_info structure
	 * hasn't been allocated yet.  Skip all work as xfs_mount_zones will
	 * add the zones to the right buckets before the file systems becomes
	 * active.
	 */
	if (!zi)
		return;

	if (!used) {
		/*
		 * The zone is now empty, remove it from the bottom bucket and
		 * trigger a reset.
		 */
		trace_xfs_zone_emptied(rtg);

		spin_lock(&zi->zi_used_buckets_lock);
		if (!was_full)
			xfs_zone_remove_from_bucket(zi, rgno, from_bucket);
		spin_unlock(&zi->zi_used_buckets_lock);

		spin_lock(&zi->zi_reset_list_lock);
		xg->xg_next_reset = zi->zi_reset_list;
		zi->zi_reset_list = xg;
		spin_unlock(&zi->zi_reset_list_lock);

		if (zi->zi_gc_thread)
			wake_up_process(zi->zi_gc_thread);
	} else if (was_full) {
		/*
		 * The zone transitioned from full, mark it up as reclaimable
		 * and wake up GC which might be waiting for zones to reclaim.
		 */
		spin_lock(&zi->zi_used_buckets_lock);
		xfs_zone_add_to_bucket(zi, rgno, to_bucket);
		spin_unlock(&zi->zi_used_buckets_lock);

		if (zi->zi_gc_thread && xfs_zoned_need_gc(mp))
			wake_up_process(zi->zi_gc_thread);
	} else if (to_bucket != from_bucket) {
		/*
		 * Move the zone to a new bucket if it dropped below the
		 * threshold.
		 */
		spin_lock(&zi->zi_used_buckets_lock);
		xfs_zone_add_to_bucket(zi, rgno, to_bucket);
		xfs_zone_remove_from_bucket(zi, rgno, from_bucket);
		spin_unlock(&zi->zi_used_buckets_lock);
	}
}

/*
 * Check if we have any zones that can be reclaimed by looking at the entry
 * counters for the zone buckets.
 */
bool
xfs_zoned_have_reclaimable(
	struct xfs_zone_info	*zi)
{
	int i;

	spin_lock(&zi->zi_used_buckets_lock);
	for (i = 0; i < XFS_ZONE_USED_BUCKETS; i++) {
		if (zi->zi_used_bucket_entries[i]) {
			spin_unlock(&zi->zi_used_buckets_lock);
			return true;
		}
	}
	spin_unlock(&zi->zi_used_buckets_lock);

	return false;
}

static void
xfs_open_zone_mark_full(
	struct xfs_open_zone	*oz)
{
	struct xfs_rtgroup	*rtg = oz->oz_rtg;
	struct xfs_mount	*mp = rtg_mount(rtg);
	struct xfs_zone_info	*zi = mp->m_zone_info;
	uint32_t		used = rtg_rmap(rtg)->i_used_blocks;

	trace_xfs_zone_full(rtg);

	WRITE_ONCE(rtg->rtg_open_zone, NULL);

	spin_lock(&zi->zi_open_zones_lock);
	if (oz->oz_is_gc)
		zi->zi_nr_open_gc_zones--;
	else
		zi->zi_nr_open_zones--;
	list_del_init(&oz->oz_entry);
	spin_unlock(&zi->zi_open_zones_lock);

	if (oz->oz_is_gc)
		wake_up_process(zi->zi_gc_thread);
	else
		wake_up_all(&zi->zi_zone_wait);

	if (used < rtg_blocks(rtg))
		xfs_zone_account_reclaimable(rtg, rtg_blocks(rtg) - used);
	xfs_open_zone_put(oz);
}

static inline void
xfs_zone_inc_written(
	struct xfs_open_zone	*oz,
	xfs_filblks_t		len)
{
	xfs_assert_ilocked(rtg_rmap(oz->oz_rtg), XFS_ILOCK_EXCL);

	oz->oz_written += len;
	if (oz->oz_written == rtg_blocks(oz->oz_rtg))
		xfs_open_zone_mark_full(oz);
}

/*
 * Called for blocks that have been written to disk, but not actually linked to
 * an inode, which can happen when garbage collection races with user data
 * writes to a file.
 */
static void
xfs_zone_skip_blocks(
	struct xfs_open_zone	*oz,
	xfs_filblks_t		len)
{
	struct xfs_rtgroup	*rtg = oz->oz_rtg;

	trace_xfs_zone_skip_blocks(oz, 0, len);

	xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
	xfs_zone_inc_written(oz, len);
	xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);

	xfs_add_frextents(rtg_mount(rtg), len);
}

static int
xfs_zoned_map_extent(
	struct xfs_trans	*tp,
	struct xfs_inode	*ip,
	struct xfs_bmbt_irec	*new,
	struct xfs_open_zone	*oz,
	xfs_fsblock_t		old_startblock)
{
	struct xfs_bmbt_irec	data;
	struct xfs_rtgroup	*rtg = oz->oz_rtg;
	struct xfs_inode	*rmapip = rtg_rmap(rtg);
	int			nmaps = 1;
	int			error;

	/* Grab the corresponding mapping in the data fork. */
	error = xfs_bmapi_read(ip, new->br_startoff, new->br_blockcount, &data,
			       &nmaps, 0);
	if (error)
		return error;

	/*
	 * Cap the update to the existing extent in the data fork because we can
	 * only overwrite one extent at a time.
	 */
	ASSERT(new->br_blockcount >= data.br_blockcount);
	new->br_blockcount = data.br_blockcount;

	/*
	 * If a data write raced with this GC write, keep the existing data in
	 * the data fork, mark our newly written GC extent as reclaimable, then
	 * move on to the next extent.
	 *
	 * Note that this can also happen when racing with operations that do
	 * not actually invalidate the data, but just move it to a different
	 * inode (XFS_IOC_EXCHANGE_RANGE), or to a different offset inside the
	 * inode (FALLOC_FL_COLLAPSE_RANGE / FALLOC_FL_INSERT_RANGE).  If the
	 * data was just moved around, GC fails to free the zone, but the zone
	 * becomes a GC candidate again as soon as all previous GC I/O has
	 * finished and these blocks will be moved out eventually.
	 */
	if (old_startblock != NULLFSBLOCK &&
	    old_startblock != data.br_startblock)
		goto skip;

	trace_xfs_reflink_cow_remap_from(ip, new);
	trace_xfs_reflink_cow_remap_to(ip, &data);

	error = xfs_iext_count_extend(tp, ip, XFS_DATA_FORK,
			XFS_IEXT_REFLINK_END_COW_CNT);
	if (error)
		return error;

	if (data.br_startblock != HOLESTARTBLOCK) {
		ASSERT(data.br_startblock != DELAYSTARTBLOCK);
		ASSERT(!isnullstartblock(data.br_startblock));

		xfs_bmap_unmap_extent(tp, ip, XFS_DATA_FORK, &data);
		if (xfs_is_reflink_inode(ip)) {
			xfs_refcount_decrease_extent(tp, true, &data);
		} else {
			error = xfs_free_extent_later(tp, data.br_startblock,
					data.br_blockcount, NULL,
					XFS_AG_RESV_NONE,
					XFS_FREE_EXTENT_REALTIME);
			if (error)
				return error;
		}
	}

	trace_xfs_zone_record_blocks(oz,
		xfs_rtb_to_rgbno(tp->t_mountp, new->br_startblock),
		new->br_blockcount);
	xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
	xfs_rtgroup_trans_join(tp, rtg, XFS_RTGLOCK_RMAP);
	rmapip->i_used_blocks += new->br_blockcount;
	ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg));
	xfs_zone_inc_written(oz, new->br_blockcount);
	xfs_trans_log_inode(tp, rmapip, XFS_ILOG_CORE);

	/* Map the new blocks into the data fork. */
	xfs_bmap_map_extent(tp, ip, XFS_DATA_FORK, new);
	return 0;

skip:
	trace_xfs_reflink_cow_remap_skip(ip, new);
	xfs_zone_skip_blocks(oz, new->br_blockcount);
	return 0;
}

int
xfs_zoned_end_io(
	struct xfs_inode	*ip,
	xfs_off_t		offset,
	xfs_off_t		count,
	xfs_daddr_t		daddr,
	struct xfs_open_zone	*oz,
	xfs_fsblock_t		old_startblock)
{
	struct xfs_mount	*mp = ip->i_mount;
	xfs_fileoff_t		end_fsb = XFS_B_TO_FSB(mp, offset + count);
	struct xfs_bmbt_irec	new = {
		.br_startoff	= XFS_B_TO_FSBT(mp, offset),
		.br_startblock	= xfs_daddr_to_rtb(mp, daddr),
		.br_state	= XFS_EXT_NORM,
	};
	unsigned int		resblks =
		XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
	struct xfs_trans	*tp;
	int			error;

	if (xfs_is_shutdown(mp))
		return -EIO;

	while (new.br_startoff < end_fsb) {
		new.br_blockcount = end_fsb - new.br_startoff;

		error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
				XFS_TRANS_RESERVE | XFS_TRANS_RES_FDBLKS, &tp);
		if (error)
			return error;
		xfs_ilock(ip, XFS_ILOCK_EXCL);
		xfs_trans_ijoin(tp, ip, 0);

		error = xfs_zoned_map_extent(tp, ip, &new, oz, old_startblock);
		if (error)
			xfs_trans_cancel(tp);
		else
			error = xfs_trans_commit(tp);
		xfs_iunlock(ip, XFS_ILOCK_EXCL);
		if (error)
			return error;

		new.br_startoff += new.br_blockcount;
		new.br_startblock += new.br_blockcount;
		if (old_startblock != NULLFSBLOCK)
			old_startblock += new.br_blockcount;
	}

	return 0;
}

/*
 * "Free" blocks allocated in a zone.
 *
 * Just decrement the used blocks counter and report the space as freed.
 */
int
xfs_zone_free_blocks(
	struct xfs_trans	*tp,
	struct xfs_rtgroup	*rtg,
	xfs_fsblock_t		fsbno,
	xfs_filblks_t		len)
{
	struct xfs_mount	*mp = tp->t_mountp;
	struct xfs_inode	*rmapip = rtg_rmap(rtg);

	xfs_assert_ilocked(rmapip, XFS_ILOCK_EXCL);

	if (len > rmapip->i_used_blocks) {
		xfs_err(mp,
"trying to free more blocks (%lld) than used counter (%u).",
			len, rmapip->i_used_blocks);
		ASSERT(len <= rmapip->i_used_blocks);
		xfs_rtginode_mark_sick(rtg, XFS_RTGI_RMAP);
		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
		return -EFSCORRUPTED;
	}

	trace_xfs_zone_free_blocks(rtg, xfs_rtb_to_rgbno(mp, fsbno), len);

	rmapip->i_used_blocks -= len;
	/*
	 * Don't add open zones to the reclaimable buckets.  The I/O completion
	 * for writing the last block will take care of accounting for already
	 * unused blocks instead.
	 */
	if (!READ_ONCE(rtg->rtg_open_zone))
		xfs_zone_account_reclaimable(rtg, len);
	xfs_add_frextents(mp, len);
	xfs_trans_log_inode(tp, rmapip, XFS_ILOG_CORE);
	return 0;
}

static struct xfs_open_zone *
xfs_init_open_zone(
	struct xfs_rtgroup	*rtg,
	xfs_rgblock_t		write_pointer,
	enum rw_hint		write_hint,
	bool			is_gc)
{
	struct xfs_open_zone	*oz;

	oz = kzalloc_obj(*oz, GFP_NOFS | __GFP_NOFAIL);
	spin_lock_init(&oz->oz_alloc_lock);
	atomic_set(&oz->oz_ref, 1);
	oz->oz_rtg = rtg;
	oz->oz_allocated = write_pointer;
	oz->oz_written = write_pointer;
	oz->oz_write_hint = write_hint;
	oz->oz_is_gc = is_gc;

	/*
	 * All dereferences of rtg->rtg_open_zone hold the ILOCK for the rmap
	 * inode, but we don't really want to take that here because we are
	 * under the zone_list_lock.  Ensure the pointer is only set for a fully
	 * initialized open zone structure so that a racy lookup finding it is
	 * fine.
	 */
	WRITE_ONCE(rtg->rtg_open_zone, oz);
	return oz;
}

/*
 * Find a completely free zone, open it, and return a reference.
 */
struct xfs_open_zone *
xfs_open_zone(
	struct xfs_mount	*mp,
	enum rw_hint		write_hint,
	bool			is_gc)
{
	struct xfs_zone_info	*zi = mp->m_zone_info;
	XA_STATE		(xas, &mp->m_groups[XG_TYPE_RTG].xa, 0);
	struct xfs_group	*xg;

	/*
	 * Pick the free zone with lowest index. Zones in the beginning of the
	 * address space typically provides higher bandwidth than those at the
	 * end of the address space on HDDs.
	 */
	xas_lock(&xas);
	xas_for_each_marked(&xas, xg, ULONG_MAX, XFS_RTG_FREE)
		if (atomic_inc_not_zero(&xg->xg_active_ref))
			goto found;
	xas_unlock(&xas);
	return NULL;

found:
	xas_clear_mark(&xas, XFS_RTG_FREE);
	atomic_dec(&zi->zi_nr_free_zones);
	xas_unlock(&xas);

	set_current_state(TASK_RUNNING);
	return xfs_init_open_zone(to_rtg(xg), 0, write_hint, is_gc);
}

static struct xfs_open_zone *
xfs_try_open_zone(
	struct xfs_mount	*mp,
	enum rw_hint		write_hint)
{
	struct xfs_zone_info	*zi = mp->m_zone_info;
	struct xfs_open_zone	*oz;

	if (zi->zi_nr_open_zones >= mp->m_max_open_zones - XFS_OPEN_GC_ZONES)
		return NULL;
	if (atomic_read(&zi->zi_nr_free_zones) <
	    XFS_GC_ZONES - XFS_OPEN_GC_ZONES)
		return NULL;

	/*
	 * Increment the open zone count to reserve our slot before dropping
	 * zi_open_zones_lock.
	 */
	zi->zi_nr_open_zones++;
	spin_unlock(&zi->zi_open_zones_lock);
	oz = xfs_open_zone(mp, write_hint, false);
	spin_lock(&zi->zi_open_zones_lock);
	if (!oz) {
		zi->zi_nr_open_zones--;
		return NULL;
	}

	atomic_inc(&oz->oz_ref);
	list_add_tail(&oz->oz_entry, &zi->zi_open_zones);

	/*
	 * If this was the last free zone, other waiters might be waiting
	 * on us to write to it as well.
	 */
	wake_up_all(&zi->zi_zone_wait);

	if (xfs_zoned_need_gc(mp))
		wake_up_process(zi->zi_gc_thread);

	trace_xfs_zone_opened(oz->oz_rtg);
	return oz;
}

enum xfs_zone_alloc_score {
	/* Any open zone will do it, we're desperate */
	XFS_ZONE_ALLOC_ANY	= 0,

	/* It better fit somehow */
	XFS_ZONE_ALLOC_OK	= 1,

	/* Only reuse a zone if it fits really well. */
	XFS_ZONE_ALLOC_GOOD	= 2,
};

/*
 * Life time hint co-location matrix.  Fields not set default to 0
 * aka XFS_ZONE_ALLOC_ANY.
 */
static const unsigned int
xfs_zoned_hint_score[WRITE_LIFE_HINT_NR][WRITE_LIFE_HINT_NR] = {
	[WRITE_LIFE_NOT_SET]	= {
		[WRITE_LIFE_NOT_SET]	= XFS_ZONE_ALLOC_OK,
	},
	[WRITE_LIFE_NONE]	= {
		[WRITE_LIFE_NONE]	= XFS_ZONE_ALLOC_OK,
	},
	[WRITE_LIFE_SHORT]	= {
		[WRITE_LIFE_SHORT]	= XFS_ZONE_ALLOC_GOOD,
	},
	[WRITE_LIFE_MEDIUM]	= {
		[WRITE_LIFE_MEDIUM]	= XFS_ZONE_ALLOC_GOOD,
	},
	[WRITE_LIFE_LONG]	= {
		[WRITE_LIFE_LONG]	= XFS_ZONE_ALLOC_OK,
		[WRITE_LIFE_EXTREME]	= XFS_ZONE_ALLOC_OK,
	},
	[WRITE_LIFE_EXTREME]	= {
		[WRITE_LIFE_LONG]	= XFS_ZONE_ALLOC_OK,
		[WRITE_LIFE_EXTREME]	= XFS_ZONE_ALLOC_OK,
	},
};

static bool
xfs_try_use_zone(
	struct xfs_zone_info	*zi,
	enum rw_hint		file_hint,
	struct xfs_open_zone	*oz,
	unsigned int		goodness)
{
	if (oz->oz_is_gc)
		return false;

	if (oz->oz_allocated == rtg_blocks(oz->oz_rtg))
		return false;

	if (xfs_zoned_hint_score[oz->oz_write_hint][file_hint] < goodness)
		return false;

	if (!atomic_inc_not_zero(&oz->oz_ref))
		return false;

	/*
	 * If we have a hint set for the data, use that for the zone even if
	 * some data was written already without any hint set, but don't change
	 * the temperature after that as that would make little sense without
	 * tracking per-temperature class written block counts, which is
	 * probably overkill anyway.
	 */
	if (file_hint != WRITE_LIFE_NOT_SET &&
	    oz->oz_write_hint == WRITE_LIFE_NOT_SET)
		oz->oz_write_hint = file_hint;

	/*
	 * If we couldn't match by inode or life time we just pick the first
	 * zone with enough space above.  For that we want the least busy zone
	 * for some definition of "least" busy.  For now this simple LRU
	 * algorithm that rotates every zone to the end of the list will do it,
	 * even if it isn't exactly cache friendly.
	 */
	if (!list_is_last(&oz->oz_entry, &zi->zi_open_zones))
		list_move_tail(&oz->oz_entry, &zi->zi_open_zones);
	return true;
}

static struct xfs_open_zone *
xfs_select_open_zone_lru(
	struct xfs_zone_info	*zi,
	enum rw_hint		file_hint,
	unsigned int		goodness)
{
	struct xfs_open_zone	*oz;

	lockdep_assert_held(&zi->zi_open_zones_lock);

	list_for_each_entry(oz, &zi->zi_open_zones, oz_entry)
		if (xfs_try_use_zone(zi, file_hint, oz, goodness))
			return oz;

	cond_resched_lock(&zi->zi_open_zones_lock);
	return NULL;
}

static struct xfs_open_zone *
xfs_select_open_zone_mru(
	struct xfs_zone_info	*zi,
	enum rw_hint		file_hint)
{
	struct xfs_open_zone	*oz;

	lockdep_assert_held(&zi->zi_open_zones_lock);

	list_for_each_entry_reverse(oz, &zi->zi_open_zones, oz_entry)
		if (xfs_try_use_zone(zi, file_hint, oz, XFS_ZONE_ALLOC_OK))
			return oz;

	cond_resched_lock(&zi->zi_open_zones_lock);
	return NULL;
}

static inline enum rw_hint xfs_inode_write_hint(struct xfs_inode *ip)
{
	if (xfs_has_nolifetime(ip->i_mount))
		return WRITE_LIFE_NOT_SET;
	return VFS_I(ip)->i_write_hint;
}

/*
 * Try to tightly pack small files that are written back after they were closed
 * instead of trying to open new zones for them or spread them to the least
 * recently used zone. This optimizes the data layout for workloads that untar
 * or copy a lot of small files. Right now this does not separate multiple such
 * streams.
 */
static inline bool xfs_zoned_pack_tight(struct xfs_inode *ip)
{
	struct xfs_mount *mp = ip->i_mount;
	size_t zone_capacity =
		XFS_FSB_TO_B(mp, mp->m_groups[XG_TYPE_RTG].blocks);

	/*
	 * Do not pack write files that are already using a full zone to avoid
	 * fragmentation.
	 */
	if (i_size_read(VFS_I(ip)) >= zone_capacity)
		return false;

	return !inode_is_open_for_write(VFS_I(ip)) &&
		!(ip->i_diflags & XFS_DIFLAG_APPEND);
}

static struct xfs_open_zone *
xfs_select_zone_nowait(
	struct xfs_mount	*mp,
	enum rw_hint		write_hint,
	bool			pack_tight)
{
	struct xfs_zone_info	*zi = mp->m_zone_info;
	struct xfs_open_zone	*oz = NULL;

	if (xfs_is_shutdown(mp))
		return NULL;

	/*
	 * Try to fill up open zones with matching temperature if available.  It
	 * is better to try to co-locate data when this is favorable, so we can
	 * activate empty zones when it is statistically better to separate
	 * data.
	 */
	spin_lock(&zi->zi_open_zones_lock);
	oz = xfs_select_open_zone_lru(zi, write_hint, XFS_ZONE_ALLOC_GOOD);
	if (oz)
		goto out_unlock;

	if (pack_tight) {
		oz = xfs_select_open_zone_mru(zi, write_hint);
		if (oz)
			goto out_unlock;
	}

	/*
	 * See if we can open a new zone and use that so that data for different
	 * files is mixed as little as possible.
	 */
	oz = xfs_try_open_zone(mp, write_hint);
	if (oz)
		goto out_unlock;

	/*
	 * Try to find a zone that is an ok match to colocate data with.
	 */
	oz = xfs_select_open_zone_lru(zi, write_hint, XFS_ZONE_ALLOC_OK);
	if (oz)
		goto out_unlock;

	/*
	 * Pick the least recently used zone, regardless of hint match
	 */
	oz = xfs_select_open_zone_lru(zi, write_hint, XFS_ZONE_ALLOC_ANY);
out_unlock:
	spin_unlock(&zi->zi_open_zones_lock);
	return oz;
}

static struct xfs_open_zone *
xfs_select_zone(
	struct xfs_mount	*mp,
	enum rw_hint		write_hint,
	bool			pack_tight)
{
	struct xfs_zone_info	*zi = mp->m_zone_info;
	DEFINE_WAIT		(wait);
	struct xfs_open_zone	*oz;

	oz = xfs_select_zone_nowait(mp, write_hint, pack_tight);
	if (oz)
		return oz;

	for (;;) {
		prepare_to_wait(&zi->zi_zone_wait, &wait, TASK_UNINTERRUPTIBLE);
		oz = xfs_select_zone_nowait(mp, write_hint, pack_tight);
		if (oz || xfs_is_shutdown(mp))
			break;
		schedule();
	}
	finish_wait(&zi->zi_zone_wait, &wait);
	return oz;
}

static unsigned int
xfs_zone_alloc_blocks(
	struct xfs_open_zone	*oz,
	xfs_filblks_t		count_fsb,
	sector_t		*sector,
	bool			*is_seq)
{
	struct xfs_rtgroup	*rtg = oz->oz_rtg;
	struct xfs_mount	*mp = rtg_mount(rtg);
	xfs_rgblock_t		allocated;

	spin_lock(&oz->oz_alloc_lock);
	count_fsb = min3(count_fsb, XFS_MAX_BMBT_EXTLEN,
		(xfs_filblks_t)rtg_blocks(rtg) - oz->oz_allocated);
	if (!count_fsb) {
		spin_unlock(&oz->oz_alloc_lock);
		return 0;
	}
	allocated = oz->oz_allocated;
	oz->oz_allocated += count_fsb;
	spin_unlock(&oz->oz_alloc_lock);

	trace_xfs_zone_alloc_blocks(oz, allocated, count_fsb);

	*sector = xfs_gbno_to_daddr(rtg_group(rtg), 0);
	*is_seq = bdev_zone_is_seq(mp->m_rtdev_targp->bt_bdev, *sector);
	if (!*is_seq)
		*sector += XFS_FSB_TO_BB(mp, allocated);
	return XFS_FSB_TO_B(mp, count_fsb);
}

void
xfs_mark_rtg_boundary(
	struct iomap_ioend	*ioend)
{
	struct xfs_mount	*mp = XFS_I(ioend->io_inode)->i_mount;
	sector_t		sector = ioend->io_bio.bi_iter.bi_sector;

	if (xfs_rtb_to_rgbno(mp, xfs_daddr_to_rtb(mp, sector)) == 0)
		ioend->io_flags |= IOMAP_IOEND_BOUNDARY;
}

/*
 * Check if we have a cached last open zone available for the inode and
 * if yes return a reference to it.
 */
static struct xfs_open_zone *
xfs_get_cached_zone(
	struct xfs_inode	*ip)
{
	struct xfs_open_zone	*oz;

	rcu_read_lock();
	oz = VFS_I(ip)->i_private;
	if (oz) {
		/*
		 * GC only steals open zones at mount time, so no GC zones
		 * should end up in the cache.
		 */
		ASSERT(!oz->oz_is_gc);
		if (!atomic_inc_not_zero(&oz->oz_ref))
			oz = NULL;
	}
	rcu_read_unlock();

	return oz;
}

/*
 * Stash our zone in the inode so that is is reused for future allocations.
 *
 * The open_zone structure will be pinned until either the inode is freed or
 * until the cached open zone is replaced with a different one because the
 * current one was full when we tried to use it.  This means we keep any
 * open zone around forever as long as any inode that used it for the last
 * write is cached, which slightly increases the memory use of cached inodes
 * that were every written to, but significantly simplifies the cached zone
 * lookup.  Because the open_zone is clearly marked as full when all data
 * in the underlying RTG was written, the caching is always safe.
 */
static void
xfs_set_cached_zone(
	struct xfs_inode	*ip,
	struct xfs_open_zone	*oz)
{
	struct xfs_open_zone	*old_oz;

	atomic_inc(&oz->oz_ref);
	old_oz = xchg(&VFS_I(ip)->i_private, oz);
	if (old_oz)
		xfs_open_zone_put(old_oz);
}

static void
xfs_submit_zoned_bio(
	struct iomap_ioend	*ioend,
	struct xfs_open_zone	*oz,
	bool			is_seq)
{
	ioend->io_bio.bi_iter.bi_sector = ioend->io_sector;
	ioend->io_private = oz;
	atomic_inc(&oz->oz_ref); /* for xfs_zoned_end_io */

	if (is_seq) {
		ioend->io_bio.bi_opf &= ~REQ_OP_WRITE;
		ioend->io_bio.bi_opf |= REQ_OP_ZONE_APPEND;
	} else {
		xfs_mark_rtg_boundary(ioend);
	}

	submit_bio(&ioend->io_bio);
}

void
xfs_zone_alloc_and_submit(
	struct iomap_ioend	*ioend,
	struct xfs_open_zone	**oz)
{
	struct xfs_inode	*ip = XFS_I(ioend->io_inode);
	struct xfs_mount	*mp = ip->i_mount;
	enum rw_hint		write_hint = xfs_inode_write_hint(ip);
	bool			pack_tight = xfs_zoned_pack_tight(ip);
	unsigned int		alloc_len;
	struct iomap_ioend	*split;
	bool			is_seq;

	if (xfs_is_shutdown(mp))
		goto out_error;

	/*
	 * If we don't have a locally cached zone in this write context, see if
	 * the inode is still associated with a zone and use that if so.
	 */
	if (!*oz)
		*oz = xfs_get_cached_zone(ip);

	if (!*oz) {
select_zone:
		*oz = xfs_select_zone(mp, write_hint, pack_tight);
		if (!*oz)
			goto out_error;
		xfs_set_cached_zone(ip, *oz);
	}

	alloc_len = xfs_zone_alloc_blocks(*oz, XFS_B_TO_FSB(mp, ioend->io_size),
			&ioend->io_sector, &is_seq);
	if (!alloc_len) {
		xfs_open_zone_put(*oz);
		goto select_zone;
	}

	while ((split = iomap_split_ioend(ioend, alloc_len, is_seq))) {
		if (IS_ERR(split))
			goto out_split_error;
		alloc_len -= split->io_bio.bi_iter.bi_size;
		xfs_submit_zoned_bio(split, *oz, is_seq);
		if (!alloc_len) {
			xfs_open_zone_put(*oz);
			goto select_zone;
		}
	}

	xfs_submit_zoned_bio(ioend, *oz, is_seq);
	return;

out_split_error:
	ioend->io_bio.bi_status = errno_to_blk_status(PTR_ERR(split));
out_error:
	bio_io_error(&ioend->io_bio);
}

/*
 * Wake up all threads waiting for a zoned space allocation when the file system
 * is shut down.
 */
void
xfs_zoned_wake_all(
	struct xfs_mount	*mp)
{
	/*
	 * Don't wake up if there is no m_zone_info.  This is complicated by the
	 * fact that unmount can't atomically clear m_zone_info and thus we need
	 * to check SB_ACTIVE for that, but mount temporarily enables SB_ACTIVE
	 * during log recovery so we can't entirely rely on that either.
	 */
	if ((mp->m_super->s_flags & SB_ACTIVE) && mp->m_zone_info)
		wake_up_all(&mp->m_zone_info->zi_zone_wait);
}

/*
 * Check if @rgbno in @rgb is a potentially valid block.  It might still be
 * unused, but that information is only found in the rmap.
 */
bool
xfs_zone_rgbno_is_valid(
	struct xfs_rtgroup	*rtg,
	xfs_rgnumber_t		rgbno)
{
	lockdep_assert_held(&rtg_rmap(rtg)->i_lock);

	if (rtg->rtg_open_zone)
		return rgbno < rtg->rtg_open_zone->oz_allocated;
	return !xa_get_mark(&rtg_mount(rtg)->m_groups[XG_TYPE_RTG].xa,
			rtg_rgno(rtg), XFS_RTG_FREE);
}

void
xfs_zone_mark_free(
	struct xfs_rtgroup	*rtg)
{
	xfs_group_set_mark(rtg_group(rtg), XFS_RTG_FREE);
	atomic_inc(&rtg_mount(rtg)->m_zone_info->zi_nr_free_zones);
}

static void
xfs_free_open_zones(
	struct xfs_zone_info	*zi)
{
	struct xfs_open_zone	*oz;

	spin_lock(&zi->zi_open_zones_lock);
	while ((oz = list_first_entry_or_null(&zi->zi_open_zones,
			struct xfs_open_zone, oz_entry))) {
		list_del(&oz->oz_entry);
		xfs_open_zone_put(oz);
	}
	spin_unlock(&zi->zi_open_zones_lock);

	/*
	 * Wait for all open zones to be freed so that they drop the group
	 * references:
	 */
	rcu_barrier();
}

struct xfs_init_zones {
	uint32_t		zone_size;
	uint32_t		zone_capacity;
	uint64_t		available;
	uint64_t		reclaimable;
};

/*
 * For sequential write required zones, we restart writing at the hardware write
 * pointer returned by xfs_validate_blk_zone().
 *
 * For conventional zones or conventional devices we have to query the rmap to
 * find the highest recorded block and set the write pointer to the block after
 * that.  In case of a power loss this misses blocks where the data I/O has
 * completed but not recorded in the rmap yet, and it also rewrites blocks if
 * the most recently written ones got deleted again before unmount, but this is
 * the best we can do without hardware support.
 */
static int
xfs_query_write_pointer(
	struct xfs_init_zones	*iz,
	struct xfs_rtgroup	*rtg,
	xfs_rgblock_t		*write_pointer)
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	struct block_device	*bdev = mp->m_rtdev_targp->bt_bdev;
	sector_t		start = xfs_gbno_to_daddr(&rtg->rtg_group, 0);
	xfs_rgblock_t		highest_rgbno;
	struct blk_zone		zone = {};
	int			error;

	if (bdev_is_zoned(bdev)) {
		error = blkdev_get_zone_info(bdev, start, &zone);
		if (error)
			return error;
		if (zone.start != start) {
			xfs_warn(mp, "mismatched zone start: 0x%llx/0x%llx.",
				zone.start, start);
			return -EFSCORRUPTED;
		}

		if (!xfs_validate_blk_zone(mp, &zone, rtg_rgno(rtg),
				iz->zone_size, iz->zone_capacity,
				write_pointer))
			return -EFSCORRUPTED;

		/*
		 * Use the hardware write pointer returned by
		 * xfs_validate_blk_zone for sequential write required zones,
		 * else fall through to the rmap-based estimation below.
		 */
		if (zone.cond != BLK_ZONE_COND_NOT_WP)
			return 0;
	}

	xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
	highest_rgbno = xfs_rtrmap_highest_rgbno(rtg);
	xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);

	if (highest_rgbno == NULLRGBLOCK)
		*write_pointer = 0;
	else
		*write_pointer = highest_rgbno + 1;
	return 0;
}

static int
xfs_init_zone(
	struct xfs_init_zones	*iz,
	struct xfs_rtgroup	*rtg,
	xfs_rgblock_t		write_pointer)
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	struct xfs_zone_info	*zi = mp->m_zone_info;
	uint32_t		used = rtg_rmap(rtg)->i_used_blocks;
	int			error;

	if (write_pointer > rtg->rtg_extents) {
		xfs_warn(mp, "zone %u has invalid write pointer (0x%x).",
			 rtg_rgno(rtg), write_pointer);
		return -EFSCORRUPTED;
	}

	if (used > rtg->rtg_extents) {
		xfs_warn(mp,
"zone %u has used counter (0x%x) larger than zone capacity (0x%llx).",
			 rtg_rgno(rtg), used, rtg->rtg_extents);
		return -EFSCORRUPTED;
	}

	if (used > write_pointer) {
		xfs_warn(mp,
"zone %u has used counter (0x%x) larger than write pointer (0x%x).",
			 rtg_rgno(rtg), used, write_pointer);
		return -EFSCORRUPTED;
	}

	if (write_pointer == 0 && used != 0) {
		xfs_warn(mp, "empty zone %u has non-zero used counter (0x%x).",
			rtg_rgno(rtg), used);
		return -EFSCORRUPTED;
	}

	/*
	 * If there are no used blocks, but the zone is not in empty state yet
	 * we lost power before the zoned reset.  In that case finish the work
	 * here.
	 */
	if (write_pointer == rtg_blocks(rtg) && used == 0) {
		error = xfs_zone_gc_reset_sync(rtg);
		if (error)
			return error;
		write_pointer = 0;
	}

	if (write_pointer == 0) {
		/* zone is empty */
		xfs_zone_mark_free(rtg);
		iz->available += rtg_blocks(rtg);
	} else if (write_pointer < rtg_blocks(rtg)) {
		/* zone is open */
		struct xfs_open_zone *oz;

		atomic_inc(&rtg_group(rtg)->xg_active_ref);
		oz = xfs_init_open_zone(rtg, write_pointer, WRITE_LIFE_NOT_SET,
				false);
		list_add_tail(&oz->oz_entry, &zi->zi_open_zones);
		zi->zi_nr_open_zones++;

		iz->available += (rtg_blocks(rtg) - write_pointer);
		iz->reclaimable += write_pointer - used;
	} else if (used < rtg_blocks(rtg)) {
		/* zone fully written, but has freed blocks */
		xfs_zone_account_reclaimable(rtg, rtg_blocks(rtg) - used);
		iz->reclaimable += (rtg_blocks(rtg) - used);
	}

	return 0;
}

/*
 * Calculate the max open zone limit based on the of number of backing zones
 * available.
 */
static inline uint32_t
xfs_max_open_zones(
	struct xfs_mount	*mp)
{
	unsigned int		max_open, max_open_data_zones;

	/*
	 * We need two zones for every open data zone, one in reserve as we
	 * don't reclaim open zones.  One data zone and its spare is included
	 * in XFS_MIN_ZONES to support at least one user data writer.
	 */
	max_open_data_zones = (mp->m_sb.sb_rgcount - XFS_MIN_ZONES) / 2 + 1;
	max_open = max_open_data_zones + XFS_OPEN_GC_ZONES;

	/*
	 * Cap the max open limit to 1/4 of available space.  Without this we'd
	 * run out of easy reclaim targets too quickly and storage devices don't
	 * handle huge numbers of concurrent write streams overly well.
	 */
	max_open = min(max_open, mp->m_sb.sb_rgcount / 4);

	return max(XFS_MIN_OPEN_ZONES, max_open);
}

/*
 * Normally we use the open zone limit that the device reports.  If there is
 * none let the user pick one from the command line.
 *
 * If the device doesn't report an open zone limit and there is no override,
 * allow to hold about a quarter of the zones open.  In theory we could allow
 * all to be open, but at that point we run into GC deadlocks because we can't
 * reclaim open zones.
 *
 * When used on conventional SSDs a lower open limit is advisable as we'll
 * otherwise overwhelm the FTL just as much as a conventional block allocator.
 *
 * Note: To debug the open zone management code, force max_open to 1 here.
 */
static int
xfs_calc_open_zones(
	struct xfs_mount	*mp)
{
	struct block_device	*bdev = mp->m_rtdev_targp->bt_bdev;
	unsigned int		bdev_open_zones = bdev_max_open_zones(bdev);

	if (!mp->m_max_open_zones) {
		if (bdev_open_zones)
			mp->m_max_open_zones = bdev_open_zones;
		else
			mp->m_max_open_zones = XFS_DEFAULT_MAX_OPEN_ZONES;
	}

	if (mp->m_max_open_zones < XFS_MIN_OPEN_ZONES) {
		xfs_notice(mp, "need at least %u open zones.",
			XFS_MIN_OPEN_ZONES);
		return -EIO;
	}

	if (bdev_open_zones && bdev_open_zones < mp->m_max_open_zones) {
		mp->m_max_open_zones = bdev_open_zones;
		xfs_info(mp, "limiting open zones to %u due to hardware limit.",
			bdev_open_zones);
	}

	if (mp->m_max_open_zones > xfs_max_open_zones(mp)) {
		mp->m_max_open_zones = xfs_max_open_zones(mp);
		xfs_info(mp,
"limiting open zones to %u due to total zone count (%u)",
			mp->m_max_open_zones, mp->m_sb.sb_rgcount);
	}

	return 0;
}

static unsigned long *
xfs_alloc_bucket_bitmap(
	struct xfs_mount	*mp)
{
	return kvmalloc_array(BITS_TO_LONGS(mp->m_sb.sb_rgcount),
			sizeof(unsigned long), GFP_KERNEL | __GFP_ZERO);
}

static struct xfs_zone_info *
xfs_alloc_zone_info(
	struct xfs_mount	*mp)
{
	struct xfs_zone_info	*zi;
	int			i;

	zi = kzalloc_obj(*zi);
	if (!zi)
		return NULL;
	INIT_LIST_HEAD(&zi->zi_open_zones);
	INIT_LIST_HEAD(&zi->zi_reclaim_reservations);
	spin_lock_init(&zi->zi_reset_list_lock);
	spin_lock_init(&zi->zi_open_zones_lock);
	spin_lock_init(&zi->zi_reservation_lock);
	init_waitqueue_head(&zi->zi_zone_wait);
	spin_lock_init(&zi->zi_used_buckets_lock);
	for (i = 0; i < XFS_ZONE_USED_BUCKETS; i++) {
		zi->zi_used_bucket_bitmap[i] = xfs_alloc_bucket_bitmap(mp);
		if (!zi->zi_used_bucket_bitmap[i])
			goto out_free_bitmaps;
	}
	return zi;

out_free_bitmaps:
	while (--i >= 0)
		kvfree(zi->zi_used_bucket_bitmap[i]);
	kfree(zi);
	return NULL;
}

static void
xfs_free_zone_info(
	struct xfs_zone_info	*zi)
{
	int			i;

	xfs_free_open_zones(zi);
	for (i = 0; i < XFS_ZONE_USED_BUCKETS; i++)
		kvfree(zi->zi_used_bucket_bitmap[i]);
	kfree(zi);
}

static int
xfs_report_zones(
	struct xfs_mount	*mp,
	struct xfs_init_zones	*iz)
{
	struct xfs_rtgroup	*rtg = NULL;

	while ((rtg = xfs_rtgroup_next(mp, rtg))) {
		xfs_rgblock_t		write_pointer;
		int			error;

		error = xfs_query_write_pointer(iz, rtg, &write_pointer);
		if (!error)
			error = xfs_init_zone(iz, rtg, write_pointer);
		if (error) {
			xfs_rtgroup_rele(rtg);
			return error;
		}
	}

	return 0;
}

static inline bool
xfs_zone_is_conv(
	struct xfs_rtgroup	*rtg)
{
	return !bdev_zone_is_seq(rtg_mount(rtg)->m_rtdev_targp->bt_bdev,
			xfs_gbno_to_daddr(rtg_group(rtg), 0));
}

static struct xfs_open_zone *
xfs_find_fullest_conventional_open_zone(
	struct xfs_mount	*mp)
{
	struct xfs_zone_info	*zi = mp->m_zone_info;
	struct xfs_open_zone	*found = NULL, *oz;

	spin_lock(&zi->zi_open_zones_lock);
	list_for_each_entry(oz, &zi->zi_open_zones, oz_entry) {
		if (!xfs_zone_is_conv(oz->oz_rtg))
			continue;
		if (!found || oz->oz_allocated > found->oz_allocated)
			found = oz;
	}
	spin_unlock(&zi->zi_open_zones_lock);

	return found;
}

/*
 * Find the fullest conventional zones and remove them from the open zone pool
 * until we are at the open zone limit.
 *
 * We can end up with spurious "open" zones when the last blocks in a fully
 * written zone were invalidate as there is no write pointer for conventional
 * zones.
 *
 * If we are still over the limit when there is no conventional open zone left,
 * the user overrode the max open zones limit using the max_open_zones mount
 * option we should fail.
 */
static int
xfs_finish_spurious_open_zones(
	struct xfs_mount	*mp,
	struct xfs_init_zones	*iz)
{
	struct xfs_zone_info	*zi = mp->m_zone_info;

	while (zi->zi_nr_open_zones > mp->m_max_open_zones) {
		struct xfs_open_zone	*oz;
		xfs_filblks_t		adjust;

		oz = xfs_find_fullest_conventional_open_zone(mp);
		if (!oz) {
			xfs_err(mp,
"too many open zones for max_open_zones limit (%u/%u)",
			zi->zi_nr_open_zones, mp->m_max_open_zones);
			return -EINVAL;
		}

		xfs_rtgroup_lock(oz->oz_rtg, XFS_RTGLOCK_RMAP);
		adjust = rtg_blocks(oz->oz_rtg) - oz->oz_written;
		trace_xfs_zone_spurious_open(oz, oz->oz_written, adjust);
		oz->oz_written = rtg_blocks(oz->oz_rtg);
		xfs_open_zone_mark_full(oz);
		xfs_rtgroup_unlock(oz->oz_rtg, XFS_RTGLOCK_RMAP);
		iz->available -= adjust;
		iz->reclaimable += adjust;
	}

	return 0;
}

int
xfs_mount_zones(
	struct xfs_mount	*mp)
{
	struct xfs_init_zones	iz = {
		.zone_capacity	= mp->m_groups[XG_TYPE_RTG].blocks,
		.zone_size	= xfs_rtgroup_raw_size(mp),
	};
	int			error;

	if (!mp->m_rtdev_targp) {
		xfs_notice(mp, "RT device missing.");
		return -EINVAL;
	}

	if (!xfs_has_rtgroups(mp) || !xfs_has_rmapbt(mp)) {
		xfs_notice(mp, "invalid flag combination.");
		return -EFSCORRUPTED;
	}
	if (mp->m_sb.sb_rextsize != 1) {
		xfs_notice(mp, "zoned file systems do not support rextsize.");
		return -EFSCORRUPTED;
	}
	if (mp->m_sb.sb_rgcount < XFS_MIN_ZONES) {
		xfs_notice(mp,
"zoned file systems need to have at least %u zones.", XFS_MIN_ZONES);
		return -EFSCORRUPTED;
	}

	error = xfs_calc_open_zones(mp);
	if (error)
		return error;

	mp->m_zone_info = xfs_alloc_zone_info(mp);
	if (!mp->m_zone_info)
		return -ENOMEM;

	error = xfs_report_zones(mp, &iz);
	if (error)
		goto out_free_zone_info;

	error = xfs_finish_spurious_open_zones(mp, &iz);
	if (error)
		goto out_free_zone_info;

	xfs_set_freecounter(mp, XC_FREE_RTAVAILABLE, iz.available);
	xfs_set_freecounter(mp, XC_FREE_RTEXTENTS,
			iz.available + iz.reclaimable);

	/*
	 * The writeback code switches between inodes regularly to provide
	 * fairness.  The default lower bound is 4MiB, but for zoned file
	 * systems we want to increase that both to reduce seeks, but also more
	 * importantly so that workloads that writes files in a multiple of the
	 * zone size do not get fragmented and require garbage collection when
	 * they shouldn't.  Increase is to the zone size capped by the max
	 * extent len.
	 *
	 * Note that because s_min_writeback_pages is a superblock field, this
	 * value also get applied to non-zoned files on the data device if
	 * there are any.  On typical zoned setup all data is on the RT device
	 * because using the more efficient sequential write required zones
	 * is the reason for using the zone allocator, and either the RT device
	 * and the (meta)data device are on the same block device, or the
	 * (meta)data device is on a fast SSD while the data on the RT device
	 * is on a SMR HDD.  In any combination of the above cases enforcing
	 * the higher min_writeback_pages for non-RT inodes is either a noop
	 * or beneficial.
	 */
	mp->m_super->s_min_writeback_pages =
		XFS_FSB_TO_B(mp, min(iz.zone_capacity, XFS_MAX_BMBT_EXTLEN)) >>
			PAGE_SHIFT;

	/*
	 * The user may configure GC to free up a percentage of unused blocks.
	 * By default this is 0. GC will always trigger at the minimum level
	 * for keeping max_open_zones available for data placement.
	 */
	mp->m_zonegc_low_space = 0;

	error = xfs_zone_gc_mount(mp);
	if (error)
		goto out_free_zone_info;

	error = xfs_zoned_sysfs_init(mp);
	if (error)
		goto out_zone_gc_unmount;

	xfs_info(mp, "%u zones of %u blocks (%u max open zones)",
		 mp->m_sb.sb_rgcount, iz.zone_capacity, mp->m_max_open_zones);
	trace_xfs_zones_mount(mp);
	return 0;

out_zone_gc_unmount:
	xfs_zone_gc_unmount(mp);
out_free_zone_info:
	xfs_free_zone_info(mp->m_zone_info);
	return error;
}

void
xfs_unmount_zones(
	struct xfs_mount	*mp)
{
	xfs_zoned_sysfs_del(mp);
	xfs_zone_gc_unmount(mp);
	xfs_free_zone_info(mp->m_zone_info);
}
