xref: /openbmc/linux/io_uring/opdef.c (revision fd9b8547)
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 
io_no_issue(struct io_kiocb * req,unsigned int issue_flags)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 
io_eopnotsupp_prep(struct io_kiocb * kiocb,const struct io_uring_sqe * sqe)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 
49a7dd2782SBreno Leitao const struct io_issue_def io_issue_defs[] = {
50d9b57aa3SJens Axboe 	[IORING_OP_NOP] = {
51d9b57aa3SJens Axboe 		.audit_skip		= 1,
52d9b57aa3SJens Axboe 		.iopoll			= 1,
53d9b57aa3SJens Axboe 		.prep			= io_nop_prep,
54d9b57aa3SJens Axboe 		.issue			= io_nop,
55d9b57aa3SJens Axboe 	},
56d9b57aa3SJens Axboe 	[IORING_OP_READV] = {
57d9b57aa3SJens Axboe 		.needs_file		= 1,
58d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
59d9b57aa3SJens Axboe 		.pollin			= 1,
60d9b57aa3SJens Axboe 		.buffer_select		= 1,
61d9b57aa3SJens Axboe 		.plug			= 1,
62d9b57aa3SJens Axboe 		.audit_skip		= 1,
63d9b57aa3SJens Axboe 		.ioprio			= 1,
64d9b57aa3SJens Axboe 		.iopoll			= 1,
65ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
66d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
67d9b57aa3SJens Axboe 		.issue			= io_read,
68d9b57aa3SJens Axboe 	},
69d9b57aa3SJens Axboe 	[IORING_OP_WRITEV] = {
70d9b57aa3SJens Axboe 		.needs_file		= 1,
71d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
72d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
73d9b57aa3SJens Axboe 		.pollout		= 1,
74d9b57aa3SJens Axboe 		.plug			= 1,
75d9b57aa3SJens Axboe 		.audit_skip		= 1,
76d9b57aa3SJens Axboe 		.ioprio			= 1,
77d9b57aa3SJens Axboe 		.iopoll			= 1,
78ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
79d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
80d9b57aa3SJens Axboe 		.issue			= io_write,
81d9b57aa3SJens Axboe 	},
82d9b57aa3SJens Axboe 	[IORING_OP_FSYNC] = {
83d9b57aa3SJens Axboe 		.needs_file		= 1,
84d9b57aa3SJens Axboe 		.audit_skip		= 1,
85d9b57aa3SJens Axboe 		.prep			= io_fsync_prep,
86d9b57aa3SJens Axboe 		.issue			= io_fsync,
87d9b57aa3SJens Axboe 	},
88d9b57aa3SJens Axboe 	[IORING_OP_READ_FIXED] = {
89d9b57aa3SJens Axboe 		.needs_file		= 1,
90d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
91d9b57aa3SJens Axboe 		.pollin			= 1,
92d9b57aa3SJens Axboe 		.plug			= 1,
93d9b57aa3SJens Axboe 		.audit_skip		= 1,
94d9b57aa3SJens Axboe 		.ioprio			= 1,
95d9b57aa3SJens Axboe 		.iopoll			= 1,
96ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
97d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
98d9b57aa3SJens Axboe 		.issue			= io_read,
99d9b57aa3SJens Axboe 	},
100d9b57aa3SJens Axboe 	[IORING_OP_WRITE_FIXED] = {
101d9b57aa3SJens Axboe 		.needs_file		= 1,
102d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
103d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
104d9b57aa3SJens Axboe 		.pollout		= 1,
105d9b57aa3SJens Axboe 		.plug			= 1,
106d9b57aa3SJens Axboe 		.audit_skip		= 1,
107d9b57aa3SJens Axboe 		.ioprio			= 1,
108d9b57aa3SJens Axboe 		.iopoll			= 1,
109ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
110d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
111d9b57aa3SJens Axboe 		.issue			= io_write,
112d9b57aa3SJens Axboe 	},
113d9b57aa3SJens Axboe 	[IORING_OP_POLL_ADD] = {
114d9b57aa3SJens Axboe 		.needs_file		= 1,
115d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
116d9b57aa3SJens Axboe 		.audit_skip		= 1,
117d9b57aa3SJens Axboe 		.prep			= io_poll_add_prep,
118d9b57aa3SJens Axboe 		.issue			= io_poll_add,
119d9b57aa3SJens Axboe 	},
120d9b57aa3SJens Axboe 	[IORING_OP_POLL_REMOVE] = {
121d9b57aa3SJens Axboe 		.audit_skip		= 1,
122d9b57aa3SJens Axboe 		.prep			= io_poll_remove_prep,
123d9b57aa3SJens Axboe 		.issue			= io_poll_remove,
124d9b57aa3SJens Axboe 	},
125d9b57aa3SJens Axboe 	[IORING_OP_SYNC_FILE_RANGE] = {
126d9b57aa3SJens Axboe 		.needs_file		= 1,
127d9b57aa3SJens Axboe 		.audit_skip		= 1,
128d9b57aa3SJens Axboe 		.prep			= io_sfr_prep,
129d9b57aa3SJens Axboe 		.issue			= io_sync_file_range,
130d9b57aa3SJens Axboe 	},
131d9b57aa3SJens Axboe 	[IORING_OP_SENDMSG] = {
132d9b57aa3SJens Axboe 		.needs_file		= 1,
133d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
134d9b57aa3SJens Axboe 		.pollout		= 1,
135d9b57aa3SJens Axboe 		.ioprio			= 1,
136858c293eSPavel Begunkov 		.manual_alloc		= 1,
137d9b57aa3SJens Axboe #if defined(CONFIG_NET)
138d9b57aa3SJens Axboe 		.prep			= io_sendmsg_prep,
139d9b57aa3SJens Axboe 		.issue			= io_sendmsg,
140d9b57aa3SJens Axboe #else
141d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
142d9b57aa3SJens Axboe #endif
143d9b57aa3SJens Axboe 	},
144d9b57aa3SJens Axboe 	[IORING_OP_RECVMSG] = {
145d9b57aa3SJens Axboe 		.needs_file		= 1,
146d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
147d9b57aa3SJens Axboe 		.pollin			= 1,
148d9b57aa3SJens Axboe 		.buffer_select		= 1,
149d9b57aa3SJens Axboe 		.ioprio			= 1,
150858c293eSPavel Begunkov 		.manual_alloc		= 1,
151d9b57aa3SJens Axboe #if defined(CONFIG_NET)
152d9b57aa3SJens Axboe 		.prep			= io_recvmsg_prep,
153d9b57aa3SJens Axboe 		.issue			= io_recvmsg,
154d9b57aa3SJens Axboe #else
155d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
156d9b57aa3SJens Axboe #endif
157d9b57aa3SJens Axboe 	},
158d9b57aa3SJens Axboe 	[IORING_OP_TIMEOUT] = {
159d9b57aa3SJens Axboe 		.audit_skip		= 1,
160d9b57aa3SJens Axboe 		.prep			= io_timeout_prep,
161d9b57aa3SJens Axboe 		.issue			= io_timeout,
162d9b57aa3SJens Axboe 	},
163d9b57aa3SJens Axboe 	[IORING_OP_TIMEOUT_REMOVE] = {
164d9b57aa3SJens Axboe 		/* used by timeout updates' prep() */
165d9b57aa3SJens Axboe 		.audit_skip		= 1,
166d9b57aa3SJens Axboe 		.prep			= io_timeout_remove_prep,
167d9b57aa3SJens Axboe 		.issue			= io_timeout_remove,
168d9b57aa3SJens Axboe 	},
169d9b57aa3SJens Axboe 	[IORING_OP_ACCEPT] = {
170d9b57aa3SJens Axboe 		.needs_file		= 1,
171d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
172d9b57aa3SJens Axboe 		.pollin			= 1,
173d9b57aa3SJens Axboe 		.poll_exclusive		= 1,
174d9b57aa3SJens Axboe 		.ioprio			= 1,	/* used for flags */
175d9b57aa3SJens Axboe #if defined(CONFIG_NET)
176d9b57aa3SJens Axboe 		.prep			= io_accept_prep,
177d9b57aa3SJens Axboe 		.issue			= io_accept,
178d9b57aa3SJens Axboe #else
179d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
180d9b57aa3SJens Axboe #endif
181d9b57aa3SJens Axboe 	},
182d9b57aa3SJens Axboe 	[IORING_OP_ASYNC_CANCEL] = {
183d9b57aa3SJens Axboe 		.audit_skip		= 1,
184d9b57aa3SJens Axboe 		.prep			= io_async_cancel_prep,
185d9b57aa3SJens Axboe 		.issue			= io_async_cancel,
186d9b57aa3SJens Axboe 	},
187d9b57aa3SJens Axboe 	[IORING_OP_LINK_TIMEOUT] = {
188d9b57aa3SJens Axboe 		.audit_skip		= 1,
189d9b57aa3SJens Axboe 		.prep			= io_link_timeout_prep,
190d9b57aa3SJens Axboe 		.issue			= io_no_issue,
191d9b57aa3SJens Axboe 	},
192d9b57aa3SJens Axboe 	[IORING_OP_CONNECT] = {
193d9b57aa3SJens Axboe 		.needs_file		= 1,
194d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
195d9b57aa3SJens Axboe 		.pollout		= 1,
196d9b57aa3SJens Axboe #if defined(CONFIG_NET)
197d9b57aa3SJens Axboe 		.prep			= io_connect_prep,
198d9b57aa3SJens Axboe 		.issue			= io_connect,
199d9b57aa3SJens Axboe #else
200d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
201d9b57aa3SJens Axboe #endif
202d9b57aa3SJens Axboe 	},
203d9b57aa3SJens Axboe 	[IORING_OP_FALLOCATE] = {
204d9b57aa3SJens Axboe 		.needs_file		= 1,
205d9b57aa3SJens Axboe 		.prep			= io_fallocate_prep,
206d9b57aa3SJens Axboe 		.issue			= io_fallocate,
207d9b57aa3SJens Axboe 	},
208d9b57aa3SJens Axboe 	[IORING_OP_OPENAT] = {
209d9b57aa3SJens Axboe 		.prep			= io_openat_prep,
210d9b57aa3SJens Axboe 		.issue			= io_openat,
211d9b57aa3SJens Axboe 	},
212d9b57aa3SJens Axboe 	[IORING_OP_CLOSE] = {
213d9b57aa3SJens Axboe 		.prep			= io_close_prep,
214d9b57aa3SJens Axboe 		.issue			= io_close,
215d9b57aa3SJens Axboe 	},
216d9808cebSPavel Begunkov 	[IORING_OP_FILES_UPDATE] = {
217d9b57aa3SJens Axboe 		.audit_skip		= 1,
218d9b57aa3SJens Axboe 		.iopoll			= 1,
219d9808cebSPavel Begunkov 		.prep			= io_files_update_prep,
220d9808cebSPavel Begunkov 		.issue			= io_files_update,
221d9b57aa3SJens Axboe 	},
222d9b57aa3SJens Axboe 	[IORING_OP_STATX] = {
223d9b57aa3SJens Axboe 		.audit_skip		= 1,
224d9b57aa3SJens Axboe 		.prep			= io_statx_prep,
225d9b57aa3SJens Axboe 		.issue			= io_statx,
226d9b57aa3SJens Axboe 	},
227d9b57aa3SJens Axboe 	[IORING_OP_READ] = {
228d9b57aa3SJens Axboe 		.needs_file		= 1,
229d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
230d9b57aa3SJens Axboe 		.pollin			= 1,
231d9b57aa3SJens Axboe 		.buffer_select		= 1,
232d9b57aa3SJens Axboe 		.plug			= 1,
233d9b57aa3SJens Axboe 		.audit_skip		= 1,
234d9b57aa3SJens Axboe 		.ioprio			= 1,
235d9b57aa3SJens Axboe 		.iopoll			= 1,
236ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
237d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
238d9b57aa3SJens Axboe 		.issue			= io_read,
239d9b57aa3SJens Axboe 	},
240d9b57aa3SJens Axboe 	[IORING_OP_WRITE] = {
241d9b57aa3SJens Axboe 		.needs_file		= 1,
242d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
243d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
244d9b57aa3SJens Axboe 		.pollout		= 1,
245d9b57aa3SJens Axboe 		.plug			= 1,
246d9b57aa3SJens Axboe 		.audit_skip		= 1,
247d9b57aa3SJens Axboe 		.ioprio			= 1,
248d9b57aa3SJens Axboe 		.iopoll			= 1,
249ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
250d9b57aa3SJens Axboe 		.prep			= io_prep_rw,
251d9b57aa3SJens Axboe 		.issue			= io_write,
252d9b57aa3SJens Axboe 	},
253d9b57aa3SJens Axboe 	[IORING_OP_FADVISE] = {
254d9b57aa3SJens Axboe 		.needs_file		= 1,
255d9b57aa3SJens Axboe 		.audit_skip		= 1,
256d9b57aa3SJens Axboe 		.prep			= io_fadvise_prep,
257d9b57aa3SJens Axboe 		.issue			= io_fadvise,
258d9b57aa3SJens Axboe 	},
259d9b57aa3SJens Axboe 	[IORING_OP_MADVISE] = {
260fbe870a7SRichard Guy Briggs 		.audit_skip		= 1,
261d9b57aa3SJens Axboe 		.prep			= io_madvise_prep,
262d9b57aa3SJens Axboe 		.issue			= io_madvise,
263d9b57aa3SJens Axboe 	},
264d9b57aa3SJens Axboe 	[IORING_OP_SEND] = {
265d9b57aa3SJens Axboe 		.needs_file		= 1,
266d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
267d9b57aa3SJens Axboe 		.pollout		= 1,
268d9b57aa3SJens Axboe 		.audit_skip		= 1,
269d9b57aa3SJens Axboe 		.ioprio			= 1,
270516e82f0SPavel Begunkov 		.manual_alloc		= 1,
271d9b57aa3SJens Axboe #if defined(CONFIG_NET)
272d9b57aa3SJens Axboe 		.prep			= io_sendmsg_prep,
273d9b57aa3SJens Axboe 		.issue			= io_send,
274d9b57aa3SJens Axboe #else
275d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
276d9b57aa3SJens Axboe #endif
277d9b57aa3SJens Axboe 	},
278d9b57aa3SJens Axboe 	[IORING_OP_RECV] = {
279d9b57aa3SJens Axboe 		.needs_file		= 1,
280d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
281d9b57aa3SJens Axboe 		.pollin			= 1,
282d9b57aa3SJens Axboe 		.buffer_select		= 1,
283d9b57aa3SJens Axboe 		.audit_skip		= 1,
284d9b57aa3SJens Axboe 		.ioprio			= 1,
285d9b57aa3SJens Axboe #if defined(CONFIG_NET)
286d9b57aa3SJens Axboe 		.prep			= io_recvmsg_prep,
287d9b57aa3SJens Axboe 		.issue			= io_recv,
288d9b57aa3SJens Axboe #else
289d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
290d9b57aa3SJens Axboe #endif
291d9b57aa3SJens Axboe 	},
292d9b57aa3SJens Axboe 	[IORING_OP_OPENAT2] = {
293d9b57aa3SJens Axboe 		.prep			= io_openat2_prep,
294d9b57aa3SJens Axboe 		.issue			= io_openat2,
295d9b57aa3SJens Axboe 	},
296d9b57aa3SJens Axboe 	[IORING_OP_EPOLL_CTL] = {
297d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
298d9b57aa3SJens Axboe 		.audit_skip		= 1,
299d9b57aa3SJens Axboe #if defined(CONFIG_EPOLL)
300d9b57aa3SJens Axboe 		.prep			= io_epoll_ctl_prep,
301d9b57aa3SJens Axboe 		.issue			= io_epoll_ctl,
302d9b57aa3SJens Axboe #else
303d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
304d9b57aa3SJens Axboe #endif
305d9b57aa3SJens Axboe 	},
306d9b57aa3SJens Axboe 	[IORING_OP_SPLICE] = {
307d9b57aa3SJens Axboe 		.needs_file		= 1,
308d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
309d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
310d9b57aa3SJens Axboe 		.audit_skip		= 1,
311d9b57aa3SJens Axboe 		.prep			= io_splice_prep,
312d9b57aa3SJens Axboe 		.issue			= io_splice,
313d9b57aa3SJens Axboe 	},
314d9b57aa3SJens Axboe 	[IORING_OP_PROVIDE_BUFFERS] = {
315d9b57aa3SJens Axboe 		.audit_skip		= 1,
316d9b57aa3SJens Axboe 		.iopoll			= 1,
317d9b57aa3SJens Axboe 		.prep			= io_provide_buffers_prep,
318d9b57aa3SJens Axboe 		.issue			= io_provide_buffers,
319d9b57aa3SJens Axboe 	},
320d9b57aa3SJens Axboe 	[IORING_OP_REMOVE_BUFFERS] = {
321d9b57aa3SJens Axboe 		.audit_skip		= 1,
322d9b57aa3SJens Axboe 		.iopoll			= 1,
323d9b57aa3SJens Axboe 		.prep			= io_remove_buffers_prep,
324d9b57aa3SJens Axboe 		.issue			= io_remove_buffers,
325d9b57aa3SJens Axboe 	},
326d9b57aa3SJens Axboe 	[IORING_OP_TEE] = {
327d9b57aa3SJens Axboe 		.needs_file		= 1,
328d9b57aa3SJens Axboe 		.hash_reg_file		= 1,
329d9b57aa3SJens Axboe 		.unbound_nonreg_file	= 1,
330d9b57aa3SJens Axboe 		.audit_skip		= 1,
331d9b57aa3SJens Axboe 		.prep			= io_tee_prep,
332d9b57aa3SJens Axboe 		.issue			= io_tee,
333d9b57aa3SJens Axboe 	},
334d9b57aa3SJens Axboe 	[IORING_OP_SHUTDOWN] = {
335d9b57aa3SJens Axboe 		.needs_file		= 1,
336d9b57aa3SJens Axboe #if defined(CONFIG_NET)
337d9b57aa3SJens Axboe 		.prep			= io_shutdown_prep,
338d9b57aa3SJens Axboe 		.issue			= io_shutdown,
339d9b57aa3SJens Axboe #else
340d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
341d9b57aa3SJens Axboe #endif
342d9b57aa3SJens Axboe 	},
343d9b57aa3SJens Axboe 	[IORING_OP_RENAMEAT] = {
344d9b57aa3SJens Axboe 		.prep			= io_renameat_prep,
345d9b57aa3SJens Axboe 		.issue			= io_renameat,
346d9b57aa3SJens Axboe 	},
347d9b57aa3SJens Axboe 	[IORING_OP_UNLINKAT] = {
348d9b57aa3SJens Axboe 		.prep			= io_unlinkat_prep,
349d9b57aa3SJens Axboe 		.issue			= io_unlinkat,
350d9b57aa3SJens Axboe 	},
351d9b57aa3SJens Axboe 	[IORING_OP_MKDIRAT] = {
352d9b57aa3SJens Axboe 		.prep			= io_mkdirat_prep,
353d9b57aa3SJens Axboe 		.issue			= io_mkdirat,
354d9b57aa3SJens Axboe 	},
355d9b57aa3SJens Axboe 	[IORING_OP_SYMLINKAT] = {
356d9b57aa3SJens Axboe 		.prep			= io_symlinkat_prep,
357d9b57aa3SJens Axboe 		.issue			= io_symlinkat,
358d9b57aa3SJens Axboe 	},
359d9b57aa3SJens Axboe 	[IORING_OP_LINKAT] = {
360d9b57aa3SJens Axboe 		.prep			= io_linkat_prep,
361d9b57aa3SJens Axboe 		.issue			= io_linkat,
362d9b57aa3SJens Axboe 	},
363d9b57aa3SJens Axboe 	[IORING_OP_MSG_RING] = {
364d9b57aa3SJens Axboe 		.needs_file		= 1,
365d9b57aa3SJens Axboe 		.iopoll			= 1,
366d9b57aa3SJens Axboe 		.prep			= io_msg_ring_prep,
367d9b57aa3SJens Axboe 		.issue			= io_msg_ring,
368d9b57aa3SJens Axboe 	},
369d9b57aa3SJens Axboe 	[IORING_OP_FSETXATTR] = {
370d9b57aa3SJens Axboe 		.needs_file = 1,
371d9b57aa3SJens Axboe 		.prep			= io_fsetxattr_prep,
372d9b57aa3SJens Axboe 		.issue			= io_fsetxattr,
373d9b57aa3SJens Axboe 	},
374d9b57aa3SJens Axboe 	[IORING_OP_SETXATTR] = {
375d9b57aa3SJens Axboe 		.prep			= io_setxattr_prep,
376d9b57aa3SJens Axboe 		.issue			= io_setxattr,
377d9b57aa3SJens Axboe 	},
378d9b57aa3SJens Axboe 	[IORING_OP_FGETXATTR] = {
379d9b57aa3SJens Axboe 		.needs_file = 1,
380d9b57aa3SJens Axboe 		.prep			= io_fgetxattr_prep,
381d9b57aa3SJens Axboe 		.issue			= io_fgetxattr,
382d9b57aa3SJens Axboe 	},
383d9b57aa3SJens Axboe 	[IORING_OP_GETXATTR] = {
384d9b57aa3SJens Axboe 		.prep			= io_getxattr_prep,
385d9b57aa3SJens Axboe 		.issue			= io_getxattr,
386d9b57aa3SJens Axboe 	},
387d9b57aa3SJens Axboe 	[IORING_OP_SOCKET] = {
388d9b57aa3SJens Axboe 		.audit_skip		= 1,
389d9b57aa3SJens Axboe #if defined(CONFIG_NET)
390d9b57aa3SJens Axboe 		.prep			= io_socket_prep,
391d9b57aa3SJens Axboe 		.issue			= io_socket,
392d9b57aa3SJens Axboe #else
393d9b57aa3SJens Axboe 		.prep			= io_eopnotsupp_prep,
394d9b57aa3SJens Axboe #endif
395d9b57aa3SJens Axboe 	},
396d9b57aa3SJens Axboe 	[IORING_OP_URING_CMD] = {
397d9b57aa3SJens Axboe 		.needs_file		= 1,
398d9b57aa3SJens Axboe 		.plug			= 1,
3995756a3a7SKanchan Joshi 		.iopoll			= 1,
400ef0ec1adSPavel Begunkov 		.iopoll_queue		= 1,
401d9b57aa3SJens Axboe 		.prep			= io_uring_cmd_prep,
402d9b57aa3SJens Axboe 		.issue			= io_uring_cmd,
403d9b57aa3SJens Axboe 	},
404b48c312bSPavel Begunkov 	[IORING_OP_SEND_ZC] = {
40506a5464bSPavel Begunkov 		.needs_file		= 1,
40606a5464bSPavel Begunkov 		.unbound_nonreg_file	= 1,
40706a5464bSPavel Begunkov 		.pollout		= 1,
40806a5464bSPavel Begunkov 		.audit_skip		= 1,
40906a5464bSPavel Begunkov 		.ioprio			= 1,
410581711c4SPavel Begunkov 		.manual_alloc		= 1,
41106a5464bSPavel Begunkov #if defined(CONFIG_NET)
412b0e9b551SPavel Begunkov 		.prep			= io_send_zc_prep,
413b0e9b551SPavel Begunkov 		.issue			= io_send_zc,
41406a5464bSPavel Begunkov #else
41506a5464bSPavel Begunkov 		.prep			= io_eopnotsupp_prep,
41606a5464bSPavel Begunkov #endif
41706a5464bSPavel Begunkov 	},
418493108d9SPavel Begunkov 	[IORING_OP_SENDMSG_ZC] = {
419493108d9SPavel Begunkov 		.needs_file		= 1,
420493108d9SPavel Begunkov 		.unbound_nonreg_file	= 1,
421493108d9SPavel Begunkov 		.pollout		= 1,
422493108d9SPavel Begunkov 		.ioprio			= 1,
423493108d9SPavel Begunkov 		.manual_alloc		= 1,
424493108d9SPavel Begunkov #if defined(CONFIG_NET)
425493108d9SPavel Begunkov 		.prep			= io_send_zc_prep,
426493108d9SPavel Begunkov 		.issue			= io_sendmsg_zc,
427f30bd4d0SBreno Leitao #else
428f30bd4d0SBreno Leitao 		.prep			= io_eopnotsupp_prep,
429f30bd4d0SBreno Leitao #endif
430f30bd4d0SBreno Leitao 	},
431f30bd4d0SBreno Leitao };
432f30bd4d0SBreno Leitao 
433f30bd4d0SBreno Leitao 
434f30bd4d0SBreno Leitao const struct io_cold_def io_cold_defs[] = {
435f30bd4d0SBreno Leitao 	[IORING_OP_NOP] = {
436f30bd4d0SBreno Leitao 		.name			= "NOP",
437f30bd4d0SBreno Leitao 	},
438f30bd4d0SBreno Leitao 	[IORING_OP_READV] = {
439f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_rw),
440f30bd4d0SBreno Leitao 		.name			= "READV",
441f30bd4d0SBreno Leitao 		.prep_async		= io_readv_prep_async,
442f30bd4d0SBreno Leitao 		.cleanup		= io_readv_writev_cleanup,
443f30bd4d0SBreno Leitao 		.fail			= io_rw_fail,
444f30bd4d0SBreno Leitao 	},
445f30bd4d0SBreno Leitao 	[IORING_OP_WRITEV] = {
446f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_rw),
447f30bd4d0SBreno Leitao 		.name			= "WRITEV",
448f30bd4d0SBreno Leitao 		.prep_async		= io_writev_prep_async,
449f30bd4d0SBreno Leitao 		.cleanup		= io_readv_writev_cleanup,
450f30bd4d0SBreno Leitao 		.fail			= io_rw_fail,
451f30bd4d0SBreno Leitao 	},
452f30bd4d0SBreno Leitao 	[IORING_OP_FSYNC] = {
453f30bd4d0SBreno Leitao 		.name			= "FSYNC",
454f30bd4d0SBreno Leitao 	},
455f30bd4d0SBreno Leitao 	[IORING_OP_READ_FIXED] = {
456f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_rw),
457f30bd4d0SBreno Leitao 		.name			= "READ_FIXED",
458f30bd4d0SBreno Leitao 		.fail			= io_rw_fail,
459f30bd4d0SBreno Leitao 	},
460f30bd4d0SBreno Leitao 	[IORING_OP_WRITE_FIXED] = {
461f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_rw),
462f30bd4d0SBreno Leitao 		.name			= "WRITE_FIXED",
463f30bd4d0SBreno Leitao 		.fail			= io_rw_fail,
464f30bd4d0SBreno Leitao 	},
465f30bd4d0SBreno Leitao 	[IORING_OP_POLL_ADD] = {
466f30bd4d0SBreno Leitao 		.name			= "POLL_ADD",
467f30bd4d0SBreno Leitao 	},
468f30bd4d0SBreno Leitao 	[IORING_OP_POLL_REMOVE] = {
469f30bd4d0SBreno Leitao 		.name			= "POLL_REMOVE",
470f30bd4d0SBreno Leitao 	},
471f30bd4d0SBreno Leitao 	[IORING_OP_SYNC_FILE_RANGE] = {
472f30bd4d0SBreno Leitao 		.name			= "SYNC_FILE_RANGE",
473f30bd4d0SBreno Leitao 	},
474f30bd4d0SBreno Leitao 	[IORING_OP_SENDMSG] = {
475f30bd4d0SBreno Leitao 		.name			= "SENDMSG",
476f30bd4d0SBreno Leitao #if defined(CONFIG_NET)
477f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_msghdr),
478f30bd4d0SBreno Leitao 		.prep_async		= io_sendmsg_prep_async,
479f30bd4d0SBreno Leitao 		.cleanup		= io_sendmsg_recvmsg_cleanup,
480f30bd4d0SBreno Leitao 		.fail			= io_sendrecv_fail,
481f30bd4d0SBreno Leitao #endif
482f30bd4d0SBreno Leitao 	},
483f30bd4d0SBreno Leitao 	[IORING_OP_RECVMSG] = {
484f30bd4d0SBreno Leitao 		.name			= "RECVMSG",
485f30bd4d0SBreno Leitao #if defined(CONFIG_NET)
486f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_msghdr),
487f30bd4d0SBreno Leitao 		.prep_async		= io_recvmsg_prep_async,
488f30bd4d0SBreno Leitao 		.cleanup		= io_sendmsg_recvmsg_cleanup,
489f30bd4d0SBreno Leitao 		.fail			= io_sendrecv_fail,
490f30bd4d0SBreno Leitao #endif
491f30bd4d0SBreno Leitao 	},
492f30bd4d0SBreno Leitao 	[IORING_OP_TIMEOUT] = {
493f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_timeout_data),
494f30bd4d0SBreno Leitao 		.name			= "TIMEOUT",
495f30bd4d0SBreno Leitao 	},
496f30bd4d0SBreno Leitao 	[IORING_OP_TIMEOUT_REMOVE] = {
497f30bd4d0SBreno Leitao 		.name			= "TIMEOUT_REMOVE",
498f30bd4d0SBreno Leitao 	},
499f30bd4d0SBreno Leitao 	[IORING_OP_ACCEPT] = {
500f30bd4d0SBreno Leitao 		.name			= "ACCEPT",
501f30bd4d0SBreno Leitao 	},
502f30bd4d0SBreno Leitao 	[IORING_OP_ASYNC_CANCEL] = {
503f30bd4d0SBreno Leitao 		.name			= "ASYNC_CANCEL",
504f30bd4d0SBreno Leitao 	},
505f30bd4d0SBreno Leitao 	[IORING_OP_LINK_TIMEOUT] = {
506f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_timeout_data),
507f30bd4d0SBreno Leitao 		.name			= "LINK_TIMEOUT",
508f30bd4d0SBreno Leitao 	},
509f30bd4d0SBreno Leitao 	[IORING_OP_CONNECT] = {
510f30bd4d0SBreno Leitao 		.name			= "CONNECT",
511f30bd4d0SBreno Leitao #if defined(CONFIG_NET)
512f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_connect),
513f30bd4d0SBreno Leitao 		.prep_async		= io_connect_prep_async,
514f30bd4d0SBreno Leitao #endif
515f30bd4d0SBreno Leitao 	},
516f30bd4d0SBreno Leitao 	[IORING_OP_FALLOCATE] = {
517f30bd4d0SBreno Leitao 		.name			= "FALLOCATE",
518f30bd4d0SBreno Leitao 	},
519f30bd4d0SBreno Leitao 	[IORING_OP_OPENAT] = {
520f30bd4d0SBreno Leitao 		.name			= "OPENAT",
521f30bd4d0SBreno Leitao 		.cleanup		= io_open_cleanup,
522f30bd4d0SBreno Leitao 	},
523f30bd4d0SBreno Leitao 	[IORING_OP_CLOSE] = {
524f30bd4d0SBreno Leitao 		.name			= "CLOSE",
525f30bd4d0SBreno Leitao 	},
526f30bd4d0SBreno Leitao 	[IORING_OP_FILES_UPDATE] = {
527f30bd4d0SBreno Leitao 		.name			= "FILES_UPDATE",
528f30bd4d0SBreno Leitao 	},
529f30bd4d0SBreno Leitao 	[IORING_OP_STATX] = {
530f30bd4d0SBreno Leitao 		.name			= "STATX",
531f30bd4d0SBreno Leitao 		.cleanup		= io_statx_cleanup,
532f30bd4d0SBreno Leitao 	},
533f30bd4d0SBreno Leitao 	[IORING_OP_READ] = {
534f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_rw),
535f30bd4d0SBreno Leitao 		.name			= "READ",
536f30bd4d0SBreno Leitao 		.fail			= io_rw_fail,
537f30bd4d0SBreno Leitao 	},
538f30bd4d0SBreno Leitao 	[IORING_OP_WRITE] = {
539f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_rw),
540f30bd4d0SBreno Leitao 		.name			= "WRITE",
541f30bd4d0SBreno Leitao 		.fail			= io_rw_fail,
542f30bd4d0SBreno Leitao 	},
543f30bd4d0SBreno Leitao 	[IORING_OP_FADVISE] = {
544f30bd4d0SBreno Leitao 		.name			= "FADVISE",
545f30bd4d0SBreno Leitao 	},
546f30bd4d0SBreno Leitao 	[IORING_OP_MADVISE] = {
547f30bd4d0SBreno Leitao 		.name			= "MADVISE",
548f30bd4d0SBreno Leitao 	},
549f30bd4d0SBreno Leitao 	[IORING_OP_SEND] = {
550f30bd4d0SBreno Leitao 		.name			= "SEND",
551f30bd4d0SBreno Leitao #if defined(CONFIG_NET)
552f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_msghdr),
553f30bd4d0SBreno Leitao 		.fail			= io_sendrecv_fail,
554f30bd4d0SBreno Leitao 		.prep_async		= io_send_prep_async,
555f30bd4d0SBreno Leitao #endif
556f30bd4d0SBreno Leitao 	},
557f30bd4d0SBreno Leitao 	[IORING_OP_RECV] = {
558f30bd4d0SBreno Leitao 		.name			= "RECV",
559f30bd4d0SBreno Leitao #if defined(CONFIG_NET)
560f30bd4d0SBreno Leitao 		.fail			= io_sendrecv_fail,
561f30bd4d0SBreno Leitao #endif
562f30bd4d0SBreno Leitao 	},
563f30bd4d0SBreno Leitao 	[IORING_OP_OPENAT2] = {
564f30bd4d0SBreno Leitao 		.name			= "OPENAT2",
565f30bd4d0SBreno Leitao 		.cleanup		= io_open_cleanup,
566f30bd4d0SBreno Leitao 	},
567f30bd4d0SBreno Leitao 	[IORING_OP_EPOLL_CTL] = {
568f30bd4d0SBreno Leitao 		.name			= "EPOLL",
569f30bd4d0SBreno Leitao 	},
570f30bd4d0SBreno Leitao 	[IORING_OP_SPLICE] = {
571f30bd4d0SBreno Leitao 		.name			= "SPLICE",
572f30bd4d0SBreno Leitao 	},
573f30bd4d0SBreno Leitao 	[IORING_OP_PROVIDE_BUFFERS] = {
574f30bd4d0SBreno Leitao 		.name			= "PROVIDE_BUFFERS",
575f30bd4d0SBreno Leitao 	},
576f30bd4d0SBreno Leitao 	[IORING_OP_REMOVE_BUFFERS] = {
577f30bd4d0SBreno Leitao 		.name			= "REMOVE_BUFFERS",
578f30bd4d0SBreno Leitao 	},
579f30bd4d0SBreno Leitao 	[IORING_OP_TEE] = {
580f30bd4d0SBreno Leitao 		.name			= "TEE",
581f30bd4d0SBreno Leitao 	},
582f30bd4d0SBreno Leitao 	[IORING_OP_SHUTDOWN] = {
583f30bd4d0SBreno Leitao 		.name			= "SHUTDOWN",
584f30bd4d0SBreno Leitao 	},
585f30bd4d0SBreno Leitao 	[IORING_OP_RENAMEAT] = {
586f30bd4d0SBreno Leitao 		.name			= "RENAMEAT",
587f30bd4d0SBreno Leitao 		.cleanup		= io_renameat_cleanup,
588f30bd4d0SBreno Leitao 	},
589f30bd4d0SBreno Leitao 	[IORING_OP_UNLINKAT] = {
590f30bd4d0SBreno Leitao 		.name			= "UNLINKAT",
591f30bd4d0SBreno Leitao 		.cleanup		= io_unlinkat_cleanup,
592f30bd4d0SBreno Leitao 	},
593f30bd4d0SBreno Leitao 	[IORING_OP_MKDIRAT] = {
594f30bd4d0SBreno Leitao 		.name			= "MKDIRAT",
595f30bd4d0SBreno Leitao 		.cleanup		= io_mkdirat_cleanup,
596f30bd4d0SBreno Leitao 	},
597f30bd4d0SBreno Leitao 	[IORING_OP_SYMLINKAT] = {
598f30bd4d0SBreno Leitao 		.name			= "SYMLINKAT",
599f30bd4d0SBreno Leitao 		.cleanup		= io_link_cleanup,
600f30bd4d0SBreno Leitao 	},
601f30bd4d0SBreno Leitao 	[IORING_OP_LINKAT] = {
602f30bd4d0SBreno Leitao 		.name			= "LINKAT",
603f30bd4d0SBreno Leitao 		.cleanup		= io_link_cleanup,
604f30bd4d0SBreno Leitao 	},
605f30bd4d0SBreno Leitao 	[IORING_OP_MSG_RING] = {
606f30bd4d0SBreno Leitao 		.name			= "MSG_RING",
607f30bd4d0SBreno Leitao 		.cleanup		= io_msg_ring_cleanup,
608f30bd4d0SBreno Leitao 	},
609f30bd4d0SBreno Leitao 	[IORING_OP_FSETXATTR] = {
610f30bd4d0SBreno Leitao 		.name			= "FSETXATTR",
611f30bd4d0SBreno Leitao 		.cleanup		= io_xattr_cleanup,
612f30bd4d0SBreno Leitao 	},
613f30bd4d0SBreno Leitao 	[IORING_OP_SETXATTR] = {
614f30bd4d0SBreno Leitao 		.name			= "SETXATTR",
615f30bd4d0SBreno Leitao 		.cleanup		= io_xattr_cleanup,
616f30bd4d0SBreno Leitao 	},
617f30bd4d0SBreno Leitao 	[IORING_OP_FGETXATTR] = {
618f30bd4d0SBreno Leitao 		.name			= "FGETXATTR",
619f30bd4d0SBreno Leitao 		.cleanup		= io_xattr_cleanup,
620f30bd4d0SBreno Leitao 	},
621f30bd4d0SBreno Leitao 	[IORING_OP_GETXATTR] = {
622f30bd4d0SBreno Leitao 		.name			= "GETXATTR",
623f30bd4d0SBreno Leitao 		.cleanup		= io_xattr_cleanup,
624f30bd4d0SBreno Leitao 	},
625f30bd4d0SBreno Leitao 	[IORING_OP_SOCKET] = {
626f30bd4d0SBreno Leitao 		.name			= "SOCKET",
627f30bd4d0SBreno Leitao 	},
628f30bd4d0SBreno Leitao 	[IORING_OP_URING_CMD] = {
629f30bd4d0SBreno Leitao 		.name			= "URING_CMD",
630*fd9b8547SBreno Leitao 		.async_size		= 2 * sizeof(struct io_uring_sqe),
631f30bd4d0SBreno Leitao 		.prep_async		= io_uring_cmd_prep_async,
632f30bd4d0SBreno Leitao 	},
633f30bd4d0SBreno Leitao 	[IORING_OP_SEND_ZC] = {
634f30bd4d0SBreno Leitao 		.name			= "SEND_ZC",
635f30bd4d0SBreno Leitao #if defined(CONFIG_NET)
636f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_msghdr),
637f30bd4d0SBreno Leitao 		.prep_async		= io_send_prep_async,
638f30bd4d0SBreno Leitao 		.cleanup		= io_send_zc_cleanup,
639f30bd4d0SBreno Leitao 		.fail			= io_sendrecv_fail,
640f30bd4d0SBreno Leitao #endif
641f30bd4d0SBreno Leitao 	},
642f30bd4d0SBreno Leitao 	[IORING_OP_SENDMSG_ZC] = {
643f30bd4d0SBreno Leitao 		.name			= "SENDMSG_ZC",
644f30bd4d0SBreno Leitao #if defined(CONFIG_NET)
645f30bd4d0SBreno Leitao 		.async_size		= sizeof(struct io_async_msghdr),
646493108d9SPavel Begunkov 		.prep_async		= io_sendmsg_prep_async,
647493108d9SPavel Begunkov 		.cleanup		= io_send_zc_cleanup,
648493108d9SPavel Begunkov 		.fail			= io_sendrecv_fail,
649493108d9SPavel Begunkov #endif
650493108d9SPavel Begunkov 	},
651d9b57aa3SJens Axboe };
652d9b57aa3SJens Axboe 
io_uring_get_opcode(u8 opcode)653d9b57aa3SJens Axboe const char *io_uring_get_opcode(u8 opcode)
654d9b57aa3SJens Axboe {
655d9b57aa3SJens Axboe 	if (opcode < IORING_OP_LAST)
656f30bd4d0SBreno Leitao 		return io_cold_defs[opcode].name;
657d9b57aa3SJens Axboe 	return "INVALID";
658d9b57aa3SJens Axboe }
659d9b57aa3SJens Axboe 
io_uring_optable_init(void)660d9b57aa3SJens Axboe void __init io_uring_optable_init(void)
661d9b57aa3SJens Axboe {
662d9b57aa3SJens Axboe 	int i;
663d9b57aa3SJens Axboe 
664f30bd4d0SBreno Leitao 	BUILD_BUG_ON(ARRAY_SIZE(io_cold_defs) != IORING_OP_LAST);
665a7dd2782SBreno Leitao 	BUILD_BUG_ON(ARRAY_SIZE(io_issue_defs) != IORING_OP_LAST);
666d9b57aa3SJens Axboe 
667a7dd2782SBreno Leitao 	for (i = 0; i < ARRAY_SIZE(io_issue_defs); i++) {
668a7dd2782SBreno Leitao 		BUG_ON(!io_issue_defs[i].prep);
669a7dd2782SBreno Leitao 		if (io_issue_defs[i].prep != io_eopnotsupp_prep)
670a7dd2782SBreno Leitao 			BUG_ON(!io_issue_defs[i].issue);
671f30bd4d0SBreno Leitao 		WARN_ON_ONCE(!io_cold_defs[i].name);
672d9b57aa3SJens Axboe 	}
673d9b57aa3SJens Axboe }
674