// SPDX-License-Identifier: GPL-2.0
#include "bcachefs.h"
#include "disk_groups.h"
#include "sb-members.h"
#include "super-io.h"

#include <linux/sort.h>

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

	return ((BCH_GROUP_DELETED(l) > BCH_GROUP_DELETED(r)) -
		(BCH_GROUP_DELETED(l) < BCH_GROUP_DELETED(r))) ?:
		((BCH_GROUP_PARENT(l) > BCH_GROUP_PARENT(r)) -
		 (BCH_GROUP_PARENT(l) < BCH_GROUP_PARENT(r))) ?:
		strncmp(l->label, r->label, sizeof(l->label));
}

static int bch2_sb_disk_groups_validate(struct bch_sb *sb, struct bch_sb_field *f,
				enum bch_validate_flags flags, struct printbuf *err)
{
	struct bch_sb_field_disk_groups *groups =
		field_to_type(f, disk_groups);
	struct bch_disk_group *g, *sorted = NULL;
	unsigned nr_groups = disk_groups_nr(groups);
	unsigned i, len;
	int ret = 0;

	for (i = 0; i < sb->nr_devices; i++) {
		struct bch_member m = bch2_sb_member_get(sb, i);
		unsigned group_id;

		if (!BCH_MEMBER_GROUP(&m))
			continue;

		group_id = BCH_MEMBER_GROUP(&m) - 1;

		if (group_id >= nr_groups) {
			prt_printf(err, "disk %u has invalid label %u (have %u)",
				   i, group_id, nr_groups);
			return -BCH_ERR_invalid_sb_disk_groups;
		}

		if (BCH_GROUP_DELETED(&groups->entries[group_id])) {
			prt_printf(err, "disk %u has deleted label %u", i, group_id);
			return -BCH_ERR_invalid_sb_disk_groups;
		}
	}

	if (!nr_groups)
		return 0;

	for (i = 0; i < nr_groups; i++) {
		g = groups->entries + i;

		if (BCH_GROUP_DELETED(g))
			continue;

		len = strnlen(g->label, sizeof(g->label));
		if (!len) {
			prt_printf(err, "label %u empty", i);
			return -BCH_ERR_invalid_sb_disk_groups;
		}
	}

	sorted = kmalloc_array(nr_groups, sizeof(*sorted), GFP_KERNEL);
	if (!sorted)
		return -BCH_ERR_ENOMEM_disk_groups_validate;

	memcpy(sorted, groups->entries, nr_groups * sizeof(*sorted));
	sort(sorted, nr_groups, sizeof(*sorted), group_cmp, NULL);

	for (g = sorted; g + 1 < sorted + nr_groups; g++)
		if (!BCH_GROUP_DELETED(g) &&
		    !group_cmp(&g[0], &g[1])) {
			prt_printf(err, "duplicate label %llu.%.*s",
			       BCH_GROUP_PARENT(g),
			       (int) sizeof(g->label), g->label);
			ret = -BCH_ERR_invalid_sb_disk_groups;
			goto err;
		}
err:
	kfree(sorted);
	return ret;
}

static void bch2_sb_disk_groups_to_text(struct printbuf *out,
					struct bch_sb *sb,
					struct bch_sb_field *f)
{
	struct bch_sb_field_disk_groups *groups =
		field_to_type(f, disk_groups);
	struct bch_disk_group *g;
	unsigned nr_groups = disk_groups_nr(groups);

	for (g = groups->entries;
	     g < groups->entries + nr_groups;
	     g++) {
		if (g != groups->entries)
			prt_printf(out, " ");

		if (BCH_GROUP_DELETED(g))
			prt_printf(out, "[deleted]");
		else
			prt_printf(out, "[parent %llu name %s]",
			       BCH_GROUP_PARENT(g), g->label);
	}
}

const struct bch_sb_field_ops bch_sb_field_ops_disk_groups = {
	.validate	= bch2_sb_disk_groups_validate,
	.to_text	= bch2_sb_disk_groups_to_text
};

