/*
 *  Copyright (C) 2002 - 2003 Ardis Technologies <roman@ardistech.com>
 *  Copyright (C) 2007 - 2018 Vladislav Bolkhovitin
 *  Copyright (C) 2007 - 2018 Western Digital Corporation
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation, version 2
 *  of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 */

#include <linux/delay.h>
#include <linux/module.h>

#include "iscsi_trace_flag.h"
#include "iscsi.h"
#include "digest.h"

#define MAX_NR_TARGETS		(1UL << 30)

DEFINE_MUTEX(target_mgmt_mutex);

/* All 3 protected by target_mgmt_mutex */
static LIST_HEAD(target_list);
static u32 next_target_id;
static u32 nr_targets;

/* target_mgmt_mutex supposed to be locked */
struct iscsi_target *target_lookup_by_id(u32 id)
{
	struct iscsi_target *target;

	lockdep_assert_held(&target_mgmt_mutex);

	list_for_each_entry(target, &target_list, target_list_entry) {
		if (target->tid == id)
			return target;
	}
	return NULL;
}

/* target_mgmt_mutex supposed to be locked */
static struct iscsi_target *target_lookup_by_name(const char *name)
{
	struct iscsi_target *target;

	lockdep_assert_held(&target_mgmt_mutex);

	list_for_each_entry(target, &target_list, target_list_entry) {
		if (!strcmp(target->name, name))
			return target;
	}
	return NULL;
}

/* target_mgmt_mutex supposed to be locked */
static int iscsi_target_create(struct iscsi_kern_target_info *info, u32 tid,
	struct iscsi_target **out_target)
{
	int err = -EINVAL, len;
	char *name = info->name;
	struct iscsi_target *target;

	TRACE_MGMT_DBG("Creating target tid %u, name %s", tid, name);

	lockdep_assert_held(&target_mgmt_mutex);

	len = strlen(name);
	if (!len) {
		PRINT_ERROR("The length of the target name is zero %u", tid);
		goto out;
	}

	if (!try_module_get(THIS_MODULE)) {
		PRINT_ERROR("Fail to get module %u", tid);
		goto out;
	}

	target = kzalloc(sizeof(*target), GFP_KERNEL);
	if (!target) {
		err = -ENOMEM;
		goto out_put;
	}

	target->tid = info->tid = tid;

	strlcpy(target->name, name, sizeof(target->name));

	mutex_init(&target->target_mutex);
	INIT_LIST_HEAD(&target->session_list);
	INIT_LIST_HEAD(&target->attrs_list);

	target->scst_tgt = scst_register_target(&iscsi_template, target->name);
	if (!target->scst_tgt) {
		PRINT_ERROR("%s", "scst_register_target() failed");
		err = -EBUSY;
		goto out_free;
	}

	scst_tgt_set_tgt_priv(target->scst_tgt, target);

	list_add_tail(&target->target_list_entry, &target_list);

	*out_target = target;

	return 0;

out_free:
	kfree(target);

out_put:
	module_put(THIS_MODULE);

out:
	return err;
}

