// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2018-2023 Oracle.  All Rights Reserved.
 * Author: Darrick J. Wong <djwong@kernel.org>
 */
#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_shared.h"
#include "xfs_bit.h"
#include "xfs_format.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
#include "xfs_btree.h"
#include "scrub/scrub.h"
#include "scrub/bitmap.h"

#include <linux/interval_tree_generic.h>

/* u64 bitmap */

struct xbitmap64_node {
	struct rb_node	bn_rbnode;

	/* First set bit of this interval and subtree. */
	uint64_t	bn_start;

	/* Last set bit of this interval. */
	uint64_t	bn_last;

	/* Last set bit of this subtree.  Do not touch this. */
	uint64_t	__bn_subtree_last;
};

/* Define our own interval tree type with uint64_t parameters. */

#define START(node) ((node)->bn_start)
#define LAST(node)  ((node)->bn_last)

/*
 * These functions are defined by the INTERVAL_TREE_DEFINE macro, but we'll
 * forward-declare them anyway for clarity.
 */
static inline __maybe_unused void
xbitmap64_tree_insert(struct xbitmap64_node *node, struct rb_root_cached *root);

static inline __maybe_unused void
xbitmap64_tree_remove(struct xbitmap64_node *node, struct rb_root_cached *root);

static inline __maybe_unused struct xbitmap64_node *
xbitmap64_tree_iter_first(struct rb_root_cached *root, uint64_t start,
			uint64_t last);

static inline __maybe_unused struct xbitmap64_node *
xbitmap64_tree_iter_next(struct xbitmap64_node *node, uint64_t start,
		       uint64_t last);

INTERVAL_TREE_DEFINE(struct xbitmap64_node, bn_rbnode, uint64_t,
		__bn_subtree_last, START, LAST, static inline __maybe_unused,
		xbitmap64_tree)

/* Iterate each interval of a bitmap.  Do not change the bitmap. */
#define for_each_xbitmap64_extent(bn, bitmap) \
	for ((bn) = rb_entry_safe(rb_first(&(bitmap)->xb_root.rb_root), \
				   struct xbitmap64_node, bn_rbnode); \
	     (bn) != NULL; \
	     (bn) = rb_entry_safe(rb_next(&(bn)->bn_rbnode), \
				   struct xbitmap64_node, bn_rbnode))

/* Clear a range of this bitmap. */
int
xbitmap64_clear(
	struct xbitmap64	*bitmap,
	uint64_t		start,
	uint64_t		len)
{
	struct xbitmap64_node	*bn;
	struct xbitmap64_node	*new_bn;
	uint64_t		last = start + len - 1;

	while ((bn = xbitmap64_tree_iter_first(&bitmap->xb_root, start, last))) {
		if (bn->bn_start < start && bn->bn_last > last) {
			uint64_t	old_last = bn->bn_last;

			/* overlaps with the entire clearing range */
			xbitmap64_tree_remove(bn, &bitmap->xb_root);
			bn->bn_last = start - 1;
			xbitmap64_tree_insert(bn, &bitmap->xb_root);

			/* add an extent */
			new_bn = kmalloc(sizeof(struct xbitmap64_node),
					XCHK_GFP_FLAGS);
			if (!new_bn)
				return -ENOMEM;
			new_bn->bn_start = last + 1;
			new_bn->bn_last = old_last;
			xbitmap64_tree_insert(new_bn, &bitmap->xb_root);
		} else if (bn->bn_start < start) {
			/* overlaps with the left side of the clearing range */
			xbitmap64_tree_remove(bn, &bitmap->xb_root);
			bn->bn_last = start - 1;
			xbitmap64_tree_insert(bn, &bitmap->xb_root);
		} else if (bn->bn_last > last) {
			/* overlaps with the right side of the clearing range */
			xbitmap64_tree_remove(bn, &bitmap->xb_root);
			bn->bn_start = last + 1;
			xbitmap64_tree_insert(bn, &bitmap->xb_root);
			break;
		} else {
			/* in the middle of the clearing range */
			xbitmap64_tree_remove(bn, &bitmap->xb_root);
			kfree(bn);
		}
	}

	return 0;
}

