// 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()
#undef x
};

void bch2_sb_error_id_to_text(struct printbuf *out, enum bch_sb_error_id id)
{
	if (id < BCH_FSCK_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;
	unsigned i;

	mutex_lock(&c->fsck_error_counts_lock);

	dst = bch2_sb_field_resize(&c->disk_sb, errors,
				   bch2_sb_field_errors_u64s(src->nr));

	if (!dst)
		goto err;

	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);
	}

err:
	mutex_unlock(&c->fsck_error_counts_lock);
}

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);
}
