// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * RDMA Transport Layer
 *
 * Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved.
 * Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved.
 * Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved.
 */
#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt

#include "rtrs-pri.h"
#include "rtrs-srv.h"
#include "rtrs-log.h"

static void rtrs_srv_release(struct kobject *kobj)
{
	struct rtrs_srv_path *srv_path;

	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
	kfree(srv_path);
}

static struct kobj_type ktype = {
	.sysfs_ops	= &kobj_sysfs_ops,
	.release	= rtrs_srv_release,
};

static ssize_t rtrs_srv_disconnect_show(struct kobject *kobj,
					struct kobj_attribute *attr, char *buf)
{
	return sysfs_emit(buf, "Usage: echo 1 > %s\n", attr->attr.name);
}

static ssize_t rtrs_srv_disconnect_store(struct kobject *kobj,
					  struct kobj_attribute *attr,
					  const char *buf, size_t count)
{
	struct rtrs_srv_path *srv_path;
	struct rtrs_path *s;
	char str[MAXHOSTNAMELEN];

	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
	s = &srv_path->s;
	if (!sysfs_streq(buf, "1")) {
		rtrs_err(s, "%s: invalid value: '%s'\n",
			  attr->attr.name, buf);
		return -EINVAL;
	}

	sockaddr_to_str((struct sockaddr *)&srv_path->s.dst_addr, str,
			sizeof(str));

	rtrs_info(s, "disconnect for path %s requested\n", str);
	/* first remove sysfs itself to avoid deadlock */
	sysfs_remove_file_self(&srv_path->kobj, &attr->attr);
	close_path(srv_path);

	return count;
}

static struct kobj_attribute rtrs_srv_disconnect_attr =
	__ATTR(disconnect, 0644,
	       rtrs_srv_disconnect_show, rtrs_srv_disconnect_store);

static ssize_t rtrs_srv_hca_port_show(struct kobject *kobj,
				       struct kobj_attribute *attr,
				       char *page)
{
	struct rtrs_srv_path *srv_path;
	struct rtrs_con *usr_con;

	srv_path = container_of(kobj, typeof(*srv_path), kobj);
	usr_con = srv_path->s.con[0];

	return sysfs_emit(page, "%u\n", usr_con->cm_id->port_num);
}

static struct kobj_attribute rtrs_srv_hca_port_attr =
	__ATTR(hca_port, 0444, rtrs_srv_hca_port_show, NULL);

static ssize_t rtrs_srv_hca_name_show(struct kobject *kobj,
				       struct kobj_attribute *attr,
				       char *page)
{
	struct rtrs_srv_path *srv_path;

	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);

	return sysfs_emit(page, "%s\n", srv_path->s.dev->ib_dev->name);
}

static struct kobj_attribute rtrs_srv_hca_name_attr =
	__ATTR(hca_name, 0444, rtrs_srv_hca_name_show, NULL);

static ssize_t rtrs_srv_src_addr_show(struct kobject *kobj,
				       struct kobj_attribute *attr,
				       char *page)
{
	struct rtrs_srv_path *srv_path;
	int cnt;

	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
	cnt = sockaddr_to_str((struct sockaddr *)&srv_path->s.dst_addr,
			      page, PAGE_SIZE);
	return cnt + scnprintf(page + cnt, PAGE_SIZE - cnt, "\n");
}

static struct kobj_attribute rtrs_srv_src_addr_attr =
	__ATTR(src_addr, 0444, rtrs_srv_src_addr_show, NULL);

static ssize_t rtrs_srv_dst_addr_show(struct kobject *kobj,
				       struct kobj_attribute *attr,
				       char *page)
{
	struct rtrs_srv_path *srv_path;
	int len;

	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
	len = sockaddr_to_str((struct sockaddr *)&srv_path->s.src_addr, page,
			      PAGE_SIZE);
	len += sysfs_emit_at(page, len, "\n");
	return len;
}

static struct kobj_attribute rtrs_srv_dst_addr_attr =
	__ATTR(dst_addr, 0444, rtrs_srv_dst_addr_show, NULL);

static struct attribute *rtrs_srv_path_attrs[] = {
	&rtrs_srv_hca_name_attr.attr,
	&rtrs_srv_hca_port_attr.attr,
	&rtrs_srv_src_addr_attr.attr,
	&rtrs_srv_dst_addr_attr.attr,
	&rtrs_srv_disconnect_attr.attr,
	NULL,
};

static const struct attribute_group rtrs_srv_path_attr_group = {
	.attrs = rtrs_srv_path_attrs,
};

STAT_ATTR(struct rtrs_srv_stats, rdma,
	  rtrs_srv_stats_rdma_to_str,
	  rtrs_srv_reset_rdma_stats);

static struct attribute *rtrs_srv_stats_attrs[] = {
	&rdma_attr.attr,
	NULL,
};

