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