1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * io_uring opcode handling table 4 */ 5 #include <linux/kernel.h> 6 #include <linux/errno.h> 7 #include <linux/fs.h> 8 #include <linux/file.h> 9 #include <linux/io_uring.h> 10 #include <linux/io_uring/cmd.h> 11 12 #include "io_uring.h" 13 #include "opdef.h" 14 #include "refs.h" 15 #include "tctx.h" 16 #include "sqpoll.h" 17 #include "fdinfo.h" 18 #include "kbuf.h" 19 #include "rsrc.h" 20 21 #include "xattr.h" 22 #include "nop.h" 23 #include "fs.h" 24 #include "splice.h" 25 #include "sync.h" 26 #include "advise.h" 27 #include "openclose.h" 28 #include "uring_cmd.h" 29 #include "epoll.h" 30 #include "statx.h" 31 #include "net.h" 32 #include "msg_ring.h" 33 #include "timeout.h" 34 #include "poll.h" 35 #include "cancel.h" 36 #include "rw.h" 37 #include "waitid.h" 38 #include "futex.h" 39 #include "truncate.h" 40 #include "zcrx.h" 41 42 static int io_no_issue(struct io_kiocb *req, unsigned int issue_flags) 43 { 44 WARN_ON_ONCE(1); 45 return -ECANCELED; 46 } 47 48 static __maybe_unused int io_eopnotsupp_prep(struct io_kiocb *kiocb, 49 const struct io_uring_sqe *sqe) 50 { 51 return -EOPNOTSUPP; 52 } 53 54 const struct io_issue_def io_issue_defs[] = { 55 [IORING_OP_NOP] = { 56 .audit_skip = 1, 57 .iopoll = 1, 58 .prep = io_nop_prep, 59 .issue = io_nop, 60 }, 61 [IORING_OP_READV] = { 62 .needs_file = 1, 63 .unbound_nonreg_file = 1, 64 .pollin = 1, 65 .buffer_select = 1, 66 .plug = 1, 67 .audit_skip = 1, 68 .ioprio = 1, 69 .iopoll = 1, 70 .vectored = 1, 71 .async_size = sizeof(struct io_async_rw), 72 .prep = io_prep_readv, 73 .issue = io_read, 74 }, 75 [IORING_OP_WRITEV] = { 76 .needs_file = 1, 77 .hash_reg_file = 1, 78 .unbound_nonreg_file = 1, 79 .pollout = 1, 80 .plug = 1, 81 .audit_skip = 1, 82 .ioprio = 1, 83 .iopoll = 1, 84 .vectored = 1, 85 .async_size = sizeof(struct io_async_rw), 86 .prep = io_prep_writev, 87 .issue = io_write, 88 }, 89 [IORING_OP_FSYNC] = { 90 .needs_file = 1, 91 .audit_skip = 1, 92 .prep = io_fsync_prep, 93 .issue = io_fsync, 94 }, 95 [IORING_OP_READ_FIXED] = { 96 .needs_file = 1, 97 .unbound_nonreg_file = 1, 98 .pollin = 1, 99 .plug = 1, 100 .audit_skip = 1, 101 .ioprio = 1, 102 .iopoll = 1, 103 .async_size = sizeof(struct io_async_rw), 104 .prep = io_prep_read_fixed, 105 .issue = io_read_fixed, 106 }, 107 [IORING_OP_WRITE_FIXED] = { 108 .needs_file = 1, 109 .hash_reg_file = 1, 110 .unbound_nonreg_file = 1, 111 .pollout = 1, 112 .plug = 1, 113 .audit_skip = 1, 114 .ioprio = 1, 115 .iopoll = 1, 116 .async_size = sizeof(struct io_async_rw), 117 .prep = io_prep_write_fixed, 118 .issue = io_write_fixed, 119 }, 120 [IORING_OP_POLL_ADD] = { 121 .needs_file = 1, 122 .unbound_nonreg_file = 1, 123 .audit_skip = 1, 124 .prep = io_poll_add_prep, 125 .issue = io_poll_add, 126 }, 127 [IORING_OP_POLL_REMOVE] = { 128 .audit_skip = 1, 129 .prep = io_poll_remove_prep, 130 .issue = io_poll_remove, 131 }, 132 [IORING_OP_SYNC_FILE_RANGE] = { 133 .needs_file = 1, 134 .audit_skip = 1, 135 .prep = io_sfr_prep, 136 .issue = io_sync_file_range, 137 }, 138 [IORING_OP_SENDMSG] = { 139 .needs_file = 1, 140 .unbound_nonreg_file = 1, 141 .pollout = 1, 142 .ioprio = 1, 143 #if defined(CONFIG_NET) 144 .async_size = sizeof(struct io_async_msghdr), 145 .prep = io_sendmsg_prep, 146 .issue = io_sendmsg, 147 #else 148 .prep = io_eopnotsupp_prep, 149 #endif 150 }, 151 [IORING_OP_RECVMSG] = { 152 .needs_file = 1, 153 .unbound_nonreg_file = 1, 154 .pollin = 1, 155 .buffer_select = 1, 156 .ioprio = 1, 157 #if defined(CONFIG_NET) 158 .async_size = sizeof(struct io_async_msghdr), 159 .prep = io_recvmsg_prep, 160 .issue = io_recvmsg, 161 #else 162 .prep = io_eopnotsupp_prep, 163 #endif 164 }, 165 [IORING_OP_TIMEOUT] = { 166 .audit_skip = 1, 167 .async_size = sizeof(struct io_timeout_data), 168 .prep = io_timeout_prep, 169 .issue = io_timeout, 170 }, 171 [IORING_OP_TIMEOUT_REMOVE] = { 172 /* used by timeout updates' prep() */ 173 .audit_skip = 1, 174 .prep = io_timeout_remove_prep, 175 .issue = io_timeout_remove, 176 }, 177 [IORING_OP_ACCEPT] = { 178 .needs_file = 1, 179 .unbound_nonreg_file = 1, 180 .pollin = 1, 181 .poll_exclusive = 1, 182 .ioprio = 1, /* used for flags */ 183 #if defined(CONFIG_NET) 184 .prep = io_accept_prep, 185 .issue = io_accept, 186 #else 187 .prep = io_eopnotsupp_prep, 188 #endif 189 }, 190 [IORING_OP_ASYNC_CANCEL] = { 191 .audit_skip = 1, 192 .prep = io_async_cancel_prep, 193 .issue = io_async_cancel, 194 }, 195 [IORING_OP_LINK_TIMEOUT] = { 196 .audit_skip = 1, 197 .async_size = sizeof(struct io_timeout_data), 198 .prep = io_link_timeout_prep, 199 .issue = io_no_issue, 200 }, 201 [IORING_OP_CONNECT] = { 202 .needs_file = 1, 203 .unbound_nonreg_file = 1, 204 .pollout = 1, 205 #if defined(CONFIG_NET) 206 .filter_pdu_size = sizeof_field(struct io_uring_bpf_ctx, connect), 207 .async_size = sizeof(struct sockaddr_storage), 208 .prep = io_connect_prep, 209 .issue = io_connect, 210 .filter_populate = io_connect_bpf_populate, 211 #else 212 .prep = io_eopnotsupp_prep, 213 #endif 214 }, 215 [IORING_OP_FALLOCATE] = { 216 .needs_file = 1, 217 .hash_reg_file = 1, 218 .prep = io_fallocate_prep, 219 .issue = io_fallocate, 220 }, 221 [IORING_OP_OPENAT] = { 222 .filter_pdu_size = sizeof_field(struct io_uring_bpf_ctx, open), 223 .prep = io_openat_prep, 224 .issue = io_openat, 225 .filter_populate = io_openat_bpf_populate, 226 }, 227 [IORING_OP_CLOSE] = { 228 .prep = io_close_prep, 229 .issue = io_close, 230 }, 231 [IORING_OP_FILES_UPDATE] = { 232 .audit_skip = 1, 233 .iopoll = 1, 234 .prep = io_files_update_prep, 235 .issue = io_files_update, 236 }, 237 [IORING_OP_STATX] = { 238 .audit_skip = 1, 239 .prep = io_statx_prep, 240 .issue = io_statx, 241 }, 242 [IORING_OP_READ] = { 243 .needs_file = 1, 244 .unbound_nonreg_file = 1, 245 .pollin = 1, 246 .buffer_select = 1, 247 .plug = 1, 248 .audit_skip = 1, 249 .ioprio = 1, 250 .iopoll = 1, 251 .async_size = sizeof(struct io_async_rw), 252 .prep = io_prep_read, 253 .issue = io_read, 254 }, 255 [IORING_OP_WRITE] = { 256 .needs_file = 1, 257 .hash_reg_file = 1, 258 .unbound_nonreg_file = 1, 259 .pollout = 1, 260 .plug = 1, 261 .audit_skip = 1, 262 .ioprio = 1, 263 .iopoll = 1, 264 .async_size = sizeof(struct io_async_rw), 265 .prep = io_prep_write, 266 .issue = io_write, 267 }, 268 [IORING_OP_FADVISE] = { 269 .needs_file = 1, 270 .audit_skip = 1, 271 .prep = io_fadvise_prep, 272 .issue = io_fadvise, 273 }, 274 [IORING_OP_MADVISE] = { 275 .audit_skip = 1, 276 .prep = io_madvise_prep, 277 .issue = io_madvise, 278 }, 279 [IORING_OP_SEND] = { 280 .needs_file = 1, 281 .unbound_nonreg_file = 1, 282 .pollout = 1, 283 .audit_skip = 1, 284 .ioprio = 1, 285 .buffer_select = 1, 286 #if defined(CONFIG_NET) 287 .async_size = sizeof(struct io_async_msghdr), 288 .prep = io_sendmsg_prep, 289 .issue = io_send, 290 #else 291 .prep = io_eopnotsupp_prep, 292 #endif 293 }, 294 [IORING_OP_RECV] = { 295 .needs_file = 1, 296 .unbound_nonreg_file = 1, 297 .pollin = 1, 298 .buffer_select = 1, 299 .audit_skip = 1, 300 .ioprio = 1, 301 #if defined(CONFIG_NET) 302 .async_size = sizeof(struct io_async_msghdr), 303 .prep = io_recvmsg_prep, 304 .issue = io_recv, 305 #else 306 .prep = io_eopnotsupp_prep, 307 #endif 308 }, 309 [IORING_OP_OPENAT2] = { 310 .filter_pdu_size = sizeof_field(struct io_uring_bpf_ctx, open), 311 .prep = io_openat2_prep, 312 .issue = io_openat2, 313 .filter_populate = io_openat_bpf_populate, 314 }, 315 [IORING_OP_EPOLL_CTL] = { 316 .unbound_nonreg_file = 1, 317 .audit_skip = 1, 318 #if defined(CONFIG_EPOLL) 319 .prep = io_epoll_ctl_prep, 320 .issue = io_epoll_ctl, 321 #else 322 .prep = io_eopnotsupp_prep, 323 #endif 324 }, 325 [IORING_OP_SPLICE] = { 326 .needs_file = 1, 327 .hash_reg_file = 1, 328 .unbound_nonreg_file = 1, 329 .audit_skip = 1, 330 .prep = io_splice_prep, 331 .issue = io_splice, 332 }, 333 [IORING_OP_PROVIDE_BUFFERS] = { 334 .audit_skip = 1, 335 .iopoll = 1, 336 .prep = io_provide_buffers_prep, 337 .issue = io_manage_buffers_legacy, 338 }, 339 [IORING_OP_REMOVE_BUFFERS] = { 340 .audit_skip = 1, 341 .iopoll = 1, 342 .prep = io_remove_buffers_prep, 343 .issue = io_manage_buffers_legacy, 344 }, 345 [IORING_OP_TEE] = { 346 .needs_file = 1, 347 .hash_reg_file = 1, 348 .unbound_nonreg_file = 1, 349 .audit_skip = 1, 350 .prep = io_tee_prep, 351 .issue = io_tee, 352 }, 353 [IORING_OP_SHUTDOWN] = { 354 .needs_file = 1, 355 #if defined(CONFIG_NET) 356 .prep = io_shutdown_prep, 357 .issue = io_shutdown, 358 #else 359 .prep = io_eopnotsupp_prep, 360 #endif 361 }, 362 [IORING_OP_RENAMEAT] = { 363 .prep = io_renameat_prep, 364 .issue = io_renameat, 365 }, 366 [IORING_OP_UNLINKAT] = { 367 .prep = io_unlinkat_prep, 368 .issue = io_unlinkat, 369 }, 370 [IORING_OP_MKDIRAT] = { 371 .prep = io_mkdirat_prep, 372 .issue = io_mkdirat, 373 }, 374 [IORING_OP_SYMLINKAT] = { 375 .prep = io_symlinkat_prep, 376 .issue = io_symlinkat, 377 }, 378 [IORING_OP_LINKAT] = { 379 .prep = io_linkat_prep, 380 .issue = io_linkat, 381 }, 382 [IORING_OP_MSG_RING] = { 383 .needs_file = 1, 384 .iopoll = 1, 385 .prep = io_msg_ring_prep, 386 .issue = io_msg_ring, 387 }, 388 [IORING_OP_FSETXATTR] = { 389 .needs_file = 1, 390 .prep = io_fsetxattr_prep, 391 .issue = io_fsetxattr, 392 }, 393 [IORING_OP_SETXATTR] = { 394 .prep = io_setxattr_prep, 395 .issue = io_setxattr, 396 }, 397 [IORING_OP_FGETXATTR] = { 398 .needs_file = 1, 399 .prep = io_fgetxattr_prep, 400 .issue = io_fgetxattr, 401 }, 402 [IORING_OP_GETXATTR] = { 403 .prep = io_getxattr_prep, 404 .issue = io_getxattr, 405 }, 406 [IORING_OP_SOCKET] = { 407 .audit_skip = 1, 408 #if defined(CONFIG_NET) 409 .filter_pdu_size = sizeof_field(struct io_uring_bpf_ctx, socket), 410 .prep = io_socket_prep, 411 .issue = io_socket, 412 .filter_populate = io_socket_bpf_populate, 413 #else 414 .prep = io_eopnotsupp_prep, 415 #endif 416 }, 417 [IORING_OP_URING_CMD] = { 418 .buffer_select = 1, 419 .needs_file = 1, 420 .plug = 1, 421 .iopoll = 1, 422 .async_size = sizeof(struct io_async_cmd), 423 .prep = io_uring_cmd_prep, 424 .issue = io_uring_cmd, 425 }, 426 [IORING_OP_SEND_ZC] = { 427 .needs_file = 1, 428 .unbound_nonreg_file = 1, 429 .pollout = 1, 430 .audit_skip = 1, 431 .ioprio = 1, 432 #if defined(CONFIG_NET) 433 .async_size = sizeof(struct io_async_msghdr), 434 .prep = io_send_zc_prep, 435 .issue = io_sendmsg_zc, 436 #else 437 .prep = io_eopnotsupp_prep, 438 #endif 439 }, 440 [IORING_OP_SENDMSG_ZC] = { 441 .needs_file = 1, 442 .unbound_nonreg_file = 1, 443 .pollout = 1, 444 .ioprio = 1, 445 #if defined(CONFIG_NET) 446 .async_size = sizeof(struct io_async_msghdr), 447 .prep = io_send_zc_prep, 448 .issue = io_sendmsg_zc, 449 #else 450 .prep = io_eopnotsupp_prep, 451 #endif 452 }, 453 [IORING_OP_READ_MULTISHOT] = { 454 .needs_file = 1, 455 .unbound_nonreg_file = 1, 456 .pollin = 1, 457 .buffer_select = 1, 458 .audit_skip = 1, 459 .async_size = sizeof(struct io_async_rw), 460 .prep = io_read_mshot_prep, 461 .issue = io_read_mshot, 462 }, 463 [IORING_OP_WAITID] = { 464 .async_size = sizeof(struct io_waitid_async), 465 .prep = io_waitid_prep, 466 .issue = io_waitid, 467 }, 468 [IORING_OP_FUTEX_WAIT] = { 469 #if defined(CONFIG_FUTEX) 470 .prep = io_futex_prep, 471 .issue = io_futex_wait, 472 #else 473 .prep = io_eopnotsupp_prep, 474 #endif 475 }, 476 [IORING_OP_FUTEX_WAKE] = { 477 #if defined(CONFIG_FUTEX) 478 .prep = io_futex_prep, 479 .issue = io_futex_wake, 480 #else 481 .prep = io_eopnotsupp_prep, 482 #endif 483 }, 484 [IORING_OP_FUTEX_WAITV] = { 485 #if defined(CONFIG_FUTEX) 486 .prep = io_futexv_prep, 487 .issue = io_futexv_wait, 488 #else 489 .prep = io_eopnotsupp_prep, 490 #endif 491 }, 492 [IORING_OP_FIXED_FD_INSTALL] = { 493 .needs_file = 1, 494 .prep = io_install_fixed_fd_prep, 495 .issue = io_install_fixed_fd, 496 }, 497 [IORING_OP_FTRUNCATE] = { 498 .needs_file = 1, 499 .hash_reg_file = 1, 500 .prep = io_ftruncate_prep, 501 .issue = io_ftruncate, 502 }, 503 [IORING_OP_BIND] = { 504 #if defined(CONFIG_NET) 505 .needs_file = 1, 506 .prep = io_bind_prep, 507 .issue = io_bind, 508 .async_size = sizeof(struct sockaddr_storage), 509 #else 510 .prep = io_eopnotsupp_prep, 511 #endif 512 }, 513 [IORING_OP_LISTEN] = { 514 #if defined(CONFIG_NET) 515 .needs_file = 1, 516 .prep = io_listen_prep, 517 .issue = io_listen, 518 #else 519 .prep = io_eopnotsupp_prep, 520 #endif 521 }, 522 [IORING_OP_RECV_ZC] = { 523 .needs_file = 1, 524 .unbound_nonreg_file = 1, 525 .pollin = 1, 526 .ioprio = 1, 527 #if defined(CONFIG_NET) 528 .prep = io_recvzc_prep, 529 .issue = io_recvzc, 530 #else 531 .prep = io_eopnotsupp_prep, 532 #endif 533 }, 534 [IORING_OP_EPOLL_WAIT] = { 535 .needs_file = 1, 536 .audit_skip = 1, 537 .pollin = 1, 538 #if defined(CONFIG_EPOLL) 539 .prep = io_epoll_wait_prep, 540 .issue = io_epoll_wait, 541 #else 542 .prep = io_eopnotsupp_prep, 543 #endif 544 }, 545 [IORING_OP_READV_FIXED] = { 546 .needs_file = 1, 547 .unbound_nonreg_file = 1, 548 .pollin = 1, 549 .plug = 1, 550 .audit_skip = 1, 551 .ioprio = 1, 552 .iopoll = 1, 553 .vectored = 1, 554 .async_size = sizeof(struct io_async_rw), 555 .prep = io_prep_readv_fixed, 556 .issue = io_read, 557 }, 558 [IORING_OP_WRITEV_FIXED] = { 559 .needs_file = 1, 560 .hash_reg_file = 1, 561 .unbound_nonreg_file = 1, 562 .pollout = 1, 563 .plug = 1, 564 .audit_skip = 1, 565 .ioprio = 1, 566 .iopoll = 1, 567 .vectored = 1, 568 .async_size = sizeof(struct io_async_rw), 569 .prep = io_prep_writev_fixed, 570 .issue = io_write, 571 }, 572 [IORING_OP_PIPE] = { 573 .prep = io_pipe_prep, 574 .issue = io_pipe, 575 }, 576 [IORING_OP_NOP128] = { 577 .audit_skip = 1, 578 .iopoll = 1, 579 .is_128 = 1, 580 .prep = io_nop_prep, 581 .issue = io_nop, 582 }, 583 [IORING_OP_URING_CMD128] = { 584 .buffer_select = 1, 585 .needs_file = 1, 586 .plug = 1, 587 .iopoll = 1, 588 .is_128 = 1, 589 .async_size = sizeof(struct io_async_cmd), 590 .prep = io_uring_cmd_prep, 591 .issue = io_uring_cmd, 592 }, 593 }; 594 595 const struct io_cold_def io_cold_defs[] = { 596 [IORING_OP_NOP] = { 597 .name = "NOP", 598 }, 599 [IORING_OP_READV] = { 600 .name = "READV", 601 .cleanup = io_readv_writev_cleanup, 602 .fail = io_rw_fail, 603 }, 604 [IORING_OP_WRITEV] = { 605 .name = "WRITEV", 606 .cleanup = io_readv_writev_cleanup, 607 .fail = io_rw_fail, 608 }, 609 [IORING_OP_FSYNC] = { 610 .name = "FSYNC", 611 }, 612 [IORING_OP_READ_FIXED] = { 613 .name = "READ_FIXED", 614 .cleanup = io_readv_writev_cleanup, 615 .fail = io_rw_fail, 616 }, 617 [IORING_OP_WRITE_FIXED] = { 618 .name = "WRITE_FIXED", 619 .cleanup = io_readv_writev_cleanup, 620 .fail = io_rw_fail, 621 }, 622 [IORING_OP_POLL_ADD] = { 623 .name = "POLL_ADD", 624 }, 625 [IORING_OP_POLL_REMOVE] = { 626 .name = "POLL_REMOVE", 627 }, 628 [IORING_OP_SYNC_FILE_RANGE] = { 629 .name = "SYNC_FILE_RANGE", 630 }, 631 [IORING_OP_SENDMSG] = { 632 .name = "SENDMSG", 633 #if defined(CONFIG_NET) 634 .cleanup = io_sendmsg_recvmsg_cleanup, 635 .fail = io_sendrecv_fail, 636 #endif 637 }, 638 [IORING_OP_RECVMSG] = { 639 .name = "RECVMSG", 640 #if defined(CONFIG_NET) 641 .cleanup = io_sendmsg_recvmsg_cleanup, 642 .fail = io_sendrecv_fail, 643 #endif 644 }, 645 [IORING_OP_TIMEOUT] = { 646 .name = "TIMEOUT", 647 }, 648 [IORING_OP_TIMEOUT_REMOVE] = { 649 .name = "TIMEOUT_REMOVE", 650 }, 651 [IORING_OP_ACCEPT] = { 652 .name = "ACCEPT", 653 }, 654 [IORING_OP_ASYNC_CANCEL] = { 655 .name = "ASYNC_CANCEL", 656 }, 657 [IORING_OP_LINK_TIMEOUT] = { 658 .name = "LINK_TIMEOUT", 659 }, 660 [IORING_OP_CONNECT] = { 661 .name = "CONNECT", 662 }, 663 [IORING_OP_FALLOCATE] = { 664 .name = "FALLOCATE", 665 }, 666 [IORING_OP_OPENAT] = { 667 .name = "OPENAT", 668 .cleanup = io_open_cleanup, 669 }, 670 [IORING_OP_CLOSE] = { 671 .name = "CLOSE", 672 }, 673 [IORING_OP_FILES_UPDATE] = { 674 .name = "FILES_UPDATE", 675 }, 676 [IORING_OP_STATX] = { 677 .name = "STATX", 678 .cleanup = io_statx_cleanup, 679 }, 680 [IORING_OP_READ] = { 681 .name = "READ", 682 .cleanup = io_readv_writev_cleanup, 683 .fail = io_rw_fail, 684 }, 685 [IORING_OP_WRITE] = { 686 .name = "WRITE", 687 .cleanup = io_readv_writev_cleanup, 688 .fail = io_rw_fail, 689 }, 690 [IORING_OP_FADVISE] = { 691 .name = "FADVISE", 692 }, 693 [IORING_OP_MADVISE] = { 694 .name = "MADVISE", 695 }, 696 [IORING_OP_SEND] = { 697 .name = "SEND", 698 #if defined(CONFIG_NET) 699 .cleanup = io_sendmsg_recvmsg_cleanup, 700 .fail = io_sendrecv_fail, 701 #endif 702 }, 703 [IORING_OP_RECV] = { 704 .name = "RECV", 705 #if defined(CONFIG_NET) 706 .cleanup = io_sendmsg_recvmsg_cleanup, 707 .fail = io_sendrecv_fail, 708 #endif 709 }, 710 [IORING_OP_OPENAT2] = { 711 .name = "OPENAT2", 712 .cleanup = io_open_cleanup, 713 }, 714 [IORING_OP_EPOLL_CTL] = { 715 .name = "EPOLL", 716 }, 717 [IORING_OP_SPLICE] = { 718 .name = "SPLICE", 719 .cleanup = io_splice_cleanup, 720 }, 721 [IORING_OP_PROVIDE_BUFFERS] = { 722 .name = "PROVIDE_BUFFERS", 723 }, 724 [IORING_OP_REMOVE_BUFFERS] = { 725 .name = "REMOVE_BUFFERS", 726 }, 727 [IORING_OP_TEE] = { 728 .name = "TEE", 729 .cleanup = io_splice_cleanup, 730 }, 731 [IORING_OP_SHUTDOWN] = { 732 .name = "SHUTDOWN", 733 }, 734 [IORING_OP_RENAMEAT] = { 735 .name = "RENAMEAT", 736 .cleanup = io_renameat_cleanup, 737 }, 738 [IORING_OP_UNLINKAT] = { 739 .name = "UNLINKAT", 740 .cleanup = io_unlinkat_cleanup, 741 }, 742 [IORING_OP_MKDIRAT] = { 743 .name = "MKDIRAT", 744 .cleanup = io_mkdirat_cleanup, 745 }, 746 [IORING_OP_SYMLINKAT] = { 747 .name = "SYMLINKAT", 748 .cleanup = io_link_cleanup, 749 }, 750 [IORING_OP_LINKAT] = { 751 .name = "LINKAT", 752 .cleanup = io_link_cleanup, 753 }, 754 [IORING_OP_MSG_RING] = { 755 .name = "MSG_RING", 756 .cleanup = io_msg_ring_cleanup, 757 }, 758 [IORING_OP_FSETXATTR] = { 759 .name = "FSETXATTR", 760 .cleanup = io_xattr_cleanup, 761 }, 762 [IORING_OP_SETXATTR] = { 763 .name = "SETXATTR", 764 .cleanup = io_xattr_cleanup, 765 }, 766 [IORING_OP_FGETXATTR] = { 767 .name = "FGETXATTR", 768 .cleanup = io_xattr_cleanup, 769 }, 770 [IORING_OP_GETXATTR] = { 771 .name = "GETXATTR", 772 .cleanup = io_xattr_cleanup, 773 }, 774 [IORING_OP_SOCKET] = { 775 .name = "SOCKET", 776 }, 777 [IORING_OP_URING_CMD] = { 778 .name = "URING_CMD", 779 .sqe_copy = io_uring_cmd_sqe_copy, 780 .cleanup = io_uring_cmd_cleanup, 781 }, 782 [IORING_OP_SEND_ZC] = { 783 .name = "SEND_ZC", 784 #if defined(CONFIG_NET) 785 .cleanup = io_send_zc_cleanup, 786 .fail = io_sendrecv_fail, 787 #endif 788 }, 789 [IORING_OP_SENDMSG_ZC] = { 790 .name = "SENDMSG_ZC", 791 #if defined(CONFIG_NET) 792 .cleanup = io_send_zc_cleanup, 793 .fail = io_sendrecv_fail, 794 #endif 795 }, 796 [IORING_OP_READ_MULTISHOT] = { 797 .name = "READ_MULTISHOT", 798 .cleanup = io_readv_writev_cleanup, 799 }, 800 [IORING_OP_WAITID] = { 801 .name = "WAITID", 802 }, 803 [IORING_OP_FUTEX_WAIT] = { 804 .name = "FUTEX_WAIT", 805 }, 806 [IORING_OP_FUTEX_WAKE] = { 807 .name = "FUTEX_WAKE", 808 }, 809 [IORING_OP_FUTEX_WAITV] = { 810 .name = "FUTEX_WAITV", 811 }, 812 [IORING_OP_FIXED_FD_INSTALL] = { 813 .name = "FIXED_FD_INSTALL", 814 }, 815 [IORING_OP_FTRUNCATE] = { 816 .name = "FTRUNCATE", 817 }, 818 [IORING_OP_BIND] = { 819 .name = "BIND", 820 }, 821 [IORING_OP_LISTEN] = { 822 .name = "LISTEN", 823 }, 824 [IORING_OP_RECV_ZC] = { 825 .name = "RECV_ZC", 826 }, 827 [IORING_OP_EPOLL_WAIT] = { 828 .name = "EPOLL_WAIT", 829 }, 830 [IORING_OP_READV_FIXED] = { 831 .name = "READV_FIXED", 832 .cleanup = io_readv_writev_cleanup, 833 .fail = io_rw_fail, 834 }, 835 [IORING_OP_WRITEV_FIXED] = { 836 .name = "WRITEV_FIXED", 837 .cleanup = io_readv_writev_cleanup, 838 .fail = io_rw_fail, 839 }, 840 [IORING_OP_PIPE] = { 841 .name = "PIPE", 842 }, 843 [IORING_OP_NOP128] = { 844 .name = "NOP128", 845 }, 846 [IORING_OP_URING_CMD128] = { 847 .name = "URING_CMD128", 848 .sqe_copy = io_uring_cmd_sqe_copy, 849 .cleanup = io_uring_cmd_cleanup, 850 }, 851 }; 852 853 const char *io_uring_get_opcode(u8 opcode) 854 { 855 if (opcode < IORING_OP_LAST) 856 return io_cold_defs[opcode].name; 857 return "INVALID"; 858 } 859 860 bool io_uring_op_supported(u8 opcode) 861 { 862 if (opcode < IORING_OP_LAST && 863 io_issue_defs[opcode].prep != io_eopnotsupp_prep) 864 return true; 865 return false; 866 } 867 868 void __init io_uring_optable_init(void) 869 { 870 int i; 871 872 BUILD_BUG_ON(ARRAY_SIZE(io_cold_defs) != IORING_OP_LAST); 873 BUILD_BUG_ON(ARRAY_SIZE(io_issue_defs) != IORING_OP_LAST); 874 875 for (i = 0; i < ARRAY_SIZE(io_issue_defs); i++) { 876 BUG_ON(!io_issue_defs[i].prep); 877 if (io_issue_defs[i].prep != io_eopnotsupp_prep) 878 BUG_ON(!io_issue_defs[i].issue); 879 WARN_ON_ONCE(!io_cold_defs[i].name); 880 } 881 } 882