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", 468d9b57aa3SJens Axboe .async_size = uring_cmd_pdu_size(1), 469d9b57aa3SJens Axboe .prep = io_uring_cmd_prep, 470d9b57aa3SJens Axboe .issue = io_uring_cmd, 471d9b57aa3SJens Axboe .prep_async = io_uring_cmd_prep_async, 472d9b57aa3SJens Axboe }, 473*b48c312bSPavel Begunkov [IORING_OP_SEND_ZC] = { 47406a5464bSPavel Begunkov .name = "SENDZC_NOTIF", 47506a5464bSPavel Begunkov .needs_file = 1, 47606a5464bSPavel Begunkov .unbound_nonreg_file = 1, 47706a5464bSPavel Begunkov .pollout = 1, 47806a5464bSPavel Begunkov .audit_skip = 1, 47906a5464bSPavel Begunkov .ioprio = 1, 480581711c4SPavel Begunkov .manual_alloc = 1, 48106a5464bSPavel Begunkov #if defined(CONFIG_NET) 482581711c4SPavel Begunkov .async_size = sizeof(struct io_async_msghdr), 48306a5464bSPavel Begunkov .prep = io_sendzc_prep, 48406a5464bSPavel Begunkov .issue = io_sendzc, 485581711c4SPavel Begunkov .prep_async = io_sendzc_prep_async, 486*b48c312bSPavel Begunkov .cleanup = io_sendzc_cleanup, 48706a5464bSPavel Begunkov #else 48806a5464bSPavel Begunkov .prep = io_eopnotsupp_prep, 48906a5464bSPavel Begunkov #endif 49006a5464bSPavel Begunkov }, 491d9b57aa3SJens Axboe }; 492d9b57aa3SJens Axboe 493d9b57aa3SJens Axboe const char *io_uring_get_opcode(u8 opcode) 494d9b57aa3SJens Axboe { 495d9b57aa3SJens Axboe if (opcode < IORING_OP_LAST) 496d9b57aa3SJens Axboe return io_op_defs[opcode].name; 497d9b57aa3SJens Axboe return "INVALID"; 498d9b57aa3SJens Axboe } 499d9b57aa3SJens Axboe 500d9b57aa3SJens Axboe void __init io_uring_optable_init(void) 501d9b57aa3SJens Axboe { 502d9b57aa3SJens Axboe int i; 503d9b57aa3SJens Axboe 504d9b57aa3SJens Axboe BUILD_BUG_ON(ARRAY_SIZE(io_op_defs) != IORING_OP_LAST); 505d9b57aa3SJens Axboe 506d9b57aa3SJens Axboe for (i = 0; i < ARRAY_SIZE(io_op_defs); i++) { 507d9b57aa3SJens Axboe BUG_ON(!io_op_defs[i].prep); 508d9b57aa3SJens Axboe if (io_op_defs[i].prep != io_eopnotsupp_prep) 509d9b57aa3SJens Axboe BUG_ON(!io_op_defs[i].issue); 510d9b57aa3SJens Axboe WARN_ON_ONCE(!io_op_defs[i].name); 511d9b57aa3SJens Axboe } 512d9b57aa3SJens Axboe } 513