// SPDX-License-Identifier: GPL-2.0

#include "bcachefs.h"
#include "sb-errors.h"
#include "super-io.h"

const char * const bch2_sb_error_strs[] = {
#define x(t, n, ...) [n] = #t,
	BCH_SB_ERRS()
	NULL
};

static void bch2_sb_error_id_to_text(struct printbuf *out, enum bch_sb_error_id id)
{
	if (id < BCH_SB_ERR_MAX)
		prt_str(out, bch2_sb_error_strs[id]);
	else
		prt_printf(out, "(unknown error %u)", id);
}

static inline unsigned bch2_sb_field_errors_nr_entries(struct bch_sb_field_errors *e)
{
	return bch2_sb_field_nr_entries(e);
}

static inline unsigned bch2_sb_field_errors_u64s(unsigned nr)
{
	return (sizeof(struct bch_sb_field_errors) +
		sizeof(struct bch_sb_field_error_entry) * nr) / sizeof(u64);
}

static int bch2_sb_errors_validate(struct bch_sb *sb, struct bch_sb_field *f,
				   enum bch_validate_flags flags, struct printbuf *err)
{
	struct bch_sb_field_errors *e = field_to_type(f, errors);
	unsigned i, nr = bch2_sb_field_errors_nr_entries(e);

	for (i = 0; i < nr; i++) {
		if (!BCH_SB_ERROR_ENTRY_NR(&e->entries[i])) {
			prt_printf(err, "entry with count 0 (id ");
			bch2_sb_error_id_to_text(err, BCH_SB_ERROR_ENTRY_ID(&e->entries[i]));
			prt_printf(err, ")");
			return -BCH_ERR_invalid_sb_errors;
		}

		if (i + 1 < nr &&
		    BCH_SB_ERROR_ENTRY_ID(&e->entries[i]) >=
		    BCH_SB_ERROR_ENTRY_ID(&e->entries[i + 1])) {
			prt_printf(err, "entries out of order");
			return -BCH_ERR_invalid_sb_errors;
		}
	}

	return 0;
}

static void bch2_sb_errors_to_text(struct printbuf *out, struct bch_sb *sb,
				   struct bch_sb_field *f)
{
	struct bch_sb_field_errors *e = field_to_type(f, errors);
	unsigned i, nr = bch2_sb_field_errors_nr_entries(e);

	if (out->nr_tabstops <= 1)
		printbuf_tabstop_push(out, 16);

	for (i = 0; i < nr; i++) {
		bch2_sb_error_id_to_text(out, BCH_SB_ERROR_ENTRY_ID(&e->entries[i]));
		prt_tab(out);
		prt_u64(out, BCH_SB_ERROR_ENTRY_NR(&e->entries[i]));
		prt_tab(out);
		bch2_prt_datetime(out, le64_to_cpu(e->entries[i].last_error_time));
		prt_newline(out);
	}
}

const struct bch_sb_field_ops bch_sb_field_ops_errors = {
	.validate	= bch2_sb_errors_validate,
	.to_text	= bch2_sb_errors_to_text,
};

void bch2_sb_error_count(struct bch_fs *c, enum bch_sb_error_id err)
{
	bch_sb_errors_cpu *e = &c->fsck_error_counts;
	struct bch_sb_error_entry_cpu n = {
		.id = err,
		.nr = 1,
		.last_error_time = ktime_get_real_seconds()
	};
	unsigned i;

	mutex_lock(&c->fsck_error_counts_lock);
	for (i = 0; i < e->nr; i++) {
		if (err == e->data[i].id) {
			e->data[i].nr++;
			e->data[i].last_error_time = n.last_error_time;
			goto out;
		}
		if (err < e->data[i].id)
			break;
	}

	if (darray_make_room(e, 1))
		goto out;

	darray_insert_item(e, i, n);
out:
	mutex_unlock(&c->fsck_error_counts_lock);
}

void bch2_sb_errors_from_cpu(struct bch_fs *c)
{
	bch_sb_errors_cpu *src = &c->fsck_error_counts;
	struct bch_sb_field_errors *dst =
		bch2_sb_field_resize(&c->disk_sb, errors,
				     bch2_sb_field_errors_u64s(src->nr));
	unsigned i;

	if (!dst)
		return;

	for (i = 0; i < src->nr; i++) {
		SET_BCH_SB_ERROR_ENTRY_ID(&dst->entries[i], src->data[i].id);
		SET_BCH_SB_ERROR_ENTRY_NR(&dst->entries[i], src->data[i].nr);
		dst->entries[i].last_error_time = cpu_to_le64(src->data[i].last_error_time);
	}
}

static int bch2_sb_errors_to_cpu(struct bch_fs *c)
{
	struct bch_sb_field_errors *src = bch2_sb_field_get(c->disk_sb.sb, errors);
	bch_sb_errors_cpu *dst = &c->fsck_error_counts;
	unsigned i, nr = bch2_sb_field_errors_nr_entries(src);
	int ret;

	if (!nr)
		return 0;

	mutex_lock(&c->fsck_error_counts_lock);
	ret = darray_make_room(dst, nr);
	if (ret)
		goto err;

	dst->nr = nr;

	for (i = 0; i < nr; i++) {
		dst->data[i].id = BCH_SB_ERROR_ENTRY_ID(&src->entries[i]);
		dst->data[i].nr = BCH_SB_ERROR_ENTRY_NR(&src->entries[i]);
		dst->data[i].last_error_time = le64_to_cpu(src->entries[i].last_error_time);
	}
err:
	mutex_unlock(&c->fsck_error_counts_lock);

	return ret;
}

void bch2_fs_sb_errors_exit(struct bch_fs *c)
{
	darray_exit(&c->fsck_error_counts);
}

void bch2_fs_sb_errors_init_early(struct bch_fs *c)
{
	mutex_init(&c->fsck_error_counts_lock);
	darray_init(&c->fsck_error_counts);
}

int bch2_fs_sb_errors_init(struct bch_fs *c)
{
	return bch2_sb_errors_to_cpu(c);
}