/* target_mgmt_mutex supposed to be locked */
int __add_target(struct iscsi_kern_target_info *info)
{
	int err;
	u32 tid = info->tid;
	struct iscsi_target *target = NULL; /* to calm down sparse */
	union add_info_union {
		struct iscsi_kern_params_info params_info;
		struct iscsi_kern_attr attr_info;
	} *add_info;
	int i, rc;
	unsigned long attrs_ptr_long;
	struct iscsi_kern_attr __user *attrs_ptr;

	lockdep_assert_held(&target_mgmt_mutex);

	if (nr_targets > MAX_NR_TARGETS) {
		err = -EBUSY;
		goto out;
	}

	if (target_lookup_by_name(info->name)) {
		PRINT_ERROR("Target %s already exist!", info->name);
		err = -EEXIST;
		goto out;
	}

	if (tid && target_lookup_by_id(tid)) {
		PRINT_ERROR("Target %u already exist!", tid);
		err = -EEXIST;
		goto out;
	}

	add_info = kmalloc(sizeof(*add_info), GFP_KERNEL);
	if (add_info == NULL) {
		PRINT_ERROR("Unable to allocate additional info (size %zd)",
			sizeof(*add_info));
		err = -ENOMEM;
		goto out;
	}

	if (tid == 0) {
		do {
			if (!++next_target_id)
				++next_target_id;
		} while (target_lookup_by_id(next_target_id));

		tid = next_target_id;
	}

	err = iscsi_target_create(info, tid, &target);
	if (err != 0)
		goto out_free;

	nr_targets++;

	{
	struct iscsi_kern_attr *attr_info = &add_info->attr_info;

	mutex_lock(&target->target_mutex);

	attrs_ptr_long = info->attrs_ptr;
	attrs_ptr = (struct iscsi_kern_attr __user *)attrs_ptr_long;
	for (i = 0; i < info->attrs_num; i++) {
		memset(attr_info, 0, sizeof(*attr_info));

		rc = copy_from_user(attr_info, attrs_ptr, sizeof(*attr_info));
		if (rc != 0) {
			PRINT_ERROR("Failed to copy users of target %s failed",
				    info->name);
			err = -EFAULT;
			goto out_del_unlock;
		}

		attr_info->name[sizeof(attr_info->name)-1] = '\0';

		err = iscsi_add_attr(target, attr_info);
		if (err != 0)
			goto out_del_unlock;

		attrs_ptr++;
	}

	mutex_unlock(&target->target_mutex);
	}

	err = tid;

out_free:
	kfree(add_info);

out:
	return err;

out_del_unlock:
	mutex_unlock(&target->target_mutex);
	__del_target(tid);
	goto out_free;
}

static void target_destroy(struct iscsi_target *target)
{
	struct iscsi_attr *attr, *t;

	TRACE_MGMT_DBG("Destroying target tid %u", target->tid);

	list_for_each_entry_safe(attr, t, &target->attrs_list,
				attrs_list_entry) {
		__iscsi_del_attr(target, attr);
	}

	scst_unregister_target(target->scst_tgt);

	kfree(target);

	module_put(THIS_MODULE);
	return;
}

/* target_mgmt_mutex supposed to be locked */
int __del_target(u32 id)
{
	struct iscsi_target *target;
	int err;

	lockdep_assert_held(&target_mgmt_mutex);

	target = target_lookup_by_id(id);
	if (!target) {
		err = -ENOENT;
		goto out;
	}

	mutex_lock(&target->target_mutex);

	if (!list_empty(&target->session_list)) {
		err = -EBUSY;
		goto out_unlock;
	}

	list_del(&target->target_list_entry);
	nr_targets--;

	mutex_unlock(&target->target_mutex);

	target_destroy(target);
	return 0;

out_unlock:
	mutex_unlock(&target->target_mutex);

out:
	return err;
}

/* target_mutex supposed to be locked */
void target_del_session(struct iscsi_target *target,
	struct iscsi_session *session, int flags)
{
	TRACE_ENTRY();

	TRACE(TRACE_MGMT, "Deleting session %p (initiator %s)", session,
		session->scst_sess->initiator_name);

	lockdep_assert_held(&target->target_mutex);

	if (!list_empty(&session->conn_list)) {
		struct iscsi_conn *conn, *tc;

		list_for_each_entry_safe(conn, tc, &session->conn_list,
					 conn_list_entry) {
			TRACE_MGMT_DBG("Del session: closing conn %p", conn);
			__mark_conn_closed(conn, flags);
		}
	} else {
		TRACE_MGMT_DBG("Freeing session %p without connections",
			       session);
		__del_session(target, session->sid);
	}

	TRACE_EXIT();
	return;
}

/* target_mutex supposed to be locked */
void target_del_all_sess(struct iscsi_target *target, int flags)
{
	struct iscsi_session *session, *ts;

	TRACE_ENTRY();

	lockdep_assert_held(&target->target_mutex);

	if (!list_empty(&target->session_list)) {
		TRACE_MGMT_DBG("Deleting all sessions from target %p", target);
		list_for_each_entry_safe(session, ts, &target->session_list,
						session_list_entry) {
			target_del_session(target, session, flags);
		}
	}

	TRACE_EXIT();
	return;
}
EXPORT_SYMBOL(target_del_all_sess);