int bch2_sb_disk_groups_to_cpu(struct bch_fs *c)
{
	struct bch_sb_field_disk_groups *groups;
	struct bch_disk_groups_cpu *cpu_g, *old_g;
	unsigned i, g, nr_groups;

	lockdep_assert_held(&c->sb_lock);

	groups		= bch2_sb_field_get(c->disk_sb.sb, disk_groups);
	nr_groups	= disk_groups_nr(groups);

	if (!groups)
		return 0;

	cpu_g = kzalloc(struct_size(cpu_g, entries, nr_groups), GFP_KERNEL);
	if (!cpu_g)
		return bch_err_throw(c, ENOMEM_disk_groups_to_cpu);

	cpu_g->nr = nr_groups;

	for (i = 0; i < nr_groups; i++) {
		struct bch_disk_group *src	= &groups->entries[i];
		struct bch_disk_group_cpu *dst	= &cpu_g->entries[i];

		dst->deleted	= BCH_GROUP_DELETED(src);
		dst->parent	= BCH_GROUP_PARENT(src);
		memcpy(dst->label, src->label, sizeof(dst->label));
	}

	for (i = 0; i < c->disk_sb.sb->nr_devices; i++) {
		struct bch_member m = bch2_sb_member_get(c->disk_sb.sb, i);
		struct bch_disk_group_cpu *dst;

		if (!bch2_member_alive(&m))
			continue;

		g = BCH_MEMBER_GROUP(&m);
		while (g) {
			dst = &cpu_g->entries[g - 1];
			__set_bit(i, dst->devs.d);
			g = dst->parent;
		}
	}

	old_g = rcu_dereference_protected(c->disk_groups,
				lockdep_is_held(&c->sb_lock));
	rcu_assign_pointer(c->disk_groups, cpu_g);
	if (old_g)
		kfree_rcu(old_g, rcu);

	return 0;
}

const struct bch_devs_mask *bch2_target_to_mask(struct bch_fs *c, unsigned target)
{
	struct target t = target_decode(target);

	guard(rcu)();

	switch (t.type) {
	case TARGET_NULL:
		return NULL;
	case TARGET_DEV: {
		struct bch_dev *ca = t.dev < c->sb.nr_devices
			? rcu_dereference(c->devs[t.dev])
			: NULL;
		return ca ? &ca->self : NULL;
	}
	case TARGET_GROUP: {
		struct bch_disk_groups_cpu *g = rcu_dereference(c->disk_groups);

		return g && t.group < g->nr && !g->entries[t.group].deleted
			? &g->entries[t.group].devs
			: NULL;
	}
	default:
		BUG();
	}
}

bool bch2_dev_in_target(struct bch_fs *c, unsigned dev, unsigned target)
{
	struct target t = target_decode(target);

	switch (t.type) {
	case TARGET_NULL:
		return false;
	case TARGET_DEV:
		return dev == t.dev;
	case TARGET_GROUP: {
		struct bch_disk_groups_cpu *g = rcu_dereference(c->disk_groups);
		const struct bch_devs_mask *m =
			g && t.group < g->nr && !g->entries[t.group].deleted
			? &g->entries[t.group].devs
			: NULL;

		return m ? test_bit(dev, m->d) : false;
	}
	default:
		BUG();
	}
}

static int __bch2_disk_group_find(struct bch_sb_field_disk_groups *groups,
				  unsigned parent,
				  const char *name, unsigned namelen)
{
	unsigned i, nr_groups = disk_groups_nr(groups);

	if (!namelen || namelen > BCH_SB_LABEL_SIZE)
		return -EINVAL;

	for (i = 0; i < nr_groups; i++) {
		struct bch_disk_group *g = groups->entries + i;

		if (BCH_GROUP_DELETED(g))
			continue;

		if (!BCH_GROUP_DELETED(g) &&
		    BCH_GROUP_PARENT(g) == parent &&
		    strnlen(g->label, sizeof(g->label)) == namelen &&
		    !memcmp(name, g->label, namelen))
			return i;
	}

	return -1;
}

