// SPDX-License-Identifier: GPL-2.0

#include "bcachefs.h"
#include "backpointers.h"
#include "bkey_methods.h"
#include "btree_cache.h"
#include "btree_types.h"
#include "alloc_background.h"
#include "dirent.h"
#include "disk_accounting.h"
#include "ec.h"
#include "error.h"
#include "extents.h"
#include "inode.h"
#include "io_misc.h"
#include "lru.h"
#include "quota.h"
#include "reflink.h"
#include "snapshot.h"
#include "subvolume.h"
#include "xattr.h"

const char * const bch2_bkey_types[] = {
#define x(name, nr, ...) #name,
	BCH_BKEY_TYPES()
#undef x
	NULL
};

static int deleted_key_validate(struct bch_fs *c, struct bkey_s_c k,
				struct bkey_validate_context from)
{
	return 0;
}

#define bch2_bkey_ops_deleted ((struct bkey_ops) {	\
	.key_validate	= deleted_key_validate,		\
})

#define bch2_bkey_ops_whiteout ((struct bkey_ops) {	\
	.key_validate	= deleted_key_validate,		\
})

static int empty_val_key_validate(struct bch_fs *c, struct bkey_s_c k,
				  struct bkey_validate_context from)
{
	int ret = 0;

	bkey_fsck_err_on(bkey_val_bytes(k.k),
			 c, bkey_val_size_nonzero,
			 "incorrect value size (%zu != 0)",
			 bkey_val_bytes(k.k));
fsck_err:
	return ret;
}

#define bch2_bkey_ops_error ((struct bkey_ops) {	\
	.key_validate = empty_val_key_validate,		\
})

static int key_type_cookie_validate(struct bch_fs *c, struct bkey_s_c k,
				    struct bkey_validate_context from)
{
	return 0;
}

static void key_type_cookie_to_text(struct printbuf *out, struct bch_fs *c,
				    struct bkey_s_c k)
{
	struct bkey_s_c_cookie ck = bkey_s_c_to_cookie(k);

	prt_printf(out, "%llu", le64_to_cpu(ck.v->cookie));
}

#define bch2_bkey_ops_cookie ((struct bkey_ops) {	\
	.key_validate	= key_type_cookie_validate,	\
	.val_to_text	= key_type_cookie_to_text,	\
	.min_val_size	= 8,				\
})

#define bch2_bkey_ops_hash_whiteout ((struct bkey_ops) {\
	.key_validate	= empty_val_key_validate,	\
})

static int key_type_inline_data_validate(struct bch_fs *c, struct bkey_s_c k,
					 struct bkey_validate_context from)
{
	return 0;
}

static void key_type_inline_data_to_text(struct printbuf *out, struct bch_fs *c,
					 struct bkey_s_c k)
{
	struct bkey_s_c_inline_data d = bkey_s_c_to_inline_data(k);
	unsigned datalen = bkey_inline_data_bytes(k.k);

	prt_printf(out, "datalen %u: %*phN",
	       datalen, min(datalen, 32U), d.v->data);
}

#define bch2_bkey_ops_inline_data ((struct bkey_ops) {		\
	.key_validate	= key_type_inline_data_validate,	\
	.val_to_text	= key_type_inline_data_to_text,		\
})

static bool key_type_set_merge(struct bch_fs *c, struct bkey_s l, struct bkey_s_c r)
{
	bch2_key_resize(l.k, l.k->size + r.k->size);
	return true;
}

#define bch2_bkey_ops_set ((struct bkey_ops) {		\
	.key_validate	= empty_val_key_validate,	\
	.key_merge	= key_type_set_merge,		\
})

const struct bkey_ops bch2_bkey_ops[] = {
#define x(name, nr, ...) [KEY_TYPE_##name]	= bch2_bkey_ops_##name,
	BCH_BKEY_TYPES()
#undef x
};

const struct bkey_ops bch2_bkey_null_ops = {
};

int bch2_bkey_val_validate(struct bch_fs *c, struct bkey_s_c k,
			   struct bkey_validate_context from)
{
	if (test_bit(BCH_FS_no_invalid_checks, &c->flags))
		return 0;

	const struct bkey_ops *ops = bch2_bkey_type_ops(k.k->type);
	int ret = 0;

