// 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 "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_invalid(struct bch_fs *c, struct bkey_s_c k,
			       enum bkey_invalid_flags flags, struct printbuf *err)
{
	return 0;
}

#define bch2_bkey_ops_deleted ((struct bkey_ops) {	\
	.key_invalid = deleted_key_invalid,		\
})

#define bch2_bkey_ops_whiteout ((struct bkey_ops) {	\
	.key_invalid = deleted_key_invalid,		\
})

static int empty_val_key_invalid(struct bch_fs *c, struct bkey_s_c k,
				 enum bkey_invalid_flags flags, struct printbuf *err)
{
	int ret = 0;

	bkey_fsck_err_on(bkey_val_bytes(k.k), c, err,
			 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_invalid = empty_val_key_invalid,		\
})

static int key_type_cookie_invalid(struct bch_fs *c, struct bkey_s_c k,
				   enum bkey_invalid_flags flags, struct printbuf *err)
{
	return 0;
}

#define bch2_bkey_ops_cookie ((struct bkey_ops) {	\
	.key_invalid	= key_type_cookie_invalid,	\
	.min_val_size	= 8,				\
})

#define bch2_bkey_ops_hash_whiteout ((struct bkey_ops) {\
	.key_invalid = empty_val_key_invalid,		\
})

static int key_type_inline_data_invalid(struct bch_fs *c, struct bkey_s_c k,
					enum bkey_invalid_flags flags, struct printbuf *err)
{
	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_invalid	= key_type_inline_data_invalid,	\
	.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_invalid	= empty_val_key_invalid,	\
	.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_invalid(struct bch_fs *c, struct bkey_s_c k,
			  enum bkey_invalid_flags flags,
			  struct printbuf *err)
{
	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, err,
			 bkey_val_size_too_small,
			 "bad val size (%zu < %u)",
			 bkey_val_bytes(k.k), ops->min_val_size);

	if (!ops->key_invalid)
		return 0;

	ret = ops->key_invalid(c, k, flags, err);
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
};

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_invalid(struct bch_fs *c, struct bkey_s_c k,
			enum btree_node_type type,
			enum bkey_invalid_flags flags,
			struct printbuf *err)
{
	int ret = 0;

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

	if (type >= BKEY_TYPE_NR)
		return 0;

	bkey_fsck_err_on((flags & BKEY_INVALID_COMMIT) &&
			 !(bch2_key_types_allowed[type] & BIT_ULL(k.k->type)), c, err,
			 bkey_invalid_type_for_btree,
			 "invalid key type for btree %s (%s)",
			 bch2_btree_node_type_str(type), bch2_bkey_types[k.k->type]);

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

		bkey_fsck_err_on(k.k->size > k.k->p.offset, c, err,
				 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, err,
				 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, err,
					 bkey_snapshot_zero,
					 "snapshot == 0");
		} else if (!btree_type_has_snapshot_field(btree)) {
			bkey_fsck_err_on(k.k->p.snapshot, c, err,
					 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, err,
				 bkey_at_pos_max,
				 "key at POS_MAX");
	}
fsck_err:
	return ret;
}

int bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
		      enum btree_node_type type,
		      enum bkey_invalid_flags flags,
		      struct printbuf *err)
{
	return __bch2_bkey_invalid(c, k, type, flags, err) ?:
		bch2_bkey_val_invalid(c, k, flags, err);
}

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

	bkey_fsck_err_on(bpos_lt(k.k->p, b->data->min_key), c, err,
			 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, err,
			 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->version.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 &&
		!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);
		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();
	}
}