/* Set a range of this bitmap. */
int
xbitmap64_set(
	struct xbitmap64	*bitmap,
	uint64_t		start,
	uint64_t		len)
{
	struct xbitmap64_node	*left;
	struct xbitmap64_node	*right;
	uint64_t		last = start + len - 1;
	int			error;

	/* Is this whole range already set? */
	left = xbitmap64_tree_iter_first(&bitmap->xb_root, start, last);
	if (left && left->bn_start <= start && left->bn_last >= last)
		return 0;

	/* Clear out everything in the range we want to set. */
	error = xbitmap64_clear(bitmap, start, len);
	if (error)
		return error;

	/* Do we have a left-adjacent extent? */
	left = xbitmap64_tree_iter_first(&bitmap->xb_root, start - 1, start - 1);
	ASSERT(!left || left->bn_last + 1 == start);

	/* Do we have a right-adjacent extent? */
	right = xbitmap64_tree_iter_first(&bitmap->xb_root, last + 1, last + 1);
	ASSERT(!right || right->bn_start == last + 1);

	if (left && right) {
		/* combine left and right adjacent extent */
		xbitmap64_tree_remove(left, &bitmap->xb_root);
		xbitmap64_tree_remove(right, &bitmap->xb_root);
		left->bn_last = right->bn_last;
		xbitmap64_tree_insert(left, &bitmap->xb_root);
		kfree(right);
	} else if (left) {
		/* combine with left extent */
		xbitmap64_tree_remove(left, &bitmap->xb_root);
		left->bn_last = last;
		xbitmap64_tree_insert(left, &bitmap->xb_root);
	} else if (right) {
		/* combine with right extent */
		xbitmap64_tree_remove(right, &bitmap->xb_root);
		right->bn_start = start;
		xbitmap64_tree_insert(right, &bitmap->xb_root);
	} else {
		/* add an extent */
		left = kmalloc(sizeof(struct xbitmap64_node), XCHK_GFP_FLAGS);
		if (!left)
			return -ENOMEM;
		left->bn_start = start;
		left->bn_last = last;
		xbitmap64_tree_insert(left, &bitmap->xb_root);
	}

	return 0;
}

/* Free everything related to this bitmap. */
void
xbitmap64_destroy(
	struct xbitmap64	*bitmap)
{
	struct xbitmap64_node	*bn;

	while ((bn = xbitmap64_tree_iter_first(&bitmap->xb_root, 0, -1ULL))) {
		xbitmap64_tree_remove(bn, &bitmap->xb_root);
		kfree(bn);
	}
}

/* Set up a per-AG block bitmap. */
void
xbitmap64_init(
	struct xbitmap64	*bitmap)
{
	bitmap->xb_root = RB_ROOT_CACHED;
}

/*
 * Remove all the blocks mentioned in @sub from the extents in @bitmap.
 *
 * The intent is that callers will iterate the rmapbt for all of its records
 * for a given owner to generate @bitmap; and iterate all the blocks of the
 * metadata structures that are not being rebuilt and have the same rmapbt
 * owner to generate @sub.  This routine subtracts all the extents
 * mentioned in sub from all the extents linked in @bitmap, which leaves
 * @bitmap as the list of blocks that are not accounted for, which we assume
 * are the dead blocks of the old metadata structure.  The blocks mentioned in
 * @bitmap can be reaped.
 *
 * This is the logical equivalent of bitmap &= ~sub.
 */
int
xbitmap64_disunion(
	struct xbitmap64	*bitmap,
	struct xbitmap64	*sub)
{
	struct xbitmap64_node	*bn;
	int			error;

	if (xbitmap64_empty(bitmap) || xbitmap64_empty(sub))
		return 0;

	for_each_xbitmap64_extent(bn, sub) {
		error = xbitmap64_clear(bitmap, bn->bn_start,
				bn->bn_last - bn->bn_start + 1);
		if (error)
			return error;
	}

	return 0;
}

/* How many bits are set in this bitmap? */
uint64_t
xbitmap64_hweight(
	struct xbitmap64	*bitmap)
{
	struct xbitmap64_node	*bn;
	uint64_t		ret = 0;

	for_each_xbitmap64_extent(bn, bitmap)
		ret += bn->bn_last - bn->bn_start + 1;

	return ret;
}

/* Call a function for every run of set bits in this bitmap. */
int
xbitmap64_walk(
	struct xbitmap64	*bitmap,
	xbitmap64_walk_fn		fn,
	void			*priv)
{
	struct xbitmap64_node	*bn;
	int			error = 0;

	for_each_xbitmap64_extent(bn, bitmap) {
		error = fn(bn->bn_start, bn->bn_last - bn->bn_start + 1, priv);
		if (error)
			break;
	}

	return error;
}

/* Does this bitmap have no bits set at all? */
bool
xbitmap64_empty(
	struct xbitmap64	*bitmap)
{
	return bitmap->xb_root.rb_root.rb_node == NULL;
}

/* Is the start of the range set or clear?  And for how long? */
bool
xbitmap64_test(
	struct xbitmap64	*bitmap,
	uint64_t		start,
	uint64_t		*len)
{
	struct xbitmap64_node	*bn;
	uint64_t		last = start + *len - 1;

	bn = xbitmap64_tree_iter_first(&bitmap->xb_root, start, last);
	if (!bn)
		return false;
	if (bn->bn_start <= start) {
		if (bn->bn_last < last)
			*len = bn->bn_last - start + 1;
		return true;
	}
	*len = bn->bn_start - start;
	return false;
}