	bkey_fsck_err_on(bkey_val_bytes(k.k) < ops->min_val_size,
			 c, bkey_val_size_too_small,
			 "bad val size (%zu < %u)",
			 bkey_val_bytes(k.k), ops->min_val_size);

	if (!ops->key_validate)
		return 0;

	ret = ops->key_validate(c, k, from);
fsck_err:
	return ret;
}

static u64 bch2_key_types_allowed[] = {
	[BKEY_TYPE_btree] =
		BIT_ULL(KEY_TYPE_deleted)|
		BIT_ULL(KEY_TYPE_btree_ptr)|
		BIT_ULL(KEY_TYPE_btree_ptr_v2),
#define x(name, nr, flags, keys)	[BKEY_TYPE_##name] = BIT_ULL(KEY_TYPE_deleted)|keys,
	BCH_BTREE_IDS()
#undef x
};

static const enum bch_bkey_type_flags bch2_bkey_type_flags[] = {
#define x(name, nr, flags)	[KEY_TYPE_##name] = flags,
	BCH_BKEY_TYPES()
#undef x
};

const char *bch2_btree_node_type_str(enum btree_node_type type)
{
	return type == BKEY_TYPE_btree ? "internal btree node" : bch2_btree_id_str(type - 1);
}

int __bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k,
			 struct bkey_validate_context from)
{
	enum btree_node_type type = __btree_node_type(from.level, from.btree);

	if (test_bit(BCH_FS_no_invalid_checks, &c->flags))
		return 0;

	int ret = 0;

	bkey_fsck_err_on(k.k->u64s < BKEY_U64s,
			 c, bkey_u64s_too_small,
			 "u64s too small (%u < %zu)", k.k->u64s, BKEY_U64s);

	if (type >= BKEY_TYPE_NR)
		return 0;

	enum bch_bkey_type_flags bkey_flags = k.k->type < KEY_TYPE_MAX
		? bch2_bkey_type_flags[k.k->type]
		: 0;

	bool strict_key_type_allowed =
		(from.flags & BCH_VALIDATE_commit) ||
		type == BKEY_TYPE_btree ||
		(from.btree < BTREE_ID_NR &&
		 (bkey_flags & BKEY_TYPE_strict_btree_checks));

	bkey_fsck_err_on(strict_key_type_allowed &&
			 k.k->type < KEY_TYPE_MAX &&
			 !(bch2_key_types_allowed[type] & BIT_ULL(k.k->type)),
			 c, bkey_invalid_type_for_btree,
			 "invalid key type for btree %s (%s)",
			 bch2_btree_node_type_str(type),
			 k.k->type < KEY_TYPE_MAX
			 ? bch2_bkey_types[k.k->type]
			 : "(unknown)");

	if (btree_node_type_is_extents(type) && !bkey_whiteout(k.k)) {
		bkey_fsck_err_on(k.k->size == 0,
				 c, bkey_extent_size_zero,
				 "size == 0");

		bkey_fsck_err_on(k.k->size > k.k->p.offset,
				 c, bkey_extent_size_greater_than_offset,
				 "size greater than offset (%u > %llu)",
				 k.k->size, k.k->p.offset);
	} else {
		bkey_fsck_err_on(k.k->size,
				 c, bkey_size_nonzero,
				 "size != 0");
	}

	if (type != BKEY_TYPE_btree) {
		enum btree_id btree = type - 1;

		if (btree_type_has_snapshots(btree)) {
			bkey_fsck_err_on(!k.k->p.snapshot,
					 c, bkey_snapshot_zero,
					 "snapshot == 0");
		} else if (!btree_type_has_snapshot_field(btree)) {
			bkey_fsck_err_on(k.k->p.snapshot,
					 c, bkey_snapshot_nonzero,
					 "nonzero snapshot");
		} else {
			/*
			 * btree uses snapshot field but it's not required to be
			 * nonzero
			 */
		}

		bkey_fsck_err_on(bkey_eq(k.k->p, POS_MAX),
				 c, bkey_at_pos_max,
				 "key at POS_MAX");
	}
fsck_err:
	return ret;
}

int bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k,
		       struct bkey_validate_context from)
{
	return __bch2_bkey_validate(c, k, from) ?:
		bch2_bkey_val_validate(c, k, from);
}