void target_del_all(void)
{
	struct iscsit_transport *transport;
	struct iscsi_target *target, *t;
	bool first = true;

	TRACE_ENTRY();

	TRACE_MGMT_DBG("%s", "Deleting all targets");

	transport = iscsit_get_transport(ISCSI_TCP);
	if (transport && transport->iscsit_close_all_portals)
		transport->iscsit_close_all_portals();

	transport = iscsit_get_transport(ISCSI_RDMA);
	if (transport && transport->iscsit_close_all_portals)
		transport->iscsit_close_all_portals();

	/* Not the best, ToDo */
	while (1) {
		mutex_lock(&target_mgmt_mutex);

		if (list_empty(&target_list))
			break;

		/*
		 * In the first iteration we won't delete targets to go at
		 * first through all sessions of all targets and close their
		 * connections. Otherwise we can stuck for noticeable time
		 * waiting during a target's unregistration for the activities
		 * suspending over active connection. This can especially got
		 * bad if any being wait connection itself stuck waiting for
		 * something and can be recovered only by connection close.
		 * Let's for such cases not wait while such connection recover
		 * theyself, but act in advance.
		 */

		list_for_each_entry_safe(target, t, &target_list,
					 target_list_entry) {
			mutex_lock(&target->target_mutex);

			if (!list_empty(&target->session_list)) {
				target_del_all_sess(target,
					ISCSI_CONN_ACTIVE_CLOSE |
					ISCSI_CONN_DELETING);
			} else if (!first) {
				TRACE_MGMT_DBG("Deleting target %p", target);
				list_del(&target->target_list_entry);
				nr_targets--;
				mutex_unlock(&target->target_mutex);
				target_destroy(target);
				continue;
			}

			mutex_unlock(&target->target_mutex);
		}
		mutex_unlock(&target_mgmt_mutex);
		msleep(100);

		first = false;
	}

	mutex_unlock(&target_mgmt_mutex);

	TRACE_MGMT_DBG("%s", "Deleting all targets finished");

	TRACE_EXIT();
	return;
}


static ssize_t iscsi_tgt_tid_show(struct kobject *kobj,
	struct kobj_attribute *attr, char *buf)
{
	int res = -E_TGT_PRIV_NOT_YET_SET;
	struct scst_tgt *scst_tgt;
	struct iscsi_target *tgt;

	TRACE_ENTRY();

	scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
	tgt = scst_tgt_get_tgt_priv(scst_tgt);
	if (!tgt)
		goto out;

	res = sprintf(buf, "%u\n", tgt->tid);

out:
	TRACE_EXIT_RES(res);
	return res;
}

static struct kobj_attribute iscsi_tgt_attr_tid =
	__ATTR(tid, S_IRUGO, iscsi_tgt_tid_show, NULL);

const struct attribute *iscsi_tgt_attrs[] = {
	&iscsi_tgt_attr_tid.attr,
	NULL,
};

ssize_t iscsi_sysfs_send_event(uint32_t tid, enum iscsi_kern_event_code code,
	const char *param1, const char *param2, void **data)
{
	int res;
	struct scst_sysfs_user_info *info;

	TRACE_ENTRY();

	if (ctr_open_state != ISCSI_CTR_OPEN_STATE_OPEN) {
		PRINT_ERROR("User space process is not connected. Is iscsi-scstd running?");
		res = -EPERM;
		goto out;
	}

	res = scst_sysfs_user_add_info(&info);
	if (res != 0)
		goto out;

	TRACE_DBG("Sending event %d (tid %d, param1 %s, param2 %s, cookie %d, info %p)",
		  code, tid, param1, param2, info->info_cookie, info);

	res = event_send(tid, 0, 0, info->info_cookie, code, param1, param2);
	if (res <= 0) {
		PRINT_ERROR("event_send() failed: %d", res);
		if (res == 0)
			res = -EFAULT;
		goto out_free;
	}

	/*
	 * It may wait 30 secs in blocking connect to an unreacheable
	 * iSNS server. It must be fixed, but not now. ToDo.
	 */
	res = scst_wait_info_completion(info, 31 * HZ);

	if (data != NULL)
		*data = info->data;

out_free:
	scst_sysfs_user_del_info(info);

out:
	TRACE_EXIT_RES(res);
	return res;
}

