// SPDX-License-Identifier: GPL-2.0
#include <linux/ceph/ceph_debug.h>

#include <linux/bug.h>
#include <linux/err.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/types.h>

#include <linux/ceph/messenger.h>
#include <linux/ceph/decode.h>

#include "mdsmap.h"
#include "mds_client.h"
#include "super.h"

#define CEPH_MDS_IS_READY(i, ignore_laggy) \
	(m->m_info[i].state > 0 && ignore_laggy ? true : !m->m_info[i].laggy)

static int __mdsmap_get_random_mds(struct ceph_mdsmap *m, bool ignore_laggy)
{
	int n = 0;
	int i, j;

	/* count */
	for (i = 0; i < m->possible_max_rank; i++)
		if (CEPH_MDS_IS_READY(i, ignore_laggy))
			n++;
	if (n == 0)
		return -1;

	/* pick */
	n = get_random_u32_below(n);
	for (j = 0, i = 0; i < m->possible_max_rank; i++) {
		if (CEPH_MDS_IS_READY(i, ignore_laggy))
			j++;
		if (j > n)
			break;
	}

	return i;
}

/*
 * choose a random mds that is "up" (i.e. has a state > 0), or -1.
 */
int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m)
{
	int mds;

	mds = __mdsmap_get_random_mds(m, false);
	if (mds == m->possible_max_rank || mds == -1)
		mds = __mdsmap_get_random_mds(m, true);

	return mds == m->possible_max_rank ? -1 : mds;
}

#define __decode_and_drop_type(p, end, type, bad)		\
	do {							\
		if (*p + sizeof(type) > end)			\
			goto bad;				\
		*p += sizeof(type);				\
	} while (0)

#define __decode_and_drop_set(p, end, type, bad)		\
	do {							\
		u32 n;						\
		size_t need;					\
		ceph_decode_32_safe(p, end, n, bad);		\
		need = sizeof(type) * n;			\
		ceph_decode_need(p, end, need, bad);		\
		*p += need;					\
	} while (0)

#define __decode_and_drop_map(p, end, ktype, vtype, bad)	\
	do {							\
		u32 n;						\
		size_t need;					\
		ceph_decode_32_safe(p, end, n, bad);		\
		need = (sizeof(ktype) + sizeof(vtype)) * n;	\
		ceph_decode_need(p, end, need, bad);		\
		*p += need;					\
	} while (0)


static int __decode_and_drop_compat_set(void **p, void* end)
{
	int i;
	/* compat, ro_compat, incompat*/
	for (i = 0; i < 3; i++) {
		u32 n;
		ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
		/* mask */
		*p += sizeof(u64);
		/* names (map<u64, string>) */
		n = ceph_decode_32(p);
		while (n-- > 0) {
			u32 len;
			ceph_decode_need(p, end, sizeof(u64) + sizeof(u32),
					 bad);
			*p += sizeof(u64);
			len = ceph_decode_32(p);
			ceph_decode_need(p, end, len, bad);
			*p += len;
		}
	}
	return 0;
bad:
	return -1;
}

/*
 * Decode an MDS map
 *
 * Ignore any fields we don't care about (there are quite a few of
 * them).
 */
struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p,
				       void *end, bool msgr2)
{
	struct ceph_client *cl = mdsc->fsc->client;
	struct ceph_mdsmap *m;
	const void *start = *p;
	int i, j, n;
	int err;
	u8 mdsmap_v;
	u16 mdsmap_ev;
	u32 target;

	m = kzalloc_obj(*m, GFP_NOFS);
	if (!m)
		return ERR_PTR(-ENOMEM);

	ceph_decode_need(p, end, 1 + 1, bad);
	mdsmap_v = ceph_decode_8(p);
	*p += sizeof(u8);			/* mdsmap_cv */
	if (mdsmap_v >= 4) {
	       u32 mdsmap_len;
	       ceph_decode_32_safe(p, end, mdsmap_len, bad);
	       if (end < *p + mdsmap_len)
		       goto bad;
	       end = *p + mdsmap_len;
	}

	ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad);
	m->m_epoch = ceph_decode_32(p);
	m->m_client_epoch = ceph_decode_32(p);
	m->m_last_failure = ceph_decode_32(p);
	m->m_root = ceph_decode_32(p);
	m->m_session_timeout = ceph_decode_32(p);
	m->m_session_autoclose = ceph_decode_32(p);
	m->m_max_file_size = ceph_decode_64(p);
	m->m_max_mds = ceph_decode_32(p);

	/*
	 * pick out the active nodes as the m_num_active_mds, the
	 * m_num_active_mds maybe larger than m_max_mds when decreasing
	 * the max_mds in cluster side, in other case it should less
	 * than or equal to m_max_mds.
	 */
	m->m_num_active_mds = n = ceph_decode_32(p);

	/*
	 * the possible max rank, it maybe larger than the m_num_active_mds,
	 * for example if the mds_max == 2 in the cluster, when the MDS(0)
	 * was laggy and being replaced by a new MDS, we will temporarily
	 * receive a new mds map with n_num_mds == 1 and the active MDS(1),
	 * and the mds rank >= m_num_active_mds.
	 */
	m->possible_max_rank = max(m->m_num_active_mds, m->m_max_mds);

	m->m_info = kzalloc_objs(*m->m_info, m->possible_max_rank, GFP_NOFS);
	if (!m->m_info)
		goto nomem;

	/* pick out active nodes from mds_info (state > 0) */
	for (i = 0; i < n; i++) {
		u64 global_id;
		u32 namelen;
		s32 mds, inc, state;
		u8 info_v;
		void *info_end = NULL;
		struct ceph_entity_addr addr;
		u32 num_export_targets;
		void *pexport_targets = NULL;
		struct ceph_timespec laggy_since;
		struct ceph_mds_info *info;
		bool laggy;

		ceph_decode_need(p, end, sizeof(u64) + 1, bad);
		global_id = ceph_decode_64(p);
		info_v= ceph_decode_8(p);
		if (info_v >= 4) {
			u32 info_len;
			ceph_decode_need(p, end, 1 + sizeof(u32), bad);
			*p += sizeof(u8);	/* info_cv */
			info_len = ceph_decode_32(p);
			info_end = *p + info_len;
			if (info_end > end)
				goto bad;
		}

		ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
		*p += sizeof(u64);
		namelen = ceph_decode_32(p);  /* skip mds name */
		*p += namelen;

		ceph_decode_32_safe(p, end, mds, bad);
		ceph_decode_32_safe(p, end, inc, bad);
		ceph_decode_32_safe(p, end, state, bad);
		*p += sizeof(u64);		/* state_seq */
		if (info_v >= 8)
			err = ceph_decode_entity_addrvec(p, end, msgr2, &addr);
		else
			err = ceph_decode_entity_addr(p, end, &addr);
		if (err)
			goto corrupt;

		ceph_decode_copy_safe(p, end, &laggy_since, sizeof(laggy_since),
				      bad);
		laggy = laggy_since.tv_sec != 0 || laggy_since.tv_nsec != 0;
		*p += sizeof(u32);
		ceph_decode_32_safe(p, end, namelen, bad);
		*p += namelen;
		if (info_v >= 2) {
			ceph_decode_32_safe(p, end, num_export_targets, bad);
			pexport_targets = *p;
			*p += num_export_targets * sizeof(u32);
		} else {
			num_export_targets = 0;
		}

		if (info_end && *p != info_end) {
			if (*p > info_end)
				goto bad;
			*p = info_end;
		}

		doutc(cl, "%d/%d %lld mds%d.%d %s %s%s\n", i+1, n, global_id,
		      mds, inc, ceph_pr_addr(&addr),
		      ceph_mds_state_name(state), laggy ? "(laggy)" : "");

		if (mds < 0 || mds >= m->possible_max_rank) {
			pr_warn_client(cl, "got incorrect mds(%d)\n", mds);
			continue;
		}

		if (state <= 0) {
			doutc(cl, "got incorrect state(%s)\n",
			      ceph_mds_state_name(state));
			continue;
		}

		info = &m->m_info[mds];
		info->global_id = global_id;
		info->state = state;
		info->addr = addr;
		info->laggy = laggy;
		info->num_export_targets = num_export_targets;
		if (num_export_targets) {
			info->export_targets = kcalloc(num_export_targets,
						       sizeof(u32), GFP_NOFS);
			if (!info->export_targets)
				goto nomem;
			for (j = 0; j < num_export_targets; j++) {
				target = ceph_decode_32(&pexport_targets);
				info->export_targets[j] = target;
			}
		} else {
			info->export_targets = NULL;
		}
	}

	/* pg_pools */
	ceph_decode_32_safe(p, end, n, bad);
	m->m_num_data_pg_pools = n;
	m->m_data_pg_pools = kcalloc(n, sizeof(u64), GFP_NOFS);
	if (!m->m_data_pg_pools)
		goto nomem;
	ceph_decode_need(p, end, sizeof(u64)*(n+1), bad);
	for (i = 0; i < n; i++)
		m->m_data_pg_pools[i] = ceph_decode_64(p);
	m->m_cas_pg_pool = ceph_decode_64(p);
	m->m_enabled = m->m_epoch > 1;

	mdsmap_ev = 1;
	if (mdsmap_v >= 2) {
		ceph_decode_16_safe(p, end, mdsmap_ev, bad_ext);
	}
	if (mdsmap_ev >= 3) {
		if (__decode_and_drop_compat_set(p, end) < 0)
			goto bad_ext;
	}
	/* metadata_pool */
	if (mdsmap_ev < 5) {
		__decode_and_drop_type(p, end, u32, bad_ext);
	} else {
		__decode_and_drop_type(p, end, u64, bad_ext);
	}

	/* created + modified + tableserver */
	__decode_and_drop_type(p, end, struct ceph_timespec, bad_ext);
	__decode_and_drop_type(p, end, struct ceph_timespec, bad_ext);
	__decode_and_drop_type(p, end, u32, bad_ext);

	/* in */
	{
		int num_laggy = 0;
		ceph_decode_32_safe(p, end, n, bad_ext);
		ceph_decode_need(p, end, sizeof(u32) * n, bad_ext);

		for (i = 0; i < n; i++) {
			s32 mds = ceph_decode_32(p);
			if (mds >= 0 && mds < m->possible_max_rank) {
				if (m->m_info[mds].laggy)
					num_laggy++;
			}
		}
		m->m_num_laggy = num_laggy;

		if (n > m->possible_max_rank) {
			void *new_m_info = krealloc(m->m_info,
						    n * sizeof(*m->m_info),
						    GFP_NOFS | __GFP_ZERO);
			if (!new_m_info)
				goto nomem;
			m->m_info = new_m_info;
		}
		m->possible_max_rank = n;
	}

	/* inc */
	__decode_and_drop_map(p, end, u32, u32, bad_ext);
	/* up */
	__decode_and_drop_map(p, end, u32, u64, bad_ext);
	/* failed */
	__decode_and_drop_set(p, end, u32, bad_ext);
	/* stopped */
	__decode_and_drop_set(p, end, u32, bad_ext);

	if (mdsmap_ev >= 4) {
		/* last_failure_osd_epoch */
		__decode_and_drop_type(p, end, u32, bad_ext);
	}
	if (mdsmap_ev >= 6) {
		/* ever_allowed_snaps */
		__decode_and_drop_type(p, end, u8, bad_ext);
		/* explicitly_allowed_snaps */
		__decode_and_drop_type(p, end, u8, bad_ext);
	}
	if (mdsmap_ev >= 7) {
		/* inline_data_enabled */
		__decode_and_drop_type(p, end, u8, bad_ext);
	}
	if (mdsmap_ev >= 8) {
		size_t fsname_len;

		/* enabled */
		ceph_decode_8_safe(p, end, m->m_enabled, bad_ext);

		/* fs_name */
		m->m_fs_name = ceph_extract_encoded_string(p, end,
							   &fsname_len,
							   GFP_NOFS);
		if (IS_ERR(m->m_fs_name)) {
			m->m_fs_name = NULL;
			goto nomem;
		}

		/* validate fsname against mds_namespace */
		if (!namespace_equals(mdsc->fsc->mount_options, m->m_fs_name,
				      fsname_len)) {
			pr_warn_client(cl, "fsname %s doesn't match mds_namespace %s\n",
				       m->m_fs_name,
				       mdsc->fsc->mount_options->mds_namespace);
			goto bad;
		}
	} else {
		m->m_enabled = false;
		m->m_fs_name = kstrdup(CEPH_OLD_FS_NAME, GFP_NOFS);
		if (!m->m_fs_name)
			goto nomem;
	}
	/* damaged */
	if (mdsmap_ev >= 9) {
		size_t need;
		ceph_decode_32_safe(p, end, n, bad_ext);
		need = sizeof(u32) * n;
		ceph_decode_need(p, end, need, bad_ext);
		*p += need;
		m->m_damaged = n > 0;
	} else {
		m->m_damaged = false;
	}
	if (mdsmap_ev >= 17) {
		/* balancer */
		ceph_decode_skip_string(p, end, bad_ext);
		/* standby_count_wanted */
		ceph_decode_skip_32(p, end, bad_ext);
		/* old_max_mds */
		ceph_decode_skip_32(p, end, bad_ext);
		/* min_compat_client */
		ceph_decode_skip_8(p, end, bad_ext);
		/* required_client_features */
		ceph_decode_skip_set(p, end, 64, bad_ext);
		/* bal_rank_mask */
		ceph_decode_skip_string(p, end, bad_ext);
	}
	if (mdsmap_ev >= 18) {
		ceph_decode_64_safe(p, end, m->m_max_xattr_size, bad_ext);
	}