int bch2_bkey_in_btree_node(struct bch_fs *c, struct btree *b,
			    struct bkey_s_c k,
			    struct bkey_validate_context from)
{
	int ret = 0;

	bkey_fsck_err_on(bpos_lt(k.k->p, b->data->min_key),
			 c, bkey_before_start_of_btree_node,
			 "key before start of btree node");

	bkey_fsck_err_on(bpos_gt(k.k->p, b->data->max_key),
			 c, bkey_after_end_of_btree_node,
			 "key past end of btree node");
fsck_err:
	return ret;
}

void bch2_bpos_to_text(struct printbuf *out, struct bpos pos)
{
	if (bpos_eq(pos, POS_MIN))
		prt_printf(out, "POS_MIN");
	else if (bpos_eq(pos, POS_MAX))
		prt_printf(out, "POS_MAX");
	else if (bpos_eq(pos, SPOS_MAX))
		prt_printf(out, "SPOS_MAX");
	else {
		if (pos.inode == U64_MAX)
			prt_printf(out, "U64_MAX");
		else
			prt_printf(out, "%llu", pos.inode);
		prt_printf(out, ":");
		if (pos.offset == U64_MAX)
			prt_printf(out, "U64_MAX");
		else
			prt_printf(out, "%llu", pos.offset);
		prt_printf(out, ":");
		if (pos.snapshot == U32_MAX)
			prt_printf(out, "U32_MAX");
		else
			prt_printf(out, "%u", pos.snapshot);
	}
}

void bch2_bkey_to_text(struct printbuf *out, const struct bkey *k)
{
	if (k) {
		prt_printf(out, "u64s %u type ", k->u64s);

		if (k->type < KEY_TYPE_MAX)
			prt_printf(out, "%s ", bch2_bkey_types[k->type]);
		else
			prt_printf(out, "%u ", k->type);

		bch2_bpos_to_text(out, k->p);

		prt_printf(out, " len %u ver %llu", k->size, k->bversion.lo);
	} else {
		prt_printf(out, "(null)");
	}
}

void bch2_val_to_text(struct printbuf *out, struct bch_fs *c,
		      struct bkey_s_c k)
{
	const struct bkey_ops *ops = bch2_bkey_type_ops(k.k->type);

	if (likely(ops->val_to_text))
		ops->val_to_text(out, c, k);
}

void bch2_bkey_val_to_text(struct printbuf *out, struct bch_fs *c,
			   struct bkey_s_c k)
{
	bch2_bkey_to_text(out, k.k);

	if (bkey_val_bytes(k.k)) {
		prt_printf(out, ": ");
		bch2_val_to_text(out, c, k);
	}
}

void bch2_bkey_swab_val(struct bkey_s k)
{
	const struct bkey_ops *ops = bch2_bkey_type_ops(k.k->type);

	if (ops->swab)
		ops->swab(k);
}

bool bch2_bkey_normalize(struct bch_fs *c, struct bkey_s k)
{
	const struct bkey_ops *ops = bch2_bkey_type_ops(k.k->type);

	return ops->key_normalize
		? ops->key_normalize(c, k)
		: false;
}

bool bch2_bkey_merge(struct bch_fs *c, struct bkey_s l, struct bkey_s_c r)
{
	const struct bkey_ops *ops = bch2_bkey_type_ops(l.k->type);

	return ops->key_merge &&
		bch2_bkey_maybe_mergable(l.k, r.k) &&
		(u64) l.k->size + r.k->size <= KEY_SIZE_MAX &&
		!static_branch_unlikely(&bch2_key_merging_disabled) &&
		ops->key_merge(c, l, r);
}

static const struct old_bkey_type {
	u8		btree_node_type;
	u8		old;
	u8		new;
} bkey_renumber_table[] = {
	{BKEY_TYPE_btree,	128, KEY_TYPE_btree_ptr		},
	{BKEY_TYPE_extents,	128, KEY_TYPE_extent		},
	{BKEY_TYPE_extents,	129, KEY_TYPE_extent		},
	{BKEY_TYPE_extents,	130, KEY_TYPE_reservation	},
	{BKEY_TYPE_inodes,	128, KEY_TYPE_inode		},
	{BKEY_TYPE_inodes,	130, KEY_TYPE_inode_generation	},
	{BKEY_TYPE_dirents,	128, KEY_TYPE_dirent		},
	{BKEY_TYPE_dirents,	129, KEY_TYPE_hash_whiteout	},
	{BKEY_TYPE_xattrs,	128, KEY_TYPE_xattr		},
	{BKEY_TYPE_xattrs,	129, KEY_TYPE_hash_whiteout	},
	{BKEY_TYPE_alloc,	128, KEY_TYPE_alloc		},
	{BKEY_TYPE_quotas,	128, KEY_TYPE_quota		},
};

