xref: /openbmc/linux/io_uring/opdef.c (revision 5756a3a7)
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,
66d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
67d9b57aa3SJens Axboe 		.name			= "READV",
68d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
69d9b57aa3SJens Axboe 		.issue			= io_read,
70d9b57aa3SJens Axboe 		.prep_async		= io_readv_prep_async,
71d9b57aa3SJens Axboe 		.cleanup		= io_readv_writev_cleanup,
72d9b57aa3SJens Axboe 	},
73d9b57aa3SJens Axboe 	[IORING_OP_WRITEV] = {
74d9b57aa3SJens Axboe 		.needs_file		= 1,
75d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
76d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
77d9b57aa3SJens Axboe 		.pollout		= 1,
78d9b57aa3SJens Axboe 		.plug			= 1,
79d9b57aa3SJens Axboe 		.audit_skip		= 1,
80d9b57aa3SJens Axboe 		.ioprio			= 1,
81d9b57aa3SJens Axboe 		.iopoll			= 1,
82d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
83d9b57aa3SJens Axboe 		.name			= "WRITEV",
84d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
85d9b57aa3SJens Axboe 		.issue			= io_write,
86d9b57aa3SJens Axboe 		.prep_async		= io_writev_prep_async,
87d9b57aa3SJens Axboe 		.cleanup		= io_readv_writev_cleanup,
88d9b57aa3SJens Axboe 	},
89d9b57aa3SJens Axboe 	[IORING_OP_FSYNC] = {
90d9b57aa3SJens Axboe 		.needs_file		= 1,
91d9b57aa3SJens Axboe 		.audit_skip		= 1,
92d9b57aa3SJens Axboe 		.name			= "FSYNC",
93d9b57aa3SJens Axboe 		.prep			= io_fsync_prep,
94d9b57aa3SJens Axboe 		.issue			= io_fsync,
95d9b57aa3SJens Axboe 	},
96d9b57aa3SJens Axboe 	[IORING_OP_READ_FIXED] = {
97d9b57aa3SJens Axboe 		.needs_file		= 1,
98d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
99d9b57aa3SJens Axboe 		.pollin			= 1,
100d9b57aa3SJens Axboe 		.plug			= 1,
101d9b57aa3SJens Axboe 		.audit_skip		= 1,
102d9b57aa3SJens Axboe 		.ioprio			= 1,
103d9b57aa3SJens Axboe 		.iopoll			= 1,
104d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
105d9b57aa3SJens Axboe 		.name			= "READ_FIXED",
106d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
107d9b57aa3SJens Axboe 		.issue			= io_read,
108d9b57aa3SJens Axboe 	},
109d9b57aa3SJens Axboe 	[IORING_OP_WRITE_FIXED] = {
110d9b57aa3SJens Axboe 		.needs_file		= 1,
111d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
112d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
113d9b57aa3SJens Axboe 		.pollout		= 1,
114d9b57aa3SJens Axboe 		.plug			= 1,
115d9b57aa3SJens Axboe 		.audit_skip		= 1,
116d9b57aa3SJens Axboe 		.ioprio			= 1,
117d9b57aa3SJens Axboe 		.iopoll			= 1,
118d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
119d9b57aa3SJens Axboe 		.name			= "WRITE_FIXED",
120d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
121d9b57aa3SJens Axboe 		.issue			= io_write,
122d9b57aa3SJens Axboe 	},
123d9b57aa3SJens Axboe 	[IORING_OP_POLL_ADD] = {
124d9b57aa3SJens Axboe 		.needs_file		= 1,
125d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
126d9b57aa3SJens Axboe 		.audit_skip		= 1,
127d9b57aa3SJens Axboe 		.name			= "POLL_ADD",
128d9b57aa3SJens Axboe 		.prep			= io_poll_add_prep,
129d9b57aa3SJens Axboe 		.issue			= io_poll_add,
130d9b57aa3SJens Axboe 	},
131d9b57aa3SJens Axboe 	[IORING_OP_POLL_REMOVE] = {
132d9b57aa3SJens Axboe 		.audit_skip		= 1,
133d9b57aa3SJens Axboe 		.name			= "POLL_REMOVE",
134d9b57aa3SJens Axboe 		.prep			= io_poll_remove_prep,
135d9b57aa3SJens Axboe 		.issue			= io_poll_remove,
136d9b57aa3SJens Axboe 	},
137d9b57aa3SJens Axboe 	[IORING_OP_SYNC_FILE_RANGE] = {
138d9b57aa3SJens Axboe 		.needs_file		= 1,
139d9b57aa3SJens Axboe 		.audit_skip		= 1,
140d9b57aa3SJens Axboe 		.name			= "SYNC_FILE_RANGE",
141d9b57aa3SJens Axboe 		.prep			= io_sfr_prep,
142d9b57aa3SJens Axboe 		.issue			= io_sync_file_range,
143d9b57aa3SJens Axboe 	},
144d9b57aa3SJens Axboe 	[IORING_OP_SENDMSG] = {
145d9b57aa3SJens Axboe 		.needs_file		= 1,
146d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
147d9b57aa3SJens Axboe 		.pollout		= 1,
148d9b57aa3SJens Axboe 		.ioprio			= 1,
149d9b57aa3SJens Axboe 		.name			= "SENDMSG",
150d9b57aa3SJens Axboe #if defined(CONFIG_NET)
151d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_msghdr),
152d9b57aa3SJens Axboe 		.prep			= io_sendmsg_prep,
153d9b57aa3SJens Axboe 		.issue			= io_sendmsg,
154d9b57aa3SJens Axboe 		.prep_async		= io_sendmsg_prep_async,
155d9b57aa3SJens Axboe 		.cleanup		= io_sendmsg_recvmsg_cleanup,
156d9b57aa3SJens Axboe #else
157d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
158d9b57aa3SJens Axboe #endif
159d9b57aa3SJens Axboe 	},
160d9b57aa3SJens Axboe 	[IORING_OP_RECVMSG] = {
161d9b57aa3SJens Axboe 		.needs_file		= 1,
162d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
163d9b57aa3SJens Axboe 		.pollin			= 1,
164d9b57aa3SJens Axboe 		.buffer_select		= 1,
165d9b57aa3SJens Axboe 		.ioprio			= 1,
166d9b57aa3SJens Axboe 		.name			= "RECVMSG",
167d9b57aa3SJens Axboe #if defined(CONFIG_NET)
168d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_msghdr),
169d9b57aa3SJens Axboe 		.prep			= io_recvmsg_prep,
170d9b57aa3SJens Axboe 		.issue			= io_recvmsg,
171d9b57aa3SJens Axboe 		.prep_async		= io_recvmsg_prep_async,
172d9b57aa3SJens Axboe 		.cleanup		= io_sendmsg_recvmsg_cleanup,
173d9b57aa3SJens Axboe #else
174d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
175d9b57aa3SJens Axboe #endif
176d9b57aa3SJens Axboe 	},
177d9b57aa3SJens Axboe 	[IORING_OP_TIMEOUT] = {
178d9b57aa3SJens Axboe 		.audit_skip		= 1,
179d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_timeout_data),
180d9b57aa3SJens Axboe 		.name			= "TIMEOUT",
181d9b57aa3SJens Axboe 		.prep			= io_timeout_prep,
182d9b57aa3SJens Axboe 		.issue			= io_timeout,
183d9b57aa3SJens Axboe 	},
184d9b57aa3SJens Axboe 	[IORING_OP_TIMEOUT_REMOVE] = {
185d9b57aa3SJens Axboe 		/* used by timeout updates' prep() */
186d9b57aa3SJens Axboe 		.audit_skip		= 1,
187d9b57aa3SJens Axboe 		.name			= "TIMEOUT_REMOVE",
188d9b57aa3SJens Axboe 		.prep			= io_timeout_remove_prep,
189d9b57aa3SJens Axboe 		.issue			= io_timeout_remove,
190d9b57aa3SJens Axboe 	},
191d9b57aa3SJens Axboe 	[IORING_OP_ACCEPT] = {
192d9b57aa3SJens Axboe 		.needs_file		= 1,
193d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
194d9b57aa3SJens Axboe 		.pollin			= 1,
195d9b57aa3SJens Axboe 		.poll_exclusive		= 1,
196d9b57aa3SJens Axboe 		.ioprio			= 1,	/* used for flags */
197d9b57aa3SJens Axboe 		.name			= "ACCEPT",
198d9b57aa3SJens Axboe #if defined(CONFIG_NET)
199d9b57aa3SJens Axboe 		.prep			= io_accept_prep,
200d9b57aa3SJens Axboe 		.issue			= io_accept,
201d9b57aa3SJens Axboe #else
202d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
203d9b57aa3SJens Axboe #endif
204d9b57aa3SJens Axboe 	},
205d9b57aa3SJens Axboe 	[IORING_OP_ASYNC_CANCEL] = {
206d9b57aa3SJens Axboe 		.audit_skip		= 1,
207d9b57aa3SJens Axboe 		.name			= "ASYNC_CANCEL",
208d9b57aa3SJens Axboe 		.prep			= io_async_cancel_prep,
209d9b57aa3SJens Axboe 		.issue			= io_async_cancel,
210d9b57aa3SJens Axboe 	},
211d9b57aa3SJens Axboe 	[IORING_OP_LINK_TIMEOUT] = {
212d9b57aa3SJens Axboe 		.audit_skip		= 1,
213d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_timeout_data),
214d9b57aa3SJens Axboe 		.name			= "LINK_TIMEOUT",
215d9b57aa3SJens Axboe 		.prep			= io_link_timeout_prep,
216d9b57aa3SJens Axboe 		.issue			= io_no_issue,
217d9b57aa3SJens Axboe 	},
218d9b57aa3SJens Axboe 	[IORING_OP_CONNECT] = {
219d9b57aa3SJens Axboe 		.needs_file		= 1,
220d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
221d9b57aa3SJens Axboe 		.pollout		= 1,
222d9b57aa3SJens Axboe 		.name			= "CONNECT",
223d9b57aa3SJens Axboe #if defined(CONFIG_NET)
224d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_connect),
225d9b57aa3SJens Axboe 		.prep			= io_connect_prep,
226d9b57aa3SJens Axboe 		.issue			= io_connect,
227d9b57aa3SJens Axboe 		.prep_async		= io_connect_prep_async,
228d9b57aa3SJens Axboe #else
229d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
230d9b57aa3SJens Axboe #endif
231d9b57aa3SJens Axboe 	},
232d9b57aa3SJens Axboe 	[IORING_OP_FALLOCATE] = {
233d9b57aa3SJens Axboe 		.needs_file		= 1,
234d9b57aa3SJens Axboe 		.name			= "FALLOCATE",
235d9b57aa3SJens Axboe 		.prep			= io_fallocate_prep,
236d9b57aa3SJens Axboe 		.issue			= io_fallocate,
237d9b57aa3SJens Axboe 	},
238d9b57aa3SJens Axboe 	[IORING_OP_OPENAT] = {
239d9b57aa3SJens Axboe 		.name			= "OPENAT",
240d9b57aa3SJens Axboe 		.prep			= io_openat_prep,
241d9b57aa3SJens Axboe 		.issue			= io_openat,
242d9b57aa3SJens Axboe 		.cleanup		= io_open_cleanup,
243d9b57aa3SJens Axboe 	},
244d9b57aa3SJens Axboe 	[IORING_OP_CLOSE] = {
245d9b57aa3SJens Axboe 		.name			= "CLOSE",
246d9b57aa3SJens Axboe 		.prep			= io_close_prep,
247d9b57aa3SJens Axboe 		.issue			= io_close,
248d9b57aa3SJens Axboe 	},
249d9808cebSPavel Begunkov 	[IORING_OP_FILES_UPDATE] = {
250d9b57aa3SJens Axboe 		.audit_skip		= 1,
251d9b57aa3SJens Axboe 		.iopoll			= 1,
252d9808cebSPavel Begunkov 		.name			= "FILES_UPDATE",
253d9808cebSPavel Begunkov 		.prep			= io_files_update_prep,
254d9808cebSPavel Begunkov 		.issue			= io_files_update,
255d9b57aa3SJens Axboe 	},
256d9b57aa3SJens Axboe 	[IORING_OP_STATX] = {
257d9b57aa3SJens Axboe 		.audit_skip		= 1,
258d9b57aa3SJens Axboe 		.name			= "STATX",
259d9b57aa3SJens Axboe 		.prep			= io_statx_prep,
260d9b57aa3SJens Axboe 		.issue			= io_statx,
261d9b57aa3SJens Axboe 		.cleanup		= io_statx_cleanup,
262d9b57aa3SJens Axboe 	},
263d9b57aa3SJens Axboe 	[IORING_OP_READ] = {
264d9b57aa3SJens Axboe 		.needs_file		= 1,
265d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
266d9b57aa3SJens Axboe 		.pollin			= 1,
267d9b57aa3SJens Axboe 		.buffer_select		= 1,
268d9b57aa3SJens Axboe 		.plug			= 1,
269d9b57aa3SJens Axboe 		.audit_skip		= 1,
270d9b57aa3SJens Axboe 		.ioprio			= 1,
271d9b57aa3SJens Axboe 		.iopoll			= 1,
272d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
273d9b57aa3SJens Axboe 		.name			= "READ",
274d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
275d9b57aa3SJens Axboe 		.issue			= io_read,
276d9b57aa3SJens Axboe 	},
277d9b57aa3SJens Axboe 	[IORING_OP_WRITE] = {
278d9b57aa3SJens Axboe 		.needs_file		= 1,
279d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
280d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
281d9b57aa3SJens Axboe 		.pollout		= 1,
282d9b57aa3SJens Axboe 		.plug			= 1,
283d9b57aa3SJens Axboe 		.audit_skip		= 1,
284d9b57aa3SJens Axboe 		.ioprio			= 1,
285d9b57aa3SJens Axboe 		.iopoll			= 1,
286d9b57aa3SJens Axboe 		.async_size		= sizeof(struct io_async_rw),
287d9b57aa3SJens Axboe 		.name			= "WRITE",
288d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
289d9b57aa3SJens Axboe 		.issue			= io_write,
290d9b57aa3SJens Axboe 	},
291d9b57aa3SJens Axboe 	[IORING_OP_FADVISE] = {
292d9b57aa3SJens Axboe 		.needs_file		= 1,
293d9b57aa3SJens Axboe 		.audit_skip		= 1,
294d9b57aa3SJens Axboe 		.name			= "FADVISE",
295d9b57aa3SJens Axboe 		.prep			= io_fadvise_prep,
296d9b57aa3SJens Axboe 		.issue			= io_fadvise,
297d9b57aa3SJens Axboe 	},
298d9b57aa3SJens Axboe 	[IORING_OP_MADVISE] = {
299d9b57aa3SJens Axboe 		.name			= "MADVISE",
300d9b57aa3SJens Axboe 		.prep			= io_madvise_prep,
301d9b57aa3SJens Axboe 		.issue			= io_madvise,
302d9b57aa3SJens Axboe 	},
303d9b57aa3SJens Axboe 	[IORING_OP_SEND] = {
304d9b57aa3SJens Axboe 		.needs_file		= 1,
305d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
306d9b57aa3SJens Axboe 		.pollout		= 1,
307d9b57aa3SJens Axboe 		.audit_skip		= 1,
308d9b57aa3SJens Axboe 		.ioprio			= 1,
309d9b57aa3SJens Axboe 		.name			= "SEND",
310d9b57aa3SJens Axboe #if defined(CONFIG_NET)
311d9b57aa3SJens Axboe 		.prep			= io_sendmsg_prep,
312d9b57aa3SJens Axboe 		.issue			= io_send,
313d9b57aa3SJens Axboe #else
314d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
315d9b57aa3SJens Axboe #endif
316d9b57aa3SJens Axboe 	},
317d9b57aa3SJens Axboe 	[IORING_OP_RECV] = {
318d9b57aa3SJens Axboe 		.needs_file		= 1,
319d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
320d9b57aa3SJens Axboe 		.pollin			= 1,
321d9b57aa3SJens Axboe 		.buffer_select		= 1,
322d9b57aa3SJens Axboe 		.audit_skip		= 1,
323d9b57aa3SJens Axboe 		.ioprio			= 1,
324d9b57aa3SJens Axboe 		.name			= "RECV",
325d9b57aa3SJens Axboe #if defined(CONFIG_NET)
326d9b57aa3SJens Axboe 		.prep			= io_recvmsg_prep,
327d9b57aa3SJens Axboe 		.issue			= io_recv,
328d9b57aa3SJens Axboe #else
329d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
330d9b57aa3SJens Axboe #endif
331d9b57aa3SJens Axboe 	},
332d9b57aa3SJens Axboe 	[IORING_OP_OPENAT2] = {
333d9b57aa3SJens Axboe 		.name			= "OPENAT2",
334d9b57aa3SJens Axboe 		.prep			= io_openat2_prep,
335d9b57aa3SJens Axboe 		.issue			= io_openat2,
336d9b57aa3SJens Axboe 		.cleanup		= io_open_cleanup,
337d9b57aa3SJens Axboe 	},
338d9b57aa3SJens Axboe 	[IORING_OP_EPOLL_CTL] = {
339d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
340d9b57aa3SJens Axboe 		.audit_skip		= 1,
341d9b57aa3SJens Axboe 		.name			= "EPOLL",
342d9b57aa3SJens Axboe #if defined(CONFIG_EPOLL)
343d9b57aa3SJens Axboe 		.prep			= io_epoll_ctl_prep,
344d9b57aa3SJens Axboe 		.issue			= io_epoll_ctl,
345d9b57aa3SJens Axboe #else
346d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
347d9b57aa3SJens Axboe #endif
348d9b57aa3SJens Axboe 	},
349d9b57aa3SJens Axboe 	[IORING_OP_SPLICE] = {
350d9b57aa3SJens Axboe 		.needs_file		= 1,
351d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
352d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
353d9b57aa3SJens Axboe 		.audit_skip		= 1,
354d9b57aa3SJens Axboe 		.name			= "SPLICE",
355d9b57aa3SJens Axboe 		.prep			= io_splice_prep,
356d9b57aa3SJens Axboe 		.issue			= io_splice,
357d9b57aa3SJens Axboe 	},
358d9b57aa3SJens Axboe 	[IORING_OP_PROVIDE_BUFFERS] = {
359d9b57aa3SJens Axboe 		.audit_skip		= 1,
360d9b57aa3SJens Axboe 		.iopoll			= 1,
361d9b57aa3SJens Axboe 		.name			= "PROVIDE_BUFFERS",
362d9b57aa3SJens Axboe 		.prep			= io_provide_buffers_prep,
363d9b57aa3SJens Axboe 		.issue			= io_provide_buffers,
364d9b57aa3SJens Axboe 	},
365d9b57aa3SJens Axboe 	[IORING_OP_REMOVE_BUFFERS] = {
366d9b57aa3SJens Axboe 		.audit_skip		= 1,
367d9b57aa3SJens Axboe 		.iopoll			= 1,
368d9b57aa3SJens Axboe 		.name			= "REMOVE_BUFFERS",
369d9b57aa3SJens Axboe 		.prep			= io_remove_buffers_prep,
370d9b57aa3SJens Axboe 		.issue			= io_remove_buffers,
371d9b57aa3SJens Axboe 	},
372d9b57aa3SJens Axboe 	[IORING_OP_TEE] = {
373d9b57aa3SJens Axboe 		.needs_file		= 1,
374d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
375d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
376d9b57aa3SJens Axboe 		.audit_skip		= 1,
377d9b57aa3SJens Axboe 		.name			= "TEE",
378d9b57aa3SJens Axboe 		.prep			= io_tee_prep,
379d9b57aa3SJens Axboe 		.issue			= io_tee,
380d9b57aa3SJens Axboe 	},
381d9b57aa3SJens Axboe 	[IORING_OP_SHUTDOWN] = {
382d9b57aa3SJens Axboe 		.needs_file		= 1,
383d9b57aa3SJens Axboe 		.name			= "SHUTDOWN",
384d9b57aa3SJens Axboe #if defined(CONFIG_NET)
385d9b57aa3SJens Axboe 		.prep			= io_shutdown_prep,
386d9b57aa3SJens Axboe 		.issue			= io_shutdown,
387d9b57aa3SJens Axboe #else
388d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
389d9b57aa3SJens Axboe #endif
390d9b57aa3SJens Axboe 	},
391d9b57aa3SJens Axboe 	[IORING_OP_RENAMEAT] = {
392d9b57aa3SJens Axboe 		.name			= "RENAMEAT",
393d9b57aa3SJens Axboe 		.prep			= io_renameat_prep,
394d9b57aa3SJens Axboe 		.issue			= io_renameat,
395d9b57aa3SJens Axboe 		.cleanup		= io_renameat_cleanup,
396d9b57aa3SJens Axboe 	},
397d9b57aa3SJens Axboe 	[IORING_OP_UNLINKAT] = {
398d9b57aa3SJens Axboe 		.name			= "UNLINKAT",
399d9b57aa3SJens Axboe 		.prep			= io_unlinkat_prep,
400d9b57aa3SJens Axboe 		.issue			= io_unlinkat,
401d9b57aa3SJens Axboe 		.cleanup		= io_unlinkat_cleanup,
402d9b57aa3SJens Axboe 	},
403d9b57aa3SJens Axboe 	[IORING_OP_MKDIRAT] = {
404d9b57aa3SJens Axboe 		.name			= "MKDIRAT",
405d9b57aa3SJens Axboe 		.prep			= io_mkdirat_prep,
406d9b57aa3SJens Axboe 		.issue			= io_mkdirat,
407d9b57aa3SJens Axboe 		.cleanup		= io_mkdirat_cleanup,
408d9b57aa3SJens Axboe 	},
409d9b57aa3SJens Axboe 	[IORING_OP_SYMLINKAT] = {
410d9b57aa3SJens Axboe 		.name			= "SYMLINKAT",
411d9b57aa3SJens Axboe 		.prep			= io_symlinkat_prep,
412d9b57aa3SJens Axboe 		.issue			= io_symlinkat,
413d9b57aa3SJens Axboe 		.cleanup		= io_link_cleanup,
414d9b57aa3SJens Axboe 	},
415d9b57aa3SJens Axboe 	[IORING_OP_LINKAT] = {
416d9b57aa3SJens Axboe 		.name			= "LINKAT",
417d9b57aa3SJens Axboe 		.prep			= io_linkat_prep,
418d9b57aa3SJens Axboe 		.issue			= io_linkat,
419d9b57aa3SJens Axboe 		.cleanup		= io_link_cleanup,
420d9b57aa3SJens Axboe 	},
421d9b57aa3SJens Axboe 	[IORING_OP_MSG_RING] = {
422d9b57aa3SJens Axboe 		.needs_file		= 1,
423d9b57aa3SJens Axboe 		.iopoll			= 1,
424d9b57aa3SJens Axboe 		.name			= "MSG_RING",
425d9b57aa3SJens Axboe 		.prep			= io_msg_ring_prep,
426d9b57aa3SJens Axboe 		.issue			= io_msg_ring,
427d9b57aa3SJens Axboe 	},
428d9b57aa3SJens Axboe 	[IORING_OP_FSETXATTR] = {
429d9b57aa3SJens Axboe 		.needs_file = 1,
430d9b57aa3SJens Axboe 		.name			= "FSETXATTR",
431d9b57aa3SJens Axboe 		.prep			= io_fsetxattr_prep,
432d9b57aa3SJens Axboe 		.issue			= io_fsetxattr,
433d9b57aa3SJens Axboe 		.cleanup		= io_xattr_cleanup,
434d9b57aa3SJens Axboe 	},
435d9b57aa3SJens Axboe 	[IORING_OP_SETXATTR] = {
436d9b57aa3SJens Axboe 		.name			= "SETXATTR",
437d9b57aa3SJens Axboe 		.prep			= io_setxattr_prep,
438d9b57aa3SJens Axboe 		.issue			= io_setxattr,
439d9b57aa3SJens Axboe 		.cleanup		= io_xattr_cleanup,
440d9b57aa3SJens Axboe 	},
441d9b57aa3SJens Axboe 	[IORING_OP_FGETXATTR] = {
442d9b57aa3SJens Axboe 		.needs_file = 1,
443d9b57aa3SJens Axboe 		.name			= "FGETXATTR",
444d9b57aa3SJens Axboe 		.prep			= io_fgetxattr_prep,
445d9b57aa3SJens Axboe 		.issue			= io_fgetxattr,
446d9b57aa3SJens Axboe 		.cleanup		= io_xattr_cleanup,
447d9b57aa3SJens Axboe 	},
448d9b57aa3SJens Axboe 	[IORING_OP_GETXATTR] = {
449d9b57aa3SJens Axboe 		.name			= "GETXATTR",
450d9b57aa3SJens Axboe 		.prep			= io_getxattr_prep,
451d9b57aa3SJens Axboe 		.issue			= io_getxattr,
452d9b57aa3SJens Axboe 		.cleanup		= io_xattr_cleanup,
453d9b57aa3SJens Axboe 	},
454d9b57aa3SJens Axboe 	[IORING_OP_SOCKET] = {
455d9b57aa3SJens Axboe 		.audit_skip		= 1,
456d9b57aa3SJens Axboe 		.name			= "SOCKET",
457d9b57aa3SJens Axboe #if defined(CONFIG_NET)
458d9b57aa3SJens Axboe 		.prep			= io_socket_prep,
459d9b57aa3SJens Axboe 		.issue			= io_socket,
460d9b57aa3SJens Axboe #else
461d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
462d9b57aa3SJens Axboe #endif
463d9b57aa3SJens Axboe 	},
464d9b57aa3SJens Axboe 	[IORING_OP_URING_CMD] = {
465d9b57aa3SJens Axboe 		.needs_file		= 1,
466d9b57aa3SJens Axboe 		.plug			= 1,
467d9b57aa3SJens Axboe 		.name			= "URING_CMD",
468*5756a3a7SKanchan Joshi 		.iopoll			= 1,
469d9b57aa3SJens Axboe 		.async_size		= uring_cmd_pdu_size(1),
470d9b57aa3SJens Axboe 		.prep			= io_uring_cmd_prep,
471d9b57aa3SJens Axboe 		.issue			= io_uring_cmd,
472d9b57aa3SJens Axboe 		.prep_async		= io_uring_cmd_prep_async,
473d9b57aa3SJens Axboe 	},
474b48c312bSPavel Begunkov 	[IORING_OP_SEND_ZC] = {
4759bd3f728SStefan Metzmacher 		.name			= "SEND_ZC",
47606a5464bSPavel Begunkov 		.needs_file		= 1,
47706a5464bSPavel Begunkov 		.unbound_nonreg_file	= 1,
47806a5464bSPavel Begunkov 		.pollout		= 1,
47906a5464bSPavel Begunkov 		.audit_skip		= 1,
48006a5464bSPavel Begunkov 		.ioprio			= 1,
481581711c4SPavel Begunkov 		.manual_alloc		= 1,
48206a5464bSPavel Begunkov #if defined(CONFIG_NET)
483581711c4SPavel Begunkov 		.async_size		= sizeof(struct io_async_msghdr),
48406a5464bSPavel Begunkov 		.prep			= io_sendzc_prep,
48506a5464bSPavel Begunkov 		.issue			= io_sendzc,
486581711c4SPavel Begunkov 		.prep_async		= io_sendzc_prep_async,
487b48c312bSPavel Begunkov 		.cleanup		= io_sendzc_cleanup,
48806a5464bSPavel Begunkov #else
48906a5464bSPavel Begunkov 		.prep			= io_eopnotsupp_prep,
49006a5464bSPavel Begunkov #endif
49106a5464bSPavel Begunkov 	},
492d9b57aa3SJens Axboe };
493d9b57aa3SJens Axboe 
494d9b57aa3SJens Axboe const char *io_uring_get_opcode(u8 opcode)
495d9b57aa3SJens Axboe {
496d9b57aa3SJens Axboe 	if (opcode < IORING_OP_LAST)
497d9b57aa3SJens Axboe 		return io_op_defs[opcode].name;
498d9b57aa3SJens Axboe 	return "INVALID";
499d9b57aa3SJens Axboe }
500d9b57aa3SJens Axboe 
501d9b57aa3SJens Axboe void __init io_uring_optable_init(void)
502d9b57aa3SJens Axboe {
503d9b57aa3SJens Axboe 	int i;
504d9b57aa3SJens Axboe 
505d9b57aa3SJens Axboe 	BUILD_BUG_ON(ARRAY_SIZE(io_op_defs) != IORING_OP_LAST);
506d9b57aa3SJens Axboe 
507d9b57aa3SJens Axboe 	for (i = 0; i < ARRAY_SIZE(io_op_defs); i++) {
508d9b57aa3SJens Axboe 		BUG_ON(!io_op_defs[i].prep);
509d9b57aa3SJens Axboe 		if (io_op_defs[i].prep != io_eopnotsupp_prep)
510d9b57aa3SJens Axboe 			BUG_ON(!io_op_defs[i].issue);
511d9b57aa3SJens Axboe 		WARN_ON_ONCE(!io_op_defs[i].name);
512d9b57aa3SJens Axboe 	}
513d9b57aa3SJens Axboe }
514