// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/file.h>
#include <linux/io_uring/cmd.h>
#include <linux/security.h>
#include <linux/nospec.h>

#include <uapi/linux/io_uring.h>

#include "io_uring.h"
#include "alloc_cache.h"
#include "rsrc.h"
#include "kbuf.h"
#include "uring_cmd.h"
#include "poll.h"

void io_cmd_cache_free(const void *entry)
{
	struct io_async_cmd *ac = (struct io_async_cmd *)entry;

	io_vec_free(&ac->vec);
	kfree(ac);
}

static void io_req_uring_cleanup(struct io_kiocb *req, unsigned int issue_flags)
{
	struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
	struct io_async_cmd *ac = req->async_data;

	if (issue_flags & IO_URING_F_UNLOCKED)
		return;

	io_alloc_cache_vec_kasan(&ac->vec);
	if (ac->vec.nr > IO_VEC_CACHE_SOFT_CAP)
		io_vec_free(&ac->vec);

	if (io_alloc_cache_put(&req->ctx->cmd_cache, ac)) {
		ioucmd->sqe = NULL;
		io_req_async_data_clear(req, REQ_F_NEED_CLEANUP);
	} else {
		io_vec_free(&ac->vec);
	}
}

void io_uring_cmd_cleanup(struct io_kiocb *req)
{
	io_req_uring_cleanup(req, 0);
}

bool io_uring_try_cancel_uring_cmd(struct io_ring_ctx *ctx,
				   struct io_uring_task *tctx, bool cancel_all)
{
	struct hlist_node *tmp;
	struct io_kiocb *req;
	bool ret = false;

	lockdep_assert_held(&ctx->uring_lock);

	hlist_for_each_entry_safe(req, tmp, &ctx->cancelable_uring_cmd,
			hash_node) {
		struct io_uring_cmd *cmd = io_kiocb_to_cmd(req,
				struct io_uring_cmd);
		struct file *file = req->file;

		if (!cancel_all && req->tctx != tctx)
			continue;

		if (cmd->flags & IORING_URING_CMD_CANCELABLE) {
			file->f_op->uring_cmd(cmd, IO_URING_F_CANCEL |
						   IO_URING_F_COMPLETE_DEFER);
			ret = true;
		}
	}
	io_submit_flush_completions(ctx);
	return ret;
}

static void io_uring_cmd_del_cancelable(struct io_uring_cmd *cmd,
		unsigned int issue_flags)
{
	struct io_kiocb *req = cmd_to_io_kiocb(cmd);
	struct io_ring_ctx *ctx = req->ctx;

	if (!(cmd->flags & IORING_URING_CMD_CANCELABLE))
		return;

	cmd->flags &= ~IORING_URING_CMD_CANCELABLE;
	io_ring_submit_lock(ctx, issue_flags);
	hlist_del_init(&req->hash_node);
	io_ring_submit_unlock(ctx, issue_flags);
}

/*
 * Mark this command as cancelable, then io_uring_try_cancel_uring_cmd()
 * will try to cancel this issued command by sending ->uring_cmd() with
 * issue_flags of IO_URING_F_CANCEL.
 *
 * The command is guaranteed to not be done when calling ->uring_cmd()
 * with IO_URING_F_CANCEL, but it is driver's responsibility to deal
 * with race between io_uring canceling and normal completion.
 */
void io_uring_cmd_mark_cancelable(struct io_uring_cmd *cmd,
		unsigned int issue_flags)
{
	struct io_kiocb *req = cmd_to_io_kiocb(cmd);
	struct io_ring_ctx *ctx = req->ctx;

	/*
	 * Doing cancelations on IOPOLL requests are not supported. Both
	 * because they can't get canceled in the block stack, but also
	 * because iopoll completion data overlaps with the hash_node used
	 * for tracking.
	 */
	if (req->flags & REQ_F_IOPOLL)
		return;

	if (!(cmd->flags & IORING_URING_CMD_CANCELABLE)) {
		cmd->flags |= IORING_URING_CMD_CANCELABLE;
		io_ring_submit_lock(ctx, issue_flags);
		hlist_add_head(&req->hash_node, &ctx->cancelable_uring_cmd);
		io_ring_submit_unlock(ctx, issue_flags);
	}
}
EXPORT_SYMBOL_GPL(io_uring_cmd_mark_cancelable);

void __io_uring_cmd_do_in_task(struct io_uring_cmd *ioucmd,
			io_req_tw_func_t task_work_cb,
			unsigned flags)
{
	struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);

	if (WARN_ON_ONCE(req->flags & REQ_F_APOLL_MULTISHOT))
		return;

	req->io_task_work.func = task_work_cb;
	__io_req_task_work_add(req, flags);
}
EXPORT_SYMBOL_GPL(__io_uring_cmd_do_in_task);