/* u32 bitmap */

struct xbitmap32_node {
	struct rb_node	bn_rbnode;

	/* First set bit of this interval and subtree. */
	uint32_t	bn_start;

	/* Last set bit of this interval. */
	uint32_t	bn_last;

	/* Last set bit of this subtree.  Do not touch this. */
	uint32_t	__bn_subtree_last;
};

/* Define our own interval tree type with uint32_t parameters. */

/*
 * These functions are defined by the INTERVAL_TREE_DEFINE macro, but we'll
 * forward-declare them anyway for clarity.
 */
static inline __maybe_unused void
xbitmap32_tree_insert(struct xbitmap32_node *node, struct rb_root_cached *root);

static inline __maybe_unused void
xbitmap32_tree_remove(struct xbitmap32_node *node, struct rb_root_cached *root);

static inline __maybe_unused struct xbitmap32_node *
xbitmap32_tree_iter_first(struct rb_root_cached *root, uint32_t start,
			  uint32_t last);

static inline __maybe_unused struct xbitmap32_node *
xbitmap32_tree_iter_next(struct xbitmap32_node *node, uint32_t start,
			 uint32_t last);

INTERVAL_TREE_DEFINE(struct xbitmap32_node, bn_rbnode, uint32_t,
		__bn_subtree_last, START, LAST, static inline __maybe_unused,
		xbitmap32_tree)

/* Iterate each interval of a bitmap.  Do not change the bitmap. */
#define for_each_xbitmap32_extent(bn, bitmap) \
	for ((bn) = rb_entry_safe(rb_first(&(bitmap)->xb_root.rb_root), \
				   struct xbitmap32_node, bn_rbnode); \
	     (bn) != NULL; \
	     (bn) = rb_entry_safe(rb_next(&(bn)->bn_rbnode), \
				   struct xbitmap32_node, bn_rbnode))

/* Clear a range of this bitmap. */
int
xbitmap32_clear(
	struct xbitmap32	*bitmap,
	uint32_t		start,
	uint32_t		len)
{
	struct xbitmap32_node	*bn;
	struct xbitmap32_node	*new_bn;
	uint32_t		last = start + len - 1;

	while ((bn = xbitmap32_tree_iter_first(&bitmap->xb_root, start, last))) {
		if (bn->bn_start < start && bn->bn_last > last) {
			uint32_t	old_last = bn->bn_last;

			/* overlaps with the entire clearing range */
			xbitmap32_tree_remove(bn, &bitmap->xb_root);
			bn->bn_last = start - 1;
			xbitmap32_tree_insert(bn, &bitmap->xb_root);

			/* add an extent */
			new_bn = kmalloc(sizeof(struct xbitmap32_node),
					XCHK_GFP_FLAGS);
			if (!new_bn)
				return -ENOMEM;
			new_bn->bn_start = last + 1;
			new_bn->bn_last = old_last;
			xbitmap32_tree_insert(new_bn, &bitmap->xb_root);
		} else if (bn->bn_start < start) {
			/* overlaps with the left side of the clearing range */
			xbitmap32_tree_remove(bn, &bitmap->xb_root);
			bn->bn_last = start - 1;
			xbitmap32_tree_insert(bn, &bitmap->xb_root);
		} else if (bn->bn_last > last) {
			/* overlaps with the right side of the clearing range */
			xbitmap32_tree_remove(bn, &bitmap->xb_root);
			bn->bn_start = last + 1;
			xbitmap32_tree_insert(bn, &bitmap->xb_root);
			break;
		} else {
			/* in the middle of the clearing range */
			xbitmap32_tree_remove(bn, &bitmap->xb_root);
			kfree(bn);
		}
	}

	return 0;
}