bad_ext:
	doutc(cl, "m_enabled: %d, m_damaged: %d, m_num_laggy: %d\n",
	      !!m->m_enabled, !!m->m_damaged, m->m_num_laggy);
	*p = end;
	doutc(cl, "success epoch %u\n", m->m_epoch);
	return m;
nomem:
	err = -ENOMEM;
	goto out_err;
corrupt:
	pr_err_client(cl, "corrupt mdsmap\n");
	print_hex_dump(KERN_DEBUG, "mdsmap: ",
		       DUMP_PREFIX_OFFSET, 16, 1,
		       start, end - start, true);
out_err:
	ceph_mdsmap_destroy(m);
	return ERR_PTR(err);
bad:
	err = -EINVAL;
	goto corrupt;
}

void ceph_mdsmap_destroy(struct ceph_mdsmap *m)
{
	int i;

	if (m->m_info) {
		for (i = 0; i < m->possible_max_rank; i++)
			kfree(m->m_info[i].export_targets);
		kfree(m->m_info);
	}
	kfree(m->m_data_pg_pools);
	kfree(m->m_fs_name);
	kfree(m);
}

bool ceph_mdsmap_is_cluster_available(struct ceph_mdsmap *m)
{
	int i, nr_active = 0;
	if (!m->m_enabled)
		return false;
	if (m->m_damaged)
		return false;
	if (m->m_num_laggy == m->m_num_active_mds)
		return false;
	for (i = 0; i < m->possible_max_rank; i++) {
		if (m->m_info[i].state == CEPH_MDS_STATE_ACTIVE)
			nr_active++;
	}
	return nr_active > 0;
}
