// 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,
					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;
}

void bch2_disk_groups_to_text(struct printbuf *out, struct bch_fs *c)
{
	struct bch_disk_groups_cpu *g;
	struct bch_dev *ca;
	int i;
	unsigned iter;

	out->atomic++;
	rcu_read_lock();

	g = rcu_dereference(c->disk_groups);
	if (!g)
		goto out;

	for (i = 0; i < g->nr; i++) {
		if (i)
			prt_printf(out, " ");

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

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

out:
	rcu_read_unlock();
	out->atomic--;
}

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_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_exists(&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);
	struct bch_devs_mask *devs;

	rcu_read_lock();

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

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

	rcu_read_unlock();

	return devs;
}

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;
		const struct bch_devs_mask *m;
		bool ret;

		rcu_read_lock();
		g = rcu_dereference(c->disk_groups);
		m = g && t.group < g->nr && !g->entries[t.group].deleted
			? &g->entries[t.group].devs
			: NULL;

		ret = m ? test_bit(dev, m->d) : false;
		rcu_read_unlock();

		return ret;
	}
	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;
}

void bch2_disk_path_to_text(struct printbuf *out, struct bch_fs *c, unsigned v)
{
	struct bch_disk_groups_cpu *groups;
	struct bch_disk_group_cpu *g;
	unsigned nr = 0;
	u16 path[32];

	out->atomic++;
	rcu_read_lock();
	groups = rcu_dereference(c->disk_groups);
	if (!groups)
		goto invalid;

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

		if (v >= groups->nr)
			goto invalid;

		g = groups->entries + v;

		if (g->deleted)
			goto invalid;

		path[nr++] = v;

		if (!g->parent)
			break;

		v = g->parent - 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, ".");
	}
out:
	rcu_read_unlock();
	out->atomic--;
	return;
invalid:
	prt_printf(out, "invalid label %u", v);
	goto out;
}

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)
{
	struct bch_member *mi;
	int ret, v = -1;

	if (!strlen(name) || !strcmp(name, "none"))
		return 0;

	v = bch2_disk_path_find_or_create(&c->disk_sb, name);
	if (v < 0)
		return v;

	ret = bch2_sb_disk_groups_to_cpu(c);
	if (ret)
		return ret;

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

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 0;

	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);
		percpu_ref_put(&ca->ref);
		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");
		break;
	case TARGET_DEV: {
		struct bch_dev *ca;

		out->atomic++;
		rcu_read_lock();
		ca = t.dev < c->sb.nr_devices
			? rcu_dereference(c->devs[t.dev])
			: NULL;

		if (ca && percpu_ref_tryget(&ca->io_ref)) {
			prt_printf(out, "/dev/%pg", ca->disk_sb.bdev);
			percpu_ref_put(&ca->io_ref);
		} else if (ca) {
			prt_printf(out, "offline device %u", t.dev);
		} else {
			prt_printf(out, "invalid device %u", t.dev);
		}

		rcu_read_unlock();
		out->atomic--;
		break;
	}
	case TARGET_GROUP:
		bch2_disk_path_to_text(out, c, t.group);
		break;
	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_dev_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);
}
