/* Copyright (c) 2015 Google Inc
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * FD taps.  Allows the user to receive events when certain things happen to an
 * FD's underlying device file/qid. */

#include <fdtap.h>
#include <vfs.h>
#include <event.h>
#include <kmalloc.h>
#include <syscall.h>
#include <error.h>
#include <umem.h>

static void tap_min_release(struct kref *kref)
{
	struct fd_tap *tap = container_of(kref, struct fd_tap, kref);
	cclose(tap->chan);
	kfree(tap);
}

static void tap_full_release(struct kref *kref)
{
	struct fd_tap *tap = container_of(kref, struct fd_tap, kref);
	devtab[tap->chan->type].tapfd(tap->chan, tap, FDTAP_CMD_REM);
	tap_min_release(kref);
}

/* Adds a tap with the file/qid of the underlying device for the requested FD.
 * The FD must be a chan, and the device must support the filter requested.
 *
 * Returns -1 or some other device-specific non-zero number on failure, 0 on
 * success. */
int add_fd_tap(struct proc *p, struct fd_tap_req *tap_req)
{
	struct fd_table *fdt = &p->open_files;
	struct fd_tap *tap;
	int ret = 0;
	struct chan *chan;
	int fd = tap_req->fd;

	if (fd < 0) {
		set_errno(EBADF);
		return -1;
	}
	tap = kzmalloc(sizeof(struct fd_tap), MEM_WAIT);
	tap->proc = p;
	tap->fd = fd;
	tap->filter = tap_req->filter;
	tap->ev_q = tap_req->ev_q;
	tap->ev_id = tap_req->ev_id;
	tap->data = tap_req->data;
	if (!is_user_rwaddr(tap->ev_q, sizeof(struct event_queue))) {
		set_error(EINVAL, "Tap request with bad event_queue %p", tap->ev_q);
		kfree(tap);
		return -1;
	}
	spin_lock(&fdt->lock);
	if (fd >= fdt->max_fdset) {
		set_errno(ENFILE);
		goto out_with_lock;
	}
	if (!GET_BITMASK_BIT(fdt->open_fds->fds_bits, fd)) {
		set_errno(EBADF);
		goto out_with_lock;
	}
	if (!fdt->fd[fd].fd_chan) {
		set_error(EINVAL, "Can't tap a VFS file");
		goto out_with_lock;
	}
	chan = fdt->fd[fd].fd_chan;
	if (fdt->fd[fd].fd_tap) {
		set_error(EBUSY, "FD %d already has a tap", fd);
		goto out_with_lock;
	}
	if (!devtab[chan->type].tapfd) {
		set_error(ENOSYS, "Device %s does not handle taps",
				  devtab[chan->type].name);
		goto out_with_lock;
	}
	/* need to keep chan alive for our call to the device.  someone else
	 * could come in and close the FD and the chan, once we unlock */
	chan_incref(chan);
	tap->chan = chan;
	/* One for the FD table, one for us to keep the removal of *this* tap from
	 * happening until we've attempted to register with the device. */
	kref_init(&tap->kref, tap_full_release, 2);
	fdt->fd[fd].fd_tap = tap;
	/* As soon as we unlock, another thread can come in and remove our old tap
	 * from the table and decref it.  Our ref keeps us from removing it yet,
	 * as well as keeps the memory safe.  However, a new tap can be installed
	 * and registered with the device before we even attempt to register.  The
	 * devices should be able to handle multiple, distinct taps, even if they
	 * happen to have the same {proc, fd} tuple. */
	spin_unlock(&fdt->lock);
	/* For refcnting fans, the tap ref is weak/uncounted.  We'll protect the
	 * memory and call the device when tap is being released. */
	ret = devtab[chan->type].tapfd(chan, tap, FDTAP_CMD_ADD);
	if (ret) {
		/* we failed, so we need to make sure *our* tap is removed.  We haven't
		 * decreffed, so we know our tap pointer is unique. */
		spin_lock(&fdt->lock);
		if (fdt->fd[fd].fd_tap == tap) {
			fdt->fd[fd].fd_tap = 0;
			/* normally we can't decref a tap while holding a lock, but we
			 * know we have another reference so this won't trigger a release */
			kref_put(&tap->kref);
		}
		spin_unlock(&fdt->lock);
		/* Regardless of whether someone else removed it or not, *we* are the
		 * only ones that know that registration failed and that we shouldn't
		 * remove it.  Since we still hold a ref, we can change the release
		 * method to skip the device dereg. */
		tap->kref.release = tap_min_release;
	}
	kref_put(&tap->kref);
	return ret;
out_with_lock:
	spin_unlock(&fdt->lock);
	kfree(tap);
	return -1;
}

/* Removes the FD tap associated with FD.  Returns 0 on success, -1 with
 * errno/errstr on failure. */
int remove_fd_tap(struct proc *p, int fd)
{
	struct fd_table *fdt = &p->open_files;
	struct fd_tap *tap;

	spin_lock(&fdt->lock);
	tap = fdt->fd[fd].fd_tap;
	fdt->fd[fd].fd_tap = 0;
	spin_unlock(&fdt->lock);
	if (tap) {
		kref_put(&tap->kref);
		return 0;
	} else {
		set_error(EBADF, "FD %d was not tapped", fd);
		return -1;
	}
}

/* Fires off tap, with the events of filter having occurred.  Returns -1 on
 * error, though this need a little more thought.
 *
 * Some callers may require this to not block. */
int fire_tap(struct fd_tap *tap, int filter)
{
	ERRSTACK(1);
	struct event_msg ev_msg = {0};
	int fire_filt = tap->filter & filter;

	if (!fire_filt)
		return 0;
	if (waserror()) {
		/* The process owning the tap could trigger a kernel PF, as with any
		 * send_event() call.  Eventually we'll catch that with waserror. */
		warn("Tap for proc %d, fd %d, threw %s", tap->proc->pid, tap->fd,
		     current_errstr());
		poperror();
		return -1;
	}
	ev_msg.ev_type = tap->ev_id;	/* e.g. CEQ idx */
	ev_msg.ev_arg2 = fire_filt;		/* e.g. CEQ coalesce */
	ev_msg.ev_arg3 = tap->data;		/* e.g. CEQ data */
	send_event(tap->proc, tap->ev_q, &ev_msg, 0);
	poperror();
	return 0;
}
