/*
 *  scst_event.c
 *
 *  Copyright (C) 2014 - 2018 Western Digital Corporation
 *
 */

#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/eventpoll.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/module.h>
#ifndef INSIDE_KERNEL_TREE
#include <linux/version.h>
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
#include <linux/sched/signal.h>
#endif

#ifdef INSIDE_KERNEL_TREE
#include <scst/scst.h>
#include <scst/scst_event.h>
#else
#include "scst.h"
#include "scst_event.h"
#endif

#include "scst_priv.h"

static struct class *scst_event_sysfs_class;

static int scst_event_major;

#define SCST_MAX_EVENTS			2048
#define SCST_MAX_PAYLOAD		(3*1024)
#define SCST_DEFAULT_EVENT_TIMEOUT	(60*HZ)

struct scst_event_priv {
	struct list_head privs_list_entry;
	int allowed_events_cnt;
	int queued_events_cnt;
	unsigned int going_to_exit:1;
	unsigned int blocking:1;
	pid_t owner_pid;
	/*
	 * WARNING: payloads in events in the allowed list queued AS IS from the
	 * user space, so they are UNTRUSTED and can NOT be used in any other
	 * way, except as BLOBs for comparison!
	 */
	struct list_head allowed_events_list;
	struct list_head queued_events_list;
	wait_queue_head_t queued_events_waitQ;
	struct list_head processing_events_list;
};

static DEFINE_MUTEX(scst_event_mutex);
static LIST_HEAD(scst_event_privs_list);

/*
 * Compares events e1_wild and e2, where e1_wild can have wildcard matching,
 * i.e.:
 *   - event_code 0 - any event code
 *   - issuer_name "*" - any issuer name
 *   - payload_len 0 - any payload
 */
