xref: /linux/io_uring/nop.c (revision a4a508df2aa34f8650afde54ea804321c618f45f)
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