1 // SPDX-License-Identifier: GPL-2.0
3 * io_uring opcode handling table
5 #include <linux/kernel.h>
6 #include <linux/errno.h>
8 #include <linux/file.h>
9 #include <linux/io_uring.h>
26 #include "openclose.h"
27 #include "uring_cmd.h"
38 static int io_no_issue(struct io_kiocb *req, unsigned int issue_flags)
44 static __maybe_unused int io_eopnotsupp_prep(struct io_kiocb *kiocb,
45 const struct io_uring_sqe *sqe)
50 const struct io_issue_def io_issue_defs[] = {
59 .unbound_nonreg_file = 1,
71 [IORING_OP_WRITEV] = {
74 .unbound_nonreg_file = 1,
88 .prep = io_fsync_prep,
91 [IORING_OP_READ_FIXED] = {
93 .unbound_nonreg_file = 1,
103 [IORING_OP_WRITE_FIXED] = {
106 .unbound_nonreg_file = 1,
116 [IORING_OP_POLL_ADD] = {
118 .unbound_nonreg_file = 1,
120 .prep = io_poll_add_prep,
121 .issue = io_poll_add,
123 [IORING_OP_POLL_REMOVE] = {
125 .prep = io_poll_remove_prep,
126 .issue = io_poll_remove,
128 [IORING_OP_SYNC_FILE_RANGE] = {
132 .issue = io_sync_file_range,
134 [IORING_OP_SENDMSG] = {
136 .unbound_nonreg_file = 1,
140 #if defined(CONFIG_NET)
141 .prep = io_sendmsg_prep,
144 .prep = io_eopnotsupp_prep,
147 [IORING_OP_RECVMSG] = {
149 .unbound_nonreg_file = 1,
154 #if defined(CONFIG_NET)
155 .prep = io_recvmsg_prep,
158 .prep = io_eopnotsupp_prep,
161 [IORING_OP_TIMEOUT] = {
163 .prep = io_timeout_prep,
166 [IORING_OP_TIMEOUT_REMOVE] = {
167 /* used by timeout updates' prep() */
169 .prep = io_timeout_remove_prep,
170 .issue = io_timeout_remove,
172 [IORING_OP_ACCEPT] = {
174 .unbound_nonreg_file = 1,
177 .ioprio = 1, /* used for flags */
178 #if defined(CONFIG_NET)
179 .prep = io_accept_prep,
182 .prep = io_eopnotsupp_prep,
185 [IORING_OP_ASYNC_CANCEL] = {
187 .prep = io_async_cancel_prep,
188 .issue = io_async_cancel,
190 [IORING_OP_LINK_TIMEOUT] = {
192 .prep = io_link_timeout_prep,
193 .issue = io_no_issue,
195 [IORING_OP_CONNECT] = {
197 .unbound_nonreg_file = 1,
199 #if defined(CONFIG_NET)
200 .prep = io_connect_prep,
203 .prep = io_eopnotsupp_prep,
206 [IORING_OP_FALLOCATE] = {
208 .prep = io_fallocate_prep,
209 .issue = io_fallocate,
211 [IORING_OP_OPENAT] = {
212 .prep = io_openat_prep,
215 [IORING_OP_CLOSE] = {
216 .prep = io_close_prep,
219 [IORING_OP_FILES_UPDATE] = {
222 .prep = io_files_update_prep,
223 .issue = io_files_update,
225 [IORING_OP_STATX] = {
227 .prep = io_statx_prep,
232 .unbound_nonreg_file = 1,
243 [IORING_OP_WRITE] = {
246 .unbound_nonreg_file = 1,
256 [IORING_OP_FADVISE] = {
259 .prep = io_fadvise_prep,
262 [IORING_OP_MADVISE] = {
264 .prep = io_madvise_prep,
269 .unbound_nonreg_file = 1,
274 #if defined(CONFIG_NET)
275 .prep = io_sendmsg_prep,
278 .prep = io_eopnotsupp_prep,
283 .unbound_nonreg_file = 1,
288 #if defined(CONFIG_NET)
289 .prep = io_recvmsg_prep,
292 .prep = io_eopnotsupp_prep,
295 [IORING_OP_OPENAT2] = {
296 .prep = io_openat2_prep,
299 [IORING_OP_EPOLL_CTL] = {
300 .unbound_nonreg_file = 1,
302 #if defined(CONFIG_EPOLL)
303 .prep = io_epoll_ctl_prep,
304 .issue = io_epoll_ctl,
306 .prep = io_eopnotsupp_prep,
309 [IORING_OP_SPLICE] = {
312 .unbound_nonreg_file = 1,
314 .prep = io_splice_prep,
317 [IORING_OP_PROVIDE_BUFFERS] = {
320 .prep = io_provide_buffers_prep,
321 .issue = io_provide_buffers,
323 [IORING_OP_REMOVE_BUFFERS] = {
326 .prep = io_remove_buffers_prep,
327 .issue = io_remove_buffers,
332 .unbound_nonreg_file = 1,
337 [IORING_OP_SHUTDOWN] = {
339 #if defined(CONFIG_NET)
340 .prep = io_shutdown_prep,
341 .issue = io_shutdown,
343 .prep = io_eopnotsupp_prep,
346 [IORING_OP_RENAMEAT] = {
347 .prep = io_renameat_prep,
348 .issue = io_renameat,
350 [IORING_OP_UNLINKAT] = {
351 .prep = io_unlinkat_prep,
352 .issue = io_unlinkat,
354 [IORING_OP_MKDIRAT] = {
355 .prep = io_mkdirat_prep,
358 [IORING_OP_SYMLINKAT] = {
359 .prep = io_symlinkat_prep,
360 .issue = io_symlinkat,
362 [IORING_OP_LINKAT] = {
363 .prep = io_linkat_prep,
366 [IORING_OP_MSG_RING] = {
369 .prep = io_msg_ring_prep,
370 .issue = io_msg_ring,
372 [IORING_OP_FSETXATTR] = {
374 .prep = io_fsetxattr_prep,
375 .issue = io_fsetxattr,
377 [IORING_OP_SETXATTR] = {
378 .prep = io_setxattr_prep,
379 .issue = io_setxattr,
381 [IORING_OP_FGETXATTR] = {
383 .prep = io_fgetxattr_prep,
384 .issue = io_fgetxattr,
386 [IORING_OP_GETXATTR] = {
387 .prep = io_getxattr_prep,
388 .issue = io_getxattr,
390 [IORING_OP_SOCKET] = {
392 #if defined(CONFIG_NET)
393 .prep = io_socket_prep,
396 .prep = io_eopnotsupp_prep,
399 [IORING_OP_URING_CMD] = {
404 .prep = io_uring_cmd_prep,
405 .issue = io_uring_cmd,
407 [IORING_OP_SEND_ZC] = {
409 .unbound_nonreg_file = 1,
414 #if defined(CONFIG_NET)
415 .prep = io_send_zc_prep,
418 .prep = io_eopnotsupp_prep,
421 [IORING_OP_SENDMSG_ZC] = {
423 .unbound_nonreg_file = 1,
427 #if defined(CONFIG_NET)
428 .prep = io_send_zc_prep,
429 .issue = io_sendmsg_zc,
431 .prep = io_eopnotsupp_prep,
434 [IORING_OP_READ_MULTISHOT] = {
436 .unbound_nonreg_file = 1,
440 .prep = io_read_mshot_prep,
441 .issue = io_read_mshot,
443 [IORING_OP_WAITID] = {
444 .prep = io_waitid_prep,
449 const struct io_cold_def io_cold_defs[] = {
453 [IORING_OP_READV] = {
454 .async_size = sizeof(struct io_async_rw),
456 .prep_async = io_readv_prep_async,
457 .cleanup = io_readv_writev_cleanup,
460 [IORING_OP_WRITEV] = {
461 .async_size = sizeof(struct io_async_rw),
463 .prep_async = io_writev_prep_async,
464 .cleanup = io_readv_writev_cleanup,
467 [IORING_OP_FSYNC] = {
470 [IORING_OP_READ_FIXED] = {
471 .async_size = sizeof(struct io_async_rw),
472 .name = "READ_FIXED",
475 [IORING_OP_WRITE_FIXED] = {
476 .async_size = sizeof(struct io_async_rw),
477 .name = "WRITE_FIXED",
480 [IORING_OP_POLL_ADD] = {
483 [IORING_OP_POLL_REMOVE] = {
484 .name = "POLL_REMOVE",
486 [IORING_OP_SYNC_FILE_RANGE] = {
487 .name = "SYNC_FILE_RANGE",
489 [IORING_OP_SENDMSG] = {
491 #if defined(CONFIG_NET)
492 .async_size = sizeof(struct io_async_msghdr),
493 .prep_async = io_sendmsg_prep_async,
494 .cleanup = io_sendmsg_recvmsg_cleanup,
495 .fail = io_sendrecv_fail,
498 [IORING_OP_RECVMSG] = {
500 #if defined(CONFIG_NET)
501 .async_size = sizeof(struct io_async_msghdr),
502 .prep_async = io_recvmsg_prep_async,
503 .cleanup = io_sendmsg_recvmsg_cleanup,
504 .fail = io_sendrecv_fail,
507 [IORING_OP_TIMEOUT] = {
508 .async_size = sizeof(struct io_timeout_data),
511 [IORING_OP_TIMEOUT_REMOVE] = {
512 .name = "TIMEOUT_REMOVE",
514 [IORING_OP_ACCEPT] = {
517 [IORING_OP_ASYNC_CANCEL] = {
518 .name = "ASYNC_CANCEL",
520 [IORING_OP_LINK_TIMEOUT] = {
521 .async_size = sizeof(struct io_timeout_data),
522 .name = "LINK_TIMEOUT",
524 [IORING_OP_CONNECT] = {
526 #if defined(CONFIG_NET)
527 .async_size = sizeof(struct io_async_connect),
528 .prep_async = io_connect_prep_async,
531 [IORING_OP_FALLOCATE] = {
534 [IORING_OP_OPENAT] = {
536 .cleanup = io_open_cleanup,
538 [IORING_OP_CLOSE] = {
541 [IORING_OP_FILES_UPDATE] = {
542 .name = "FILES_UPDATE",
544 [IORING_OP_STATX] = {
546 .cleanup = io_statx_cleanup,
549 .async_size = sizeof(struct io_async_rw),
553 [IORING_OP_WRITE] = {
554 .async_size = sizeof(struct io_async_rw),
558 [IORING_OP_FADVISE] = {
561 [IORING_OP_MADVISE] = {
566 #if defined(CONFIG_NET)
567 .async_size = sizeof(struct io_async_msghdr),
568 .fail = io_sendrecv_fail,
569 .prep_async = io_send_prep_async,
574 #if defined(CONFIG_NET)
575 .fail = io_sendrecv_fail,
578 [IORING_OP_OPENAT2] = {
580 .cleanup = io_open_cleanup,
582 [IORING_OP_EPOLL_CTL] = {
585 [IORING_OP_SPLICE] = {
588 [IORING_OP_PROVIDE_BUFFERS] = {
589 .name = "PROVIDE_BUFFERS",
591 [IORING_OP_REMOVE_BUFFERS] = {
592 .name = "REMOVE_BUFFERS",
597 [IORING_OP_SHUTDOWN] = {
600 [IORING_OP_RENAMEAT] = {
602 .cleanup = io_renameat_cleanup,
604 [IORING_OP_UNLINKAT] = {
606 .cleanup = io_unlinkat_cleanup,
608 [IORING_OP_MKDIRAT] = {
610 .cleanup = io_mkdirat_cleanup,
612 [IORING_OP_SYMLINKAT] = {
614 .cleanup = io_link_cleanup,
616 [IORING_OP_LINKAT] = {
618 .cleanup = io_link_cleanup,
620 [IORING_OP_MSG_RING] = {
622 .cleanup = io_msg_ring_cleanup,
624 [IORING_OP_FSETXATTR] = {
626 .cleanup = io_xattr_cleanup,
628 [IORING_OP_SETXATTR] = {
630 .cleanup = io_xattr_cleanup,
632 [IORING_OP_FGETXATTR] = {
634 .cleanup = io_xattr_cleanup,
636 [IORING_OP_GETXATTR] = {
638 .cleanup = io_xattr_cleanup,
640 [IORING_OP_SOCKET] = {
643 [IORING_OP_URING_CMD] = {
645 .async_size = 2 * sizeof(struct io_uring_sqe),
646 .prep_async = io_uring_cmd_prep_async,
648 [IORING_OP_SEND_ZC] = {
650 #if defined(CONFIG_NET)
651 .async_size = sizeof(struct io_async_msghdr),
652 .prep_async = io_send_prep_async,
653 .cleanup = io_send_zc_cleanup,
654 .fail = io_sendrecv_fail,
657 [IORING_OP_SENDMSG_ZC] = {
658 .name = "SENDMSG_ZC",
659 #if defined(CONFIG_NET)
660 .async_size = sizeof(struct io_async_msghdr),
661 .prep_async = io_sendmsg_prep_async,
662 .cleanup = io_send_zc_cleanup,
663 .fail = io_sendrecv_fail,
666 [IORING_OP_READ_MULTISHOT] = {
667 .name = "READ_MULTISHOT",
669 [IORING_OP_WAITID] = {
671 .async_size = sizeof(struct io_waitid_async),
675 const char *io_uring_get_opcode(u8 opcode)
677 if (opcode < IORING_OP_LAST)
678 return io_cold_defs[opcode].name;
682 void __init io_uring_optable_init(void)
686 BUILD_BUG_ON(ARRAY_SIZE(io_cold_defs) != IORING_OP_LAST);
687 BUILD_BUG_ON(ARRAY_SIZE(io_issue_defs) != IORING_OP_LAST);
689 for (i = 0; i < ARRAY_SIZE(io_issue_defs); i++) {
690 BUG_ON(!io_issue_defs[i].prep);
691 if (io_issue_defs[i].prep != io_eopnotsupp_prep)
692 BUG_ON(!io_issue_defs[i].issue);
693 WARN_ON_ONCE(!io_cold_defs[i].name);