void bch2_bkey_renumber(enum btree_node_type btree_node_type,
			struct bkey_packed *k,
			int write)
{
	const struct old_bkey_type *i;

	for (i = bkey_renumber_table;
	     i < bkey_renumber_table + ARRAY_SIZE(bkey_renumber_table);
	     i++)
		if (btree_node_type == i->btree_node_type &&
		    k->type == (write ? i->new : i->old)) {
			k->type = write ? i->old : i->new;
			break;
		}
}

void __bch2_bkey_compat(unsigned level, enum btree_id btree_id,
			unsigned version, unsigned big_endian,
			int write,
			struct bkey_format *f,
			struct bkey_packed *k)
{
	const struct bkey_ops *ops;
	struct bkey uk;
	unsigned nr_compat = 5;
	int i;

	/*
	 * Do these operations in reverse order in the write path:
	 */

	for (i = 0; i < nr_compat; i++)
	switch (!write ? i : nr_compat - 1 - i) {
	case 0:
		if (big_endian != CPU_BIG_ENDIAN) {
			bch2_bkey_swab_key(f, k);
		} else if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG)) {
			bch2_bkey_swab_key(f, k);
			bch2_bkey_swab_key(f, k);
		}
		break;
	case 1:
		if (version < bcachefs_metadata_version_bkey_renumber)
			bch2_bkey_renumber(__btree_node_type(level, btree_id), k, write);
		break;
	case 2:
		if (version < bcachefs_metadata_version_inode_btree_change &&
		    btree_id == BTREE_ID_inodes) {
			if (!bkey_packed(k)) {
				struct bkey_i *u = packed_to_bkey(k);

				swap(u->k.p.inode, u->k.p.offset);
			} else if (f->bits_per_field[BKEY_FIELD_INODE] &&
				   f->bits_per_field[BKEY_FIELD_OFFSET]) {
				struct bkey_format tmp = *f, *in = f, *out = &tmp;

				swap(tmp.bits_per_field[BKEY_FIELD_INODE],
				     tmp.bits_per_field[BKEY_FIELD_OFFSET]);
				swap(tmp.field_offset[BKEY_FIELD_INODE],
				     tmp.field_offset[BKEY_FIELD_OFFSET]);

				if (!write)
					swap(in, out);

				uk = __bch2_bkey_unpack_key(in, k);
				swap(uk.p.inode, uk.p.offset);
				BUG_ON(!bch2_bkey_pack_key(k, &uk, out));
			}
		}
		break;
	case 3:
		if (version < bcachefs_metadata_version_snapshot &&
		    (level || btree_type_has_snapshots(btree_id))) {
			struct bkey_i *u = packed_to_bkey(k);

			if (u) {
				u->k.p.snapshot = write
					? 0 : U32_MAX;
			} else {
				u64 min_packed = le64_to_cpu(f->field_offset[BKEY_FIELD_SNAPSHOT]);
				u64 max_packed = min_packed +
					~(~0ULL << f->bits_per_field[BKEY_FIELD_SNAPSHOT]);

				uk = __bch2_bkey_unpack_key(f, k);
				uk.p.snapshot = write
					? min_packed : min_t(u64, U32_MAX, max_packed);

				BUG_ON(!bch2_bkey_pack_key(k, &uk, f));
			}
		}

		break;
	case 4: {
		struct bkey_s u;

		if (!bkey_packed(k)) {
			u = bkey_i_to_s(packed_to_bkey(k));
		} else {
			uk = __bch2_bkey_unpack_key(f, k);
			u.k = &uk;
			u.v = bkeyp_val(f, k);
		}

		if (big_endian != CPU_BIG_ENDIAN)
			bch2_bkey_swab_val(u);

		ops = bch2_bkey_type_ops(k->type);

		if (ops->compat)
			ops->compat(btree_id, version, big_endian, write, u);
		break;
	}
	default:
		BUG();
	}
}
