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, 66*ef0ec1adSPavel Begunkov .iopoll_queue = 1, 67d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 68d9b57aa3SJens Axboe .name = "READV", 69d9b57aa3SJens Axboe .prep = io_prep_rw, 70d9b57aa3SJens Axboe .issue = io_read, 71d9b57aa3SJens Axboe .prep_async = io_readv_prep_async, 72d9b57aa3SJens Axboe .cleanup = io_readv_writev_cleanup, 7347b4c686SPavel Begunkov .fail = io_rw_fail, 74d9b57aa3SJens Axboe }, 75d9b57aa3SJens Axboe [IORING_OP_WRITEV] = { 76d9b57aa3SJens Axboe .needs_file = 1, 77d9b57aa3SJens Axboe .hash_reg_file = 1, 78d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 79d9b57aa3SJens Axboe .pollout = 1, 80d9b57aa3SJens Axboe .plug = 1, 81d9b57aa3SJens Axboe .audit_skip = 1, 82d9b57aa3SJens Axboe .ioprio = 1, 83d9b57aa3SJens Axboe .iopoll = 1, 84*ef0ec1adSPavel Begunkov .iopoll_queue = 1, 85d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 86d9b57aa3SJens Axboe .name = "WRITEV", 87d9b57aa3SJens Axboe .prep = io_prep_rw, 88d9b57aa3SJens Axboe .issue = io_write, 89d9b57aa3SJens Axboe .prep_async = io_writev_prep_async, 90d9b57aa3SJens Axboe .cleanup = io_readv_writev_cleanup, 9147b4c686SPavel Begunkov .fail = io_rw_fail, 92d9b57aa3SJens Axboe }, 93d9b57aa3SJens Axboe [IORING_OP_FSYNC] = { 94d9b57aa3SJens Axboe .needs_file = 1, 95d9b57aa3SJens Axboe .audit_skip = 1, 96d9b57aa3SJens Axboe .name = "FSYNC", 97d9b57aa3SJens Axboe .prep = io_fsync_prep, 98d9b57aa3SJens Axboe .issue = io_fsync, 99d9b57aa3SJens Axboe }, 100d9b57aa3SJens Axboe [IORING_OP_READ_FIXED] = { 101d9b57aa3SJens Axboe .needs_file = 1, 102d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 103d9b57aa3SJens Axboe .pollin = 1, 104d9b57aa3SJens Axboe .plug = 1, 105d9b57aa3SJens Axboe .audit_skip = 1, 106d9b57aa3SJens Axboe .ioprio = 1, 107d9b57aa3SJens Axboe .iopoll = 1, 108*ef0ec1adSPavel Begunkov .iopoll_queue = 1, 109d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 110d9b57aa3SJens Axboe .name = "READ_FIXED", 111d9b57aa3SJens Axboe .prep = io_prep_rw, 112d9b57aa3SJens Axboe .issue = io_read, 11347b4c686SPavel Begunkov .fail = io_rw_fail, 114d9b57aa3SJens Axboe }, 115d9b57aa3SJens Axboe [IORING_OP_WRITE_FIXED] = { 116d9b57aa3SJens Axboe .needs_file = 1, 117d9b57aa3SJens Axboe .hash_reg_file = 1, 118d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 119d9b57aa3SJens Axboe .pollout = 1, 120d9b57aa3SJens Axboe .plug = 1, 121d9b57aa3SJens Axboe .audit_skip = 1, 122d9b57aa3SJens Axboe .ioprio = 1, 123d9b57aa3SJens Axboe .iopoll = 1, 124*ef0ec1adSPavel Begunkov .iopoll_queue = 1, 125d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 126d9b57aa3SJens Axboe .name = "WRITE_FIXED", 127d9b57aa3SJens Axboe .prep = io_prep_rw, 128d9b57aa3SJens Axboe .issue = io_write, 12947b4c686SPavel Begunkov .fail = io_rw_fail, 130d9b57aa3SJens Axboe }, 131d9b57aa3SJens Axboe [IORING_OP_POLL_ADD] = { 132d9b57aa3SJens Axboe .needs_file = 1, 133d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 134d9b57aa3SJens Axboe .audit_skip = 1, 135d9b57aa3SJens Axboe .name = "POLL_ADD", 136d9b57aa3SJens Axboe .prep = io_poll_add_prep, 137d9b57aa3SJens Axboe .issue = io_poll_add, 138d9b57aa3SJens Axboe }, 139d9b57aa3SJens Axboe [IORING_OP_POLL_REMOVE] = { 140d9b57aa3SJens Axboe .audit_skip = 1, 141d9b57aa3SJens Axboe .name = "POLL_REMOVE", 142d9b57aa3SJens Axboe .prep = io_poll_remove_prep, 143d9b57aa3SJens Axboe .issue = io_poll_remove, 144d9b57aa3SJens Axboe }, 145d9b57aa3SJens Axboe [IORING_OP_SYNC_FILE_RANGE] = { 146d9b57aa3SJens Axboe .needs_file = 1, 147d9b57aa3SJens Axboe .audit_skip = 1, 148d9b57aa3SJens Axboe .name = "SYNC_FILE_RANGE", 149d9b57aa3SJens Axboe .prep = io_sfr_prep, 150d9b57aa3SJens Axboe .issue = io_sync_file_range, 151d9b57aa3SJens Axboe }, 152d9b57aa3SJens Axboe [IORING_OP_SENDMSG] = { 153d9b57aa3SJens Axboe .needs_file = 1, 154d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 155d9b57aa3SJens Axboe .pollout = 1, 156d9b57aa3SJens Axboe .ioprio = 1, 157858c293eSPavel Begunkov .manual_alloc = 1, 158d9b57aa3SJens Axboe .name = "SENDMSG", 159d9b57aa3SJens Axboe #if defined(CONFIG_NET) 160d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_msghdr), 161d9b57aa3SJens Axboe .prep = io_sendmsg_prep, 162d9b57aa3SJens Axboe .issue = io_sendmsg, 163d9b57aa3SJens Axboe .prep_async = io_sendmsg_prep_async, 164d9b57aa3SJens Axboe .cleanup = io_sendmsg_recvmsg_cleanup, 1657e6b638eSPavel Begunkov .fail = io_sendrecv_fail, 166d9b57aa3SJens Axboe #else 167d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 168d9b57aa3SJens Axboe #endif 169d9b57aa3SJens Axboe }, 170d9b57aa3SJens Axboe [IORING_OP_RECVMSG] = { 171d9b57aa3SJens Axboe .needs_file = 1, 172d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 173d9b57aa3SJens Axboe .pollin = 1, 174d9b57aa3SJens Axboe .buffer_select = 1, 175d9b57aa3SJens Axboe .ioprio = 1, 176858c293eSPavel Begunkov .manual_alloc = 1, 177d9b57aa3SJens Axboe .name = "RECVMSG", 178d9b57aa3SJens Axboe #if defined(CONFIG_NET) 179d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_msghdr), 180d9b57aa3SJens Axboe .prep = io_recvmsg_prep, 181d9b57aa3SJens Axboe .issue = io_recvmsg, 182d9b57aa3SJens Axboe .prep_async = io_recvmsg_prep_async, 183d9b57aa3SJens Axboe .cleanup = io_sendmsg_recvmsg_cleanup, 1847e6b638eSPavel Begunkov .fail = io_sendrecv_fail, 185d9b57aa3SJens Axboe #else 186d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 187d9b57aa3SJens Axboe #endif 188d9b57aa3SJens Axboe }, 189d9b57aa3SJens Axboe [IORING_OP_TIMEOUT] = { 190d9b57aa3SJens Axboe .audit_skip = 1, 191d9b57aa3SJens Axboe .async_size = sizeof(struct io_timeout_data), 192d9b57aa3SJens Axboe .name = "TIMEOUT", 193d9b57aa3SJens Axboe .prep = io_timeout_prep, 194d9b57aa3SJens Axboe .issue = io_timeout, 195d9b57aa3SJens Axboe }, 196d9b57aa3SJens Axboe [IORING_OP_TIMEOUT_REMOVE] = { 197d9b57aa3SJens Axboe /* used by timeout updates' prep() */ 198d9b57aa3SJens Axboe .audit_skip = 1, 199d9b57aa3SJens Axboe .name = "TIMEOUT_REMOVE", 200d9b57aa3SJens Axboe .prep = io_timeout_remove_prep, 201d9b57aa3SJens Axboe .issue = io_timeout_remove, 202d9b57aa3SJens Axboe }, 203d9b57aa3SJens Axboe [IORING_OP_ACCEPT] = { 204d9b57aa3SJens Axboe .needs_file = 1, 205d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 206d9b57aa3SJens Axboe .pollin = 1, 207d9b57aa3SJens Axboe .poll_exclusive = 1, 208d9b57aa3SJens Axboe .ioprio = 1, /* used for flags */ 209d9b57aa3SJens Axboe .name = "ACCEPT", 210d9b57aa3SJens Axboe #if defined(CONFIG_NET) 211d9b57aa3SJens Axboe .prep = io_accept_prep, 212d9b57aa3SJens Axboe .issue = io_accept, 213d9b57aa3SJens Axboe #else 214d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 215d9b57aa3SJens Axboe #endif 216d9b57aa3SJens Axboe }, 217d9b57aa3SJens Axboe [IORING_OP_ASYNC_CANCEL] = { 218d9b57aa3SJens Axboe .audit_skip = 1, 219d9b57aa3SJens Axboe .name = "ASYNC_CANCEL", 220d9b57aa3SJens Axboe .prep = io_async_cancel_prep, 221d9b57aa3SJens Axboe .issue = io_async_cancel, 222d9b57aa3SJens Axboe }, 223d9b57aa3SJens Axboe [IORING_OP_LINK_TIMEOUT] = { 224d9b57aa3SJens Axboe .audit_skip = 1, 225d9b57aa3SJens Axboe .async_size = sizeof(struct io_timeout_data), 226d9b57aa3SJens Axboe .name = "LINK_TIMEOUT", 227d9b57aa3SJens Axboe .prep = io_link_timeout_prep, 228d9b57aa3SJens Axboe .issue = io_no_issue, 229d9b57aa3SJens Axboe }, 230d9b57aa3SJens Axboe [IORING_OP_CONNECT] = { 231d9b57aa3SJens Axboe .needs_file = 1, 232d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 233d9b57aa3SJens Axboe .pollout = 1, 234d9b57aa3SJens Axboe .name = "CONNECT", 235d9b57aa3SJens Axboe #if defined(CONFIG_NET) 236d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_connect), 237d9b57aa3SJens Axboe .prep = io_connect_prep, 238d9b57aa3SJens Axboe .issue = io_connect, 239d9b57aa3SJens Axboe .prep_async = io_connect_prep_async, 240d9b57aa3SJens Axboe #else 241d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 242d9b57aa3SJens Axboe #endif 243d9b57aa3SJens Axboe }, 244d9b57aa3SJens Axboe [IORING_OP_FALLOCATE] = { 245d9b57aa3SJens Axboe .needs_file = 1, 246d9b57aa3SJens Axboe .name = "FALLOCATE", 247d9b57aa3SJens Axboe .prep = io_fallocate_prep, 248d9b57aa3SJens Axboe .issue = io_fallocate, 249d9b57aa3SJens Axboe }, 250d9b57aa3SJens Axboe [IORING_OP_OPENAT] = { 251d9b57aa3SJens Axboe .name = "OPENAT", 252d9b57aa3SJens Axboe .prep = io_openat_prep, 253d9b57aa3SJens Axboe .issue = io_openat, 254d9b57aa3SJens Axboe .cleanup = io_open_cleanup, 255d9b57aa3SJens Axboe }, 256d9b57aa3SJens Axboe [IORING_OP_CLOSE] = { 257d9b57aa3SJens Axboe .name = "CLOSE", 258d9b57aa3SJens Axboe .prep = io_close_prep, 259d9b57aa3SJens Axboe .issue = io_close, 260d9b57aa3SJens Axboe }, 261d9808cebSPavel Begunkov [IORING_OP_FILES_UPDATE] = { 262d9b57aa3SJens Axboe .audit_skip = 1, 263d9b57aa3SJens Axboe .iopoll = 1, 264d9808cebSPavel Begunkov .name = "FILES_UPDATE", 265d9808cebSPavel Begunkov .prep = io_files_update_prep, 266d9808cebSPavel Begunkov .issue = io_files_update, 267d9b57aa3SJens Axboe }, 268d9b57aa3SJens Axboe [IORING_OP_STATX] = { 269d9b57aa3SJens Axboe .audit_skip = 1, 270d9b57aa3SJens Axboe .name = "STATX", 271d9b57aa3SJens Axboe .prep = io_statx_prep, 272d9b57aa3SJens Axboe .issue = io_statx, 273d9b57aa3SJens Axboe .cleanup = io_statx_cleanup, 274d9b57aa3SJens Axboe }, 275d9b57aa3SJens Axboe [IORING_OP_READ] = { 276d9b57aa3SJens Axboe .needs_file = 1, 277d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 278d9b57aa3SJens Axboe .pollin = 1, 279d9b57aa3SJens Axboe .buffer_select = 1, 280d9b57aa3SJens Axboe .plug = 1, 281d9b57aa3SJens Axboe .audit_skip = 1, 282d9b57aa3SJens Axboe .ioprio = 1, 283d9b57aa3SJens Axboe .iopoll = 1, 284*ef0ec1adSPavel Begunkov .iopoll_queue = 1, 285d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 286d9b57aa3SJens Axboe .name = "READ", 287d9b57aa3SJens Axboe .prep = io_prep_rw, 288d9b57aa3SJens Axboe .issue = io_read, 28947b4c686SPavel Begunkov .fail = io_rw_fail, 290d9b57aa3SJens Axboe }, 291d9b57aa3SJens Axboe [IORING_OP_WRITE] = { 292d9b57aa3SJens Axboe .needs_file = 1, 293d9b57aa3SJens Axboe .hash_reg_file = 1, 294d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 295d9b57aa3SJens Axboe .pollout = 1, 296d9b57aa3SJens Axboe .plug = 1, 297d9b57aa3SJens Axboe .audit_skip = 1, 298d9b57aa3SJens Axboe .ioprio = 1, 299d9b57aa3SJens Axboe .iopoll = 1, 300*ef0ec1adSPavel Begunkov .iopoll_queue = 1, 301d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 302d9b57aa3SJens Axboe .name = "WRITE", 303d9b57aa3SJens Axboe .prep = io_prep_rw, 304d9b57aa3SJens Axboe .issue = io_write, 30547b4c686SPavel Begunkov .fail = io_rw_fail, 306d9b57aa3SJens Axboe }, 307d9b57aa3SJens Axboe [IORING_OP_FADVISE] = { 308d9b57aa3SJens Axboe .needs_file = 1, 309d9b57aa3SJens Axboe .audit_skip = 1, 310d9b57aa3SJens Axboe .name = "FADVISE", 311d9b57aa3SJens Axboe .prep = io_fadvise_prep, 312d9b57aa3SJens Axboe .issue = io_fadvise, 313d9b57aa3SJens Axboe }, 314d9b57aa3SJens Axboe [IORING_OP_MADVISE] = { 315d9b57aa3SJens Axboe .name = "MADVISE", 316d9b57aa3SJens Axboe .prep = io_madvise_prep, 317d9b57aa3SJens Axboe .issue = io_madvise, 318d9b57aa3SJens Axboe }, 319d9b57aa3SJens Axboe [IORING_OP_SEND] = { 320d9b57aa3SJens Axboe .needs_file = 1, 321d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 322d9b57aa3SJens Axboe .pollout = 1, 323d9b57aa3SJens Axboe .audit_skip = 1, 324d9b57aa3SJens Axboe .ioprio = 1, 325516e82f0SPavel Begunkov .manual_alloc = 1, 326d9b57aa3SJens Axboe .name = "SEND", 327d9b57aa3SJens Axboe #if defined(CONFIG_NET) 328516e82f0SPavel Begunkov .async_size = sizeof(struct io_async_msghdr), 329d9b57aa3SJens Axboe .prep = io_sendmsg_prep, 330d9b57aa3SJens Axboe .issue = io_send, 3317e6b638eSPavel Begunkov .fail = io_sendrecv_fail, 332516e82f0SPavel Begunkov .prep_async = io_send_prep_async, 333d9b57aa3SJens Axboe #else 334d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 335d9b57aa3SJens Axboe #endif 336d9b57aa3SJens Axboe }, 337d9b57aa3SJens Axboe [IORING_OP_RECV] = { 338d9b57aa3SJens Axboe .needs_file = 1, 339d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 340d9b57aa3SJens Axboe .pollin = 1, 341d9b57aa3SJens Axboe .buffer_select = 1, 342d9b57aa3SJens Axboe .audit_skip = 1, 343d9b57aa3SJens Axboe .ioprio = 1, 344d9b57aa3SJens Axboe .name = "RECV", 345d9b57aa3SJens Axboe #if defined(CONFIG_NET) 346d9b57aa3SJens Axboe .prep = io_recvmsg_prep, 347d9b57aa3SJens Axboe .issue = io_recv, 3487e6b638eSPavel Begunkov .fail = io_sendrecv_fail, 349d9b57aa3SJens Axboe #else 350d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 351d9b57aa3SJens Axboe #endif 352d9b57aa3SJens Axboe }, 353d9b57aa3SJens Axboe [IORING_OP_OPENAT2] = { 354d9b57aa3SJens Axboe .name = "OPENAT2", 355d9b57aa3SJens Axboe .prep = io_openat2_prep, 356d9b57aa3SJens Axboe .issue = io_openat2, 357d9b57aa3SJens Axboe .cleanup = io_open_cleanup, 358d9b57aa3SJens Axboe }, 359d9b57aa3SJens Axboe [IORING_OP_EPOLL_CTL] = { 360d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 361d9b57aa3SJens Axboe .audit_skip = 1, 362d9b57aa3SJens Axboe .name = "EPOLL", 363d9b57aa3SJens Axboe #if defined(CONFIG_EPOLL) 364d9b57aa3SJens Axboe .prep = io_epoll_ctl_prep, 365d9b57aa3SJens Axboe .issue = io_epoll_ctl, 366d9b57aa3SJens Axboe #else 367d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 368d9b57aa3SJens Axboe #endif 369d9b57aa3SJens Axboe }, 370d9b57aa3SJens Axboe [IORING_OP_SPLICE] = { 371d9b57aa3SJens Axboe .needs_file = 1, 372d9b57aa3SJens Axboe .hash_reg_file = 1, 373d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 374d9b57aa3SJens Axboe .audit_skip = 1, 375d9b57aa3SJens Axboe .name = "SPLICE", 376d9b57aa3SJens Axboe .prep = io_splice_prep, 377d9b57aa3SJens Axboe .issue = io_splice, 378d9b57aa3SJens Axboe }, 379d9b57aa3SJens Axboe [IORING_OP_PROVIDE_BUFFERS] = { 380d9b57aa3SJens Axboe .audit_skip = 1, 381d9b57aa3SJens Axboe .iopoll = 1, 382d9b57aa3SJens Axboe .name = "PROVIDE_BUFFERS", 383d9b57aa3SJens Axboe .prep = io_provide_buffers_prep, 384d9b57aa3SJens Axboe .issue = io_provide_buffers, 385d9b57aa3SJens Axboe }, 386d9b57aa3SJens Axboe [IORING_OP_REMOVE_BUFFERS] = { 387d9b57aa3SJens Axboe .audit_skip = 1, 388d9b57aa3SJens Axboe .iopoll = 1, 389d9b57aa3SJens Axboe .name = "REMOVE_BUFFERS", 390d9b57aa3SJens Axboe .prep = io_remove_buffers_prep, 391d9b57aa3SJens Axboe .issue = io_remove_buffers, 392d9b57aa3SJens Axboe }, 393d9b57aa3SJens Axboe [IORING_OP_TEE] = { 394d9b57aa3SJens Axboe .needs_file = 1, 395d9b57aa3SJens Axboe .hash_reg_file = 1, 396d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 397d9b57aa3SJens Axboe .audit_skip = 1, 398d9b57aa3SJens Axboe .name = "TEE", 399d9b57aa3SJens Axboe .prep = io_tee_prep, 400d9b57aa3SJens Axboe .issue = io_tee, 401d9b57aa3SJens Axboe }, 402d9b57aa3SJens Axboe [IORING_OP_SHUTDOWN] = { 403d9b57aa3SJens Axboe .needs_file = 1, 404d9b57aa3SJens Axboe .name = "SHUTDOWN", 405d9b57aa3SJens Axboe #if defined(CONFIG_NET) 406d9b57aa3SJens Axboe .prep = io_shutdown_prep, 407d9b57aa3SJens Axboe .issue = io_shutdown, 408d9b57aa3SJens Axboe #else 409d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 410d9b57aa3SJens Axboe #endif 411d9b57aa3SJens Axboe }, 412d9b57aa3SJens Axboe [IORING_OP_RENAMEAT] = { 413d9b57aa3SJens Axboe .name = "RENAMEAT", 414d9b57aa3SJens Axboe .prep = io_renameat_prep, 415d9b57aa3SJens Axboe .issue = io_renameat, 416d9b57aa3SJens Axboe .cleanup = io_renameat_cleanup, 417d9b57aa3SJens Axboe }, 418d9b57aa3SJens Axboe [IORING_OP_UNLINKAT] = { 419d9b57aa3SJens Axboe .name = "UNLINKAT", 420d9b57aa3SJens Axboe .prep = io_unlinkat_prep, 421d9b57aa3SJens Axboe .issue = io_unlinkat, 422d9b57aa3SJens Axboe .cleanup = io_unlinkat_cleanup, 423d9b57aa3SJens Axboe }, 424d9b57aa3SJens Axboe [IORING_OP_MKDIRAT] = { 425d9b57aa3SJens Axboe .name = "MKDIRAT", 426d9b57aa3SJens Axboe .prep = io_mkdirat_prep, 427d9b57aa3SJens Axboe .issue = io_mkdirat, 428d9b57aa3SJens Axboe .cleanup = io_mkdirat_cleanup, 429d9b57aa3SJens Axboe }, 430d9b57aa3SJens Axboe [IORING_OP_SYMLINKAT] = { 431d9b57aa3SJens Axboe .name = "SYMLINKAT", 432d9b57aa3SJens Axboe .prep = io_symlinkat_prep, 433d9b57aa3SJens Axboe .issue = io_symlinkat, 434d9b57aa3SJens Axboe .cleanup = io_link_cleanup, 435d9b57aa3SJens Axboe }, 436d9b57aa3SJens Axboe [IORING_OP_LINKAT] = { 437d9b57aa3SJens Axboe .name = "LINKAT", 438d9b57aa3SJens Axboe .prep = io_linkat_prep, 439d9b57aa3SJens Axboe .issue = io_linkat, 440d9b57aa3SJens Axboe .cleanup = io_link_cleanup, 441d9b57aa3SJens Axboe }, 442d9b57aa3SJens Axboe [IORING_OP_MSG_RING] = { 443d9b57aa3SJens Axboe .needs_file = 1, 444d9b57aa3SJens Axboe .iopoll = 1, 445d9b57aa3SJens Axboe .name = "MSG_RING", 446d9b57aa3SJens Axboe .prep = io_msg_ring_prep, 447d9b57aa3SJens Axboe .issue = io_msg_ring, 448d9b57aa3SJens Axboe }, 449d9b57aa3SJens Axboe [IORING_OP_FSETXATTR] = { 450d9b57aa3SJens Axboe .needs_file = 1, 451d9b57aa3SJens Axboe .name = "FSETXATTR", 452d9b57aa3SJens Axboe .prep = io_fsetxattr_prep, 453d9b57aa3SJens Axboe .issue = io_fsetxattr, 454d9b57aa3SJens Axboe .cleanup = io_xattr_cleanup, 455d9b57aa3SJens Axboe }, 456d9b57aa3SJens Axboe [IORING_OP_SETXATTR] = { 457d9b57aa3SJens Axboe .name = "SETXATTR", 458d9b57aa3SJens Axboe .prep = io_setxattr_prep, 459d9b57aa3SJens Axboe .issue = io_setxattr, 460d9b57aa3SJens Axboe .cleanup = io_xattr_cleanup, 461d9b57aa3SJens Axboe }, 462d9b57aa3SJens Axboe [IORING_OP_FGETXATTR] = { 463d9b57aa3SJens Axboe .needs_file = 1, 464d9b57aa3SJens Axboe .name = "FGETXATTR", 465d9b57aa3SJens Axboe .prep = io_fgetxattr_prep, 466d9b57aa3SJens Axboe .issue = io_fgetxattr, 467d9b57aa3SJens Axboe .cleanup = io_xattr_cleanup, 468d9b57aa3SJens Axboe }, 469d9b57aa3SJens Axboe [IORING_OP_GETXATTR] = { 470d9b57aa3SJens Axboe .name = "GETXATTR", 471d9b57aa3SJens Axboe .prep = io_getxattr_prep, 472d9b57aa3SJens Axboe .issue = io_getxattr, 473d9b57aa3SJens Axboe .cleanup = io_xattr_cleanup, 474d9b57aa3SJens Axboe }, 475d9b57aa3SJens Axboe [IORING_OP_SOCKET] = { 476d9b57aa3SJens Axboe .audit_skip = 1, 477d9b57aa3SJens Axboe .name = "SOCKET", 478d9b57aa3SJens Axboe #if defined(CONFIG_NET) 479d9b57aa3SJens Axboe .prep = io_socket_prep, 480d9b57aa3SJens Axboe .issue = io_socket, 481d9b57aa3SJens Axboe #else 482d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 483d9b57aa3SJens Axboe #endif 484d9b57aa3SJens Axboe }, 485d9b57aa3SJens Axboe [IORING_OP_URING_CMD] = { 486d9b57aa3SJens Axboe .needs_file = 1, 487d9b57aa3SJens Axboe .plug = 1, 488d9b57aa3SJens Axboe .name = "URING_CMD", 4895756a3a7SKanchan Joshi .iopoll = 1, 490*ef0ec1adSPavel Begunkov .iopoll_queue = 1, 491d9b57aa3SJens Axboe .async_size = uring_cmd_pdu_size(1), 492d9b57aa3SJens Axboe .prep = io_uring_cmd_prep, 493d9b57aa3SJens Axboe .issue = io_uring_cmd, 494d9b57aa3SJens Axboe .prep_async = io_uring_cmd_prep_async, 495d9b57aa3SJens Axboe }, 496b48c312bSPavel Begunkov [IORING_OP_SEND_ZC] = { 4979bd3f728SStefan Metzmacher .name = "SEND_ZC", 49806a5464bSPavel Begunkov .needs_file = 1, 49906a5464bSPavel Begunkov .unbound_nonreg_file = 1, 50006a5464bSPavel Begunkov .pollout = 1, 50106a5464bSPavel Begunkov .audit_skip = 1, 50206a5464bSPavel Begunkov .ioprio = 1, 503581711c4SPavel Begunkov .manual_alloc = 1, 50406a5464bSPavel Begunkov #if defined(CONFIG_NET) 505581711c4SPavel Begunkov .async_size = sizeof(struct io_async_msghdr), 506b0e9b551SPavel Begunkov .prep = io_send_zc_prep, 507b0e9b551SPavel Begunkov .issue = io_send_zc, 508516e82f0SPavel Begunkov .prep_async = io_send_prep_async, 509b0e9b551SPavel Begunkov .cleanup = io_send_zc_cleanup, 510c4c0009eSPavel Begunkov .fail = io_sendrecv_fail, 51106a5464bSPavel Begunkov #else 51206a5464bSPavel Begunkov .prep = io_eopnotsupp_prep, 51306a5464bSPavel Begunkov #endif 51406a5464bSPavel Begunkov }, 515493108d9SPavel Begunkov [IORING_OP_SENDMSG_ZC] = { 516493108d9SPavel Begunkov .name = "SENDMSG_ZC", 517493108d9SPavel Begunkov .needs_file = 1, 518493108d9SPavel Begunkov .unbound_nonreg_file = 1, 519493108d9SPavel Begunkov .pollout = 1, 520493108d9SPavel Begunkov .ioprio = 1, 521493108d9SPavel Begunkov .manual_alloc = 1, 522493108d9SPavel Begunkov #if defined(CONFIG_NET) 523493108d9SPavel Begunkov .async_size = sizeof(struct io_async_msghdr), 524493108d9SPavel Begunkov .prep = io_send_zc_prep, 525493108d9SPavel Begunkov .issue = io_sendmsg_zc, 526493108d9SPavel Begunkov .prep_async = io_sendmsg_prep_async, 527493108d9SPavel Begunkov .cleanup = io_send_zc_cleanup, 528493108d9SPavel Begunkov .fail = io_sendrecv_fail, 529493108d9SPavel Begunkov #else 530493108d9SPavel Begunkov .prep = io_eopnotsupp_prep, 531493108d9SPavel Begunkov #endif 532493108d9SPavel Begunkov }, 533d9b57aa3SJens Axboe }; 534d9b57aa3SJens Axboe 535d9b57aa3SJens Axboe const char *io_uring_get_opcode(u8 opcode) 536d9b57aa3SJens Axboe { 537d9b57aa3SJens Axboe if (opcode < IORING_OP_LAST) 538d9b57aa3SJens Axboe return io_op_defs[opcode].name; 539d9b57aa3SJens Axboe return "INVALID"; 540d9b57aa3SJens Axboe } 541d9b57aa3SJens Axboe 542d9b57aa3SJens Axboe void __init io_uring_optable_init(void) 543d9b57aa3SJens Axboe { 544d9b57aa3SJens Axboe int i; 545d9b57aa3SJens Axboe 546d9b57aa3SJens Axboe BUILD_BUG_ON(ARRAY_SIZE(io_op_defs) != IORING_OP_LAST); 547d9b57aa3SJens Axboe 548d9b57aa3SJens Axboe for (i = 0; i < ARRAY_SIZE(io_op_defs); i++) { 549d9b57aa3SJens Axboe BUG_ON(!io_op_defs[i].prep); 550d9b57aa3SJens Axboe if (io_op_defs[i].prep != io_eopnotsupp_prep) 551d9b57aa3SJens Axboe BUG_ON(!io_op_defs[i].issue); 552d9b57aa3SJens Axboe WARN_ON_ONCE(!io_op_defs[i].name); 553d9b57aa3SJens Axboe } 554d9b57aa3SJens Axboe } 555