xref: /openbmc/linux/io_uring/opdef.c (revision ef0ec1ad)
1d9b57aa3SJens Axboe // SPDX-License-Identifier: GPL-2.0
2d9b57aa3SJens Axboe /*
3d9b57aa3SJens Axboe  * io_uring opcode handling table
4d9b57aa3SJens Axboe  */
5d9b57aa3SJens Axboe #include <linux/kernel.h>
6d9b57aa3SJens Axboe #include <linux/errno.h>
7d9b57aa3SJens Axboe #include <linux/fs.h>
8d9b57aa3SJens Axboe #include <linux/file.h>
9d9b57aa3SJens Axboe #include <linux/io_uring.h>
10d9b57aa3SJens Axboe 
11d9b57aa3SJens Axboe #include "io_uring.h"
12d9b57aa3SJens Axboe #include "opdef.h"
13d9b57aa3SJens Axboe #include "refs.h"
14d9b57aa3SJens Axboe #include "tctx.h"
15d9b57aa3SJens Axboe #include "sqpoll.h"
16d9b57aa3SJens Axboe #include "fdinfo.h"
17d9b57aa3SJens Axboe #include "kbuf.h"
18d9b57aa3SJens Axboe #include "rsrc.h"
19d9b57aa3SJens Axboe 
20d9b57aa3SJens Axboe #include "xattr.h"
21d9b57aa3SJens Axboe #include "nop.h"
22d9b57aa3SJens Axboe #include "fs.h"
23d9b57aa3SJens Axboe #include "splice.h"
24d9b57aa3SJens Axboe #include "sync.h"
25d9b57aa3SJens Axboe #include "advise.h"
26d9b57aa3SJens Axboe #include "openclose.h"
27d9b57aa3SJens Axboe #include "uring_cmd.h"
28d9b57aa3SJens Axboe #include "epoll.h"
29d9b57aa3SJens Axboe #include "statx.h"
30d9b57aa3SJens Axboe #include "net.h"
31d9b57aa3SJens Axboe #include "msg_ring.h"
32d9b57aa3SJens Axboe #include "timeout.h"
33d9b57aa3SJens Axboe #include "poll.h"
34d9b57aa3SJens Axboe #include "cancel.h"
35d9b57aa3SJens Axboe #include "rw.h"
36d9b57aa3SJens Axboe 
37d9b57aa3SJens Axboe static int io_no_issue(struct io_kiocb *req, unsigned int issue_flags)
38d9b57aa3SJens Axboe {
39d9b57aa3SJens Axboe 	WARN_ON_ONCE(1);
40d9b57aa3SJens Axboe 	return -ECANCELED;
41d9b57aa3SJens Axboe }
42d9b57aa3SJens Axboe 
43d9b57aa3SJens Axboe static __maybe_unused int io_eopnotsupp_prep(struct io_kiocb *kiocb,
44d9b57aa3SJens Axboe 					     const struct io_uring_sqe *sqe)
45d9b57aa3SJens Axboe {
46d9b57aa3SJens Axboe 	return -EOPNOTSUPP;
47d9b57aa3SJens Axboe }
48d9b57aa3SJens Axboe 
49d9b57aa3SJens Axboe const struct io_op_def io_op_defs[] = {
50d9b57aa3SJens Axboe 	[IORING_OP_NOP] = {
51d9b57aa3SJens Axboe 		.audit_skip		= 1,
52d9b57aa3SJens Axboe 		.iopoll			= 1,
53d9b57aa3SJens Axboe 		.name			= "NOP",
54d9b57aa3SJens Axboe 		.prep			= io_nop_prep,
55d9b57aa3SJens Axboe 		.issue			= io_nop,
56d9b57aa3SJens Axboe 	},
57d9b57aa3SJens Axboe 	[IORING_OP_READV] = {
58d9b57aa3SJens Axboe 		.needs_file		= 1,
59d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
60d9b57aa3SJens Axboe 		.pollin			= 1,
61d9b57aa3SJens Axboe 		.buffer_select		= 1,
62d9b57aa3SJens Axboe 		.plug			= 1,
63d9b57aa3SJens Axboe 		.audit_skip		= 1,
64d9b57aa3SJens Axboe 		.ioprio			= 1,
65d9b57aa3SJens Axboe 		.iopoll			= 1,
66*ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
67d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
68d9b57aa3SJens Axboe 		.name			= "READV",
69d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
70d9b57aa3SJens Axboe 		.issue			= io_read,
71d9b57aa3SJens Axboe 		.prep_async		= io_readv_prep_async,
72d9b57aa3SJens Axboe 		.cleanup		= io_readv_writev_cleanup,
7347b4c686SPavel Begunkov 		.fail			= io_rw_fail,
74d9b57aa3SJens Axboe 	},
75d9b57aa3SJens Axboe 	[IORING_OP_WRITEV] = {
76d9b57aa3SJens Axboe 		.needs_file		= 1,
77d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
78d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
79d9b57aa3SJens Axboe 		.pollout		= 1,
80d9b57aa3SJens Axboe 		.plug			= 1,
81d9b57aa3SJens Axboe 		.audit_skip		= 1,
82d9b57aa3SJens Axboe 		.ioprio			= 1,
83d9b57aa3SJens Axboe 		.iopoll			= 1,
84*ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
85d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
86d9b57aa3SJens Axboe 		.name			= "WRITEV",
87d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
88d9b57aa3SJens Axboe 		.issue			= io_write,
89d9b57aa3SJens Axboe 		.prep_async		= io_writev_prep_async,
90d9b57aa3SJens Axboe 		.cleanup		= io_readv_writev_cleanup,
9147b4c686SPavel Begunkov 		.fail			= io_rw_fail,
92d9b57aa3SJens Axboe 	},
93d9b57aa3SJens Axboe 	[IORING_OP_FSYNC] = {
94d9b57aa3SJens Axboe 		.needs_file		= 1,
95d9b57aa3SJens Axboe 		.audit_skip		= 1,
96d9b57aa3SJens Axboe 		.name			= "FSYNC",
97d9b57aa3SJens Axboe 		.prep			= io_fsync_prep,
98d9b57aa3SJens Axboe 		.issue			= io_fsync,
99d9b57aa3SJens Axboe 	},
100d9b57aa3SJens Axboe 	[IORING_OP_READ_FIXED] = {
101d9b57aa3SJens Axboe 		.needs_file		= 1,
102d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
103d9b57aa3SJens Axboe 		.pollin			= 1,
104d9b57aa3SJens Axboe 		.plug			= 1,
105d9b57aa3SJens Axboe 		.audit_skip		= 1,
106d9b57aa3SJens Axboe 		.ioprio			= 1,
107d9b57aa3SJens Axboe 		.iopoll			= 1,
108*ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
109d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
110d9b57aa3SJens Axboe 		.name			= "READ_FIXED",
111d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
112d9b57aa3SJens Axboe 		.issue			= io_read,
11347b4c686SPavel Begunkov 		.fail			= io_rw_fail,
114d9b57aa3SJens Axboe 	},
115d9b57aa3SJens Axboe 	[IORING_OP_WRITE_FIXED] = {
116d9b57aa3SJens Axboe 		.needs_file		= 1,
117d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
118d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
119d9b57aa3SJens Axboe 		.pollout		= 1,
120d9b57aa3SJens Axboe 		.plug			= 1,
121d9b57aa3SJens Axboe 		.audit_skip		= 1,
122d9b57aa3SJens Axboe 		.ioprio			= 1,
123d9b57aa3SJens Axboe 		.iopoll			= 1,
124*ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
125d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
126d9b57aa3SJens Axboe 		.name			= "WRITE_FIXED",
127d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
128d9b57aa3SJens Axboe 		.issue			= io_write,
12947b4c686SPavel Begunkov 		.fail			= io_rw_fail,
130d9b57aa3SJens Axboe 	},
131d9b57aa3SJens Axboe 	[IORING_OP_POLL_ADD] = {
132d9b57aa3SJens Axboe 		.needs_file		= 1,
133d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
134d9b57aa3SJens Axboe 		.audit_skip		= 1,
135d9b57aa3SJens Axboe 		.name			= "POLL_ADD",
136d9b57aa3SJens Axboe 		.prep			= io_poll_add_prep,
137d9b57aa3SJens Axboe 		.issue			= io_poll_add,
138d9b57aa3SJens Axboe 	},
139d9b57aa3SJens Axboe 	[IORING_OP_POLL_REMOVE] = {
140d9b57aa3SJens Axboe 		.audit_skip		= 1,
141d9b57aa3SJens Axboe 		.name			= "POLL_REMOVE",
142d9b57aa3SJens Axboe 		.prep			= io_poll_remove_prep,
143d9b57aa3SJens Axboe 		.issue			= io_poll_remove,
144d9b57aa3SJens Axboe 	},
145d9b57aa3SJens Axboe 	[IORING_OP_SYNC_FILE_RANGE] = {
146d9b57aa3SJens Axboe 		.needs_file		= 1,
147d9b57aa3SJens Axboe 		.audit_skip		= 1,
148d9b57aa3SJens Axboe 		.name			= "SYNC_FILE_RANGE",
149d9b57aa3SJens Axboe 		.prep			= io_sfr_prep,
150d9b57aa3SJens Axboe 		.issue			= io_sync_file_range,
151d9b57aa3SJens Axboe 	},
152d9b57aa3SJens Axboe 	[IORING_OP_SENDMSG] = {
153d9b57aa3SJens Axboe 		.needs_file		= 1,
154d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
155d9b57aa3SJens Axboe 		.pollout		= 1,
156d9b57aa3SJens Axboe 		.ioprio			= 1,
157858c293eSPavel Begunkov 		.manual_alloc		= 1,
158d9b57aa3SJens Axboe 		.name			= "SENDMSG",
159d9b57aa3SJens Axboe #if defined(CONFIG_NET)
160d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_msghdr),
161d9b57aa3SJens Axboe 		.prep			= io_sendmsg_prep,
162d9b57aa3SJens Axboe 		.issue			= io_sendmsg,
163d9b57aa3SJens Axboe 		.prep_async		= io_sendmsg_prep_async,
164d9b57aa3SJens Axboe 		.cleanup		= io_sendmsg_recvmsg_cleanup,
1657e6b638eSPavel Begunkov 		.fail			= io_sendrecv_fail,
166d9b57aa3SJens Axboe #else
167d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
168d9b57aa3SJens Axboe #endif
169d9b57aa3SJens Axboe 	},
170d9b57aa3SJens Axboe 	[IORING_OP_RECVMSG] = {
171d9b57aa3SJens Axboe 		.needs_file		= 1,
172d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
173d9b57aa3SJens Axboe 		.pollin			= 1,
174d9b57aa3SJens Axboe 		.buffer_select		= 1,
175d9b57aa3SJens Axboe 		.ioprio			= 1,
176858c293eSPavel Begunkov 		.manual_alloc		= 1,
177d9b57aa3SJens Axboe 		.name			= "RECVMSG",
178d9b57aa3SJens Axboe #if defined(CONFIG_NET)
179d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_msghdr),
180d9b57aa3SJens Axboe 		.prep			= io_recvmsg_prep,
181d9b57aa3SJens Axboe 		.issue			= io_recvmsg,
182d9b57aa3SJens Axboe 		.prep_async		= io_recvmsg_prep_async,
183d9b57aa3SJens Axboe 		.cleanup		= io_sendmsg_recvmsg_cleanup,
1847e6b638eSPavel Begunkov 		.fail			= io_sendrecv_fail,
185d9b57aa3SJens Axboe #else
186d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
187d9b57aa3SJens Axboe #endif
188d9b57aa3SJens Axboe 	},
189d9b57aa3SJens Axboe 	[IORING_OP_TIMEOUT] = {
190d9b57aa3SJens Axboe 		.audit_skip		= 1,
191d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_timeout_data),
192d9b57aa3SJens Axboe 		.name			= "TIMEOUT",
193d9b57aa3SJens Axboe 		.prep			= io_timeout_prep,
194d9b57aa3SJens Axboe 		.issue			= io_timeout,
195d9b57aa3SJens Axboe 	},
196d9b57aa3SJens Axboe 	[IORING_OP_TIMEOUT_REMOVE] = {
197d9b57aa3SJens Axboe 		/* used by timeout updates' prep() */
198d9b57aa3SJens Axboe 		.audit_skip		= 1,
199d9b57aa3SJens Axboe 		.name			= "TIMEOUT_REMOVE",
200d9b57aa3SJens Axboe 		.prep			= io_timeout_remove_prep,
201d9b57aa3SJens Axboe 		.issue			= io_timeout_remove,
202d9b57aa3SJens Axboe 	},
203d9b57aa3SJens Axboe 	[IORING_OP_ACCEPT] = {
204d9b57aa3SJens Axboe 		.needs_file		= 1,
205d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
206d9b57aa3SJens Axboe 		.pollin			= 1,
207d9b57aa3SJens Axboe 		.poll_exclusive		= 1,
208d9b57aa3SJens Axboe 		.ioprio			= 1,	/* used for flags */
209d9b57aa3SJens Axboe 		.name			= "ACCEPT",
210d9b57aa3SJens Axboe #if defined(CONFIG_NET)
211d9b57aa3SJens Axboe 		.prep			= io_accept_prep,
212d9b57aa3SJens Axboe 		.issue			= io_accept,
213d9b57aa3SJens Axboe #else
214d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
215d9b57aa3SJens Axboe #endif
216d9b57aa3SJens Axboe 	},
217d9b57aa3SJens Axboe 	[IORING_OP_ASYNC_CANCEL] = {
218d9b57aa3SJens Axboe 		.audit_skip		= 1,
219d9b57aa3SJens Axboe 		.name			= "ASYNC_CANCEL",
220d9b57aa3SJens Axboe 		.prep			= io_async_cancel_prep,
221d9b57aa3SJens Axboe 		.issue			= io_async_cancel,
222d9b57aa3SJens Axboe 	},
223d9b57aa3SJens Axboe 	[IORING_OP_LINK_TIMEOUT] = {
224d9b57aa3SJens Axboe 		.audit_skip		= 1,
225d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_timeout_data),
226d9b57aa3SJens Axboe 		.name			= "LINK_TIMEOUT",
227d9b57aa3SJens Axboe 		.prep			= io_link_timeout_prep,
228d9b57aa3SJens Axboe 		.issue			= io_no_issue,
229d9b57aa3SJens Axboe 	},
230d9b57aa3SJens Axboe 	[IORING_OP_CONNECT] = {
231d9b57aa3SJens Axboe 		.needs_file		= 1,
232d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
233d9b57aa3SJens Axboe 		.pollout		= 1,
234d9b57aa3SJens Axboe 		.name			= "CONNECT",
235d9b57aa3SJens Axboe #if defined(CONFIG_NET)
236d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_connect),
237d9b57aa3SJens Axboe 		.prep			= io_connect_prep,
238d9b57aa3SJens Axboe 		.issue			= io_connect,
239d9b57aa3SJens Axboe 		.prep_async		= io_connect_prep_async,
240d9b57aa3SJens Axboe #else
241d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
242d9b57aa3SJens Axboe #endif
243d9b57aa3SJens Axboe 	},
244d9b57aa3SJens Axboe 	[IORING_OP_FALLOCATE] = {
245d9b57aa3SJens Axboe 		.needs_file		= 1,
246d9b57aa3SJens Axboe 		.name			= "FALLOCATE",
247d9b57aa3SJens Axboe 		.prep			= io_fallocate_prep,
248d9b57aa3SJens Axboe 		.issue			= io_fallocate,
249d9b57aa3SJens Axboe 	},
250d9b57aa3SJens Axboe 	[IORING_OP_OPENAT] = {
251d9b57aa3SJens Axboe 		.name			= "OPENAT",
252d9b57aa3SJens Axboe 		.prep			= io_openat_prep,
253d9b57aa3SJens Axboe 		.issue			= io_openat,
254d9b57aa3SJens Axboe 		.cleanup		= io_open_cleanup,
255d9b57aa3SJens Axboe 	},
256d9b57aa3SJens Axboe 	[IORING_OP_CLOSE] = {
257d9b57aa3SJens Axboe 		.name			= "CLOSE",
258d9b57aa3SJens Axboe 		.prep			= io_close_prep,
259d9b57aa3SJens Axboe 		.issue			= io_close,
260d9b57aa3SJens Axboe 	},
261d9808cebSPavel Begunkov 	[IORING_OP_FILES_UPDATE] = {
262d9b57aa3SJens Axboe 		.audit_skip		= 1,
263d9b57aa3SJens Axboe 		.iopoll			= 1,
264d9808cebSPavel Begunkov 		.name			= "FILES_UPDATE",
265d9808cebSPavel Begunkov 		.prep			= io_files_update_prep,
266d9808cebSPavel Begunkov 		.issue			= io_files_update,
267d9b57aa3SJens Axboe 	},
268d9b57aa3SJens Axboe 	[IORING_OP_STATX] = {
269d9b57aa3SJens Axboe 		.audit_skip		= 1,
270d9b57aa3SJens Axboe 		.name			= "STATX",
271d9b57aa3SJens Axboe 		.prep			= io_statx_prep,
272d9b57aa3SJens Axboe 		.issue			= io_statx,
273d9b57aa3SJens Axboe 		.cleanup		= io_statx_cleanup,
274d9b57aa3SJens Axboe 	},
275d9b57aa3SJens Axboe 	[IORING_OP_READ] = {
276d9b57aa3SJens Axboe 		.needs_file		= 1,
277d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
278d9b57aa3SJens Axboe 		.pollin			= 1,
279d9b57aa3SJens Axboe 		.buffer_select		= 1,
280d9b57aa3SJens Axboe 		.plug			= 1,
281d9b57aa3SJens Axboe 		.audit_skip		= 1,
282d9b57aa3SJens Axboe 		.ioprio			= 1,
283d9b57aa3SJens Axboe 		.iopoll			= 1,
284*ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
285d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
286d9b57aa3SJens Axboe 		.name			= "READ",
287d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
288d9b57aa3SJens Axboe 		.issue			= io_read,
28947b4c686SPavel Begunkov 		.fail			= io_rw_fail,
290d9b57aa3SJens Axboe 	},
291d9b57aa3SJens Axboe 	[IORING_OP_WRITE] = {
292d9b57aa3SJens Axboe 		.needs_file		= 1,
293d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
294d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
295d9b57aa3SJens Axboe 		.pollout		= 1,
296d9b57aa3SJens Axboe 		.plug			= 1,
297d9b57aa3SJens Axboe 		.audit_skip		= 1,
298d9b57aa3SJens Axboe 		.ioprio			= 1,
299d9b57aa3SJens Axboe 		.iopoll			= 1,
300*ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
301d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
302d9b57aa3SJens Axboe 		.name			= "WRITE",
303d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
304d9b57aa3SJens Axboe 		.issue			= io_write,
30547b4c686SPavel Begunkov 		.fail			= io_rw_fail,
306d9b57aa3SJens Axboe 	},
307d9b57aa3SJens Axboe 	[IORING_OP_FADVISE] = {
308d9b57aa3SJens Axboe 		.needs_file		= 1,
309d9b57aa3SJens Axboe 		.audit_skip		= 1,
310d9b57aa3SJens Axboe 		.name			= "FADVISE",
311d9b57aa3SJens Axboe 		.prep			= io_fadvise_prep,
312d9b57aa3SJens Axboe 		.issue			= io_fadvise,
313d9b57aa3SJens Axboe 	},
314d9b57aa3SJens Axboe 	[IORING_OP_MADVISE] = {
315d9b57aa3SJens Axboe 		.name			= "MADVISE",
316d9b57aa3SJens Axboe 		.prep			= io_madvise_prep,
317d9b57aa3SJens Axboe 		.issue			= io_madvise,
318d9b57aa3SJens Axboe 	},
319d9b57aa3SJens Axboe 	[IORING_OP_SEND] = {
320d9b57aa3SJens Axboe 		.needs_file		= 1,
321d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
322d9b57aa3SJens Axboe 		.pollout		= 1,
323d9b57aa3SJens Axboe 		.audit_skip		= 1,
324d9b57aa3SJens Axboe 		.ioprio			= 1,
325516e82f0SPavel Begunkov 		.manual_alloc		= 1,
326d9b57aa3SJens Axboe 		.name			= "SEND",
327d9b57aa3SJens Axboe #if defined(CONFIG_NET)
328516e82f0SPavel Begunkov 		.async_size		= sizeof(struct io_async_msghdr),
329d9b57aa3SJens Axboe 		.prep			= io_sendmsg_prep,
330d9b57aa3SJens Axboe 		.issue			= io_send,
3317e6b638eSPavel Begunkov 		.fail			= io_sendrecv_fail,
332516e82f0SPavel Begunkov 		.prep_async		= io_send_prep_async,
333d9b57aa3SJens Axboe #else
334d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
335d9b57aa3SJens Axboe #endif
336d9b57aa3SJens Axboe 	},
337d9b57aa3SJens Axboe 	[IORING_OP_RECV] = {
338d9b57aa3SJens Axboe 		.needs_file		= 1,
339d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
340d9b57aa3SJens Axboe 		.pollin			= 1,
341d9b57aa3SJens Axboe 		.buffer_select		= 1,
342d9b57aa3SJens Axboe 		.audit_skip		= 1,
343d9b57aa3SJens Axboe 		.ioprio			= 1,
344d9b57aa3SJens Axboe 		.name			= "RECV",
345d9b57aa3SJens Axboe #if defined(CONFIG_NET)
346d9b57aa3SJens Axboe 		.prep			= io_recvmsg_prep,
347d9b57aa3SJens Axboe 		.issue			= io_recv,
3487e6b638eSPavel Begunkov 		.fail			= io_sendrecv_fail,
349d9b57aa3SJens Axboe #else
350d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
351d9b57aa3SJens Axboe #endif
352d9b57aa3SJens Axboe 	},
353d9b57aa3SJens Axboe 	[IORING_OP_OPENAT2] = {
354d9b57aa3SJens Axboe 		.name			= "OPENAT2",
355d9b57aa3SJens Axboe 		.prep			= io_openat2_prep,
356d9b57aa3SJens Axboe 		.issue			= io_openat2,
357d9b57aa3SJens Axboe 		.cleanup		= io_open_cleanup,
358d9b57aa3SJens Axboe 	},
359d9b57aa3SJens Axboe 	[IORING_OP_EPOLL_CTL] = {
360d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
361d9b57aa3SJens Axboe 		.audit_skip		= 1,
362d9b57aa3SJens Axboe 		.name			= "EPOLL",
363d9b57aa3SJens Axboe #if defined(CONFIG_EPOLL)
364d9b57aa3SJens Axboe 		.prep			= io_epoll_ctl_prep,
365d9b57aa3SJens Axboe 		.issue			= io_epoll_ctl,
366d9b57aa3SJens Axboe #else
367d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
368d9b57aa3SJens Axboe #endif
369d9b57aa3SJens Axboe 	},
370d9b57aa3SJens Axboe 	[IORING_OP_SPLICE] = {
371d9b57aa3SJens Axboe 		.needs_file		= 1,
372d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
373d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
374d9b57aa3SJens Axboe 		.audit_skip		= 1,
375d9b57aa3SJens Axboe 		.name			= "SPLICE",
376d9b57aa3SJens Axboe 		.prep			= io_splice_prep,
377d9b57aa3SJens Axboe 		.issue			= io_splice,
378d9b57aa3SJens Axboe 	},
379d9b57aa3SJens Axboe 	[IORING_OP_PROVIDE_BUFFERS] = {
380d9b57aa3SJens Axboe 		.audit_skip		= 1,
381d9b57aa3SJens Axboe 		.iopoll			= 1,
382d9b57aa3SJens Axboe 		.name			= "PROVIDE_BUFFERS",
383d9b57aa3SJens Axboe 		.prep			= io_provide_buffers_prep,
384d9b57aa3SJens Axboe 		.issue			= io_provide_buffers,
385d9b57aa3SJens Axboe 	},
386d9b57aa3SJens Axboe 	[IORING_OP_REMOVE_BUFFERS] = {
387d9b57aa3SJens Axboe 		.audit_skip		= 1,
388d9b57aa3SJens Axboe 		.iopoll			= 1,
389d9b57aa3SJens Axboe 		.name			= "REMOVE_BUFFERS",
390d9b57aa3SJens Axboe 		.prep			= io_remove_buffers_prep,
391d9b57aa3SJens Axboe 		.issue			= io_remove_buffers,
392d9b57aa3SJens Axboe 	},
393d9b57aa3SJens Axboe 	[IORING_OP_TEE] = {
394d9b57aa3SJens Axboe 		.needs_file		= 1,
395d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
396d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
397d9b57aa3SJens Axboe 		.audit_skip		= 1,
398d9b57aa3SJens Axboe 		.name			= "TEE",
399d9b57aa3SJens Axboe 		.prep			= io_tee_prep,
400d9b57aa3SJens Axboe 		.issue			= io_tee,
401d9b57aa3SJens Axboe 	},
402d9b57aa3SJens Axboe 	[IORING_OP_SHUTDOWN] = {
403d9b57aa3SJens Axboe 		.needs_file		= 1,
404d9b57aa3SJens Axboe 		.name			= "SHUTDOWN",
405d9b57aa3SJens Axboe #if defined(CONFIG_NET)
406d9b57aa3SJens Axboe 		.prep			= io_shutdown_prep,
407d9b57aa3SJens Axboe 		.issue			= io_shutdown,
408d9b57aa3SJens Axboe #else
409d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
410d9b57aa3SJens Axboe #endif
411d9b57aa3SJens Axboe 	},
412d9b57aa3SJens Axboe 	[IORING_OP_RENAMEAT] = {
413d9b57aa3SJens Axboe 		.name			= "RENAMEAT",
414d9b57aa3SJens Axboe 		.prep			= io_renameat_prep,
415d9b57aa3SJens Axboe 		.issue			= io_renameat,
416d9b57aa3SJens Axboe 		.cleanup		= io_renameat_cleanup,
417d9b57aa3SJens Axboe 	},
418d9b57aa3SJens Axboe 	[IORING_OP_UNLINKAT] = {
419d9b57aa3SJens Axboe 		.name			= "UNLINKAT",
420d9b57aa3SJens Axboe 		.prep			= io_unlinkat_prep,
421d9b57aa3SJens Axboe 		.issue			= io_unlinkat,
422d9b57aa3SJens Axboe 		.cleanup		= io_unlinkat_cleanup,
423d9b57aa3SJens Axboe 	},
424d9b57aa3SJens Axboe 	[IORING_OP_MKDIRAT] = {
425d9b57aa3SJens Axboe 		.name			= "MKDIRAT",
426d9b57aa3SJens Axboe 		.prep			= io_mkdirat_prep,
427d9b57aa3SJens Axboe 		.issue			= io_mkdirat,
428d9b57aa3SJens Axboe 		.cleanup		= io_mkdirat_cleanup,
429d9b57aa3SJens Axboe 	},
430d9b57aa3SJens Axboe 	[IORING_OP_SYMLINKAT] = {
431d9b57aa3SJens Axboe 		.name			= "SYMLINKAT",
432d9b57aa3SJens Axboe 		.prep			= io_symlinkat_prep,
433d9b57aa3SJens Axboe 		.issue			= io_symlinkat,
434d9b57aa3SJens Axboe 		.cleanup		= io_link_cleanup,
435d9b57aa3SJens Axboe 	},
436d9b57aa3SJens Axboe 	[IORING_OP_LINKAT] = {
437d9b57aa3SJens Axboe 		.name			= "LINKAT",
438d9b57aa3SJens Axboe 		.prep			= io_linkat_prep,
439d9b57aa3SJens Axboe 		.issue			= io_linkat,
440d9b57aa3SJens Axboe 		.cleanup		= io_link_cleanup,
441d9b57aa3SJens Axboe 	},
442d9b57aa3SJens Axboe 	[IORING_OP_MSG_RING] = {
443d9b57aa3SJens Axboe 		.needs_file		= 1,
444d9b57aa3SJens Axboe 		.iopoll			= 1,
445d9b57aa3SJens Axboe 		.name			= "MSG_RING",
446d9b57aa3SJens Axboe 		.prep			= io_msg_ring_prep,
447d9b57aa3SJens Axboe 		.issue			= io_msg_ring,
448d9b57aa3SJens Axboe 	},
449d9b57aa3SJens Axboe 	[IORING_OP_FSETXATTR] = {
450d9b57aa3SJens Axboe 		.needs_file = 1,
451d9b57aa3SJens Axboe 		.name			= "FSETXATTR",
452d9b57aa3SJens Axboe 		.prep			= io_fsetxattr_prep,
453d9b57aa3SJens Axboe 		.issue			= io_fsetxattr,
454d9b57aa3SJens Axboe 		.cleanup		= io_xattr_cleanup,
455d9b57aa3SJens Axboe 	},
456d9b57aa3SJens Axboe 	[IORING_OP_SETXATTR] = {
457d9b57aa3SJens Axboe 		.name			= "SETXATTR",
458d9b57aa3SJens Axboe 		.prep			= io_setxattr_prep,
459d9b57aa3SJens Axboe 		.issue			= io_setxattr,
460d9b57aa3SJens Axboe 		.cleanup		= io_xattr_cleanup,
461d9b57aa3SJens Axboe 	},
462d9b57aa3SJens Axboe 	[IORING_OP_FGETXATTR] = {
463d9b57aa3SJens Axboe 		.needs_file = 1,
464d9b57aa3SJens Axboe 		.name			= "FGETXATTR",
465d9b57aa3SJens Axboe 		.prep			= io_fgetxattr_prep,
466d9b57aa3SJens Axboe 		.issue			= io_fgetxattr,
467d9b57aa3SJens Axboe 		.cleanup		= io_xattr_cleanup,
468d9b57aa3SJens Axboe 	},
469d9b57aa3SJens Axboe 	[IORING_OP_GETXATTR] = {
470d9b57aa3SJens Axboe 		.name			= "GETXATTR",
471d9b57aa3SJens Axboe 		.prep			= io_getxattr_prep,
472d9b57aa3SJens Axboe 		.issue			= io_getxattr,
473d9b57aa3SJens Axboe 		.cleanup		= io_xattr_cleanup,
474d9b57aa3SJens Axboe 	},
475d9b57aa3SJens Axboe 	[IORING_OP_SOCKET] = {
476d9b57aa3SJens Axboe 		.audit_skip		= 1,
477d9b57aa3SJens Axboe 		.name			= "SOCKET",
478d9b57aa3SJens Axboe #if defined(CONFIG_NET)
479d9b57aa3SJens Axboe 		.prep			= io_socket_prep,
480d9b57aa3SJens Axboe 		.issue			= io_socket,
481d9b57aa3SJens Axboe #else
482d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
483d9b57aa3SJens Axboe #endif
484d9b57aa3SJens Axboe 	},
485d9b57aa3SJens Axboe 	[IORING_OP_URING_CMD] = {
486d9b57aa3SJens Axboe 		.needs_file		= 1,
487d9b57aa3SJens Axboe 		.plug			= 1,
488d9b57aa3SJens Axboe 		.name			= "URING_CMD",
4895756a3a7SKanchan Joshi 		.iopoll			= 1,
490*ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
491d9b57aa3SJens Axboe 		.async_size		= uring_cmd_pdu_size(1),
492d9b57aa3SJens Axboe 		.prep			= io_uring_cmd_prep,
493d9b57aa3SJens Axboe 		.issue			= io_uring_cmd,
494d9b57aa3SJens Axboe 		.prep_async		= io_uring_cmd_prep_async,
495d9b57aa3SJens Axboe 	},
496b48c312bSPavel Begunkov 	[IORING_OP_SEND_ZC] = {
4979bd3f728SStefan Metzmacher 		.name			= "SEND_ZC",
49806a5464bSPavel Begunkov 		.needs_file		= 1,
49906a5464bSPavel Begunkov 		.unbound_nonreg_file	= 1,
50006a5464bSPavel Begunkov 		.pollout		= 1,
50106a5464bSPavel Begunkov 		.audit_skip		= 1,
50206a5464bSPavel Begunkov 		.ioprio			= 1,
503581711c4SPavel Begunkov 		.manual_alloc		= 1,
50406a5464bSPavel Begunkov #if defined(CONFIG_NET)
505581711c4SPavel Begunkov 		.async_size		= sizeof(struct io_async_msghdr),
506b0e9b551SPavel Begunkov 		.prep			= io_send_zc_prep,
507b0e9b551SPavel Begunkov 		.issue			= io_send_zc,
508516e82f0SPavel Begunkov 		.prep_async		= io_send_prep_async,
509b0e9b551SPavel Begunkov 		.cleanup		= io_send_zc_cleanup,
510c4c0009eSPavel Begunkov 		.fail			= io_sendrecv_fail,
51106a5464bSPavel Begunkov #else
51206a5464bSPavel Begunkov 		.prep			= io_eopnotsupp_prep,
51306a5464bSPavel Begunkov #endif
51406a5464bSPavel Begunkov 	},
515493108d9SPavel Begunkov 	[IORING_OP_SENDMSG_ZC] = {
516493108d9SPavel Begunkov 		.name			= "SENDMSG_ZC",
517493108d9SPavel Begunkov 		.needs_file		= 1,
518493108d9SPavel Begunkov 		.unbound_nonreg_file	= 1,
519493108d9SPavel Begunkov 		.pollout		= 1,
520493108d9SPavel Begunkov 		.ioprio			= 1,
521493108d9SPavel Begunkov 		.manual_alloc		= 1,
522493108d9SPavel Begunkov #if defined(CONFIG_NET)
523493108d9SPavel Begunkov 		.async_size		= sizeof(struct io_async_msghdr),
524493108d9SPavel Begunkov 		.prep			= io_send_zc_prep,
525493108d9SPavel Begunkov 		.issue			= io_sendmsg_zc,
526493108d9SPavel Begunkov 		.prep_async		= io_sendmsg_prep_async,
527493108d9SPavel Begunkov 		.cleanup		= io_send_zc_cleanup,
528493108d9SPavel Begunkov 		.fail			= io_sendrecv_fail,
529493108d9SPavel Begunkov #else
530493108d9SPavel Begunkov 		.prep			= io_eopnotsupp_prep,
531493108d9SPavel Begunkov #endif
532493108d9SPavel Begunkov 	},
533d9b57aa3SJens Axboe };
534d9b57aa3SJens Axboe 
535d9b57aa3SJens Axboe const char *io_uring_get_opcode(u8 opcode)
536d9b57aa3SJens Axboe {
537d9b57aa3SJens Axboe 	if (opcode < IORING_OP_LAST)
538d9b57aa3SJens Axboe 		return io_op_defs[opcode].name;
539d9b57aa3SJens Axboe 	return "INVALID";
540d9b57aa3SJens Axboe }
541d9b57aa3SJens Axboe 
542d9b57aa3SJens Axboe void __init io_uring_optable_init(void)
543d9b57aa3SJens Axboe {
544d9b57aa3SJens Axboe 	int i;
545d9b57aa3SJens Axboe 
546d9b57aa3SJens Axboe 	BUILD_BUG_ON(ARRAY_SIZE(io_op_defs) != IORING_OP_LAST);
547d9b57aa3SJens Axboe 
548d9b57aa3SJens Axboe 	for (i = 0; i < ARRAY_SIZE(io_op_defs); i++) {
549d9b57aa3SJens Axboe 		BUG_ON(!io_op_defs[i].prep);
550d9b57aa3SJens Axboe 		if (io_op_defs[i].prep != io_eopnotsupp_prep)
551d9b57aa3SJens Axboe 			BUG_ON(!io_op_defs[i].issue);
552d9b57aa3SJens Axboe 		WARN_ON_ONCE(!io_op_defs[i].name);
553d9b57aa3SJens Axboe 	}
554d9b57aa3SJens Axboe }
555