1e28683bdSJens Axboe // SPDX-License-Identifier: GPL-2.0
2e28683bdSJens Axboe #include <linux/kernel.h>
3e28683bdSJens Axboe #include <linux/errno.h>
4e28683bdSJens Axboe #include <linux/fs.h>
5e28683bdSJens Axboe #include <linux/file.h>
6e28683bdSJens Axboe #include <linux/io_uring.h>
7e28683bdSJens Axboe
8e28683bdSJens Axboe #include <uapi/linux/io_uring.h>
9e28683bdSJens Axboe
10e28683bdSJens Axboe #include "io_uring.h"
11a85f3105SJens Axboe #include "rsrc.h"
12e28683bdSJens Axboe #include "nop.h"
13e28683bdSJens Axboe
14deb1e496SMing Lei struct io_nop {
15deb1e496SMing Lei /* NOTE: kiocb has the file as the first member, so don't do it here */
16deb1e496SMing Lei struct file *file;
17deb1e496SMing Lei int result;
18a85f3105SJens Axboe int fd;
19a85f3105SJens Axboe unsigned int flags;
20*806ecb20SJens Axboe __u64 extra1;
21*806ecb20SJens Axboe __u64 extra2;
22deb1e496SMing Lei };
23deb1e496SMing Lei
24a85f3105SJens Axboe #define NOP_FLAGS (IORING_NOP_INJECT_RESULT | IORING_NOP_FIXED_FILE | \
25cb9ccfb4SJens Axboe IORING_NOP_FIXED_BUFFER | IORING_NOP_FILE | \
26*806ecb20SJens Axboe IORING_NOP_TW | IORING_NOP_CQE32)
27a85f3105SJens Axboe
io_nop_prep(struct io_kiocb * req,const struct io_uring_sqe * sqe)28e28683bdSJens Axboe int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
29e28683bdSJens Axboe {
30deb1e496SMing Lei struct io_nop *nop = io_kiocb_to_cmd(req, struct io_nop);
31deb1e496SMing Lei
32a85f3105SJens Axboe nop->flags = READ_ONCE(sqe->nop_flags);
33a85f3105SJens Axboe if (nop->flags & ~NOP_FLAGS)
343d8f874bSMing Lei return -EINVAL;
35deb1e496SMing Lei
36a85f3105SJens Axboe if (nop->flags & IORING_NOP_INJECT_RESULT)
37deb1e496SMing Lei nop->result = READ_ONCE(sqe->len);
38deb1e496SMing Lei else
39deb1e496SMing Lei nop->result = 0;
40ee116574SJens Axboe if (nop->flags & IORING_NOP_FILE)
41a85f3105SJens Axboe nop->fd = READ_ONCE(sqe->fd);
42ee116574SJens Axboe else
43ee116574SJens Axboe nop->fd = -1;
44a85f3105SJens Axboe if (nop->flags & IORING_NOP_FIXED_BUFFER)
45a14ca7a4SKeith Busch req->buf_index = READ_ONCE(sqe->buf_index);
46*806ecb20SJens Axboe if (nop->flags & IORING_NOP_CQE32) {
47*806ecb20SJens Axboe struct io_ring_ctx *ctx = req->ctx;
48*806ecb20SJens Axboe
49*806ecb20SJens Axboe if (!(ctx->flags & (IORING_SETUP_CQE32|IORING_SETUP_CQE_MIXED)))
50*806ecb20SJens Axboe return -EINVAL;
51*806ecb20SJens Axboe nop->extra1 = READ_ONCE(sqe->off);
52*806ecb20SJens Axboe nop->extra2 = READ_ONCE(sqe->addr);
53*806ecb20SJens Axboe }
54e28683bdSJens Axboe return 0;
55e28683bdSJens Axboe }
56e28683bdSJens Axboe
io_nop(struct io_kiocb * req,unsigned int issue_flags)57e28683bdSJens Axboe int io_nop(struct io_kiocb *req, unsigned int issue_flags)
58e28683bdSJens Axboe {
59deb1e496SMing Lei struct io_nop *nop = io_kiocb_to_cmd(req, struct io_nop);
60a85f3105SJens Axboe int ret = nop->result;
61deb1e496SMing Lei
62a85f3105SJens Axboe if (nop->flags & IORING_NOP_FILE) {
63a85f3105SJens Axboe if (nop->flags & IORING_NOP_FIXED_FILE) {
64a85f3105SJens Axboe req->file = io_file_get_fixed(req, nop->fd, issue_flags);
65a85f3105SJens Axboe req->flags |= REQ_F_FIXED_FILE;
66a85f3105SJens Axboe } else {
67a85f3105SJens Axboe req->file = io_file_get_normal(req, nop->fd);
68a85f3105SJens Axboe }
69a85f3105SJens Axboe if (!req->file) {
70a85f3105SJens Axboe ret = -EBADF;
71a85f3105SJens Axboe goto done;
72a85f3105SJens Axboe }
73a85f3105SJens Axboe }
74a85f3105SJens Axboe if (nop->flags & IORING_NOP_FIXED_BUFFER) {
756e83a442SCaleb Sander Mateos if (!io_find_buf_node(req, issue_flags))
76a85f3105SJens Axboe ret = -EFAULT;
77a85f3105SJens Axboe }
78a85f3105SJens Axboe done:
79a85f3105SJens Axboe if (ret < 0)
80deb1e496SMing Lei req_set_fail(req);
81*806ecb20SJens Axboe if (nop->flags & IORING_NOP_CQE32)
82*806ecb20SJens Axboe io_req_set_res32(req, nop->result, 0, nop->extra1, nop->extra2);
83*806ecb20SJens Axboe else
84deb1e496SMing Lei io_req_set_res(req, nop->result, 0);
85cb9ccfb4SJens Axboe if (nop->flags & IORING_NOP_TW) {
86cb9ccfb4SJens Axboe req->io_task_work.func = io_req_task_complete;
87cb9ccfb4SJens Axboe io_req_task_work_add(req);
88cb9ccfb4SJens Axboe return IOU_ISSUE_SKIP_COMPLETE;
89cb9ccfb4SJens Axboe }
908bb9d6ccSJens Axboe return IOU_COMPLETE;
91e28683bdSJens Axboe }
92