// 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)
		__releases(&mp->m_zone_info->zi_open_zones_lock)
		__acquires(&mp->m_zone_info->zi_open_zones_lock)
{
	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)
		goto out_unlock;

	/*
	 * GC only steals open zones at mount time, so no GC zones should end up
	 * in the cache.
	 */
	ASSERT(!oz->oz_is_gc);

	/*
	 * Drop the old cached open zone if it is full.
	 */
	if (oz->oz_allocated == rtg_blocks(oz->oz_rtg)) {
		spin_lock(&ip->i_flags_lock);
		oz = VFS_I(ip)->i_private;
		if (oz && oz->oz_allocated == rtg_blocks(oz->oz_rtg)) {
			VFS_I(ip)->i_private = NULL;
			spin_unlock(&ip->i_flags_lock);
			xfs_open_zone_put(oz);
			oz = NULL;
			goto out_unlock;
		}
		spin_unlock(&ip->i_flags_lock);
	}

	if (oz && !atomic_inc_not_zero(&oz->oz_ref))
		oz = NULL;
out_unlock:
	rcu_read_unlock();
	return oz;
}

/*
 * Stash our zone in the inode so that it 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.
 *
 * Called with a reference on @oz held.  And returns two references on the
 * returned zone: one for the caller and one for pinning the zone in
 * inode->i_private.
 */
static struct xfs_open_zone *
xfs_set_cached_zone(
	struct xfs_inode	*ip,
	struct xfs_open_zone	*oz)
{
	struct xfs_open_zone	*old_oz;

	/*
	 * If the open zone cached in the inode still has free space, use that
	 * instead of the new open zone just selected.  This can happen when
	 * multiple threads race to perform zone selection for an inode.
	 * io_uring worker threads seem to be good way to trigger this.
	 *
	 * We need to grab an extra reference to this open zone as the caller
	 * owns a reference in addition to the i_private pointer.
	 */
	spin_lock(&ip->i_flags_lock);
	old_oz = VFS_I(ip)->i_private;
	if (old_oz && old_oz->oz_allocated < rtg_blocks(old_oz->oz_rtg) &&
	    atomic_inc_not_zero(&old_oz->oz_ref)) {
		spin_unlock(&ip->i_flags_lock);
		xfs_open_zone_put(oz);
		return old_oz;
	}
	VFS_I(ip)->i_private = oz;
	atomic_inc(&oz->oz_ref);
	spin_unlock(&ip->i_flags_lock);
	if (old_oz)
		xfs_open_zone_put(old_oz);
	return 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)
select_zone:
		*oz = xfs_get_cached_zone(ip);
	if (!*oz) {
		*oz = xfs_select_zone(mp, write_hint, pack_tight);
		if (!*oz)
			goto out_error;
		*oz = 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);
}