int iscsi_enable_target(struct scst_tgt *scst_tgt, bool enable)
{
	struct iscsi_target *tgt =
		(struct iscsi_target *)scst_tgt_get_tgt_priv(scst_tgt);
	int res;
	uint32_t type;

	TRACE_ENTRY();

	if (tgt == NULL) {
		res = -E_TGT_PRIV_NOT_YET_SET;
		goto out;
	}

	if (enable)
		type = E_ENABLE_TARGET;
	else
		type = E_DISABLE_TARGET;

	TRACE_DBG("%s target %d", enable ? "Enabling" : "Disabling", tgt->tid);

	res = iscsi_sysfs_send_event(tgt->tid, type, NULL, NULL, NULL);

out:
	TRACE_EXIT_RES(res);
	return res;
}

bool iscsi_is_target_enabled(struct scst_tgt *scst_tgt)
{
	struct iscsi_target *tgt =
		(struct iscsi_target *)scst_tgt_get_tgt_priv(scst_tgt);

	if (tgt != NULL)
		return tgt->tgt_enabled;
	else
		return false;
}

ssize_t iscsi_sysfs_add_target(const char *target_name, char *params)
{
	int res;

	TRACE_ENTRY();

	res = iscsi_sysfs_send_event(0, E_ADD_TARGET, target_name,
			params, NULL);
	if (res > 0) {
		/* It's tid */
		res = 0;
	}

	TRACE_EXIT_RES(res);
	return res;
}

ssize_t iscsi_sysfs_del_target(const char *target_name)
{
	int res = 0, tid;

	TRACE_ENTRY();

	/* We don't want to have tgt visible after the mutex unlock */
	{
		struct iscsi_target *tgt;

		mutex_lock(&target_mgmt_mutex);
		tgt = target_lookup_by_name(target_name);
		if (tgt == NULL) {
			PRINT_ERROR("Target %s not found", target_name);
			mutex_unlock(&target_mgmt_mutex);
			res = -ENOENT;
			goto out;
		}
		tid = tgt->tid;
		mutex_unlock(&target_mgmt_mutex);
	}

	TRACE_DBG("Deleting target %s (tid %d)", target_name, tid);

	res = iscsi_sysfs_send_event(tid, E_DEL_TARGET, NULL, NULL, NULL);

out:
	TRACE_EXIT_RES(res);
	return res;
}

ssize_t iscsi_sysfs_mgmt_cmd(char *cmd)
{
	int res;

	TRACE_ENTRY();

	TRACE_DBG("Sending mgmt cmd %s", cmd);

	res = iscsi_sysfs_send_event(0, E_MGMT_CMD, cmd, NULL, NULL);

	TRACE_EXIT_RES(res);
	return res;
}

static ssize_t iscsi_acg_sess_dedicated_threads_show(struct kobject *kobj,
	struct kobj_attribute *attr, char *buf)
{
	int pos;
	struct scst_acg *acg;
	bool dedicated;

	TRACE_ENTRY();

	acg = container_of(kobj, struct scst_acg, acg_kobj);
	dedicated = scst_get_acg_tgt_priv(acg) != NULL;

	pos = sprintf(buf, "%d\n%s", dedicated,
		dedicated ? SCST_SYSFS_KEY_MARK "\n" : "");

	TRACE_EXIT_RES(pos);
	return pos;
}

static ssize_t iscsi_acg_sess_dedicated_threads_store(struct kobject *kobj,
	struct kobj_attribute *attr, const char *buf, size_t count)
{
	int res;
	struct scst_acg *acg;
	unsigned long val;

	TRACE_ENTRY();

	acg = container_of(kobj, struct scst_acg, acg_kobj);

	res = kstrtoul(buf, 0, &val);
	if (res != 0) {
		PRINT_ERROR("kstrtoul() for %s failed: %d ", buf, res);
		goto out;
	}

	scst_set_acg_tgt_priv(acg, (void *)(unsigned long)(val != 0));

	res = count;

out:
	TRACE_EXIT_RES(res);
	return res;
}

static struct kobj_attribute iscsi_acg_attr_sess_dedicated_threads =
	__ATTR(per_sess_dedicated_tgt_threads, S_IRUGO | S_IWUSR,
		iscsi_acg_sess_dedicated_threads_show,
		iscsi_acg_sess_dedicated_threads_store);

const struct attribute *iscsi_acg_attrs[] = {
	&iscsi_acg_attr_sess_dedicated_threads.attr,
	NULL,
};
