// SPDX-License-Identifier: GPL-2.0

#include "bcachefs.h"
#include "journal_sb.h"
#include "darray.h"

#include <linux/sort.h>

/* BCH_SB_FIELD_journal: */

static int u64_cmp(const void *_l, const void *_r)
{
	const u64 *l = _l;
	const u64 *r = _r;

	return cmp_int(*l, *r);
}

static int bch2_sb_journal_validate(struct bch_sb *sb, struct bch_sb_field *f,
				enum bch_validate_flags flags, struct printbuf *err)
{
	struct bch_sb_field_journal *journal = field_to_type(f, journal);
	struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
	int ret = -BCH_ERR_invalid_sb_journal;
	unsigned nr;
	unsigned i;
	u64 *b;

	nr = bch2_nr_journal_buckets(journal);
	if (!nr)
		return 0;

	b = kmalloc_array(nr, sizeof(u64), GFP_KERNEL);
	if (!b)
		return -BCH_ERR_ENOMEM_sb_journal_validate;

	for (i = 0; i < nr; i++)
		b[i] = le64_to_cpu(journal->buckets[i]);

	sort(b, nr, sizeof(u64), u64_cmp, NULL);

	if (!b[0]) {
		prt_printf(err, "journal bucket at sector 0");
		goto err;
	}

	if (b[0] < le16_to_cpu(m.first_bucket)) {
		prt_printf(err, "journal bucket %llu before first bucket %u",
		       b[0], le16_to_cpu(m.first_bucket));
		goto err;
	}

	if (b[nr - 1] >= le64_to_cpu(m.nbuckets)) {
		prt_printf(err, "journal bucket %llu past end of device (nbuckets %llu)",
		       b[nr - 1], le64_to_cpu(m.nbuckets));
		goto err;
	}

	for (i = 0; i + 1 < nr; i++)
		if (b[i] == b[i + 1]) {
			prt_printf(err, "duplicate journal buckets %llu", b[i]);
			goto err;
		}

	ret = 0;
err:
	kfree(b);
	return ret;
}

static void bch2_sb_journal_to_text(struct printbuf *out, struct bch_sb *sb,
				    struct bch_sb_field *f)
{
	struct bch_sb_field_journal *journal = field_to_type(f, journal);
	unsigned i, nr = bch2_nr_journal_buckets(journal);

	prt_printf(out, "Buckets: ");
	for (i = 0; i < nr; i++)
		prt_printf(out, " %llu", le64_to_cpu(journal->buckets[i]));
	prt_newline(out);
}

const struct bch_sb_field_ops bch_sb_field_ops_journal = {
	.validate	= bch2_sb_journal_validate,
	.to_text	= bch2_sb_journal_to_text,
};

struct u64_range {
	u64	start;
	u64	end;
};

static int u64_range_cmp(const void *_l, const void *_r)
{
	const struct u64_range *l = _l;
	const struct u64_range *r = _r;

	return cmp_int(l->start, r->start);
}