/* Set a range of this bitmap. */
int
xbitmap32_set(
	struct xbitmap32	*bitmap,
	uint32_t		start,
	uint32_t		len)
{
	struct xbitmap32_node	*left;
	struct xbitmap32_node	*right;
	uint32_t		last = start + len - 1;
	int			error;

	/* Is this whole range already set? */
	left = xbitmap32_tree_iter_first(&bitmap->xb_root, start, last);
	if (left && left->bn_start <= start && left->bn_last >= last)
		return 0;

	/* Clear out everything in the range we want to set. */
	error = xbitmap32_clear(bitmap, start, len);
	if (error)
		return error;

	/* Do we have a left-adjacent extent? */
	left = xbitmap32_tree_iter_first(&bitmap->xb_root, start - 1, start - 1);
	ASSERT(!left || left->bn_last + 1 == start);

	/* Do we have a right-adjacent extent? */
	right = xbitmap32_tree_iter_first(&bitmap->xb_root, last + 1, last + 1);
	ASSERT(!right || right->bn_start == last + 1);

	if (left && right) {
		/* combine left and right adjacent extent */
		xbitmap32_tree_remove(left, &bitmap->xb_root);
		xbitmap32_tree_remove(right, &bitmap->xb_root);
		left->bn_last = right->bn_last;
		xbitmap32_tree_insert(left, &bitmap->xb_root);
		kfree(right);
	} else if (left) {
		/* combine with left extent */
		xbitmap32_tree_remove(left, &bitmap->xb_root);
		left->bn_last = last;
		xbitmap32_tree_insert(left, &bitmap->xb_root);
	} else if (right) {
		/* combine with right extent */
		xbitmap32_tree_remove(right, &bitmap->xb_root);
		right->bn_start = start;
		xbitmap32_tree_insert(right, &bitmap->xb_root);
	} else {
		/* add an extent */
		left = kmalloc(sizeof(struct xbitmap32_node), XCHK_GFP_FLAGS);
		if (!left)
			return -ENOMEM;
		left->bn_start = start;
		left->bn_last = last;
		xbitmap32_tree_insert(left, &bitmap->xb_root);
	}

	return 0;
}

/* Free everything related to this bitmap. */
void
xbitmap32_destroy(
	struct xbitmap32	*bitmap)
{
	struct xbitmap32_node	*bn;

	while ((bn = xbitmap32_tree_iter_first(&bitmap->xb_root, 0, -1U))) {
		xbitmap32_tree_remove(bn, &bitmap->xb_root);
		kfree(bn);
	}
}

/* Set up a per-AG block bitmap. */
void
xbitmap32_init(
	struct xbitmap32	*bitmap)
{
	bitmap->xb_root = RB_ROOT_CACHED;
}

/*
 * Remove all the blocks mentioned in @sub from the extents in @bitmap.
 *
 * The intent is that callers will iterate the rmapbt for all of its records
 * for a given owner to generate @bitmap; and iterate all the blocks of the
 * metadata structures that are not being rebuilt and have the same rmapbt
 * owner to generate @sub.  This routine subtracts all the extents
 * mentioned in sub from all the extents linked in @bitmap, which leaves
 * @bitmap as the list of blocks that are not accounted for, which we assume
 * are the dead blocks of the old metadata structure.  The blocks mentioned in
 * @bitmap can be reaped.
 *
 * This is the logical equivalent of bitmap &= ~sub.
 */
int
xbitmap32_disunion(
	struct xbitmap32	*bitmap,
	struct xbitmap32	*sub)
{
	struct xbitmap32_node	*bn;
	int			error;

	if (xbitmap32_empty(bitmap) || xbitmap32_empty(sub))
		return 0;

	for_each_xbitmap32_extent(bn, sub) {
		error = xbitmap32_clear(bitmap, bn->bn_start,
				bn->bn_last - bn->bn_start + 1);
		if (error)
			return error;
	}

	return 0;
}

/* How many bits are set in this bitmap? */
uint32_t
xbitmap32_hweight(
	struct xbitmap32	*bitmap)
{
	struct xbitmap32_node	*bn;
	uint32_t		ret = 0;

	for_each_xbitmap32_extent(bn, bitmap)
		ret += bn->bn_last - bn->bn_start + 1;

	return ret;
}

/* Call a function for every run of set bits in this bitmap. */
int
xbitmap32_walk(
	struct xbitmap32	*bitmap,
	xbitmap32_walk_fn	fn,
	void			*priv)
{
	struct xbitmap32_node	*bn;
	int			error = 0;

	for_each_xbitmap32_extent(bn, bitmap) {
		error = fn(bn->bn_start, bn->bn_last - bn->bn_start + 1, priv);
		if (error)
			break;
	}

	return error;
}

/* Does this bitmap have no bits set at all? */
bool
xbitmap32_empty(
	struct xbitmap32	*bitmap)
{
	return bitmap->xb_root.rb_root.rb_node == NULL;
}

/* Is the start of the range set or clear?  And for how long? */
bool
xbitmap32_test(
	struct xbitmap32	*bitmap,
	uint32_t		start,
	uint32_t		*len)
{
	struct xbitmap32_node	*bn;
	uint32_t		last = start + *len - 1;

	bn = xbitmap32_tree_iter_first(&bitmap->xb_root, start, last);
	if (!bn)
		return false;
	if (bn->bn_start <= start) {
		if (bn->bn_last < last)
			*len = bn->bn_last - start + 1;
		return true;
	}
	*len = bn->bn_start - start;
	return false;
}

/* Count the number of set regions in this bitmap. */
uint32_t
xbitmap32_count_set_regions(
	struct xbitmap32	*bitmap)
{
	struct xbitmap32_node	*bn;
	uint32_t		nr = 0;

	for_each_xbitmap32_extent(bn, bitmap)
		nr++;

	return nr;
}