static inline void io_req_set_cqe32_extra(struct io_kiocb *req,
					  u64 extra1, u64 extra2)
{
	req->big_cqe.extra1 = extra1;
	req->big_cqe.extra2 = extra2;
}

/*
 * Called by consumers of io_uring_cmd, if they originally returned
 * -EIOCBQUEUED upon receiving the command.
 */
void __io_uring_cmd_done(struct io_uring_cmd *ioucmd, s32 ret, u64 res2,
		       unsigned issue_flags, bool is_cqe32)
{
	struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);

	if (WARN_ON_ONCE(req->flags & REQ_F_APOLL_MULTISHOT))
		return;

	io_uring_cmd_del_cancelable(ioucmd, issue_flags);

	if (ret < 0)
		req_set_fail(req);

	io_req_set_res(req, ret, 0);
	if (is_cqe32) {
		if (req->ctx->flags & IORING_SETUP_CQE_MIXED)
			req->cqe.flags |= IORING_CQE_F_32;
		io_req_set_cqe32_extra(req, res2, 0);
	}
	io_req_uring_cleanup(req, issue_flags);
	if (req->flags & REQ_F_IOPOLL) {
		/* order with io_do_iopoll() checking ->iopoll_completed */
		smp_store_release(&req->iopoll_completed, 1);
	} else if (issue_flags & IO_URING_F_COMPLETE_DEFER) {
		if (WARN_ON_ONCE(issue_flags & IO_URING_F_UNLOCKED))
			return;
		io_req_complete_defer(req);
	} else {
		req->io_task_work.func = io_req_task_complete;
		io_req_task_work_add(req);
	}
}
EXPORT_SYMBOL_GPL(__io_uring_cmd_done);

int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
	struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
	struct io_async_cmd *ac;

	if (sqe->__pad1)
		return -EINVAL;

	ioucmd->flags = READ_ONCE(sqe->uring_cmd_flags);
	if (ioucmd->flags & ~IORING_URING_CMD_MASK)
		return -EINVAL;

	if (ioucmd->flags & IORING_URING_CMD_FIXED) {
		if (ioucmd->flags & IORING_URING_CMD_MULTISHOT)
			return -EINVAL;
		req->buf_index = READ_ONCE(sqe->buf_index);
	}

	if (!!(ioucmd->flags & IORING_URING_CMD_MULTISHOT) !=
	    !!(req->flags & REQ_F_BUFFER_SELECT))
		return -EINVAL;

	ioucmd->cmd_op = READ_ONCE(sqe->cmd_op);

	ac = io_uring_alloc_async_data(&req->ctx->cmd_cache, req);
	if (!ac)
		return -ENOMEM;
	if (ac->vec.iovec)
		req->flags |= REQ_F_NEED_CLEANUP;
	ioucmd->sqe = sqe;
	return 0;
}

/*
 * IORING_SETUP_SQE128 contexts allocate twice the normal SQE size for each
 * slot.
 */
static inline size_t uring_sqe_size(struct io_kiocb *req)
{
	if (req->ctx->flags & IORING_SETUP_SQE128 ||
	    req->opcode == IORING_OP_URING_CMD128)
		return 2 * sizeof(struct io_uring_sqe);
	return sizeof(struct io_uring_sqe);
}

void io_uring_cmd_sqe_copy(struct io_kiocb *req)
{
	struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
	struct io_async_cmd *ac = req->async_data;

	/* Should not happen, as REQ_F_SQE_COPIED covers this */
	if (WARN_ON_ONCE(ioucmd->sqe == ac->sqes))
		return;
	memcpy(ac->sqes, ioucmd->sqe, uring_sqe_size(req));
	ioucmd->sqe = ac->sqes;
}

int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags)
{
	struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
	struct io_ring_ctx *ctx = req->ctx;
	struct file *file = req->file;
	int ret;

	if (!file->f_op->uring_cmd)
		return -EOPNOTSUPP;

	ret = security_uring_cmd(ioucmd);
	if (ret)
		return ret;

	if (ctx->flags & IORING_SETUP_SQE128 ||
	    req->opcode == IORING_OP_URING_CMD128)
		issue_flags |= IO_URING_F_SQE128;
	if (ctx->flags & (IORING_SETUP_CQE32 | IORING_SETUP_CQE_MIXED))
		issue_flags |= IO_URING_F_CQE32;
	if (io_is_compat(ctx))
		issue_flags |= IO_URING_F_COMPAT;
	if (ctx->flags & IORING_SETUP_IOPOLL && file->f_op->uring_cmd_iopoll) {
		req->flags |= REQ_F_IOPOLL;
		issue_flags |= IO_URING_F_IOPOLL;
		req->iopoll_completed = 0;
		if (ctx->flags & IORING_SETUP_HYBRID_IOPOLL) {
			/* make sure every req only blocks once */
			req->flags &= ~REQ_F_IOPOLL_STATE;
			req->iopoll_start = ktime_get_ns();
		}
	}

	ret = file->f_op->uring_cmd(ioucmd, issue_flags);
	if (ret == -EAGAIN) {
		ioucmd->flags |= IORING_URING_CMD_REISSUE;
		return ret;
	}
	if (ret == -EIOCBQUEUED)
		return ret;
	if (ret < 0)
		req_set_fail(req);
	io_req_uring_cleanup(req, issue_flags);
	io_req_set_res(req, ret, 0);
	return IOU_COMPLETE;
}