static int __bch2_disk_group_add(struct bch_sb_handle *sb, unsigned parent,
				 const char *name, unsigned namelen)
{
	struct bch_sb_field_disk_groups *groups =
		bch2_sb_field_get(sb->sb, disk_groups);
	unsigned i, nr_groups = disk_groups_nr(groups);
	struct bch_disk_group *g;

	if (!namelen || namelen > BCH_SB_LABEL_SIZE)
		return -EINVAL;

	for (i = 0;
	     i < nr_groups && !BCH_GROUP_DELETED(&groups->entries[i]);
	     i++)
		;

	if (i == nr_groups) {
		unsigned u64s =
			(sizeof(struct bch_sb_field_disk_groups) +
			 sizeof(struct bch_disk_group) * (nr_groups + 1)) /
			sizeof(u64);

		groups = bch2_sb_field_resize(sb, disk_groups, u64s);
		if (!groups)
			return -BCH_ERR_ENOSPC_disk_label_add;

		nr_groups = disk_groups_nr(groups);
	}

	BUG_ON(i >= nr_groups);

	g = &groups->entries[i];

	memcpy(g->label, name, namelen);
	if (namelen < sizeof(g->label))
		g->label[namelen] = '\0';
	SET_BCH_GROUP_DELETED(g, 0);
	SET_BCH_GROUP_PARENT(g, parent);
	SET_BCH_GROUP_DATA_ALLOWED(g, ~0);

	return i;
}

int bch2_disk_path_find(struct bch_sb_handle *sb, const char *name)
{
	struct bch_sb_field_disk_groups *groups =
		bch2_sb_field_get(sb->sb, disk_groups);
	int v = -1;

	do {
		const char *next = strchrnul(name, '.');
		unsigned len = next - name;

		if (*next == '.')
			next++;

		v = __bch2_disk_group_find(groups, v + 1, name, len);
		name = next;
	} while (*name && v >= 0);

	return v;
}

int bch2_disk_path_find_or_create(struct bch_sb_handle *sb, const char *name)
{
	struct bch_sb_field_disk_groups *groups;
	unsigned parent = 0;
	int v = -1;

	do {
		const char *next = strchrnul(name, '.');
		unsigned len = next - name;

		if (*next == '.')
			next++;

		groups = bch2_sb_field_get(sb->sb, disk_groups);

		v = __bch2_disk_group_find(groups, parent, name, len);
		if (v < 0)
			v = __bch2_disk_group_add(sb, parent, name, len);
		if (v < 0)
			return v;

		parent = v + 1;
		name = next;
	} while (*name && v >= 0);

	return v;
}

static void __bch2_disk_path_to_text(struct printbuf *out, struct bch_disk_groups_cpu *g,
				     unsigned v)
{
	u16 path[32];
	unsigned nr = 0;

	while (1) {
		if (nr == ARRAY_SIZE(path))
			goto invalid;

		if (v >= (g ? g->nr : 0))
			goto invalid;

		struct bch_disk_group_cpu *e = g->entries + v;

		if (e->deleted)
			goto invalid;

		path[nr++] = v;

		if (!e->parent)
			break;

		v = e->parent - 1;
	}

	while (nr) {
		struct bch_disk_group_cpu *e = g->entries + path[--nr];

		prt_printf(out, "%.*s", (int) sizeof(e->label), e->label);
		if (nr)
			prt_printf(out, ".");
	}
	return;
invalid:
	prt_printf(out, "invalid label %u", v);
}

void bch2_disk_groups_to_text(struct printbuf *out, struct bch_fs *c)
{
	bch2_printbuf_make_room(out, 4096);

	out->atomic++;
	guard(rcu)();
	struct bch_disk_groups_cpu *g = rcu_dereference(c->disk_groups);

	for (unsigned i = 0; i < (g ? g->nr : 0); i++) {
		prt_printf(out, "%2u: ", i);

		if (g->entries[i].deleted) {
			prt_printf(out, "[deleted]");
			goto next;
		}

		__bch2_disk_path_to_text(out, g, i);

		prt_printf(out, " devs");

		for_each_member_device_rcu(c, ca, &g->entries[i].devs)
			prt_printf(out, " %s", ca->name);
next:
		prt_newline(out);
	}

	out->atomic--;
}

void bch2_disk_path_to_text(struct printbuf *out, struct bch_fs *c, unsigned v)
{
	out->atomic++;
	guard(rcu)();
	__bch2_disk_path_to_text(out, rcu_dereference(c->disk_groups), v),
	--out->atomic;
}