static int bch2_sb_journal_v2_validate(struct bch_sb *sb, struct bch_sb_field *f,
				enum bch_validate_flags flags, struct printbuf *err)
{
	struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2);
	struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
	int ret = -BCH_ERR_invalid_sb_journal;
	u64 sum = 0;
	unsigned nr;
	unsigned i;
	struct u64_range *b;

	nr = bch2_sb_field_journal_v2_nr_entries(journal);
	if (!nr)
		return 0;

	b = kmalloc_array(nr, sizeof(*b), GFP_KERNEL);
	if (!b)
		return -BCH_ERR_ENOMEM_sb_journal_v2_validate;

	for (i = 0; i < nr; i++) {
		b[i].start = le64_to_cpu(journal->d[i].start);
		b[i].end = b[i].start + le64_to_cpu(journal->d[i].nr);

		if (b[i].end <= b[i].start) {
			prt_printf(err, "journal buckets entry with bad nr: %llu+%llu",
				   le64_to_cpu(journal->d[i].start),
				   le64_to_cpu(journal->d[i].nr));
			goto err;
		}

		sum += le64_to_cpu(journal->d[i].nr);
	}

	sort(b, nr, sizeof(*b), u64_range_cmp, NULL);

	if (!b[0].start) {
		prt_printf(err, "journal bucket at sector 0");
		goto err;
	}

	if (b[0].start < le16_to_cpu(m.first_bucket)) {
		prt_printf(err, "journal bucket %llu before first bucket %u",
		       b[0].start, le16_to_cpu(m.first_bucket));
		goto err;
	}

	if (b[nr - 1].end > le64_to_cpu(m.nbuckets)) {
		prt_printf(err, "journal bucket %llu past end of device (nbuckets %llu)",
		       b[nr - 1].end - 1, le64_to_cpu(m.nbuckets));
		goto err;
	}

	for (i = 0; i + 1 < nr; i++) {
		if (b[i].end > b[i + 1].start) {
			prt_printf(err, "duplicate journal buckets in ranges %llu-%llu, %llu-%llu",
			       b[i].start, b[i].end, b[i + 1].start, b[i + 1].end);
			goto err;
		}
	}

	if (sum > UINT_MAX) {
		prt_printf(err, "too many journal buckets: %llu > %u", sum, UINT_MAX);
		goto err;
	}

	ret = 0;
err:
	kfree(b);
	return ret;
}

static void bch2_sb_journal_v2_to_text(struct printbuf *out, struct bch_sb *sb,
				    struct bch_sb_field *f)
{
	struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2);
	unsigned i, nr = bch2_sb_field_journal_v2_nr_entries(journal);

	prt_printf(out, "Buckets: ");
	for (i = 0; i < nr; i++)
		prt_printf(out, " %llu-%llu",
		       le64_to_cpu(journal->d[i].start),
		       le64_to_cpu(journal->d[i].start) + le64_to_cpu(journal->d[i].nr));
	prt_newline(out);
}

const struct bch_sb_field_ops bch_sb_field_ops_journal_v2 = {
	.validate	= bch2_sb_journal_v2_validate,
	.to_text	= bch2_sb_journal_v2_to_text,
};

int bch2_journal_buckets_to_sb(struct bch_fs *c, struct bch_dev *ca,
			       u64 *buckets, unsigned nr)
{
	struct bch_sb_field_journal_v2 *j;
	unsigned i, dst = 0, nr_compacted = 1;

	if (c)
		lockdep_assert_held(&c->sb_lock);

	if (!nr) {
		bch2_sb_field_delete(&ca->disk_sb, BCH_SB_FIELD_journal);
		bch2_sb_field_delete(&ca->disk_sb, BCH_SB_FIELD_journal_v2);
		return 0;
	}

	for (i = 0; i + 1 < nr; i++)
		if (buckets[i] + 1 != buckets[i + 1])
			nr_compacted++;

	j = bch2_sb_field_resize(&ca->disk_sb, journal_v2,
			 (sizeof(*j) + sizeof(j->d[0]) * nr_compacted) / sizeof(u64));
	if (!j)
		return -BCH_ERR_ENOSPC_sb_journal;

	bch2_sb_field_delete(&ca->disk_sb, BCH_SB_FIELD_journal);

	j->d[dst].start = cpu_to_le64(buckets[0]);
	j->d[dst].nr	= cpu_to_le64(1);

	for (i = 1; i < nr; i++) {
		if (buckets[i] == buckets[i - 1] + 1) {
			le64_add_cpu(&j->d[dst].nr, 1);
		} else {
			dst++;
			j->d[dst].start = cpu_to_le64(buckets[i]);
			j->d[dst].nr	= cpu_to_le64(1);
		}
	}

	BUG_ON(dst + 1 != nr_compacted);
	return 0;
}