int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
			      struct iov_iter *iter,
			      struct io_uring_cmd *ioucmd,
			      unsigned int issue_flags)
{
	struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);

	if (WARN_ON_ONCE(!(ioucmd->flags & IORING_URING_CMD_FIXED)))
		return -EINVAL;

	return io_import_reg_buf(req, iter, ubuf, len, rw, issue_flags);
}
EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed);

int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd,
				  const struct iovec __user *uvec,
				  size_t uvec_segs,
				  int ddir, struct iov_iter *iter,
				  unsigned issue_flags)
{
	struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
	struct io_async_cmd *ac = req->async_data;
	int ret;

	if (WARN_ON_ONCE(!(ioucmd->flags & IORING_URING_CMD_FIXED)))
		return -EINVAL;

	ret = io_prep_reg_iovec(req, &ac->vec, uvec, uvec_segs);
	if (ret)
		return ret;

	return io_import_reg_vec(ddir, iter, req, &ac->vec, uvec_segs,
				 issue_flags);
}
EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed_vec);

void io_uring_cmd_issue_blocking(struct io_uring_cmd *ioucmd)
{
	struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);

	io_queue_iowq(req);
}

int io_cmd_poll_multishot(struct io_uring_cmd *cmd,
			  unsigned int issue_flags, __poll_t mask)
{
	struct io_kiocb *req = cmd_to_io_kiocb(cmd);
	int ret;

	if (likely(req->flags & REQ_F_APOLL_MULTISHOT))
		return 0;

	req->flags |= REQ_F_APOLL_MULTISHOT;
	mask &= ~EPOLLONESHOT;

	ret = io_arm_apoll(req, issue_flags, mask);
	return ret == IO_APOLL_OK ? -EIOCBQUEUED : -ECANCELED;
}

bool io_uring_cmd_post_mshot_cqe32(struct io_uring_cmd *cmd,
				   unsigned int issue_flags,
				   struct io_uring_cqe cqe[2])
{
	struct io_kiocb *req = cmd_to_io_kiocb(cmd);

	if (WARN_ON_ONCE(!(issue_flags & IO_URING_F_MULTISHOT)))
		return false;
	return io_req_post_cqe32(req, cqe);
}

/*
 * Work with io_uring_mshot_cmd_post_cqe() together for committing the
 * provided buffer upfront
 */
struct io_br_sel io_uring_cmd_buffer_select(struct io_uring_cmd *ioucmd,
					    unsigned buf_group, size_t *len,
					    unsigned int issue_flags)
{
	struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);

	if (!(ioucmd->flags & IORING_URING_CMD_MULTISHOT))
		return (struct io_br_sel) { .val = -EINVAL };

	if (WARN_ON_ONCE(!io_do_buffer_select(req)))
		return (struct io_br_sel) { .val = -EINVAL };

	return io_buffer_select(req, len, buf_group, issue_flags);
}
EXPORT_SYMBOL_GPL(io_uring_cmd_buffer_select);

/*
 * Return true if this multishot uring_cmd needs to be completed, otherwise
 * the event CQE is posted successfully.
 *
 * This function must use `struct io_br_sel` returned from
 * io_uring_cmd_buffer_select() for committing the buffer in the same
 * uring_cmd submission context.
 */
bool io_uring_mshot_cmd_post_cqe(struct io_uring_cmd *ioucmd,
				 struct io_br_sel *sel, unsigned int issue_flags)
{
	struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
	unsigned int cflags = 0;

	if (!(ioucmd->flags & IORING_URING_CMD_MULTISHOT))
		return true;

	if (sel->val > 0) {
		cflags = io_put_kbuf(req, sel->val, sel->buf_list);
		if (io_req_post_cqe(req, sel->val, cflags | IORING_CQE_F_MORE))
			return false;
	}

	io_kbuf_recycle(req, sel->buf_list, issue_flags);
	if (sel->val < 0)
		req_set_fail(req);
	io_req_set_res(req, sel->val, cflags);
	return true;
}
EXPORT_SYMBOL_GPL(io_uring_mshot_cmd_post_cqe);