void bch2_disk_path_to_text_sb(struct printbuf *out, struct bch_sb *sb, unsigned v)
{
	struct bch_sb_field_disk_groups *groups =
		bch2_sb_field_get(sb, disk_groups);
	struct bch_disk_group *g;
	unsigned nr = 0;
	u16 path[32];

	while (1) {
		if (nr == ARRAY_SIZE(path))
			goto inval;

		if (v >= disk_groups_nr(groups))
			goto inval;

		g = groups->entries + v;

		if (BCH_GROUP_DELETED(g))
			goto inval;

		path[nr++] = v;

		if (!BCH_GROUP_PARENT(g))
			break;

		v = BCH_GROUP_PARENT(g) - 1;
	}

	while (nr) {
		v = path[--nr];
		g = groups->entries + v;

		prt_printf(out, "%.*s", (int) sizeof(g->label), g->label);
		if (nr)
			prt_printf(out, ".");
	}
	return;
inval:
	prt_printf(out, "invalid label %u", v);
}

int __bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name)
{
	lockdep_assert_held(&c->sb_lock);


	if (!strlen(name) || !strcmp(name, "none")) {
		struct bch_member *mi = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
		SET_BCH_MEMBER_GROUP(mi, 0);
	} else {
		int v = bch2_disk_path_find_or_create(&c->disk_sb, name);
		if (v < 0)
			return v;

		struct bch_member *mi = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
		SET_BCH_MEMBER_GROUP(mi, v + 1);
	}

	return bch2_sb_disk_groups_to_cpu(c);
}

int bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name)
{
	int ret;

	mutex_lock(&c->sb_lock);
	ret = __bch2_dev_group_set(c, ca, name) ?:
		bch2_write_super(c);
	mutex_unlock(&c->sb_lock);

	return ret;
}

int bch2_opt_target_parse(struct bch_fs *c, const char *val, u64 *res,
			  struct printbuf *err)
{
	struct bch_dev *ca;
	int g;

	if (!val)
		return -EINVAL;

	if (!c)
		return -BCH_ERR_option_needs_open_fs;

	if (!strlen(val) || !strcmp(val, "none")) {
		*res = 0;
		return 0;
	}

	/* Is it a device? */
	ca = bch2_dev_lookup(c, val);
	if (!IS_ERR(ca)) {
		*res = dev_to_target(ca->dev_idx);
		bch2_dev_put(ca);
		return 0;
	}

	mutex_lock(&c->sb_lock);
	g = bch2_disk_path_find(&c->disk_sb, val);
	mutex_unlock(&c->sb_lock);

	if (g >= 0) {
		*res = group_to_target(g);
		return 0;
	}

	return -EINVAL;
}

void bch2_target_to_text(struct printbuf *out, struct bch_fs *c, unsigned v)
{
	struct target t = target_decode(v);

	switch (t.type) {
	case TARGET_NULL:
		prt_printf(out, "none");
		return;
	case TARGET_DEV: {
		out->atomic++;
		guard(rcu)();
		struct bch_dev *ca = t.dev < c->sb.nr_devices
			? rcu_dereference(c->devs[t.dev])
			: NULL;

		if (ca && ca->disk_sb.bdev)
			prt_printf(out, "/dev/%s", ca->name);
		else if (ca)
			prt_printf(out, "offline device %u", t.dev);
		else
			prt_printf(out, "invalid device %u", t.dev);

		out->atomic--;
		return;
	}
	case TARGET_GROUP:
		bch2_disk_path_to_text(out, c, t.group);
		return;
	default:
		BUG();
	}
}

static void bch2_target_to_text_sb(struct printbuf *out, struct bch_sb *sb, unsigned v)
{
	struct target t = target_decode(v);

	switch (t.type) {
	case TARGET_NULL:
		prt_printf(out, "none");
		break;
	case TARGET_DEV: {
		struct bch_member m = bch2_sb_member_get(sb, t.dev);

		if (bch2_member_exists(sb, t.dev)) {
			prt_printf(out, "Device ");
			pr_uuid(out, m.uuid.b);
			prt_printf(out, " (%u)", t.dev);
		} else {
			prt_printf(out, "Bad device %u", t.dev);
		}
		break;
	}
	case TARGET_GROUP:
		bch2_disk_path_to_text_sb(out, sb, t.group);
		break;
	default:
		BUG();
	}
}

void bch2_opt_target_to_text(struct printbuf *out,
			     struct bch_fs *c,
			     struct bch_sb *sb,
			     u64 v)
{
	if (c)
		bch2_target_to_text(out, c, v);
	else
		bch2_target_to_text_sb(out, sb, v);
}