static bool scst_event_cmp(const struct scst_event *e1_wild,
	const struct scst_event *e2)
{
	int res = false;

	TRACE_ENTRY();

	if ((e1_wild->event_code != e2->event_code) &&
	    (e1_wild->event_code != 0))
		goto out;

	if ((strcmp(e1_wild->issuer_name, e2->issuer_name) != 0) &&
	    (strcmp(e1_wild->issuer_name, "*") != 0))
		goto out;

	if (e1_wild->payload_len == 0)
		goto out_true;

	if ((e1_wild->payload_len != e2->payload_len) ||
	    (memcmp(e1_wild->payload, e2->payload, e1_wild->payload_len) != 0))
		goto out;

out_true:
	res = true;

out:
	TRACE_EXIT_RES(res);
	return res;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
static void scst_event_timeout_fn(void *p)
{
	struct scst_event_entry *event_entry = p;
#else
static void scst_event_timeout_fn(struct work_struct *work)
{
	struct scst_event_entry *event_entry = container_of(work,
		struct scst_event_entry, event_timeout_work.work);
#endif

	TRACE_ENTRY();

	TRACE_MGMT_DBG("Timeout of event %d (issuer %s, id %u, entry %p)",
		event_entry->event.event_code, event_entry->event.issuer_name,
		event_entry->event.event_id, event_entry);

	mutex_lock(&scst_event_mutex);

	if (list_empty(&event_entry->events_list_entry)) {
		/* It's done already and about to be freed */
		mutex_unlock(&scst_event_mutex);
		goto out;
	}
	list_del_init(&event_entry->events_list_entry);

	(*event_entry->pqueued_events_cnt)--;

	mutex_unlock(&scst_event_mutex);

	TRACE_DBG("Calling notify_fn of event_entry %p", event_entry);
	event_entry->event_notify_fn(&event_entry->event,
		 event_entry->notify_fn_priv, -ETIMEDOUT);

	TRACE_MEM("Freeing event entry %p", event_entry);
	kfree(event_entry);

out:
	TRACE_EXIT();
	return;
}

static int scst_clone_event(const struct scst_event_entry *orig_entry,
	struct scst_event_entry **new_event_entry)
{
	int res = 0;
	const struct scst_event *event = &orig_entry->event;
	struct scst_event_entry *event_entry;
	int event_entry_len = sizeof(*event_entry) + event->payload_len;

	TRACE_ENTRY();

	event_entry = kzalloc(event_entry_len, GFP_KERNEL);
	if (event_entry == NULL) {
		PRINT_ERROR("Unable to clone event entry (size %d, event %d, "
			"issuer %s", event_entry_len, event->event_code,
			event->issuer_name);
		res = -ENOMEM;
		goto out;
	}

	TRACE_MEM("event_entry %p (len %d) allocated", event_entry, event_entry_len);

	memcpy(&event_entry->event, event, sizeof(*event) + event->payload_len);

	WARN_ON(orig_entry->event_notify_fn != NULL);

	*new_event_entry = event_entry;

out:
	TRACE_EXIT_RES(res);
	return res;
}

static void __scst_event_queue(struct scst_event_entry *event_entry)
{
	const struct scst_event *event = &event_entry->event;
	struct scst_event_priv *priv;
	struct scst_event_entry *allowed_entry;
	bool queued = false;
	int rc = 0;
	static atomic_t base_event_id = ATOMIC_INIT(0);

	TRACE_ENTRY();

	mutex_lock(&scst_event_mutex);

	list_for_each_entry(priv, &scst_event_privs_list, privs_list_entry) {
		list_for_each_entry(allowed_entry, &priv->allowed_events_list,
				events_list_entry) {
			if (scst_event_cmp(&allowed_entry->event, event)) {
				struct scst_event_entry *new_event_entry;

				if (priv->queued_events_cnt >= SCST_MAX_EVENTS) {
					PRINT_ERROR("Too many queued events %d, "
						"event %d, issuer %s is lost.",
						priv->queued_events_cnt,
						event->event_code,
						event->issuer_name);
					rc = -EMFILE;
					break;
				}

				if (!queued)
					new_event_entry = event_entry;
				else if (event_entry->event_notify_fn == NULL) {
					rc = scst_clone_event(event_entry, &new_event_entry);
					if (rc != 0)
						goto done;
				} else {
					PRINT_WARNING("Event %d can be queued only once, "
						"dublicated receiver pid %d will miss it!",
						event->event_code, priv->owner_pid);
					break;
				}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
				INIT_WORK(&new_event_entry->event_timeout_work,
					  scst_event_timeout_fn,
					  new_event_entry);
#else
				INIT_DELAYED_WORK(&new_event_entry->event_timeout_work,
						  scst_event_timeout_fn);
#endif
				if (new_event_entry->event_notify_fn != NULL) {
					new_event_entry->event.event_id = atomic_inc_return(&base_event_id);
					if (new_event_entry->event_timeout == 0)
						new_event_entry->event_timeout = SCST_DEFAULT_EVENT_TIMEOUT;
					schedule_delayed_work(&new_event_entry->event_timeout_work,
						new_event_entry->event_timeout);
				}

				list_add_tail(&new_event_entry->events_list_entry,
					&priv->queued_events_list);
				priv->queued_events_cnt++;
				new_event_entry->pqueued_events_cnt = &priv->queued_events_cnt;
				queued = true;

				TRACE_DBG("event %d queued (issuer %s, id %u, "
					"entry %p)", new_event_entry->event.event_code,
					new_event_entry->event.issuer_name,
					new_event_entry->event.event_id, new_event_entry);

				wake_up_all(&priv->queued_events_waitQ);
				break;
			}
		}
	}
done:
	mutex_unlock(&scst_event_mutex);

	if (!queued) {
		if (event_entry->event_notify_fn != NULL) {
			if (rc == 0)
				rc = -ENOENT;
			TRACE_DBG("Calling notify_fn of event_entry %p (rc %d)",
				event_entry, rc);
			event_entry->event_notify_fn(&event_entry->event,
				event_entry->notify_fn_priv, rc);
		}

		TRACE_MEM("Freeing orphan event entry %p", event_entry);
		kfree(event_entry);
	}

	TRACE_EXIT();
	return;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
static void scst_event_queue_work_fn(void *p)
{
	struct scst_event_entry *e = p;
#else
static void scst_event_queue_work_fn(struct work_struct *work)
{
	struct scst_event_entry *e = container_of(work,
		struct scst_event_entry, scst_event_queue_work);
#endif

	TRACE_ENTRY();

	__scst_event_queue(e);

	TRACE_EXIT();
	return;
}

/* Can be called on IRQ with any lock held */
void scst_event_queue(uint32_t event_code, const char *issuer_name,
	struct scst_event_entry *e)
{
	TRACE_ENTRY();

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
	INIT_WORK(&e->scst_event_queue_work, scst_event_queue_work_fn, e);
#else
	INIT_WORK(&e->scst_event_queue_work, scst_event_queue_work_fn);
#endif

	TRACE_DBG("Scheduling event entry %p", e);

	e->event.event_code = event_code;
	strlcpy(e->event.issuer_name, issuer_name, sizeof(e->event.issuer_name));

	schedule_work(&e->scst_event_queue_work);

	TRACE_EXIT();
	return;
}
EXPORT_SYMBOL_GPL(scst_event_queue);

/* Might be called on IRQ with any lock held */
int scst_event_queue_lun_not_found(const struct scst_cmd *cmd)
{
	int res = 0, event_entry_len;
	struct scst_event_entry *event_entry;
	struct scst_event *event;
	struct scst_event_lun_not_found_payload *payload;

	TRACE_ENTRY();

	event_entry_len = sizeof(*event_entry) + sizeof(*payload);
	event_entry = kzalloc(event_entry_len, GFP_ATOMIC);
	if (event_entry == NULL) {
		PRINT_ERROR("Unable to allocate event (size %d). LUN not found "
			"event is lost (LUN %lld, initiator %s, target %s)!",
			event_entry_len, (unsigned long long)cmd->lun,
			cmd->sess->initiator_name, cmd->tgt->tgt_name);
		res = -ENOMEM;
		goto out;
	}

	TRACE_MEM("event_entry %p (len %d) allocated", event_entry,
		event_entry_len);

	event = &event_entry->event;

	event->payload_len = sizeof(*payload);
	payload = (struct scst_event_lun_not_found_payload *)event->payload;

	payload->lun = cmd->lun;
	strlcpy(payload->initiator_name, cmd->sess->initiator_name,
		sizeof(payload->initiator_name));
	strlcpy(payload->target_name, cmd->tgt->tgt_name,
		sizeof(payload->target_name));

	scst_event_queue(SCST_EVENT_LUN_NOT_FOUND,
		SCST_EVENT_SCST_CORE_ISSUER, event_entry);

out:
	TRACE_EXIT_RES(res);
	return res;
}

int scst_event_queue_negative_luns_inquiry(const struct scst_tgt *tgt,
	const char *initiator_name)
{
	int res = 0, event_entry_len;
	struct scst_event_entry *event_entry;
	struct scst_event *event;
	struct scst_event_negative_luns_inquiry_payload *payload;

	TRACE_ENTRY();

	event_entry_len = sizeof(*event_entry) + sizeof(*payload);
	event_entry = kzalloc(event_entry_len, GFP_ATOMIC);
	if (event_entry == NULL) {
		PRINT_ERROR("Unable to allocate event (size %d). NEGATIVE LUNS "
			"INQUIRY event is lost (initiator %s, target %s)!",
			event_entry_len, initiator_name, tgt->tgt_name);
		res = -ENOMEM;
		goto out;
	}

	TRACE_MEM("event_entry %p (len %d) allocated", event_entry,
		event_entry_len);

	event = &event_entry->event;

	event->payload_len = sizeof(*payload);
	payload = (struct scst_event_negative_luns_inquiry_payload *)event->payload;

	strlcpy(payload->initiator_name, initiator_name,
		sizeof(payload->initiator_name));
	strlcpy(payload->target_name, tgt->tgt_name,
		sizeof(payload->target_name));

	scst_event_queue(SCST_EVENT_NEGATIVE_LUNS_INQUIRY,
		SCST_EVENT_SCST_CORE_ISSUER, event_entry);

out:
	TRACE_EXIT_RES(res);
	return res;
}

/* No locks */
int scst_event_queue_ext_blocking_done(struct scst_device *dev, void *data, int len)
{
	int res, event_entry_len;
	struct scst_event_entry *event_entry;
	struct scst_event *event;
	struct scst_event_ext_blocking_done_payload *payload;

	TRACE_ENTRY();

	event_entry_len = sizeof(*event_entry) + sizeof(*payload) + len;
	event_entry = kzalloc(event_entry_len, GFP_ATOMIC);
	if (event_entry == NULL) {
		PRINT_CRIT_ERROR("Unable to allocate event. Ext blocking "
			"done event is lost (device %s, size %zd)!", dev->virt_name,
			sizeof(*event_entry) + sizeof(*payload) + len);
		res = -ENOMEM;
		goto out;
	}

	TRACE_MEM("event_entry %p (len %d) allocated", event_entry,
		event_entry_len);

	event = &event_entry->event;

	event->payload_len = sizeof(*payload) + len;
	payload = (struct scst_event_ext_blocking_done_payload *)event->payload;

	strlcpy(payload->device_name, dev->virt_name, sizeof(payload->device_name));
	if (len > 0)
		memcpy(payload->data, data, len);

	scst_event_queue(SCST_EVENT_EXT_BLOCKING_DONE,
		SCST_EVENT_SCST_CORE_ISSUER, event_entry);
	res = 0;

out:
	TRACE_EXIT_RES(res);
	return res;
}

/* No locks */
int scst_event_queue_tm_fn_received(struct scst_mgmt_cmd *mcmd)
{
	int res = 0, event_entry_len;
	struct scst_event_entry *event_entry;
	struct scst_event *event;
	struct scst_event_tm_fn_received_payload *payload;

	TRACE_ENTRY();

	event_entry_len = sizeof(*event_entry) + sizeof(*payload);
	event_entry = kzalloc(event_entry_len, GFP_KERNEL);
	if (event_entry == NULL) {
		PRINT_CRIT_ERROR("Unable to allocate event (size %d). External "
			"TM fn received event is lost!", event_entry_len);
		res = -ENOMEM;
		goto out;
	}

	TRACE_MEM("event_entry %p (len %d) allocated", event_entry,
		event_entry_len);

	event = &event_entry->event;

	event->payload_len = sizeof(*payload);
	payload = (struct scst_event_tm_fn_received_payload *)event->payload;

	payload->fn = mcmd->fn;
	payload->lun = mcmd->lun;
	if (mcmd->mcmd_tgt_dev != NULL)
		strlcpy(payload->device_name, mcmd->mcmd_tgt_dev->dev->virt_name,
			sizeof(payload->device_name));
	strlcpy(payload->initiator_name, mcmd->sess->initiator_name,
		sizeof(payload->initiator_name));
	strlcpy(payload->target_name, mcmd->sess->tgt->tgt_name,
		sizeof(payload->target_name));
	strlcpy(payload->session_sysfs_name, mcmd->sess->sess_name,
		sizeof(payload->session_sysfs_name));
	if (mcmd->cmd_to_abort != NULL) {
		payload->cmd_to_abort_tag = mcmd->cmd_to_abort->tag;
		memcpy(payload->cdb, mcmd->cmd_to_abort->cdb,
		       min_t(u32, mcmd->cmd_to_abort->cdb_len,
			     sizeof(payload->cdb)));
	}

	scst_event_queue(SCST_EVENT_TM_FN_RECEIVED,
		SCST_EVENT_SCST_CORE_ISSUER, event_entry);

out:
	TRACE_EXIT_RES(res);
	return res;
}

/* No locks */
int scst_event_queue_reg_vdev(const char *dev_name)
{
	int res = 0, event_entry_len;
	struct scst_event_entry *event_entry;
	struct scst_event *event;
	struct scst_event_reg_vdev_payload *payload;

	TRACE_ENTRY();

	event_entry_len = sizeof(*event_entry) + sizeof(*payload);
	event_entry = kzalloc(event_entry_len, GFP_ATOMIC);
	if (event_entry == NULL) {
		PRINT_ERROR("Unable to allocate event (size %d). Virtual "
			"device registration event is lost (device name %s)!",
			event_entry_len, dev_name);
		res = -ENOMEM;
		goto out;
	}

	TRACE_MEM("event_entry %p (len %d) allocated", event_entry,
		event_entry_len);

	event = &event_entry->event;

	event->payload_len = sizeof(*payload);
	payload = (struct scst_event_reg_vdev_payload *)event->payload;

	strlcpy(payload->device_name, dev_name,
		sizeof(payload->device_name));

	scst_event_queue(SCST_EVENT_REG_VIRT_DEV,
		SCST_EVENT_SCST_CORE_ISSUER, event_entry);

out:
	TRACE_EXIT_RES(res);
	return res;
}

/* scst_event_mutex supposed to be held. Can release/reacquire it inside */
static void scst_release_event_entry(struct scst_event_entry *e)
{
	TRACE_ENTRY();

	TRACE_DBG("Deleting event entry %p", e);
	list_del(&e->events_list_entry);

	if (e->event_notify_fn != NULL) {
		mutex_unlock(&scst_event_mutex);

		cancel_delayed_work_sync(&e->event_timeout_work);

		TRACE_DBG("Calling notify_fn of event_entry %p", e);
		e->event_notify_fn(&e->event, e->notify_fn_priv, -EFAULT);

		mutex_lock(&scst_event_mutex);
	}

	TRACE_MEM("Freeing notified event entry %p", e);
	kfree(e);

	TRACE_EXIT();
	return;
}

static int scst_event_release(struct inode *inode, struct file *file)
{
	struct scst_event_priv *priv;
	struct scst_event_entry *e, *et;

	TRACE_ENTRY();

	mutex_lock(&scst_event_mutex);

	priv = file->private_data;
	if (priv == NULL) {
		mutex_unlock(&scst_event_mutex);
		goto out;
	}
	file->private_data = NULL;

	list_del(&priv->privs_list_entry);

	mutex_unlock(&scst_event_mutex);

	TRACE_DBG("Going to release event priv %p", priv);

	priv->going_to_exit = 1;
	wake_up_all(&priv->queued_events_waitQ);

	list_for_each_entry_safe(e, et, &priv->allowed_events_list,
					events_list_entry) {
		TRACE_MEM("Deleting allowed event entry %p", e);
		list_del(&e->events_list_entry);
		kfree(e);
	}

	mutex_lock(&scst_event_mutex); /* to sync with timeout_work */
	while (!list_empty(&priv->queued_events_list)) {
		e = list_entry(priv->queued_events_list.next,
				typeof(*e), events_list_entry);
		scst_release_event_entry(e);
	}
	while (!list_empty(&priv->processing_events_list)) {
		e = list_entry(priv->processing_events_list.next,
				typeof(*e), events_list_entry);
		scst_release_event_entry(e);
	}
	mutex_unlock(&scst_event_mutex);

	TRACE_MEM("Deleting priv %p", priv);
	kfree(priv);

	module_put(THIS_MODULE);

out:
	TRACE_EXIT();
	return 0;
}

/*
 * scst_event_mutex supposed to be held. Caller supposed to free returned
 * out_event_entry using kfree(). This function returns event_entry, not
 * plain event, because this entry can then be queued in some list.
 */
static int scst_event_get_event_from_user(struct scst_event_user __user *arg,
	struct scst_event_entry **out_event_entry)
{
	int res, rc, event_entry_len;
	uint32_t payload_len;
	struct scst_event_entry *event_entry;

	TRACE_ENTRY();

	res = get_user(payload_len, &arg->max_event_size);
	if (res != 0) {
		PRINT_ERROR("Failed to get payload len: %d", res);
		goto out;
	}

	if (payload_len > SCST_MAX_PAYLOAD) {
		PRINT_ERROR("Payload len %d is too big (max %d)", payload_len,
			SCST_MAX_PAYLOAD);
		res = -EINVAL;
		goto out;
	}

	TRACE_DBG("payload_len %d", payload_len);

	event_entry_len = sizeof(*event_entry) + payload_len;

	event_entry = kzalloc(event_entry_len, GFP_KERNEL);
	if (event_entry == NULL) {
		PRINT_ERROR("Unable to allocate event entry (size %d)",
			event_entry_len);
		res = -ENOMEM;
		goto out;
	}

	TRACE_MEM("Allocated event entry %p", event_entry);

	rc = copy_from_user((u8 *)event_entry +
			    offsetof(typeof(*event_entry), event), arg,
			    event_entry_len);
	if (rc != 0) {
		PRINT_ERROR("Failed to copy %d user's bytes", rc);
		res = -EFAULT;
		goto out_free;
	}

	/* payload_len has been recopied, so recheck it. */
	if (event_entry->event.payload_len != event_entry_len) {
		PRINT_ERROR("Payload len changed while being read");
		res = -EINVAL;
		goto out_free;
	}

	event_entry->event.issuer_name[sizeof(event_entry->event.issuer_name)-1] = '\0';

	TRACE_DBG("user event: event_code %d, issuer_name %s",
		event_entry->event.event_code, event_entry->event.issuer_name);

	*out_event_entry = event_entry;

out:
	TRACE_EXIT_RES(res);
	return res;

out_free:
	TRACE_MEM("Deleting event entry %p", event_entry);
	kfree(event_entry);
	goto out;
}

/* scst_event_mutex supposed to be held */
static int scst_event_allow_event(struct scst_event_priv *priv, void __user *arg)
{
	int res;
	struct scst_event_entry *event_entry, *e;

	TRACE_ENTRY();

	res = scst_event_get_event_from_user(arg, &event_entry);
	if (res != 0)
		goto out;

	list_for_each_entry(e, &priv->allowed_events_list, events_list_entry) {
		if (scst_event_cmp(&event_entry->event, &e->event)) {
			PRINT_WARNING("Allowed event (event_code %d, "
				"issuer_name %s) already exists",
				e->event.event_code, e->event.issuer_name);
			res = -EEXIST;
			goto out_free;
		}
	}

	if (priv->allowed_events_cnt >= SCST_MAX_EVENTS) {
		PRINT_ERROR("Too many allowed events %d",
			priv->allowed_events_cnt);
		res = -EMFILE;
		goto out_free;
	}

	list_add_tail(&event_entry->events_list_entry,
		&priv->allowed_events_list);
	priv->allowed_events_cnt++;
	res = 0;

out:
	TRACE_EXIT_RES(res);
	return res;

out_free:
	TRACE_MEM("Deleting event entry %p", event_entry);
	kfree(event_entry);
	goto out;
}

/* scst_event_mutex supposed to be held */
static int scst_event_disallow_event(struct scst_event_priv *priv,
	void __user *arg)
{
	int res;
	struct scst_event_entry *event_entry, *e, *et;
	bool found = false;

	TRACE_ENTRY();

	res = scst_event_get_event_from_user(arg, &event_entry);
	if (res != 0)
		goto out;

	/* For wildcard events we might delete several events */
	list_for_each_entry_safe(e, et, &priv->allowed_events_list,
					events_list_entry) {
		if (scst_event_cmp(&event_entry->event, &e->event)) {
			PRINT_INFO("Deleting allowed event (event_code %d, "
				"issuer_name %s)", e->event.event_code,
				e->event.issuer_name);
			TRACE_MEM("Deleting event entry %p", e);
			list_del(&e->events_list_entry);
			kfree(e);
			priv->allowed_events_cnt--;
			found = true;
		}
	}
	if (!found) {
		PRINT_WARNING("Allowed event (event_code %d, issuer_name %s) "
			"not found", event_entry->event.event_code,
			event_entry->event.issuer_name);
		res = -ENOENT;
	} else
		res = 0;

	TRACE_MEM("Deleting event entry %p", e);
	kfree(event_entry);

out:
	TRACE_EXIT_RES(res);
	return res;
}

/* scst_event_mutex supposed to be held. Might drop it, then get back. */
static int scst_event_user_next_event(struct scst_event_priv *priv,
	void __user *arg)
{
	int res, rc;
	int32_t max_event_size, needed_size;
	struct scst_event_entry *event_entry;
	struct scst_event_user __user *event_user = arg;

	TRACE_ENTRY();

	res = get_user(max_event_size, (int32_t __user *)arg);
	if (res != 0) {
		PRINT_ERROR("Failed to get max event size: %d", res);
		goto out;
	};

	/* Waiting for at least one event, if blocking */
	while (list_empty(&priv->queued_events_list)) {
		mutex_unlock(&scst_event_mutex);
		wait_event_interruptible(priv->queued_events_waitQ,
			(!list_empty(&priv->queued_events_list) || priv->going_to_exit ||
			 !priv->blocking || signal_pending(current)));
		mutex_lock(&scst_event_mutex);
		if (priv->going_to_exit || signal_pending(current)) {
			res = -EINTR;
			TRACE_DBG("Signal pending or going_to_exit (%d), returning",
				priv->going_to_exit);
			goto out;
		} else if (list_empty(&priv->queued_events_list) && !priv->blocking) {
			res = -EAGAIN;
			TRACE_DBG("Nothing pending, returning %d", res);
			goto out;
		}
	}

	EXTRACHECKS_BUG_ON(list_empty(&priv->queued_events_list));

	event_entry = list_entry(priv->queued_events_list.next,
			struct scst_event_entry, events_list_entry);

	needed_size = sizeof(event_entry->event) + event_entry->event.payload_len;

	if (needed_size > max_event_size) {
		TRACE_DBG("Too big event (size %d, max size %d)", needed_size,
			max_event_size);
		res = put_user(needed_size, (int32_t __user *)arg);
		if (res == 0)
			res = -ENOSPC;
		goto out;
	}

	rc = copy_to_user(&event_user->out_event, &event_entry->event, needed_size);
	if (rc != 0) {
		PRINT_ERROR("Copy to user failed (%d)", rc);
		res = -EFAULT;
		goto out;
	}

	if (event_entry->event_notify_fn) {
		TRACE_DBG("Moving event entry %p to processing events list",
			event_entry);
		list_move_tail(&event_entry->events_list_entry,
			&priv->processing_events_list);
	} else {
		TRACE_MEM("Deleting event entry %p", event_entry);
		list_del(&event_entry->events_list_entry);
		kfree(event_entry);
	}

	priv->queued_events_cnt--;

	res = 0;

out:
	TRACE_EXIT_RES(res);
	return res;
}

/* scst_event_mutex supposed to be held. Might drop it, then get back. */
static int scst_event_user_notify_done(struct scst_event_priv *priv,
	void __user *arg)
{
	int res, rc;
	struct scst_event_notify_done n;
	struct scst_event_entry *e;
	bool found = false;

	TRACE_ENTRY();

	rc = copy_from_user(&n, arg, sizeof(n));
	if (rc != 0) {
		PRINT_ERROR("Failed to copy %d user's bytes of notify done", rc);
		res = -EFAULT;
		goto out;
	}

	res = 0;

	list_for_each_entry(e, &priv->processing_events_list, events_list_entry) {
		if (e->event.event_id == n.event_id) {
			found = true;
			break;
		}
	}
	if (!found) {
		PRINT_ERROR("Waiting event for id %u not found", n.event_id);
		res = -ENOENT;
		goto out;
	}

	list_del_init(&e->events_list_entry);

	mutex_unlock(&scst_event_mutex);

	cancel_delayed_work_sync(&e->event_timeout_work);

	if (e->event_notify_fn != NULL) {
		TRACE_DBG("Calling notify_fn of event_entry %p", e);
		e->event_notify_fn(&e->event, e->notify_fn_priv, n.status);
	}

	TRACE_MEM("Freeing event entry %p", e);
	kfree(e);

	/* Lock it back, because we expected to do so */
	mutex_lock(&scst_event_mutex);

out:
	TRACE_EXIT_RES(res);
	return res;
}

/* scst_event_mutex supposed to be held */
static int scst_event_create_priv(struct file *file)
{
	int res;
	struct scst_event_priv *priv;

	TRACE_ENTRY();

	EXTRACHECKS_BUG_ON(file->private_data != NULL);

	if (!try_module_get(THIS_MODULE)) {
		PRINT_ERROR("Fail to get module");
		res = -ETXTBSY;
		goto out;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (priv == NULL) {
		PRINT_ERROR("Unable to allocate priv (size %zd)",
			sizeof(*priv));
		res = -ENOMEM;
		goto out_put;
	}

	TRACE_MEM("priv %p allocated", priv);

	priv->owner_pid = current->pid;
	INIT_LIST_HEAD(&priv->allowed_events_list);
	init_waitqueue_head(&priv->queued_events_waitQ);
	INIT_LIST_HEAD(&priv->queued_events_list);
	INIT_LIST_HEAD(&priv->processing_events_list);
	if (file->f_flags & O_NONBLOCK) {
		TRACE_DBG("%s", "Non-blocking operations");
		priv->blocking = 0;
	} else
		priv->blocking = 1;

	list_add_tail(&priv->privs_list_entry, &scst_event_privs_list);

	file->private_data = priv;

	res = 0;

out:
	TRACE_EXIT_RES(res);
	return res;

out_put:
	module_put(THIS_MODULE);
	goto out;
}

static long scst_event_ioctl(struct file *file, unsigned int cmd,
	unsigned long arg)
{
	long res;
	struct scst_event_priv *priv;

	TRACE_ENTRY();

	mutex_lock(&scst_event_mutex);

	priv = file->private_data;
	if (unlikely(priv == NULL)) {
		/* This is the first time we are here */
		res = scst_event_create_priv(file);
		if (res != 0)
			goto out_unlock;
		priv = file->private_data;
	}

	TRACE_DBG("priv %p", priv);

	/*
	 * Handler functions called under scst_event_mutex for their
	 * convenience only, because they would need to reacquire it back again
	 * anyway. It has nothing common with protecting private_data, which
	 * protected from release() by the file reference counting.
	 */

	switch (cmd) {
	case SCST_EVENT_ALLOW_EVENT:
		TRACE_DBG("%s", "ALLOW_EVENT");
		res = scst_event_allow_event(priv, (void __user *)arg);
		break;

	case SCST_EVENT_DISALLOW_EVENT:
		TRACE_DBG("%s", "DISALLOW_EVENT");
		res = scst_event_disallow_event(priv, (void __user *)arg);
		break;

	case SCST_EVENT_GET_NEXT_EVENT:
		TRACE_DBG("%s", "GET_NEXT_EVENT");
		res = scst_event_user_next_event(priv, (void __user *)arg);
		break;

	case SCST_EVENT_NOTIFY_DONE:
		TRACE_DBG("%s", "NOTIFY_DONE");
		res = scst_event_user_notify_done(priv, (void __user *)arg);
		break;

	default:
		PRINT_ERROR("Invalid ioctl cmd %x", cmd);
		res = -EINVAL;
		goto out_unlock;
	}

out_unlock:
	mutex_unlock(&scst_event_mutex);

	TRACE_EXIT_RES(res);
	return res;
}

static __poll_t scst_event_poll(struct file *file, poll_table *wait)
{
	__poll_t res = 0;
	struct scst_event_priv *priv;

	TRACE_ENTRY();

	mutex_lock(&scst_event_mutex);

	priv = file->private_data;
	if (unlikely(priv == NULL)) {
		PRINT_ERROR("At least one allowed event must be set");
		res = EPOLLNVAL;
		goto out_unlock;
	}

	if (!list_empty(&priv->queued_events_list)) {
		res = EPOLLIN | EPOLLRDNORM;
		goto out_unlock;
	}

	mutex_unlock(&scst_event_mutex);

	TRACE_DBG("Before poll_wait() (priv %p)", priv);
	poll_wait(file, &priv->queued_events_waitQ, wait);
	TRACE_DBG("After poll_wait() (priv %p)", priv);

	mutex_lock(&scst_event_mutex);

	if (!list_empty(&priv->queued_events_list)) {
		res = EPOLLIN | EPOLLRDNORM;
		goto out_unlock;
	}

out_unlock:
	mutex_unlock(&scst_event_mutex);

	TRACE_EXIT_HRES((__force unsigned int)res);
	return res;
}

#if 0
#define CONFIG_EVENTS_WAIT_TEST
#endif

#ifdef CONFIG_EVENTS_WAIT_TEST
static void scst_event_test_notify_fn(struct scst_event *event,
	void *priv, int status)
{
	TRACE_ENTRY();

	PRINT_INFO("Notification for event %u (id %d) received with status %d "
		"(priv %p)", event->event_code, event->event_id, status,
		priv);

	TRACE_EXIT();
	return;
}

static ssize_t event_wait_test_store(struct kobject *kobj,
	struct kobj_attribute *attr, const char *buf, size_t count)
{
	int res = 0, event_entry_len;
	struct scst_event_entry *event_entry;

	TRACE_ENTRY();

	event_entry_len = sizeof(*event_entry);
	event_entry = kzalloc(event_entry_len, GFP_KERNEL);
	if (event_entry == NULL) {
		PRINT_ERROR("Unable to allocate event (size %d). Test "
			"event is lost!", event_entry_len);
		res = -ENOMEM;
		goto out;
	}

	TRACE_MEM("event_entry %p (len %d) allocated", event_entry,
		event_entry_len);

	event_entry->event_notify_fn = scst_event_test_notify_fn;
	event_entry->event_timeout = 10*HZ;

	scst_event_queue(0x12345, SCST_EVENT_SCST_CORE_ISSUER, event_entry);

	if (res == 0)
		res = count;

out:
	TRACE_EXIT_RES(res);
	return res;
}

static struct kobj_attribute event_wait_test_attr =
	__ATTR(event_wait_test, S_IWUSR, NULL, event_wait_test_store);

#endif /* #ifdef CONFIG_EVENTS_WAIT_TEST */

static const struct file_operations scst_event_fops = {
	.poll		= scst_event_poll,
	.unlocked_ioctl	= scst_event_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= scst_event_ioctl,
#endif
	.release	= scst_event_release,
};

int scst_event_init(void)
{
	int res = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21)
	struct class_device *class_member;
#else
	struct device *dev;
#endif

	TRACE_ENTRY();

	scst_event_sysfs_class = class_create(THIS_MODULE, SCST_EVENT_NAME);
	if (IS_ERR(scst_event_sysfs_class)) {
		PRINT_ERROR("%s", "Unable create sysfs class for SCST event");
		res = PTR_ERR(scst_event_sysfs_class);
		goto out;
	}

	scst_event_major = register_chrdev(0, SCST_EVENT_NAME, &scst_event_fops);
	if (scst_event_major < 0) {
		PRINT_ERROR("register_chrdev() failed: %d", res);
		res = scst_event_major;
		goto out_class;
	}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21)
	class_member = class_device_create(scst_event_sysfs_class, NULL,
					   MKDEV(scst_event_major, 0), NULL,
					   SCST_EVENT_NAME);
	if (IS_ERR(class_member)) {
		res = PTR_ERR(class_member);
		goto out_chrdev;
	}
#else
	dev = device_create(scst_event_sysfs_class, NULL,
			    MKDEV(scst_event_major, 0),
				NULL,
				SCST_EVENT_NAME);
	if (IS_ERR(dev)) {
		res = PTR_ERR(dev);
		goto out_chrdev;
	}
#endif

#ifdef CONFIG_EVENTS_WAIT_TEST
	sysfs_create_file(kernel_kobj, &event_wait_test_attr.attr);
#endif

out:
	TRACE_EXIT_RES(res);
	return res;


out_chrdev:
	unregister_chrdev(scst_event_major, SCST_EVENT_NAME);

out_class:
	class_destroy(scst_event_sysfs_class);
	goto out;
}

void scst_event_exit(void)
{
	TRACE_ENTRY();

#ifdef CONFIG_EVENTS_WAIT_TEST
	sysfs_remove_file(kernel_kobj, &event_wait_test_attr.attr);
#endif

	unregister_chrdev(scst_event_major, SCST_EVENT_NAME);

	device_destroy(scst_event_sysfs_class, MKDEV(scst_event_major, 0));
	class_destroy(scst_event_sysfs_class);

	/* Wait for all pending being queued events to process */
	flush_scheduled_work();

	TRACE_EXIT();
	return;
}