static const struct attribute_group rtrs_srv_stats_attr_group = {
	.attrs = rtrs_srv_stats_attrs,
};

static int rtrs_srv_create_once_sysfs_root_folders(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv *srv = srv_path->srv;
	int err = 0;

	mutex_lock(&srv->paths_mutex);
	if (srv->dev_ref++) {
		/*
		 * Device needs to be registered only on the first session
		 */
		goto unlock;
	}
	srv->dev.class = rtrs_dev_class;
	err = dev_set_name(&srv->dev, "%s", srv_path->s.sessname);
	if (err)
		goto unlock;

	/*
	 * Suppress user space notification until
	 * sysfs files are created
	 */
	dev_set_uevent_suppress(&srv->dev, true);
	err = device_add(&srv->dev);
	if (err) {
		pr_err("device_add(): %d\n", err);
		put_device(&srv->dev);
		goto unlock;
	}
	srv->kobj_paths = kobject_create_and_add("paths", &srv->dev.kobj);
	if (!srv->kobj_paths) {
		err = -ENOMEM;
		pr_err("kobject_create_and_add(): %d\n", err);
		device_del(&srv->dev);
		put_device(&srv->dev);
		goto unlock;
	}
	dev_set_uevent_suppress(&srv->dev, false);
	kobject_uevent(&srv->dev.kobj, KOBJ_ADD);
unlock:
	mutex_unlock(&srv->paths_mutex);

	return err;
}

static void
rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv *srv = srv_path->srv;

	mutex_lock(&srv->paths_mutex);
	if (!--srv->dev_ref) {
		kobject_del(srv->kobj_paths);
		kobject_put(srv->kobj_paths);
		mutex_unlock(&srv->paths_mutex);
		device_del(&srv->dev);
		put_device(&srv->dev);
	} else {
		put_device(&srv->dev);
		mutex_unlock(&srv->paths_mutex);
	}
}

static void rtrs_srv_path_stats_release(struct kobject *kobj)
{
	struct rtrs_srv_stats *stats;

	stats = container_of(kobj, struct rtrs_srv_stats, kobj_stats);

	kfree(stats);
}

static struct kobj_type ktype_stats = {
	.sysfs_ops = &kobj_sysfs_ops,
	.release = rtrs_srv_path_stats_release,
};

static int rtrs_srv_create_stats_files(struct rtrs_srv_path *srv_path)
{
	int err;
	struct rtrs_path *s = &srv_path->s;

	err = kobject_init_and_add(&srv_path->stats->kobj_stats, &ktype_stats,
				   &srv_path->kobj, "stats");
	if (err) {
		rtrs_err(s, "kobject_init_and_add(): %d\n", err);
		kobject_put(&srv_path->stats->kobj_stats);
		return err;
	}
	err = sysfs_create_group(&srv_path->stats->kobj_stats,
				 &rtrs_srv_stats_attr_group);
	if (err) {
		rtrs_err(s, "sysfs_create_group(): %d\n", err);
		goto err;
	}

	return 0;

err:
	kobject_del(&srv_path->stats->kobj_stats);
	kobject_put(&srv_path->stats->kobj_stats);

	return err;
}

int rtrs_srv_create_path_files(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv *srv = srv_path->srv;
	struct rtrs_path *s = &srv_path->s;
	char str[NAME_MAX];
	int err;
	struct rtrs_addr path = {
		.src = &srv_path->s.dst_addr,
		.dst = &srv_path->s.src_addr,
	};

	rtrs_addr_to_str(&path, str, sizeof(str));
	err = rtrs_srv_create_once_sysfs_root_folders(srv_path);
	if (err)
		return err;

	err = kobject_init_and_add(&srv_path->kobj, &ktype, srv->kobj_paths,
				   "%s", str);
	if (err) {
		rtrs_err(s, "kobject_init_and_add(): %d\n", err);
		goto destroy_root;
	}
	err = sysfs_create_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
	if (err) {
		rtrs_err(s, "sysfs_create_group(): %d\n", err);
		goto put_kobj;
	}
	err = rtrs_srv_create_stats_files(srv_path);
	if (err)
		goto remove_group;

	return 0;

remove_group:
	sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
put_kobj:
	kobject_del(&srv_path->kobj);
destroy_root:
	kobject_put(&srv_path->kobj);
	rtrs_srv_destroy_once_sysfs_root_folders(srv_path);

	return err;
}

void rtrs_srv_destroy_path_files(struct rtrs_srv_path *srv_path)
{
	if (srv_path->kobj.state_in_sysfs) {
		kobject_del(&srv_path->stats->kobj_stats);
		kobject_put(&srv_path->stats->kobj_stats);
		sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
		kobject_put(&srv_path->kobj);

		rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
	}
}
